Skip to content

Commit

Permalink
Add Users.create_password_challenge() method (#199)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonatascastro12 authored Aug 23, 2023
1 parent 4212609 commit 04abda5
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 5 deletions.
31 changes: 30 additions & 1 deletion tests/test_users.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import pytest

import workos
from tests.utils.fixtures.mock_session import MockSession
from tests.utils.fixtures.mock_user import MockUser
from workos.users import Users
Expand Down Expand Up @@ -111,6 +110,15 @@ def mock_auth_response(self):
"session": session,
}

@pytest.fixture
def mock_password_challenge_response(self):
user = MockUser("user_01H7ZGXFP5C6BBQY6Z7277ZCT0").to_dict()

return {
"user": user,
"token": "token_123",
}

def test_create_user(self, mock_user, mock_request_method):
mock_request_method("post", mock_user, 201)

Expand Down Expand Up @@ -279,3 +287,24 @@ def test_authenticate_with_code(self, capture_and_mock_request, mock_auth_respon
assert request["json"]["client_id"] == "client_b27needthisforssotemxo"
assert request["json"]["client_secret"] == "sk_abdsomecharactersm284"
assert request["json"]["grant_type"] == "authorization_code"

def test_create_password_challenge(
self, capture_and_mock_request, mock_password_challenge_response
):
email = "[email protected]"
password_reset_url = "https://foo-corp.com/reset-password"

url, request = capture_and_mock_request(
"post", mock_password_challenge_response, 200
)

response = self.users.create_password_reset_challenge(
email=email,
password_reset_url=password_reset_url,
)

assert url[0].endswith("users/password_reset_challenge")
assert response["user"]["id"] == "user_01H7ZGXFP5C6BBQY6Z7277ZCT0"
assert response["token"] == "token_123"
assert request["json"]["email"] == email
assert request["json"]["password_reset_url"] == password_reset_url
33 changes: 33 additions & 0 deletions workos/resources/password_challenge_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from workos.resources.base import WorkOSBaseResource
from workos.resources.session import WorkOSSession
from workos.resources.users import WorkOSUser


class WorkOSPasswordChallengeResponse(WorkOSBaseResource):
"""Representation of a User and token response as returned by WorkOS through User Management features.
Attributes:
OBJECT_FIELDS (list): List of fields a WorkOSPasswordChallengeResponse is comprised of.
"""

OBJECT_FIELDS = [
"token",
]

@classmethod
def construct_from_response(cls, response):
challenge_response = super(
WorkOSPasswordChallengeResponse, cls
).construct_from_response(response)

user = WorkOSUser.construct_from_response(response["user"])
challenge_response.user = user

return challenge_response

def to_dict(self):
challenge_response = super(WorkOSPasswordChallengeResponse, self).to_dict()

user_dict = self.user.to_dict()
challenge_response["user"] = user_dict

return challenge_response
46 changes: 42 additions & 4 deletions workos/users.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import workos
from workos.resources.authentication_response import WorkOSAuthenticationResponse
from workos.resources.password_challenge_response import WorkOSPasswordChallengeResponse
from workos.resources.list import WorkOSListResource
from workos.resources.users import (
WorkOSUser,
Expand All @@ -16,7 +17,8 @@
USER_PATH = "users"
USER_DETAIL_PATH = "users/{0}"
USER_ORGANIZATION_PATH = "users/{0}/organization/{1}"
USER_SESSION_TOKEN = "users/session/token"
USER_SESSION_TOKEN_PATH = "users/session/token"
USER_PASSWORD_RESET_CHALLENGE_PATH = "users/password_reset_challenge"

RESPONSE_LIMIT = 10

Expand Down Expand Up @@ -231,7 +233,7 @@ def authenticate_with_magic_auth(
payload["user_agent"] = user_agent

response = self.request_helper.request(
USER_SESSION_TOKEN,
USER_SESSION_TOKEN_PATH,
method=REQUEST_METHOD_POST,
headers=headers,
params=payload,
Expand Down Expand Up @@ -282,7 +284,7 @@ def authenticate_with_password(
payload["user_agent"] = user_agent

response = self.request_helper.request(
USER_SESSION_TOKEN,
USER_SESSION_TOKEN_PATH,
method=REQUEST_METHOD_POST,
headers=headers,
params=payload,
Expand Down Expand Up @@ -331,10 +333,46 @@ def authenticate_with_code(
payload["user_agent"] = user_agent

response = self.request_helper.request(
USER_SESSION_TOKEN,
USER_SESSION_TOKEN_PATH,
method=REQUEST_METHOD_POST,
headers=headers,
params=payload,
)

return WorkOSAuthenticationResponse.construct_from_response(response).to_dict()

def create_password_reset_challenge(
self,
email,
password_reset_url,
):
"""Creates a password reset challenge and emails a password reset link to a user
Kwargs:
email (str): The email of the user that wishes to reset their password.
password_reset_url (str): The URL that will be linked to in the email.
Returns:
(dict): Authentication response from WorkOS.
[token] (str): The password reset token.
[user] (dict): User response from WorkOS
"""

headers = {}

payload = {
"email": email,
"password_reset_url": password_reset_url,
}

response = self.request_helper.request(
USER_PASSWORD_RESET_CHALLENGE_PATH,
method=REQUEST_METHOD_POST,
headers=headers,
params=payload,
token=workos.api_key,
)

return WorkOSPasswordChallengeResponse.construct_from_response(
response
).to_dict()

0 comments on commit 04abda5

Please sign in to comment.