workos 1.5.1__py3-none-any.whl → 5.38.0__py3-none-any.whl
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/__about__.py +1 -1
- workos/__init__.py +3 -7
- workos/_base_client.py +138 -0
- workos/_client_configuration.py +10 -0
- workos/api_keys.py +53 -0
- workos/async_client.py +144 -0
- workos/audit_logs.py +125 -0
- workos/client.py +110 -18
- workos/directory_sync.py +379 -99
- workos/events.py +111 -0
- workos/exceptions.py +53 -26
- workos/fga.py +649 -0
- workos/mfa.py +205 -0
- workos/organization_domains.py +179 -0
- workos/organizations.py +403 -73
- workos/passwordless.py +67 -43
- workos/pipes.py +93 -0
- workos/portal.py +51 -28
- workos/session.py +337 -0
- workos/sso.py +311 -101
- workos/types/__init__.py +4 -0
- workos/types/api_keys/__init__.py +1 -0
- workos/types/api_keys/api_keys.py +20 -0
- workos/types/audit_logs/__init__.py +6 -0
- workos/types/audit_logs/audit_log_event.py +16 -0
- workos/types/audit_logs/audit_log_event_actor.py +12 -0
- workos/types/audit_logs/audit_log_event_context.py +8 -0
- workos/types/audit_logs/audit_log_event_target.py +12 -0
- workos/types/audit_logs/audit_log_export.py +18 -0
- workos/types/audit_logs/audit_log_metadata.py +4 -0
- workos/types/directory_sync/__init__.py +5 -0
- workos/types/directory_sync/directory.py +31 -0
- workos/types/directory_sync/directory_group.py +16 -0
- workos/types/directory_sync/directory_state.py +28 -0
- workos/types/directory_sync/directory_type.py +24 -0
- workos/types/directory_sync/directory_user.py +50 -0
- workos/types/directory_sync/list_filters.py +21 -0
- workos/types/events/__init__.py +13 -0
- workos/types/events/authentication_payload.py +70 -0
- workos/types/events/connection_payload_with_legacy_fields.py +5 -0
- workos/types/events/directory_group_membership_payload.py +9 -0
- workos/types/events/directory_group_with_previous_attributes.py +6 -0
- workos/types/events/directory_payload.py +16 -0
- workos/types/events/directory_payload_with_legacy_fields.py +29 -0
- workos/types/events/directory_user_with_previous_attributes.py +6 -0
- workos/types/events/event.py +324 -0
- workos/types/events/event_model.py +103 -0
- workos/types/events/event_type.py +59 -0
- workos/types/events/list_filters.py +10 -0
- workos/types/events/organization_domain_verification_failed_payload.py +14 -0
- workos/types/events/previous_attributes.py +3 -0
- workos/types/events/session_payload.py +27 -0
- workos/types/feature_flags/__init__.py +3 -0
- workos/types/feature_flags/feature_flag.py +12 -0
- workos/types/feature_flags/list_filters.py +5 -0
- workos/types/fga/__init__.py +5 -0
- workos/types/fga/authorization_resource_types.py +9 -0
- workos/types/fga/authorization_resources.py +10 -0
- workos/types/fga/check.py +51 -0
- workos/types/fga/list_filters.py +24 -0
- workos/types/fga/warnings.py +33 -0
- workos/types/fga/warrant.py +49 -0
- workos/types/list_resource.py +198 -0
- workos/types/metadata.py +4 -0
- workos/types/mfa/__init__.py +5 -0
- workos/types/mfa/authentication_challenge.py +14 -0
- workos/types/mfa/authentication_challenge_verification_response.py +9 -0
- workos/types/mfa/authentication_factor.py +70 -0
- workos/types/mfa/authentication_factor_totp_and_challenge_response.py +10 -0
- workos/types/mfa/enroll_authentication_factor_type.py +8 -0
- workos/types/organization_domains/__init__.py +1 -0
- workos/types/organization_domains/organization_domain.py +18 -0
- workos/types/organizations/__init__.py +6 -0
- workos/types/organizations/domain_data_input.py +7 -0
- workos/types/organizations/list_filters.py +6 -0
- workos/types/organizations/organization.py +13 -0
- workos/types/organizations/organization_common.py +12 -0
- workos/types/passwordless/__init__.py +2 -0
- workos/types/passwordless/passwordless_session.py +12 -0
- workos/types/passwordless/passwordless_session_type.py +3 -0
- workos/types/pipes/__init__.py +6 -0
- workos/types/pipes/pipes.py +34 -0
- workos/types/portal/__init__.py +2 -0
- workos/types/portal/portal_link.py +7 -0
- workos/types/portal/portal_link_intent.py +11 -0
- workos/types/portal/portal_link_intent_options.py +9 -0
- workos/types/roles/__init__.py +0 -0
- workos/types/roles/role.py +27 -0
- workos/types/sso/__init__.py +4 -0
- workos/types/sso/connection.py +70 -0
- workos/types/sso/connection_domain.py +8 -0
- workos/types/sso/profile.py +35 -0
- workos/types/sso/sso_provider_type.py +10 -0
- workos/types/user_management/__init__.py +12 -0
- workos/types/user_management/authenticate_with_common.py +66 -0
- workos/types/user_management/authentication_response.py +53 -0
- workos/types/user_management/email_verification.py +18 -0
- workos/types/user_management/impersonator.py +8 -0
- workos/types/user_management/invitation.py +26 -0
- workos/types/user_management/list_filters.py +29 -0
- workos/types/user_management/magic_auth.py +18 -0
- workos/types/user_management/oauth_tokens.py +21 -0
- workos/types/user_management/organization_membership.py +25 -0
- workos/types/user_management/password_hash_type.py +4 -0
- workos/types/user_management/password_reset.py +18 -0
- workos/types/user_management/screen_hint.py +3 -0
- workos/types/user_management/session.py +79 -0
- workos/types/user_management/user.py +22 -0
- workos/types/user_management/user_management_provider_type.py +11 -0
- workos/types/vault/__init__.py +2 -0
- workos/types/vault/key.py +25 -0
- workos/types/vault/object.py +38 -0
- workos/types/webhooks/__init__.py +0 -0
- workos/types/webhooks/webhook.py +330 -0
- workos/types/webhooks/webhook_model.py +14 -0
- workos/types/webhooks/webhook_payload.py +4 -0
- workos/types/widgets/__init__.py +2 -0
- workos/types/widgets/widget_scope.py +4 -0
- workos/types/widgets/widget_token_response.py +7 -0
- workos/types/workos_model.py +26 -0
- workos/typing/__init__.py +1 -0
- workos/typing/literals.py +32 -0
- workos/typing/sync_or_async.py +5 -0
- workos/typing/untyped_literal.py +37 -0
- workos/typing/webhooks.py +18 -0
- workos/user_management.py +2400 -0
- workos/utils/_base_http_client.py +252 -0
- workos/utils/crypto_provider.py +39 -0
- workos/utils/http_client.py +214 -0
- workos/utils/pagination_order.py +4 -0
- workos/utils/request_helper.py +27 -0
- workos/vault.py +544 -0
- workos/webhooks.py +96 -39
- workos/widgets.py +55 -0
- {workos-1.5.1.dist-info → workos-5.38.0.dist-info}/LICENSE +1 -1
- workos-5.38.0.dist-info/METADATA +107 -0
- workos-5.38.0.dist-info/RECORD +141 -0
- {workos-1.5.1.dist-info → workos-5.38.0.dist-info}/WHEEL +1 -1
- workos/audit_trail.py +0 -172
- workos/resources/base.py +0 -36
- workos/resources/event.py +0 -42
- workos/resources/event_action.py +0 -11
- workos/resources/sso.py +0 -53
- workos/utils/connection_types.py +0 -17
- workos/utils/request.py +0 -95
- workos/utils/validation.py +0 -45
- workos-1.5.1.dist-info/METADATA +0 -77
- workos-1.5.1.dist-info/RECORD +0 -25
- /workos/{resources/__init__.py → py.typed} +0 -0
- {workos-1.5.1.dist-info → workos-5.38.0.dist-info}/top_level.txt +0 -0
workos/sso.py
CHANGED
|
@@ -1,20 +1,27 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
from
|
|
4
|
-
from
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
from workos.
|
|
8
|
-
from workos.
|
|
9
|
-
from workos.utils.
|
|
10
|
-
|
|
11
|
-
RequestHelper,
|
|
1
|
+
from typing import Optional, Protocol
|
|
2
|
+
from workos._client_configuration import ClientConfiguration
|
|
3
|
+
from workos.types.sso.connection import ConnectionType
|
|
4
|
+
from workos.types.sso.sso_provider_type import SsoProviderType
|
|
5
|
+
from workos.typing.sync_or_async import SyncOrAsync
|
|
6
|
+
from workos.utils.http_client import AsyncHTTPClient, SyncHTTPClient
|
|
7
|
+
from workos.utils.pagination_order import PaginationOrder
|
|
8
|
+
from workos.types.sso import ConnectionWithDomains, Profile, ProfileAndToken
|
|
9
|
+
from workos.utils.request_helper import (
|
|
10
|
+
DEFAULT_LIST_RESPONSE_LIMIT,
|
|
12
11
|
RESPONSE_TYPE_CODE,
|
|
13
12
|
REQUEST_METHOD_DELETE,
|
|
14
13
|
REQUEST_METHOD_GET,
|
|
15
14
|
REQUEST_METHOD_POST,
|
|
15
|
+
QueryParameters,
|
|
16
|
+
RequestHelper,
|
|
17
|
+
REQUEST_METHOD_PUT,
|
|
18
|
+
)
|
|
19
|
+
from workos.types.list_resource import (
|
|
20
|
+
ListArgs,
|
|
21
|
+
ListMetadata,
|
|
22
|
+
ListPage,
|
|
23
|
+
WorkOSListResource,
|
|
16
24
|
)
|
|
17
|
-
from workos.utils.validation import SSO_MODULE, validate_settings
|
|
18
25
|
|
|
19
26
|
AUTHORIZATION_PATH = "sso/authorize"
|
|
20
27
|
TOKEN_PATH = "sso/token"
|
|
@@ -22,174 +29,377 @@ PROFILE_PATH = "sso/profile"
|
|
|
22
29
|
|
|
23
30
|
OAUTH_GRANT_TYPE = "authorization_code"
|
|
24
31
|
|
|
25
|
-
RESPONSE_LIMIT = 10
|
|
26
32
|
|
|
33
|
+
class ConnectionsListFilters(ListArgs, total=False):
|
|
34
|
+
connection_type: Optional[ConnectionType]
|
|
35
|
+
domain: Optional[str]
|
|
36
|
+
organization_id: Optional[str]
|
|
27
37
|
|
|
28
|
-
class SSO(object):
|
|
29
|
-
"""Offers methods to assist in authenticating through the WorkOS SSO service."""
|
|
30
38
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
ConnectionsListResource = WorkOSListResource[
|
|
40
|
+
ConnectionWithDomains, ConnectionsListFilters, ListMetadata
|
|
41
|
+
]
|
|
34
42
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
43
|
+
|
|
44
|
+
class SSOModule(Protocol):
|
|
45
|
+
"""Offers methods to assist in authenticating through the WorkOS SSO service."""
|
|
46
|
+
|
|
47
|
+
_client_configuration: ClientConfiguration
|
|
40
48
|
|
|
41
49
|
def get_authorization_url(
|
|
42
|
-
self,
|
|
43
|
-
|
|
50
|
+
self,
|
|
51
|
+
*,
|
|
52
|
+
redirect_uri: str,
|
|
53
|
+
domain_hint: Optional[str] = None,
|
|
54
|
+
login_hint: Optional[str] = None,
|
|
55
|
+
state: Optional[str] = None,
|
|
56
|
+
provider: Optional[SsoProviderType] = None,
|
|
57
|
+
connection_id: Optional[str] = None,
|
|
58
|
+
organization_id: Optional[str] = None,
|
|
59
|
+
) -> str:
|
|
44
60
|
"""Generate an OAuth 2.0 authorization URL.
|
|
45
61
|
|
|
46
62
|
The URL generated will redirect a User to the Identity Provider configured through
|
|
47
63
|
WorkOS.
|
|
48
64
|
|
|
65
|
+
This method is purposefully designed as synchronous as it does not make any HTTP requests.
|
|
66
|
+
|
|
49
67
|
Kwargs:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
state (str) - An encoded string passed to WorkOS that'd be preserved through the authentication workflow, passed
|
|
68
|
+
redirect_uri (str) : A valid redirect URI, as specified on WorkOS
|
|
69
|
+
state (str) : An encoded string passed to WorkOS that'd be preserved through the authentication workflow, passed
|
|
53
70
|
back as a query parameter
|
|
54
|
-
provider (
|
|
55
|
-
|
|
71
|
+
provider (SSOProviderType) : Authentication service provider descriptor
|
|
72
|
+
connection_id (string) : Unique identifier for a WorkOS Connection
|
|
73
|
+
organization_id (string) : Unique identifier for a WorkOS Organization
|
|
56
74
|
|
|
57
75
|
Returns:
|
|
58
76
|
str: URL to redirect a User to to begin the OAuth workflow with WorkOS
|
|
59
77
|
"""
|
|
60
|
-
params = {
|
|
61
|
-
"client_id":
|
|
78
|
+
params: QueryParameters = {
|
|
79
|
+
"client_id": self._client_configuration.client_id,
|
|
62
80
|
"redirect_uri": redirect_uri,
|
|
63
81
|
"response_type": RESPONSE_TYPE_CODE,
|
|
64
82
|
}
|
|
65
83
|
|
|
66
|
-
if
|
|
84
|
+
if connection_id is None and organization_id is None and provider is None:
|
|
67
85
|
raise ValueError(
|
|
68
|
-
"Incomplete arguments. Need to specify either a 'connection', '
|
|
86
|
+
"Incomplete arguments. Need to specify either a 'connection', 'organization', or 'provider'"
|
|
69
87
|
)
|
|
70
88
|
if provider is not None:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
params["
|
|
74
|
-
if
|
|
75
|
-
params["
|
|
76
|
-
if
|
|
77
|
-
params["connection"] =
|
|
89
|
+
params["provider"] = provider
|
|
90
|
+
if domain_hint is not None:
|
|
91
|
+
params["domain_hint"] = domain_hint
|
|
92
|
+
if login_hint is not None:
|
|
93
|
+
params["login_hint"] = login_hint
|
|
94
|
+
if connection_id is not None:
|
|
95
|
+
params["connection"] = connection_id
|
|
96
|
+
if organization_id is not None:
|
|
97
|
+
params["organization"] = organization_id
|
|
78
98
|
|
|
79
99
|
if state is not None:
|
|
80
100
|
params["state"] = state
|
|
81
101
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
params
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
return prepared_request.url
|
|
102
|
+
return RequestHelper.build_url_with_query_params(
|
|
103
|
+
base_url=self._client_configuration.base_url,
|
|
104
|
+
path=AUTHORIZATION_PATH,
|
|
105
|
+
**params,
|
|
106
|
+
)
|
|
89
107
|
|
|
90
|
-
def get_profile(self,
|
|
108
|
+
def get_profile(self, access_token: str) -> SyncOrAsync[Profile]:
|
|
91
109
|
"""
|
|
92
110
|
Verify that SSO has been completed successfully and retrieve the identity of the user.
|
|
93
111
|
|
|
94
112
|
Args:
|
|
95
|
-
|
|
113
|
+
access_token (str): The token used to authenticate the API call
|
|
96
114
|
|
|
97
115
|
Returns:
|
|
98
|
-
|
|
116
|
+
Profile
|
|
99
117
|
"""
|
|
118
|
+
...
|
|
100
119
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
response = self.request_helper.request(
|
|
104
|
-
PROFILE_PATH, method=REQUEST_METHOD_GET, token=token
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
return WorkOSProfile.construct_from_response(response)
|
|
108
|
-
|
|
109
|
-
def get_profile_and_token(self, code):
|
|
120
|
+
def get_profile_and_token(self, code: str) -> SyncOrAsync[ProfileAndToken]:
|
|
110
121
|
"""Get the profile of an authenticated User
|
|
111
122
|
|
|
112
123
|
Once authenticated, using the code returned having followed the authorization URL,
|
|
113
124
|
get the WorkOS profile of the User.
|
|
114
125
|
|
|
115
126
|
Args:
|
|
116
|
-
code (str): Code returned by WorkOS on completion of OAuth 2.0 workflow
|
|
127
|
+
code (str): Code returned by WorkOS on completion of OAuth 2.0 workflow.
|
|
117
128
|
|
|
118
129
|
Returns:
|
|
119
|
-
|
|
130
|
+
ProfileAndToken: WorkOSProfileAndToken object representing the User.
|
|
120
131
|
"""
|
|
121
|
-
|
|
122
|
-
"client_id": workos.client_id,
|
|
123
|
-
"client_secret": workos.api_key,
|
|
124
|
-
"code": code,
|
|
125
|
-
"grant_type": OAUTH_GRANT_TYPE,
|
|
126
|
-
}
|
|
132
|
+
...
|
|
127
133
|
|
|
128
|
-
|
|
129
|
-
TOKEN_PATH, method=REQUEST_METHOD_POST, params=params
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
return WorkOSProfileAndToken.construct_from_response(response)
|
|
133
|
-
|
|
134
|
-
def get_connection(self, connection):
|
|
134
|
+
def get_connection(self, connection_id: str) -> SyncOrAsync[ConnectionWithDomains]:
|
|
135
135
|
"""Gets details for a single Connection
|
|
136
136
|
|
|
137
137
|
Args:
|
|
138
138
|
connection (str): Connection unique identifier
|
|
139
139
|
|
|
140
140
|
Returns:
|
|
141
|
-
|
|
141
|
+
ConnectionWithDomains: Connection response from WorkOS.
|
|
142
142
|
"""
|
|
143
|
-
|
|
144
|
-
"connections/{connection}".format(connection=connection),
|
|
145
|
-
method=REQUEST_METHOD_GET,
|
|
146
|
-
token=workos.api_key,
|
|
147
|
-
)
|
|
143
|
+
...
|
|
148
144
|
|
|
149
145
|
def list_connections(
|
|
150
146
|
self,
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
147
|
+
*,
|
|
148
|
+
connection_type: Optional[ConnectionType] = None,
|
|
149
|
+
domain: Optional[str] = None,
|
|
150
|
+
organization_id: Optional[str] = None,
|
|
151
|
+
limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
|
|
152
|
+
before: Optional[str] = None,
|
|
153
|
+
after: Optional[str] = None,
|
|
154
|
+
order: PaginationOrder = "desc",
|
|
155
|
+
) -> SyncOrAsync[ConnectionsListResource]:
|
|
158
156
|
"""Gets details for existing Connections.
|
|
159
157
|
|
|
160
|
-
|
|
158
|
+
Kwargs:
|
|
161
159
|
connection_type (ConnectionType): Authentication service provider descriptor. (Optional)
|
|
162
160
|
domain (str): Domain of a Connection. (Optional)
|
|
163
161
|
limit (int): Maximum number of records to return. (Optional)
|
|
164
162
|
before (str): Pagination cursor to receive records before a provided Connection ID. (Optional)
|
|
165
163
|
after (str): Pagination cursor to receive records after a provided Connection ID. (Optional)
|
|
164
|
+
order (Literal["asc","desc"]): Sort records in either ascending or descending (default) order by created_at timestamp. (Optional)
|
|
166
165
|
|
|
167
166
|
Returns:
|
|
168
|
-
|
|
167
|
+
ConnectionsListResource: Connections response from WorkOS.
|
|
169
168
|
"""
|
|
170
|
-
|
|
169
|
+
...
|
|
170
|
+
|
|
171
|
+
def update_connection(
|
|
172
|
+
self,
|
|
173
|
+
*,
|
|
174
|
+
connection_id: str,
|
|
175
|
+
saml_options_signing_key: Optional[str] = None,
|
|
176
|
+
saml_options_signing_cert: Optional[str] = None,
|
|
177
|
+
) -> SyncOrAsync[ConnectionWithDomains]:
|
|
178
|
+
"""Updates a single connection
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
connection_id (str): Connection unique identifier
|
|
182
|
+
saml_options_signing_key (str): Signing key for the connection (Optional)
|
|
183
|
+
saml_options_signing_cert (str): Signing certificate for the connection (Optional)
|
|
184
|
+
Returns:
|
|
185
|
+
None
|
|
186
|
+
"""
|
|
187
|
+
...
|
|
188
|
+
|
|
189
|
+
def delete_connection(self, connection_id: str) -> SyncOrAsync[None]:
|
|
190
|
+
"""Deletes a single Connection
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
connection_id (str): Connection unique identifier
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
None
|
|
197
|
+
"""
|
|
198
|
+
...
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class SSO(SSOModule):
|
|
202
|
+
_http_client: SyncHTTPClient
|
|
203
|
+
|
|
204
|
+
def __init__(
|
|
205
|
+
self, http_client: SyncHTTPClient, client_configuration: ClientConfiguration
|
|
206
|
+
):
|
|
207
|
+
self._client_configuration = client_configuration
|
|
208
|
+
self._http_client = http_client
|
|
209
|
+
|
|
210
|
+
def get_profile(self, access_token: str) -> Profile:
|
|
211
|
+
response = self._http_client.request(
|
|
212
|
+
PROFILE_PATH,
|
|
213
|
+
method=REQUEST_METHOD_GET,
|
|
214
|
+
headers={**self._http_client.auth_header_from_token(access_token)},
|
|
215
|
+
exclude_default_auth_headers=True,
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
return Profile.model_validate(response)
|
|
219
|
+
|
|
220
|
+
def get_profile_and_token(self, code: str) -> ProfileAndToken:
|
|
221
|
+
json = {
|
|
222
|
+
"client_id": self._http_client.client_id,
|
|
223
|
+
"client_secret": self._http_client.api_key,
|
|
224
|
+
"code": code,
|
|
225
|
+
"grant_type": OAUTH_GRANT_TYPE,
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
response = self._http_client.request(
|
|
229
|
+
TOKEN_PATH, method=REQUEST_METHOD_POST, json=json
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
return ProfileAndToken.model_validate(response)
|
|
233
|
+
|
|
234
|
+
def get_connection(self, connection_id: str) -> ConnectionWithDomains:
|
|
235
|
+
response = self._http_client.request(
|
|
236
|
+
f"connections/{connection_id}",
|
|
237
|
+
method=REQUEST_METHOD_GET,
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
return ConnectionWithDomains.model_validate(response)
|
|
241
|
+
|
|
242
|
+
def list_connections(
|
|
243
|
+
self,
|
|
244
|
+
*,
|
|
245
|
+
connection_type: Optional[ConnectionType] = None,
|
|
246
|
+
domain: Optional[str] = None,
|
|
247
|
+
organization_id: Optional[str] = None,
|
|
248
|
+
limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
|
|
249
|
+
before: Optional[str] = None,
|
|
250
|
+
after: Optional[str] = None,
|
|
251
|
+
order: PaginationOrder = "desc",
|
|
252
|
+
) -> ConnectionsListResource:
|
|
253
|
+
params: ConnectionsListFilters = {
|
|
171
254
|
"connection_type": connection_type,
|
|
172
255
|
"domain": domain,
|
|
173
256
|
"organization_id": organization_id,
|
|
174
257
|
"limit": limit,
|
|
175
258
|
"before": before,
|
|
176
259
|
"after": after,
|
|
260
|
+
"order": order,
|
|
177
261
|
}
|
|
178
|
-
|
|
262
|
+
|
|
263
|
+
response = self._http_client.request(
|
|
179
264
|
"connections",
|
|
180
265
|
method=REQUEST_METHOD_GET,
|
|
181
266
|
params=params,
|
|
182
|
-
token=workos.api_key,
|
|
183
267
|
)
|
|
184
268
|
|
|
185
|
-
|
|
186
|
-
|
|
269
|
+
return WorkOSListResource[
|
|
270
|
+
ConnectionWithDomains, ConnectionsListFilters, ListMetadata
|
|
271
|
+
](
|
|
272
|
+
list_method=self.list_connections,
|
|
273
|
+
list_args=params,
|
|
274
|
+
**ListPage[ConnectionWithDomains](**response).model_dump(),
|
|
275
|
+
)
|
|
187
276
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
277
|
+
def update_connection(
|
|
278
|
+
self,
|
|
279
|
+
*,
|
|
280
|
+
connection_id: str,
|
|
281
|
+
saml_options_signing_key: Optional[str] = None,
|
|
282
|
+
saml_options_signing_cert: Optional[str] = None,
|
|
283
|
+
) -> ConnectionWithDomains:
|
|
284
|
+
json = {
|
|
285
|
+
"options": {
|
|
286
|
+
"signing_key": saml_options_signing_key,
|
|
287
|
+
"signing_cert": saml_options_signing_cert,
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
response = self._http_client.request(
|
|
292
|
+
f"connections/{connection_id}",
|
|
293
|
+
method=REQUEST_METHOD_PUT,
|
|
294
|
+
json=json,
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
return ConnectionWithDomains.model_validate(response)
|
|
298
|
+
|
|
299
|
+
def delete_connection(self, connection_id: str) -> None:
|
|
300
|
+
self._http_client.request(
|
|
301
|
+
f"connections/{connection_id}", method=REQUEST_METHOD_DELETE
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
class AsyncSSO(SSOModule):
|
|
306
|
+
_http_client: AsyncHTTPClient
|
|
307
|
+
|
|
308
|
+
def __init__(
|
|
309
|
+
self, http_client: AsyncHTTPClient, client_configuration: ClientConfiguration
|
|
310
|
+
):
|
|
311
|
+
self._client_configuration = client_configuration
|
|
312
|
+
self._http_client = http_client
|
|
313
|
+
|
|
314
|
+
async def get_profile(self, access_token: str) -> Profile:
|
|
315
|
+
response = await self._http_client.request(
|
|
316
|
+
PROFILE_PATH,
|
|
317
|
+
method=REQUEST_METHOD_GET,
|
|
318
|
+
headers={**self._http_client.auth_header_from_token(access_token)},
|
|
319
|
+
exclude_default_auth_headers=True,
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
return Profile.model_validate(response)
|
|
323
|
+
|
|
324
|
+
async def get_profile_and_token(self, code: str) -> ProfileAndToken:
|
|
325
|
+
json = {
|
|
326
|
+
"client_id": self._http_client.client_id,
|
|
327
|
+
"client_secret": self._http_client.api_key,
|
|
328
|
+
"code": code,
|
|
329
|
+
"grant_type": OAUTH_GRANT_TYPE,
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
response = await self._http_client.request(
|
|
333
|
+
TOKEN_PATH, method=REQUEST_METHOD_POST, json=json
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
return ProfileAndToken.model_validate(response)
|
|
337
|
+
|
|
338
|
+
async def get_connection(self, connection_id: str) -> ConnectionWithDomains:
|
|
339
|
+
response = await self._http_client.request(
|
|
340
|
+
f"connections/{connection_id}",
|
|
341
|
+
method=REQUEST_METHOD_GET,
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
return ConnectionWithDomains.model_validate(response)
|
|
345
|
+
|
|
346
|
+
async def list_connections(
|
|
347
|
+
self,
|
|
348
|
+
*,
|
|
349
|
+
connection_type: Optional[ConnectionType] = None,
|
|
350
|
+
domain: Optional[str] = None,
|
|
351
|
+
organization_id: Optional[str] = None,
|
|
352
|
+
limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
|
|
353
|
+
before: Optional[str] = None,
|
|
354
|
+
after: Optional[str] = None,
|
|
355
|
+
order: PaginationOrder = "desc",
|
|
356
|
+
) -> ConnectionsListResource:
|
|
357
|
+
params: ConnectionsListFilters = {
|
|
358
|
+
"connection_type": connection_type,
|
|
359
|
+
"domain": domain,
|
|
360
|
+
"organization_id": organization_id,
|
|
361
|
+
"limit": limit,
|
|
362
|
+
"before": before,
|
|
363
|
+
"after": after,
|
|
364
|
+
"order": order,
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
response = await self._http_client.request(
|
|
368
|
+
"connections", method=REQUEST_METHOD_GET, params=params
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
return WorkOSListResource[
|
|
372
|
+
ConnectionWithDomains, ConnectionsListFilters, ListMetadata
|
|
373
|
+
](
|
|
374
|
+
list_method=self.list_connections,
|
|
375
|
+
list_args=params,
|
|
376
|
+
**ListPage[ConnectionWithDomains](**response).model_dump(),
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
async def update_connection(
|
|
380
|
+
self,
|
|
381
|
+
*,
|
|
382
|
+
connection_id: str,
|
|
383
|
+
saml_options_signing_key: Optional[str] = None,
|
|
384
|
+
saml_options_signing_cert: Optional[str] = None,
|
|
385
|
+
) -> ConnectionWithDomains:
|
|
386
|
+
json = {
|
|
387
|
+
"options": {
|
|
388
|
+
"signing_key": saml_options_signing_key,
|
|
389
|
+
"signing_cert": saml_options_signing_cert,
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
response = await self._http_client.request(
|
|
394
|
+
f"connections/{connection_id}",
|
|
395
|
+
method=REQUEST_METHOD_PUT,
|
|
396
|
+
json=json,
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
return ConnectionWithDomains.model_validate(response)
|
|
400
|
+
|
|
401
|
+
async def delete_connection(self, connection_id: str) -> None:
|
|
402
|
+
await self._http_client.request(
|
|
403
|
+
f"connections/{connection_id}",
|
|
193
404
|
method=REQUEST_METHOD_DELETE,
|
|
194
|
-
token=workos.api_key,
|
|
195
405
|
)
|
workos/types/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .api_keys import ApiKey as ApiKey # noqa: F401
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from typing import Literal, Optional, Sequence
|
|
2
|
+
|
|
3
|
+
from workos.types.workos_model import WorkOSModel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ApiKeyOwner(WorkOSModel):
|
|
7
|
+
type: str
|
|
8
|
+
id: str
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ApiKey(WorkOSModel):
|
|
12
|
+
object: Literal["api_key"]
|
|
13
|
+
id: str
|
|
14
|
+
owner: ApiKeyOwner
|
|
15
|
+
name: str
|
|
16
|
+
obfuscated_value: str
|
|
17
|
+
last_used_at: Optional[str] = None
|
|
18
|
+
permissions: Sequence[str]
|
|
19
|
+
created_at: str
|
|
20
|
+
updated_at: str
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from typing_extensions import NotRequired, Sequence, TypedDict
|
|
2
|
+
|
|
3
|
+
from workos.types.audit_logs.audit_log_event_actor import AuditLogEventActor
|
|
4
|
+
from workos.types.audit_logs.audit_log_event_context import AuditLogEventContext
|
|
5
|
+
from workos.types.audit_logs.audit_log_metadata import AuditLogMetadata
|
|
6
|
+
from workos.types.audit_logs.audit_log_event_target import AuditLogEventTarget
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AuditLogEvent(TypedDict):
|
|
10
|
+
action: str
|
|
11
|
+
version: NotRequired[int]
|
|
12
|
+
occurred_at: str # ISO-8601 datetime of when an event occurred
|
|
13
|
+
actor: AuditLogEventActor
|
|
14
|
+
targets: Sequence[AuditLogEventTarget]
|
|
15
|
+
context: AuditLogEventContext
|
|
16
|
+
metadata: NotRequired[AuditLogMetadata]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from typing_extensions import NotRequired, TypedDict
|
|
2
|
+
|
|
3
|
+
from workos.types.audit_logs.audit_log_metadata import AuditLogMetadata
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AuditLogEventActor(TypedDict):
|
|
7
|
+
"""Describes the entity that generated the event."""
|
|
8
|
+
|
|
9
|
+
id: str
|
|
10
|
+
metadata: NotRequired[AuditLogMetadata]
|
|
11
|
+
name: NotRequired[str]
|
|
12
|
+
type: str
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from typing_extensions import NotRequired, TypedDict
|
|
2
|
+
|
|
3
|
+
from workos.types.audit_logs.audit_log_metadata import AuditLogMetadata
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AuditLogEventTarget(TypedDict):
|
|
7
|
+
"""Describes the entity that was targeted by the event."""
|
|
8
|
+
|
|
9
|
+
id: str
|
|
10
|
+
metadata: NotRequired[AuditLogMetadata]
|
|
11
|
+
name: NotRequired[str]
|
|
12
|
+
type: str
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from typing import Literal, Optional
|
|
2
|
+
|
|
3
|
+
from workos.types.workos_model import WorkOSModel
|
|
4
|
+
from workos.typing.literals import LiteralOrUntyped
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
AuditLogExportState = Literal["error", "pending", "ready"]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AuditLogExport(WorkOSModel):
|
|
11
|
+
"""Representation of a WorkOS audit logs export."""
|
|
12
|
+
|
|
13
|
+
object: Literal["audit_log_export"]
|
|
14
|
+
id: str
|
|
15
|
+
created_at: str
|
|
16
|
+
updated_at: str
|
|
17
|
+
state: LiteralOrUntyped[AuditLogExportState]
|
|
18
|
+
url: Optional[str] = None
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from typing import Literal, Optional
|
|
2
|
+
from workos.types.workos_model import WorkOSModel
|
|
3
|
+
from workos.types.directory_sync.directory_state import DirectoryState
|
|
4
|
+
from workos.types.directory_sync.directory_type import DirectoryType
|
|
5
|
+
from workos.typing.literals import LiteralOrUntyped
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DirectoryUsersMetadata(WorkOSModel):
|
|
9
|
+
active: int
|
|
10
|
+
inactive: int
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class DirectoryMetadata(WorkOSModel):
|
|
14
|
+
users: DirectoryUsersMetadata
|
|
15
|
+
groups: int
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Directory(WorkOSModel):
|
|
19
|
+
"""Representation of a Directory Response as returned by WorkOS through the Directory Sync feature."""
|
|
20
|
+
|
|
21
|
+
id: str
|
|
22
|
+
object: Literal["directory"]
|
|
23
|
+
domain: Optional[str] = None
|
|
24
|
+
name: str
|
|
25
|
+
organization_id: str
|
|
26
|
+
external_key: str
|
|
27
|
+
state: LiteralOrUntyped[DirectoryState]
|
|
28
|
+
type: LiteralOrUntyped[DirectoryType]
|
|
29
|
+
metadata: Optional[DirectoryMetadata] = None
|
|
30
|
+
created_at: str
|
|
31
|
+
updated_at: str
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from typing import Any, Literal, Mapping
|
|
2
|
+
from workos.types.workos_model import WorkOSModel
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DirectoryGroup(WorkOSModel):
|
|
6
|
+
"""Representation of a Directory Group as returned by WorkOS through the Directory Sync feature."""
|
|
7
|
+
|
|
8
|
+
id: str
|
|
9
|
+
object: Literal["directory_group"]
|
|
10
|
+
idp_id: str
|
|
11
|
+
name: str
|
|
12
|
+
directory_id: str
|
|
13
|
+
organization_id: str
|
|
14
|
+
raw_attributes: Mapping[str, Any]
|
|
15
|
+
created_at: str
|
|
16
|
+
updated_at: str
|