diff --git a/.last-synced-sha b/.last-synced-sha new file mode 100644 index 00000000..f72eb0e2 --- /dev/null +++ b/.last-synced-sha @@ -0,0 +1 @@ +92db0495807c86fbbc4d45bd266a6c1f5bcbb59c diff --git a/.oagen-manifest.json b/.oagen-manifest.json index 58b74aac..3804b4fc 100644 --- a/.oagen-manifest.json +++ b/.oagen-manifest.json @@ -1,7 +1,7 @@ { - "version": 1, + "version": 2, "language": "go", - "generatedAt": "2026-04-21T08:15:56.919Z", + "generatedAt": "2026-04-27T21:21:02.564Z", "files": [ "admin_portal.go", "admin_portal_test.go", @@ -20,6 +20,8 @@ "events_test.go", "feature_flags.go", "feature_flags_test.go", + "groups.go", + "groups_test.go", "helpers_test.go", "models.go", "multi_factor_auth.go", @@ -150,6 +152,8 @@ "testdata/create_authorization_permission.json", "testdata/create_authorization_resource.json", "testdata/create_cors_origin.json", + "testdata/create_group.json", + "testdata/create_group_membership.json", "testdata/create_m2m_application.json", "testdata/create_magic_code_and_return.json", "testdata/create_oauth_application.json", @@ -181,6 +185,7 @@ "testdata/directory_user.json", "testdata/directory_user_email.json", "testdata/directory_user_with_groups.json", + "testdata/domain_verification_intent_options.json", "testdata/dsync_activated.json", "testdata/dsync_activated_data.json", "testdata/dsync_activated_data_domain.json", @@ -269,12 +274,12 @@ "testdata/list_directory_group.json", "testdata/list_directory_user_with_groups.json", "testdata/list_event_schema.json", + "testdata/list_group.json", "testdata/list_organization.json", "testdata/list_role_assignment.json", "testdata/list_user.json", "testdata/list_user_invite.json", "testdata/list_user_organization_membership.json", - "testdata/list_user_organization_membership_base_list_data.json", "testdata/list_user_sessions_list_item.json", "testdata/list_webhook_endpoint_json.json", "testdata/magic_auth.json", @@ -357,6 +362,7 @@ "testdata/update_audit_logs_retention.json", "testdata/update_authorization_permission.json", "testdata/update_authorization_resource.json", + "testdata/update_group.json", "testdata/update_jwt_template.json", "testdata/update_oauth_application.json", "testdata/update_organization.json", @@ -402,15 +408,691 @@ "testdata/vault_names_listed_data.json", "testdata/verify_email_address.json", "testdata/verify_email_response.json", + "testdata/waitlist_user.json", + "testdata/waitlist_user_approved.json", + "testdata/waitlist_user_created.json", + "testdata/waitlist_user_denied.json", "testdata/webhook_endpoint_json.json", "testdata/widget_session_token.json", "testdata/widget_session_token_response.json", "user_management.go", + "user_management_organization_membership_groups.go", + "user_management_organization_membership_groups_test.go", "user_management_test.go", "webhooks.go", "webhooks_test.go", "widgets.go", "widgets_test.go", "workos.go" - ] + ], + "operations": { + "POST /api_keys/validations": { + "sdkMethod": "CreateValidation", + "service": "api_keys" + }, + "DELETE /api_keys/{id}": { + "sdkMethod": "Delete", + "service": "api_keys" + }, + "POST /auth/challenges/{id}/verify": { + "sdkMethod": "VerifyChallenge", + "service": "multi_factor_auth" + }, + "POST /auth/factors/enroll": { + "sdkMethod": "EnrollFactor", + "service": "multi_factor_auth" + }, + "GET /auth/factors/{id}": { + "sdkMethod": "GetFactor", + "service": "multi_factor_auth" + }, + "DELETE /auth/factors/{id}": { + "sdkMethod": "DeleteFactor", + "service": "multi_factor_auth" + }, + "POST /auth/factors/{id}/challenge": { + "sdkMethod": "ChallengeFactor", + "service": "multi_factor_auth" + }, + "POST /authkit/oauth2/complete": { + "sdkMethod": "CompleteOAuth2", + "service": "connect" + }, + "POST /authorization/organization_memberships/{organization_membership_id}/check": { + "sdkMethod": "Check", + "service": "authorization" + }, + "GET /authorization/organization_memberships/{organization_membership_id}/resources": { + "sdkMethod": "ListResourcesForMembership", + "service": "authorization" + }, + "GET /authorization/organization_memberships/{organization_membership_id}/resources/{resource_id}/permissions": { + "sdkMethod": "ListEffectivePermissions", + "service": "authorization" + }, + "GET /authorization/organization_memberships/{organization_membership_id}/resources/{resource_type_slug}/{external_id}/permissions": { + "sdkMethod": "ListEffectivePermissionsByExternalID", + "service": "authorization" + }, + "GET /authorization/organization_memberships/{organization_membership_id}/role_assignments": { + "sdkMethod": "ListRoleAssignments", + "service": "authorization" + }, + "POST /authorization/organization_memberships/{organization_membership_id}/role_assignments": { + "sdkMethod": "AssignRole", + "service": "authorization" + }, + "DELETE /authorization/organization_memberships/{organization_membership_id}/role_assignments": { + "sdkMethod": "RemoveRole", + "service": "authorization" + }, + "DELETE /authorization/organization_memberships/{organization_membership_id}/role_assignments/{role_assignment_id}": { + "sdkMethod": "RemoveRoleAssignment", + "service": "authorization" + }, + "GET /authorization/organizations/{organizationId}/roles": { + "sdkMethod": "ListOrganizationRoles", + "service": "authorization" + }, + "POST /authorization/organizations/{organizationId}/roles": { + "sdkMethod": "CreateOrganizationRole", + "service": "authorization" + }, + "GET /authorization/organizations/{organizationId}/roles/{slug}": { + "sdkMethod": "GetOrganizationRole", + "service": "authorization" + }, + "PATCH /authorization/organizations/{organizationId}/roles/{slug}": { + "sdkMethod": "UpdateOrganizationRole", + "service": "authorization" + }, + "DELETE /authorization/organizations/{organizationId}/roles/{slug}": { + "sdkMethod": "DeleteOrganizationRole", + "service": "authorization" + }, + "POST /authorization/organizations/{organizationId}/roles/{slug}/permissions": { + "sdkMethod": "AddOrganizationRolePermission", + "service": "authorization" + }, + "PUT /authorization/organizations/{organizationId}/roles/{slug}/permissions": { + "sdkMethod": "SetOrganizationRolePermissions", + "service": "authorization" + }, + "DELETE /authorization/organizations/{organizationId}/roles/{slug}/permissions/{permissionSlug}": { + "sdkMethod": "RemoveOrganizationRolePermission", + "service": "authorization" + }, + "GET /authorization/organizations/{organization_id}/resources/{resource_type_slug}/{external_id}": { + "sdkMethod": "GetResourceByExternalID", + "service": "authorization" + }, + "PATCH /authorization/organizations/{organization_id}/resources/{resource_type_slug}/{external_id}": { + "sdkMethod": "UpdateResourceByExternalID", + "service": "authorization" + }, + "DELETE /authorization/organizations/{organization_id}/resources/{resource_type_slug}/{external_id}": { + "sdkMethod": "DeleteResourceByExternalID", + "service": "authorization" + }, + "GET /authorization/organizations/{organization_id}/resources/{resource_type_slug}/{external_id}/organization_memberships": { + "sdkMethod": "ListMembershipsForResourceByExternalID", + "service": "authorization" + }, + "GET /authorization/resources": { + "sdkMethod": "ListResources", + "service": "authorization" + }, + "POST /authorization/resources": { + "sdkMethod": "CreateResource", + "service": "authorization" + }, + "GET /authorization/resources/{resource_id}": { + "sdkMethod": "GetResource", + "service": "authorization" + }, + "PATCH /authorization/resources/{resource_id}": { + "sdkMethod": "UpdateResource", + "service": "authorization" + }, + "DELETE /authorization/resources/{resource_id}": { + "sdkMethod": "DeleteResource", + "service": "authorization" + }, + "GET /authorization/resources/{resource_id}/organization_memberships": { + "sdkMethod": "ListMembershipsForResource", + "service": "authorization" + }, + "GET /authorization/roles": { + "sdkMethod": "ListEnvironmentRoles", + "service": "authorization" + }, + "POST /authorization/roles": { + "sdkMethod": "CreateEnvironmentRole", + "service": "authorization" + }, + "GET /authorization/roles/{slug}": { + "sdkMethod": "GetEnvironmentRole", + "service": "authorization" + }, + "PATCH /authorization/roles/{slug}": { + "sdkMethod": "UpdateEnvironmentRole", + "service": "authorization" + }, + "POST /authorization/roles/{slug}/permissions": { + "sdkMethod": "AddEnvironmentRolePermission", + "service": "authorization" + }, + "PUT /authorization/roles/{slug}/permissions": { + "sdkMethod": "SetEnvironmentRolePermissions", + "service": "authorization" + }, + "GET /authorization/permissions": { + "sdkMethod": "ListPermissions", + "service": "authorization" + }, + "POST /authorization/permissions": { + "sdkMethod": "CreatePermission", + "service": "authorization" + }, + "GET /authorization/permissions/{slug}": { + "sdkMethod": "GetPermission", + "service": "authorization" + }, + "PATCH /authorization/permissions/{slug}": { + "sdkMethod": "UpdatePermission", + "service": "authorization" + }, + "DELETE /authorization/permissions/{slug}": { + "sdkMethod": "DeletePermission", + "service": "authorization" + }, + "GET /connect/applications": { + "sdkMethod": "ListApplications", + "service": "connect" + }, + "POST /connect/applications": { + "sdkMethod": "CreateApplication", + "service": "connect" + }, + "GET /connect/applications/{id}": { + "sdkMethod": "GetApplication", + "service": "connect" + }, + "PUT /connect/applications/{id}": { + "sdkMethod": "UpdateApplication", + "service": "connect" + }, + "DELETE /connect/applications/{id}": { + "sdkMethod": "DeleteApplication", + "service": "connect" + }, + "GET /connect/applications/{id}/client_secrets": { + "sdkMethod": "ListApplicationClientSecrets", + "service": "connect" + }, + "POST /connect/applications/{id}/client_secrets": { + "sdkMethod": "CreateApplicationClientSecret", + "service": "connect" + }, + "DELETE /connect/client_secrets/{id}": { + "sdkMethod": "DeleteClientSecret", + "service": "connect" + }, + "GET /connections": { + "sdkMethod": "ListConnections", + "service": "sso" + }, + "GET /connections/{id}": { + "sdkMethod": "GetConnection", + "service": "sso" + }, + "DELETE /connections/{id}": { + "sdkMethod": "DeleteConnection", + "service": "sso" + }, + "POST /data-integrations/{slug}/authorize": { + "sdkMethod": "AuthorizeDataIntegration", + "service": "pipes" + }, + "POST /data-integrations/{slug}/token": { + "sdkMethod": "CreateDataIntegrationToken", + "service": "pipes" + }, + "GET /directories": { + "sdkMethod": "List", + "service": "directory_sync" + }, + "GET /directories/{id}": { + "sdkMethod": "Get", + "service": "directory_sync" + }, + "DELETE /directories/{id}": { + "sdkMethod": "Delete", + "service": "directory_sync" + }, + "GET /directory_groups": { + "sdkMethod": "ListGroups", + "service": "directory_sync" + }, + "GET /directory_groups/{id}": { + "sdkMethod": "GetGroup", + "service": "directory_sync" + }, + "GET /directory_users": { + "sdkMethod": "ListUsers", + "service": "directory_sync" + }, + "GET /directory_users/{id}": { + "sdkMethod": "GetUser", + "service": "directory_sync" + }, + "GET /events": { + "sdkMethod": "List", + "service": "events" + }, + "GET /feature-flags": { + "sdkMethod": "List", + "service": "feature_flags" + }, + "GET /feature-flags/{slug}": { + "sdkMethod": "Get", + "service": "feature_flags" + }, + "PUT /feature-flags/{slug}/disable": { + "sdkMethod": "Disable", + "service": "feature_flags" + }, + "PUT /feature-flags/{slug}/enable": { + "sdkMethod": "Enable", + "service": "feature_flags" + }, + "POST /feature-flags/{slug}/targets/{resourceId}": { + "sdkMethod": "AddFlagTarget", + "service": "feature_flags" + }, + "DELETE /feature-flags/{slug}/targets/{resourceId}": { + "sdkMethod": "RemoveFlagTarget", + "service": "feature_flags" + }, + "POST /organization_domains": { + "sdkMethod": "Create", + "service": "organization_domains" + }, + "GET /organization_domains/{id}": { + "sdkMethod": "Get", + "service": "organization_domains" + }, + "DELETE /organization_domains/{id}": { + "sdkMethod": "Delete", + "service": "organization_domains" + }, + "POST /organization_domains/{id}/verify": { + "sdkMethod": "Verify", + "service": "organization_domains" + }, + "GET /organizations": { + "sdkMethod": "List", + "service": "organizations" + }, + "POST /organizations": { + "sdkMethod": "Create", + "service": "organizations" + }, + "GET /organizations/external_id/{external_id}": { + "sdkMethod": "GetByExternalID", + "service": "organizations" + }, + "GET /organizations/{id}": { + "sdkMethod": "Get", + "service": "organizations" + }, + "PUT /organizations/{id}": { + "sdkMethod": "Update", + "service": "organizations" + }, + "DELETE /organizations/{id}": { + "sdkMethod": "Delete", + "service": "organizations" + }, + "GET /organizations/{id}/audit_log_configuration": { + "sdkMethod": "GetAuditLogConfiguration", + "service": "organizations" + }, + "GET /organizations/{id}/audit_logs_retention": { + "sdkMethod": "GetAuditLogsRetention", + "service": "audit_logs" + }, + "PUT /organizations/{id}/audit_logs_retention": { + "sdkMethod": "UpdateAuditLogsRetention", + "service": "audit_logs" + }, + "GET /organizations/{organizationId}/api_keys": { + "sdkMethod": "ListOrganizationAPIKeys", + "service": "api_keys" + }, + "POST /organizations/{organizationId}/api_keys": { + "sdkMethod": "CreateOrganizationAPIKey", + "service": "api_keys" + }, + "GET /organizations/{organizationId}/feature-flags": { + "sdkMethod": "ListOrganizationFeatureFlags", + "service": "feature_flags" + }, + "GET /organizations/{organizationId}/groups": { + "sdkMethod": "ListOrganizationGroups", + "service": "groups" + }, + "POST /organizations/{organizationId}/groups": { + "sdkMethod": "CreateOrganizationGroup", + "service": "groups" + }, + "GET /organizations/{organizationId}/groups/{groupId}": { + "sdkMethod": "GetOrganizationGroup", + "service": "groups" + }, + "PATCH /organizations/{organizationId}/groups/{groupId}": { + "sdkMethod": "UpdateOrganizationGroup", + "service": "groups" + }, + "DELETE /organizations/{organizationId}/groups/{groupId}": { + "sdkMethod": "DeleteOrganizationGroup", + "service": "groups" + }, + "GET /organizations/{organizationId}/groups/{groupId}/organization-memberships": { + "sdkMethod": "ListOrganizationMemberships", + "service": "groups" + }, + "POST /organizations/{organizationId}/groups/{groupId}/organization-memberships": { + "sdkMethod": "CreateOrganizationMembership", + "service": "groups" + }, + "DELETE /organizations/{organizationId}/groups/{groupId}/organization-memberships/{omId}": { + "sdkMethod": "DeleteOrganizationMembership", + "service": "groups" + }, + "POST /portal/generate_link": { + "sdkMethod": "GenerateLink", + "service": "admin_portal" + }, + "POST /radar/attempts": { + "sdkMethod": "CreateAttempt", + "service": "radar" + }, + "PUT /radar/attempts/{id}": { + "sdkMethod": "UpdateAttempt", + "service": "radar" + }, + "POST /radar/lists/{type}/{action}": { + "sdkMethod": "AddListEntry", + "service": "radar" + }, + "DELETE /radar/lists/{type}/{action}": { + "sdkMethod": "RemoveListEntry", + "service": "radar" + }, + "GET /sso/authorize": { + "sdkMethod": "GetAuthorizationURL", + "service": "sso" + }, + "GET /sso/logout": { + "sdkMethod": "GetLogoutURL", + "service": "sso" + }, + "POST /sso/logout/authorize": { + "sdkMethod": "AuthorizeLogout", + "service": "sso" + }, + "GET /sso/profile": { + "sdkMethod": "GetProfile", + "service": "sso" + }, + "POST /sso/token": { + "sdkMethod": "GetProfileAndToken", + "service": "sso" + }, + "GET /sso/jwks/{clientId}": { + "sdkMethod": "GetJWKS", + "service": "user_management" + }, + "POST /user_management/authenticate": { + "sdkMethod": "CreateAuthenticate", + "service": "user_management" + }, + "GET /user_management/authorize": { + "sdkMethod": "GetAuthorizationURL", + "service": "user_management" + }, + "POST /user_management/authorize/device": { + "sdkMethod": "CreateDevice", + "service": "user_management" + }, + "GET /user_management/sessions/logout": { + "sdkMethod": "GetLogoutURL", + "service": "user_management" + }, + "POST /user_management/sessions/revoke": { + "sdkMethod": "RevokeSession", + "service": "user_management" + }, + "POST /user_management/cors_origins": { + "sdkMethod": "CreateCORSOrigin", + "service": "user_management" + }, + "GET /user_management/email_verification/{id}": { + "sdkMethod": "GetEmailVerification", + "service": "user_management" + }, + "POST /user_management/password_reset": { + "sdkMethod": "ResetPassword", + "service": "user_management" + }, + "POST /user_management/password_reset/confirm": { + "sdkMethod": "ConfirmPasswordReset", + "service": "user_management" + }, + "GET /user_management/password_reset/{id}": { + "sdkMethod": "GetPasswordReset", + "service": "user_management" + }, + "GET /user_management/users": { + "sdkMethod": "List", + "service": "user_management" + }, + "POST /user_management/users": { + "sdkMethod": "Create", + "service": "user_management" + }, + "GET /user_management/users/external_id/{external_id}": { + "sdkMethod": "GetByExternalID", + "service": "user_management" + }, + "GET /user_management/users/{id}": { + "sdkMethod": "Get", + "service": "user_management" + }, + "PUT /user_management/users/{id}": { + "sdkMethod": "Update", + "service": "user_management" + }, + "DELETE /user_management/users/{id}": { + "sdkMethod": "Delete", + "service": "user_management" + }, + "POST /user_management/users/{id}/email_change/confirm": { + "sdkMethod": "ConfirmEmailChange", + "service": "user_management" + }, + "POST /user_management/users/{id}/email_change/send": { + "sdkMethod": "SendEmailChange", + "service": "user_management" + }, + "POST /user_management/users/{id}/email_verification/confirm": { + "sdkMethod": "VerifyEmail", + "service": "user_management" + }, + "POST /user_management/users/{id}/email_verification/send": { + "sdkMethod": "SendVerificationEmail", + "service": "user_management" + }, + "GET /user_management/users/{id}/identities": { + "sdkMethod": "GetIdentities", + "service": "user_management" + }, + "GET /user_management/users/{id}/sessions": { + "sdkMethod": "ListSessions", + "service": "user_management" + }, + "GET /user_management/invitations": { + "sdkMethod": "ListInvitations", + "service": "user_management" + }, + "POST /user_management/invitations": { + "sdkMethod": "SendInvitation", + "service": "user_management" + }, + "GET /user_management/invitations/by_token/{token}": { + "sdkMethod": "FindInvitationByToken", + "service": "user_management" + }, + "GET /user_management/invitations/{id}": { + "sdkMethod": "GetInvitation", + "service": "user_management" + }, + "POST /user_management/invitations/{id}/accept": { + "sdkMethod": "AcceptInvitation", + "service": "user_management" + }, + "POST /user_management/invitations/{id}/resend": { + "sdkMethod": "ResendInvitation", + "service": "user_management" + }, + "POST /user_management/invitations/{id}/revoke": { + "sdkMethod": "RevokeInvitation", + "service": "user_management" + }, + "PUT /user_management/jwt_template": { + "sdkMethod": "UpdateJWTTemplate", + "service": "user_management" + }, + "POST /user_management/magic_auth": { + "sdkMethod": "CreateMagicAuth", + "service": "user_management" + }, + "GET /user_management/magic_auth/{id}": { + "sdkMethod": "GetMagicAuth", + "service": "user_management" + }, + "GET /user_management/organization_memberships": { + "sdkMethod": "ListOrganizationMemberships", + "service": "user_management" + }, + "POST /user_management/organization_memberships": { + "sdkMethod": "CreateOrganizationMembership", + "service": "user_management" + }, + "GET /user_management/organization_memberships/{id}": { + "sdkMethod": "GetOrganizationMembership", + "service": "user_management" + }, + "PUT /user_management/organization_memberships/{id}": { + "sdkMethod": "UpdateOrganizationMembership", + "service": "user_management" + }, + "DELETE /user_management/organization_memberships/{id}": { + "sdkMethod": "DeleteOrganizationMembership", + "service": "user_management" + }, + "PUT /user_management/organization_memberships/{id}/deactivate": { + "sdkMethod": "DeactivateOrganizationMembership", + "service": "user_management" + }, + "PUT /user_management/organization_memberships/{id}/reactivate": { + "sdkMethod": "ReactivateOrganizationMembership", + "service": "user_management" + }, + "GET /user_management/organization_memberships/{omId}/groups": { + "sdkMethod": "ListOrganizationMembershipGroups", + "service": "user_management_organization_membership_groups" + }, + "POST /user_management/redirect_uris": { + "sdkMethod": "CreateRedirectURI", + "service": "user_management" + }, + "GET /user_management/users/{userId}/feature-flags": { + "sdkMethod": "ListUserFeatureFlags", + "service": "feature_flags" + }, + "GET /user_management/users/{user_id}/authorized_applications": { + "sdkMethod": "ListAuthorizedApplications", + "service": "user_management" + }, + "DELETE /user_management/users/{user_id}/authorized_applications/{application_id}": { + "sdkMethod": "DeleteAuthorizedApplication", + "service": "user_management" + }, + "GET /user_management/users/{user_id}/connected_accounts/{slug}": { + "sdkMethod": "GetUserConnectedAccount", + "service": "pipes" + }, + "DELETE /user_management/users/{user_id}/connected_accounts/{slug}": { + "sdkMethod": "DeleteUserConnectedAccount", + "service": "pipes" + }, + "GET /user_management/users/{user_id}/data_providers": { + "sdkMethod": "ListUserDataProviders", + "service": "pipes" + }, + "GET /user_management/users/{userlandUserId}/auth_factors": { + "sdkMethod": "ListUserAuthFactors", + "service": "multi_factor_auth" + }, + "POST /user_management/users/{userlandUserId}/auth_factors": { + "sdkMethod": "CreateUserAuthFactor", + "service": "multi_factor_auth" + }, + "GET /webhook_endpoints": { + "sdkMethod": "ListEndpoints", + "service": "webhooks" + }, + "POST /webhook_endpoints": { + "sdkMethod": "CreateEndpoint", + "service": "webhooks" + }, + "PATCH /webhook_endpoints/{id}": { + "sdkMethod": "UpdateEndpoint", + "service": "webhooks" + }, + "DELETE /webhook_endpoints/{id}": { + "sdkMethod": "DeleteEndpoint", + "service": "webhooks" + }, + "POST /widgets/token": { + "sdkMethod": "CreateToken", + "service": "widgets" + }, + "GET /audit_logs/actions": { + "sdkMethod": "ListActions", + "service": "audit_logs" + }, + "GET /audit_logs/actions/{actionName}/schemas": { + "sdkMethod": "ListActionSchemas", + "service": "audit_logs" + }, + "POST /audit_logs/actions/{actionName}/schemas": { + "sdkMethod": "CreateSchema", + "service": "audit_logs" + }, + "POST /audit_logs/events": { + "sdkMethod": "CreateEvent", + "service": "audit_logs" + }, + "POST /audit_logs/exports": { + "sdkMethod": "CreateExport", + "service": "audit_logs" + }, + "GET /audit_logs/exports/{auditLogExportId}": { + "sdkMethod": "GetExport", + "service": "audit_logs" + } + } } diff --git a/admin_portal.go b/admin_portal.go index 3bfd29a2..f4666771 100644 --- a/admin_portal.go +++ b/admin_portal.go @@ -30,8 +30,8 @@ type AdminPortalGenerateLinkParams struct { Intent *GenerateLinkIntent `json:"intent,omitempty"` // IntentOptions is options to configure the Admin Portal based on the intent. IntentOptions *IntentOptions `json:"intent_options,omitempty"` - // AdminEmails is the email addresses of the IT admins to grant access to the Admin Portal for the given organization. Accepts up to 20 emails. - AdminEmails []string `json:"admin_emails,omitempty"` + // ItContactEmails is the email addresses of the IT contacts to grant access to the Admin Portal for the given organization. Accepts up to 20 emails. + ItContactEmails []string `json:"it_contact_emails,omitempty"` } // GenerateLink generate a Portal Link diff --git a/authorization.go b/authorization.go index 86a379af..3e3ca251 100644 --- a/authorization.go +++ b/authorization.go @@ -145,8 +145,8 @@ func (s *AuthorizationService) Check(ctx context.Context, organizationMembership return &result, nil } -// AuthorizationListOrganizationMembershipResourcesParams contains the parameters for ListOrganizationMembershipResources. -type AuthorizationListOrganizationMembershipResourcesParams struct { +// AuthorizationListResourcesForMembershipParams contains the parameters for ListResourcesForMembership. +type AuthorizationListResourcesForMembershipParams struct { PaginationParams // PermissionSlug is the permission slug to filter by. Only child resources where the organization membership has this permission are returned. PermissionSlug string `url:"permission_slug" json:"-"` @@ -154,10 +154,10 @@ type AuthorizationListOrganizationMembershipResourcesParams struct { ParentResource AuthorizationParentResource `url:"-" json:"-"` } -// ListOrganizationMembershipResources list resources for organization membership +// ListResourcesForMembership list resources for organization membership // Returns all child resources of a parent resource where the organization membership has a specific permission. This is useful for resource discovery—answering "What projects can this user access in this workspace?" // You must provide either `parent_resource_id` or both `parent_resource_external_id` and `parent_resource_type_slug` to identify the parent resource. -func (s *AuthorizationService) ListOrganizationMembershipResources(ctx context.Context, organizationMembershipID string, params *AuthorizationListOrganizationMembershipResourcesParams, opts ...RequestOption) *Iterator[AuthorizationResource] { +func (s *AuthorizationService) ListResourcesForMembership(ctx context.Context, organizationMembershipID string, params *AuthorizationListResourcesForMembershipParams, opts ...RequestOption) *Iterator[AuthorizationResource] { query := url.Values{} if params.Before != nil { query.Set("before", *params.Before) @@ -178,14 +178,14 @@ func (s *AuthorizationService) ListOrganizationMembershipResources(ctx context.C return newIterator[AuthorizationResource](ctx, s.client, "GET", fmt.Sprintf("/authorization/organization_memberships/%s/resources", url.PathEscape(organizationMembershipID)), query, "after", "data", opts, map[string]string{"limit": "10", "order": "desc"}) } -// AuthorizationListResourcePermissionsParams contains the parameters for ListResourcePermissions. -type AuthorizationListResourcePermissionsParams struct { +// AuthorizationListEffectivePermissionsParams contains the parameters for ListEffectivePermissions. +type AuthorizationListEffectivePermissionsParams struct { PaginationParams } -// ListResourcePermissions list effective permissions for an organization membership on a resource +// ListEffectivePermissions for an organization membership on a resource // Returns all permissions the organization membership effectively has on a resource, including permissions inherited through roles assigned to ancestor resources. -func (s *AuthorizationService) ListResourcePermissions(ctx context.Context, organizationMembershipID string, resourceID string, params *AuthorizationListResourcePermissionsParams, opts ...RequestOption) *Iterator[AuthorizationPermission] { +func (s *AuthorizationService) ListEffectivePermissions(ctx context.Context, organizationMembershipID string, resourceID string, params *AuthorizationListEffectivePermissionsParams, opts ...RequestOption) *Iterator[AuthorizationPermission] { return newIterator[AuthorizationPermission](ctx, s.client, "GET", fmt.Sprintf("/authorization/organization_memberships/%s/resources/%s/permissions", url.PathEscape(organizationMembershipID), url.PathEscape(resourceID)), params, "after", "data", opts, map[string]string{"limit": "10", "order": "desc"}) } @@ -200,14 +200,14 @@ func (s *AuthorizationService) ListEffectivePermissionsByExternalID(ctx context. return newIterator[AuthorizationPermission](ctx, s.client, "GET", fmt.Sprintf("/authorization/organization_memberships/%s/resources/%s/%s/permissions", url.PathEscape(organizationMembershipID), url.PathEscape(resourceTypeSlug), url.PathEscape(externalID)), params, "after", "data", opts, map[string]string{"limit": "10", "order": "desc"}) } -// AuthorizationListOrganizationMembershipRoleAssignmentsParams contains the parameters for ListOrganizationMembershipRoleAssignments. -type AuthorizationListOrganizationMembershipRoleAssignmentsParams struct { +// AuthorizationListRoleAssignmentsParams contains the parameters for ListRoleAssignments. +type AuthorizationListRoleAssignmentsParams struct { PaginationParams } -// ListOrganizationMembershipRoleAssignments list role assignments +// ListRoleAssignments // List all role assignments for an organization membership. This returns all roles that have been assigned to the user on resources, including organization-level and sub-resource roles. -func (s *AuthorizationService) ListOrganizationMembershipRoleAssignments(ctx context.Context, organizationMembershipID string, params *AuthorizationListOrganizationMembershipRoleAssignmentsParams, opts ...RequestOption) *Iterator[RoleAssignment] { +func (s *AuthorizationService) ListRoleAssignments(ctx context.Context, organizationMembershipID string, params *AuthorizationListRoleAssignmentsParams, opts ...RequestOption) *Iterator[RoleAssignment] { return newIterator[RoleAssignment](ctx, s.client, "GET", fmt.Sprintf("/authorization/organization_memberships/%s/role_assignments", url.PathEscape(organizationMembershipID)), params, "after", "data", opts, map[string]string{"limit": "10", "order": "desc"}) } @@ -285,9 +285,9 @@ func (s *AuthorizationService) RemoveRole(ctx context.Context, organizationMembe return err } -// DeleteOrganizationMembershipRoleAssignment remove a role assignment by ID +// RemoveRoleAssignment remove a role assignment by ID // Remove a role assignment using its ID. -func (s *AuthorizationService) DeleteOrganizationMembershipRoleAssignment(ctx context.Context, organizationMembershipID string, roleAssignmentID string, opts ...RequestOption) error { +func (s *AuthorizationService) RemoveRoleAssignment(ctx context.Context, organizationMembershipID string, roleAssignmentID string, opts ...RequestOption) error { _, err := s.client.request(ctx, "DELETE", fmt.Sprintf("/authorization/organization_memberships/%s/role_assignments/%s", url.PathEscape(organizationMembershipID), url.PathEscape(roleAssignmentID)), nil, nil, nil, opts) return err } @@ -363,15 +363,15 @@ func (s *AuthorizationService) DeleteOrganizationRole(ctx context.Context, organ return err } -// AuthorizationCreateRolePermissionParams contains the parameters for CreateRolePermission. -type AuthorizationCreateRolePermissionParams struct { +// AuthorizationAddOrganizationRolePermissionParams contains the parameters for AddOrganizationRolePermission. +type AuthorizationAddOrganizationRolePermissionParams struct { // Slug is the slug of the permission to add to the role. Slug string `json:"slug"` } -// CreateRolePermission add a permission to a custom role +// AddOrganizationRolePermission add a permission to a custom role // Add a single permission to a custom role. If the permission is already assigned to the role, this operation has no effect. -func (s *AuthorizationService) CreateRolePermission(ctx context.Context, organizationID string, slug string, params *AuthorizationCreateRolePermissionParams, opts ...RequestOption) (*Role, error) { +func (s *AuthorizationService) AddOrganizationRolePermission(ctx context.Context, organizationID string, slug string, params *AuthorizationAddOrganizationRolePermissionParams, opts ...RequestOption) (*Role, error) { var result Role _, err := s.client.request(ctx, "POST", fmt.Sprintf("/authorization/organizations/%s/roles/%s/permissions", url.PathEscape(organizationID), url.PathEscape(slug)), nil, params, &result, opts) if err != nil { @@ -380,15 +380,15 @@ func (s *AuthorizationService) CreateRolePermission(ctx context.Context, organiz return &result, nil } -// AuthorizationUpdateRolePermissionsParams contains the parameters for UpdateRolePermissions. -type AuthorizationUpdateRolePermissionsParams struct { +// AuthorizationSetOrganizationRolePermissionsParams contains the parameters for SetOrganizationRolePermissions. +type AuthorizationSetOrganizationRolePermissionsParams struct { // Permissions is the permission slugs to assign to the role. Permissions []string `json:"permissions"` } -// UpdateRolePermissions set permissions for a custom role +// SetOrganizationRolePermissions set permissions for a custom role // Replace all permissions on a custom role with the provided list. -func (s *AuthorizationService) UpdateRolePermissions(ctx context.Context, organizationID string, slug string, params *AuthorizationUpdateRolePermissionsParams, opts ...RequestOption) (*Role, error) { +func (s *AuthorizationService) SetOrganizationRolePermissions(ctx context.Context, organizationID string, slug string, params *AuthorizationSetOrganizationRolePermissionsParams, opts ...RequestOption) (*Role, error) { var result Role _, err := s.client.request(ctx, "PUT", fmt.Sprintf("/authorization/organizations/%s/roles/%s/permissions", url.PathEscape(organizationID), url.PathEscape(slug)), nil, params, &result, opts) if err != nil { @@ -397,16 +397,16 @@ func (s *AuthorizationService) UpdateRolePermissions(ctx context.Context, organi return &result, nil } -// DeleteRolePermission remove a permission from a custom role +// RemoveOrganizationRolePermission remove a permission from a custom role // Remove a single permission from a custom role by its slug. -func (s *AuthorizationService) DeleteRolePermission(ctx context.Context, organizationID string, slug string, permissionSlug string, opts ...RequestOption) error { +func (s *AuthorizationService) RemoveOrganizationRolePermission(ctx context.Context, organizationID string, slug string, permissionSlug string, opts ...RequestOption) error { _, err := s.client.request(ctx, "DELETE", fmt.Sprintf("/authorization/organizations/%s/roles/%s/permissions/%s", url.PathEscape(organizationID), url.PathEscape(slug), url.PathEscape(permissionSlug)), nil, nil, nil, opts) return err } -// GetOrganizationResource get a resource by external ID +// GetResourceByExternalID get a resource by external ID // Retrieve the details of an authorization resource by its external ID, organization, and resource type. This is useful when you only have the external ID from your system and need to fetch the full resource details. -func (s *AuthorizationService) GetOrganizationResource(ctx context.Context, organizationID string, resourceTypeSlug string, externalID string, opts ...RequestOption) (*AuthorizationResource, error) { +func (s *AuthorizationService) GetResourceByExternalID(ctx context.Context, organizationID string, resourceTypeSlug string, externalID string, opts ...RequestOption) (*AuthorizationResource, error) { var result AuthorizationResource _, err := s.client.request(ctx, "GET", fmt.Sprintf("/authorization/organizations/%s/resources/%s/%s", url.PathEscape(organizationID), url.PathEscape(resourceTypeSlug), url.PathEscape(externalID)), nil, nil, &result, opts) if err != nil { @@ -415,8 +415,8 @@ func (s *AuthorizationService) GetOrganizationResource(ctx context.Context, orga return &result, nil } -// AuthorizationUpdateOrganizationResourceParams contains the parameters for UpdateOrganizationResource. -type AuthorizationUpdateOrganizationResourceParams struct { +// AuthorizationUpdateResourceByExternalIDParams contains the parameters for UpdateResourceByExternalID. +type AuthorizationUpdateResourceByExternalIDParams struct { // Name is a display name for the resource. Name *string `json:"name,omitempty"` // Description is an optional description of the resource. @@ -425,9 +425,9 @@ type AuthorizationUpdateOrganizationResourceParams struct { ParentResource AuthorizationParentResource `url:"-" json:"-"` } -// MarshalJSON implements json.Marshaler for AuthorizationUpdateOrganizationResourceParams. -func (p AuthorizationUpdateOrganizationResourceParams) MarshalJSON() ([]byte, error) { - type Alias AuthorizationUpdateOrganizationResourceParams +// MarshalJSON implements json.Marshaler for AuthorizationUpdateResourceByExternalIDParams. +func (p AuthorizationUpdateResourceByExternalIDParams) MarshalJSON() ([]byte, error) { + type Alias AuthorizationUpdateResourceByExternalIDParams data, err := json.Marshal(Alias(p)) if err != nil { return nil, err @@ -445,9 +445,9 @@ func (p AuthorizationUpdateOrganizationResourceParams) MarshalJSON() ([]byte, er return json.Marshal(m) } -// UpdateOrganizationResource update a resource by external ID +// UpdateResourceByExternalID update a resource by external ID // Update an existing authorization resource using its external ID. -func (s *AuthorizationService) UpdateOrganizationResource(ctx context.Context, organizationID string, resourceTypeSlug string, externalID string, params *AuthorizationUpdateOrganizationResourceParams, opts ...RequestOption) (*AuthorizationResource, error) { +func (s *AuthorizationService) UpdateResourceByExternalID(ctx context.Context, organizationID string, resourceTypeSlug string, externalID string, params *AuthorizationUpdateResourceByExternalIDParams, opts ...RequestOption) (*AuthorizationResource, error) { var result AuthorizationResource _, err := s.client.request(ctx, "PATCH", fmt.Sprintf("/authorization/organizations/%s/resources/%s/%s", url.PathEscape(organizationID), url.PathEscape(resourceTypeSlug), url.PathEscape(externalID)), nil, params, &result, opts) if err != nil { @@ -456,22 +456,22 @@ func (s *AuthorizationService) UpdateOrganizationResource(ctx context.Context, o return &result, nil } -// AuthorizationDeleteOrganizationResourceParams contains the parameters for DeleteOrganizationResource. -type AuthorizationDeleteOrganizationResourceParams struct { +// AuthorizationDeleteResourceByExternalIDParams contains the parameters for DeleteResourceByExternalID. +type AuthorizationDeleteResourceByExternalIDParams struct { // CascadeDelete is if true, deletes all descendant resources and role assignments. If not set and the resource has children or assignments, the request will fail. // Defaults to false. CascadeDelete *bool `url:"cascade_delete,omitempty" json:"-"` } -// DeleteOrganizationResource delete an authorization resource by external ID +// DeleteResourceByExternalID delete an authorization resource by external ID // Delete an authorization resource by organization, resource type, and external ID. This also deletes all descendant resources. -func (s *AuthorizationService) DeleteOrganizationResource(ctx context.Context, organizationID string, resourceTypeSlug string, externalID string, params *AuthorizationDeleteOrganizationResourceParams, opts ...RequestOption) error { +func (s *AuthorizationService) DeleteResourceByExternalID(ctx context.Context, organizationID string, resourceTypeSlug string, externalID string, params *AuthorizationDeleteResourceByExternalIDParams, opts ...RequestOption) error { _, err := s.client.request(ctx, "DELETE", fmt.Sprintf("/authorization/organizations/%s/resources/%s/%s", url.PathEscape(organizationID), url.PathEscape(resourceTypeSlug), url.PathEscape(externalID)), params, nil, nil, opts) return err } -// AuthorizationListResourceOrganizationMembershipsParams contains the parameters for ListResourceOrganizationMemberships. -type AuthorizationListResourceOrganizationMembershipsParams struct { +// AuthorizationListMembershipsForResourceByExternalIDParams contains the parameters for ListMembershipsForResourceByExternalID. +type AuthorizationListMembershipsForResourceByExternalIDParams struct { PaginationParams // PermissionSlug is the permission slug to filter by. Only users with this permission on the resource are returned. PermissionSlug string `url:"permission_slug" json:"-"` @@ -479,9 +479,9 @@ type AuthorizationListResourceOrganizationMembershipsParams struct { Assignment *AuthorizationAssignment `url:"assignment,omitempty" json:"-"` } -// ListResourceOrganizationMemberships list memberships for a resource by external ID +// ListMembershipsForResourceByExternalID list memberships for a resource by external ID // Returns all organization memberships that have a specific permission on a resource, using the resource's external ID. This is useful for answering "Who can access this resource?" when you only have the external ID. -func (s *AuthorizationService) ListResourceOrganizationMemberships(ctx context.Context, organizationID string, resourceTypeSlug string, externalID string, params *AuthorizationListResourceOrganizationMembershipsParams, opts ...RequestOption) *Iterator[UserOrganizationMembershipBaseListData] { +func (s *AuthorizationService) ListMembershipsForResourceByExternalID(ctx context.Context, organizationID string, resourceTypeSlug string, externalID string, params *AuthorizationListMembershipsForResourceByExternalIDParams, opts ...RequestOption) *Iterator[UserOrganizationMembershipBaseListData] { return newIterator[UserOrganizationMembershipBaseListData](ctx, s.client, "GET", fmt.Sprintf("/authorization/organizations/%s/resources/%s/%s/organization_memberships", url.PathEscape(organizationID), url.PathEscape(resourceTypeSlug), url.PathEscape(externalID)), params, "after", "data", opts, map[string]string{"limit": "10", "order": "desc"}) } @@ -492,6 +492,8 @@ type AuthorizationListResourcesParams struct { OrganizationID *string `url:"organization_id,omitempty" json:"-"` // ResourceTypeSlug is filter resources by resource type slug. ResourceTypeSlug *string `url:"resource_type_slug,omitempty" json:"-"` + // ResourceExternalID is filter resources by external ID. + ResourceExternalID *string `url:"resource_external_id,omitempty" json:"-"` // Search is search resources by name. Search *string `url:"search,omitempty" json:"-"` // Parent optionally identifies the parent. @@ -520,6 +522,9 @@ func (s *AuthorizationService) ListResources(ctx context.Context, params *Author if params.ResourceTypeSlug != nil { query.Set("resource_type_slug", *params.ResourceTypeSlug) } + if params.ResourceExternalID != nil { + query.Set("resource_external_id", *params.ResourceExternalID) + } if params.Search != nil { query.Set("search", *params.Search) } diff --git a/authorization_test.go b/authorization_test.go index 11b61b86..c42fcd25 100644 --- a/authorization_test.go +++ b/authorization_test.go @@ -38,7 +38,7 @@ func TestAuthorization_Check(t *testing.T) { require.NotNil(t, result) } -func TestAuthorization_ListOrganizationMembershipResources(t *testing.T) { +func TestAuthorization_ListResourcesForMembership(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "GET", r.Method) require.Equal(t, "/authorization/organization_memberships/test_organization_membership_id/resources", r.URL.Path) @@ -54,7 +54,7 @@ func TestAuthorization_ListOrganizationMembershipResources(t *testing.T) { defer server.Close() client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) - iter := client.Authorization().ListOrganizationMembershipResources(context.Background(), "test_organization_membership_id", &workos.AuthorizationListOrganizationMembershipResourcesParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) + iter := client.Authorization().ListResourcesForMembership(context.Background(), "test_organization_membership_id", &workos.AuthorizationListResourcesForMembershipParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) require.NotNil(t, iter) require.True(t, iter.Next()) require.NoError(t, iter.Err()) @@ -62,7 +62,7 @@ func TestAuthorization_ListOrganizationMembershipResources(t *testing.T) { require.NotNil(t, item) } -func TestAuthorization_ListOrganizationMembershipResources_Empty(t *testing.T) { +func TestAuthorization_ListResourcesForMembership_Empty(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -71,12 +71,12 @@ func TestAuthorization_ListOrganizationMembershipResources_Empty(t *testing.T) { defer server.Close() client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) - iter := client.Authorization().ListOrganizationMembershipResources(context.Background(), "test_organization_membership_id", &workos.AuthorizationListOrganizationMembershipResourcesParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) + iter := client.Authorization().ListResourcesForMembership(context.Background(), "test_organization_membership_id", &workos.AuthorizationListResourcesForMembershipParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) require.False(t, iter.Next()) require.NoError(t, iter.Err()) } -func TestAuthorization_ListResourcePermissions(t *testing.T) { +func TestAuthorization_ListEffectivePermissions(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "GET", r.Method) require.Equal(t, "/authorization/organization_memberships/test_organization_membership_id/resources/test_resource_id/permissions", r.URL.Path) @@ -92,7 +92,7 @@ func TestAuthorization_ListResourcePermissions(t *testing.T) { defer server.Close() client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) - iter := client.Authorization().ListResourcePermissions(context.Background(), "test_organization_membership_id", "test_resource_id", &workos.AuthorizationListResourcePermissionsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) + iter := client.Authorization().ListEffectivePermissions(context.Background(), "test_organization_membership_id", "test_resource_id", &workos.AuthorizationListEffectivePermissionsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) require.NotNil(t, iter) require.True(t, iter.Next()) require.NoError(t, iter.Err()) @@ -100,7 +100,7 @@ func TestAuthorization_ListResourcePermissions(t *testing.T) { require.NotNil(t, item) } -func TestAuthorization_ListResourcePermissions_Empty(t *testing.T) { +func TestAuthorization_ListEffectivePermissions_Empty(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -109,7 +109,7 @@ func TestAuthorization_ListResourcePermissions_Empty(t *testing.T) { defer server.Close() client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) - iter := client.Authorization().ListResourcePermissions(context.Background(), "test_organization_membership_id", "test_resource_id", &workos.AuthorizationListResourcePermissionsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) + iter := client.Authorization().ListEffectivePermissions(context.Background(), "test_organization_membership_id", "test_resource_id", &workos.AuthorizationListEffectivePermissionsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) require.False(t, iter.Next()) require.NoError(t, iter.Err()) } @@ -152,7 +152,7 @@ func TestAuthorization_ListEffectivePermissionsByExternalID_Empty(t *testing.T) require.NoError(t, iter.Err()) } -func TestAuthorization_ListOrganizationMembershipRoleAssignments(t *testing.T) { +func TestAuthorization_ListRoleAssignments(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "GET", r.Method) require.Equal(t, "/authorization/organization_memberships/test_organization_membership_id/role_assignments", r.URL.Path) @@ -168,7 +168,7 @@ func TestAuthorization_ListOrganizationMembershipRoleAssignments(t *testing.T) { defer server.Close() client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) - iter := client.Authorization().ListOrganizationMembershipRoleAssignments(context.Background(), "test_organization_membership_id", &workos.AuthorizationListOrganizationMembershipRoleAssignmentsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) + iter := client.Authorization().ListRoleAssignments(context.Background(), "test_organization_membership_id", &workos.AuthorizationListRoleAssignmentsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) require.NotNil(t, iter) require.True(t, iter.Next()) require.NoError(t, iter.Err()) @@ -176,7 +176,7 @@ func TestAuthorization_ListOrganizationMembershipRoleAssignments(t *testing.T) { require.NotNil(t, item) } -func TestAuthorization_ListOrganizationMembershipRoleAssignments_Empty(t *testing.T) { +func TestAuthorization_ListRoleAssignments_Empty(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -185,7 +185,7 @@ func TestAuthorization_ListOrganizationMembershipRoleAssignments_Empty(t *testin defer server.Close() client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) - iter := client.Authorization().ListOrganizationMembershipRoleAssignments(context.Background(), "test_organization_membership_id", &workos.AuthorizationListOrganizationMembershipRoleAssignmentsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) + iter := client.Authorization().ListRoleAssignments(context.Background(), "test_organization_membership_id", &workos.AuthorizationListRoleAssignmentsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) require.False(t, iter.Next()) require.NoError(t, iter.Err()) } @@ -229,7 +229,7 @@ func TestAuthorization_RemoveRole(t *testing.T) { require.NoError(t, err) } -func TestAuthorization_DeleteOrganizationMembershipRoleAssignment(t *testing.T) { +func TestAuthorization_RemoveRoleAssignment(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "DELETE", r.Method) require.Equal(t, "/authorization/organization_memberships/test_organization_membership_id/role_assignments/test_role_assignment_id", r.URL.Path) @@ -238,7 +238,7 @@ func TestAuthorization_DeleteOrganizationMembershipRoleAssignment(t *testing.T) defer server.Close() client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) - err := client.Authorization().DeleteOrganizationMembershipRoleAssignment(context.Background(), "test_organization_membership_id", "test_role_assignment_id") + err := client.Authorization().RemoveRoleAssignment(context.Background(), "test_organization_membership_id", "test_role_assignment_id") require.NoError(t, err) } @@ -350,7 +350,7 @@ func TestAuthorization_DeleteOrganizationRole(t *testing.T) { require.NoError(t, err) } -func TestAuthorization_CreateRolePermission(t *testing.T) { +func TestAuthorization_AddOrganizationRolePermission(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "POST", r.Method) require.Equal(t, "/authorization/organizations/test_organizationId/roles/test_slug/permissions", r.URL.Path) @@ -368,7 +368,7 @@ func TestAuthorization_CreateRolePermission(t *testing.T) { defer server.Close() client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) - result, err := client.Authorization().CreateRolePermission(context.Background(), "test_organizationId", "test_slug", &workos.AuthorizationCreateRolePermissionParams{}) + result, err := client.Authorization().AddOrganizationRolePermission(context.Background(), "test_organizationId", "test_slug", &workos.AuthorizationAddOrganizationRolePermissionParams{}) require.NoError(t, err) require.NotNil(t, result) require.Equal(t, "role_01EHQMYV6MBK39QC5PZXHY59C3", result.ID) @@ -376,7 +376,7 @@ func TestAuthorization_CreateRolePermission(t *testing.T) { require.Equal(t, "Admin", result.Name) } -func TestAuthorization_UpdateRolePermissions(t *testing.T) { +func TestAuthorization_SetOrganizationRolePermissions(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "PUT", r.Method) require.Equal(t, "/authorization/organizations/test_organizationId/roles/test_slug/permissions", r.URL.Path) @@ -394,7 +394,7 @@ func TestAuthorization_UpdateRolePermissions(t *testing.T) { defer server.Close() client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) - result, err := client.Authorization().UpdateRolePermissions(context.Background(), "test_organizationId", "test_slug", &workos.AuthorizationUpdateRolePermissionsParams{}) + result, err := client.Authorization().SetOrganizationRolePermissions(context.Background(), "test_organizationId", "test_slug", &workos.AuthorizationSetOrganizationRolePermissionsParams{}) require.NoError(t, err) require.NotNil(t, result) require.Equal(t, "role_01EHQMYV6MBK39QC5PZXHY59C3", result.ID) @@ -402,7 +402,7 @@ func TestAuthorization_UpdateRolePermissions(t *testing.T) { require.Equal(t, "Admin", result.Name) } -func TestAuthorization_DeleteRolePermission(t *testing.T) { +func TestAuthorization_RemoveOrganizationRolePermission(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "DELETE", r.Method) require.Equal(t, "/authorization/organizations/test_organizationId/roles/test_slug/permissions/test_permissionSlug", r.URL.Path) @@ -411,11 +411,11 @@ func TestAuthorization_DeleteRolePermission(t *testing.T) { defer server.Close() client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) - err := client.Authorization().DeleteRolePermission(context.Background(), "test_organizationId", "test_slug", "test_permissionSlug") + err := client.Authorization().RemoveOrganizationRolePermission(context.Background(), "test_organizationId", "test_slug", "test_permissionSlug") require.NoError(t, err) } -func TestAuthorization_GetOrganizationResource(t *testing.T) { +func TestAuthorization_GetResourceByExternalID(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "GET", r.Method) require.Equal(t, "/authorization/organizations/test_organization_id/resources/test_resource_type_slug/test_external_id", r.URL.Path) @@ -430,7 +430,7 @@ func TestAuthorization_GetOrganizationResource(t *testing.T) { defer server.Close() client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) - result, err := client.Authorization().GetOrganizationResource(context.Background(), "test_organization_id", "test_resource_type_slug", "test_external_id") + result, err := client.Authorization().GetResourceByExternalID(context.Background(), "test_organization_id", "test_resource_type_slug", "test_external_id") require.NoError(t, err) require.NotNil(t, result) require.Equal(t, "authz_resource_01HXYZ123456789ABCDEFGH", result.ID) @@ -438,7 +438,7 @@ func TestAuthorization_GetOrganizationResource(t *testing.T) { require.Equal(t, "org_01EHZNVPK3SFK441A1RGBFSHRT", result.OrganizationID) } -func TestAuthorization_UpdateOrganizationResource(t *testing.T) { +func TestAuthorization_UpdateResourceByExternalID(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "PATCH", r.Method) require.Equal(t, "/authorization/organizations/test_organization_id/resources/test_resource_type_slug/test_external_id", r.URL.Path) @@ -456,7 +456,7 @@ func TestAuthorization_UpdateOrganizationResource(t *testing.T) { defer server.Close() client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) - result, err := client.Authorization().UpdateOrganizationResource(context.Background(), "test_organization_id", "test_resource_type_slug", "test_external_id", &workos.AuthorizationUpdateOrganizationResourceParams{}) + result, err := client.Authorization().UpdateResourceByExternalID(context.Background(), "test_organization_id", "test_resource_type_slug", "test_external_id", &workos.AuthorizationUpdateResourceByExternalIDParams{}) require.NoError(t, err) require.NotNil(t, result) require.Equal(t, "authz_resource_01HXYZ123456789ABCDEFGH", result.ID) @@ -464,7 +464,7 @@ func TestAuthorization_UpdateOrganizationResource(t *testing.T) { require.Equal(t, "org_01EHZNVPK3SFK441A1RGBFSHRT", result.OrganizationID) } -func TestAuthorization_DeleteOrganizationResource(t *testing.T) { +func TestAuthorization_DeleteResourceByExternalID(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "DELETE", r.Method) require.Equal(t, "/authorization/organizations/test_organization_id/resources/test_resource_type_slug/test_external_id", r.URL.Path) @@ -473,11 +473,11 @@ func TestAuthorization_DeleteOrganizationResource(t *testing.T) { defer server.Close() client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) - err := client.Authorization().DeleteOrganizationResource(context.Background(), "test_organization_id", "test_resource_type_slug", "test_external_id", &workos.AuthorizationDeleteOrganizationResourceParams{}) + err := client.Authorization().DeleteResourceByExternalID(context.Background(), "test_organization_id", "test_resource_type_slug", "test_external_id", &workos.AuthorizationDeleteResourceByExternalIDParams{}) require.NoError(t, err) } -func TestAuthorization_ListResourceOrganizationMemberships(t *testing.T) { +func TestAuthorization_ListMembershipsForResourceByExternalID(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "GET", r.Method) require.Equal(t, "/authorization/organizations/test_organization_id/resources/test_resource_type_slug/test_external_id/organization_memberships", r.URL.Path) @@ -493,7 +493,7 @@ func TestAuthorization_ListResourceOrganizationMemberships(t *testing.T) { defer server.Close() client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) - iter := client.Authorization().ListResourceOrganizationMemberships(context.Background(), "test_organization_id", "test_resource_type_slug", "test_external_id", &workos.AuthorizationListResourceOrganizationMembershipsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) + iter := client.Authorization().ListMembershipsForResourceByExternalID(context.Background(), "test_organization_id", "test_resource_type_slug", "test_external_id", &workos.AuthorizationListMembershipsForResourceByExternalIDParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) require.NotNil(t, iter) require.True(t, iter.Next()) require.NoError(t, iter.Err()) @@ -501,7 +501,7 @@ func TestAuthorization_ListResourceOrganizationMemberships(t *testing.T) { require.NotNil(t, item) } -func TestAuthorization_ListResourceOrganizationMemberships_Empty(t *testing.T) { +func TestAuthorization_ListMembershipsForResourceByExternalID_Empty(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -510,7 +510,7 @@ func TestAuthorization_ListResourceOrganizationMemberships_Empty(t *testing.T) { defer server.Close() client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) - iter := client.Authorization().ListResourceOrganizationMemberships(context.Background(), "test_organization_id", "test_resource_type_slug", "test_external_id", &workos.AuthorizationListResourceOrganizationMembershipsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) + iter := client.Authorization().ListMembershipsForResourceByExternalID(context.Background(), "test_organization_id", "test_resource_type_slug", "test_external_id", &workos.AuthorizationListMembershipsForResourceByExternalIDParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) require.False(t, iter.Next()) require.NoError(t, iter.Err()) } diff --git a/enums.go b/enums.go index cfdaf375..d9ee13cb 100644 --- a/enums.go +++ b/enums.go @@ -215,6 +215,9 @@ const ( CreateWebhookEndpointEventsPermissionUpdated CreateWebhookEndpointEvents = "permission.updated" CreateWebhookEndpointEventsSessionCreated CreateWebhookEndpointEvents = "session.created" CreateWebhookEndpointEventsSessionRevoked CreateWebhookEndpointEvents = "session.revoked" + CreateWebhookEndpointEventsWaitlistUserApproved CreateWebhookEndpointEvents = "waitlist_user.approved" + CreateWebhookEndpointEventsWaitlistUserCreated CreateWebhookEndpointEvents = "waitlist_user.created" + CreateWebhookEndpointEventsWaitlistUserDenied CreateWebhookEndpointEvents = "waitlist_user.denied" ) // UpdateWebhookEndpointStatus represents update webhook endpoint status values. @@ -401,6 +404,15 @@ const ( DirectoryUserStateInactive DirectoryUserState = "inactive" ) +// WaitlistUserState represents waitlist user state values. +type WaitlistUserState string + +const ( + WaitlistUserStatePending WaitlistUserState = "pending" + WaitlistUserStateApproved WaitlistUserState = "approved" + WaitlistUserStateDenied WaitlistUserState = "denied" +) + // AuthenticationRadarRiskDetectedDataAction represents authentication radar risk detected data action values. type AuthenticationRadarRiskDetectedDataAction string @@ -1090,6 +1102,9 @@ type OrganizationsAPIKeysOrder = ApplicationsOrder // OrganizationsFeatureFlagsOrder is an alias for ApplicationsOrder. type OrganizationsFeatureFlagsOrder = ApplicationsOrder +// GroupsOrder is an alias for ApplicationsOrder. +type GroupsOrder = ApplicationsOrder + // RadarType is an alias for RadarStandaloneResponseBlocklistType. type RadarType = RadarStandaloneResponseBlocklistType @@ -1105,10 +1120,19 @@ const ( type SSOProvider string const ( - SSOProviderAppleOAuth SSOProvider = "AppleOAuth" - SSOProviderGitHubOAuth SSOProvider = "GitHubOAuth" - SSOProviderGoogleOAuth SSOProvider = "GoogleOAuth" - SSOProviderMicrosoftOAuth SSOProvider = "MicrosoftOAuth" + SSOProviderAppleOAuth SSOProvider = "AppleOAuth" + SSOProviderBitbucketOAuth SSOProvider = "BitbucketOAuth" + SSOProviderGitHubOAuth SSOProvider = "GitHubOAuth" + SSOProviderGitLabOAuth SSOProvider = "GitLabOAuth" + SSOProviderGoogleOAuth SSOProvider = "GoogleOAuth" + SSOProviderIntuitOAuth SSOProvider = "IntuitOAuth" + SSOProviderLinkedInOAuth SSOProvider = "LinkedInOAuth" + SSOProviderMicrosoftOAuth SSOProvider = "MicrosoftOAuth" + SSOProviderSalesforceOAuth SSOProvider = "SalesforceOAuth" + SSOProviderSlackOAuth SSOProvider = "SlackOAuth" + SSOProviderVercelMarketplaceOAuth SSOProvider = "VercelMarketplaceOAuth" + SSOProviderVercelOAuth SSOProvider = "VercelOAuth" + SSOProviderXeroOAuth SSOProvider = "XeroOAuth" ) // UserManagementAuthenticationScreenHint represents user management authentication screen hint values. @@ -1123,11 +1147,20 @@ const ( type UserManagementAuthenticationProvider string const ( - UserManagementAuthenticationProviderAuthkit UserManagementAuthenticationProvider = "authkit" - UserManagementAuthenticationProviderAppleOAuth UserManagementAuthenticationProvider = "AppleOAuth" - UserManagementAuthenticationProviderGitHubOAuth UserManagementAuthenticationProvider = "GitHubOAuth" - UserManagementAuthenticationProviderGoogleOAuth UserManagementAuthenticationProvider = "GoogleOAuth" - UserManagementAuthenticationProviderMicrosoftOAuth UserManagementAuthenticationProvider = "MicrosoftOAuth" + UserManagementAuthenticationProviderAuthkit UserManagementAuthenticationProvider = "authkit" + UserManagementAuthenticationProviderAppleOAuth UserManagementAuthenticationProvider = "AppleOAuth" + UserManagementAuthenticationProviderBitbucketOAuth UserManagementAuthenticationProvider = "BitbucketOAuth" + UserManagementAuthenticationProviderGitHubOAuth UserManagementAuthenticationProvider = "GitHubOAuth" + UserManagementAuthenticationProviderGitLabOAuth UserManagementAuthenticationProvider = "GitLabOAuth" + UserManagementAuthenticationProviderGoogleOAuth UserManagementAuthenticationProvider = "GoogleOAuth" + UserManagementAuthenticationProviderIntuitOAuth UserManagementAuthenticationProvider = "IntuitOAuth" + UserManagementAuthenticationProviderLinkedInOAuth UserManagementAuthenticationProvider = "LinkedInOAuth" + UserManagementAuthenticationProviderMicrosoftOAuth UserManagementAuthenticationProvider = "MicrosoftOAuth" + UserManagementAuthenticationProviderSalesforceOAuth UserManagementAuthenticationProvider = "SalesforceOAuth" + UserManagementAuthenticationProviderSlackOAuth UserManagementAuthenticationProvider = "SlackOAuth" + UserManagementAuthenticationProviderVercelMarketplaceOAuth UserManagementAuthenticationProvider = "VercelMarketplaceOAuth" + UserManagementAuthenticationProviderVercelOAuth UserManagementAuthenticationProvider = "VercelOAuth" + UserManagementAuthenticationProviderXeroOAuth UserManagementAuthenticationProvider = "XeroOAuth" ) // UserManagementUsersOrder is an alias for ApplicationsOrder. @@ -1142,6 +1175,9 @@ type UserManagementOrganizationMembershipOrder = ApplicationsOrder // UserManagementOrganizationMembershipStatuses is an alias for OrganizationMembershipCreatedDataStatus. type UserManagementOrganizationMembershipStatuses = OrganizationMembershipCreatedDataStatus +// UserManagementOrganizationMembershipGroupsOrder is an alias for ApplicationsOrder. +type UserManagementOrganizationMembershipGroupsOrder = ApplicationsOrder + // UserManagementUsersFeatureFlagsOrder is an alias for ApplicationsOrder. type UserManagementUsersFeatureFlagsOrder = ApplicationsOrder @@ -1156,6 +1192,3 @@ type WebhooksOrder = ApplicationsOrder // AuditLogsOrder is an alias for ApplicationsOrder. type AuditLogsOrder = ApplicationsOrder - -// EventSchemaContextActorSource is an alias for EventContextActorSource. -type EventSchemaContextActorSource = EventContextActorSource diff --git a/groups.go b/groups.go new file mode 100644 index 00000000..edbdb6ef --- /dev/null +++ b/groups.go @@ -0,0 +1,116 @@ +// Code generated by oagen. DO NOT EDIT. + +package workos + +import ( + "context" + "fmt" + "net/url" +) + +// GroupService handles Groups operations. +type GroupService struct { + client *Client +} + +// GroupsListOrganizationGroupsParams contains the parameters for ListOrganizationGroups. +type GroupsListOrganizationGroupsParams struct { + PaginationParams +} + +// ListOrganizationGroups list groups +// Get a paginated list of groups within an organization. +func (s *GroupService) ListOrganizationGroups(ctx context.Context, organizationID string, params *GroupsListOrganizationGroupsParams, opts ...RequestOption) *Iterator[Group] { + return newIterator[Group](ctx, s.client, "GET", fmt.Sprintf("/organizations/%s/groups", url.PathEscape(organizationID)), params, "after", "data", opts, map[string]string{"limit": "10", "order": "desc"}) +} + +// GroupsCreateOrganizationGroupParams contains the parameters for CreateOrganizationGroup. +type GroupsCreateOrganizationGroupParams struct { + // Name is the name of the Group. + Name string `json:"name"` + // Description is an optional description of the Group. + Description *string `json:"description,omitempty"` +} + +// CreateOrganizationGroup create a group +// Create a new group within an organization. +func (s *GroupService) CreateOrganizationGroup(ctx context.Context, organizationID string, params *GroupsCreateOrganizationGroupParams, opts ...RequestOption) (*Group, error) { + var result Group + _, err := s.client.request(ctx, "POST", fmt.Sprintf("/organizations/%s/groups", url.PathEscape(organizationID)), nil, params, &result, opts) + if err != nil { + return nil, err + } + return &result, nil +} + +// GetOrganizationGroup get a group +// Retrieve a group by its ID within an organization. +func (s *GroupService) GetOrganizationGroup(ctx context.Context, organizationID string, groupID string, opts ...RequestOption) (*Group, error) { + var result Group + _, err := s.client.request(ctx, "GET", fmt.Sprintf("/organizations/%s/groups/%s", url.PathEscape(organizationID), url.PathEscape(groupID)), nil, nil, &result, opts) + if err != nil { + return nil, err + } + return &result, nil +} + +// GroupsUpdateOrganizationGroupParams contains the parameters for UpdateOrganizationGroup. +type GroupsUpdateOrganizationGroupParams struct { + // Name is the name of the Group. + Name *string `json:"name,omitempty"` + // Description is an optional description of the Group. + Description *string `json:"description,omitempty"` +} + +// UpdateOrganizationGroup update a group +// Update an existing group. Only the fields provided in the request body will be updated. +func (s *GroupService) UpdateOrganizationGroup(ctx context.Context, organizationID string, groupID string, params *GroupsUpdateOrganizationGroupParams, opts ...RequestOption) (*Group, error) { + var result Group + _, err := s.client.request(ctx, "PATCH", fmt.Sprintf("/organizations/%s/groups/%s", url.PathEscape(organizationID), url.PathEscape(groupID)), nil, params, &result, opts) + if err != nil { + return nil, err + } + return &result, nil +} + +// DeleteOrganizationGroup delete a group +// Delete a group from an organization. +func (s *GroupService) DeleteOrganizationGroup(ctx context.Context, organizationID string, groupID string, opts ...RequestOption) error { + _, err := s.client.request(ctx, "DELETE", fmt.Sprintf("/organizations/%s/groups/%s", url.PathEscape(organizationID), url.PathEscape(groupID)), nil, nil, nil, opts) + return err +} + +// GroupsListOrganizationMembershipsParams contains the parameters for ListOrganizationMemberships. +type GroupsListOrganizationMembershipsParams struct { + PaginationParams +} + +// ListOrganizationMemberships list Group members +// Get a list of organization memberships in a group. +func (s *GroupService) ListOrganizationMemberships(ctx context.Context, organizationID string, groupID string, params *GroupsListOrganizationMembershipsParams, opts ...RequestOption) *Iterator[UserOrganizationMembershipBaseListData] { + return newIterator[UserOrganizationMembershipBaseListData](ctx, s.client, "GET", fmt.Sprintf("/organizations/%s/groups/%s/organization-memberships", url.PathEscape(organizationID), url.PathEscape(groupID)), params, "after", "data", opts, map[string]string{"limit": "10", "order": "desc"}) +} + +// GroupsCreateOrganizationMembershipParams contains the parameters for CreateOrganizationMembership. +type GroupsCreateOrganizationMembershipParams struct { + // OrganizationMembershipID is the ID of the Organization Membership to add to the group. + OrganizationMembershipID string `json:"organization_membership_id"` +} + +// CreateOrganizationMembership add a member to a Group +// Add an organization membership to a group. +func (s *GroupService) CreateOrganizationMembership(ctx context.Context, organizationID string, groupID string, params *GroupsCreateOrganizationMembershipParams, opts ...RequestOption) (*Group, error) { + var result Group + _, err := s.client.request(ctx, "POST", fmt.Sprintf("/organizations/%s/groups/%s/organization-memberships", url.PathEscape(organizationID), url.PathEscape(groupID)), nil, params, &result, opts) + if err != nil { + return nil, err + } + return &result, nil +} + +// DeleteOrganizationMembership remove a member from a Group +// Remove an organization membership from a group. +func (s *GroupService) DeleteOrganizationMembership(ctx context.Context, organizationID string, groupID string, omID string, opts ...RequestOption) error { + _, err := s.client.request(ctx, "DELETE", fmt.Sprintf("/organizations/%s/groups/%s/organization-memberships/%s", url.PathEscape(organizationID), url.PathEscape(groupID), url.PathEscape(omID)), nil, nil, nil, opts) + return err +} diff --git a/groups_test.go b/groups_test.go new file mode 100644 index 00000000..53257c15 --- /dev/null +++ b/groups_test.go @@ -0,0 +1,261 @@ +// Code generated by oagen. DO NOT EDIT. + +package workos_test + +import ( + "context" + "encoding/json" + "io" + "net/http" + "net/http/httptest" + "os" + "testing" + + "github.com/stretchr/testify/require" + "github.com/workos/workos-go/v7" +) + +func TestGroups_ListOrganizationGroups(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "GET", r.Method) + require.Equal(t, "/organizations/test_organizationId/groups", r.URL.Path) + require.Equal(t, "10", r.URL.Query().Get("limit")) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fixture, err := os.ReadFile("testdata/list_group.json") + if err != nil { + t.Fatalf("failed to read fixture: %v", err) + } + w.Write(fixture) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + iter := client.Groups().ListOrganizationGroups(context.Background(), "test_organizationId", &workos.GroupsListOrganizationGroupsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) + require.NotNil(t, iter) + require.True(t, iter.Next()) + require.NoError(t, iter.Err()) + item := iter.Current() + require.NotNil(t, item) +} + +func TestGroups_ListOrganizationGroups_Empty(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write([]byte(`{"data":[],"list_metadata":{"before":null,"after":null}}`)) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + iter := client.Groups().ListOrganizationGroups(context.Background(), "test_organizationId", &workos.GroupsListOrganizationGroupsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) + require.False(t, iter.Next()) + require.NoError(t, iter.Err()) +} + +func TestGroups_CreateOrganizationGroup(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "POST", r.Method) + require.Equal(t, "/organizations/test_organizationId/groups", r.URL.Path) + body, _ := io.ReadAll(r.Body) + var bodyMap map[string]interface{} + require.NoError(t, json.Unmarshal(body, &bodyMap)) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fixture, err := os.ReadFile("testdata/group.json") + if err != nil { + t.Fatalf("failed to read fixture: %v", err) + } + w.Write(fixture) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + result, err := client.Groups().CreateOrganizationGroup(context.Background(), "test_organizationId", &workos.GroupsCreateOrganizationGroupParams{}) + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, "group_01HXYZ123456789ABCDEFGHIJ", result.ID) + require.Equal(t, "org_01EHWNCE74X7JSDV0X3SZ3KJNY", result.OrganizationID) + require.Equal(t, "Engineering", result.Name) +} + +func TestGroups_GetOrganizationGroup(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "GET", r.Method) + require.Equal(t, "/organizations/test_organizationId/groups/test_groupId", r.URL.Path) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fixture, err := os.ReadFile("testdata/group.json") + if err != nil { + t.Fatalf("failed to read fixture: %v", err) + } + w.Write(fixture) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + result, err := client.Groups().GetOrganizationGroup(context.Background(), "test_organizationId", "test_groupId") + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, "group_01HXYZ123456789ABCDEFGHIJ", result.ID) + require.Equal(t, "org_01EHWNCE74X7JSDV0X3SZ3KJNY", result.OrganizationID) + require.Equal(t, "Engineering", result.Name) +} + +func TestGroups_UpdateOrganizationGroup(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "PATCH", r.Method) + require.Equal(t, "/organizations/test_organizationId/groups/test_groupId", r.URL.Path) + body, _ := io.ReadAll(r.Body) + var bodyMap map[string]interface{} + require.NoError(t, json.Unmarshal(body, &bodyMap)) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fixture, err := os.ReadFile("testdata/group.json") + if err != nil { + t.Fatalf("failed to read fixture: %v", err) + } + w.Write(fixture) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + result, err := client.Groups().UpdateOrganizationGroup(context.Background(), "test_organizationId", "test_groupId", &workos.GroupsUpdateOrganizationGroupParams{}) + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, "group_01HXYZ123456789ABCDEFGHIJ", result.ID) + require.Equal(t, "org_01EHWNCE74X7JSDV0X3SZ3KJNY", result.OrganizationID) + require.Equal(t, "Engineering", result.Name) +} + +func TestGroups_DeleteOrganizationGroup(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "DELETE", r.Method) + require.Equal(t, "/organizations/test_organizationId/groups/test_groupId", r.URL.Path) + w.WriteHeader(http.StatusNoContent) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + err := client.Groups().DeleteOrganizationGroup(context.Background(), "test_organizationId", "test_groupId") + require.NoError(t, err) +} + +func TestGroups_ListOrganizationMemberships(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "GET", r.Method) + require.Equal(t, "/organizations/test_organizationId/groups/test_groupId/organization-memberships", r.URL.Path) + require.Equal(t, "10", r.URL.Query().Get("limit")) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fixture, err := os.ReadFile("testdata/list_user_organization_membership_base_list_data.json") + if err != nil { + t.Fatalf("failed to read fixture: %v", err) + } + w.Write(fixture) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + iter := client.Groups().ListOrganizationMemberships(context.Background(), "test_organizationId", "test_groupId", &workos.GroupsListOrganizationMembershipsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) + require.NotNil(t, iter) + require.True(t, iter.Next()) + require.NoError(t, iter.Err()) + item := iter.Current() + require.NotNil(t, item) +} + +func TestGroups_ListOrganizationMemberships_Empty(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write([]byte(`{"data":[],"list_metadata":{"before":null,"after":null}}`)) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + iter := client.Groups().ListOrganizationMemberships(context.Background(), "test_organizationId", "test_groupId", &workos.GroupsListOrganizationMembershipsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) + require.False(t, iter.Next()) + require.NoError(t, iter.Err()) +} + +func TestGroups_CreateOrganizationMembership(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "POST", r.Method) + require.Equal(t, "/organizations/test_organizationId/groups/test_groupId/organization-memberships", r.URL.Path) + body, _ := io.ReadAll(r.Body) + var bodyMap map[string]interface{} + require.NoError(t, json.Unmarshal(body, &bodyMap)) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fixture, err := os.ReadFile("testdata/group.json") + if err != nil { + t.Fatalf("failed to read fixture: %v", err) + } + w.Write(fixture) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + result, err := client.Groups().CreateOrganizationMembership(context.Background(), "test_organizationId", "test_groupId", &workos.GroupsCreateOrganizationMembershipParams{}) + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, "group_01HXYZ123456789ABCDEFGHIJ", result.ID) + require.Equal(t, "org_01EHWNCE74X7JSDV0X3SZ3KJNY", result.OrganizationID) + require.Equal(t, "Engineering", result.Name) +} + +func TestGroups_DeleteOrganizationMembership(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "DELETE", r.Method) + require.Equal(t, "/organizations/test_organizationId/groups/test_groupId/organization-memberships/test_omId", r.URL.Path) + w.WriteHeader(http.StatusNoContent) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + err := client.Groups().DeleteOrganizationMembership(context.Background(), "test_organizationId", "test_groupId", "test_omId") + require.NoError(t, err) +} + +func TestGroups_Error401(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusUnauthorized) + w.Write([]byte(`{"code":"unauthorized","message":"Unauthorized"}`)) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + iter := client.Groups().ListOrganizationGroups(context.Background(), "test_organizationId", &workos.GroupsListOrganizationGroupsParams{}) + require.False(t, iter.Next()) + require.IsType(t, &workos.AuthenticationError{}, iter.Err()) +} + +func TestGroups_Error404(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + w.Write([]byte(`{"code":"not_found","message":"Not Found"}`)) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + iter := client.Groups().ListOrganizationGroups(context.Background(), "test_organizationId", &workos.GroupsListOrganizationGroupsParams{}) + require.False(t, iter.Next()) + require.IsType(t, &workos.NotFoundError{}, iter.Err()) +} + +func TestGroups_Error422(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(422) + w.Write([]byte(`{"code":"unprocessable_entity","message":"Unprocessable"}`)) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + iter := client.Groups().ListOrganizationGroups(context.Background(), "test_organizationId", &workos.GroupsListOrganizationGroupsParams{}) + require.False(t, iter.Next()) + require.IsType(t, &workos.UnprocessableEntityError{}, iter.Err()) +} diff --git a/models.go b/models.go index 950b4499..fa9cc653 100644 --- a/models.go +++ b/models.go @@ -324,6 +324,23 @@ type CreateCORSOrigin struct { Origin string `json:"origin"` } +// CreateGroupMembership represents a create group membership. +type CreateGroupMembership struct { + // OrganizationMembershipID is the ID of the Organization Membership to add to the group. + OrganizationMembershipID string `json:"organization_membership_id"` +} + +// CreateGroup represents a create group. +type CreateGroup struct { + // Name is the name of the Group. + Name string `json:"name"` + // Description is an optional description of the Group. + Description *string `json:"description,omitempty"` +} + +// UpdateGroup is an alias for UpdateAuthorizationPermission. +type UpdateGroup = UpdateAuthorizationPermission + // UpdateJWTTemplate represents an update JWT template. type UpdateJWTTemplate struct { // Content is the JWT template content as a Liquid template string. @@ -398,10 +415,18 @@ type SSOIntentOptions struct { ProviderType *string `json:"provider_type,omitempty"` } +// DomainVerificationIntentOptions represents a domain verification intent options. +type DomainVerificationIntentOptions struct { + // DomainName is the domain name to verify. When provided, the domain verification flow will skip the domain entry form and go directly to the verification step. + DomainName *string `json:"domain_name,omitempty"` +} + // IntentOptions represents an intent options. type IntentOptions struct { // SSO is sso-specific options for the Admin Portal. - SSO *SSOIntentOptions `json:"sso"` + SSO *SSOIntentOptions `json:"sso,omitempty"` + // DomainVerification is domain verification-specific options for the Admin Portal. + DomainVerification *DomainVerificationIntentOptions `json:"domain_verification,omitempty"` } // GenerateLink represents a generate link. @@ -423,8 +448,8 @@ type GenerateLink struct { Intent *GenerateLinkIntent `json:"intent,omitempty"` // IntentOptions is options to configure the Admin Portal based on the intent. IntentOptions *IntentOptions `json:"intent_options,omitempty"` - // AdminEmails is the email addresses of the IT admins to grant access to the Admin Portal for the given organization. Accepts up to 20 emails. - AdminEmails []string `json:"admin_emails,omitempty"` + // ItContactEmails is the email addresses of the IT contacts to grant access to the Admin Portal for the given organization. Accepts up to 20 emails. + ItContactEmails []string `json:"it_contact_emails,omitempty"` } // CreateRedirectURI represents a create redirect uri. @@ -1059,10 +1084,30 @@ type DirectoryUserWithGroups struct { CreatedAt string `json:"created_at"` // UpdatedAt is an ISO 8601 timestamp. UpdatedAt string `json:"updated_at"` - // Groups is the directory groups the user belongs to. + // Groups is the directory groups the user belongs to. Use the List Directory Groups endpoint with a user filter instead. + // + // Deprecated: this field is deprecated. Groups []*DirectoryGroup `json:"groups"` } +// Group represents a group. +type Group struct { + // Object is the Group object. + Object string `json:"object"` + // ID is the unique ID of the Group. + ID string `json:"id"` + // OrganizationID is the ID of the Organization the Group belongs to. + OrganizationID string `json:"organization_id"` + // Name is the name of the Group. + Name string `json:"name"` + // Description is an optional description of the Group. + Description *string `json:"description"` + // CreatedAt is an ISO 8601 timestamp. + CreatedAt string `json:"created_at"` + // UpdatedAt is an ISO 8601 timestamp. + UpdatedAt string `json:"updated_at"` +} + // EventContextActor the actor who performed the action. type EventContextActor struct { // ID is unique identifier of the actor. @@ -1135,27 +1180,27 @@ type DirectoryUser struct { UpdatedAt string `json:"updated_at"` } -// Group represents a group. -type Group struct { - // Object is the Group object. +// User is an alias for EmailChangeConfirmationUser. +type User = EmailChangeConfirmationUser + +// WaitlistUser represents a waitlist user. +type WaitlistUser struct { + // Object distinguishes the Waitlist User object. Object string `json:"object"` - // ID is the unique ID of the Group. + // ID is the unique ID of the Waitlist User. ID string `json:"id"` - // OrganizationID is the ID of the Organization the Group belongs to. - OrganizationID string `json:"organization_id"` - // Name is the name of the Group. - Name string `json:"name"` - // Description is an optional description of the Group. - Description *string `json:"description"` + // Email is the email address of the Waitlist User. + Email string `json:"email"` + // State is the state of the Waitlist User. + State WaitlistUserState `json:"state"` + // ApprovedAt is the timestamp when the Waitlist User was approved, or null if not yet approved. + ApprovedAt *string `json:"approved_at"` // CreatedAt is an ISO 8601 timestamp. CreatedAt string `json:"created_at"` // UpdatedAt is an ISO 8601 timestamp. UpdatedAt string `json:"updated_at"` } -// User is an alias for EmailChangeConfirmationUser. -type User = EmailChangeConfirmationUser - // EventSchema an event emitted by WorkOS. type EventSchema struct { // Object distinguishes the Event object. @@ -2881,6 +2926,8 @@ type InvitationAcceptedData struct { InviterUserID *string `json:"inviter_user_id"` // AcceptedUserID is the ID of the user who accepted the invitation, once accepted. AcceptedUserID *string `json:"accepted_user_id"` + // RoleSlug is slug of the role the invitee will be assigned on acceptance. Reflects the current role on the invitee's organization membership. null when the invitation has no associated organization. + RoleSlug *string `json:"role_slug"` // CreatedAt is an ISO 8601 timestamp. CreatedAt string `json:"created_at"` // UpdatedAt is an ISO 8601 timestamp. @@ -2923,6 +2970,8 @@ type InvitationCreatedData struct { InviterUserID *string `json:"inviter_user_id"` // AcceptedUserID is the ID of the user who accepted the invitation, once accepted. AcceptedUserID *string `json:"accepted_user_id"` + // RoleSlug is slug of the role the invitee will be assigned on acceptance. Reflects the current role on the invitee's organization membership. null when the invitation has no associated organization. + RoleSlug *string `json:"role_slug"` // CreatedAt is an ISO 8601 timestamp. CreatedAt string `json:"created_at"` // UpdatedAt is an ISO 8601 timestamp. @@ -2965,6 +3014,8 @@ type InvitationResentData struct { InviterUserID *string `json:"inviter_user_id"` // AcceptedUserID is the ID of the user who accepted the invitation, once accepted. AcceptedUserID *string `json:"accepted_user_id"` + // RoleSlug is slug of the role the invitee will be assigned on acceptance. Reflects the current role on the invitee's organization membership. null when the invitation has no associated organization. + RoleSlug *string `json:"role_slug"` // CreatedAt is an ISO 8601 timestamp. CreatedAt string `json:"created_at"` // UpdatedAt is an ISO 8601 timestamp. @@ -3007,6 +3058,8 @@ type InvitationRevokedData struct { InviterUserID *string `json:"inviter_user_id"` // AcceptedUserID is the ID of the user who accepted the invitation, once accepted. AcceptedUserID *string `json:"accepted_user_id"` + // RoleSlug is slug of the role the invitee will be assigned on acceptance. Reflects the current role on the invitee's organization membership. null when the invitation has no associated organization. + RoleSlug *string `json:"role_slug"` // CreatedAt is an ISO 8601 timestamp. CreatedAt string `json:"created_at"` // UpdatedAt is an ISO 8601 timestamp. @@ -4186,6 +4239,48 @@ type VaultNamesListedData struct { ActorName string `json:"actor_name"` } +// WaitlistUserApproved represents a waitlist user approved. +type WaitlistUserApproved struct { + // ID is unique identifier for the event. + ID string `json:"id"` + Event string `json:"event"` + // Data is the event payload. + Data *WaitlistUser `json:"data"` + // CreatedAt is an ISO 8601 timestamp. + CreatedAt string `json:"created_at"` + Context *EventContext `json:"context,omitempty"` + // Object distinguishes the Event object. + Object string `json:"object"` +} + +// WaitlistUserCreated represents a waitlist user created. +type WaitlistUserCreated struct { + // ID is unique identifier for the event. + ID string `json:"id"` + Event string `json:"event"` + // Data is the event payload. + Data *WaitlistUser `json:"data"` + // CreatedAt is an ISO 8601 timestamp. + CreatedAt string `json:"created_at"` + Context *EventContext `json:"context,omitempty"` + // Object distinguishes the Event object. + Object string `json:"object"` +} + +// WaitlistUserDenied represents a waitlist user denied. +type WaitlistUserDenied struct { + // ID is unique identifier for the event. + ID string `json:"id"` + Event string `json:"event"` + // Data is the event payload. + Data *WaitlistUser `json:"data"` + // CreatedAt is an ISO 8601 timestamp. + CreatedAt string `json:"created_at"` + Context *EventContext `json:"context,omitempty"` + // Object distinguishes the Event object. + Object string `json:"object"` +} + // JWTTemplateResponse represents a JWT template response. type JWTTemplateResponse struct { // Object is the object type. @@ -4450,6 +4545,8 @@ type UserInvite struct { InviterUserID *string `json:"inviter_user_id"` // AcceptedUserID is the ID of the user who accepted the invitation, once accepted. AcceptedUserID *string `json:"accepted_user_id"` + // RoleSlug is slug of the role the invitee will be assigned on acceptance. Reflects the current role on the invitee's organization membership. null when the invitation has no associated organization. + RoleSlug *string `json:"role_slug"` // CreatedAt is an ISO 8601 timestamp. CreatedAt string `json:"created_at"` // UpdatedAt is an ISO 8601 timestamp. @@ -5271,6 +5368,8 @@ type Invitation struct { InviterUserID *string `json:"inviter_user_id"` // AcceptedUserID is the ID of the user who accepted the invitation, once accepted. AcceptedUserID *string `json:"accepted_user_id"` + // RoleSlug is slug of the role the invitee will be assigned on acceptance. Reflects the current role on the invitee's organization membership. null when the invitation has no associated organization. + RoleSlug *string `json:"role_slug"` // CreatedAt is an ISO 8601 timestamp. CreatedAt string `json:"created_at"` // UpdatedAt is an ISO 8601 timestamp. @@ -5431,27 +5530,6 @@ type ConnectApplicationRedirectURI struct { Default bool `json:"default"` } -// EventSchemaData is an alias for ActionAuthenticationDeniedData. -type EventSchemaData = ActionAuthenticationDeniedData - -// EventSchemaContextActor the actor who performed the action. -type EventSchemaContextActor struct { - // ID is unique identifier of the actor. - ID string `json:"id"` - // Source is the source of the actor that performed the action. - Source EventSchemaContextActorSource `json:"source"` - // Name is the name of the actor. - Name *string `json:"name"` -} - -// EventSchemaContext additional context about the event. -type EventSchemaContext struct { - // ClientID is the client ID associated with the flag event. - ClientID string `json:"client_id"` - // Actor is the actor who performed the action. - Actor *EventSchemaContextActor `json:"actor"` -} - // PaginationParams contains common pagination parameters for list operations. type PaginationParams struct { // Before is a cursor for reverse pagination. diff --git a/sso.go b/sso.go index c2d820fa..5fe2376d 100644 --- a/sso.go +++ b/sso.go @@ -61,7 +61,7 @@ type SSOGetAuthorizationURLParams struct { // // Deprecated: this parameter is deprecated. Domain *string `url:"domain,omitempty" json:"-"` - // Provider is used to initiate OAuth authentication with Google, Microsoft, GitHub, or Apple. + // Provider is used to initiate OAuth authentication with various providers. Provider *SSOProvider `url:"provider,omitempty" json:"-"` // RedirectURI is where to redirect the user after they complete the authentication process. You must use one of the redirect URIs configured via the [Redirects](https://dashboard.workos.com/redirects) page on the dashboard. RedirectURI string `url:"redirect_uri" json:"-"` diff --git a/testdata/create_group.json b/testdata/create_group.json new file mode 100644 index 00000000..bcb47249 --- /dev/null +++ b/testdata/create_group.json @@ -0,0 +1,4 @@ +{ + "name": "Engineering", + "description": "The engineering team" +} diff --git a/testdata/create_group_membership.json b/testdata/create_group_membership.json new file mode 100644 index 00000000..45ebd1dd --- /dev/null +++ b/testdata/create_group_membership.json @@ -0,0 +1,3 @@ +{ + "organization_membership_id": "om_01HXYZ123456789ABCDEFGHIJ" +} diff --git a/testdata/domain_verification_intent_options.json b/testdata/domain_verification_intent_options.json new file mode 100644 index 00000000..d132a78a --- /dev/null +++ b/testdata/domain_verification_intent_options.json @@ -0,0 +1,3 @@ +{ + "domain_name": "example.com" +} diff --git a/testdata/generate_link.json b/testdata/generate_link.json index 660b36a7..4be367d9 100644 --- a/testdata/generate_link.json +++ b/testdata/generate_link.json @@ -7,9 +7,15 @@ "sso": { "bookmark_slug": "chatgpt", "provider_type": "GoogleSAML" + }, + "domain_verification": { + "domain_name": "example.com" } }, "admin_emails": [ "admin@example.com" + ], + "it_contact_emails": [ + "it-contact@example.com" ] } diff --git a/testdata/intent_options.json b/testdata/intent_options.json index 31bad913..894d5998 100644 --- a/testdata/intent_options.json +++ b/testdata/intent_options.json @@ -2,5 +2,8 @@ "sso": { "bookmark_slug": "chatgpt", "provider_type": "GoogleSAML" + }, + "domain_verification": { + "domain_name": "example.com" } } diff --git a/testdata/invitation.json b/testdata/invitation.json index c2019df7..5dabcd8e 100644 --- a/testdata/invitation.json +++ b/testdata/invitation.json @@ -12,5 +12,6 @@ "created_at": "2026-01-15T12:00:00.000Z", "updated_at": "2026-01-15T12:00:00.000Z", "token": "Z1uX3RbwcIl5fIGJJJCXXisdI", - "accept_invitation_url": "https://your-app.com/invite?invitation_token=Z1uX3RbwcIl5fIGJJJCXXisdI" + "accept_invitation_url": "https://your-app.com/invite?invitation_token=Z1uX3RbwcIl5fIGJJJCXXisdI", + "role_slug": "admin" } diff --git a/testdata/invitation_accepted.json b/testdata/invitation_accepted.json index 61b93ab4..100adfa9 100644 --- a/testdata/invitation_accepted.json +++ b/testdata/invitation_accepted.json @@ -13,7 +13,8 @@ "inviter_user_id": "user_01HYGBX8ZGD19949T3BM4FW1C3", "accepted_user_id": null, "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z" + "updated_at": "2026-01-15T12:00:00.000Z", + "role_slug": "admin" }, "created_at": "2026-01-15T12:00:00.000Z", "context": { diff --git a/testdata/invitation_created.json b/testdata/invitation_created.json index c83b104d..b1398e12 100644 --- a/testdata/invitation_created.json +++ b/testdata/invitation_created.json @@ -13,7 +13,8 @@ "inviter_user_id": "user_01HYGBX8ZGD19949T3BM4FW1C3", "accepted_user_id": null, "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z" + "updated_at": "2026-01-15T12:00:00.000Z", + "role_slug": "admin" }, "created_at": "2026-01-15T12:00:00.000Z", "context": { diff --git a/testdata/invitation_resent.json b/testdata/invitation_resent.json index 7ace11e7..17adc958 100644 --- a/testdata/invitation_resent.json +++ b/testdata/invitation_resent.json @@ -13,7 +13,8 @@ "inviter_user_id": "user_01HYGBX8ZGD19949T3BM4FW1C3", "accepted_user_id": null, "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z" + "updated_at": "2026-01-15T12:00:00.000Z", + "role_slug": "admin" }, "created_at": "2026-01-15T12:00:00.000Z", "context": { diff --git a/testdata/invitation_resent_data.json b/testdata/invitation_resent_data.json index 66102c6b..94f2e81d 100644 --- a/testdata/invitation_resent_data.json +++ b/testdata/invitation_resent_data.json @@ -10,5 +10,6 @@ "inviter_user_id": "user_01HYGBX8ZGD19949T3BM4FW1C3", "accepted_user_id": null, "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z" + "updated_at": "2026-01-15T12:00:00.000Z", + "role_slug": "admin" } diff --git a/testdata/invitation_revoked.json b/testdata/invitation_revoked.json index e8f8ff62..e22216e3 100644 --- a/testdata/invitation_revoked.json +++ b/testdata/invitation_revoked.json @@ -13,7 +13,8 @@ "inviter_user_id": "user_01HYGBX8ZGD19949T3BM4FW1C3", "accepted_user_id": null, "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z" + "updated_at": "2026-01-15T12:00:00.000Z", + "role_slug": "admin" }, "created_at": "2026-01-15T12:00:00.000Z", "context": { diff --git a/testdata/list_group.json b/testdata/list_group.json new file mode 100644 index 00000000..9516016b --- /dev/null +++ b/testdata/list_group.json @@ -0,0 +1,17 @@ +{ + "data": [ + { + "object": "group", + "id": "group_01HXYZ123456789ABCDEFGHIJ", + "organization_id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY", + "name": "Engineering", + "description": "The engineering team", + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" + } + ], + "list_metadata": { + "before": null, + "after": null + } +} diff --git a/testdata/list_user_invite.json b/testdata/list_user_invite.json index 355f3e44..6288c488 100644 --- a/testdata/list_user_invite.json +++ b/testdata/list_user_invite.json @@ -11,6 +11,7 @@ "organization_id": "org_01E4ZCR3C56J083X43JQXF3JK5", "inviter_user_id": "user_01HYGBX8ZGD19949T3BM4FW1C3", "accepted_user_id": null, + "role_slug": "admin", "created_at": "2026-01-15T12:00:00.000Z", "updated_at": "2026-01-15T12:00:00.000Z", "token": "Z1uX3RbwcIl5fIGJJJCXXisdI", diff --git a/testdata/update_group.json b/testdata/update_group.json new file mode 100644 index 00000000..bcb47249 --- /dev/null +++ b/testdata/update_group.json @@ -0,0 +1,4 @@ +{ + "name": "Engineering", + "description": "The engineering team" +} diff --git a/testdata/user_invite.json b/testdata/user_invite.json index b3a1dbbd..9c91ed19 100644 --- a/testdata/user_invite.json +++ b/testdata/user_invite.json @@ -12,5 +12,6 @@ "created_at": "2026-01-15T12:00:00.000Z", "updated_at": "2026-01-15T12:00:00.000Z", "token": "Z1uX3RbwcIl5fIGJJJCXXisdI", - "accept_invitation_url": "https://your-app.com/invite?invitation_token=Z1uX3RbwcIl5fIGJJJCXXisdI" + "accept_invitation_url": "https://your-app.com/invite?invitation_token=Z1uX3RbwcIl5fIGJJJCXXisdI", + "role_slug": "admin" } diff --git a/testdata/waitlist_user.json b/testdata/waitlist_user.json new file mode 100644 index 00000000..05973598 --- /dev/null +++ b/testdata/waitlist_user.json @@ -0,0 +1,9 @@ +{ + "object": "waitlist_user", + "id": "wl_user_01E4ZCR3C56J083X43JQXF3JK5", + "email": "marcelina.davis@example.com", + "state": "pending", + "approved_at": null, + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" +} diff --git a/testdata/waitlist_user_approved.json b/testdata/waitlist_user_approved.json new file mode 100644 index 00000000..eddf230b --- /dev/null +++ b/testdata/waitlist_user_approved.json @@ -0,0 +1,35 @@ +{ + "id": "event_01EHZNVPK3SFK441A1RGBFSHRT", + "event": "waitlist_user.approved", + "data": { + "object": "waitlist_user", + "id": "wl_user_01E4ZCR3C56J083X43JQXF3JK5", + "email": "marcelina.davis@example.com", + "state": "pending", + "approved_at": null, + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" + }, + "created_at": "2026-01-15T12:00:00.000Z", + "context": { + "google_analytics_client_id": "GA1.2.1234567890.1234567890", + "google_analytics_sessions": [ + { + "containerId": "GTM-ABCDEF", + "sessionId": "1234567890", + "sessionNumber": "1" + } + ], + "ajs_anonymous_id": "ajs_anon_01EHWNCE74X7JSDV0X3SZ3KJNY", + "client_id": "client_01EHWNCE74X7JSDV0X3SZ3KJNY", + "actor": { + "id": "user_01EHWNCE74X7JSDV0X3SZ3KJNY", + "source": "api", + "name": "Jane Doe" + }, + "previous_attributes": { + "key": {} + } + }, + "object": "event" +} diff --git a/testdata/waitlist_user_created.json b/testdata/waitlist_user_created.json new file mode 100644 index 00000000..c3faaad7 --- /dev/null +++ b/testdata/waitlist_user_created.json @@ -0,0 +1,35 @@ +{ + "id": "event_01EHZNVPK3SFK441A1RGBFSHRT", + "event": "waitlist_user.created", + "data": { + "object": "waitlist_user", + "id": "wl_user_01E4ZCR3C56J083X43JQXF3JK5", + "email": "marcelina.davis@example.com", + "state": "pending", + "approved_at": null, + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" + }, + "created_at": "2026-01-15T12:00:00.000Z", + "context": { + "google_analytics_client_id": "GA1.2.1234567890.1234567890", + "google_analytics_sessions": [ + { + "containerId": "GTM-ABCDEF", + "sessionId": "1234567890", + "sessionNumber": "1" + } + ], + "ajs_anonymous_id": "ajs_anon_01EHWNCE74X7JSDV0X3SZ3KJNY", + "client_id": "client_01EHWNCE74X7JSDV0X3SZ3KJNY", + "actor": { + "id": "user_01EHWNCE74X7JSDV0X3SZ3KJNY", + "source": "api", + "name": "Jane Doe" + }, + "previous_attributes": { + "key": {} + } + }, + "object": "event" +} diff --git a/testdata/waitlist_user_denied.json b/testdata/waitlist_user_denied.json new file mode 100644 index 00000000..6079919b --- /dev/null +++ b/testdata/waitlist_user_denied.json @@ -0,0 +1,35 @@ +{ + "id": "event_01EHZNVPK3SFK441A1RGBFSHRT", + "event": "waitlist_user.denied", + "data": { + "object": "waitlist_user", + "id": "wl_user_01E4ZCR3C56J083X43JQXF3JK5", + "email": "marcelina.davis@example.com", + "state": "pending", + "approved_at": null, + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" + }, + "created_at": "2026-01-15T12:00:00.000Z", + "context": { + "google_analytics_client_id": "GA1.2.1234567890.1234567890", + "google_analytics_sessions": [ + { + "containerId": "GTM-ABCDEF", + "sessionId": "1234567890", + "sessionNumber": "1" + } + ], + "ajs_anonymous_id": "ajs_anon_01EHWNCE74X7JSDV0X3SZ3KJNY", + "client_id": "client_01EHWNCE74X7JSDV0X3SZ3KJNY", + "actor": { + "id": "user_01EHWNCE74X7JSDV0X3SZ3KJNY", + "source": "api", + "name": "Jane Doe" + }, + "previous_attributes": { + "key": {} + } + }, + "object": "event" +} diff --git a/user_management_organization_membership_groups.go b/user_management_organization_membership_groups.go new file mode 100644 index 00000000..2ac4026f --- /dev/null +++ b/user_management_organization_membership_groups.go @@ -0,0 +1,25 @@ +// Code generated by oagen. DO NOT EDIT. + +package workos + +import ( + "context" + "fmt" + "net/url" +) + +// UserManagementOrganizationMembershipGroupService handles UserManagementOrganizationMembershipGroups operations. +type UserManagementOrganizationMembershipGroupService struct { + client *Client +} + +// UserManagementOrganizationMembershipGroupsListOrganizationMembershipGroupsParams contains the parameters for ListOrganizationMembershipGroups. +type UserManagementOrganizationMembershipGroupsListOrganizationMembershipGroupsParams struct { + PaginationParams +} + +// ListOrganizationMembershipGroups list groups +// Get a list of groups that an organization membership belongs to. +func (s *UserManagementOrganizationMembershipGroupService) ListOrganizationMembershipGroups(ctx context.Context, omID string, params *UserManagementOrganizationMembershipGroupsListOrganizationMembershipGroupsParams, opts ...RequestOption) *Iterator[Group] { + return newIterator[Group](ctx, s.client, "GET", fmt.Sprintf("/user_management/organization_memberships/%s/groups", url.PathEscape(omID)), params, "after", "data", opts, map[string]string{"limit": "10", "order": "desc"}) +} diff --git a/user_management_organization_membership_groups_test.go b/user_management_organization_membership_groups_test.go new file mode 100644 index 00000000..fd7afc55 --- /dev/null +++ b/user_management_organization_membership_groups_test.go @@ -0,0 +1,94 @@ +// Code generated by oagen. DO NOT EDIT. + +package workos_test + +import ( + "context" + "net/http" + "net/http/httptest" + "os" + "testing" + + "github.com/stretchr/testify/require" + "github.com/workos/workos-go/v7" +) + +func TestUserManagementOrganizationMembershipGroups_ListOrganizationMembershipGroups(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "GET", r.Method) + require.Equal(t, "/user_management/organization_memberships/test_omId/groups", r.URL.Path) + require.Equal(t, "10", r.URL.Query().Get("limit")) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fixture, err := os.ReadFile("testdata/list_group.json") + if err != nil { + t.Fatalf("failed to read fixture: %v", err) + } + w.Write(fixture) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + iter := client.UserManagementOrganizationMembershipGroups().ListOrganizationMembershipGroups(context.Background(), "test_omId", &workos.UserManagementOrganizationMembershipGroupsListOrganizationMembershipGroupsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) + require.NotNil(t, iter) + require.True(t, iter.Next()) + require.NoError(t, iter.Err()) + item := iter.Current() + require.NotNil(t, item) +} + +func TestUserManagementOrganizationMembershipGroups_ListOrganizationMembershipGroups_Empty(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write([]byte(`{"data":[],"list_metadata":{"before":null,"after":null}}`)) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + iter := client.UserManagementOrganizationMembershipGroups().ListOrganizationMembershipGroups(context.Background(), "test_omId", &workos.UserManagementOrganizationMembershipGroupsListOrganizationMembershipGroupsParams{PaginationParams: workos.PaginationParams{Limit: ptrInt(10)}}) + require.False(t, iter.Next()) + require.NoError(t, iter.Err()) +} + +func TestUserManagementOrganizationMembershipGroups_Error401(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusUnauthorized) + w.Write([]byte(`{"code":"unauthorized","message":"Unauthorized"}`)) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + iter := client.UserManagementOrganizationMembershipGroups().ListOrganizationMembershipGroups(context.Background(), "test_omId", &workos.UserManagementOrganizationMembershipGroupsListOrganizationMembershipGroupsParams{}) + require.False(t, iter.Next()) + require.IsType(t, &workos.AuthenticationError{}, iter.Err()) +} + +func TestUserManagementOrganizationMembershipGroups_Error404(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + w.Write([]byte(`{"code":"not_found","message":"Not Found"}`)) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + iter := client.UserManagementOrganizationMembershipGroups().ListOrganizationMembershipGroups(context.Background(), "test_omId", &workos.UserManagementOrganizationMembershipGroupsListOrganizationMembershipGroupsParams{}) + require.False(t, iter.Next()) + require.IsType(t, &workos.NotFoundError{}, iter.Err()) +} + +func TestUserManagementOrganizationMembershipGroups_Error422(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(422) + w.Write([]byte(`{"code":"unprocessable_entity","message":"Unprocessable"}`)) + })) + defer server.Close() + + client := workos.NewClient("sk_test", workos.WithBaseURL(server.URL)) + iter := client.UserManagementOrganizationMembershipGroups().ListOrganizationMembershipGroups(context.Background(), "test_omId", &workos.UserManagementOrganizationMembershipGroupsListOrganizationMembershipGroupsParams{}) + require.False(t, iter.Next()) + require.IsType(t, &workos.UnprocessableEntityError{}, iter.Err()) +} diff --git a/workos.go b/workos.go index 53da1ef3..bae2805b 100644 --- a/workos.go +++ b/workos.go @@ -14,25 +14,27 @@ type Client struct { logger Logger appInfo appInfo - apiKeys *APIKeyService - multiFactorAuth *MultiFactorAuthService - connect *ConnectService - authorization *AuthorizationService - sso *SSOService - pipes *PipeService - directorySync *DirectorySyncService - events *EventService - featureFlags *FeatureFlagService - organizationDomains *OrganizationDomainService - organizations *OrganizationService - adminPortal *AdminPortalService - radar *RadarService - userManagement *UserManagementService - webhooks *WebhookService - widgets *WidgetService - auditLogs *AuditLogService - passwordless *PasswordlessService - vault *VaultService + apiKeys *APIKeyService + multiFactorAuth *MultiFactorAuthService + connect *ConnectService + authorization *AuthorizationService + sso *SSOService + pipes *PipeService + directorySync *DirectorySyncService + events *EventService + featureFlags *FeatureFlagService + organizationDomains *OrganizationDomainService + organizations *OrganizationService + groups *GroupService + adminPortal *AdminPortalService + radar *RadarService + userManagement *UserManagementService + userManagementOrganizationMembershipGroups *UserManagementOrganizationMembershipGroupService + webhooks *WebhookService + widgets *WidgetService + auditLogs *AuditLogService + passwordless *PasswordlessService + vault *VaultService } // NewClient creates a new WorkOS API client. @@ -57,9 +59,11 @@ func NewClient(apiKey string, opts ...ClientOption) *Client { c.featureFlags = &FeatureFlagService{client: c} c.organizationDomains = &OrganizationDomainService{client: c} c.organizations = &OrganizationService{client: c} + c.groups = &GroupService{client: c} c.adminPortal = &AdminPortalService{client: c} c.radar = &RadarService{client: c} c.userManagement = &UserManagementService{client: c} + c.userManagementOrganizationMembershipGroups = &UserManagementOrganizationMembershipGroupService{client: c} c.webhooks = &WebhookService{client: c} c.widgets = &WidgetService{client: c} c.auditLogs = &AuditLogService{client: c} @@ -123,6 +127,11 @@ func (c *Client) Organizations() *OrganizationService { return c.organizations } +// Groups returns the Groups service. +func (c *Client) Groups() *GroupService { + return c.groups +} + // AdminPortal returns the AdminPortal service. func (c *Client) AdminPortal() *AdminPortalService { return c.adminPortal @@ -138,6 +147,11 @@ func (c *Client) UserManagement() *UserManagementService { return c.userManagement } +// UserManagementOrganizationMembershipGroups returns the UserManagementOrganizationMembershipGroups service. +func (c *Client) UserManagementOrganizationMembershipGroups() *UserManagementOrganizationMembershipGroupService { + return c.userManagementOrganizationMembershipGroups +} + // Webhooks returns the Webhooks service. func (c *Client) Webhooks() *WebhookService { return c.webhooks