From 1a1d9d1b7ab6806a89b90ac75545cfd995a33dab Mon Sep 17 00:00:00 2001 From: "workos-sdk-automation[bot]" <255426317+workos-sdk-automation[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 13:51:05 +0000 Subject: [PATCH 1/2] chore(generated): shared regenerated files --- .last-synced-sha | 2 +- .oagen-manifest.json | 8 +- src/workos/common/__init__.py | 18 +- src/workos/common/models/__init__.py | 22 +- .../organization_domains/models/__init__.py | 3 - .../models/organization_membership.py | 9 +- .../fixtures/auth_method_mismatch_error.json | 4 + .../list_user_organization_membership.json | 5 + tests/fixtures/organization_membership.json | 5 + ...s_connected_account_connection_failed.json | 38 ++ ...nected_account_connection_failed_data.json | 12 + tests/fixtures/session_reauthenticated.json | 44 ++ .../session_reauthenticated_data.json | 18 + ...ion_reauthenticated_data_impersonator.json | 4 + .../user_organization_membership.json | 5 + tests/test_models_round_trip.py | 528 ++++++++++++++---- 16 files changed, 585 insertions(+), 140 deletions(-) create mode 100644 tests/fixtures/auth_method_mismatch_error.json create mode 100644 tests/fixtures/pipes_connected_account_connection_failed.json create mode 100644 tests/fixtures/pipes_connected_account_connection_failed_data.json create mode 100644 tests/fixtures/session_reauthenticated.json create mode 100644 tests/fixtures/session_reauthenticated_data.json create mode 100644 tests/fixtures/session_reauthenticated_data_impersonator.json diff --git a/.last-synced-sha b/.last-synced-sha index 409f7391..d5b98283 100644 --- a/.last-synced-sha +++ b/.last-synced-sha @@ -1 +1 @@ -b6a68da8bd60c1478e0a86ca97c75448677e8871 +1a2f47b20f63f2c8f0eb56bbd2adb3b5947d693a diff --git a/.oagen-manifest.json b/.oagen-manifest.json index ce6bfc85..115b1e7a 100644 --- a/.oagen-manifest.json +++ b/.oagen-manifest.json @@ -1,7 +1,7 @@ { "version": 2, "language": "python", - "generatedAt": "2026-06-17T20:55:36.392Z", + "generatedAt": "2026-06-25T13:50:58.519Z", "files": [ "src/workos/_client.py", "src/workos/admin_portal/__init__.py", @@ -729,6 +729,7 @@ "tests/fixtures/audit_log_schema_target.json", "tests/fixtures/audit_log_schema_target_input.json", "tests/fixtures/audit_logs_retention.json", + "tests/fixtures/auth_method_mismatch_error.json", "tests/fixtures/authenticate_response.json", "tests/fixtures/authenticate_response_impersonator.json", "tests/fixtures/authenticate_response_oauth_token.json", @@ -1067,6 +1068,8 @@ "tests/fixtures/permission_updated_data.json", "tests/fixtures/pipe_connected_account.json", "tests/fixtures/pipes_connected_account_connected.json", + "tests/fixtures/pipes_connected_account_connection_failed.json", + "tests/fixtures/pipes_connected_account_connection_failed_data.json", "tests/fixtures/pipes_connected_account_disconnected.json", "tests/fixtures/pipes_connected_account_reauthorization_needed.json", "tests/fixtures/portal_link_response.json", @@ -1100,6 +1103,9 @@ "tests/fixtures/session_created.json", "tests/fixtures/session_created_data.json", "tests/fixtures/session_created_data_impersonator.json", + "tests/fixtures/session_reauthenticated.json", + "tests/fixtures/session_reauthenticated_data.json", + "tests/fixtures/session_reauthenticated_data_impersonator.json", "tests/fixtures/session_revoked.json", "tests/fixtures/session_revoked_data.json", "tests/fixtures/session_revoked_data_impersonator.json", diff --git a/src/workos/common/__init__.py b/src/workos/common/__init__.py index 83b7feb6..86f49b53 100644 --- a/src/workos/common/__init__.py +++ b/src/workos/common/__init__.py @@ -120,6 +120,7 @@ AuthenticationSSOTimedOutDataError as AuthenticationSSOTimedOutDataError, ) from .models import AuthenticationSSOTimedOutDataSSO as AuthenticationSSOTimedOutDataSSO +from .models import AuthMethodMismatchError as AuthMethodMismatchError from .models import AuthorizationPermission as AuthorizationPermission from .models import ConnectApplication as ConnectApplication from .models import ConnectApplicationM2M as ConnectApplicationM2M @@ -311,12 +312,6 @@ from .models import OrganizationDomainDataState as OrganizationDomainDataState from .models import OrganizationDomainDeleted as OrganizationDomainDeleted from .models import OrganizationDomainDeletedData as OrganizationDomainDeletedData -from .models import ( - OrganizationDomainStandAloneState as OrganizationDomainStandAloneState, -) -from .models import ( - OrganizationDomainStandAloneVerificationStrategy as OrganizationDomainStandAloneVerificationStrategy, -) from .models import OrganizationDomainState as OrganizationDomainState from .models import OrganizationDomainUpdated as OrganizationDomainUpdated from .models import OrganizationDomainUpdatedData as OrganizationDomainUpdatedData @@ -369,6 +364,12 @@ from .models import PermissionUpdatedData as PermissionUpdatedData from .models import PipeConnectedAccount as PipeConnectedAccount from .models import PipesConnectedAccountConnected as PipesConnectedAccountConnected +from .models import ( + PipesConnectedAccountConnectionFailed as PipesConnectedAccountConnectionFailed, +) +from .models import ( + PipesConnectedAccountConnectionFailedData as PipesConnectedAccountConnectionFailedData, +) from .models import ( PipesConnectedAccountDisconnected as PipesConnectedAccountDisconnected, ) @@ -398,6 +399,11 @@ from .models import SessionCreated as SessionCreated from .models import SessionCreatedData as SessionCreatedData from .models import SessionCreatedDataImpersonator as SessionCreatedDataImpersonator +from .models import SessionReauthenticated as SessionReauthenticated +from .models import SessionReauthenticatedData as SessionReauthenticatedData +from .models import ( + SessionReauthenticatedDataImpersonator as SessionReauthenticatedDataImpersonator, +) from .models import SessionRevoked as SessionRevoked from .models import SessionRevokedData as SessionRevokedData from .models import SessionRevokedDataImpersonator as SessionRevokedDataImpersonator diff --git a/src/workos/common/models/__init__.py b/src/workos/common/models/__init__.py index 440e41f3..9347026e 100644 --- a/src/workos/common/models/__init__.py +++ b/src/workos/common/models/__init__.py @@ -206,6 +206,9 @@ from .authentication_sso_timed_out_data_sso import ( AuthenticationSSOTimedOutDataSSO as AuthenticationSSOTimedOutDataSSO, ) +from .auth_method_mismatch_error import ( + AuthMethodMismatchError as AuthMethodMismatchError, +) from .authorization_permission import AuthorizationPermission as AuthorizationPermission from .connect_application import ConnectApplication as ConnectApplication from .connect_application_m2m import ConnectApplicationM2M as ConnectApplicationM2M @@ -459,12 +462,6 @@ from .organization_domain_deleted_data import ( OrganizationDomainDeletedData as OrganizationDomainDeletedData, ) -from .organization_domain_stand_alone_state import ( - OrganizationDomainStandAloneState as OrganizationDomainStandAloneState, -) -from .organization_domain_stand_alone_verification_strategy import ( - OrganizationDomainStandAloneVerificationStrategy as OrganizationDomainStandAloneVerificationStrategy, -) from .organization_domain_state import ( OrganizationDomainState as OrganizationDomainState, ) @@ -557,6 +554,12 @@ from .pipes_connected_account_connected import ( PipesConnectedAccountConnected as PipesConnectedAccountConnected, ) +from .pipes_connected_account_connection_failed import ( + PipesConnectedAccountConnectionFailed as PipesConnectedAccountConnectionFailed, +) +from .pipes_connected_account_connection_failed_data import ( + PipesConnectedAccountConnectionFailedData as PipesConnectedAccountConnectionFailedData, +) from .pipes_connected_account_disconnected import ( PipesConnectedAccountDisconnected as PipesConnectedAccountDisconnected, ) @@ -594,6 +597,13 @@ from .session_created_data_impersonator import ( SessionCreatedDataImpersonator as SessionCreatedDataImpersonator, ) +from .session_reauthenticated import SessionReauthenticated as SessionReauthenticated +from .session_reauthenticated_data import ( + SessionReauthenticatedData as SessionReauthenticatedData, +) +from .session_reauthenticated_data_impersonator import ( + SessionReauthenticatedDataImpersonator as SessionReauthenticatedDataImpersonator, +) from .session_revoked import SessionRevoked as SessionRevoked from .session_revoked_data import SessionRevokedData as SessionRevokedData from .session_revoked_data_impersonator import ( diff --git a/src/workos/organization_domains/models/__init__.py b/src/workos/organization_domains/models/__init__.py index a8435a78..29011846 100644 --- a/src/workos/organization_domains/models/__init__.py +++ b/src/workos/organization_domains/models/__init__.py @@ -6,6 +6,3 @@ from workos.common.models.organization_domain import ( OrganizationDomain as OrganizationDomain, ) -from .organization_domain_stand_alone import ( - OrganizationDomainStandAlone as OrganizationDomainStandAlone, -) diff --git a/src/workos/organization_membership/models/organization_membership.py b/src/workos/organization_membership/models/organization_membership.py index 53008d7f..f95f478c 100644 --- a/src/workos/organization_membership/models/organization_membership.py +++ b/src/workos/organization_membership/models/organization_membership.py @@ -6,7 +6,7 @@ from datetime import datetime from enum import Enum from typing import cast -from typing import Any, Dict, Literal, Optional +from typing import Any, Dict, List, Literal, Optional from workos._types import _raise_deserialize_error from workos._types import _format_datetime, _parse_datetime @@ -39,6 +39,8 @@ class OrganizationMembership: """An ISO 8601 timestamp.""" role: "SlimRole" """The primary role assigned to the user within the organization.""" + roles: List["SlimRole"] + """The list of roles assigned to the user within the organization.""" user: "User" """The user that belongs to the organization through this membership.""" organization_name: Optional[str] = None @@ -60,6 +62,10 @@ def from_dict(cls, data: Dict[str, Any]) -> "OrganizationMembership": created_at=_parse_datetime(data["created_at"]), updated_at=_parse_datetime(data["updated_at"]), role=SlimRole.from_dict(cast(Dict[str, Any], data["role"])), + roles=[ + SlimRole.from_dict(cast(Dict[str, Any], item)) + for item in cast(list[Any], data["roles"]) + ], user=User.from_dict(cast(Dict[str, Any], data["user"])), organization_name=data.get("organization_name"), custom_attributes=data.get("custom_attributes"), @@ -81,6 +87,7 @@ def to_dict(self) -> Dict[str, Any]: result["created_at"] = _format_datetime(self.created_at) result["updated_at"] = _format_datetime(self.updated_at) result["role"] = self.role.to_dict() + result["roles"] = [item.to_dict() for item in self.roles] result["user"] = self.user.to_dict() if self.organization_name is not None: result["organization_name"] = self.organization_name diff --git a/tests/fixtures/auth_method_mismatch_error.json b/tests/fixtures/auth_method_mismatch_error.json new file mode 100644 index 00000000..6b3ed0d2 --- /dev/null +++ b/tests/fixtures/auth_method_mismatch_error.json @@ -0,0 +1,4 @@ +{ + "code": "auth_method_mismatch", + "message": "This installation uses oauth authentication. Use the POST /:slug/token endpoint instead." +} diff --git a/tests/fixtures/list_user_organization_membership.json b/tests/fixtures/list_user_organization_membership.json index d97c4dcf..ddc8fdab 100644 --- a/tests/fixtures/list_user_organization_membership.json +++ b/tests/fixtures/list_user_organization_membership.json @@ -18,6 +18,11 @@ "role": { "slug": "admin" }, + "roles": [ + { + "slug": "admin" + } + ], "user": { "object": "user", "id": "user_01E4ZCR3C56J083X43JQXF3JK5", diff --git a/tests/fixtures/organization_membership.json b/tests/fixtures/organization_membership.json index c21b9611..2cc50650 100644 --- a/tests/fixtures/organization_membership.json +++ b/tests/fixtures/organization_membership.json @@ -16,6 +16,11 @@ "role": { "slug": "admin" }, + "roles": [ + { + "slug": "admin" + } + ], "user": { "object": "user", "id": "user_01E4ZCR3C56J083X43JQXF3JK5", diff --git a/tests/fixtures/pipes_connected_account_connection_failed.json b/tests/fixtures/pipes_connected_account_connection_failed.json new file mode 100644 index 00000000..db36784b --- /dev/null +++ b/tests/fixtures/pipes_connected_account_connection_failed.json @@ -0,0 +1,38 @@ +{ + "object": "event", + "id": "event_01EHZNVPK3SFK441A1RGBFSHRT", + "event": "pipes.connected_account.connection_failed", + "data": { + "object": "connection_failed", + "data_integration_id": "data_integration_01EHZNVPK3SFK441A1RGBFSHRT", + "provider_slug": "github", + "user_id": "user_01EHZNVPK3SFK441A1RGBFSHRT", + "organization_id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY", + "error_code": "authorization_code_exchange_error", + "error_reason": "The authorization code has expired.", + "provider_error": "access_denied", + "provider_error_description": "The user denied the authorization request.", + "created_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": {} + } + } +} diff --git a/tests/fixtures/pipes_connected_account_connection_failed_data.json b/tests/fixtures/pipes_connected_account_connection_failed_data.json new file mode 100644 index 00000000..cd5f1fc6 --- /dev/null +++ b/tests/fixtures/pipes_connected_account_connection_failed_data.json @@ -0,0 +1,12 @@ +{ + "object": "connection_failed", + "data_integration_id": "data_integration_01EHZNVPK3SFK441A1RGBFSHRT", + "provider_slug": "github", + "user_id": "user_01EHZNVPK3SFK441A1RGBFSHRT", + "organization_id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY", + "error_code": "authorization_code_exchange_error", + "error_reason": "The authorization code has expired.", + "provider_error": "access_denied", + "provider_error_description": "The user denied the authorization request.", + "created_at": "2026-01-15T12:00:00.000Z" +} diff --git a/tests/fixtures/session_reauthenticated.json b/tests/fixtures/session_reauthenticated.json new file mode 100644 index 00000000..af8ef66e --- /dev/null +++ b/tests/fixtures/session_reauthenticated.json @@ -0,0 +1,44 @@ +{ + "object": "event", + "id": "event_01EHZNVPK3SFK441A1RGBFSHRT", + "event": "session.reauthenticated", + "data": { + "object": "session", + "id": "session_01H93ZY4F80QPBEZ1R5B2SHQG8", + "impersonator": { + "email": "admin@foocorp.com", + "reason": "Investigating an issue with the customer's account." + }, + "ip_address": "198.51.100.42", + "organization_id": "org_01H945H0YD4F97JN9MATX7BYAG", + "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36", + "user_id": "user_01E4ZCR3C56J083X43JQXF3JK5", + "auth_method": "sso", + "status": "active", + "expires_at": "2026-01-15T12:00:00.000Z", + "ended_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": {} + } + } +} diff --git a/tests/fixtures/session_reauthenticated_data.json b/tests/fixtures/session_reauthenticated_data.json new file mode 100644 index 00000000..233ec56a --- /dev/null +++ b/tests/fixtures/session_reauthenticated_data.json @@ -0,0 +1,18 @@ +{ + "object": "session", + "id": "session_01H93ZY4F80QPBEZ1R5B2SHQG8", + "impersonator": { + "email": "admin@foocorp.com", + "reason": "Investigating an issue with the customer's account." + }, + "ip_address": "198.51.100.42", + "organization_id": "org_01H945H0YD4F97JN9MATX7BYAG", + "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36", + "user_id": "user_01E4ZCR3C56J083X43JQXF3JK5", + "auth_method": "sso", + "status": "active", + "expires_at": "2026-01-15T12:00:00.000Z", + "ended_at": null, + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" +} diff --git a/tests/fixtures/session_reauthenticated_data_impersonator.json b/tests/fixtures/session_reauthenticated_data_impersonator.json new file mode 100644 index 00000000..b483e3f0 --- /dev/null +++ b/tests/fixtures/session_reauthenticated_data_impersonator.json @@ -0,0 +1,4 @@ +{ + "email": "admin@foocorp.com", + "reason": "Investigating an issue with the customer's account." +} diff --git a/tests/fixtures/user_organization_membership.json b/tests/fixtures/user_organization_membership.json index 93a4fff6..127ab8db 100644 --- a/tests/fixtures/user_organization_membership.json +++ b/tests/fixtures/user_organization_membership.json @@ -16,6 +16,11 @@ "role": { "slug": "admin" }, + "roles": [ + { + "slug": "admin" + } + ], "user": { "object": "user", "id": "user_01E4ZCR3C56J083X43JQXF3JK5", diff --git a/tests/test_models_round_trip.py b/tests/test_models_round_trip.py index 162d74cd..327e2408 100644 --- a/tests/test_models_round_trip.py +++ b/tests/test_models_round_trip.py @@ -67,6 +67,7 @@ ApiKeyUpdatedData, ApiKeyUpdatedDataOwner, ApiKeyUpdatedDataPreviousAttribute, + AuthMethodMismatchError, AuthenticationEmailVerificationFailed, AuthenticationEmailVerificationFailedData, AuthenticationEmailVerificationFailedDataError, @@ -254,6 +255,8 @@ PermissionUpdatedData, PipeConnectedAccount, PipesConnectedAccountConnected, + PipesConnectedAccountConnectionFailed, + PipesConnectedAccountConnectionFailedData, PipesConnectedAccountDisconnected, PipesConnectedAccountReauthorizationNeeded, RoleCreated, @@ -265,6 +268,9 @@ SessionCreated, SessionCreatedData, SessionCreatedDataImpersonator, + SessionReauthenticated, + SessionReauthenticatedData, + SessionReauthenticatedDataImpersonator, SessionRevoked, SessionRevokedData, SessionRevokedDataImpersonator, @@ -334,10 +340,7 @@ AuthenticationFactorTotp, UserAuthenticationFactorEnrollResponse, ) -from workos.organization_domains.models import ( - OrganizationDomain, - OrganizationDomainStandAlone, -) +from workos.organization_domains.models import OrganizationDomain from workos.organization_membership.models import ( OrganizationMembership, UserOrganizationMembership, @@ -12717,6 +12720,126 @@ def test_pipes_connected_account_connected_omits_absent_optional_non_nullable_fi serialized = instance.to_dict() assert "context" not in serialized + def test_pipes_connected_account_connection_failed_round_trip(self): + data = load_fixture("pipes_connected_account_connection_failed.json") + instance = PipesConnectedAccountConnectionFailed.from_dict(data) + serialized = instance.to_dict() + assert serialized == data + restored = PipesConnectedAccountConnectionFailed.from_dict(serialized) + assert restored.to_dict() == serialized + + def test_pipes_connected_account_connection_failed_minimal_payload(self): + data = { + "object": "event", + "id": "event_01EHZNVPK3SFK441A1RGBFSHRT", + "event": "pipes.connected_account.connection_failed", + "data": { + "object": "connection_failed", + "data_integration_id": "data_integration_01EHZNVPK3SFK441A1RGBFSHRT", + "provider_slug": "github", + "user_id": "user_01EHZNVPK3SFK441A1RGBFSHRT", + "organization_id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY", + "error_code": "authorization_code_exchange_error", + "error_reason": "The authorization code has expired.", + "provider_error": "access_denied", + "provider_error_description": "The user denied the authorization request.", + "created_at": "2026-01-15T12:00:00.000Z", + }, + "created_at": "2026-01-15T12:00:00.000Z", + } + instance = PipesConnectedAccountConnectionFailed.from_dict(data) + serialized = instance.to_dict() + assert serialized["object"] == data["object"] + assert serialized["id"] == data["id"] + assert serialized["event"] == data["event"] + assert serialized["data"] == data["data"] + assert serialized["created_at"] == data["created_at"] + + def test_pipes_connected_account_connection_failed_omits_absent_optional_non_nullable_fields( + self, + ): + data = { + "object": "event", + "id": "event_01EHZNVPK3SFK441A1RGBFSHRT", + "event": "pipes.connected_account.connection_failed", + "data": { + "object": "connection_failed", + "data_integration_id": "data_integration_01EHZNVPK3SFK441A1RGBFSHRT", + "provider_slug": "github", + "user_id": "user_01EHZNVPK3SFK441A1RGBFSHRT", + "organization_id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY", + "error_code": "authorization_code_exchange_error", + "error_reason": "The authorization code has expired.", + "provider_error": "access_denied", + "provider_error_description": "The user denied the authorization request.", + "created_at": "2026-01-15T12:00:00.000Z", + }, + "created_at": "2026-01-15T12:00:00.000Z", + } + instance = PipesConnectedAccountConnectionFailed.from_dict(data) + serialized = instance.to_dict() + assert "context" not in serialized + + def test_pipes_connected_account_connection_failed_data_round_trip(self): + data = load_fixture("pipes_connected_account_connection_failed_data.json") + instance = PipesConnectedAccountConnectionFailedData.from_dict(data) + serialized = instance.to_dict() + assert serialized == data + restored = PipesConnectedAccountConnectionFailedData.from_dict(serialized) + assert restored.to_dict() == serialized + + def test_pipes_connected_account_connection_failed_data_minimal_payload(self): + data = { + "object": "connection_failed", + "data_integration_id": "data_integration_01EHZNVPK3SFK441A1RGBFSHRT", + "provider_slug": "github", + "user_id": None, + "organization_id": None, + "error_code": "authorization_code_exchange_error", + "error_reason": None, + "provider_error": None, + "provider_error_description": None, + "created_at": "2026-01-15T12:00:00.000Z", + } + instance = PipesConnectedAccountConnectionFailedData.from_dict(data) + serialized = instance.to_dict() + assert serialized["object"] == data["object"] + assert serialized["data_integration_id"] == data["data_integration_id"] + assert serialized["provider_slug"] == data["provider_slug"] + assert serialized["user_id"] == data["user_id"] + assert serialized["organization_id"] == data["organization_id"] + assert serialized["error_code"] == data["error_code"] + assert serialized["error_reason"] == data["error_reason"] + assert serialized["provider_error"] == data["provider_error"] + assert ( + serialized["provider_error_description"] + == data["provider_error_description"] + ) + assert serialized["created_at"] == data["created_at"] + + def test_pipes_connected_account_connection_failed_data_preserves_nullable_fields( + self, + ): + data = { + "object": "connection_failed", + "data_integration_id": "data_integration_01EHZNVPK3SFK441A1RGBFSHRT", + "provider_slug": "github", + "user_id": None, + "organization_id": None, + "error_code": "authorization_code_exchange_error", + "error_reason": None, + "provider_error": None, + "provider_error_description": None, + "created_at": "2026-01-15T12:00:00.000Z", + } + instance = PipesConnectedAccountConnectionFailedData.from_dict(data) + serialized = instance.to_dict() + assert serialized["user_id"] is None + assert serialized["organization_id"] is None + assert serialized["error_reason"] is None + assert serialized["provider_error"] is None + assert serialized["provider_error_description"] is None + def test_pipes_connected_account_disconnected_round_trip(self): data = load_fixture("pipes_connected_account_disconnected.json") instance = PipesConnectedAccountDisconnected.from_dict(data) @@ -13288,6 +13411,201 @@ def test_session_created_data_impersonator_preserves_nullable_fields(self): serialized = instance.to_dict() assert serialized["reason"] is None + def test_session_reauthenticated_round_trip(self): + data = load_fixture("session_reauthenticated.json") + instance = SessionReauthenticated.from_dict(data) + serialized = instance.to_dict() + assert serialized == data + restored = SessionReauthenticated.from_dict(serialized) + assert restored.to_dict() == serialized + + def test_session_reauthenticated_minimal_payload(self): + data = { + "object": "event", + "id": "event_01EHZNVPK3SFK441A1RGBFSHRT", + "event": "session.reauthenticated", + "data": { + "object": "session", + "id": "session_01H93ZY4F80QPBEZ1R5B2SHQG8", + "impersonator": { + "email": "admin@foocorp.com", + "reason": "Investigating an issue with the customer's account.", + }, + "ip_address": "198.51.100.42", + "organization_id": "org_01H945H0YD4F97JN9MATX7BYAG", + "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36", + "user_id": "user_01E4ZCR3C56J083X43JQXF3JK5", + "auth_method": "sso", + "status": "active", + "expires_at": "2026-01-15T12:00:00.000Z", + "ended_at": None, + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z", + }, + "created_at": "2026-01-15T12:00:00.000Z", + } + instance = SessionReauthenticated.from_dict(data) + serialized = instance.to_dict() + assert serialized["object"] == data["object"] + assert serialized["id"] == data["id"] + assert serialized["event"] == data["event"] + assert serialized["data"] == data["data"] + assert serialized["created_at"] == data["created_at"] + + def test_session_reauthenticated_omits_absent_optional_non_nullable_fields(self): + data = { + "object": "event", + "id": "event_01EHZNVPK3SFK441A1RGBFSHRT", + "event": "session.reauthenticated", + "data": { + "object": "session", + "id": "session_01H93ZY4F80QPBEZ1R5B2SHQG8", + "impersonator": { + "email": "admin@foocorp.com", + "reason": "Investigating an issue with the customer's account.", + }, + "ip_address": "198.51.100.42", + "organization_id": "org_01H945H0YD4F97JN9MATX7BYAG", + "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36", + "user_id": "user_01E4ZCR3C56J083X43JQXF3JK5", + "auth_method": "sso", + "status": "active", + "expires_at": "2026-01-15T12:00:00.000Z", + "ended_at": None, + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z", + }, + "created_at": "2026-01-15T12:00:00.000Z", + } + instance = SessionReauthenticated.from_dict(data) + serialized = instance.to_dict() + assert "context" not in serialized + + def test_session_reauthenticated_data_round_trip(self): + data = load_fixture("session_reauthenticated_data.json") + instance = SessionReauthenticatedData.from_dict(data) + serialized = instance.to_dict() + assert serialized == data + restored = SessionReauthenticatedData.from_dict(serialized) + assert restored.to_dict() == serialized + + def test_session_reauthenticated_data_minimal_payload(self): + data = { + "object": "session", + "id": "session_01H93ZY4F80QPBEZ1R5B2SHQG8", + "ip_address": None, + "user_agent": None, + "user_id": "user_01E4ZCR3C56J083X43JQXF3JK5", + "auth_method": "sso", + "status": "active", + "expires_at": "2026-01-15T12:00:00.000Z", + "ended_at": None, + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z", + } + instance = SessionReauthenticatedData.from_dict(data) + serialized = instance.to_dict() + assert serialized["object"] == data["object"] + assert serialized["id"] == data["id"] + assert serialized["ip_address"] == data["ip_address"] + assert serialized["user_agent"] == data["user_agent"] + assert serialized["user_id"] == data["user_id"] + assert serialized["auth_method"] == data["auth_method"] + assert serialized["status"] == data["status"] + assert serialized["expires_at"] == data["expires_at"] + assert serialized["ended_at"] == data["ended_at"] + assert serialized["created_at"] == data["created_at"] + assert serialized["updated_at"] == data["updated_at"] + + def test_session_reauthenticated_data_omits_absent_optional_non_nullable_fields( + self, + ): + data = { + "object": "session", + "id": "session_01H93ZY4F80QPBEZ1R5B2SHQG8", + "ip_address": "198.51.100.42", + "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36", + "user_id": "user_01E4ZCR3C56J083X43JQXF3JK5", + "auth_method": "sso", + "status": "active", + "expires_at": "2026-01-15T12:00:00.000Z", + "ended_at": None, + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z", + } + instance = SessionReauthenticatedData.from_dict(data) + serialized = instance.to_dict() + assert "impersonator" not in serialized + assert "organization_id" not in serialized + + def test_session_reauthenticated_data_preserves_nullable_fields(self): + data = { + "object": "session", + "id": "session_01H93ZY4F80QPBEZ1R5B2SHQG8", + "impersonator": { + "email": "admin@foocorp.com", + "reason": "Investigating an issue with the customer's account.", + }, + "ip_address": None, + "organization_id": "org_01H945H0YD4F97JN9MATX7BYAG", + "user_agent": None, + "user_id": "user_01E4ZCR3C56J083X43JQXF3JK5", + "auth_method": "sso", + "status": "active", + "expires_at": "2026-01-15T12:00:00.000Z", + "ended_at": None, + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z", + } + instance = SessionReauthenticatedData.from_dict(data) + serialized = instance.to_dict() + assert serialized["ip_address"] is None + assert serialized["user_agent"] is None + assert serialized["ended_at"] is None + + def test_session_reauthenticated_data_round_trips_unknown_enum_values(self): + data = { + "object": "session", + "id": "session_01H93ZY4F80QPBEZ1R5B2SHQG8", + "impersonator": { + "email": "admin@foocorp.com", + "reason": "Investigating an issue with the customer's account.", + }, + "ip_address": "198.51.100.42", + "organization_id": "org_01H945H0YD4F97JN9MATX7BYAG", + "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36", + "user_id": "user_01E4ZCR3C56J083X43JQXF3JK5", + "auth_method": "unexpected_session_reauthenticated_data_auth_method", + "status": "active", + "expires_at": "2026-01-15T12:00:00.000Z", + "ended_at": None, + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z", + } + instance = SessionReauthenticatedData.from_dict(data) + assert instance.to_dict() == data + + def test_session_reauthenticated_data_impersonator_round_trip(self): + data = load_fixture("session_reauthenticated_data_impersonator.json") + instance = SessionReauthenticatedDataImpersonator.from_dict(data) + serialized = instance.to_dict() + assert serialized == data + restored = SessionReauthenticatedDataImpersonator.from_dict(serialized) + assert restored.to_dict() == serialized + + def test_session_reauthenticated_data_impersonator_minimal_payload(self): + data = {"email": "admin@foocorp.com", "reason": None} + instance = SessionReauthenticatedDataImpersonator.from_dict(data) + serialized = instance.to_dict() + assert serialized["email"] == data["email"] + assert serialized["reason"] == data["reason"] + + def test_session_reauthenticated_data_impersonator_preserves_nullable_fields(self): + data = {"email": "admin@foocorp.com", "reason": None} + instance = SessionReauthenticatedDataImpersonator.from_dict(data) + serialized = instance.to_dict() + assert serialized["reason"] is None + def test_session_revoked_round_trip(self): data = load_fixture("session_revoked.json") instance = SessionRevoked.from_dict(data) @@ -14712,66 +15030,6 @@ def test_waitlist_user_denied_omits_absent_optional_non_nullable_fields(self): serialized = instance.to_dict() assert "context" not in serialized - def test_organization_domain_stand_alone_round_trip(self): - data = load_fixture("organization_domain_stand_alone.json") - instance = OrganizationDomainStandAlone.from_dict(data) - serialized = instance.to_dict() - assert serialized == data - restored = OrganizationDomainStandAlone.from_dict(serialized) - assert restored.to_dict() == serialized - - def test_organization_domain_stand_alone_minimal_payload(self): - data = { - "object": "organization_domain", - "id": "org_domain_01EHZNVPK2QXHMVWCEDQEKY69A", - "organization_id": "org_01HE8GSH8FQPASKSY27THRKRBP", - "domain": "foo-corp.com", - "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z", - } - instance = OrganizationDomainStandAlone.from_dict(data) - serialized = instance.to_dict() - assert serialized["object"] == data["object"] - assert serialized["id"] == data["id"] - assert serialized["organization_id"] == data["organization_id"] - assert serialized["domain"] == data["domain"] - assert serialized["created_at"] == data["created_at"] - assert serialized["updated_at"] == data["updated_at"] - - def test_organization_domain_stand_alone_omits_absent_optional_non_nullable_fields( - self, - ): - data = { - "object": "organization_domain", - "id": "org_domain_01EHZNVPK2QXHMVWCEDQEKY69A", - "organization_id": "org_01HE8GSH8FQPASKSY27THRKRBP", - "domain": "foo-corp.com", - "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z", - } - instance = OrganizationDomainStandAlone.from_dict(data) - serialized = instance.to_dict() - assert "state" not in serialized - assert "verification_prefix" not in serialized - assert "verification_token" not in serialized - assert "verification_strategy" not in serialized - - def test_organization_domain_stand_alone_round_trips_unknown_enum_values(self): - data = { - "object": "organization_domain", - "id": "org_domain_01EHZNVPK2QXHMVWCEDQEKY69A", - "organization_id": "org_01HE8GSH8FQPASKSY27THRKRBP", - "domain": "foo-corp.com", - "state": "unexpected_organization_domain_stand_alone_state", - "verification_prefix": "superapp-domain-verification-z3kjny", - "verification_token": "m5Oztg3jdK4NJLgs8uIlIprMw", - "verification_strategy": "dns", - "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z", - } - instance = OrganizationDomainStandAlone.from_dict(data) - assert instance.to_dict() == data - def test_flag_round_trip(self): data = load_fixture("flag.json") instance = Flag.from_dict(data) @@ -15298,6 +15556,24 @@ def test_data_integration_access_token_response_round_trips_unknown_enum_values( instance = DataIntegrationAccessTokenResponse.from_dict(data) assert instance.to_dict() == data + def test_auth_method_mismatch_error_round_trip(self): + data = load_fixture("auth_method_mismatch_error.json") + instance = AuthMethodMismatchError.from_dict(data) + serialized = instance.to_dict() + assert serialized == data + restored = AuthMethodMismatchError.from_dict(serialized) + assert restored.to_dict() == serialized + + def test_auth_method_mismatch_error_minimal_payload(self): + data = { + "code": "auth_method_mismatch", + "message": "This installation uses oauth authentication. Use the POST /:slug/token endpoint instead.", + } + instance = AuthMethodMismatchError.from_dict(data) + serialized = instance.to_dict() + assert serialized["code"] == data["code"] + assert serialized["message"] == data["message"] + def test_connected_account_round_trip(self): data = load_fixture("connected_account.json") instance = ConnectedAccount.from_dict(data) @@ -15707,6 +15983,7 @@ def test_user_organization_membership_minimal_payload(self): "created_at": "2026-01-15T12:00:00.000Z", "updated_at": "2026-01-15T12:00:00.000Z", "role": {"slug": "admin"}, + "roles": [{"slug": "admin"}], "user": { "object": "user", "id": "user_01E4ZCR3C56J083X43JQXF3JK5", @@ -15735,6 +16012,7 @@ def test_user_organization_membership_minimal_payload(self): assert serialized["created_at"] == data["created_at"] assert serialized["updated_at"] == data["updated_at"] assert serialized["role"] == data["role"] + assert serialized["roles"] == data["roles"] assert serialized["user"] == data["user"] def test_user_organization_membership_omits_absent_optional_non_nullable_fields( @@ -15750,6 +16028,7 @@ def test_user_organization_membership_omits_absent_optional_non_nullable_fields( "created_at": "2026-01-15T12:00:00.000Z", "updated_at": "2026-01-15T12:00:00.000Z", "role": {"slug": "admin"}, + "roles": [{"slug": "admin"}], "user": { "object": "user", "id": "user_01E4ZCR3C56J083X43JQXF3JK5", @@ -15789,6 +16068,7 @@ def test_user_organization_membership_round_trips_unknown_enum_values(self): "created_at": "2026-01-15T12:00:00.000Z", "updated_at": "2026-01-15T12:00:00.000Z", "role": {"slug": "admin"}, + "roles": [{"slug": "admin"}], "user": { "object": "user", "id": "user_01E4ZCR3C56J083X43JQXF3JK5", @@ -16587,6 +16867,64 @@ def test_jwt_template_response_minimal_payload(self): assert serialized["created_at"] == data["created_at"] assert serialized["updated_at"] == data["updated_at"] + def test_organization_domain_round_trip(self): + data = load_fixture("organization_domain.json") + instance = OrganizationDomain.from_dict(data) + serialized = instance.to_dict() + assert serialized == data + restored = OrganizationDomain.from_dict(serialized) + assert restored.to_dict() == serialized + + def test_organization_domain_minimal_payload(self): + data = { + "object": "organization_domain", + "id": "org_domain_01EHZNVPK2QXHMVWCEDQEKY69A", + "organization_id": "org_01HE8GSH8FQPASKSY27THRKRBP", + "domain": "foo-corp.com", + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z", + } + instance = OrganizationDomain.from_dict(data) + serialized = instance.to_dict() + assert serialized["object"] == data["object"] + assert serialized["id"] == data["id"] + assert serialized["organization_id"] == data["organization_id"] + assert serialized["domain"] == data["domain"] + assert serialized["created_at"] == data["created_at"] + assert serialized["updated_at"] == data["updated_at"] + + def test_organization_domain_omits_absent_optional_non_nullable_fields(self): + data = { + "object": "organization_domain", + "id": "org_domain_01EHZNVPK2QXHMVWCEDQEKY69A", + "organization_id": "org_01HE8GSH8FQPASKSY27THRKRBP", + "domain": "foo-corp.com", + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z", + } + instance = OrganizationDomain.from_dict(data) + serialized = instance.to_dict() + assert "state" not in serialized + assert "verification_prefix" not in serialized + assert "verification_token" not in serialized + assert "verification_strategy" not in serialized + + def test_organization_domain_round_trips_unknown_enum_values(self): + data = { + "object": "organization_domain", + "id": "org_domain_01EHZNVPK2QXHMVWCEDQEKY69A", + "organization_id": "org_01HE8GSH8FQPASKSY27THRKRBP", + "domain": "foo-corp.com", + "state": "unexpected_organization_domain_state", + "verification_prefix": "superapp-domain-verification-z3kjny", + "verification_token": "m5Oztg3jdK4NJLgs8uIlIprMw", + "verification_strategy": "dns", + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z", + } + instance = OrganizationDomain.from_dict(data) + assert instance.to_dict() == data + def test_jwks_response_keys_round_trip(self): data = load_fixture("jwks_response_keys.json") instance = JwksResponseKeys.from_dict(data) @@ -16935,64 +17273,6 @@ def test_audit_log_configuration_log_stream_round_trips_unknown_enum_values(self instance = AuditLogConfigurationLogStream.from_dict(data) assert instance.to_dict() == data - def test_organization_domain_round_trip(self): - data = load_fixture("organization_domain.json") - instance = OrganizationDomain.from_dict(data) - serialized = instance.to_dict() - assert serialized == data - restored = OrganizationDomain.from_dict(serialized) - assert restored.to_dict() == serialized - - def test_organization_domain_minimal_payload(self): - data = { - "object": "organization_domain", - "id": "org_domain_01EHZNVPK2QXHMVWCEDQEKY69A", - "organization_id": "org_01HE8GSH8FQPASKSY27THRKRBP", - "domain": "foo-corp.com", - "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z", - } - instance = OrganizationDomain.from_dict(data) - serialized = instance.to_dict() - assert serialized["object"] == data["object"] - assert serialized["id"] == data["id"] - assert serialized["organization_id"] == data["organization_id"] - assert serialized["domain"] == data["domain"] - assert serialized["created_at"] == data["created_at"] - assert serialized["updated_at"] == data["updated_at"] - - def test_organization_domain_omits_absent_optional_non_nullable_fields(self): - data = { - "object": "organization_domain", - "id": "org_domain_01EHZNVPK2QXHMVWCEDQEKY69A", - "organization_id": "org_01HE8GSH8FQPASKSY27THRKRBP", - "domain": "foo-corp.com", - "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z", - } - instance = OrganizationDomain.from_dict(data) - serialized = instance.to_dict() - assert "state" not in serialized - assert "verification_prefix" not in serialized - assert "verification_token" not in serialized - assert "verification_strategy" not in serialized - - def test_organization_domain_round_trips_unknown_enum_values(self): - data = { - "object": "organization_domain", - "id": "org_domain_01EHZNVPK2QXHMVWCEDQEKY69A", - "organization_id": "org_01HE8GSH8FQPASKSY27THRKRBP", - "domain": "foo-corp.com", - "state": "unexpected_organization_domain_state", - "verification_prefix": "superapp-domain-verification-z3kjny", - "verification_token": "m5Oztg3jdK4NJLgs8uIlIprMw", - "verification_strategy": "dns", - "created_at": "2026-01-15T12:00:00.000Z", - "updated_at": "2026-01-15T12:00:00.000Z", - } - instance = OrganizationDomain.from_dict(data) - assert instance.to_dict() == data - def test_organization_api_key_with_value_owner_round_trip(self): data = load_fixture("organization_api_key_with_value_owner.json") instance = OrganizationApiKeyWithValueOwner.from_dict(data) @@ -17838,6 +18118,7 @@ def test_organization_membership_minimal_payload(self): "created_at": "2026-01-15T12:00:00.000Z", "updated_at": "2026-01-15T12:00:00.000Z", "role": {"slug": "admin"}, + "roles": [{"slug": "admin"}], "user": { "object": "user", "id": "user_01E4ZCR3C56J083X43JQXF3JK5", @@ -17866,6 +18147,7 @@ def test_organization_membership_minimal_payload(self): assert serialized["created_at"] == data["created_at"] assert serialized["updated_at"] == data["updated_at"] assert serialized["role"] == data["role"] + assert serialized["roles"] == data["roles"] assert serialized["user"] == data["user"] def test_organization_membership_omits_absent_optional_non_nullable_fields(self): @@ -17879,6 +18161,7 @@ def test_organization_membership_omits_absent_optional_non_nullable_fields(self) "created_at": "2026-01-15T12:00:00.000Z", "updated_at": "2026-01-15T12:00:00.000Z", "role": {"slug": "admin"}, + "roles": [{"slug": "admin"}], "user": { "object": "user", "id": "user_01E4ZCR3C56J083X43JQXF3JK5", @@ -17918,6 +18201,7 @@ def test_organization_membership_round_trips_unknown_enum_values(self): "created_at": "2026-01-15T12:00:00.000Z", "updated_at": "2026-01-15T12:00:00.000Z", "role": {"slug": "admin"}, + "roles": [{"slug": "admin"}], "user": { "object": "user", "id": "user_01E4ZCR3C56J083X43JQXF3JK5", From fb39a285a0fb2bcb0606da0bb845ca2efc971150 Mon Sep 17 00:00:00 2001 From: "workos-sdk-automation[bot]" <255426317+workos-sdk-automation[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 13:51:10 +0000 Subject: [PATCH 2/2] chore(generated): add release notes fragment --- ...6-25T13-51-10-75604c7277a4d4f18269108cf038ab394ee25402.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changelog-pending/2026-06-25T13-51-10-75604c7277a4d4f18269108cf038ab394ee25402.md diff --git a/.changelog-pending/2026-06-25T13-51-10-75604c7277a4d4f18269108cf038ab394ee25402.md b/.changelog-pending/2026-06-25T13-51-10-75604c7277a4d4f18269108cf038ab394ee25402.md new file mode 100644 index 00000000..043620b6 --- /dev/null +++ b/.changelog-pending/2026-06-25T13-51-10-75604c7277a4d4f18269108cf038ab394ee25402.md @@ -0,0 +1,5 @@ +* [#675](https://github.com/workos/workos-python/pull/675) fix(generated): regenerate from spec + + **Fixes** + * **[organization_membership](https://workos.com/docs/reference/authkit/organization-membership)**: + * Added `roles` to organization membership models