4545 verify_microsoft_access_token ,
4646)
4747
48-
4948# ─────────────────────────────────────────────────────────────────────────────
5049# Shared helpers
5150# ─────────────────────────────────────────────────────────────────────────────
@@ -64,8 +63,10 @@ def _generate_rsa_key_pair():
6463 public_key = private_key .public_key ()
6564
6665 # Build a minimal JWK for the public key (PyJWT RSAAlgorithm.from_jwk accepts this).
67- from jwt .algorithms import RSAAlgorithm
6866 import json
67+
68+ from jwt .algorithms import RSAAlgorithm
69+
6970 jwk_str = RSAAlgorithm .to_jwk (public_key )
7071 jwk_dict = json .loads (jwk_str )
7172 jwk_dict ["kid" ] = KID
@@ -136,10 +137,11 @@ def _clear_cache():
136137# _resolve_ms_jwks_url
137138# ─────────────────────────────────────────────────────────────────────────────
138139
140+
139141class TestResolveMsJwksUrl :
140142 def test_v2_token_uses_v2_endpoint (self ):
141143 url = _resolve_ms_jwks_url (TENANT_ID , "2.0" )
142- assert f "/discovery/v2.0/keys" in url
144+ assert "/discovery/v2.0/keys" in url
143145 assert TENANT_ID in url
144146
145147 def test_v1_token_uses_v1_endpoint (self ):
@@ -157,6 +159,7 @@ def test_unknown_version_defaults_to_v2(self):
157159# _validate_ms_issuer
158160# ─────────────────────────────────────────────────────────────────────────────
159161
162+
160163class TestValidateMsIssuer :
161164 def test_v2_exact_match_passes (self ):
162165 """Signing key issuer exactly matches token iss — should pass."""
@@ -194,6 +197,7 @@ def test_issuer_without_guid_segment_skips_tid_url_check(self):
194197# verify_microsoft_access_token
195198# ─────────────────────────────────────────────────────────────────────────────
196199
200+
197201class TestVerifyMsAccessToken :
198202 """Tests for verify_microsoft_access_token()."""
199203
@@ -222,9 +226,12 @@ def test_graph_token_tenant_allow_list_enforced(self):
222226 token = _make_ms_token (self .private_key , aud = MS_GRAPH_AUD )
223227
224228 with patch ("utils.jwt_verification._fetch_jwks" ):
225- with pytest .raises (InvalidIssuerError , match = "not in the configured allowed tenant list" ):
229+ with pytest .raises (
230+ InvalidIssuerError , match = "not in the configured allowed tenant list"
231+ ):
226232 verify_microsoft_access_token (
227- token , CLIENT_ID ,
233+ token ,
234+ CLIENT_ID ,
228235 allowed_tenant_ids = {"ffffffff-ffff-ffff-ffff-ffffffffffff" },
229236 )
230237
@@ -235,7 +242,8 @@ def test_graph_token_allowed_tenant_passes(self):
235242
236243 with patch ("utils.jwt_verification._fetch_jwks" ):
237244 claims = verify_microsoft_access_token (
238- token , CLIENT_ID ,
245+ token ,
246+ CLIENT_ID ,
239247 allowed_tenant_ids = {TENANT_ID },
240248 )
241249 assert claims ["tid" ] == TENANT_ID
@@ -331,9 +339,12 @@ def test_tenant_allow_list_rejects_unlisted_tenant(self):
331339 token = _make_ms_token (self .private_key )
332340
333341 with patch ("utils.jwt_verification._fetch_jwks" , return_value = self .jwks ):
334- with pytest .raises (InvalidIssuerError , match = "not in the configured allowed tenant list" ):
342+ with pytest .raises (
343+ InvalidIssuerError , match = "not in the configured allowed tenant list"
344+ ):
335345 verify_microsoft_access_token (
336- token , CLIENT_ID ,
346+ token ,
347+ CLIENT_ID ,
337348 allowed_tenant_ids = {"ffffffff-ffff-ffff-ffff-ffffffffffff" },
338349 )
339350
@@ -343,7 +354,8 @@ def test_tenant_allow_list_accepts_listed_tenant(self):
343354
344355 with patch ("utils.jwt_verification._fetch_jwks" , return_value = self .jwks ):
345356 claims = verify_microsoft_access_token (
346- token , CLIENT_ID ,
357+ token ,
358+ CLIENT_ID ,
347359 allowed_tenant_ids = {TENANT_ID },
348360 )
349361 assert claims ["tid" ] == TENANT_ID
@@ -392,8 +404,9 @@ def test_jwks_fetch_failure_raises(self):
392404 """Network failure during JWKS fetch propagates as JWTVerificationError."""
393405 token = _make_ms_token (self .private_key )
394406
395- with patch ("utils.jwt_verification._fetch_jwks" ,
396- side_effect = JWTVerificationError ("network error" )):
407+ with patch (
408+ "utils.jwt_verification._fetch_jwks" , side_effect = JWTVerificationError ("network error" )
409+ ):
397410 with pytest .raises (JWTVerificationError ):
398411 verify_microsoft_access_token (token , CLIENT_ID )
399412
@@ -430,6 +443,7 @@ def test_templated_jwks_key_issuer_accepted(self):
430443# verify_google_id_token
431444# ─────────────────────────────────────────────────────────────────────────────
432445
446+
433447class TestVerifyGoogleIdToken :
434448 """Tests for verify_google_id_token()."""
435449
@@ -523,44 +537,52 @@ def test_jwks_cached_between_calls(self):
523537# get_env_set (env_utils helper)
524538# ─────────────────────────────────────────────────────────────────────────────
525539
540+
526541class TestGetEnvSet :
527542 """Tests for the get_env_set() helper used for MICROSOFT_ALLOWED_TENANT_IDS."""
528543
529544 def test_unset_returns_none (self , monkeypatch ):
530545 monkeypatch .delenv ("MICROSOFT_ALLOWED_TENANT_IDS" , raising = False )
531546 from utils .env_utils import get_env_set
547+
532548 assert get_env_set ("MICROSOFT_ALLOWED_TENANT_IDS" ) is None
533549
534550 def test_empty_string_returns_none (self , monkeypatch ):
535551 monkeypatch .setenv ("MICROSOFT_ALLOWED_TENANT_IDS" , "" )
536552 from utils .env_utils import get_env_set
553+
537554 assert get_env_set ("MICROSOFT_ALLOWED_TENANT_IDS" ) is None
538555
539556 def test_whitespace_only_returns_none (self , monkeypatch ):
540557 monkeypatch .setenv ("MICROSOFT_ALLOWED_TENANT_IDS" , " " )
541558 from utils .env_utils import get_env_set
559+
542560 assert get_env_set ("MICROSOFT_ALLOWED_TENANT_IDS" ) is None
543561
544562 def test_single_value_returns_set (self , monkeypatch ):
545563 monkeypatch .setenv ("MICROSOFT_ALLOWED_TENANT_IDS" , "aaaa-1111" )
546564 from utils .env_utils import get_env_set
565+
547566 result = get_env_set ("MICROSOFT_ALLOWED_TENANT_IDS" )
548567 assert result == {"aaaa-1111" }
549568
550569 def test_multiple_values_returns_set (self , monkeypatch ):
551570 monkeypatch .setenv ("MICROSOFT_ALLOWED_TENANT_IDS" , "aaaa-1111,bbbb-2222,cccc-3333" )
552571 from utils .env_utils import get_env_set
572+
553573 result = get_env_set ("MICROSOFT_ALLOWED_TENANT_IDS" )
554574 assert result == {"aaaa-1111" , "bbbb-2222" , "cccc-3333" }
555575
556576 def test_values_are_stripped (self , monkeypatch ):
557577 monkeypatch .setenv ("MICROSOFT_ALLOWED_TENANT_IDS" , " aaaa-1111 , bbbb-2222 " )
558578 from utils .env_utils import get_env_set
579+
559580 result = get_env_set ("MICROSOFT_ALLOWED_TENANT_IDS" )
560581 assert result == {"aaaa-1111" , "bbbb-2222" }
561582
562583 def test_empty_segments_ignored (self , monkeypatch ):
563584 monkeypatch .setenv ("MICROSOFT_ALLOWED_TENANT_IDS" , "aaaa-1111,,bbbb-2222," )
564585 from utils .env_utils import get_env_set
586+
565587 result = get_env_set ("MICROSOFT_ALLOWED_TENANT_IDS" )
566588 assert result == {"aaaa-1111" , "bbbb-2222" }
0 commit comments