Skip to content

Commit e767631

Browse files
authored
Move Organization operations to the top-level (#68)
1 parent f0629ff commit e767631

File tree

5 files changed

+149
-118
lines changed

5 files changed

+149
-118
lines changed

tests/test_organizations.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import json
2+
from requests import Response
3+
4+
import pytest
5+
6+
import workos
7+
from workos.organizations import Organizations
8+
9+
10+
class TestOrganizations(object):
11+
@pytest.fixture(autouse=True)
12+
def setup(self, set_api_key):
13+
self.organizations = Organizations()
14+
15+
@pytest.fixture
16+
def mock_organization(self):
17+
return {
18+
"name": "Test Organization",
19+
"object": "organization",
20+
"id": "org_01EHT88Z8J8795GZNQ4ZP1J81T",
21+
"domains": [
22+
{
23+
"domain": "example.com",
24+
"object": "organization_domain",
25+
"id": "org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8",
26+
}
27+
],
28+
}
29+
30+
@pytest.fixture
31+
def mock_organizations(self):
32+
return {
33+
"object": "list",
34+
"data": [
35+
{
36+
"object": "organization",
37+
"id": "org_01EHQMYV6MBK39QC5PZXHY59C3",
38+
"name": "example.com",
39+
"domains": [
40+
{
41+
"object": "organization_domain",
42+
"id": "org_domain_01EHQMYV71XT8H31WE5HF8YK4A",
43+
"domain": "example.com",
44+
}
45+
],
46+
},
47+
{
48+
"object": "organization",
49+
"id": "org_01EHQMVDTC2GRAHFCCRNTSKH46",
50+
"name": "example2.com",
51+
"domains": [
52+
{
53+
"object": "organization_domain",
54+
"id": "org_domain_01EHQMVDTZVA27PK614ME4YK7V",
55+
"domain": "example2.com",
56+
}
57+
],
58+
},
59+
],
60+
"listMetadata": {"before": "before-id", "after": None},
61+
}
62+
63+
def test_list_organizations(self, mock_organizations, mock_request_method):
64+
mock_response = Response()
65+
mock_response.status_code = 200
66+
mock_response.response_dict = mock_organizations
67+
mock_request_method("get", mock_response, 200)
68+
response = self.organizations.list_organizations()
69+
assert response.status_code == 200
70+
assert len(response.response_dict["data"]) == 2
71+
72+
def test_create_organization(self, mock_organization, mock_request_method):
73+
organization = {"domains": ["example.com"], "name": "Test Organization"}
74+
mock_response = Response()
75+
mock_response.status_code = 201
76+
mock_response.response_dict = mock_organization
77+
mock_request_method("post", mock_response, 201)
78+
79+
result = self.organizations.create_organization(organization)
80+
subject = result.response_dict
81+
82+
assert subject["id"] == "org_01EHT88Z8J8795GZNQ4ZP1J81T"
83+
assert subject["name"] == "Test Organization"

tests/test_portal.py

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -16,67 +16,6 @@ def setup(self, set_api_key):
1616
def mock_portal_link(self):
1717
return {"link": "https://id.workos.com/portal/launch?secret=secret"}
1818

19-
@pytest.fixture
20-
def mock_organization(self):
21-
return {
22-
"name": "Test Organization",
23-
"object": "organization",
24-
"id": "org_01EHT88Z8J8795GZNQ4ZP1J81T",
25-
"domains": [
26-
{
27-
"domain": "example.com",
28-
"object": "organization_domain",
29-
"id": "org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8",
30-
}
31-
],
32-
}
33-
34-
@pytest.fixture
35-
def mock_organizations(self):
36-
return {
37-
"object": "list",
38-
"data": [
39-
{
40-
"object": "organization",
41-
"id": "org_01EHQMYV6MBK39QC5PZXHY59C3",
42-
"name": "example.com",
43-
"domains": [
44-
{
45-
"object": "organization_domain",
46-
"id": "org_domain_01EHQMYV71XT8H31WE5HF8YK4A",
47-
"domain": "example.com",
48-
}
49-
],
50-
},
51-
{
52-
"object": "organization",
53-
"id": "org_01EHQMVDTC2GRAHFCCRNTSKH46",
54-
"name": "example2.com",
55-
"domains": [
56-
{
57-
"object": "organization_domain",
58-
"id": "org_domain_01EHQMVDTZVA27PK614ME4YK7V",
59-
"domain": "example2.com",
60-
}
61-
],
62-
},
63-
],
64-
"listMetadata": {"before": "before-id", "after": None},
65-
}
66-
67-
def test_create_organization(self, mock_organization, mock_request_method):
68-
organization = {"domains": ["example.com"], "name": "Test Organization"}
69-
mock_response = Response()
70-
mock_response.status_code = 201
71-
mock_response.response_dict = mock_organization
72-
mock_request_method("post", mock_response, 201)
73-
74-
result = self.portal.create_organization(organization)
75-
subject = result.response_dict
76-
77-
assert subject["id"] == "org_01EHT88Z8J8795GZNQ4ZP1J81T"
78-
assert subject["name"] == "Test Organization"
79-
8019
def test_generate_link_sso(self, mock_portal_link, mock_request_method):
8120
mock_response = Response()
8221
mock_response.status_code = 201
@@ -98,12 +37,3 @@ def test_generate_link_dsync(self, mock_portal_link, mock_request_method):
9837
subject = result.response_dict
9938

10039
assert subject["link"] == "https://id.workos.com/portal/launch?secret=secret"
101-
102-
def test_list_organizations(self, mock_organizations, mock_request_method):
103-
mock_response = Response()
104-
mock_response.status_code = 200
105-
mock_response.response_dict = mock_organizations
106-
mock_request_method("get", mock_response, 200)
107-
response = self.portal.list_organizations()
108-
assert response.status_code == 200
109-
assert len(response.response_dict["data"]) == 2

workos/organizations.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import workos
2+
from workos.utils.request import RequestHelper, REQUEST_METHOD_GET, REQUEST_METHOD_POST
3+
from workos.utils.validation import ORGANIZATIONS_MODULE, validate_settings
4+
5+
ORGANIZATIONS_PATH = "organizations"
6+
RESPONSE_LIMIT = 10
7+
8+
9+
class Organizations(object):
10+
@validate_settings(ORGANIZATIONS_MODULE)
11+
def __init__(self):
12+
pass
13+
14+
@property
15+
def request_helper(self):
16+
if not getattr(self, "_request_helper", None):
17+
self._request_helper = RequestHelper()
18+
return self._request_helper
19+
20+
def list_organizations(
21+
self, domains=None, limit=RESPONSE_LIMIT, before=None, after=None
22+
):
23+
"""Retrieve a list of organizations that have connections configured within your WorkOS dashboard.
24+
25+
Kwargs:
26+
domains (list): Filter organizations to only return those that are associated with the provided domains. (Optional)
27+
limit (int): Maximum number of records to return. (Optional)
28+
before (str): Pagination cursor to receive records before a provided Organization ID. (Optional)
29+
after (str): Pagination cursor to receive records after a provided Organization ID. (Optional)
30+
31+
Returns:
32+
dict: Organizations response from WorkOS.
33+
"""
34+
params = {
35+
"domains": domains,
36+
"limit": limit,
37+
"before": before,
38+
"after": after,
39+
}
40+
return self.request_helper.request(
41+
ORGANIZATIONS_PATH,
42+
method=REQUEST_METHOD_GET,
43+
params=params,
44+
token=workos.api_key,
45+
)
46+
47+
def create_organization(self, organization):
48+
"""Create an organization
49+
50+
Args:
51+
organization (dict) - An organization object
52+
organization[domains] (list) - List of domains that belong to the organization
53+
organization[name] (str) - A unique, descriptive name for the organization
54+
55+
Returns:
56+
dict: Created Organization response from WorkOS.
57+
"""
58+
return self.request_helper.request(
59+
ORGANIZATIONS_PATH,
60+
method=REQUEST_METHOD_POST,
61+
params=organization,
62+
token=workos.api_key,
63+
)

workos/portal.py

Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import workos
2-
from workos.utils.request import RequestHelper, REQUEST_METHOD_GET, REQUEST_METHOD_POST
2+
from workos.utils.request import RequestHelper, REQUEST_METHOD_POST
33
from workos.utils.validation import PORTAL_MODULE, validate_settings
44

5-
ORGANIZATIONS_PATH = "organizations"
65
PORTAL_GENERATE_PATH = "portal/generate_link"
7-
RESPONSE_LIMIT = 10
86

97

108
class Portal(object):
@@ -18,24 +16,6 @@ def request_helper(self):
1816
self._request_helper = RequestHelper()
1917
return self._request_helper
2018

21-
def create_organization(self, organization):
22-
"""Create an organization
23-
24-
Args:
25-
organization (dict) - An organization object
26-
organization[domains] (list) - List of domains that belong to the organization
27-
organization[name] (str) - A unique, descriptive name for the organization
28-
29-
Returns:
30-
dict: Created Organization response from WorkOS.
31-
"""
32-
return self.request_helper.request(
33-
ORGANIZATIONS_PATH,
34-
method=REQUEST_METHOD_POST,
35-
params=organization,
36-
token=workos.api_key,
37-
)
38-
3919
def generate_link(self, intent, organization, return_url=None):
4020
"""Generate a link to grant access to an organization's Admin Portal
4121
@@ -60,30 +40,3 @@ def generate_link(self, intent, organization, return_url=None):
6040
params=params,
6141
token=workos.api_key,
6242
)
63-
64-
def list_organizations(
65-
self, domains=None, limit=RESPONSE_LIMIT, before=None, after=None
66-
):
67-
"""Retrieve a list of organizations that have connections configured within your WorkOS dashboard.
68-
69-
Kwargs:
70-
domains (list): Filter organizations to only return those that are associated with the provided domains. (Optional)
71-
limit (int): Maximum number of records to return. (Optional)
72-
before (str): Pagination cursor to receive records before a provided Organization ID. (Optional)
73-
after (str): Pagination cursor to receive records after a provided Organization ID. (Optional)
74-
75-
Returns:
76-
dict: Organizations response from WorkOS.
77-
"""
78-
params = {
79-
"domains": domains,
80-
"limit": limit,
81-
"before": before,
82-
"after": after,
83-
}
84-
return self.request_helper.request(
85-
ORGANIZATIONS_PATH,
86-
method=REQUEST_METHOD_GET,
87-
params=params,
88-
token=workos.api_key,
89-
)

workos/utils/validation.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55

66
AUDIT_TRAIL_MODULE = "AuditTrail"
77
DIRECTORY_SYNC_MODULE = "DirectorySync"
8+
ORGANIZATIONS_MODULE = "Organizations"
89
PASSWORDLESS_MODULE = "Passwordless"
910
PORTAL_MODULE = "Portal"
1011
SSO_MODULE = "SSO"
1112

1213
REQUIRED_SETTINGS_FOR_MODULE = {
1314
AUDIT_TRAIL_MODULE: ["api_key",],
1415
DIRECTORY_SYNC_MODULE: ["api_key",],
16+
ORGANIZATIONS_MODULE: ["api_key"],
1517
PASSWORDLESS_MODULE: ["api_key",],
1618
PORTAL_MODULE: ["api_key",],
1719
SSO_MODULE: ["api_key", "client_id",],

0 commit comments

Comments
 (0)