From 9b4f7a99e5432dd1ff3c0074ab194cfd7b130e2d Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 2 Jul 2024 13:25:36 +0200 Subject: [PATCH 01/21] add typing for dsync events --- workos/events/__init__.py | 0 workos/events/directory.py | 50 ++++++++++++++++++++++++++++++ workos/resources/directory_sync.py | 10 +++++- 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 workos/events/__init__.py create mode 100644 workos/events/directory.py diff --git a/workos/events/__init__.py b/workos/events/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/workos/events/directory.py b/workos/events/directory.py new file mode 100644 index 00000000..0d72205e --- /dev/null +++ b/workos/events/directory.py @@ -0,0 +1,50 @@ +from typing import Dict, Any, List +from enum import Enum + +JsonDict = Dict[str, Any] + +class DirectoryType(Enum): + AZURE_SCIM_v2 = 'azure scim v2.0' + BAMBOO_HR = 'bamboohr' + BREATHE_HR = 'breathe hr' + CEZANNE_HR = 'cezanne hr' + CYBERARK_SCIM_v2 = 'cyperark scim v2.0' + FOURTH_HR = 'fourth hr' + GENERIC_SCIM_v2 = 'generic scim v2.0' + GOOGLE = 'gsuite directory' + GUSTO = 'gusto' + HIBOB = 'hibob' + JUMPCLOUD_SCIM_v2 = 'jump cloud scim v2.0' + OKTA_SCIM_v2 = 'okta scim v2.0' + ONELOGIN_SCIM_v2 = 'onelogin scim v2.0' + PEOPLE_HR = 'people hr' + PERSONIO = 'personio' + PINGFEDERATE_SCIM_v2 = 'pingfederate scim v2.0' + RIPPLING_SCIM_v2 = 'rippling v2.0' + SFTP = 'sftp' + SFTP_WORKDAY = 'sftp workday' + WORKDAY = 'workday' + +class DirectoryState(Enum): + ACTIVE = 'active' + DELETING = 'deleting' + + +class OrganizationDomain(): + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes['id'] + self.domain: str = attributes['domain'] + +class DirectoryActivatedEvent(): + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes['id'] + self.name: str = attributes['name'] + self.type: DirectoryType = DirectoryType(attributes['type']) + self.state: DirectoryState = DirectoryState(attributes['state']) + self.domains: List[OrganizationDomain] = [] + for domain in attributes['domains']: + self.domains.push(OrganizationDomain(domain)) + self.organization_id: str = attributes['organization_id'] + self.created_at: str = attributes['created_at'] + self.updated_at: str = attributes['updated_at'] + self.external_key: str = attributes['external_key'] diff --git a/workos/resources/directory_sync.py b/workos/resources/directory_sync.py index 1c15b163..6d1c8524 100644 --- a/workos/resources/directory_sync.py +++ b/workos/resources/directory_sync.py @@ -1,4 +1,7 @@ from workos.resources.base import WorkOSBaseResource +from typing import Dict, Any + +JsonDict = Dict[str, Any] class WorkOSDirectory(WorkOSBaseResource): @@ -6,6 +9,11 @@ class WorkOSDirectory(WorkOSBaseResource): Attributes: OBJECT_FIELDS (list): List of fields a WorkOSConnection is comprised of. """ + def __init__(self, attributes: JsonDict) -> None: + super().__init__() + self.id: string = attributes['id'] + self. + OBJECT_FIELDS = [ "object", @@ -20,7 +28,7 @@ class WorkOSDirectory(WorkOSBaseResource): ] @classmethod - def construct_from_response(cls, response): + def construct_from_response(cls, response: JsonDict) -> WorkOSDirectory: connection_response = super(WorkOSDirectory, cls).construct_from_response( response ) From 692b5cb2e5e75f06ad2e735a0d3d3693b64fc81a Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 2 Jul 2024 13:39:51 +0200 Subject: [PATCH 02/21] add directory group and directory user --- workos/events/directory.py | 20 ++++++++++++++- workos/events/directory_group.py | 44 ++++++++++++++++++++++++++++++++ workos/events/directory_user.py | 42 ++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 workos/events/directory_group.py create mode 100644 workos/events/directory_user.py diff --git a/workos/events/directory.py b/workos/events/directory.py index 0d72205e..a50617a8 100644 --- a/workos/events/directory.py +++ b/workos/events/directory.py @@ -40,7 +40,7 @@ def __init__(self, attributes: JsonDict) -> None: self.id: str = attributes['id'] self.name: str = attributes['name'] self.type: DirectoryType = DirectoryType(attributes['type']) - self.state: DirectoryState = DirectoryState(attributes['state']) + self.state: DirectoryState = DirectoryState.ACTIVE self.domains: List[OrganizationDomain] = [] for domain in attributes['domains']: self.domains.push(OrganizationDomain(domain)) @@ -48,3 +48,21 @@ def __init__(self, attributes: JsonDict) -> None: self.created_at: str = attributes['created_at'] self.updated_at: str = attributes['updated_at'] self.external_key: str = attributes['external_key'] + # always 'directory' for this event + self.object: str = attributes['object'] + +class DirectoryDeletedEvent(): + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes['id'] + self.name: str = attributes['name'] + self.type: DirectoryType = DirectoryType(attributes['type']) + self.state: DirectoryState = DirectoryState.DELETING + self.domains: List[OrganizationDomain] = [] + for domain in attributes['domains']: + self.domains.push(OrganizationDomain(domain)) + self.organization_id: str = attributes['organization_id'] + self.created_at: str = attributes['created_at'] + self.updated_at: str = attributes['updated_at'] + self.external_key: str = attributes['external_key'] + # always 'directory' for this event + self.object: str = attributes['object'] diff --git a/workos/events/directory_group.py b/workos/events/directory_group.py new file mode 100644 index 00000000..f5aec825 --- /dev/null +++ b/workos/events/directory_group.py @@ -0,0 +1,44 @@ +from typing import Dict, Any +from enum import Enum + +JsonDict = Dict[str, Any] + +class DirectoryGroupCreatedEvent(): + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes['id'] + self.name: str = attributes['name'] + self.idp_id: str = attributes['idp_id'] + self.directory_id: str = attributes['directory_id'] + self.organization_id: str = attributes['organization_id'] + self.created_at: str = attributes['created_at'] + self.updated_at: str = attributes['updated_at'] + self.raw_attributes: JsonDict = attributes.get('raw_attributes', {}) + # always 'directory_group' for this event + self.object: str = attributes['object'] + +class DirectoryGroupDeletedEvent(): + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes['id'] + self.name: str = attributes['name'] + self.idp_id: str = attributes['idp_id'] + self.directory_id: str = attributes['directory_id'] + self.organization_id: str = attributes['organization_id'] + self.created_at: str = attributes['created_at'] + self.updated_at: str = attributes['updated_at'] + self.raw_attributes: JsonDict = attributes.get('raw_attributes', {}) + # always 'directory_group' for this event + self.object: str = attributes['object'] + +class DirectoryGroupUpdatedEvent(): + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes['id'] + self.name: str = attributes['name'] + self.idp_id: str = attributes['idp_id'] + self.directory_id: str = attributes['directory_id'] + self.organization_id: str = attributes['organization_id'] + self.created_at: str = attributes['created_at'] + self.updated_at: str = attributes['updated_at'] + self.raw_attributes: JsonDict = attributes.get('raw_attributes', {}) + self.previous_attributes: JsonDict = attributes.get('previous_attributes', {}) + # always 'directory_group' for this event + self.object: str = attributes['object'] diff --git a/workos/events/directory_user.py b/workos/events/directory_user.py new file mode 100644 index 00000000..6c659f92 --- /dev/null +++ b/workos/events/directory_user.py @@ -0,0 +1,42 @@ +from typing import Dict, Any, Optional, List +from enum import Enum + +JsonDict = Dict[str, Any] + +class DirectoryUserRole(): + def __init__(self, attributes: JsonDict) -> None: + self.slug: str = attributes['slug'] + +class DirectoryUserEmail(): + def __init__(self, attributes: JsonDict) -> None: + self.type: Optional[str] = attributes.get('type') + self.value: Optional[str] = attributes.get('value') + self.primary: Optional[bool] = attributes.get('primary') + +class DirectoryUserState(Enum): + ACTIVE = 'active' + INACTIVE = 'inactive' + +class DirectoryUserCreatedEvent(): + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes['id'] + self.name: str = attributes['name'] + self.idp_id: str = attributes['idp_id'] + self.directory_id: str = attributes['directory_id'] + self.organization_id: str = attributes['organization_id'] + self.first_name: Optional[str] = attributes.get('first_name') + self.last_name: Optional[str] = attributes.get('last_name') + self.job_title: Optional[str] = attributes.get('job_title') + self.emails: List[DirectoryUserEmail] = [] + for email in attributes.get('emails'): + self.emails.push(DirectoryUserEmail(email)) + self.username: Optional[str] = attributes.get('username') + self.state: DirectoryUserState = DirectoryUserState(attributes['state']) + self.custom_attributes: JsonDict = attributes.get('custom_attributes', {}) + self.raw_attributes: JsonDict = attributes.get('raw_attributes', {}) + self.created_at: str = attributes['created_at'] + self.updated_at: str = attributes['updated_at'] + self.raw_attributes: JsonDict = attributes.get('raw_attributes', {}) + self.role: Optional[DirectoryUserRole] = attributes.get('role') ? DirectoryUserRole(attributes['role']) : None + # always 'directory_user' for this event + self.object: str = attributes['object'] From 44826fa1df7d1486b077185750b336a3df36dc2b Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 2 Jul 2024 13:41:05 +0200 Subject: [PATCH 03/21] undo api change --- workos/resources/directory_sync.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/workos/resources/directory_sync.py b/workos/resources/directory_sync.py index 6d1c8524..9c78429b 100644 --- a/workos/resources/directory_sync.py +++ b/workos/resources/directory_sync.py @@ -1,19 +1,10 @@ from workos.resources.base import WorkOSBaseResource -from typing import Dict, Any - -JsonDict = Dict[str, Any] - class WorkOSDirectory(WorkOSBaseResource): """Representation of a Directory Response as returned by WorkOS through the Directory Sync feature. Attributes: OBJECT_FIELDS (list): List of fields a WorkOSConnection is comprised of. """ - def __init__(self, attributes: JsonDict) -> None: - super().__init__() - self.id: string = attributes['id'] - self. - OBJECT_FIELDS = [ "object", @@ -28,7 +19,7 @@ def __init__(self, attributes: JsonDict) -> None: ] @classmethod - def construct_from_response(cls, response: JsonDict) -> WorkOSDirectory: + def construct_from_response(cls, response): connection_response = super(WorkOSDirectory, cls).construct_from_response( response ) From 75578f4719a7cfb83f6bb1167ca78d28955078ef Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 2 Jul 2024 13:41:53 +0200 Subject: [PATCH 04/21] fmt --- workos/events/directory.py | 116 +++++++++++++++-------------- workos/events/directory_group.py | 77 ++++++++++--------- workos/organizations.py | 6 +- workos/resources/directory_sync.py | 1 + workos/user_management.py | 20 ++--- 5 files changed, 114 insertions(+), 106 deletions(-) diff --git a/workos/events/directory.py b/workos/events/directory.py index a50617a8..3c47a28d 100644 --- a/workos/events/directory.py +++ b/workos/events/directory.py @@ -3,66 +3,70 @@ JsonDict = Dict[str, Any] + class DirectoryType(Enum): - AZURE_SCIM_v2 = 'azure scim v2.0' - BAMBOO_HR = 'bamboohr' - BREATHE_HR = 'breathe hr' - CEZANNE_HR = 'cezanne hr' - CYBERARK_SCIM_v2 = 'cyperark scim v2.0' - FOURTH_HR = 'fourth hr' - GENERIC_SCIM_v2 = 'generic scim v2.0' - GOOGLE = 'gsuite directory' - GUSTO = 'gusto' - HIBOB = 'hibob' - JUMPCLOUD_SCIM_v2 = 'jump cloud scim v2.0' - OKTA_SCIM_v2 = 'okta scim v2.0' - ONELOGIN_SCIM_v2 = 'onelogin scim v2.0' - PEOPLE_HR = 'people hr' - PERSONIO = 'personio' - PINGFEDERATE_SCIM_v2 = 'pingfederate scim v2.0' - RIPPLING_SCIM_v2 = 'rippling v2.0' - SFTP = 'sftp' - SFTP_WORKDAY = 'sftp workday' - WORKDAY = 'workday' + AZURE_SCIM_v2 = "azure scim v2.0" + BAMBOO_HR = "bamboohr" + BREATHE_HR = "breathe hr" + CEZANNE_HR = "cezanne hr" + CYBERARK_SCIM_v2 = "cyperark scim v2.0" + FOURTH_HR = "fourth hr" + GENERIC_SCIM_v2 = "generic scim v2.0" + GOOGLE = "gsuite directory" + GUSTO = "gusto" + HIBOB = "hibob" + JUMPCLOUD_SCIM_v2 = "jump cloud scim v2.0" + OKTA_SCIM_v2 = "okta scim v2.0" + ONELOGIN_SCIM_v2 = "onelogin scim v2.0" + PEOPLE_HR = "people hr" + PERSONIO = "personio" + PINGFEDERATE_SCIM_v2 = "pingfederate scim v2.0" + RIPPLING_SCIM_v2 = "rippling v2.0" + SFTP = "sftp" + SFTP_WORKDAY = "sftp workday" + WORKDAY = "workday" + class DirectoryState(Enum): - ACTIVE = 'active' - DELETING = 'deleting' + ACTIVE = "active" + DELETING = "deleting" + + +class OrganizationDomain: + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes["id"] + self.domain: str = attributes["domain"] -class OrganizationDomain(): - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes['id'] - self.domain: str = attributes['domain'] +class DirectoryActivatedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes["id"] + self.name: str = attributes["name"] + self.type: DirectoryType = DirectoryType(attributes["type"]) + self.state: DirectoryState = DirectoryState.ACTIVE + self.domains: List[OrganizationDomain] = [] + for domain in attributes["domains"]: + self.domains.push(OrganizationDomain(domain)) + self.organization_id: str = attributes["organization_id"] + self.created_at: str = attributes["created_at"] + self.updated_at: str = attributes["updated_at"] + self.external_key: str = attributes["external_key"] + # always 'directory' for this event + self.object: str = attributes["object"] -class DirectoryActivatedEvent(): - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes['id'] - self.name: str = attributes['name'] - self.type: DirectoryType = DirectoryType(attributes['type']) - self.state: DirectoryState = DirectoryState.ACTIVE - self.domains: List[OrganizationDomain] = [] - for domain in attributes['domains']: - self.domains.push(OrganizationDomain(domain)) - self.organization_id: str = attributes['organization_id'] - self.created_at: str = attributes['created_at'] - self.updated_at: str = attributes['updated_at'] - self.external_key: str = attributes['external_key'] - # always 'directory' for this event - self.object: str = attributes['object'] -class DirectoryDeletedEvent(): - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes['id'] - self.name: str = attributes['name'] - self.type: DirectoryType = DirectoryType(attributes['type']) - self.state: DirectoryState = DirectoryState.DELETING - self.domains: List[OrganizationDomain] = [] - for domain in attributes['domains']: - self.domains.push(OrganizationDomain(domain)) - self.organization_id: str = attributes['organization_id'] - self.created_at: str = attributes['created_at'] - self.updated_at: str = attributes['updated_at'] - self.external_key: str = attributes['external_key'] - # always 'directory' for this event - self.object: str = attributes['object'] +class DirectoryDeletedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes["id"] + self.name: str = attributes["name"] + self.type: DirectoryType = DirectoryType(attributes["type"]) + self.state: DirectoryState = DirectoryState.DELETING + self.domains: List[OrganizationDomain] = [] + for domain in attributes["domains"]: + self.domains.push(OrganizationDomain(domain)) + self.organization_id: str = attributes["organization_id"] + self.created_at: str = attributes["created_at"] + self.updated_at: str = attributes["updated_at"] + self.external_key: str = attributes["external_key"] + # always 'directory' for this event + self.object: str = attributes["object"] diff --git a/workos/events/directory_group.py b/workos/events/directory_group.py index f5aec825..61a668cf 100644 --- a/workos/events/directory_group.py +++ b/workos/events/directory_group.py @@ -3,42 +3,45 @@ JsonDict = Dict[str, Any] -class DirectoryGroupCreatedEvent(): - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes['id'] - self.name: str = attributes['name'] - self.idp_id: str = attributes['idp_id'] - self.directory_id: str = attributes['directory_id'] - self.organization_id: str = attributes['organization_id'] - self.created_at: str = attributes['created_at'] - self.updated_at: str = attributes['updated_at'] - self.raw_attributes: JsonDict = attributes.get('raw_attributes', {}) - # always 'directory_group' for this event - self.object: str = attributes['object'] -class DirectoryGroupDeletedEvent(): - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes['id'] - self.name: str = attributes['name'] - self.idp_id: str = attributes['idp_id'] - self.directory_id: str = attributes['directory_id'] - self.organization_id: str = attributes['organization_id'] - self.created_at: str = attributes['created_at'] - self.updated_at: str = attributes['updated_at'] - self.raw_attributes: JsonDict = attributes.get('raw_attributes', {}) - # always 'directory_group' for this event - self.object: str = attributes['object'] +class DirectoryGroupCreatedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes["id"] + self.name: str = attributes["name"] + self.idp_id: str = attributes["idp_id"] + self.directory_id: str = attributes["directory_id"] + self.organization_id: str = attributes["organization_id"] + self.created_at: str = attributes["created_at"] + self.updated_at: str = attributes["updated_at"] + self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) + # always 'directory_group' for this event + self.object: str = attributes["object"] -class DirectoryGroupUpdatedEvent(): - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes['id'] - self.name: str = attributes['name'] - self.idp_id: str = attributes['idp_id'] - self.directory_id: str = attributes['directory_id'] - self.organization_id: str = attributes['organization_id'] - self.created_at: str = attributes['created_at'] - self.updated_at: str = attributes['updated_at'] - self.raw_attributes: JsonDict = attributes.get('raw_attributes', {}) - self.previous_attributes: JsonDict = attributes.get('previous_attributes', {}) - # always 'directory_group' for this event - self.object: str = attributes['object'] + +class DirectoryGroupDeletedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes["id"] + self.name: str = attributes["name"] + self.idp_id: str = attributes["idp_id"] + self.directory_id: str = attributes["directory_id"] + self.organization_id: str = attributes["organization_id"] + self.created_at: str = attributes["created_at"] + self.updated_at: str = attributes["updated_at"] + self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) + # always 'directory_group' for this event + self.object: str = attributes["object"] + + +class DirectoryGroupUpdatedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes["id"] + self.name: str = attributes["name"] + self.idp_id: str = attributes["idp_id"] + self.directory_id: str = attributes["directory_id"] + self.organization_id: str = attributes["organization_id"] + self.created_at: str = attributes["created_at"] + self.updated_at: str = attributes["updated_at"] + self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) + self.previous_attributes: JsonDict = attributes.get("previous_attributes", {}) + # always 'directory_group' for this event + self.object: str = attributes["object"] diff --git a/workos/organizations.py b/workos/organizations.py index 818bd436..d431c1ce 100644 --- a/workos/organizations.py +++ b/workos/organizations.py @@ -271,9 +271,9 @@ def update_organization( "If you need to allow sign-ins from any email domain, contact support@workos.com.", DeprecationWarning, ) - params[ - "allow_profiles_outside_organization" - ] = allow_profiles_outside_organization + params["allow_profiles_outside_organization"] = ( + allow_profiles_outside_organization + ) if domain_data is not None: params["domain_data"] = domain_data diff --git a/workos/resources/directory_sync.py b/workos/resources/directory_sync.py index 9c78429b..1c15b163 100644 --- a/workos/resources/directory_sync.py +++ b/workos/resources/directory_sync.py @@ -1,5 +1,6 @@ from workos.resources.base import WorkOSBaseResource + class WorkOSDirectory(WorkOSBaseResource): """Representation of a Directory Response as returned by WorkOS through the Directory Sync feature. Attributes: diff --git a/workos/user_management.py b/workos/user_management.py index 73760ba7..113355b2 100644 --- a/workos/user_management.py +++ b/workos/user_management.py @@ -1159,17 +1159,17 @@ def enroll_auth_factor( ) factor_and_challenge = {} - factor_and_challenge[ - "authentication_factor" - ] = WorkOSAuthenticationFactorTotp.construct_from_response( - response["authentication_factor"] - ).to_dict() + factor_and_challenge["authentication_factor"] = ( + WorkOSAuthenticationFactorTotp.construct_from_response( + response["authentication_factor"] + ).to_dict() + ) - factor_and_challenge[ - "authentication_challenge" - ] = WorkOSChallenge.construct_from_response( - response["authentication_challenge"] - ).to_dict() + factor_and_challenge["authentication_challenge"] = ( + WorkOSChallenge.construct_from_response( + response["authentication_challenge"] + ).to_dict() + ) return factor_and_challenge From 622036f4b9d94a07f76ed510c5fb49d4c7665aba Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 2 Jul 2024 13:44:06 +0200 Subject: [PATCH 05/21] ts -> py --- workos/events/directory_user.py | 129 +++++++++++++++++++++++--------- 1 file changed, 95 insertions(+), 34 deletions(-) diff --git a/workos/events/directory_user.py b/workos/events/directory_user.py index 6c659f92..69c4b730 100644 --- a/workos/events/directory_user.py +++ b/workos/events/directory_user.py @@ -3,40 +3,101 @@ JsonDict = Dict[str, Any] -class DirectoryUserRole(): - def __init__(self, attributes: JsonDict) -> None: - self.slug: str = attributes['slug'] -class DirectoryUserEmail(): - def __init__(self, attributes: JsonDict) -> None: - self.type: Optional[str] = attributes.get('type') - self.value: Optional[str] = attributes.get('value') - self.primary: Optional[bool] = attributes.get('primary') +class DirectoryUserRole: + def __init__(self, attributes: JsonDict) -> None: + self.slug: str = attributes["slug"] + + +class DirectoryUserEmail: + def __init__(self, attributes: JsonDict) -> None: + self.type: Optional[str] = attributes.get("type") + self.value: Optional[str] = attributes.get("value") + self.primary: Optional[bool] = attributes.get("primary") + class DirectoryUserState(Enum): - ACTIVE = 'active' - INACTIVE = 'inactive' - -class DirectoryUserCreatedEvent(): - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes['id'] - self.name: str = attributes['name'] - self.idp_id: str = attributes['idp_id'] - self.directory_id: str = attributes['directory_id'] - self.organization_id: str = attributes['organization_id'] - self.first_name: Optional[str] = attributes.get('first_name') - self.last_name: Optional[str] = attributes.get('last_name') - self.job_title: Optional[str] = attributes.get('job_title') - self.emails: List[DirectoryUserEmail] = [] - for email in attributes.get('emails'): - self.emails.push(DirectoryUserEmail(email)) - self.username: Optional[str] = attributes.get('username') - self.state: DirectoryUserState = DirectoryUserState(attributes['state']) - self.custom_attributes: JsonDict = attributes.get('custom_attributes', {}) - self.raw_attributes: JsonDict = attributes.get('raw_attributes', {}) - self.created_at: str = attributes['created_at'] - self.updated_at: str = attributes['updated_at'] - self.raw_attributes: JsonDict = attributes.get('raw_attributes', {}) - self.role: Optional[DirectoryUserRole] = attributes.get('role') ? DirectoryUserRole(attributes['role']) : None - # always 'directory_user' for this event - self.object: str = attributes['object'] + ACTIVE = "active" + INACTIVE = "inactive" + + +class DirectoryUserCreatedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes["id"] + self.name: str = attributes["name"] + self.idp_id: str = attributes["idp_id"] + self.directory_id: str = attributes["directory_id"] + self.organization_id: str = attributes["organization_id"] + self.first_name: Optional[str] = attributes.get("first_name") + self.last_name: Optional[str] = attributes.get("last_name") + self.job_title: Optional[str] = attributes.get("job_title") + self.emails: List[DirectoryUserEmail] = [] + for email in attributes.get("emails"): + self.emails.push(DirectoryUserEmail(email)) + self.username: Optional[str] = attributes.get("username") + self.state: DirectoryUserState = DirectoryUserState(attributes["state"]) + self.custom_attributes: JsonDict = attributes.get("custom_attributes", {}) + self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) + self.created_at: str = attributes["created_at"] + self.updated_at: str = attributes["updated_at"] + self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) + self.role: Optional[DirectoryUserRole] = ( + DirectoryUserRole(attributes["role"]) if attributes.get("role") else None + ) + # always 'directory_user' for this event + self.object: str = attributes["object"] + + +class DirectoryUserDeletedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes["id"] + self.name: str = attributes["name"] + self.idp_id: str = attributes["idp_id"] + self.directory_id: str = attributes["directory_id"] + self.organization_id: str = attributes["organization_id"] + self.first_name: Optional[str] = attributes.get("first_name") + self.last_name: Optional[str] = attributes.get("last_name") + self.job_title: Optional[str] = attributes.get("job_title") + self.emails: List[DirectoryUserEmail] = [] + for email in attributes.get("emails"): + self.emails.push(DirectoryUserEmail(email)) + self.username: Optional[str] = attributes.get("username") + self.state: DirectoryUserState = DirectoryUserState(attributes["state"]) + self.custom_attributes: JsonDict = attributes.get("custom_attributes", {}) + self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) + self.created_at: str = attributes["created_at"] + self.updated_at: str = attributes["updated_at"] + self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) + self.role: Optional[DirectoryUserRole] = ( + DirectoryUserRole(attributes["role"]) if attributes.get("role") else None + ) + # always 'directory_user' for this event + self.object: str = attributes["object"] + + +class DirectoryUserUpdatedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes["id"] + self.name: str = attributes["name"] + self.idp_id: str = attributes["idp_id"] + self.directory_id: str = attributes["directory_id"] + self.organization_id: str = attributes["organization_id"] + self.first_name: Optional[str] = attributes.get("first_name") + self.last_name: Optional[str] = attributes.get("last_name") + self.job_title: Optional[str] = attributes.get("job_title") + self.emails: List[DirectoryUserEmail] = [] + for email in attributes.get("emails"): + self.emails.push(DirectoryUserEmail(email)) + self.username: Optional[str] = attributes.get("username") + self.state: DirectoryUserState = DirectoryUserState(attributes["state"]) + self.custom_attributes: JsonDict = attributes.get("custom_attributes", {}) + self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) + self.created_at: str = attributes["created_at"] + self.updated_at: str = attributes["updated_at"] + self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) + self.role: Optional[DirectoryUserRole] = ( + DirectoryUserRole(attributes["role"]) if attributes.get("role") else None + ) + self.previous_attributes: JsonDict = attributes.get("previous_attributes", {}) + # always 'directory_user' for this event + self.object: str = attributes["object"] From 49bb7ba1c8921628da9574441ab1db52252d1025 Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 2 Jul 2024 13:47:16 +0200 Subject: [PATCH 06/21] fmt --- workos/organizations.py | 6 +++--- workos/user_management.py | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/workos/organizations.py b/workos/organizations.py index d431c1ce..818bd436 100644 --- a/workos/organizations.py +++ b/workos/organizations.py @@ -271,9 +271,9 @@ def update_organization( "If you need to allow sign-ins from any email domain, contact support@workos.com.", DeprecationWarning, ) - params["allow_profiles_outside_organization"] = ( - allow_profiles_outside_organization - ) + params[ + "allow_profiles_outside_organization" + ] = allow_profiles_outside_organization if domain_data is not None: params["domain_data"] = domain_data diff --git a/workos/user_management.py b/workos/user_management.py index 113355b2..73760ba7 100644 --- a/workos/user_management.py +++ b/workos/user_management.py @@ -1159,17 +1159,17 @@ def enroll_auth_factor( ) factor_and_challenge = {} - factor_and_challenge["authentication_factor"] = ( - WorkOSAuthenticationFactorTotp.construct_from_response( - response["authentication_factor"] - ).to_dict() - ) + factor_and_challenge[ + "authentication_factor" + ] = WorkOSAuthenticationFactorTotp.construct_from_response( + response["authentication_factor"] + ).to_dict() - factor_and_challenge["authentication_challenge"] = ( - WorkOSChallenge.construct_from_response( - response["authentication_challenge"] - ).to_dict() - ) + factor_and_challenge[ + "authentication_challenge" + ] = WorkOSChallenge.construct_from_response( + response["authentication_challenge"] + ).to_dict() return factor_and_challenge From 7e986326a13b1b4362d51768583c0d8459bec2b1 Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 2 Jul 2024 13:49:43 +0200 Subject: [PATCH 07/21] new name --- workos/events/__init__.py | 0 workos/events/directory.py | 72 --------------------- workos/events/directory_group.py | 47 -------------- workos/events/directory_user.py | 103 ------------------------------- 4 files changed, 222 deletions(-) delete mode 100644 workos/events/__init__.py delete mode 100644 workos/events/directory.py delete mode 100644 workos/events/directory_group.py delete mode 100644 workos/events/directory_user.py diff --git a/workos/events/__init__.py b/workos/events/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/workos/events/directory.py b/workos/events/directory.py deleted file mode 100644 index 3c47a28d..00000000 --- a/workos/events/directory.py +++ /dev/null @@ -1,72 +0,0 @@ -from typing import Dict, Any, List -from enum import Enum - -JsonDict = Dict[str, Any] - - -class DirectoryType(Enum): - AZURE_SCIM_v2 = "azure scim v2.0" - BAMBOO_HR = "bamboohr" - BREATHE_HR = "breathe hr" - CEZANNE_HR = "cezanne hr" - CYBERARK_SCIM_v2 = "cyperark scim v2.0" - FOURTH_HR = "fourth hr" - GENERIC_SCIM_v2 = "generic scim v2.0" - GOOGLE = "gsuite directory" - GUSTO = "gusto" - HIBOB = "hibob" - JUMPCLOUD_SCIM_v2 = "jump cloud scim v2.0" - OKTA_SCIM_v2 = "okta scim v2.0" - ONELOGIN_SCIM_v2 = "onelogin scim v2.0" - PEOPLE_HR = "people hr" - PERSONIO = "personio" - PINGFEDERATE_SCIM_v2 = "pingfederate scim v2.0" - RIPPLING_SCIM_v2 = "rippling v2.0" - SFTP = "sftp" - SFTP_WORKDAY = "sftp workday" - WORKDAY = "workday" - - -class DirectoryState(Enum): - ACTIVE = "active" - DELETING = "deleting" - - -class OrganizationDomain: - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes["id"] - self.domain: str = attributes["domain"] - - -class DirectoryActivatedEvent: - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes["id"] - self.name: str = attributes["name"] - self.type: DirectoryType = DirectoryType(attributes["type"]) - self.state: DirectoryState = DirectoryState.ACTIVE - self.domains: List[OrganizationDomain] = [] - for domain in attributes["domains"]: - self.domains.push(OrganizationDomain(domain)) - self.organization_id: str = attributes["organization_id"] - self.created_at: str = attributes["created_at"] - self.updated_at: str = attributes["updated_at"] - self.external_key: str = attributes["external_key"] - # always 'directory' for this event - self.object: str = attributes["object"] - - -class DirectoryDeletedEvent: - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes["id"] - self.name: str = attributes["name"] - self.type: DirectoryType = DirectoryType(attributes["type"]) - self.state: DirectoryState = DirectoryState.DELETING - self.domains: List[OrganizationDomain] = [] - for domain in attributes["domains"]: - self.domains.push(OrganizationDomain(domain)) - self.organization_id: str = attributes["organization_id"] - self.created_at: str = attributes["created_at"] - self.updated_at: str = attributes["updated_at"] - self.external_key: str = attributes["external_key"] - # always 'directory' for this event - self.object: str = attributes["object"] diff --git a/workos/events/directory_group.py b/workos/events/directory_group.py deleted file mode 100644 index 61a668cf..00000000 --- a/workos/events/directory_group.py +++ /dev/null @@ -1,47 +0,0 @@ -from typing import Dict, Any -from enum import Enum - -JsonDict = Dict[str, Any] - - -class DirectoryGroupCreatedEvent: - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes["id"] - self.name: str = attributes["name"] - self.idp_id: str = attributes["idp_id"] - self.directory_id: str = attributes["directory_id"] - self.organization_id: str = attributes["organization_id"] - self.created_at: str = attributes["created_at"] - self.updated_at: str = attributes["updated_at"] - self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) - # always 'directory_group' for this event - self.object: str = attributes["object"] - - -class DirectoryGroupDeletedEvent: - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes["id"] - self.name: str = attributes["name"] - self.idp_id: str = attributes["idp_id"] - self.directory_id: str = attributes["directory_id"] - self.organization_id: str = attributes["organization_id"] - self.created_at: str = attributes["created_at"] - self.updated_at: str = attributes["updated_at"] - self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) - # always 'directory_group' for this event - self.object: str = attributes["object"] - - -class DirectoryGroupUpdatedEvent: - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes["id"] - self.name: str = attributes["name"] - self.idp_id: str = attributes["idp_id"] - self.directory_id: str = attributes["directory_id"] - self.organization_id: str = attributes["organization_id"] - self.created_at: str = attributes["created_at"] - self.updated_at: str = attributes["updated_at"] - self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) - self.previous_attributes: JsonDict = attributes.get("previous_attributes", {}) - # always 'directory_group' for this event - self.object: str = attributes["object"] diff --git a/workos/events/directory_user.py b/workos/events/directory_user.py deleted file mode 100644 index 69c4b730..00000000 --- a/workos/events/directory_user.py +++ /dev/null @@ -1,103 +0,0 @@ -from typing import Dict, Any, Optional, List -from enum import Enum - -JsonDict = Dict[str, Any] - - -class DirectoryUserRole: - def __init__(self, attributes: JsonDict) -> None: - self.slug: str = attributes["slug"] - - -class DirectoryUserEmail: - def __init__(self, attributes: JsonDict) -> None: - self.type: Optional[str] = attributes.get("type") - self.value: Optional[str] = attributes.get("value") - self.primary: Optional[bool] = attributes.get("primary") - - -class DirectoryUserState(Enum): - ACTIVE = "active" - INACTIVE = "inactive" - - -class DirectoryUserCreatedEvent: - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes["id"] - self.name: str = attributes["name"] - self.idp_id: str = attributes["idp_id"] - self.directory_id: str = attributes["directory_id"] - self.organization_id: str = attributes["organization_id"] - self.first_name: Optional[str] = attributes.get("first_name") - self.last_name: Optional[str] = attributes.get("last_name") - self.job_title: Optional[str] = attributes.get("job_title") - self.emails: List[DirectoryUserEmail] = [] - for email in attributes.get("emails"): - self.emails.push(DirectoryUserEmail(email)) - self.username: Optional[str] = attributes.get("username") - self.state: DirectoryUserState = DirectoryUserState(attributes["state"]) - self.custom_attributes: JsonDict = attributes.get("custom_attributes", {}) - self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) - self.created_at: str = attributes["created_at"] - self.updated_at: str = attributes["updated_at"] - self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) - self.role: Optional[DirectoryUserRole] = ( - DirectoryUserRole(attributes["role"]) if attributes.get("role") else None - ) - # always 'directory_user' for this event - self.object: str = attributes["object"] - - -class DirectoryUserDeletedEvent: - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes["id"] - self.name: str = attributes["name"] - self.idp_id: str = attributes["idp_id"] - self.directory_id: str = attributes["directory_id"] - self.organization_id: str = attributes["organization_id"] - self.first_name: Optional[str] = attributes.get("first_name") - self.last_name: Optional[str] = attributes.get("last_name") - self.job_title: Optional[str] = attributes.get("job_title") - self.emails: List[DirectoryUserEmail] = [] - for email in attributes.get("emails"): - self.emails.push(DirectoryUserEmail(email)) - self.username: Optional[str] = attributes.get("username") - self.state: DirectoryUserState = DirectoryUserState(attributes["state"]) - self.custom_attributes: JsonDict = attributes.get("custom_attributes", {}) - self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) - self.created_at: str = attributes["created_at"] - self.updated_at: str = attributes["updated_at"] - self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) - self.role: Optional[DirectoryUserRole] = ( - DirectoryUserRole(attributes["role"]) if attributes.get("role") else None - ) - # always 'directory_user' for this event - self.object: str = attributes["object"] - - -class DirectoryUserUpdatedEvent: - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes["id"] - self.name: str = attributes["name"] - self.idp_id: str = attributes["idp_id"] - self.directory_id: str = attributes["directory_id"] - self.organization_id: str = attributes["organization_id"] - self.first_name: Optional[str] = attributes.get("first_name") - self.last_name: Optional[str] = attributes.get("last_name") - self.job_title: Optional[str] = attributes.get("job_title") - self.emails: List[DirectoryUserEmail] = [] - for email in attributes.get("emails"): - self.emails.push(DirectoryUserEmail(email)) - self.username: Optional[str] = attributes.get("username") - self.state: DirectoryUserState = DirectoryUserState(attributes["state"]) - self.custom_attributes: JsonDict = attributes.get("custom_attributes", {}) - self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) - self.created_at: str = attributes["created_at"] - self.updated_at: str = attributes["updated_at"] - self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) - self.role: Optional[DirectoryUserRole] = ( - DirectoryUserRole(attributes["role"]) if attributes.get("role") else None - ) - self.previous_attributes: JsonDict = attributes.get("previous_attributes", {}) - # always 'directory_user' for this event - self.object: str = attributes["object"] From d6a137fd4a8cd9c9b02c02e207ef65d8e3acb121 Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 2 Jul 2024 14:13:53 +0200 Subject: [PATCH 08/21] rename files --- workos/event_objects/__init__.py | 0 workos/event_objects/directory.py | 71 ++++++++++++++++++++++++ workos/event_objects/directory_group.py | 42 ++++++++++++++ workos/event_objects/directory_user.py | 72 ++++++++++++++++++++++++ workos/events.py | 73 +++++++++++++++++++++++++ 5 files changed, 258 insertions(+) create mode 100644 workos/event_objects/__init__.py create mode 100644 workos/event_objects/directory.py create mode 100644 workos/event_objects/directory_group.py create mode 100644 workos/event_objects/directory_user.py diff --git a/workos/event_objects/__init__.py b/workos/event_objects/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/workos/event_objects/directory.py b/workos/event_objects/directory.py new file mode 100644 index 00000000..5b308321 --- /dev/null +++ b/workos/event_objects/directory.py @@ -0,0 +1,71 @@ +from typing import Dict, Any, List +from enum import Enum + +JsonDict = Dict[str, Any] + + +class DirectoryType(Enum): + AZURE_SCIM_v2 = "azure scim v2.0" + BAMBOO_HR = "bamboohr" + BREATHE_HR = "breathe hr" + CEZANNE_HR = "cezanne hr" + CYBERARK_SCIM_v2 = "cyperark scim v2.0" + FOURTH_HR = "fourth hr" + GENERIC_SCIM_v2 = "generic scim v2.0" + GOOGLE = "gsuite directory" + GUSTO = "gusto" + HIBOB = "hibob" + JUMPCLOUD_SCIM_v2 = "jump cloud scim v2.0" + OKTA_SCIM_v2 = "okta scim v2.0" + ONELOGIN_SCIM_v2 = "onelogin scim v2.0" + PEOPLE_HR = "people hr" + PERSONIO = "personio" + PINGFEDERATE_SCIM_v2 = "pingfederate scim v2.0" + RIPPLING_SCIM_v2 = "rippling v2.0" + SFTP = "sftp" + SFTP_WORKDAY = "sftp workday" + WORKDAY = "workday" + + +class DirectoryState(Enum): + ACTIVE = "active" + DELETING = "deleting" + + +class OrganizationDomain: + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes["id"] + self.domain: str = attributes["domain"] + + +class DirectoryEvent: + def __init__(self) -> None: + self.id: str = attributes["id"] + self.name: str = attributes["name"] + self.type: DirectoryType = DirectoryType(attributes["type"]) + self.state: DirectoryState = DirectoryState.ACTIVE + self.domains: List[OrganizationDomain] = [] + for domain in attributes["domains"]: + self.domains.push(OrganizationDomain(domain)) + self.organization_id: str = attributes["organization_id"] + self.created_at: str = attributes["created_at"] + self.updated_at: str = attributes["updated_at"] + self.external_key: str = attributes["external_key"] + # always 'directory' for this event + self.object: str = attributes["object"] + + +class DirectoryActivatedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.event: str = "dsync.activated" + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: DirectoryEvent = DirectoryEvent(attributes["data"]) + + +class DirectoryDeletedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.event: str = "dsync.deleted" + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: DirectoryEvent = DirectoryEvent(attributes["data"]) diff --git a/workos/event_objects/directory_group.py b/workos/event_objects/directory_group.py new file mode 100644 index 00000000..98260c3c --- /dev/null +++ b/workos/event_objects/directory_group.py @@ -0,0 +1,42 @@ +from typing import Dict, Any + +JsonDict = Dict[str, Any] + + +class DirectoryGroupEvent: + def __init__(self) -> None: + self.id: str = attributes["id"] + self.name: str = attributes["name"] + self.idp_id: str = attributes["idp_id"] + self.directory_id: str = attributes["directory_id"] + self.organization_id: str = attributes["organization_id"] + self.created_at: str = attributes["created_at"] + self.updated_at: str = attributes["updated_at"] + self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) + self.previous_attributes: JsonDict = attributes.get("previous_attributes", {}) + # always 'directory_group' for this event + self.object: str = attributes["object"] + + +class DirectoryGroupCreatedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.event: str = "dsync.group.created" + self.id: str = attributes["id"] + self.created_at: str = attributes["created_at"] + self.data: DirectoryGroupEvent = DirectoryGroupEvent(attributes["data"]) + + +class DirectoryGroupDeletedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.event: str = "dsync.group.deleted" + self.id: str = attributes["id"] + self.created_at: str = attributes["created_at"] + self.data: DirectoryGroupEvent = DirectoryGroupEvent(attributes["data"]) + + +class DirectoryGroupUpdatedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.event: str = "dsync.group.updated" + self.id: str = attributes["id"] + self.created_at: str = attributes["created_at"] + self.data: DirectoryGroupEvent = DirectoryGroupEvent(attributes["data"]) diff --git a/workos/event_objects/directory_user.py b/workos/event_objects/directory_user.py new file mode 100644 index 00000000..bb9c7638 --- /dev/null +++ b/workos/event_objects/directory_user.py @@ -0,0 +1,72 @@ +from typing import Dict, Any, Optional, List +from enum import Enum + +JsonDict = Dict[str, Any] + + +class DirectoryUserRole: + def __init__(self, attributes: JsonDict) -> None: + self.slug: str = attributes["slug"] + + +class DirectoryUserEmail: + def __init__(self, attributes: JsonDict) -> None: + self.type: Optional[str] = attributes.get("type") + self.value: Optional[str] = attributes.get("value") + self.primary: Optional[bool] = attributes.get("primary") + + +class DirectoryUserState(Enum): + ACTIVE = "active" + INACTIVE = "inactive" + + +class DirectoryUserEvent: + def __init__(self) -> None: + self.id: str = attributes["id"] + self.name: str = attributes["name"] + self.idp_id: str = attributes["idp_id"] + self.directory_id: str = attributes["directory_id"] + self.organization_id: str = attributes["organization_id"] + self.first_name: Optional[str] = attributes.get("first_name") + self.last_name: Optional[str] = attributes.get("last_name") + self.job_title: Optional[str] = attributes.get("job_title") + self.emails: List[DirectoryUserEmail] = [] + for email in attributes.get("emails"): + self.emails.push(DirectoryUserEmail(email)) + self.username: Optional[str] = attributes.get("username") + self.state: DirectoryUserState = DirectoryUserState(attributes["state"]) + self.custom_attributes: JsonDict = attributes.get("custom_attributes", {}) + self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) + self.created_at: str = attributes["created_at"] + self.updated_at: str = attributes["updated_at"] + self.role: Optional[DirectoryUserRole] = ( + DirectoryUserRole(attributes["role"]) if attributes.get("role") else None + ) + self.previous_attributes: JsonDict = attributes.get("previous_attributes", {}) + # always 'directory_user' for this event + self.object: str = attributes["object"] + + +class DirectoryUserCreatedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes["id"] + self.event: str = "dsync.user.created" + self.created_at: str = attributes["created_at"] + self.data: DirectoryUserEvent = DirectoryUserEvent(attributes["data"]) + + +class DirectoryUserDeletedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes["id"] + self.event: str = "dsync.user.deleted" + self.created_at: str = attributes["created_at"] + self.data: DirectoryUserEvent = DirectoryUserEvent(attributes["data"]) + + +class DirectoryUserUpdatedEvent: + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes["id"] + self.event: str = "dsync.user.updated" + self.created_at: str = attributes["created_at"] + self.data: DirectoryUserEvent = DirectoryUserEvent(attributes["data"]) diff --git a/workos/events.py b/workos/events.py index d4aef529..b6314f21 100644 --- a/workos/events.py +++ b/workos/events.py @@ -7,6 +7,40 @@ from workos.utils.validation import EVENTS_MODULE, validate_settings from workos.resources.list import WorkOSListResource +from typing import Optional, Dict, TypedDict, List, Any +from workos.event_objects.directory import ( + DirectoryActivatedEvent, + DirectoryDeletedEvent, +) +from workos.event_objects.directory_group import ( + DirectoryGroupCreatedEvent, + DirectoryGroupDeletedEvent, + DirectoryGroupUpdatedEvent, +) +from workos.event_objects.directory_user import ( + DirectoryUserCreatedEvent, + DirectoryUserDeletedEvent, + DirectoryUserUpdatedEvent, +) + +JsonDict = Dict[str, Any] +DSYNC_EVENT_TYPES = Dict[ + DirectoryUserUpdatedEvent.event : DirectoryUserUpdatedEvent, + DirectoryUserCreatedEvent.event : DirectoryUserCreatedEvent, + DirectoryUserDeletedEvent.event : DirectoryUserDeletedEvent, + DirectoryGroupCreatedEvent.event : DirectoryGroupCreatedEvent, + DirectoryGroupDeletedEvent.event : DirectoryGroupDeletedEvent, + DirectoryGroupUpdatedEvent.event : DirectoryGroupUpdatedEvent, + DirectoryActivatedEvent.event : DirectoryActivatedEvent, + DirectoryActivatedEvent.event : DirectoryDeletedEvent, +] + + +class ListDsyncEventsResponse(TypedDict): + object: str + data: List[DSYNC_EVENT_TYPES.values()] + metadata: JsonDict + RESPONSE_LIMIT = 10 @@ -24,6 +58,45 @@ def request_helper(self): self._request_helper = RequestHelper() return self._request_helper + def list_dsync_events( + self, + limit: Optional[int] = None, + organization_id: Optional[str] = None, + after: Optional[str] = None, + range_start: Optional[str] = None, + range_end: Optional[str] = None, + ) -> ListDsyncEventsResponse: + if limit is None: + limit = RESPONSE_LIMIT + default_limit = True + + params = { + "events": DSYNC_EVENT_TYPES.keys(), + "limit": limit, + "after": after, + "organization_id": organization_id, + "range_start": range_start, + "range_end": range_end, + } + + response = self.request_helper.request( + "events", + method=REQUEST_METHOD_GET, + params=params, + token=workos.api_key, + ) + + response = { + "object": "list", + "params": params, + } + + data = [] + for list_data in response["data"]: + data.push(DSYNC_EVENT_TYPES[list_data["event"]](list_data)) + response["data"] = data + return response + def list_events( self, events=None, From 548dc53ee769c76ea840c612ec006b93484a9881 Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 2 Jul 2024 14:22:44 +0200 Subject: [PATCH 09/21] export type util --- workos/event_objects/directory.py | 7 +++---- workos/event_objects/directory_group.py | 6 ++---- workos/event_objects/directory_user.py | 5 ++--- workos/events.py | 2 +- workos/utils/types.py | 3 +++ 5 files changed, 11 insertions(+), 12 deletions(-) create mode 100644 workos/utils/types.py diff --git a/workos/event_objects/directory.py b/workos/event_objects/directory.py index 5b308321..59022725 100644 --- a/workos/event_objects/directory.py +++ b/workos/event_objects/directory.py @@ -1,7 +1,6 @@ -from typing import Dict, Any, List +from typing import List from enum import Enum - -JsonDict = Dict[str, Any] +from workos.utils.types import JsonDict class DirectoryType(Enum): @@ -39,7 +38,7 @@ def __init__(self, attributes: JsonDict) -> None: class DirectoryEvent: - def __init__(self) -> None: + def __init__(self, attributes) -> None: self.id: str = attributes["id"] self.name: str = attributes["name"] self.type: DirectoryType = DirectoryType(attributes["type"]) diff --git a/workos/event_objects/directory_group.py b/workos/event_objects/directory_group.py index 98260c3c..c0d26956 100644 --- a/workos/event_objects/directory_group.py +++ b/workos/event_objects/directory_group.py @@ -1,10 +1,8 @@ -from typing import Dict, Any - -JsonDict = Dict[str, Any] +from workos.utils.types import JsonDict class DirectoryGroupEvent: - def __init__(self) -> None: + def __init__(self, attributes) -> None: self.id: str = attributes["id"] self.name: str = attributes["name"] self.idp_id: str = attributes["idp_id"] diff --git a/workos/event_objects/directory_user.py b/workos/event_objects/directory_user.py index bb9c7638..c7c1fb54 100644 --- a/workos/event_objects/directory_user.py +++ b/workos/event_objects/directory_user.py @@ -1,7 +1,6 @@ -from typing import Dict, Any, Optional, List +from typing import Optional, List from enum import Enum - -JsonDict = Dict[str, Any] +from workos.utils.types import JsonDict class DirectoryUserRole: diff --git a/workos/events.py b/workos/events.py index b6314f21..49ac7fa2 100644 --- a/workos/events.py +++ b/workos/events.py @@ -6,6 +6,7 @@ ) from workos.utils.validation import EVENTS_MODULE, validate_settings +from workos.utils.types import JsonDict from workos.resources.list import WorkOSListResource from typing import Optional, Dict, TypedDict, List, Any from workos.event_objects.directory import ( @@ -23,7 +24,6 @@ DirectoryUserUpdatedEvent, ) -JsonDict = Dict[str, Any] DSYNC_EVENT_TYPES = Dict[ DirectoryUserUpdatedEvent.event : DirectoryUserUpdatedEvent, DirectoryUserCreatedEvent.event : DirectoryUserCreatedEvent, diff --git a/workos/utils/types.py b/workos/utils/types.py new file mode 100644 index 00000000..73ff6af8 --- /dev/null +++ b/workos/utils/types.py @@ -0,0 +1,3 @@ +from typing import Dict, Any + +JsonDict = Dict[str, Any] From 1565d7395f1fc0ad51f56357b3dca6e08a2033e1 Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 2 Jul 2024 14:47:10 +0200 Subject: [PATCH 10/21] save --- workos/event_objects/directory_user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workos/event_objects/directory_user.py b/workos/event_objects/directory_user.py index c7c1fb54..783f16d0 100644 --- a/workos/event_objects/directory_user.py +++ b/workos/event_objects/directory_user.py @@ -21,7 +21,7 @@ class DirectoryUserState(Enum): class DirectoryUserEvent: - def __init__(self) -> None: + def __init__(self, attributes) -> None: self.id: str = attributes["id"] self.name: str = attributes["name"] self.idp_id: str = attributes["idp_id"] From 5d88c9fd6e71af55bebc4edee174c27369b96e44 Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 2 Jul 2024 15:15:51 +0200 Subject: [PATCH 11/21] static event names --- workos/event_objects/directory.py | 8 ++++++-- workos/event_objects/directory_group.py | 12 +++++++++--- workos/event_objects/directory_user.py | 12 +++++++++--- workos/events.py | 16 ++++++++-------- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/workos/event_objects/directory.py b/workos/event_objects/directory.py index 59022725..5e86aa3c 100644 --- a/workos/event_objects/directory.py +++ b/workos/event_objects/directory.py @@ -55,16 +55,20 @@ def __init__(self, attributes) -> None: class DirectoryActivatedEvent: + event_name = "dsync.activated" + def __init__(self, attributes: JsonDict) -> None: - self.event: str = "dsync.activated" + self.event: str = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] self.data: DirectoryEvent = DirectoryEvent(attributes["data"]) class DirectoryDeletedEvent: + event_name = "dsync.deleted" + def __init__(self, attributes: JsonDict) -> None: - self.event: str = "dsync.deleted" + self.event: str = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] self.data: DirectoryEvent = DirectoryEvent(attributes["data"]) diff --git a/workos/event_objects/directory_group.py b/workos/event_objects/directory_group.py index c0d26956..c078c571 100644 --- a/workos/event_objects/directory_group.py +++ b/workos/event_objects/directory_group.py @@ -17,24 +17,30 @@ def __init__(self, attributes) -> None: class DirectoryGroupCreatedEvent: + event_name = "dsync.group.created" + def __init__(self, attributes: JsonDict) -> None: - self.event: str = "dsync.group.created" + self.event: str = attributes["event"] self.id: str = attributes["id"] self.created_at: str = attributes["created_at"] self.data: DirectoryGroupEvent = DirectoryGroupEvent(attributes["data"]) class DirectoryGroupDeletedEvent: + event_name = "dsync.group.deleted" + def __init__(self, attributes: JsonDict) -> None: - self.event: str = "dsync.group.deleted" + self.event: str = attributes["event"] self.id: str = attributes["id"] self.created_at: str = attributes["created_at"] self.data: DirectoryGroupEvent = DirectoryGroupEvent(attributes["data"]) class DirectoryGroupUpdatedEvent: + event_name = "dsync.group.updated" + def __init__(self, attributes: JsonDict) -> None: - self.event: str = "dsync.group.updated" + self.event: str = attributes["event"] self.id: str = attributes["id"] self.created_at: str = attributes["created_at"] self.data: DirectoryGroupEvent = DirectoryGroupEvent(attributes["data"]) diff --git a/workos/event_objects/directory_user.py b/workos/event_objects/directory_user.py index 783f16d0..1f6eda00 100644 --- a/workos/event_objects/directory_user.py +++ b/workos/event_objects/directory_user.py @@ -48,24 +48,30 @@ def __init__(self, attributes) -> None: class DirectoryUserCreatedEvent: + event_name = "dsync.user.created" + def __init__(self, attributes: JsonDict) -> None: self.id: str = attributes["id"] - self.event: str = "dsync.user.created" + self.event: str = attributes["event"] self.created_at: str = attributes["created_at"] self.data: DirectoryUserEvent = DirectoryUserEvent(attributes["data"]) class DirectoryUserDeletedEvent: + event_name = "dsync.user.deleted" + def __init__(self, attributes: JsonDict) -> None: self.id: str = attributes["id"] - self.event: str = "dsync.user.deleted" + self.event: str = attributes["event"] self.created_at: str = attributes["created_at"] self.data: DirectoryUserEvent = DirectoryUserEvent(attributes["data"]) class DirectoryUserUpdatedEvent: + event_name = "dsync.user.updated" + def __init__(self, attributes: JsonDict) -> None: self.id: str = attributes["id"] - self.event: str = "dsync.user.updated" + self.event: str = attributes["event"] self.created_at: str = attributes["created_at"] self.data: DirectoryUserEvent = DirectoryUserEvent(attributes["data"]) diff --git a/workos/events.py b/workos/events.py index 49ac7fa2..3979bd00 100644 --- a/workos/events.py +++ b/workos/events.py @@ -25,14 +25,14 @@ ) DSYNC_EVENT_TYPES = Dict[ - DirectoryUserUpdatedEvent.event : DirectoryUserUpdatedEvent, - DirectoryUserCreatedEvent.event : DirectoryUserCreatedEvent, - DirectoryUserDeletedEvent.event : DirectoryUserDeletedEvent, - DirectoryGroupCreatedEvent.event : DirectoryGroupCreatedEvent, - DirectoryGroupDeletedEvent.event : DirectoryGroupDeletedEvent, - DirectoryGroupUpdatedEvent.event : DirectoryGroupUpdatedEvent, - DirectoryActivatedEvent.event : DirectoryActivatedEvent, - DirectoryActivatedEvent.event : DirectoryDeletedEvent, + DirectoryUserUpdatedEvent.event_name : DirectoryUserUpdatedEvent, + DirectoryUserCreatedEvent.event_name : DirectoryUserCreatedEvent, + DirectoryUserDeletedEvent.event_name : DirectoryUserDeletedEvent, + DirectoryGroupCreatedEvent.event_name : DirectoryGroupCreatedEvent, + DirectoryGroupDeletedEvent.event_name : DirectoryGroupDeletedEvent, + DirectoryGroupUpdatedEvent.event_name : DirectoryGroupUpdatedEvent, + DirectoryActivatedEvent.event_name : DirectoryActivatedEvent, + DirectoryActivatedEvent.event_name : DirectoryDeletedEvent, ] From 3ce4d32c6ac87090fbd7be85170f83208b06e03a Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 2 Jul 2024 15:19:26 +0200 Subject: [PATCH 12/21] oops --- workos/events.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workos/events.py b/workos/events.py index 3979bd00..41ffd170 100644 --- a/workos/events.py +++ b/workos/events.py @@ -24,7 +24,7 @@ DirectoryUserUpdatedEvent, ) -DSYNC_EVENT_TYPES = Dict[ +DSYNC_EVENT_TYPES = { DirectoryUserUpdatedEvent.event_name : DirectoryUserUpdatedEvent, DirectoryUserCreatedEvent.event_name : DirectoryUserCreatedEvent, DirectoryUserDeletedEvent.event_name : DirectoryUserDeletedEvent, @@ -33,7 +33,7 @@ DirectoryGroupUpdatedEvent.event_name : DirectoryGroupUpdatedEvent, DirectoryActivatedEvent.event_name : DirectoryActivatedEvent, DirectoryActivatedEvent.event_name : DirectoryDeletedEvent, -] +} class ListDsyncEventsResponse(TypedDict): From 88f0ec11f774e97bfda0971abdc41e76db1bd1e6 Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 2 Jul 2024 15:21:17 +0200 Subject: [PATCH 13/21] fmt --- workos/events.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/workos/events.py b/workos/events.py index 41ffd170..c3399112 100644 --- a/workos/events.py +++ b/workos/events.py @@ -25,14 +25,14 @@ ) DSYNC_EVENT_TYPES = { - DirectoryUserUpdatedEvent.event_name : DirectoryUserUpdatedEvent, - DirectoryUserCreatedEvent.event_name : DirectoryUserCreatedEvent, - DirectoryUserDeletedEvent.event_name : DirectoryUserDeletedEvent, - DirectoryGroupCreatedEvent.event_name : DirectoryGroupCreatedEvent, - DirectoryGroupDeletedEvent.event_name : DirectoryGroupDeletedEvent, - DirectoryGroupUpdatedEvent.event_name : DirectoryGroupUpdatedEvent, - DirectoryActivatedEvent.event_name : DirectoryActivatedEvent, - DirectoryActivatedEvent.event_name : DirectoryDeletedEvent, + DirectoryUserUpdatedEvent.event_name: DirectoryUserUpdatedEvent, + DirectoryUserCreatedEvent.event_name: DirectoryUserCreatedEvent, + DirectoryUserDeletedEvent.event_name: DirectoryUserDeletedEvent, + DirectoryGroupCreatedEvent.event_name: DirectoryGroupCreatedEvent, + DirectoryGroupDeletedEvent.event_name: DirectoryGroupDeletedEvent, + DirectoryGroupUpdatedEvent.event_name: DirectoryGroupUpdatedEvent, + DirectoryActivatedEvent.event_name: DirectoryActivatedEvent, + DirectoryActivatedEvent.event_name: DirectoryDeletedEvent, } From b5c2a6b74c4762a9c33cfed2ca184b818dc66a8d Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 2 Jul 2024 15:24:07 +0200 Subject: [PATCH 14/21] change typing for py 3.8to10 --- workos/events.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/workos/events.py b/workos/events.py index c3399112..3c6fda72 100644 --- a/workos/events.py +++ b/workos/events.py @@ -8,7 +8,7 @@ from workos.utils.validation import EVENTS_MODULE, validate_settings from workos.utils.types import JsonDict from workos.resources.list import WorkOSListResource -from typing import Optional, Dict, TypedDict, List, Any +from typing import Optional, TypedDict, List, Union from workos.event_objects.directory import ( DirectoryActivatedEvent, DirectoryDeletedEvent, @@ -24,7 +24,7 @@ DirectoryUserUpdatedEvent, ) -DSYNC_EVENT_TYPES = { +DSYNC_EVENT_TO_OBJECT = { DirectoryUserUpdatedEvent.event_name: DirectoryUserUpdatedEvent, DirectoryUserCreatedEvent.event_name: DirectoryUserCreatedEvent, DirectoryUserDeletedEvent.event_name: DirectoryUserDeletedEvent, @@ -34,11 +34,21 @@ DirectoryActivatedEvent.event_name: DirectoryActivatedEvent, DirectoryActivatedEvent.event_name: DirectoryDeletedEvent, } +DSYNC_EVENT_TYPES = Union[ + DirectoryActivatedEvent, + DirectoryDeletedEvent, + DirectoryUserCreatedEvent, + DirectoryUserDeletedEvent, + DirectoryUserUpdatedEvent, + DirectoryGroupCreatedEvent, + DirectoryGroupDeletedEvent, + DirectoryGroupUpdatedEvent, +] class ListDsyncEventsResponse(TypedDict): object: str - data: List[DSYNC_EVENT_TYPES.values()] + data: List[DSYNC_EVENT_TYPES] metadata: JsonDict From bd9b1f41fbc04d0a44750541ad74f77f5762b3e9 Mon Sep 17 00:00:00 2001 From: mattgd Date: Tue, 2 Jul 2024 16:18:57 -0400 Subject: [PATCH 15/21] Updates. --- tests/test_events.py | 31 +++++++++++++++ .../fixtures/mock_directory_sync_event.py | 39 +++++++++++++++++++ tests/utils/fixtures/mock_event.py | 7 +++- workos/event_objects/directory.py | 25 +++++++++--- workos/event_objects/directory_group.py | 4 +- workos/event_objects/directory_user.py | 12 +++--- workos/events.py | 18 ++++++--- 7 files changed, 114 insertions(+), 22 deletions(-) create mode 100644 tests/utils/fixtures/mock_directory_sync_event.py diff --git a/tests/test_events.py b/tests/test_events.py index 8805517d..50d909df 100644 --- a/tests/test_events.py +++ b/tests/test_events.py @@ -1,6 +1,7 @@ import pytest from workos.events import Events from tests.utils.fixtures.mock_event import MockEvent +from tests.utils.fixtures.mock_directory_sync_event import MockDirectorySyncEvent class TestEvents(object): @@ -8,6 +9,27 @@ class TestEvents(object): def setup(self, set_api_key, set_client_id): self.events = Events() + @pytest.fixture + def mock_directory_sync_events(self): + events = [MockDirectorySyncEvent(id=str(i)).to_dict() for i in range(100)] + + return { + "data": events, + "list_metadata": {"after": None}, + "metadata": { + "params": { + "events": None, + "limit": None, + "organization_id": None, + "after": None, + "range_start": None, + "range_end": None, + "default_limit": True, + }, + "method": Events.list_directory_sync_events, + }, + } + @pytest.fixture def mock_events(self): events = [MockEvent(id=str(i)).to_dict() for i in range(100)] @@ -29,6 +51,15 @@ def mock_events(self): }, } + def test_list_directory_sync_events( + self, mock_directory_sync_events, mock_request_method + ): + mock_request_method("get", mock_directory_sync_events, 200) + + events = self.events.list_directory_sync_events() + + assert events == mock_directory_sync_events + def test_list_events(self, mock_events, mock_request_method): mock_request_method("get", mock_events, 200) diff --git a/tests/utils/fixtures/mock_directory_sync_event.py b/tests/utils/fixtures/mock_directory_sync_event.py new file mode 100644 index 00000000..93070829 --- /dev/null +++ b/tests/utils/fixtures/mock_directory_sync_event.py @@ -0,0 +1,39 @@ +import datetime +from workos.resources.base import WorkOSBaseResource +from workos.event_objects.directory_user import DirectoryUserEvent + + +class MockDirectorySyncEvent(WorkOSBaseResource): + def __init__(self, id): + self.object = "event" + self.id = id + self.event = "dsync.user.created" + self.data = { + "id": "directory_user_01E1X1B89NH8Z3SDFJR4H7RGX7", + "directory_id": "directory_01ECAZ4NV9QMV47GW873HDCX74", + "organization_id": "org_01EZTR6WYX1A0DSE2CYMGXQ24Y", + "idp_id": "8931", + "emails": [ + {"primary": True, "type": "work", "value": "lela.block@example.com"} + ], + "first_name": "Lela", + "last_name": "Block", + "job_title": "Software Engineer", + "username": "lela.block@example.com", + "state": "active", + "created_at": "2021-06-25T19:07:33.155Z", + "updated_at": "2021-06-25T19:07:33.155Z", + "custom_attributes": {"department": "Engineering"}, + "raw_attributes": {}, + "object": "directory_user", + } + + self.created_at = datetime.datetime.now() + + OBJECT_FIELDS = [ + "object", + "id", + "event", + "data", + "created_at", + ] diff --git a/tests/utils/fixtures/mock_event.py b/tests/utils/fixtures/mock_event.py index 0acdda4d..a7a756e3 100644 --- a/tests/utils/fixtures/mock_event.py +++ b/tests/utils/fixtures/mock_event.py @@ -6,8 +6,11 @@ class MockEvent(WorkOSBaseResource): def __init__(self, id): self.object = "event" self.id = id - self.event = "dsync.user.created" - self.data = {"id": "event_01234ABCD", "organization_id": "org_1234"} + self.event = "user.created" + self.data = { + "id": "user_01E4ZCR3C5A4QZ2Z2JQXGKZJ9E", + "email": "todd@example.com", + } self.created_at = datetime.datetime.now() OBJECT_FIELDS = [ diff --git a/workos/event_objects/directory.py b/workos/event_objects/directory.py index 5e86aa3c..3ed1993d 100644 --- a/workos/event_objects/directory.py +++ b/workos/event_objects/directory.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, Literal from enum import Enum from workos.utils.types import JsonDict @@ -12,7 +12,6 @@ class DirectoryType(Enum): FOURTH_HR = "fourth hr" GENERIC_SCIM_v2 = "generic scim v2.0" GOOGLE = "gsuite directory" - GUSTO = "gusto" HIBOB = "hibob" JUMPCLOUD_SCIM_v2 = "jump cloud scim v2.0" OKTA_SCIM_v2 = "okta scim v2.0" @@ -37,7 +36,7 @@ def __init__(self, attributes: JsonDict) -> None: self.domain: str = attributes["domain"] -class DirectoryEvent: +class DirectoryEventWithLegacyFields: def __init__(self, attributes) -> None: self.id: str = attributes["id"] self.name: str = attributes["name"] @@ -50,8 +49,19 @@ def __init__(self, attributes) -> None: self.created_at: str = attributes["created_at"] self.updated_at: str = attributes["updated_at"] self.external_key: str = attributes["external_key"] - # always 'directory' for this event - self.object: str = attributes["object"] + self.object: Literal["directory"] = attributes["object"] + + +class DirectoryEvent: + def __init__(self, attributes) -> None: + self.id: str = attributes["id"] + self.name: str = attributes["name"] + self.type: DirectoryType = DirectoryType(attributes["type"]) + self.state: DirectoryState = DirectoryState.ACTIVE + self.organization_id: str = attributes["organization_id"] + self.created_at: str = attributes["created_at"] + self.updated_at: str = attributes["updated_at"] + self.object: Literal["directory"] = attributes["object"] class DirectoryActivatedEvent: @@ -61,7 +71,9 @@ def __init__(self, attributes: JsonDict) -> None: self.event: str = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] - self.data: DirectoryEvent = DirectoryEvent(attributes["data"]) + self.data: DirectoryEventWithLegacyFields = DirectoryEventWithLegacyFields( + attributes["data"] + ) class DirectoryDeletedEvent: @@ -71,4 +83,5 @@ def __init__(self, attributes: JsonDict) -> None: self.event: str = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] + self.state: DirectoryState = DirectoryState.DELETING self.data: DirectoryEvent = DirectoryEvent(attributes["data"]) diff --git a/workos/event_objects/directory_group.py b/workos/event_objects/directory_group.py index c078c571..488f3970 100644 --- a/workos/event_objects/directory_group.py +++ b/workos/event_objects/directory_group.py @@ -1,3 +1,4 @@ +from typing import Literal from workos.utils.types import JsonDict @@ -12,8 +13,7 @@ def __init__(self, attributes) -> None: self.updated_at: str = attributes["updated_at"] self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) self.previous_attributes: JsonDict = attributes.get("previous_attributes", {}) - # always 'directory_group' for this event - self.object: str = attributes["object"] + self.object: Literal["directory_group"] = attributes["object"] class DirectoryGroupCreatedEvent: diff --git a/workos/event_objects/directory_user.py b/workos/event_objects/directory_user.py index 1f6eda00..fe6c74f5 100644 --- a/workos/event_objects/directory_user.py +++ b/workos/event_objects/directory_user.py @@ -1,4 +1,4 @@ -from typing import Optional, List +from typing import Optional, List, Literal from enum import Enum from workos.utils.types import JsonDict @@ -21,18 +21,19 @@ class DirectoryUserState(Enum): class DirectoryUserEvent: - def __init__(self, attributes) -> None: + def __init__(self, attributes: JsonDict) -> None: self.id: str = attributes["id"] - self.name: str = attributes["name"] self.idp_id: str = attributes["idp_id"] self.directory_id: str = attributes["directory_id"] self.organization_id: str = attributes["organization_id"] self.first_name: Optional[str] = attributes.get("first_name") self.last_name: Optional[str] = attributes.get("last_name") self.job_title: Optional[str] = attributes.get("job_title") + self.emails: List[DirectoryUserEmail] = [] for email in attributes.get("emails"): - self.emails.push(DirectoryUserEmail(email)) + self.emails.append(DirectoryUserEmail(email)) + self.username: Optional[str] = attributes.get("username") self.state: DirectoryUserState = DirectoryUserState(attributes["state"]) self.custom_attributes: JsonDict = attributes.get("custom_attributes", {}) @@ -43,8 +44,7 @@ def __init__(self, attributes) -> None: DirectoryUserRole(attributes["role"]) if attributes.get("role") else None ) self.previous_attributes: JsonDict = attributes.get("previous_attributes", {}) - # always 'directory_user' for this event - self.object: str = attributes["object"] + self.object: Literal["directory_user"] = attributes["object"] class DirectoryUserCreatedEvent: diff --git a/workos/events.py b/workos/events.py index 3c6fda72..0c700e1b 100644 --- a/workos/events.py +++ b/workos/events.py @@ -1,4 +1,3 @@ -from warnings import warn import workos from workos.utils.request import ( RequestHelper, @@ -68,7 +67,7 @@ def request_helper(self): self._request_helper = RequestHelper() return self._request_helper - def list_dsync_events( + def list_directory_sync_events( self, limit: Optional[int] = None, organization_id: Optional[str] = None, @@ -81,7 +80,7 @@ def list_dsync_events( default_limit = True params = { - "events": DSYNC_EVENT_TYPES.keys(), + "events": list(DSYNC_EVENT_TO_OBJECT.keys()), "limit": limit, "after": after, "organization_id": organization_id, @@ -96,15 +95,22 @@ def list_dsync_events( token=workos.api_key, ) - response = { - "object": "list", + response["metadata"] = { "params": params, + "method": Events.list_directory_sync_events, } + if "default_limit" in locals(): + if "metadata" in response and "params" in response["metadata"]: + response["metadata"]["params"]["default_limit"] = default_limit + else: + response["metadata"] = {"params": {"default_limit": default_limit}} + data = [] for list_data in response["data"]: - data.push(DSYNC_EVENT_TYPES[list_data["event"]](list_data)) + data.append(DSYNC_EVENT_TO_OBJECT[list_data["event"]](list_data)) response["data"] = data + return response def list_events( From 6c14e8af801ce1586af4e5b9089878d06a78d985 Mon Sep 17 00:00:00 2001 From: mattgd Date: Wed, 3 Jul 2024 10:02:15 -0400 Subject: [PATCH 16/21] Improve directory API typing. --- workos/directory_sync.py | 52 ++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/workos/directory_sync.py b/workos/directory_sync.py index 2a1dd43a..c56157ef 100644 --- a/workos/directory_sync.py +++ b/workos/directory_sync.py @@ -107,13 +107,13 @@ def list_users( def list_users_v2( self, - directory=None, - group=None, - limit=None, - before=None, - after=None, - order=None, - ): + directory: str = None, + group: str = None, + limit: int = None, + before: str = None, + after: str = None, + order: Order = None, + ) -> WorkOSListResource: """Gets a list of provisioned Users for a Directory. Note, either 'directory' or 'group' must be provided. @@ -247,13 +247,13 @@ def list_groups( def list_groups_v2( self, - directory=None, - user=None, - limit=None, - before=None, - after=None, - order=None, - ): + directory: str = None, + user: str = None, + limit: int = None, + before: str = None, + after: str = None, + order: Order = None, + ) -> WorkOSListResource: """Gets a list of provisioned Groups for a Directory . Note, either 'directory' or 'user' must be provided. @@ -312,7 +312,7 @@ def list_groups_v2( return self.construct_from_response(response) - def get_user(self, user): + def get_user(self, user: str) -> WorkOSDirectoryUser: """Gets details for a single provisioned Directory User. Args: @@ -329,7 +329,7 @@ def get_user(self, user): return WorkOSDirectoryUser.construct_from_response(response).to_dict() - def get_group(self, group): + def get_group(self, group: str) -> WorkOSDirectoryGroup: """Gets details for a single provisioned Directory Group. Args: @@ -439,19 +439,19 @@ def list_directories( def list_directories_v2( self, - domain=None, - search=None, - limit=None, - before=None, - after=None, - organization=None, - order=None, + domain: str = None, + search: str = None, + limit: int = None, + before: str = None, + after: str = None, + organization: str = None, + order: Order = None, ): """Gets details for existing Directories. Args: domain (str): Domain of a Directory. (Optional) - organization: ID of an Organization (Optional) + organization (str): ID of an Organization (Optional) search (str): Searchable text for a Directory. (Optional) limit (int): Maximum number of records to return. (Optional) before (str): Pagination cursor to receive records before a provided Directory ID. (Optional) @@ -505,7 +505,7 @@ def list_directories_v2( return self.construct_from_response(response) - def get_directory(self, directory): + def get_directory(self, directory: str) -> WorkOSDirectory: """Gets details for a single Directory Args: @@ -524,7 +524,7 @@ def get_directory(self, directory): return WorkOSDirectory.construct_from_response(response).to_dict() - def delete_directory(self, directory): + def delete_directory(self, directory: str) -> dict: """Delete one existing Directory. Args: From bd8020ccd4cf39706439e9bdad00ce7deafc1357 Mon Sep 17 00:00:00 2001 From: mattgd Date: Wed, 3 Jul 2024 13:26:41 -0400 Subject: [PATCH 17/21] Update typing. --- workos/directory_sync.py | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/workos/directory_sync.py b/workos/directory_sync.py index c56157ef..43f8990f 100644 --- a/workos/directory_sync.py +++ b/workos/directory_sync.py @@ -1,4 +1,6 @@ from warnings import warn +from typing import Optional + import workos from workos.utils.pagination_order import Order from workos.utils.request import ( @@ -107,12 +109,12 @@ def list_users( def list_users_v2( self, - directory: str = None, - group: str = None, - limit: int = None, - before: str = None, - after: str = None, - order: Order = None, + directory: Optional[str] = None, + group: Optional[str] = None, + limit: Optional[int] = None, + before: Optional[str] = None, + after: Optional[str] = None, + order: Optional[Order] = None, ) -> WorkOSListResource: """Gets a list of provisioned Users for a Directory. @@ -247,12 +249,12 @@ def list_groups( def list_groups_v2( self, - directory: str = None, - user: str = None, - limit: int = None, - before: str = None, - after: str = None, - order: Order = None, + directory: Optional[str] = None, + user: Optional[str] = None, + limit: Optional[int] = None, + before: Optional[str] = None, + after: Optional[str] = None, + order: Optional[Order] = None, ) -> WorkOSListResource: """Gets a list of provisioned Groups for a Directory . @@ -439,13 +441,13 @@ def list_directories( def list_directories_v2( self, - domain: str = None, - search: str = None, - limit: int = None, - before: str = None, - after: str = None, - organization: str = None, - order: Order = None, + domain: Optional[str] = None, + search: Optional[str] = None, + limit: Optional[int] = None, + before: Optional[str] = None, + after: Optional[str] = None, + organization: Optional[str] = None, + order: Optional[Order] = None, ): """Gets details for existing Directories. From 3fea3d129f7bab09aa1348f38376c417add55e24 Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Mon, 8 Jul 2024 11:40:40 +0100 Subject: [PATCH 18/21] dupe method and typing --- workos/directory_sync.py | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/workos/directory_sync.py b/workos/directory_sync.py index 43f8990f..32098b0a 100644 --- a/workos/directory_sync.py +++ b/workos/directory_sync.py @@ -8,6 +8,7 @@ REQUEST_METHOD_DELETE, REQUEST_METHOD_GET, ) +from workos.utils.types import JsonDict from workos.utils.validation import DIRECTORY_SYNC_MODULE, validate_settings from workos.resources.directory_sync import ( @@ -348,7 +349,7 @@ def get_group(self, group: str) -> WorkOSDirectoryGroup: return WorkOSDirectoryGroup.construct_from_response(response).to_dict() - def get_directory(self, directory): + def get_directory(self, directory: str) -> WorkOSDirectory: """Gets details for a single Directory Args: @@ -507,26 +508,7 @@ def list_directories_v2( return self.construct_from_response(response) - def get_directory(self, directory: str) -> WorkOSDirectory: - """Gets details for a single Directory - - Args: - directory (str): Directory unique identifier. - - Returns: - dict: Directory response from WorkOS - - """ - - response = self.request_helper.request( - "directories/{directory}".format(directory=directory), - method=REQUEST_METHOD_GET, - token=workos.api_key, - ) - - return WorkOSDirectory.construct_from_response(response).to_dict() - - def delete_directory(self, directory: str) -> dict: + def delete_directory(self, directory: str) -> JsonDict: """Delete one existing Directory. Args: From 6025c771e169f96cdf9c6ba789a49f71813dd0d7 Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Mon, 8 Jul 2024 12:48:27 +0100 Subject: [PATCH 19/21] remove separate dsync event list --- workos/events.py | 67 ++++++++++-------------------------------------- 1 file changed, 14 insertions(+), 53 deletions(-) diff --git a/workos/events.py b/workos/events.py index 0c700e1b..61e7fe39 100644 --- a/workos/events.py +++ b/workos/events.py @@ -23,7 +23,7 @@ DirectoryUserUpdatedEvent, ) -DSYNC_EVENT_TO_OBJECT = { +EVENT_TO_OBJECT = { DirectoryUserUpdatedEvent.event_name: DirectoryUserUpdatedEvent, DirectoryUserCreatedEvent.event_name: DirectoryUserCreatedEvent, DirectoryUserDeletedEvent.event_name: DirectoryUserDeletedEvent, @@ -33,7 +33,7 @@ DirectoryActivatedEvent.event_name: DirectoryActivatedEvent, DirectoryActivatedEvent.event_name: DirectoryDeletedEvent, } -DSYNC_EVENT_TYPES = Union[ +EVENT_TYPES = Union[ DirectoryActivatedEvent, DirectoryDeletedEvent, DirectoryUserCreatedEvent, @@ -45,9 +45,9 @@ ] -class ListDsyncEventsResponse(TypedDict): +class ListEventsResponse(TypedDict): object: str - data: List[DSYNC_EVENT_TYPES] + data: List[EVENT_TYPES] metadata: JsonDict @@ -67,61 +67,15 @@ def request_helper(self): self._request_helper = RequestHelper() return self._request_helper - def list_directory_sync_events( + def list_events( self, + events: Optional[List[EVENT_TYPES]]=None, limit: Optional[int] = None, organization_id: Optional[str] = None, after: Optional[str] = None, range_start: Optional[str] = None, range_end: Optional[str] = None, - ) -> ListDsyncEventsResponse: - if limit is None: - limit = RESPONSE_LIMIT - default_limit = True - - params = { - "events": list(DSYNC_EVENT_TO_OBJECT.keys()), - "limit": limit, - "after": after, - "organization_id": organization_id, - "range_start": range_start, - "range_end": range_end, - } - - response = self.request_helper.request( - "events", - method=REQUEST_METHOD_GET, - params=params, - token=workos.api_key, - ) - - response["metadata"] = { - "params": params, - "method": Events.list_directory_sync_events, - } - - if "default_limit" in locals(): - if "metadata" in response and "params" in response["metadata"]: - response["metadata"]["params"]["default_limit"] = default_limit - else: - response["metadata"] = {"params": {"default_limit": default_limit}} - - data = [] - for list_data in response["data"]: - data.append(DSYNC_EVENT_TO_OBJECT[list_data["event"]](list_data)) - response["data"] = data - - return response - - def list_events( - self, - events=None, - limit=None, - organization_id=None, - after=None, - range_start=None, - range_end=None, - ): + ) -> ListEventsResponse: """Gets a list of Events . Kwargs: events (list): Filter to only return events of particular types. (Optional) @@ -167,4 +121,11 @@ def list_events( "method": Events.list_events, } + data = [] + for list_data in response["data"]: + if list_data["event"] in EVENT_TO_OBJECT.keys(): + data.append(EVENT_TO_OBJECT[list_data["event"]](list_data)) + + response["data"] = data + return response From e8bb412e046a70628f9930972ddb99f97f0b256d Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 9 Jul 2024 13:54:46 -0400 Subject: [PATCH 20/21] auth and connection event types --- workos/event_objects/authentication.py | 171 +++++++++++++++++++++++++ workos/event_objects/connection.py | 95 ++++++++++++++ 2 files changed, 266 insertions(+) create mode 100644 workos/event_objects/authentication.py create mode 100644 workos/event_objects/connection.py diff --git a/workos/event_objects/authentication.py b/workos/event_objects/authentication.py new file mode 100644 index 00000000..5fa0a954 --- /dev/null +++ b/workos/event_objects/authentication.py @@ -0,0 +1,171 @@ +from typing import List, Literal, NamedTuple +from enum import Enum +from workos.utils.types import JsonDict + + +class AuthenticationType(Enum): + EMAIL_VERIFICATION = "email_verification" + MAGIC_AUTH = "magic_auth" + MFA = "mfa" + OAUTH = "oauth" + PASSWORD = "password" + SSO = "sso" + + +class Error(NamedTuple): + code: str + message: str + + +class AuthenticationFailedFields: + def __init__(self, attributes: JsonDict) -> None: + self.type: AuthenticationType = AuthenticationType(attributes["type"]) + self.status: str = attributes["status"] + self.user_id: str = attributes["user_id"] + self.email: str = attributes["email"] + self.ip_address: str = attributes["ip_address"] + self.user_agent: str = attributes["user_agent"] + self.error: Error = Error(code=attributes["error"]["code"], message=attributes["error"]["message"]) + +class AuthenticationSucceededFields: + def __init__(self, attributes: JsonDict) -> None: + self.type: AuthenticationType = AuthenticationType(attributes["type"]) + self.status: str = attributes["status"] + self.user_id: str = attributes["user_id"] + self.email: str = attributes["email"] + self.ip_address: str = attributes["ip_address"] + self.user_agent: str = attributes["user_agent"] + +class AuthenticationEmailVerificationFailedEvent: + event_name: str = "authentication.email_verification_failed" + + def __init__(self, attributes: JsonDict) -> None: + self.event: Literal["authentication.email_verification_failed"] = attributes['event'] + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: AuthenticationFailedFields = AuthenticationFailedFields( + attributes["data"] + ) + +class AuthenticationEmailVerificationSucceededEvent: + event_name: str = "authentication.email_verification_succeeded" + + def __init__(self, attributes: JsonDict) -> None: + self.event: Literal["authentication.email_verification_succeeded"] = attributes['event'] + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: AuthenticationSucceededFields = AuthenticationSucceededFields( + attributes["data"] + ) + +class AuthenticationMagicAuthFailedEvent: + event_name: str = "authentication.magic_auth_failed" + + def __init__(self, attributes: JsonDict) -> None: + self.event: Literal["authentication.magic_auth_failed"] = attributes['event'] + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: AuthenticationFailedFields = AuthenticationFailedFields( + attributes["data"] + ) + +class AuthenticationMagicAuthSucceededEvent: + event_name: str = "authentication.magic_auth_succeeded" + + def __init__(self, attributes: JsonDict) -> None: + self.event: Literal["authentication.magic_auth_succeeded"] = attributes['event'] + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: AuthenticationSucceededFields = AuthenticationSucceededFields( + attributes["data"] + ) + +class AuthenticationMFAFailedEvent: + event_name: str = "authentication.mfa_failed" + + def __init__(self, attributes: JsonDict) -> None: + self.event: Literal["authentication.mfa_failed"] = attributes['event'] + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: AuthenticationFailedFields = AuthenticationFailedFields( + attributes["data"] + ) + +class AuthenticationMFASucceededEvent: + event_name: str = "authentication.mfa_succeeded" + + def __init__(self, attributes: JsonDict) -> None: + self.event: Literal["authentication.mfa_succeeded"] = attributes['event'] + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: AuthenticationSucceededFields = AuthenticationSucceededFields( + attributes["data"] + ) + +class AuthenticationOAuthFailedEvent: + event_name: str = "authentication.oauth_failed" + + def __init__(self, attributes: JsonDict) -> None: + self.event: Literal["authentication.oauth_failed"] = attributes['event'] + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: AuthenticationFailedFields = AuthenticationFailedFields( + attributes["data"] + ) + +class AuthenticationOAuthSucceededEvent: + event_name: str = "authentication.oauth_succeeded" + + def __init__(self, attributes: JsonDict) -> None: + self.event: Literal["authentication.oauth_succeeded"] = attributes['event'] + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: AuthenticationSucceededFields = AuthenticationSucceededFields( + attributes["data"] + ) + +class AuthenticationPasswordFailedEvent: + event_name: str = "authentication.password_failed" + + def __init__(self, attributes: JsonDict) -> None: + self.event: Literal["authentication.password_failed"] = attributes['event'] + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: AuthenticationFailedFields = AuthenticationFailedFields( + attributes["data"] + ) + +class AuthenticationPasswordSucceededEvent: + event_name: str = "authentication.password_succeeded" + + def __init__(self, attributes: JsonDict) -> None: + self.event: Literal["authentication.password_succeeded"] = attributes['event'] + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: AuthenticationSucceededFields = AuthenticationSucceededFields( + attributes["data"] + ) + + +class AuthenticationSSOFailedEvent: + event_name: str = "authentication.sso_failed" + + def __init__(self, attributes: JsonDict) -> None: + self.event: Literal["authentication.sso_failed"] = attributes['event'] + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: AuthenticationFailedFields = AuthenticationFailedFields( + attributes["data"] + ) + +class AuthenticationSSOSucceededEvent: + event_name: str = "authentication.sso_succeeded" + + def __init__(self, attributes: JsonDict) -> None: + self.event: Literal["authentication.sso_succeeded"] = attributes['event'] + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: AuthenticationSucceededFields = AuthenticationSucceededFields( + attributes["data"] + ) + diff --git a/workos/event_objects/connection.py b/workos/event_objects/connection.py new file mode 100644 index 00000000..405959c4 --- /dev/null +++ b/workos/event_objects/connection.py @@ -0,0 +1,95 @@ +from typing import List, Literal, NamedTuple +from enum import Enum +from workos.utils.types import JsonDict + +class ConnectionState(Enum): + INACTIVE = "inactive" + ACTIVE = "active" + +class ConnectionType(Enum): + ADFS_SAML = 'ADFSSAML' + ADP_OIDC = 'AdpOidc' + AUTH0_SAML = 'Auth0SAML' + AZURE_SAML = 'AzureSAML' + CAS_SAML = 'CasSAML' + CLASS_LINK_SAML = 'ClassLinkSAML' + CLOUDFLARE_SAML = 'CloudflareSAML' + CYBER_ARK_SAML = 'CyberArkSAML' + DUO_SAML = 'DuoSAML' + GENERIC_OIDC = 'GenericOIDC' + GENERIC_SAML = 'GenericSAML' + GOOGLE_OAUTH = 'GoogleOAuth' + GOOGLE_SAML = 'GoogleSAML' + JUMP_CLOUD_SAML = 'JumpCloudSAML' + KEYCLOAK_SAML = 'KeycloakSAML' + LAST_PASS_SAML = 'LastPassSAML' + LOGIN_GOV_OIDC = 'LoginGovOidc' + MAGIC_LINK = 'MagicLink' + MICROSOFT_OAUTH = 'MicrosoftOAuth' + MINI_ORANGE_SAML = 'MiniOrangeSAML' + NET_IQ_SAML = 'NetIqSAML' + OKTA_SAML = 'OktaSAML' + ONE_LOGIN_SAML ='OneLoginSAML' + ORACLE_SAML = 'OracleSAML' + PING_FEDERATE_SAML = 'PingFederateSAML' + PING_ONE_SAML = 'PingOneSAML' + RIPPLING_SAML = 'RipplingSAML' + SALESFORCE_SAML = 'SalesforceSAML' + SHIBBOLETH_GENERIC_SAML = 'ShibbolethGenericSAML' + SHIBBOLETH_SAML = 'ShibbolethSAML' + SIMPLE_SAML_PHP_SAML = 'SimpleSamlPhpSAML' + VM_WARE_SAML = 'VMwareSAML' + +class Domain: + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes["id"] + self.object: Literal["connection_domain"] = attributes["object"] + self.domain: str = attributes["domain"] + + +class ConnectionEvent: + def __init__(self, attributes: JsonDict) -> None: + self.object: Literal["connection"] = attributes["object"] + self.id: str = attributes["id"] + self.organization_id: str = attributes["organization_id"] + self.state: str = ConnectionState(attributes["state"]) + self.connection_type: str = ConnectionType(attributes["connection_type"]) + self.name: str = attributes["name"] + self.created_at: str = attributes["created_at"] + self.updated_at: str = attributes["updated_at"] + self.domains = [] + for domain in attributes["domains"]: + self.domains.push(Domain(attributes=domain)) + +class ConnectionActivatedEvent: + event_name = "connection.activated" + + def __init__(self, attributes: JsonDict) -> None: + self.event: Literal['connection.activated'] = attributes["event"] + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: ConnectionEvent = ConnectionEvent( + attributes["data"] + ) + +class ConnectionDeactivatedEvent: + event_name = "connection.deactivated" + + def __init__(self, attributes: JsonDict) -> None: + self.event: Literal['connection.deactivated'] = attributes["event"] + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: ConnectionEvent = ConnectionEvent( + attributes["data"] + ) + +class ConnectionDeactivatedEvent: + event_name = "connection.deleted" + + def __init__(self, attributes: JsonDict) -> None: + self.event: Literal['connection.deleted'] = attributes["event"] + self.id: str = attributes["id"] + self.created_at = attributes["created_at"] + self.data: ConnectionEvent = ConnectionEvent( + attributes["data"] + ) From 7d8228877dcb9e21741844cd56c5fbb7c3d1b0bd Mon Sep 17 00:00:00 2001 From: Ameesha Isaac Date: Tue, 9 Jul 2024 13:58:08 -0400 Subject: [PATCH 21/21] fmt --- workos/event_objects/authentication.py | 49 ++++++++---- workos/event_objects/connection.py | 102 ++++++++++++------------- workos/events.py | 4 +- 3 files changed, 86 insertions(+), 69 deletions(-) diff --git a/workos/event_objects/authentication.py b/workos/event_objects/authentication.py index 5fa0a954..211b6629 100644 --- a/workos/event_objects/authentication.py +++ b/workos/event_objects/authentication.py @@ -13,8 +13,8 @@ class AuthenticationType(Enum): class Error(NamedTuple): - code: str - message: str + code: str + message: str class AuthenticationFailedFields: @@ -25,7 +25,10 @@ def __init__(self, attributes: JsonDict) -> None: self.email: str = attributes["email"] self.ip_address: str = attributes["ip_address"] self.user_agent: str = attributes["user_agent"] - self.error: Error = Error(code=attributes["error"]["code"], message=attributes["error"]["message"]) + self.error: Error = Error( + code=attributes["error"]["code"], message=attributes["error"]["message"] + ) + class AuthenticationSucceededFields: def __init__(self, attributes: JsonDict) -> None: @@ -36,110 +39,124 @@ def __init__(self, attributes: JsonDict) -> None: self.ip_address: str = attributes["ip_address"] self.user_agent: str = attributes["user_agent"] + class AuthenticationEmailVerificationFailedEvent: event_name: str = "authentication.email_verification_failed" def __init__(self, attributes: JsonDict) -> None: - self.event: Literal["authentication.email_verification_failed"] = attributes['event'] + self.event: Literal["authentication.email_verification_failed"] = attributes[ + "event" + ] self.id: str = attributes["id"] self.created_at = attributes["created_at"] self.data: AuthenticationFailedFields = AuthenticationFailedFields( attributes["data"] ) + class AuthenticationEmailVerificationSucceededEvent: event_name: str = "authentication.email_verification_succeeded" def __init__(self, attributes: JsonDict) -> None: - self.event: Literal["authentication.email_verification_succeeded"] = attributes['event'] + self.event: Literal["authentication.email_verification_succeeded"] = attributes[ + "event" + ] self.id: str = attributes["id"] self.created_at = attributes["created_at"] self.data: AuthenticationSucceededFields = AuthenticationSucceededFields( attributes["data"] ) + class AuthenticationMagicAuthFailedEvent: event_name: str = "authentication.magic_auth_failed" def __init__(self, attributes: JsonDict) -> None: - self.event: Literal["authentication.magic_auth_failed"] = attributes['event'] + self.event: Literal["authentication.magic_auth_failed"] = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] self.data: AuthenticationFailedFields = AuthenticationFailedFields( attributes["data"] ) + class AuthenticationMagicAuthSucceededEvent: event_name: str = "authentication.magic_auth_succeeded" def __init__(self, attributes: JsonDict) -> None: - self.event: Literal["authentication.magic_auth_succeeded"] = attributes['event'] + self.event: Literal["authentication.magic_auth_succeeded"] = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] self.data: AuthenticationSucceededFields = AuthenticationSucceededFields( attributes["data"] ) + class AuthenticationMFAFailedEvent: event_name: str = "authentication.mfa_failed" def __init__(self, attributes: JsonDict) -> None: - self.event: Literal["authentication.mfa_failed"] = attributes['event'] + self.event: Literal["authentication.mfa_failed"] = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] self.data: AuthenticationFailedFields = AuthenticationFailedFields( attributes["data"] ) + class AuthenticationMFASucceededEvent: event_name: str = "authentication.mfa_succeeded" def __init__(self, attributes: JsonDict) -> None: - self.event: Literal["authentication.mfa_succeeded"] = attributes['event'] + self.event: Literal["authentication.mfa_succeeded"] = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] self.data: AuthenticationSucceededFields = AuthenticationSucceededFields( attributes["data"] ) + class AuthenticationOAuthFailedEvent: event_name: str = "authentication.oauth_failed" def __init__(self, attributes: JsonDict) -> None: - self.event: Literal["authentication.oauth_failed"] = attributes['event'] + self.event: Literal["authentication.oauth_failed"] = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] self.data: AuthenticationFailedFields = AuthenticationFailedFields( attributes["data"] ) + class AuthenticationOAuthSucceededEvent: event_name: str = "authentication.oauth_succeeded" def __init__(self, attributes: JsonDict) -> None: - self.event: Literal["authentication.oauth_succeeded"] = attributes['event'] + self.event: Literal["authentication.oauth_succeeded"] = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] self.data: AuthenticationSucceededFields = AuthenticationSucceededFields( attributes["data"] ) + class AuthenticationPasswordFailedEvent: event_name: str = "authentication.password_failed" def __init__(self, attributes: JsonDict) -> None: - self.event: Literal["authentication.password_failed"] = attributes['event'] + self.event: Literal["authentication.password_failed"] = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] self.data: AuthenticationFailedFields = AuthenticationFailedFields( attributes["data"] ) + class AuthenticationPasswordSucceededEvent: event_name: str = "authentication.password_succeeded" def __init__(self, attributes: JsonDict) -> None: - self.event: Literal["authentication.password_succeeded"] = attributes['event'] + self.event: Literal["authentication.password_succeeded"] = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] self.data: AuthenticationSucceededFields = AuthenticationSucceededFields( @@ -151,21 +168,21 @@ class AuthenticationSSOFailedEvent: event_name: str = "authentication.sso_failed" def __init__(self, attributes: JsonDict) -> None: - self.event: Literal["authentication.sso_failed"] = attributes['event'] + self.event: Literal["authentication.sso_failed"] = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] self.data: AuthenticationFailedFields = AuthenticationFailedFields( attributes["data"] ) + class AuthenticationSSOSucceededEvent: event_name: str = "authentication.sso_succeeded" def __init__(self, attributes: JsonDict) -> None: - self.event: Literal["authentication.sso_succeeded"] = attributes['event'] + self.event: Literal["authentication.sso_succeeded"] = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] self.data: AuthenticationSucceededFields = AuthenticationSucceededFields( attributes["data"] ) - diff --git a/workos/event_objects/connection.py b/workos/event_objects/connection.py index 405959c4..b20b686f 100644 --- a/workos/event_objects/connection.py +++ b/workos/event_objects/connection.py @@ -2,49 +2,52 @@ from enum import Enum from workos.utils.types import JsonDict + class ConnectionState(Enum): - INACTIVE = "inactive" - ACTIVE = "active" + INACTIVE = "inactive" + ACTIVE = "active" + class ConnectionType(Enum): - ADFS_SAML = 'ADFSSAML' - ADP_OIDC = 'AdpOidc' - AUTH0_SAML = 'Auth0SAML' - AZURE_SAML = 'AzureSAML' - CAS_SAML = 'CasSAML' - CLASS_LINK_SAML = 'ClassLinkSAML' - CLOUDFLARE_SAML = 'CloudflareSAML' - CYBER_ARK_SAML = 'CyberArkSAML' - DUO_SAML = 'DuoSAML' - GENERIC_OIDC = 'GenericOIDC' - GENERIC_SAML = 'GenericSAML' - GOOGLE_OAUTH = 'GoogleOAuth' - GOOGLE_SAML = 'GoogleSAML' - JUMP_CLOUD_SAML = 'JumpCloudSAML' - KEYCLOAK_SAML = 'KeycloakSAML' - LAST_PASS_SAML = 'LastPassSAML' - LOGIN_GOV_OIDC = 'LoginGovOidc' - MAGIC_LINK = 'MagicLink' - MICROSOFT_OAUTH = 'MicrosoftOAuth' - MINI_ORANGE_SAML = 'MiniOrangeSAML' - NET_IQ_SAML = 'NetIqSAML' - OKTA_SAML = 'OktaSAML' - ONE_LOGIN_SAML ='OneLoginSAML' - ORACLE_SAML = 'OracleSAML' - PING_FEDERATE_SAML = 'PingFederateSAML' - PING_ONE_SAML = 'PingOneSAML' - RIPPLING_SAML = 'RipplingSAML' - SALESFORCE_SAML = 'SalesforceSAML' - SHIBBOLETH_GENERIC_SAML = 'ShibbolethGenericSAML' - SHIBBOLETH_SAML = 'ShibbolethSAML' - SIMPLE_SAML_PHP_SAML = 'SimpleSamlPhpSAML' - VM_WARE_SAML = 'VMwareSAML' + ADFS_SAML = "ADFSSAML" + ADP_OIDC = "AdpOidc" + AUTH0_SAML = "Auth0SAML" + AZURE_SAML = "AzureSAML" + CAS_SAML = "CasSAML" + CLASS_LINK_SAML = "ClassLinkSAML" + CLOUDFLARE_SAML = "CloudflareSAML" + CYBER_ARK_SAML = "CyberArkSAML" + DUO_SAML = "DuoSAML" + GENERIC_OIDC = "GenericOIDC" + GENERIC_SAML = "GenericSAML" + GOOGLE_OAUTH = "GoogleOAuth" + GOOGLE_SAML = "GoogleSAML" + JUMP_CLOUD_SAML = "JumpCloudSAML" + KEYCLOAK_SAML = "KeycloakSAML" + LAST_PASS_SAML = "LastPassSAML" + LOGIN_GOV_OIDC = "LoginGovOidc" + MAGIC_LINK = "MagicLink" + MICROSOFT_OAUTH = "MicrosoftOAuth" + MINI_ORANGE_SAML = "MiniOrangeSAML" + NET_IQ_SAML = "NetIqSAML" + OKTA_SAML = "OktaSAML" + ONE_LOGIN_SAML = "OneLoginSAML" + ORACLE_SAML = "OracleSAML" + PING_FEDERATE_SAML = "PingFederateSAML" + PING_ONE_SAML = "PingOneSAML" + RIPPLING_SAML = "RipplingSAML" + SALESFORCE_SAML = "SalesforceSAML" + SHIBBOLETH_GENERIC_SAML = "ShibbolethGenericSAML" + SHIBBOLETH_SAML = "ShibbolethSAML" + SIMPLE_SAML_PHP_SAML = "SimpleSamlPhpSAML" + VM_WARE_SAML = "VMwareSAML" + class Domain: - def __init__(self, attributes: JsonDict) -> None: - self.id: str = attributes["id"] - self.object: Literal["connection_domain"] = attributes["object"] - self.domain: str = attributes["domain"] + def __init__(self, attributes: JsonDict) -> None: + self.id: str = attributes["id"] + self.object: Literal["connection_domain"] = attributes["object"] + self.domain: str = attributes["domain"] class ConnectionEvent: @@ -59,37 +62,34 @@ def __init__(self, attributes: JsonDict) -> None: self.updated_at: str = attributes["updated_at"] self.domains = [] for domain in attributes["domains"]: - self.domains.push(Domain(attributes=domain)) + self.domains.push(Domain(attributes=domain)) + class ConnectionActivatedEvent: event_name = "connection.activated" def __init__(self, attributes: JsonDict) -> None: - self.event: Literal['connection.activated'] = attributes["event"] + self.event: Literal["connection.activated"] = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] - self.data: ConnectionEvent = ConnectionEvent( - attributes["data"] - ) + self.data: ConnectionEvent = ConnectionEvent(attributes["data"]) + class ConnectionDeactivatedEvent: event_name = "connection.deactivated" def __init__(self, attributes: JsonDict) -> None: - self.event: Literal['connection.deactivated'] = attributes["event"] + self.event: Literal["connection.deactivated"] = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] - self.data: ConnectionEvent = ConnectionEvent( - attributes["data"] - ) + self.data: ConnectionEvent = ConnectionEvent(attributes["data"]) + class ConnectionDeactivatedEvent: event_name = "connection.deleted" def __init__(self, attributes: JsonDict) -> None: - self.event: Literal['connection.deleted'] = attributes["event"] + self.event: Literal["connection.deleted"] = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] - self.data: ConnectionEvent = ConnectionEvent( - attributes["data"] - ) + self.data: ConnectionEvent = ConnectionEvent(attributes["data"]) diff --git a/workos/events.py b/workos/events.py index 61e7fe39..bbd70b54 100644 --- a/workos/events.py +++ b/workos/events.py @@ -69,7 +69,7 @@ def request_helper(self): def list_events( self, - events: Optional[List[EVENT_TYPES]]=None, + events: Optional[List[EVENT_TYPES]] = None, limit: Optional[int] = None, organization_id: Optional[str] = None, after: Optional[str] = None, @@ -125,7 +125,7 @@ def list_events( for list_data in response["data"]: if list_data["event"] in EVENT_TO_OBJECT.keys(): data.append(EVENT_TO_OBJECT[list_data["event"]](list_data)) - + response["data"] = data return response