workos 5.24.0__tar.gz → 5.26.1__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.24.0 → workos-5.26.1}/PKG-INFO +1 -1
- workos-5.26.1/tests/test_organization_domains.py +136 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_session.py +48 -1
- {workos-5.24.0 → workos-5.26.1}/workos/__about__.py +1 -1
- {workos-5.24.0 → workos-5.26.1}/workos/_base_client.py +5 -0
- {workos-5.24.0 → workos-5.26.1}/workos/async_client.py +9 -0
- {workos-5.24.0 → workos-5.26.1}/workos/client.py +9 -0
- workos-5.26.1/workos/organization_domains.py +179 -0
- {workos-5.24.0 → workos-5.26.1}/workos/session.py +9 -3
- {workos-5.24.0 → workos-5.26.1}/workos/types/events/event.py +1 -1
- {workos-5.24.0 → workos-5.26.1}/workos/types/events/event_model.py +1 -1
- {workos-5.24.0 → workos-5.26.1}/workos/types/events/organization_domain_verification_failed_payload.py +1 -1
- workos-5.26.1/workos/types/organization_domains/__init__.py +1 -0
- workos-5.26.1/workos/types/organizations/__init__.py +6 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/organizations/organization.py +1 -1
- {workos-5.24.0 → workos-5.26.1}/workos/types/organizations/organization_common.py +1 -1
- {workos-5.24.0 → workos-5.26.1}/workos/types/webhooks/webhook.py +1 -1
- {workos-5.24.0 → workos-5.26.1}/workos.egg-info/PKG-INFO +1 -1
- {workos-5.24.0 → workos-5.26.1}/workos.egg-info/SOURCES.txt +4 -1
- workos-5.24.0/workos/types/organizations/__init__.py +0 -4
- {workos-5.24.0 → workos-5.26.1}/LICENSE +0 -0
- {workos-5.24.0 → workos-5.26.1}/README.md +0 -0
- {workos-5.24.0 → workos-5.26.1}/setup.cfg +0 -0
- {workos-5.24.0 → workos-5.26.1}/setup.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_async_http_client.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_audit_logs.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_client.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_directory_sync.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_events.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_fga.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_mfa.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_organizations.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_passwordless.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_portal.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_sso.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_sync_http_client.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_user_management.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_vault.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_webhooks.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/tests/test_widgets.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/_client_configuration.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/audit_logs.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/directory_sync.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/events.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/exceptions.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/fga.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/mfa.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/organizations.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/passwordless.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/portal.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/py.typed +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/sso.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/audit_logs/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/audit_logs/audit_log_event.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/audit_logs/audit_log_event_actor.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/audit_logs/audit_log_event_context.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/audit_logs/audit_log_event_target.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/audit_logs/audit_log_export.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/audit_logs/audit_log_metadata.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/directory_sync/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/directory_sync/directory.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/directory_sync/directory_group.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/directory_sync/directory_state.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/directory_sync/directory_type.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/directory_sync/directory_user.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/directory_sync/list_filters.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/events/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/events/authentication_payload.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/events/connection_payload_with_legacy_fields.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/events/directory_group_membership_payload.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/events/directory_group_with_previous_attributes.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/events/directory_payload.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/events/directory_payload_with_legacy_fields.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/events/directory_user_with_previous_attributes.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/events/event_type.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/events/list_filters.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/events/previous_attributes.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/events/session_created_payload.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/fga/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/fga/authorization_resource_types.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/fga/authorization_resources.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/fga/check.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/fga/list_filters.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/fga/warnings.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/fga/warrant.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/list_resource.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/metadata.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/mfa/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/mfa/authentication_challenge.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/mfa/authentication_challenge_verification_response.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/mfa/authentication_factor.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/mfa/authentication_factor_totp_and_challenge_response.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/mfa/enroll_authentication_factor_type.py +0 -0
- {workos-5.24.0/workos/types/organizations → workos-5.26.1/workos/types/organization_domains}/organization_domain.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/organizations/domain_data_input.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/organizations/list_filters.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/passwordless/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/passwordless/passwordless_session.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/passwordless/passwordless_session_type.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/portal/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/portal/portal_link.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/portal/portal_link_intent.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/portal/portal_link_intent_options.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/roles/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/roles/role.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/sso/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/sso/connection.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/sso/connection_domain.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/sso/profile.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/sso/sso_provider_type.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/authenticate_with_common.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/authentication_response.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/email_verification.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/impersonator.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/invitation.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/list_filters.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/magic_auth.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/oauth_tokens.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/organization_membership.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/password_hash_type.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/password_reset.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/screen_hint.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/session.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/user.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/user_management/user_management_provider_type.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/vault/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/vault/key.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/vault/object.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/webhooks/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/webhooks/webhook_model.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/webhooks/webhook_payload.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/widgets/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/widgets/widget_scope.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/widgets/widget_token_response.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/types/workos_model.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/typing/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/typing/literals.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/typing/sync_or_async.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/typing/untyped_literal.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/typing/webhooks.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/user_management.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/utils/__init__.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/utils/_base_http_client.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/utils/crypto_provider.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/utils/http_client.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/utils/pagination_order.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/utils/request_helper.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/vault.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/webhooks.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos/widgets.py +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos.egg-info/dependency_links.txt +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos.egg-info/not-zip-safe +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos.egg-info/requires.txt +0 -0
- {workos-5.24.0 → workos-5.26.1}/workos.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
import pytest
|
|
3
|
+
from tests.utils.syncify import syncify
|
|
4
|
+
from workos.organization_domains import AsyncOrganizationDomains, OrganizationDomains
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@pytest.mark.sync_and_async(OrganizationDomains, AsyncOrganizationDomains)
|
|
8
|
+
class TestOrganizationDomains:
|
|
9
|
+
@pytest.fixture(autouse=True)
|
|
10
|
+
def setup(
|
|
11
|
+
self, module_instance: Union[OrganizationDomains, AsyncOrganizationDomains]
|
|
12
|
+
):
|
|
13
|
+
self.http_client = module_instance._http_client
|
|
14
|
+
self.organization_domains = module_instance
|
|
15
|
+
|
|
16
|
+
@pytest.fixture
|
|
17
|
+
def mock_organization_domain(self):
|
|
18
|
+
return {
|
|
19
|
+
"object": "organization_domain",
|
|
20
|
+
"id": "org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8",
|
|
21
|
+
"organization_id": "org_01EHT88Z8J8795GZNQ4ZP1J81T",
|
|
22
|
+
"domain": "example.com",
|
|
23
|
+
"state": "pending",
|
|
24
|
+
"verification_strategy": "dns",
|
|
25
|
+
"verification_token": "workos_example_verification_token_12345",
|
|
26
|
+
"verification_prefix": "_workos-challenge",
|
|
27
|
+
"created_at": "2023-01-01T12:00:00.000Z",
|
|
28
|
+
"updated_at": "2023-01-01T12:00:00.000Z",
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@pytest.fixture
|
|
32
|
+
def mock_organization_domain_verified(self):
|
|
33
|
+
return {
|
|
34
|
+
"object": "organization_domain",
|
|
35
|
+
"id": "org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8",
|
|
36
|
+
"organization_id": "org_01EHT88Z8J8795GZNQ4ZP1J81T",
|
|
37
|
+
"domain": "example.com",
|
|
38
|
+
"state": "verified",
|
|
39
|
+
"verification_strategy": "dns",
|
|
40
|
+
"verification_token": "workos_example_verification_token_12345",
|
|
41
|
+
"verification_prefix": "_workos-challenge",
|
|
42
|
+
"created_at": "2023-01-01T12:00:00.000Z",
|
|
43
|
+
"updated_at": "2023-01-01T12:00:00.000Z",
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
def test_get_organization_domain(
|
|
47
|
+
self, capture_and_mock_http_client_request, mock_organization_domain
|
|
48
|
+
):
|
|
49
|
+
request_kwargs = capture_and_mock_http_client_request(
|
|
50
|
+
self.http_client,
|
|
51
|
+
mock_organization_domain,
|
|
52
|
+
200,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
organization_domain = syncify(
|
|
56
|
+
self.organization_domains.get_organization_domain(
|
|
57
|
+
organization_domain_id="org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8"
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
assert request_kwargs["url"].endswith(
|
|
62
|
+
"/organization_domains/org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8"
|
|
63
|
+
)
|
|
64
|
+
assert request_kwargs["method"] == "get"
|
|
65
|
+
assert organization_domain.id == "org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8"
|
|
66
|
+
assert organization_domain.domain == "example.com"
|
|
67
|
+
assert organization_domain.state == "pending"
|
|
68
|
+
assert organization_domain.verification_strategy == "dns"
|
|
69
|
+
|
|
70
|
+
def test_create_organization_domain(
|
|
71
|
+
self, capture_and_mock_http_client_request, mock_organization_domain
|
|
72
|
+
):
|
|
73
|
+
request_kwargs = capture_and_mock_http_client_request(
|
|
74
|
+
self.http_client,
|
|
75
|
+
mock_organization_domain,
|
|
76
|
+
201,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
organization_domain = syncify(
|
|
80
|
+
self.organization_domains.create_organization_domain(
|
|
81
|
+
organization_id="org_01EHT88Z8J8795GZNQ4ZP1J81T",
|
|
82
|
+
domain="example.com",
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
assert request_kwargs["url"].endswith("/organization_domains")
|
|
87
|
+
assert request_kwargs["method"] == "post"
|
|
88
|
+
assert request_kwargs["json"] == {
|
|
89
|
+
"organization_id": "org_01EHT88Z8J8795GZNQ4ZP1J81T",
|
|
90
|
+
"domain": "example.com",
|
|
91
|
+
}
|
|
92
|
+
assert organization_domain.id == "org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8"
|
|
93
|
+
assert organization_domain.domain == "example.com"
|
|
94
|
+
assert organization_domain.organization_id == "org_01EHT88Z8J8795GZNQ4ZP1J81T"
|
|
95
|
+
|
|
96
|
+
def test_verify_organization_domain(
|
|
97
|
+
self, capture_and_mock_http_client_request, mock_organization_domain_verified
|
|
98
|
+
):
|
|
99
|
+
request_kwargs = capture_and_mock_http_client_request(
|
|
100
|
+
self.http_client,
|
|
101
|
+
mock_organization_domain_verified,
|
|
102
|
+
200,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
organization_domain = syncify(
|
|
106
|
+
self.organization_domains.verify_organization_domain(
|
|
107
|
+
organization_domain_id="org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8"
|
|
108
|
+
)
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
assert request_kwargs["url"].endswith(
|
|
112
|
+
"/organization_domains/org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8/verify"
|
|
113
|
+
)
|
|
114
|
+
assert request_kwargs["method"] == "post"
|
|
115
|
+
assert organization_domain.id == "org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8"
|
|
116
|
+
assert organization_domain.state == "verified"
|
|
117
|
+
|
|
118
|
+
def test_delete_organization_domain(self, capture_and_mock_http_client_request):
|
|
119
|
+
request_kwargs = capture_and_mock_http_client_request(
|
|
120
|
+
self.http_client,
|
|
121
|
+
None,
|
|
122
|
+
204,
|
|
123
|
+
headers={"content-type": "text/plain; charset=utf-8"},
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
response = syncify(
|
|
127
|
+
self.organization_domains.delete_organization_domain(
|
|
128
|
+
organization_domain_id="org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8"
|
|
129
|
+
)
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
assert request_kwargs["url"].endswith(
|
|
133
|
+
"/organization_domains/org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8"
|
|
134
|
+
)
|
|
135
|
+
assert request_kwargs["method"] == "delete"
|
|
136
|
+
assert response is None
|
|
@@ -2,9 +2,10 @@ import pytest
|
|
|
2
2
|
from unittest.mock import AsyncMock, Mock, patch
|
|
3
3
|
import jwt
|
|
4
4
|
from datetime import datetime, timezone
|
|
5
|
+
import concurrent.futures
|
|
5
6
|
|
|
6
7
|
from tests.conftest import with_jwks_mock
|
|
7
|
-
from workos.session import AsyncSession, Session
|
|
8
|
+
from workos.session import AsyncSession, Session, _get_jwks_client
|
|
8
9
|
from workos.types.user_management.authentication_response import (
|
|
9
10
|
RefreshTokenAuthenticationResponse,
|
|
10
11
|
)
|
|
@@ -20,6 +21,12 @@ from cryptography.hazmat.primitives.asymmetric import rsa
|
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
class SessionFixtures:
|
|
24
|
+
@pytest.fixture(autouse=True)
|
|
25
|
+
def clear_jwks_cache(self):
|
|
26
|
+
_get_jwks_client.cache_clear()
|
|
27
|
+
yield
|
|
28
|
+
_get_jwks_client.cache_clear()
|
|
29
|
+
|
|
23
30
|
@pytest.fixture
|
|
24
31
|
def session_constants(self):
|
|
25
32
|
# Generate RSA key pair for testing
|
|
@@ -491,3 +498,43 @@ class TestAsyncSession(SessionFixtures):
|
|
|
491
498
|
response = await session.refresh()
|
|
492
499
|
|
|
493
500
|
assert isinstance(response, RefreshWithSessionCookieSuccessResponse)
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
class TestJWKSCaching:
|
|
504
|
+
def test_jwks_client_caching_same_url(self):
|
|
505
|
+
url = "https://api.workos.com/sso/jwks/test"
|
|
506
|
+
|
|
507
|
+
client1 = _get_jwks_client(url)
|
|
508
|
+
client2 = _get_jwks_client(url)
|
|
509
|
+
|
|
510
|
+
# Should be the exact same instance
|
|
511
|
+
assert client1 is client2
|
|
512
|
+
assert id(client1) == id(client2)
|
|
513
|
+
|
|
514
|
+
def test_jwks_client_caching_different_urls(self):
|
|
515
|
+
url1 = "https://api.workos.com/sso/jwks/client1"
|
|
516
|
+
url2 = "https://api.workos.com/sso/jwks/client2"
|
|
517
|
+
|
|
518
|
+
client1 = _get_jwks_client(url1)
|
|
519
|
+
client2 = _get_jwks_client(url2)
|
|
520
|
+
|
|
521
|
+
# Should be different instances
|
|
522
|
+
assert client1 is not client2
|
|
523
|
+
assert id(client1) != id(client2)
|
|
524
|
+
|
|
525
|
+
def test_jwks_cache_thread_safety(self):
|
|
526
|
+
url = "https://api.workos.com/sso/jwks/thread_test"
|
|
527
|
+
clients = []
|
|
528
|
+
|
|
529
|
+
def get_client():
|
|
530
|
+
return _get_jwks_client(url)
|
|
531
|
+
|
|
532
|
+
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
|
|
533
|
+
futures = [executor.submit(get_client) for _ in range(10)]
|
|
534
|
+
clients = [future.result() for future in futures]
|
|
535
|
+
|
|
536
|
+
first_client = clients[0]
|
|
537
|
+
for client in clients[1:]:
|
|
538
|
+
assert (
|
|
539
|
+
client is first_client
|
|
540
|
+
), "All concurrent calls should return the same instance"
|
|
@@ -11,6 +11,7 @@ from workos.directory_sync import DirectorySyncModule
|
|
|
11
11
|
from workos.events import EventsModule
|
|
12
12
|
from workos.mfa import MFAModule
|
|
13
13
|
from workos.organizations import OrganizationsModule
|
|
14
|
+
from workos.organization_domains import OrganizationDomainsModule
|
|
14
15
|
from workos.passwordless import PasswordlessModule
|
|
15
16
|
from workos.portal import PortalModule
|
|
16
17
|
from workos.sso import SSOModule
|
|
@@ -88,6 +89,10 @@ class BaseClient(ClientConfiguration):
|
|
|
88
89
|
@abstractmethod
|
|
89
90
|
def organizations(self) -> OrganizationsModule: ...
|
|
90
91
|
|
|
92
|
+
@property
|
|
93
|
+
@abstractmethod
|
|
94
|
+
def organization_domains(self) -> OrganizationDomainsModule: ...
|
|
95
|
+
|
|
91
96
|
@property
|
|
92
97
|
@abstractmethod
|
|
93
98
|
def passwordless(self) -> PasswordlessModule: ...
|
|
@@ -7,6 +7,7 @@ from workos.events import AsyncEvents
|
|
|
7
7
|
from workos.fga import FGAModule
|
|
8
8
|
from workos.mfa import MFAModule
|
|
9
9
|
from workos.organizations import AsyncOrganizations
|
|
10
|
+
from workos.organization_domains import AsyncOrganizationDomains
|
|
10
11
|
from workos.passwordless import PasswordlessModule
|
|
11
12
|
from workos.portal import PortalModule
|
|
12
13
|
from workos.sso import AsyncSSO
|
|
@@ -80,6 +81,14 @@ class AsyncClient(BaseClient):
|
|
|
80
81
|
self._organizations = AsyncOrganizations(self._http_client)
|
|
81
82
|
return self._organizations
|
|
82
83
|
|
|
84
|
+
@property
|
|
85
|
+
def organization_domains(self) -> AsyncOrganizationDomains:
|
|
86
|
+
if not getattr(self, "_organization_domains", None):
|
|
87
|
+
self._organization_domains = AsyncOrganizationDomains(
|
|
88
|
+
http_client=self._http_client, client_configuration=self
|
|
89
|
+
)
|
|
90
|
+
return self._organization_domains
|
|
91
|
+
|
|
83
92
|
@property
|
|
84
93
|
def passwordless(self) -> PasswordlessModule:
|
|
85
94
|
raise NotImplementedError(
|
|
@@ -5,6 +5,7 @@ from workos.audit_logs import AuditLogs
|
|
|
5
5
|
from workos.directory_sync import DirectorySync
|
|
6
6
|
from workos.fga import FGA
|
|
7
7
|
from workos.organizations import Organizations
|
|
8
|
+
from workos.organization_domains import OrganizationDomains
|
|
8
9
|
from workos.passwordless import Passwordless
|
|
9
10
|
from workos.portal import Portal
|
|
10
11
|
from workos.sso import SSO
|
|
@@ -80,6 +81,14 @@ class SyncClient(BaseClient):
|
|
|
80
81
|
self._organizations = Organizations(self._http_client)
|
|
81
82
|
return self._organizations
|
|
82
83
|
|
|
84
|
+
@property
|
|
85
|
+
def organization_domains(self) -> OrganizationDomains:
|
|
86
|
+
if not getattr(self, "_organization_domains", None):
|
|
87
|
+
self._organization_domains = OrganizationDomains(
|
|
88
|
+
http_client=self._http_client, client_configuration=self
|
|
89
|
+
)
|
|
90
|
+
return self._organization_domains
|
|
91
|
+
|
|
83
92
|
@property
|
|
84
93
|
def passwordless(self) -> Passwordless:
|
|
85
94
|
if not getattr(self, "_passwordless", None):
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
from typing import Protocol
|
|
2
|
+
from workos._client_configuration import ClientConfiguration
|
|
3
|
+
from workos.types.organization_domains import OrganizationDomain
|
|
4
|
+
from workos.typing.sync_or_async import SyncOrAsync
|
|
5
|
+
from workos.utils.http_client import AsyncHTTPClient, SyncHTTPClient
|
|
6
|
+
from workos.utils.request_helper import (
|
|
7
|
+
REQUEST_METHOD_DELETE,
|
|
8
|
+
REQUEST_METHOD_GET,
|
|
9
|
+
REQUEST_METHOD_POST,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class OrganizationDomainsModule(Protocol):
|
|
14
|
+
"""Offers methods for managing organization domains."""
|
|
15
|
+
|
|
16
|
+
_client_configuration: ClientConfiguration
|
|
17
|
+
|
|
18
|
+
def get_organization_domain(
|
|
19
|
+
self, organization_domain_id: str
|
|
20
|
+
) -> SyncOrAsync[OrganizationDomain]:
|
|
21
|
+
"""Gets a single Organization Domain
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
organization_domain_id (str): Organization Domain unique identifier
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
OrganizationDomain: Organization Domain response from WorkOS
|
|
28
|
+
"""
|
|
29
|
+
...
|
|
30
|
+
|
|
31
|
+
def create_organization_domain(
|
|
32
|
+
self,
|
|
33
|
+
organization_id: str,
|
|
34
|
+
domain: str,
|
|
35
|
+
) -> SyncOrAsync[OrganizationDomain]:
|
|
36
|
+
"""Creates an Organization Domain
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
organization_id (str): Organization unique identifier
|
|
40
|
+
domain (str): Domain to be added to the organization
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
OrganizationDomain: Organization Domain response from WorkOS
|
|
44
|
+
"""
|
|
45
|
+
...
|
|
46
|
+
|
|
47
|
+
def verify_organization_domain(
|
|
48
|
+
self, organization_domain_id: str
|
|
49
|
+
) -> SyncOrAsync[OrganizationDomain]:
|
|
50
|
+
"""Verifies an Organization Domain
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
organization_domain_id (str): Organization Domain unique identifier
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
OrganizationDomain: Organization Domain response from WorkOS
|
|
57
|
+
"""
|
|
58
|
+
...
|
|
59
|
+
|
|
60
|
+
def delete_organization_domain(
|
|
61
|
+
self, organization_domain_id: str
|
|
62
|
+
) -> SyncOrAsync[None]:
|
|
63
|
+
"""Deletes a single Organization Domain
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
organization_domain_id (str): Organization Domain unique identifier
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
None
|
|
70
|
+
"""
|
|
71
|
+
...
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class OrganizationDomains:
|
|
75
|
+
"""Offers methods for managing organization domains."""
|
|
76
|
+
|
|
77
|
+
_http_client: SyncHTTPClient
|
|
78
|
+
_client_configuration: ClientConfiguration
|
|
79
|
+
|
|
80
|
+
def __init__(
|
|
81
|
+
self,
|
|
82
|
+
http_client: SyncHTTPClient,
|
|
83
|
+
client_configuration: ClientConfiguration,
|
|
84
|
+
):
|
|
85
|
+
self._http_client = http_client
|
|
86
|
+
self._client_configuration = client_configuration
|
|
87
|
+
|
|
88
|
+
def get_organization_domain(
|
|
89
|
+
self, organization_domain_id: str
|
|
90
|
+
) -> OrganizationDomain:
|
|
91
|
+
response = self._http_client.request(
|
|
92
|
+
f"organization_domains/{organization_domain_id}",
|
|
93
|
+
method=REQUEST_METHOD_GET,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
return OrganizationDomain.model_validate(response)
|
|
97
|
+
|
|
98
|
+
def create_organization_domain(
|
|
99
|
+
self,
|
|
100
|
+
organization_id: str,
|
|
101
|
+
domain: str,
|
|
102
|
+
) -> OrganizationDomain:
|
|
103
|
+
response = self._http_client.request(
|
|
104
|
+
"organization_domains",
|
|
105
|
+
method=REQUEST_METHOD_POST,
|
|
106
|
+
json={"organization_id": organization_id, "domain": domain},
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
return OrganizationDomain.model_validate(response)
|
|
110
|
+
|
|
111
|
+
def verify_organization_domain(
|
|
112
|
+
self, organization_domain_id: str
|
|
113
|
+
) -> OrganizationDomain:
|
|
114
|
+
response = self._http_client.request(
|
|
115
|
+
f"organization_domains/{organization_domain_id}/verify",
|
|
116
|
+
method=REQUEST_METHOD_POST,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
return OrganizationDomain.model_validate(response)
|
|
120
|
+
|
|
121
|
+
def delete_organization_domain(self, organization_domain_id: str) -> None:
|
|
122
|
+
self._http_client.request(
|
|
123
|
+
f"organization_domains/{organization_domain_id}",
|
|
124
|
+
method=REQUEST_METHOD_DELETE,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class AsyncOrganizationDomains:
|
|
129
|
+
"""Offers async methods for managing organization domains."""
|
|
130
|
+
|
|
131
|
+
_http_client: AsyncHTTPClient
|
|
132
|
+
_client_configuration: ClientConfiguration
|
|
133
|
+
|
|
134
|
+
def __init__(
|
|
135
|
+
self,
|
|
136
|
+
http_client: AsyncHTTPClient,
|
|
137
|
+
client_configuration: ClientConfiguration,
|
|
138
|
+
):
|
|
139
|
+
self._http_client = http_client
|
|
140
|
+
self._client_configuration = client_configuration
|
|
141
|
+
|
|
142
|
+
async def get_organization_domain(
|
|
143
|
+
self, organization_domain_id: str
|
|
144
|
+
) -> OrganizationDomain:
|
|
145
|
+
response = await self._http_client.request(
|
|
146
|
+
f"organization_domains/{organization_domain_id}",
|
|
147
|
+
method=REQUEST_METHOD_GET,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
return OrganizationDomain.model_validate(response)
|
|
151
|
+
|
|
152
|
+
async def create_organization_domain(
|
|
153
|
+
self,
|
|
154
|
+
organization_id: str,
|
|
155
|
+
domain: str,
|
|
156
|
+
) -> OrganizationDomain:
|
|
157
|
+
response = await self._http_client.request(
|
|
158
|
+
"organization_domains",
|
|
159
|
+
method=REQUEST_METHOD_POST,
|
|
160
|
+
json={"organization_id": organization_id, "domain": domain},
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
return OrganizationDomain.model_validate(response)
|
|
164
|
+
|
|
165
|
+
async def verify_organization_domain(
|
|
166
|
+
self, organization_domain_id: str
|
|
167
|
+
) -> OrganizationDomain:
|
|
168
|
+
response = await self._http_client.request(
|
|
169
|
+
f"organization_domains/{organization_domain_id}/verify",
|
|
170
|
+
method=REQUEST_METHOD_POST,
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
return OrganizationDomain.model_validate(response)
|
|
174
|
+
|
|
175
|
+
async def delete_organization_domain(self, organization_domain_id: str) -> None:
|
|
176
|
+
await self._http_client.request(
|
|
177
|
+
f"organization_domains/{organization_domain_id}",
|
|
178
|
+
method=REQUEST_METHOD_DELETE,
|
|
179
|
+
)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
from typing import TYPE_CHECKING, List, Protocol
|
|
3
3
|
|
|
4
|
+
from functools import lru_cache
|
|
4
5
|
import json
|
|
5
6
|
from typing import Any, Dict, Optional, Union, cast
|
|
6
7
|
import jwt
|
|
@@ -21,6 +22,11 @@ if TYPE_CHECKING:
|
|
|
21
22
|
from workos.user_management import AsyncUserManagement, UserManagement
|
|
22
23
|
|
|
23
24
|
|
|
25
|
+
@lru_cache(maxsize=None)
|
|
26
|
+
def _get_jwks_client(jwks_url: str) -> PyJWKClient:
|
|
27
|
+
return PyJWKClient(jwks_url)
|
|
28
|
+
|
|
29
|
+
|
|
24
30
|
class SessionModule(Protocol):
|
|
25
31
|
user_management: "UserManagementModule"
|
|
26
32
|
client_id: str
|
|
@@ -46,7 +52,7 @@ class SessionModule(Protocol):
|
|
|
46
52
|
self.session_data = session_data
|
|
47
53
|
self.cookie_password = cookie_password
|
|
48
54
|
|
|
49
|
-
self.jwks =
|
|
55
|
+
self.jwks = _get_jwks_client(self.user_management.get_jwks_url())
|
|
50
56
|
|
|
51
57
|
# Algorithms are hardcoded for security reasons. See https://pyjwt.readthedocs.io/en/stable/algorithms.html#specifying-an-algorithm
|
|
52
58
|
self.jwk_algorithms = ["RS256"]
|
|
@@ -164,7 +170,7 @@ class Session(SessionModule):
|
|
|
164
170
|
self.session_data = session_data
|
|
165
171
|
self.cookie_password = cookie_password
|
|
166
172
|
|
|
167
|
-
self.jwks =
|
|
173
|
+
self.jwks = _get_jwks_client(self.user_management.get_jwks_url())
|
|
168
174
|
|
|
169
175
|
# Algorithms are hardcoded for security reasons. See https://pyjwt.readthedocs.io/en/stable/algorithms.html#specifying-an-algorithm
|
|
170
176
|
self.jwk_algorithms = ["RS256"]
|
|
@@ -254,7 +260,7 @@ class AsyncSession(SessionModule):
|
|
|
254
260
|
self.session_data = session_data
|
|
255
261
|
self.cookie_password = cookie_password
|
|
256
262
|
|
|
257
|
-
self.jwks =
|
|
263
|
+
self.jwks = _get_jwks_client(self.user_management.get_jwks_url())
|
|
258
264
|
|
|
259
265
|
# Algorithms are hardcoded for security reasons. See https://pyjwt.readthedocs.io/en/stable/algorithms.html#specifying-an-algorithm
|
|
260
266
|
self.jwk_algorithms = ["RS256"]
|
|
@@ -38,7 +38,7 @@ from workos.types.events.organization_domain_verification_failed_payload import
|
|
|
38
38
|
)
|
|
39
39
|
from workos.types.events.session_created_payload import SessionCreatedPayload
|
|
40
40
|
from workos.types.organizations.organization_common import OrganizationCommon
|
|
41
|
-
from workos.types.
|
|
41
|
+
from workos.types.organization_domains import OrganizationDomain
|
|
42
42
|
from workos.types.roles.role import EventRole
|
|
43
43
|
from workos.types.sso.connection import Connection
|
|
44
44
|
from workos.types.user_management.email_verification import (
|
|
@@ -37,7 +37,7 @@ from workos.types.events.organization_domain_verification_failed_payload import
|
|
|
37
37
|
)
|
|
38
38
|
from workos.types.events.session_created_payload import SessionCreatedPayload
|
|
39
39
|
from workos.types.organizations.organization_common import OrganizationCommon
|
|
40
|
-
from workos.types.
|
|
40
|
+
from workos.types.organization_domains import OrganizationDomain
|
|
41
41
|
from workos.types.roles.role import EventRole
|
|
42
42
|
from workos.types.sso.connection import Connection
|
|
43
43
|
from workos.types.user_management.email_verification import (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Literal
|
|
2
2
|
from workos.types.workos_model import WorkOSModel
|
|
3
|
-
from workos.types.
|
|
3
|
+
from workos.types.organization_domains import OrganizationDomain
|
|
4
4
|
from workos.typing.literals import LiteralOrUntyped
|
|
5
5
|
|
|
6
6
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .organization_domain import *
|
|
@@ -2,7 +2,7 @@ from dataclasses import field
|
|
|
2
2
|
from typing import Optional, Sequence
|
|
3
3
|
from workos.types.metadata import Metadata
|
|
4
4
|
from workos.types.organizations.organization_common import OrganizationCommon
|
|
5
|
-
from workos.types.
|
|
5
|
+
from workos.types.organization_domains import OrganizationDomain
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class Organization(OrganizationCommon):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Literal, Sequence
|
|
2
2
|
from workos.types.workos_model import WorkOSModel
|
|
3
|
-
from workos.types.
|
|
3
|
+
from workos.types.organization_domains import OrganizationDomain
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class OrganizationCommon(WorkOSModel):
|
|
@@ -38,7 +38,7 @@ from workos.types.events.organization_domain_verification_failed_payload import
|
|
|
38
38
|
)
|
|
39
39
|
from workos.types.events.session_created_payload import SessionCreatedPayload
|
|
40
40
|
from workos.types.organizations.organization_common import OrganizationCommon
|
|
41
|
-
from workos.types.
|
|
41
|
+
from workos.types.organization_domains import OrganizationDomain
|
|
42
42
|
from workos.types.roles.role import EventRole
|
|
43
43
|
from workos.types.sso.connection import Connection
|
|
44
44
|
from workos.types.user_management.email_verification import (
|
|
@@ -8,6 +8,7 @@ tests/test_directory_sync.py
|
|
|
8
8
|
tests/test_events.py
|
|
9
9
|
tests/test_fga.py
|
|
10
10
|
tests/test_mfa.py
|
|
11
|
+
tests/test_organization_domains.py
|
|
11
12
|
tests/test_organizations.py
|
|
12
13
|
tests/test_passwordless.py
|
|
13
14
|
tests/test_portal.py
|
|
@@ -30,6 +31,7 @@ workos/events.py
|
|
|
30
31
|
workos/exceptions.py
|
|
31
32
|
workos/fga.py
|
|
32
33
|
workos/mfa.py
|
|
34
|
+
workos/organization_domains.py
|
|
33
35
|
workos/organizations.py
|
|
34
36
|
workos/passwordless.py
|
|
35
37
|
workos/portal.py
|
|
@@ -92,12 +94,13 @@ workos/types/mfa/authentication_challenge_verification_response.py
|
|
|
92
94
|
workos/types/mfa/authentication_factor.py
|
|
93
95
|
workos/types/mfa/authentication_factor_totp_and_challenge_response.py
|
|
94
96
|
workos/types/mfa/enroll_authentication_factor_type.py
|
|
97
|
+
workos/types/organization_domains/__init__.py
|
|
98
|
+
workos/types/organization_domains/organization_domain.py
|
|
95
99
|
workos/types/organizations/__init__.py
|
|
96
100
|
workos/types/organizations/domain_data_input.py
|
|
97
101
|
workos/types/organizations/list_filters.py
|
|
98
102
|
workos/types/organizations/organization.py
|
|
99
103
|
workos/types/organizations/organization_common.py
|
|
100
|
-
workos/types/organizations/organization_domain.py
|
|
101
104
|
workos/types/passwordless/__init__.py
|
|
102
105
|
workos/types/passwordless/passwordless_session.py
|
|
103
106
|
workos/types/passwordless/passwordless_session_type.py
|
|
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.24.0 → workos-5.26.1}/workos/types/events/connection_payload_with_legacy_fields.py
RENAMED
|
File without changes
|
|
File without changes
|
{workos-5.24.0 → workos-5.26.1}/workos/types/events/directory_group_with_previous_attributes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{workos-5.24.0 → workos-5.26.1}/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
|
{workos-5.24.0 → workos-5.26.1}/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
|
{workos-5.24.0 → workos-5.26.1}/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
|