66
77from tests .conftest import with_jwks_mock
88from workos .session import SessionModule
9- from workos .types .user_management .authentication_response import RefreshTokenAuthenticationResponse
9+ from workos .types .user_management .authentication_response import (
10+ RefreshTokenAuthenticationResponse ,
11+ )
1012from workos .types .user_management .session import (
1113 AuthenticateWithSessionCookieFailureReason ,
1214 AuthenticateWithSessionCookieSuccessResponse ,
1820from cryptography .hazmat .primitives import serialization
1921from cryptography .hazmat .primitives .asymmetric import rsa
2022
23+
2124@pytest .fixture (scope = "session" )
2225def TEST_CONSTANTS ():
2326 # Generate RSA key pair for testing
24- private_key = rsa .generate_private_key (
25- public_exponent = 65537 ,
26- key_size = 2048
27- )
27+ private_key = rsa .generate_private_key (public_exponent = 65537 , key_size = 2048 )
2828
2929 public_key = private_key .public_key ()
3030
3131 # Get the private key in PEM format
3232 private_pem = private_key .private_bytes (
3333 encoding = serialization .Encoding .PEM ,
3434 format = serialization .PrivateFormat .PKCS8 ,
35- encryption_algorithm = serialization .NoEncryption ()
35+ encryption_algorithm = serialization .NoEncryption (),
3636 )
3737
3838 return {
@@ -56,86 +56,103 @@ def TEST_CONSTANTS():
5656 "iat" : int (datetime .now (timezone .utc ).timestamp ()),
5757 },
5858 private_pem ,
59- algorithm = "RS256"
60- )
59+ algorithm = "RS256" ,
60+ ),
6161 }
6262
63+
6364@pytest .fixture
6465def mock_user_management ():
6566 mock = Mock ()
66- mock .get_jwks_url .return_value = "https://api.workos.com/user_management/sso/jwks/client_123"
67+ mock .get_jwks_url .return_value = (
68+ "https://api.workos.com/user_management/sso/jwks/client_123"
69+ )
6770
6871 return mock
6972
73+
7074@with_jwks_mock
7175def test_initialize_session_module (TEST_CONSTANTS , mock_user_management ):
7276 session = SessionModule (
7377 user_management = mock_user_management ,
7478 client_id = TEST_CONSTANTS ["CLIENT_ID" ],
7579 session_data = TEST_CONSTANTS ["SESSION_DATA" ],
76- cookie_password = TEST_CONSTANTS ["COOKIE_PASSWORD" ]
80+ cookie_password = TEST_CONSTANTS ["COOKIE_PASSWORD" ],
7781 )
7882
7983 assert session .client_id == TEST_CONSTANTS ["CLIENT_ID" ]
8084 assert session .cookie_password is not None
8185
86+
8287@with_jwks_mock
8388def test_initialize_without_cookie_password (TEST_CONSTANTS , mock_user_management ):
8489 with pytest .raises (ValueError , match = "cookie_password is required" ):
8590 SessionModule (
8691 user_management = mock_user_management ,
8792 client_id = TEST_CONSTANTS ["CLIENT_ID" ],
8893 session_data = TEST_CONSTANTS ["SESSION_DATA" ],
89- cookie_password = ""
94+ cookie_password = "" ,
9095 )
9196
97+
9298@with_jwks_mock
9399def test_authenticate_no_session_cookie_provided (TEST_CONSTANTS , mock_user_management ):
94100 session = SessionModule (
95101 user_management = mock_user_management ,
96102 client_id = TEST_CONSTANTS ["CLIENT_ID" ],
97103 session_data = None ,
98- cookie_password = TEST_CONSTANTS ["COOKIE_PASSWORD" ]
104+ cookie_password = TEST_CONSTANTS ["COOKIE_PASSWORD" ],
99105 )
100106
101107 response = session .authenticate ()
102108
103- assert response .reason == AuthenticateWithSessionCookieFailureReason .NO_SESSION_COOKIE_PROVIDED
109+ assert (
110+ response .reason
111+ == AuthenticateWithSessionCookieFailureReason .NO_SESSION_COOKIE_PROVIDED
112+ )
113+
104114
105115@with_jwks_mock
106116def test_authenticate_invalid_session_cookie (TEST_CONSTANTS , mock_user_management ):
107117 session = SessionModule (
108118 user_management = mock_user_management ,
109119 client_id = TEST_CONSTANTS ["CLIENT_ID" ],
110120 session_data = "invalid_session_data" ,
111- cookie_password = TEST_CONSTANTS ["COOKIE_PASSWORD" ]
121+ cookie_password = TEST_CONSTANTS ["COOKIE_PASSWORD" ],
112122 )
113123
114124 response = session .authenticate ()
115125
116- assert response .reason == AuthenticateWithSessionCookieFailureReason .INVALID_SESSION_COOKIE
126+ assert (
127+ response .reason
128+ == AuthenticateWithSessionCookieFailureReason .INVALID_SESSION_COOKIE
129+ )
130+
117131
118132@with_jwks_mock
119133def test_authenticate_invalid_jwt (TEST_CONSTANTS , mock_user_management ):
120- invalid_session_data = SessionModule .seal_data ({ "access_token" : "invalid_session_data" }, TEST_CONSTANTS ["COOKIE_PASSWORD" ])
134+ invalid_session_data = SessionModule .seal_data (
135+ {"access_token" : "invalid_session_data" }, TEST_CONSTANTS ["COOKIE_PASSWORD" ]
136+ )
121137 session = SessionModule (
122138 user_management = mock_user_management ,
123139 client_id = TEST_CONSTANTS ["CLIENT_ID" ],
124140 session_data = invalid_session_data ,
125- cookie_password = TEST_CONSTANTS ["COOKIE_PASSWORD" ]
141+ cookie_password = TEST_CONSTANTS ["COOKIE_PASSWORD" ],
126142 )
127143
128144 response = session .authenticate ()
129145
130146 assert response .reason == AuthenticateWithSessionCookieFailureReason .INVALID_JWT
131147
148+
132149@with_jwks_mock
133150def test_authenticate_success (TEST_CONSTANTS , mock_user_management ):
134151 session = SessionModule (
135152 user_management = mock_user_management ,
136153 client_id = TEST_CONSTANTS ["CLIENT_ID" ],
137154 session_data = TEST_CONSTANTS ["SESSION_DATA" ],
138- cookie_password = TEST_CONSTANTS ["COOKIE_PASSWORD" ]
155+ cookie_password = TEST_CONSTANTS ["COOKIE_PASSWORD" ],
139156 )
140157
141158 # Mock the session data that would be unsealed
@@ -151,7 +168,7 @@ def test_authenticate_success(TEST_CONSTANTS, mock_user_management):
151168 "iat" : int (datetime .now (timezone .utc ).timestamp ()),
152169 },
153170 TEST_CONSTANTS ["PRIVATE_KEY" ],
154- algorithm = "RS256"
171+ algorithm = "RS256" ,
155172 ),
156173 "user" : {
157174 "object" : "user" ,
@@ -161,7 +178,7 @@ def test_authenticate_success(TEST_CONSTANTS, mock_user_management):
161178 "created_at" : TEST_CONSTANTS ["CURRENT_TIMESTAMP" ],
162179 "updated_at" : TEST_CONSTANTS ["CURRENT_TIMESTAMP" ],
163180 },
164- "impersonator" : None
181+ "impersonator" : None ,
165182 }
166183
167184 # Mock the JWT payload that would be decoded
@@ -170,33 +187,22 @@ def test_authenticate_success(TEST_CONSTANTS, mock_user_management):
170187 "org_id" : TEST_CONSTANTS ["ORGANIZATION_ID" ],
171188 "role" : "admin" ,
172189 "permissions" : ["read" ],
173- "entitlements" : ["feature_1" ]
190+ "entitlements" : ["feature_1" ],
174191 }
175192
176193 with (
177194 # Mock unsealing the session data
178- patch .object (
179- SessionModule ,
180- "unseal_data" ,
181- return_value = mock_session
182- ),
195+ patch .object (SessionModule , "unseal_data" , return_value = mock_session ),
183196 # Mock JWT validation
184- patch .object (
185- session ,
186- "is_valid_jwt" ,
187- return_value = True
188- ),
197+ patch .object (session , "is_valid_jwt" , return_value = True ),
189198 # Mock JWT decoding
190- patch (
191- "jwt.decode" ,
192- return_value = mock_jwt_payload
193- ),
199+ patch ("jwt.decode" , return_value = mock_jwt_payload ),
194200 # Mock JWT signing key retrieval
195201 patch .object (
196202 session .jwks ,
197203 "get_signing_key_from_jwt" ,
198- return_value = Mock (key = TEST_CONSTANTS ["PUBLIC_KEY" ])
199- )
204+ return_value = Mock (key = TEST_CONSTANTS ["PUBLIC_KEY" ]),
205+ ),
200206 ):
201207 response = session .authenticate ()
202208
@@ -210,19 +216,24 @@ def test_authenticate_success(TEST_CONSTANTS, mock_user_management):
210216 assert response .user .id == TEST_CONSTANTS ["USER_ID" ]
211217 assert response .impersonator is None
212218
219+
213220@with_jwks_mock
214221def test_refresh_invalid_session_cookie (TEST_CONSTANTS , mock_user_management ):
215222 session = SessionModule (
216223 user_management = mock_user_management ,
217224 client_id = TEST_CONSTANTS ["CLIENT_ID" ],
218225 session_data = "invalid_session_data" ,
219- cookie_password = TEST_CONSTANTS ["COOKIE_PASSWORD" ]
226+ cookie_password = TEST_CONSTANTS ["COOKIE_PASSWORD" ],
220227 )
221228
222229 response = session .refresh ()
223230
224231 assert isinstance (response , RefreshWithSessionCookieErrorResponse )
225- assert response .reason == AuthenticateWithSessionCookieFailureReason .INVALID_SESSION_COOKIE
232+ assert (
233+ response .reason
234+ == AuthenticateWithSessionCookieFailureReason .INVALID_SESSION_COOKIE
235+ )
236+
226237
227238@with_jwks_mock
228239def test_refresh_success (TEST_CONSTANTS , mock_user_management ):
@@ -237,45 +248,41 @@ def test_refresh_success(TEST_CONSTANTS, mock_user_management):
237248 "updated_at" : TEST_CONSTANTS ["CURRENT_TIMESTAMP" ],
238249 }
239250
240- session_data = SessionModule .seal_data ({
241- "refresh_token" : "refresh_token_12345" ,
242- "user" : test_user
243- }, TEST_CONSTANTS [ "COOKIE_PASSWORD" ] )
251+ session_data = SessionModule .seal_data (
252+ { "refresh_token" : "refresh_token_12345" , "user" : test_user } ,
253+ TEST_CONSTANTS [ "COOKIE_PASSWORD" ],
254+ )
244255
245256 mock_response = {
246257 "access_token" : TEST_CONSTANTS ["TEST_TOKEN" ],
247258 "refresh_token" : "refresh_token_123" ,
248259 "sealed_session" : session_data ,
249- "user" : test_user
260+ "user" : test_user ,
250261 }
251262
252- mock_user_management .authenticate_with_refresh_token .return_value = RefreshTokenAuthenticationResponse (
253- ** mock_response
263+ mock_user_management .authenticate_with_refresh_token .return_value = (
264+ RefreshTokenAuthenticationResponse ( ** mock_response )
254265 )
255266
256267 session = SessionModule (
257268 user_management = mock_user_management ,
258269 client_id = TEST_CONSTANTS ["CLIENT_ID" ],
259270 session_data = session_data ,
260- cookie_password = TEST_CONSTANTS ["COOKIE_PASSWORD" ]
271+ cookie_password = TEST_CONSTANTS ["COOKIE_PASSWORD" ],
261272 )
262273
263274 with (
264- patch .object (
265- session ,
266- "is_valid_jwt" ,
267- return_value = True
268- ),
275+ patch .object (session , "is_valid_jwt" , return_value = True ),
269276 patch (
270277 "jwt.decode" ,
271278 return_value = {
272279 "sid" : TEST_CONSTANTS ["SESSION_ID" ],
273280 "org_id" : TEST_CONSTANTS ["ORGANIZATION_ID" ],
274281 "role" : "admin" ,
275282 "permissions" : ["read" ],
276- "entitlements" : ["feature_1" ]
277- }
278- )
283+ "entitlements" : ["feature_1" ],
284+ },
285+ ),
279286 ):
280287 response = session .refresh ()
281288
@@ -289,8 +296,8 @@ def test_refresh_success(TEST_CONSTANTS, mock_user_management):
289296 organization_id = None ,
290297 session = {
291298 "seal_session" : True ,
292- "cookie_password" : TEST_CONSTANTS ["COOKIE_PASSWORD" ]
293- }
299+ "cookie_password" : TEST_CONSTANTS ["COOKIE_PASSWORD" ],
300+ },
294301 )
295302
296303
@@ -303,6 +310,9 @@ def test_seal_data(TEST_CONSTANTS):
303310 unsealed = SessionModule .unseal_data (sealed , TEST_CONSTANTS ["COOKIE_PASSWORD" ])
304311 assert unsealed == test_data
305312
313+
306314def test_unseal_invalid_data (TEST_CONSTANTS ):
307315 with pytest .raises (Exception ): # Adjust exception type based on your implementation
308- SessionModule .unseal_data ("invalid_sealed_data" , TEST_CONSTANTS ["COOKIE_PASSWORD" ])
316+ SessionModule .unseal_data (
317+ "invalid_sealed_data" , TEST_CONSTANTS ["COOKIE_PASSWORD" ]
318+ )
0 commit comments