workos 5.27.0__tar.gz → 5.28.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {workos-5.27.0 → workos-5.28.0}/PKG-INFO +1 -1
- {workos-5.27.0 → workos-5.28.0}/tests/test_session.py +80 -6
- {workos-5.27.0 → workos-5.28.0}/workos/__about__.py +1 -1
- {workos-5.27.0 → workos-5.28.0}/workos/session.py +3 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/organization_membership.py +2 -1
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/session.py +4 -1
- {workos-5.27.0 → workos-5.28.0}/workos/types/webhooks/webhook.py +20 -3
- {workos-5.27.0 → workos-5.28.0}/workos/user_management.py +51 -12
- {workos-5.27.0 → workos-5.28.0}/workos.egg-info/PKG-INFO +1 -1
- {workos-5.27.0 → workos-5.28.0}/LICENSE +0 -0
- {workos-5.27.0 → workos-5.28.0}/README.md +0 -0
- {workos-5.27.0 → workos-5.28.0}/setup.cfg +0 -0
- {workos-5.27.0 → workos-5.28.0}/setup.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_async_http_client.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_audit_logs.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_client.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_directory_sync.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_events.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_fga.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_mfa.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_organization_domains.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_organizations.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_passwordless.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_portal.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_sso.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_sync_http_client.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_user_management.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_vault.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_webhooks.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/tests/test_widgets.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/_base_client.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/_client_configuration.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/async_client.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/audit_logs.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/client.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/directory_sync.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/events.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/exceptions.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/fga.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/mfa.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/organization_domains.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/organizations.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/passwordless.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/portal.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/py.typed +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/sso.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/audit_logs/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/audit_logs/audit_log_event.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/audit_logs/audit_log_event_actor.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/audit_logs/audit_log_event_context.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/audit_logs/audit_log_event_target.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/audit_logs/audit_log_export.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/audit_logs/audit_log_metadata.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/directory_sync/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/directory_sync/directory.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/directory_sync/directory_group.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/directory_sync/directory_state.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/directory_sync/directory_type.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/directory_sync/directory_user.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/directory_sync/list_filters.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/events/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/events/authentication_payload.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/events/connection_payload_with_legacy_fields.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/events/directory_group_membership_payload.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/events/directory_group_with_previous_attributes.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/events/directory_payload.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/events/directory_payload_with_legacy_fields.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/events/directory_user_with_previous_attributes.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/events/event.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/events/event_model.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/events/event_type.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/events/list_filters.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/events/organization_domain_verification_failed_payload.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/events/previous_attributes.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/events/session_created_payload.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/fga/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/fga/authorization_resource_types.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/fga/authorization_resources.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/fga/check.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/fga/list_filters.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/fga/warnings.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/fga/warrant.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/list_resource.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/metadata.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/mfa/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/mfa/authentication_challenge.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/mfa/authentication_challenge_verification_response.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/mfa/authentication_factor.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/mfa/authentication_factor_totp_and_challenge_response.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/mfa/enroll_authentication_factor_type.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/organization_domains/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/organization_domains/organization_domain.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/organizations/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/organizations/domain_data_input.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/organizations/list_filters.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/organizations/organization.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/organizations/organization_common.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/passwordless/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/passwordless/passwordless_session.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/passwordless/passwordless_session_type.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/portal/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/portal/portal_link.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/portal/portal_link_intent.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/portal/portal_link_intent_options.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/roles/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/roles/role.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/sso/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/sso/connection.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/sso/connection_domain.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/sso/profile.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/sso/sso_provider_type.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/authenticate_with_common.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/authentication_response.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/email_verification.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/impersonator.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/invitation.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/list_filters.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/magic_auth.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/oauth_tokens.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/password_hash_type.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/password_reset.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/screen_hint.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/user.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/user_management/user_management_provider_type.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/vault/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/vault/key.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/vault/object.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/webhooks/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/webhooks/webhook_model.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/webhooks/webhook_payload.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/widgets/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/widgets/widget_scope.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/widgets/widget_token_response.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/types/workos_model.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/typing/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/typing/literals.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/typing/sync_or_async.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/typing/untyped_literal.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/typing/webhooks.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/utils/__init__.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/utils/_base_http_client.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/utils/crypto_provider.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/utils/http_client.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/utils/pagination_order.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/utils/request_helper.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/vault.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/webhooks.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos/widgets.py +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos.egg-info/SOURCES.txt +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos.egg-info/dependency_links.txt +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos.egg-info/not-zip-safe +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos.egg-info/requires.txt +0 -0
- {workos-5.27.0 → workos-5.28.0}/workos.egg-info/top_level.txt +0 -0
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import concurrent.futures
|
|
2
|
+
from datetime import datetime, timezone
|
|
2
3
|
from unittest.mock import AsyncMock, Mock, patch
|
|
4
|
+
|
|
3
5
|
import jwt
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
+
import pytest
|
|
7
|
+
from cryptography.hazmat.primitives import serialization
|
|
8
|
+
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
6
9
|
|
|
7
10
|
from tests.conftest import with_jwks_mock
|
|
8
11
|
from workos.session import AsyncSession, Session, _get_jwks_client
|
|
@@ -16,9 +19,6 @@ from workos.types.user_management.session import (
|
|
|
16
19
|
RefreshWithSessionCookieSuccessResponse,
|
|
17
20
|
)
|
|
18
21
|
|
|
19
|
-
from cryptography.hazmat.primitives import serialization
|
|
20
|
-
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
21
|
-
|
|
22
22
|
|
|
23
23
|
class SessionFixtures:
|
|
24
24
|
@pytest.fixture(autouse=True)
|
|
@@ -48,6 +48,7 @@ class SessionFixtures:
|
|
|
48
48
|
"sid": "session_123",
|
|
49
49
|
"org_id": "organization_123",
|
|
50
50
|
"role": "admin",
|
|
51
|
+
"roles": ["admin"],
|
|
51
52
|
"permissions": ["read"],
|
|
52
53
|
"entitlements": ["feature_1"],
|
|
53
54
|
"exp": int(current_datetime.timestamp()) + 3600,
|
|
@@ -215,6 +216,7 @@ class TestSessionBase(SessionFixtures):
|
|
|
215
216
|
"sid": session_constants["SESSION_ID"],
|
|
216
217
|
"org_id": session_constants["ORGANIZATION_ID"],
|
|
217
218
|
"role": "admin",
|
|
219
|
+
"roles": ["admin"],
|
|
218
220
|
"permissions": ["read"],
|
|
219
221
|
"entitlements": ["feature_1"],
|
|
220
222
|
"exp": int(datetime.now(timezone.utc).timestamp()) + 3600,
|
|
@@ -239,6 +241,7 @@ class TestSessionBase(SessionFixtures):
|
|
|
239
241
|
"sid": session_constants["SESSION_ID"],
|
|
240
242
|
"org_id": session_constants["ORGANIZATION_ID"],
|
|
241
243
|
"role": "admin",
|
|
244
|
+
"roles": ["admin"],
|
|
242
245
|
"permissions": ["read"],
|
|
243
246
|
"entitlements": ["feature_1"],
|
|
244
247
|
}
|
|
@@ -257,11 +260,80 @@ class TestSessionBase(SessionFixtures):
|
|
|
257
260
|
assert response.session_id == session_constants["SESSION_ID"]
|
|
258
261
|
assert response.organization_id == session_constants["ORGANIZATION_ID"]
|
|
259
262
|
assert response.role == "admin"
|
|
263
|
+
assert response.roles == ["admin"]
|
|
260
264
|
assert response.permissions == ["read"]
|
|
261
265
|
assert response.entitlements == ["feature_1"]
|
|
262
266
|
assert response.user.id == session_constants["USER_ID"]
|
|
263
267
|
assert response.impersonator is None
|
|
264
268
|
|
|
269
|
+
@with_jwks_mock
|
|
270
|
+
def test_authenticate_success_with_roles(
|
|
271
|
+
self, session_constants, mock_user_management
|
|
272
|
+
):
|
|
273
|
+
session = Session(
|
|
274
|
+
user_management=mock_user_management,
|
|
275
|
+
client_id=session_constants["CLIENT_ID"],
|
|
276
|
+
session_data=session_constants["SESSION_DATA"],
|
|
277
|
+
cookie_password=session_constants["COOKIE_PASSWORD"],
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
# Mock the session data that would be unsealed
|
|
281
|
+
mock_session = {
|
|
282
|
+
"access_token": jwt.encode(
|
|
283
|
+
{
|
|
284
|
+
"sid": session_constants["SESSION_ID"],
|
|
285
|
+
"org_id": session_constants["ORGANIZATION_ID"],
|
|
286
|
+
"role": "admin",
|
|
287
|
+
"roles": ["admin", "member"],
|
|
288
|
+
"permissions": ["read", "write"],
|
|
289
|
+
"entitlements": ["feature_1"],
|
|
290
|
+
"exp": int(datetime.now(timezone.utc).timestamp()) + 3600,
|
|
291
|
+
"iat": int(datetime.now(timezone.utc).timestamp()),
|
|
292
|
+
},
|
|
293
|
+
session_constants["PRIVATE_KEY"],
|
|
294
|
+
algorithm="RS256",
|
|
295
|
+
),
|
|
296
|
+
"user": {
|
|
297
|
+
"object": "user",
|
|
298
|
+
"id": session_constants["USER_ID"],
|
|
299
|
+
"email": "user@example.com",
|
|
300
|
+
"email_verified": True,
|
|
301
|
+
"created_at": session_constants["CURRENT_TIMESTAMP"],
|
|
302
|
+
"updated_at": session_constants["CURRENT_TIMESTAMP"],
|
|
303
|
+
},
|
|
304
|
+
"impersonator": None,
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
# Mock the JWT payload that would be decoded
|
|
308
|
+
mock_jwt_payload = {
|
|
309
|
+
"sid": session_constants["SESSION_ID"],
|
|
310
|
+
"org_id": session_constants["ORGANIZATION_ID"],
|
|
311
|
+
"role": "admin",
|
|
312
|
+
"roles": ["admin", "member"],
|
|
313
|
+
"permissions": ["read", "write"],
|
|
314
|
+
"entitlements": ["feature_1"],
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
with patch.object(Session, "unseal_data", return_value=mock_session), patch(
|
|
318
|
+
"jwt.decode", return_value=mock_jwt_payload
|
|
319
|
+
), patch.object(
|
|
320
|
+
session.jwks,
|
|
321
|
+
"get_signing_key_from_jwt",
|
|
322
|
+
return_value=Mock(key=session_constants["PUBLIC_KEY"]),
|
|
323
|
+
):
|
|
324
|
+
response = session.authenticate()
|
|
325
|
+
|
|
326
|
+
assert isinstance(response, AuthenticateWithSessionCookieSuccessResponse)
|
|
327
|
+
assert response.authenticated is True
|
|
328
|
+
assert response.session_id == session_constants["SESSION_ID"]
|
|
329
|
+
assert response.organization_id == session_constants["ORGANIZATION_ID"]
|
|
330
|
+
assert response.role == "admin"
|
|
331
|
+
assert response.roles == ["admin", "member"]
|
|
332
|
+
assert response.permissions == ["read", "write"]
|
|
333
|
+
assert response.entitlements == ["feature_1"]
|
|
334
|
+
assert response.user.id == session_constants["USER_ID"]
|
|
335
|
+
assert response.impersonator is None
|
|
336
|
+
|
|
265
337
|
@with_jwks_mock
|
|
266
338
|
def test_refresh_invalid_session_cookie(
|
|
267
339
|
self, session_constants, mock_user_management
|
|
@@ -335,6 +407,7 @@ class TestSession(SessionFixtures):
|
|
|
335
407
|
"sid": session_constants["SESSION_ID"],
|
|
336
408
|
"org_id": session_constants["ORGANIZATION_ID"],
|
|
337
409
|
"role": "admin",
|
|
410
|
+
"roles": ["admin"],
|
|
338
411
|
"permissions": ["read"],
|
|
339
412
|
"entitlements": ["feature_1"],
|
|
340
413
|
},
|
|
@@ -435,6 +508,7 @@ class TestAsyncSession(SessionFixtures):
|
|
|
435
508
|
"sid": session_constants["SESSION_ID"],
|
|
436
509
|
"org_id": session_constants["ORGANIZATION_ID"],
|
|
437
510
|
"role": "admin",
|
|
511
|
+
"roles": ["admin"],
|
|
438
512
|
"permissions": ["read"],
|
|
439
513
|
"entitlements": ["feature_1"],
|
|
440
514
|
},
|
|
@@ -102,6 +102,7 @@ class SessionModule(Protocol):
|
|
|
102
102
|
session_id=decoded["sid"],
|
|
103
103
|
organization_id=decoded.get("org_id", None),
|
|
104
104
|
role=decoded.get("role", None),
|
|
105
|
+
roles=decoded.get("roles", None),
|
|
105
106
|
permissions=decoded.get("permissions", None),
|
|
106
107
|
entitlements=decoded.get("entitlements", None),
|
|
107
108
|
user=session["user"],
|
|
@@ -229,6 +230,7 @@ class Session(SessionModule):
|
|
|
229
230
|
session_id=decoded["sid"],
|
|
230
231
|
organization_id=decoded.get("org_id", None),
|
|
231
232
|
role=decoded.get("role", None),
|
|
233
|
+
roles=decoded.get("roles", None),
|
|
232
234
|
permissions=decoded.get("permissions", None),
|
|
233
235
|
entitlements=decoded.get("entitlements", None),
|
|
234
236
|
user=auth_response.user,
|
|
@@ -319,6 +321,7 @@ class AsyncSession(SessionModule):
|
|
|
319
321
|
session_id=decoded["sid"],
|
|
320
322
|
organization_id=decoded.get("org_id", None),
|
|
321
323
|
role=decoded.get("role", None),
|
|
324
|
+
roles=decoded.get("roles", None),
|
|
322
325
|
permissions=decoded.get("permissions", None),
|
|
323
326
|
entitlements=decoded.get("entitlements", None),
|
|
324
327
|
user=auth_response.user,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Literal
|
|
1
|
+
from typing import Literal, Sequence, Optional
|
|
2
2
|
from typing_extensions import TypedDict
|
|
3
3
|
|
|
4
4
|
from workos.types.workos_model import WorkOSModel
|
|
@@ -19,6 +19,7 @@ class OrganizationMembership(WorkOSModel):
|
|
|
19
19
|
user_id: str
|
|
20
20
|
organization_id: str
|
|
21
21
|
role: OrganizationMembershipRole
|
|
22
|
+
roles: Optional[Sequence[OrganizationMembershipRole]] = None
|
|
22
23
|
status: LiteralOrUntyped[OrganizationMembershipStatus]
|
|
23
24
|
created_at: str
|
|
24
25
|
updated_at: str
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
from typing import Optional, Sequence, TypedDict, Union
|
|
2
1
|
from enum import Enum
|
|
2
|
+
from typing import Optional, Sequence, TypedDict, Union
|
|
3
|
+
|
|
3
4
|
from typing_extensions import Literal
|
|
5
|
+
|
|
4
6
|
from workos.types.user_management.impersonator import Impersonator
|
|
5
7
|
from workos.types.user_management.user import User
|
|
6
8
|
from workos.types.workos_model import WorkOSModel
|
|
@@ -17,6 +19,7 @@ class AuthenticateWithSessionCookieSuccessResponse(WorkOSModel):
|
|
|
17
19
|
session_id: str
|
|
18
20
|
organization_id: Optional[str] = None
|
|
19
21
|
role: Optional[str] = None
|
|
22
|
+
roles: Optional[Sequence[str]] = None
|
|
20
23
|
permissions: Optional[Sequence[str]] = None
|
|
21
24
|
user: User
|
|
22
25
|
impersonator: Optional[Impersonator] = None
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from typing import Literal, Union
|
|
2
|
+
|
|
2
3
|
from pydantic import Field
|
|
3
4
|
from typing_extensions import Annotated
|
|
5
|
+
|
|
4
6
|
from workos.types.directory_sync import DirectoryGroup
|
|
5
|
-
from workos.types.user_management import OrganizationMembership, User
|
|
6
|
-
from workos.types.webhooks.webhook_model import WebhookModel
|
|
7
7
|
from workos.types.directory_sync.directory_user import DirectoryUser
|
|
8
8
|
from workos.types.events.authentication_payload import (
|
|
9
9
|
AuthenticationEmailVerificationSucceededPayload,
|
|
@@ -37,16 +37,18 @@ from workos.types.events.organization_domain_verification_failed_payload import
|
|
|
37
37
|
OrganizationDomainVerificationFailedPayload,
|
|
38
38
|
)
|
|
39
39
|
from workos.types.events.session_created_payload import SessionCreatedPayload
|
|
40
|
-
from workos.types.organizations.organization_common import OrganizationCommon
|
|
41
40
|
from workos.types.organization_domains import OrganizationDomain
|
|
41
|
+
from workos.types.organizations.organization_common import OrganizationCommon
|
|
42
42
|
from workos.types.roles.role import EventRole
|
|
43
43
|
from workos.types.sso.connection import Connection
|
|
44
|
+
from workos.types.user_management import OrganizationMembership, User
|
|
44
45
|
from workos.types.user_management.email_verification import (
|
|
45
46
|
EmailVerificationCommon,
|
|
46
47
|
)
|
|
47
48
|
from workos.types.user_management.invitation import InvitationCommon
|
|
48
49
|
from workos.types.user_management.magic_auth import MagicAuthCommon
|
|
49
50
|
from workos.types.user_management.password_reset import PasswordResetCommon
|
|
51
|
+
from workos.types.webhooks.webhook_model import WebhookModel
|
|
50
52
|
|
|
51
53
|
# README
|
|
52
54
|
# When adding a new webhook event type, ensure the new webhook class is
|
|
@@ -205,6 +207,18 @@ class OrganizationDomainVerifiedWebhook(WebhookModel[OrganizationDomain]):
|
|
|
205
207
|
event: Literal["organization_domain.verified"]
|
|
206
208
|
|
|
207
209
|
|
|
210
|
+
class OrganizationDomainCreatedWebhook(WebhookModel[OrganizationDomain]):
|
|
211
|
+
event: Literal["organization_domain.created"]
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
class OrganizationDomainUpdatedWebhook(WebhookModel[OrganizationDomain]):
|
|
215
|
+
event: Literal["organization_domain.updated"]
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class OrganizationDomainDeletedWebhook(WebhookModel[OrganizationDomain]):
|
|
219
|
+
event: Literal["organization_domain.deleted"]
|
|
220
|
+
|
|
221
|
+
|
|
208
222
|
class OrganizationMembershipCreatedWebhook(WebhookModel[OrganizationMembership]):
|
|
209
223
|
event: Literal["organization_membership.created"]
|
|
210
224
|
|
|
@@ -286,6 +300,9 @@ Webhook = Annotated[
|
|
|
286
300
|
OrganizationCreatedWebhook,
|
|
287
301
|
OrganizationDeletedWebhook,
|
|
288
302
|
OrganizationUpdatedWebhook,
|
|
303
|
+
OrganizationDomainCreatedWebhook,
|
|
304
|
+
OrganizationDomainDeletedWebhook,
|
|
305
|
+
OrganizationDomainUpdatedWebhook,
|
|
289
306
|
OrganizationDomainVerificationFailedWebhook,
|
|
290
307
|
OrganizationDomainVerifiedWebhook,
|
|
291
308
|
OrganizationMembershipCreatedWebhook,
|
|
@@ -245,15 +245,24 @@ class UserManagementModule(Protocol):
|
|
|
245
245
|
...
|
|
246
246
|
|
|
247
247
|
def create_organization_membership(
|
|
248
|
-
self,
|
|
248
|
+
self,
|
|
249
|
+
*,
|
|
250
|
+
user_id: str,
|
|
251
|
+
organization_id: str,
|
|
252
|
+
role_slug: Optional[str] = None,
|
|
253
|
+
role_slugs: Optional[Sequence[str]] = None,
|
|
249
254
|
) -> SyncOrAsync[OrganizationMembership]:
|
|
250
255
|
"""Create a new OrganizationMembership for the given Organization and User.
|
|
251
256
|
|
|
252
257
|
Kwargs:
|
|
253
|
-
user_id: The
|
|
254
|
-
organization_id: The
|
|
255
|
-
role_slug: The
|
|
256
|
-
|
|
258
|
+
user_id: The unique ID of the User.
|
|
259
|
+
organization_id: The unique ID of the Organization to which the user belongs to.
|
|
260
|
+
role_slug: The unique slug of the role to grant to this membership.(Optional)
|
|
261
|
+
role_slugs: The unique slugs of the roles to grant to this membership.(Optional)
|
|
262
|
+
|
|
263
|
+
Note:
|
|
264
|
+
role_slug and role_slugs are mutually exclusive. If neither is provided,
|
|
265
|
+
the user will be assigned the organization's default role.
|
|
257
266
|
|
|
258
267
|
Returns:
|
|
259
268
|
OrganizationMembership: Created OrganizationMembership response from WorkOS.
|
|
@@ -261,14 +270,22 @@ class UserManagementModule(Protocol):
|
|
|
261
270
|
...
|
|
262
271
|
|
|
263
272
|
def update_organization_membership(
|
|
264
|
-
self,
|
|
273
|
+
self,
|
|
274
|
+
*,
|
|
275
|
+
organization_membership_id: str,
|
|
276
|
+
role_slug: Optional[str] = None,
|
|
277
|
+
role_slugs: Optional[Sequence[str]] = None,
|
|
265
278
|
) -> SyncOrAsync[OrganizationMembership]:
|
|
266
279
|
"""Updates an OrganizationMembership for the given id.
|
|
267
280
|
|
|
268
281
|
Args:
|
|
269
282
|
organization_membership_id (str): The unique ID of the Organization Membership.
|
|
270
|
-
role_slug: The
|
|
271
|
-
|
|
283
|
+
role_slug: The unique slug of the role to grant to this membership.(Optional)
|
|
284
|
+
role_slugs: The unique slugs of the roles to grant to this membership.(Optional)
|
|
285
|
+
|
|
286
|
+
Note:
|
|
287
|
+
role_slug and role_slugs are mutually exclusive. If neither is provided,
|
|
288
|
+
the role(s) of the membership will remain unchanged.
|
|
272
289
|
|
|
273
290
|
Returns:
|
|
274
291
|
OrganizationMembership: Updated OrganizationMembership response from WorkOS.
|
|
@@ -988,12 +1005,18 @@ class UserManagement(UserManagementModule):
|
|
|
988
1005
|
)
|
|
989
1006
|
|
|
990
1007
|
def create_organization_membership(
|
|
991
|
-
self,
|
|
1008
|
+
self,
|
|
1009
|
+
*,
|
|
1010
|
+
user_id: str,
|
|
1011
|
+
organization_id: str,
|
|
1012
|
+
role_slug: Optional[str] = None,
|
|
1013
|
+
role_slugs: Optional[Sequence[str]] = None,
|
|
992
1014
|
) -> OrganizationMembership:
|
|
993
1015
|
json = {
|
|
994
1016
|
"user_id": user_id,
|
|
995
1017
|
"organization_id": organization_id,
|
|
996
1018
|
"role_slug": role_slug,
|
|
1019
|
+
"role_slugs": role_slugs,
|
|
997
1020
|
}
|
|
998
1021
|
|
|
999
1022
|
response = self._http_client.request(
|
|
@@ -1003,10 +1026,15 @@ class UserManagement(UserManagementModule):
|
|
|
1003
1026
|
return OrganizationMembership.model_validate(response)
|
|
1004
1027
|
|
|
1005
1028
|
def update_organization_membership(
|
|
1006
|
-
self,
|
|
1029
|
+
self,
|
|
1030
|
+
*,
|
|
1031
|
+
organization_membership_id: str,
|
|
1032
|
+
role_slug: Optional[str] = None,
|
|
1033
|
+
role_slugs: Optional[Sequence[str]] = None,
|
|
1007
1034
|
) -> OrganizationMembership:
|
|
1008
1035
|
json = {
|
|
1009
1036
|
"role_slug": role_slug,
|
|
1037
|
+
"role_slugs": role_slugs,
|
|
1010
1038
|
}
|
|
1011
1039
|
|
|
1012
1040
|
response = self._http_client.request(
|
|
@@ -1614,12 +1642,18 @@ class AsyncUserManagement(UserManagementModule):
|
|
|
1614
1642
|
)
|
|
1615
1643
|
|
|
1616
1644
|
async def create_organization_membership(
|
|
1617
|
-
self,
|
|
1645
|
+
self,
|
|
1646
|
+
*,
|
|
1647
|
+
user_id: str,
|
|
1648
|
+
organization_id: str,
|
|
1649
|
+
role_slug: Optional[str] = None,
|
|
1650
|
+
role_slugs: Optional[Sequence[str]] = None,
|
|
1618
1651
|
) -> OrganizationMembership:
|
|
1619
1652
|
json = {
|
|
1620
1653
|
"user_id": user_id,
|
|
1621
1654
|
"organization_id": organization_id,
|
|
1622
1655
|
"role_slug": role_slug,
|
|
1656
|
+
"role_slugs": role_slugs,
|
|
1623
1657
|
}
|
|
1624
1658
|
|
|
1625
1659
|
response = await self._http_client.request(
|
|
@@ -1629,10 +1663,15 @@ class AsyncUserManagement(UserManagementModule):
|
|
|
1629
1663
|
return OrganizationMembership.model_validate(response)
|
|
1630
1664
|
|
|
1631
1665
|
async def update_organization_membership(
|
|
1632
|
-
self,
|
|
1666
|
+
self,
|
|
1667
|
+
*,
|
|
1668
|
+
organization_membership_id: str,
|
|
1669
|
+
role_slug: Optional[str] = None,
|
|
1670
|
+
role_slugs: Optional[Sequence[str]] = None,
|
|
1633
1671
|
) -> OrganizationMembership:
|
|
1634
1672
|
json = {
|
|
1635
1673
|
"role_slug": role_slug,
|
|
1674
|
+
"role_slugs": role_slugs,
|
|
1636
1675
|
}
|
|
1637
1676
|
|
|
1638
1677
|
response = await self._http_client.request(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{workos-5.27.0 → workos-5.28.0}/workos/types/events/connection_payload_with_legacy_fields.py
RENAMED
|
File without changes
|
|
File without changes
|
{workos-5.27.0 → workos-5.28.0}/workos/types/events/directory_group_with_previous_attributes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{workos-5.27.0 → workos-5.28.0}/workos/types/events/directory_user_with_previous_attributes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{workos-5.27.0 → workos-5.28.0}/workos/types/mfa/authentication_challenge_verification_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{workos-5.27.0 → workos-5.28.0}/workos/types/user_management/user_management_provider_type.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|