1- import pytest
1+ import concurrent .futures
2+ from datetime import datetime , timezone
23from unittest .mock import AsyncMock , Mock , patch
4+
35import jwt
4- from datetime import datetime , timezone
5- import concurrent .futures
6+ import pytest
7+ from cryptography .hazmat .primitives import serialization
8+ from cryptography .hazmat .primitives .asymmetric import rsa
69
710from tests .conftest import with_jwks_mock
811from workos .session import AsyncSession , Session , _get_jwks_client
1619 RefreshWithSessionCookieSuccessResponse ,
1720)
1821
19- from cryptography .hazmat .primitives import serialization
20- from cryptography .hazmat .primitives .asymmetric import rsa
21-
2222
2323class SessionFixtures :
2424 @pytest .fixture (autouse = True )
@@ -48,6 +48,7 @@ def session_constants(self):
4848 "sid" : "session_123" ,
4949 "org_id" : "organization_123" ,
5050 "role" : "admin" ,
51+ "roles" : ["admin" ],
5152 "permissions" : ["read" ],
5253 "entitlements" : ["feature_1" ],
5354 "exp" : int (current_datetime .timestamp ()) + 3600 ,
@@ -215,6 +216,7 @@ def test_authenticate_success(self, session_constants, mock_user_management):
215216 "sid" : session_constants ["SESSION_ID" ],
216217 "org_id" : session_constants ["ORGANIZATION_ID" ],
217218 "role" : "admin" ,
219+ "roles" : ["admin" ],
218220 "permissions" : ["read" ],
219221 "entitlements" : ["feature_1" ],
220222 "exp" : int (datetime .now (timezone .utc ).timestamp ()) + 3600 ,
@@ -239,6 +241,7 @@ def test_authenticate_success(self, session_constants, mock_user_management):
239241 "sid" : session_constants ["SESSION_ID" ],
240242 "org_id" : session_constants ["ORGANIZATION_ID" ],
241243 "role" : "admin" ,
244+ "roles" : ["admin" ],
242245 "permissions" : ["read" ],
243246 "entitlements" : ["feature_1" ],
244247 }
@@ -257,11 +260,80 @@ def test_authenticate_success(self, session_constants, mock_user_management):
257260 assert response .session_id == session_constants ["SESSION_ID" ]
258261 assert response .organization_id == session_constants ["ORGANIZATION_ID" ]
259262 assert response .role == "admin"
263+ assert response .roles == ["admin" ]
260264 assert response .permissions == ["read" ]
261265 assert response .entitlements == ["feature_1" ]
262266 assert response .user .id == session_constants ["USER_ID" ]
263267 assert response .impersonator is None
264268
269+ @with_jwks_mock
270+ def test_authenticate_success_with_roles (
271+ self , session_constants , mock_user_management
272+ ):
273+ session = Session (
274+ user_management = mock_user_management ,
275+ client_id = session_constants ["CLIENT_ID" ],
276+ session_data = session_constants ["SESSION_DATA" ],
277+ cookie_password = session_constants ["COOKIE_PASSWORD" ],
278+ )
279+
280+ # Mock the session data that would be unsealed
281+ mock_session = {
282+ "access_token" : jwt .encode (
283+ {
284+ "sid" : session_constants ["SESSION_ID" ],
285+ "org_id" : session_constants ["ORGANIZATION_ID" ],
286+ "role" : "admin" ,
287+ "roles" : ["admin" , "member" ],
288+ "permissions" : ["read" , "write" ],
289+ "entitlements" : ["feature_1" ],
290+ "exp" : int (datetime .now (timezone .utc ).timestamp ()) + 3600 ,
291+ "iat" : int (datetime .now (timezone .utc ).timestamp ()),
292+ },
293+ session_constants ["PRIVATE_KEY" ],
294+ algorithm = "RS256" ,
295+ ),
296+ "user" : {
297+ "object" : "user" ,
298+ "id" : session_constants ["USER_ID" ],
299+ 300+ "email_verified" : True ,
301+ "created_at" : session_constants ["CURRENT_TIMESTAMP" ],
302+ "updated_at" : session_constants ["CURRENT_TIMESTAMP" ],
303+ },
304+ "impersonator" : None ,
305+ }
306+
307+ # Mock the JWT payload that would be decoded
308+ mock_jwt_payload = {
309+ "sid" : session_constants ["SESSION_ID" ],
310+ "org_id" : session_constants ["ORGANIZATION_ID" ],
311+ "role" : "admin" ,
312+ "roles" : ["admin" , "member" ],
313+ "permissions" : ["read" , "write" ],
314+ "entitlements" : ["feature_1" ],
315+ }
316+
317+ with patch .object (Session , "unseal_data" , return_value = mock_session ), patch (
318+ "jwt.decode" , return_value = mock_jwt_payload
319+ ), patch .object (
320+ session .jwks ,
321+ "get_signing_key_from_jwt" ,
322+ return_value = Mock (key = session_constants ["PUBLIC_KEY" ]),
323+ ):
324+ response = session .authenticate ()
325+
326+ assert isinstance (response , AuthenticateWithSessionCookieSuccessResponse )
327+ assert response .authenticated is True
328+ assert response .session_id == session_constants ["SESSION_ID" ]
329+ assert response .organization_id == session_constants ["ORGANIZATION_ID" ]
330+ assert response .role == "admin"
331+ assert response .roles == ["admin" , "member" ]
332+ assert response .permissions == ["read" , "write" ]
333+ assert response .entitlements == ["feature_1" ]
334+ assert response .user .id == session_constants ["USER_ID" ]
335+ assert response .impersonator is None
336+
265337 @with_jwks_mock
266338 def test_refresh_invalid_session_cookie (
267339 self , session_constants , mock_user_management
@@ -335,6 +407,7 @@ def test_refresh_success(self, session_constants, mock_user_management):
335407 "sid" : session_constants ["SESSION_ID" ],
336408 "org_id" : session_constants ["ORGANIZATION_ID" ],
337409 "role" : "admin" ,
410+ "roles" : ["admin" ],
338411 "permissions" : ["read" ],
339412 "entitlements" : ["feature_1" ],
340413 },
@@ -435,6 +508,7 @@ async def test_refresh_success(self, session_constants, mock_user_management):
435508 "sid" : session_constants ["SESSION_ID" ],
436509 "org_id" : session_constants ["ORGANIZATION_ID" ],
437510 "role" : "admin" ,
511+ "roles" : ["admin" ],
438512 "permissions" : ["read" ],
439513 "entitlements" : ["feature_1" ],
440514 },
0 commit comments