Skip to content

Commit 0b2e91c

Browse files
committed
Make tests and mypy happy
1 parent f63fed1 commit 0b2e91c

File tree

4 files changed

+76
-79
lines changed

4 files changed

+76
-79
lines changed

tests/test_session.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from datetime import datetime, timezone
66

77
from tests.conftest import with_jwks_mock
8-
from workos.session import SessionModule
8+
from workos.session import Session
99
from workos.types.user_management.authentication_response import (
1010
RefreshTokenAuthenticationResponse,
1111
)
@@ -73,7 +73,7 @@ def mock_user_management():
7373

7474
@with_jwks_mock
7575
def test_initialize_session_module(TEST_CONSTANTS, mock_user_management):
76-
session = SessionModule(
76+
session = Session(
7777
user_management=mock_user_management,
7878
client_id=TEST_CONSTANTS["CLIENT_ID"],
7979
session_data=TEST_CONSTANTS["SESSION_DATA"],
@@ -87,7 +87,7 @@ def test_initialize_session_module(TEST_CONSTANTS, mock_user_management):
8787
@with_jwks_mock
8888
def test_initialize_without_cookie_password(TEST_CONSTANTS, mock_user_management):
8989
with pytest.raises(ValueError, match="cookie_password is required"):
90-
SessionModule(
90+
Session(
9191
user_management=mock_user_management,
9292
client_id=TEST_CONSTANTS["CLIENT_ID"],
9393
session_data=TEST_CONSTANTS["SESSION_DATA"],
@@ -97,7 +97,7 @@ def test_initialize_without_cookie_password(TEST_CONSTANTS, mock_user_management
9797

9898
@with_jwks_mock
9999
def test_authenticate_no_session_cookie_provided(TEST_CONSTANTS, mock_user_management):
100-
session = SessionModule(
100+
session = Session(
101101
user_management=mock_user_management,
102102
client_id=TEST_CONSTANTS["CLIENT_ID"],
103103
session_data=None,
@@ -114,7 +114,7 @@ def test_authenticate_no_session_cookie_provided(TEST_CONSTANTS, mock_user_manag
114114

115115
@with_jwks_mock
116116
def test_authenticate_invalid_session_cookie(TEST_CONSTANTS, mock_user_management):
117-
session = SessionModule(
117+
session = Session(
118118
user_management=mock_user_management,
119119
client_id=TEST_CONSTANTS["CLIENT_ID"],
120120
session_data="invalid_session_data",
@@ -131,10 +131,10 @@ def test_authenticate_invalid_session_cookie(TEST_CONSTANTS, mock_user_managemen
131131

132132
@with_jwks_mock
133133
def test_authenticate_invalid_jwt(TEST_CONSTANTS, mock_user_management):
134-
invalid_session_data = SessionModule.seal_data(
134+
invalid_session_data = Session.seal_data(
135135
{"access_token": "invalid_session_data"}, TEST_CONSTANTS["COOKIE_PASSWORD"]
136136
)
137-
session = SessionModule(
137+
session = Session(
138138
user_management=mock_user_management,
139139
client_id=TEST_CONSTANTS["CLIENT_ID"],
140140
session_data=invalid_session_data,
@@ -143,12 +143,14 @@ def test_authenticate_invalid_jwt(TEST_CONSTANTS, mock_user_management):
143143

144144
response = session.authenticate()
145145

146+
print(response)
147+
146148
assert response.reason == AuthenticateWithSessionCookieFailureReason.INVALID_JWT
147149

148150

149151
@with_jwks_mock
150152
def test_authenticate_success(TEST_CONSTANTS, mock_user_management):
151-
session = SessionModule(
153+
session = Session(
152154
user_management=mock_user_management,
153155
client_id=TEST_CONSTANTS["CLIENT_ID"],
154156
session_data=TEST_CONSTANTS["SESSION_DATA"],
@@ -192,7 +194,7 @@ def test_authenticate_success(TEST_CONSTANTS, mock_user_management):
192194

193195
with (
194196
# Mock unsealing the session data
195-
patch.object(SessionModule, "unseal_data", return_value=mock_session),
197+
patch.object(Session, "unseal_data", return_value=mock_session),
196198
# Mock JWT validation
197199
patch.object(session, "is_valid_jwt", return_value=True),
198200
# Mock JWT decoding
@@ -219,7 +221,7 @@ def test_authenticate_success(TEST_CONSTANTS, mock_user_management):
219221

220222
@with_jwks_mock
221223
def test_refresh_invalid_session_cookie(TEST_CONSTANTS, mock_user_management):
222-
session = SessionModule(
224+
session = Session(
223225
user_management=mock_user_management,
224226
client_id=TEST_CONSTANTS["CLIENT_ID"],
225227
session_data="invalid_session_data",
@@ -248,7 +250,7 @@ def test_refresh_success(TEST_CONSTANTS, mock_user_management):
248250
"updated_at": TEST_CONSTANTS["CURRENT_TIMESTAMP"],
249251
}
250252

251-
session_data = SessionModule.seal_data(
253+
session_data = Session.seal_data(
252254
{"refresh_token": "refresh_token_12345", "user": test_user},
253255
TEST_CONSTANTS["COOKIE_PASSWORD"],
254256
)
@@ -264,7 +266,7 @@ def test_refresh_success(TEST_CONSTANTS, mock_user_management):
264266
RefreshTokenAuthenticationResponse(**mock_response)
265267
)
266268

267-
session = SessionModule(
269+
session = Session(
268270
user_management=mock_user_management,
269271
client_id=TEST_CONSTANTS["CLIENT_ID"],
270272
session_data=session_data,
@@ -303,16 +305,19 @@ def test_refresh_success(TEST_CONSTANTS, mock_user_management):
303305

304306
def test_seal_data(TEST_CONSTANTS):
305307
test_data = {"test": "data"}
306-
sealed = SessionModule.seal_data(test_data, TEST_CONSTANTS["COOKIE_PASSWORD"])
308+
sealed = Session.seal_data(test_data, TEST_CONSTANTS["COOKIE_PASSWORD"])
307309
assert isinstance(sealed, str)
308310

309311
# Test unsealing
310-
unsealed = SessionModule.unseal_data(sealed, TEST_CONSTANTS["COOKIE_PASSWORD"])
312+
unsealed = Session.unseal_data(sealed, TEST_CONSTANTS["COOKIE_PASSWORD"])
313+
print(test_data)
314+
print(unsealed)
315+
311316
assert unsealed == test_data
312317

313318

314319
def test_unseal_invalid_data(TEST_CONSTANTS):
315320
with pytest.raises(Exception): # Adjust exception type based on your implementation
316-
SessionModule.unseal_data(
321+
Session.unseal_data(
317322
"invalid_sealed_data", TEST_CONSTANTS["COOKIE_PASSWORD"]
318323
)

workos/session.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
from __future__ import annotations
12
import json
2-
from typing import Any, Dict, List, Optional, Union
3+
from typing import Any, Dict, Optional, Union, cast
34
import jwt
45
from jwt import PyJWKClient
56
from cryptography.fernet import Fernet
@@ -12,12 +13,11 @@
1213
RefreshWithSessionCookieSuccessResponse,
1314
)
1415

15-
16-
class SessionModule:
16+
class Session:
1717
def __init__(
1818
self,
1919
*,
20-
user_management: Any,
20+
user_management: "UserManagementModule", # type: ignore
2121
client_id: str,
2222
session_data: str,
2323
cookie_password: str,
@@ -42,7 +42,7 @@ def authenticate(
4242
AuthenticateWithSessionCookieSuccessResponse,
4343
AuthenticateWithSessionCookieErrorResponse,
4444
]:
45-
if self.session_data is None:
45+
if self.session_data is None or self.session_data == "":
4646
return AuthenticateWithSessionCookieErrorResponse(
4747
authenticated=False,
4848
reason=AuthenticateWithSessionCookieFailureReason.NO_SESSION_COOKIE_PROVIDED,
@@ -56,7 +56,7 @@ def authenticate(
5656
reason=AuthenticateWithSessionCookieFailureReason.INVALID_SESSION_COOKIE,
5757
)
5858

59-
if not session["access_token"]:
59+
if not session.get("access_token", None):
6060
return AuthenticateWithSessionCookieErrorResponse(
6161
authenticated=False,
6262
reason=AuthenticateWithSessionCookieFailureReason.INVALID_SESSION_COOKIE,
@@ -84,14 +84,15 @@ def authenticate(
8484
impersonator=session.get("impersonator", None),
8585
)
8686

87-
def refresh(self, options: Optional[Dict[str, Any]] = None) -> Union[
87+
def refresh(
88+
self, *, organization_id: Optional[str] = None, cookie_password: Optional[str] = None
89+
) -> Union[
8890
RefreshWithSessionCookieSuccessResponse,
8991
RefreshWithSessionCookieErrorResponse,
9092
]:
9193
cookie_password = (
92-
self.cookie_password if options is None else options.get("cookie_password")
94+
self.cookie_password if cookie_password is None else cookie_password
9395
)
94-
organization_id = None if options is None else options.get("organization_id")
9596

9697
try:
9798
session = self.unseal_data(self.session_data, cookie_password)
@@ -101,7 +102,7 @@ def refresh(self, options: Optional[Dict[str, Any]] = None) -> Union[
101102
reason=AuthenticateWithSessionCookieFailureReason.INVALID_SESSION_COOKIE,
102103
)
103104

104-
if not session["refresh_token"] or not session["user"]:
105+
if not session.get("refresh_token", None) or not session.get("user", None):
105106
return RefreshWithSessionCookieErrorResponse(
106107
authenticated=False,
107108
reason=AuthenticateWithSessionCookieFailureReason.INVALID_SESSION_COOKIE,
@@ -144,12 +145,14 @@ def refresh(self, options: Optional[Dict[str, Any]] = None) -> Union[
144145
def get_logout_url(self) -> str:
145146
auth_response = self.authenticate()
146147

147-
if not auth_response.authenticated:
148+
if isinstance(auth_response, AuthenticateWithSessionCookieErrorResponse):
148149
raise ValueError(
149150
f"Failed to extract session ID for logout URL: {auth_response.reason}"
150151
)
151152

152-
return self.user_management.get_logout_url(session_id=auth_response.session_id)
153+
result = self.user_management.get_logout_url(session_id=auth_response.session_id)
154+
return str(result)
155+
153156

154157
def is_valid_jwt(self, token: str) -> bool:
155158
try:
@@ -171,4 +174,5 @@ def unseal_data(sealed_data: str, key: str) -> Dict[str, Any]:
171174
fernet = Fernet(key)
172175
# Convert string back to bytes before decryption
173176
encrypted_bytes = sealed_data.encode("utf-8")
174-
return json.loads(fernet.decrypt(encrypted_bytes).decode())
177+
decrypted_str = fernet.decrypt(encrypted_bytes).decode()
178+
return cast(Dict[str, Any], json.loads(decrypted_str))

workos/types/user_management/session.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import List, Optional, TypedDict, Union
22
from enum import Enum
3-
3+
from typing_extensions import Literal
44
from workos.types.user_management.impersonator import Impersonator
55
from workos.types.user_management.user import User
66
from workos.types.workos_model import WorkOSModel
@@ -13,7 +13,7 @@ class AuthenticateWithSessionCookieFailureReason(Enum):
1313

1414

1515
class AuthenticateWithSessionCookieSuccessResponse(WorkOSModel):
16-
authenticated: bool = True
16+
authenticated: Literal[True]
1717
session_id: str
1818
organization_id: Optional[str] = None
1919
role: Optional[str] = None
@@ -24,7 +24,7 @@ class AuthenticateWithSessionCookieSuccessResponse(WorkOSModel):
2424

2525

2626
class AuthenticateWithSessionCookieErrorResponse(WorkOSModel):
27-
authenticated: bool = False
27+
authenticated: Literal[False]
2828
reason: Union[AuthenticateWithSessionCookieFailureReason, str]
2929

3030

@@ -35,10 +35,10 @@ class RefreshWithSessionCookieSuccessResponse(
3535

3636

3737
class RefreshWithSessionCookieErrorResponse(WorkOSModel):
38-
authenticated: bool = False
38+
authenticated: Literal[False]
3939
reason: Union[AuthenticateWithSessionCookieFailureReason, str]
4040

4141

42-
class SessionConfig(TypedDict):
42+
class SessionConfig(TypedDict, total=False):
4343
seal_session: bool
4444
cookie_password: str

0 commit comments

Comments
 (0)