Skip to content

Commit b83034c

Browse files
Add Users client and Users.create_user() method (#191)
* Add Users client and Users.create_user() method * Fix comment and format.
1 parent 2667837 commit b83034c

File tree

7 files changed

+174
-0
lines changed

7 files changed

+174
-0
lines changed

tests/test_client.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def setup(self):
1414
client._passwordless = None
1515
client._portal = None
1616
client._sso = None
17+
client._users = None
1718

1819
def test_initialize_sso(self, set_api_key_and_client_id):
1920
assert bool(client.sso)
@@ -36,6 +37,9 @@ def test_initialize_passwordless(self, set_api_key):
3637
def test_initialize_portal(self, set_api_key):
3738
assert bool(client.portal)
3839

40+
def test_initialize_users(self, set_api_key, set_client_id):
41+
assert bool(client.users)
42+
3943
def test_initialize_sso_missing_api_key(self, set_client_id):
4044
with pytest.raises(ConfigurationException) as ex:
4145
client.sso
@@ -107,3 +111,28 @@ def test_initialize_portal_missing_api_key(self):
107111
message = str(ex)
108112

109113
assert "api_key" in message
114+
115+
def test_initialize_users_missing_client_id(self, set_api_key):
116+
with pytest.raises(ConfigurationException) as ex:
117+
client.users
118+
119+
message = str(ex)
120+
121+
assert "client_id" in message
122+
123+
def test_initialize_users_missing_api_key(self, set_client_id):
124+
with pytest.raises(ConfigurationException) as ex:
125+
client.users
126+
127+
message = str(ex)
128+
129+
assert "api_key" in message
130+
131+
def test_initialize_users_missing_api_key_and_client_id(self):
132+
with pytest.raises(ConfigurationException) as ex:
133+
client.users
134+
135+
message = str(ex)
136+
137+
assert "api_key" in message
138+
assert "client_id" in message

tests/test_users.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import pytest
2+
3+
from tests.utils.fixtures.mock_user import MockUser
4+
from workos.users import Users
5+
6+
7+
class TestUsers(object):
8+
@pytest.fixture(autouse=True)
9+
def setup(self, set_api_key, set_client_id):
10+
self.users = Users()
11+
12+
@pytest.fixture
13+
def mock_user(self):
14+
return MockUser("user_01H7ZGXFP5C6BBQY6Z7277ZCT0").to_dict()
15+
16+
def test_create_user(self, mock_user, mock_request_method):
17+
mock_request_method("post", mock_user, 201)
18+
19+
payload = {
20+
"email": "[email protected]",
21+
"first_name": "Marcelina",
22+
"last_name": "Hoeger",
23+
"password": "password",
24+
"email_verified": False,
25+
}
26+
user = self.users.create_user(payload)
27+
28+
assert user["id"] == "user_01H7ZGXFP5C6BBQY6Z7277ZCT0"

tests/utils/fixtures/mock_user.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import datetime
2+
from workos.resources.base import WorkOSBaseResource
3+
4+
5+
class MockUser(WorkOSBaseResource):
6+
def __init__(self, id):
7+
self.id = id
8+
self.email = "[email protected]"
9+
self.first_name = "Marcelina"
10+
self.last_name = "Hoeger"
11+
self.user_type = "unmanaged"
12+
self.sso_profile_id = None
13+
self.email_verified_at = ""
14+
self.google_oauth_profile_id = None
15+
self.microsoft_oauth_profile_id = None
16+
self.created_at = datetime.datetime.now()
17+
self.updated_at = datetime.datetime.now()
18+
19+
OBJECT_FIELDS = [
20+
"id",
21+
"email",
22+
"first_name",
23+
"last_name",
24+
"user_type",
25+
"sso_profile_id",
26+
"email_verified_at",
27+
"google_oauth_profile_id",
28+
"microsoft_oauth_profile_id",
29+
"created_at",
30+
"updated_at",
31+
]

workos/client.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from workos.webhooks import Webhooks
99
from workos.mfa import Mfa
1010
from workos.events import Events
11+
from workos.users import Users
1112

1213

1314
class Client(object):
@@ -73,5 +74,11 @@ def mfa(self):
7374
self._mfa = Mfa()
7475
return self._mfa
7576

77+
@property
78+
def users(self):
79+
if not getattr(self, "_users", None):
80+
self._users = Users()
81+
return self._users
82+
7683

7784
client = Client()

workos/resources/users.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from workos.resources.base import WorkOSBaseResource
2+
3+
4+
class WorkOSUser(WorkOSBaseResource):
5+
"""Representation of a User as returned by WorkOS through User Management features.
6+
7+
Attributes:
8+
OBJECT_FIELDS (list): List of fields a WorkOSUser comprises.
9+
"""
10+
11+
OBJECT_FIELDS = [
12+
"id",
13+
"email",
14+
"first_name",
15+
"last_name",
16+
"user_type",
17+
"sso_profile_id",
18+
"email_verified_at",
19+
"google_oauth_profile_id",
20+
"microsoft_oauth_profile_id",
21+
"created_at",
22+
"updated_at",
23+
]

workos/users.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import workos
2+
from workos.resources.list import WorkOSListResource
3+
from workos.resources.users import (
4+
WorkOSUser,
5+
)
6+
from workos.utils.request import (
7+
RequestHelper,
8+
REQUEST_METHOD_POST,
9+
)
10+
from workos.utils.validation import validate_settings, USERS_MODULE
11+
12+
USER_PATH = "users"
13+
14+
RESPONSE_LIMIT = 10
15+
16+
17+
class Users(WorkOSListResource):
18+
"""Offers methods for using the WorkOS User Management API."""
19+
20+
@validate_settings(USERS_MODULE)
21+
def __init__(self):
22+
pass
23+
24+
@property
25+
def request_helper(self):
26+
if not getattr(self, "_request_helper", None):
27+
self._request_helper = RequestHelper()
28+
return self._request_helper
29+
30+
def create_user(self, user):
31+
"""Create a new unmanaged user with email password authentication.
32+
33+
Args:
34+
user (dict) - An user object
35+
user[email] (string) - The email address of the user.
36+
user[password] (string) - The password to set for the user.
37+
user[first_name] (string) - The user's first name.
38+
user[last_name] (string) - The user's last name.
39+
user[email_verified] (bool) - Whether the user's email address was previously verified.
40+
41+
Returns:
42+
dict: Created User response from WorkOS.
43+
"""
44+
headers = {}
45+
46+
response = self.request_helper.request(
47+
USER_PATH,
48+
method=REQUEST_METHOD_POST,
49+
params=user,
50+
headers=headers,
51+
token=workos.api_key,
52+
)
53+
54+
return WorkOSUser.construct_from_response(response).to_dict()

workos/utils/validation.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
SSO_MODULE = "SSO"
1414
WEBHOOKS_MODULE = "Webhooks"
1515
MFA_MODULE = "MFA"
16+
USERS_MODULE = "UserManagement"
1617

1718
REQUIRED_SETTINGS_FOR_MODULE = {
1819
AUDIT_LOGS_MODULE: [
@@ -42,6 +43,7 @@
4243
],
4344
WEBHOOKS_MODULE: ["api_key"],
4445
MFA_MODULE: ["api_key"],
46+
USERS_MODULE: ["client_id", "api_key"],
4547
}
4648

4749

0 commit comments

Comments
 (0)