1+ import unittest
2+ from msal .oauth2cli import oauth2
3+ import string
4+
5+ class TestTokenGenerationSecurity (unittest .TestCase ):
6+ """Verify secure token generation using secrets module."""
7+
8+ def test_pkce_verifier_format (self ):
9+ """Verify PKCE verifier is valid and uses correct alphabet."""
10+ pkce = oauth2 ._generate_pkce_code_verifier (length = 43 )
11+ verifier = pkce ["code_verifier" ]
12+
13+ # Check length
14+ self .assertEqual (len (verifier ), 43 )
15+
16+ # Check alphabet compliance (RFC 7636)
17+ allowed_chars = set (string .ascii_letters + string .digits + "-._~" )
18+ self .assertTrue (all (c in allowed_chars for c in verifier ))
19+
20+ # Verify code_challenge exists and is base64url encoded (no padding)
21+ self .assertIn ("code_challenge" , pkce )
22+ self .assertNotIn (b"=" , pkce ["code_challenge" ])
23+
24+ def test_pkce_verifier_custom_length (self ):
25+ """Test PKCE verifier with valid custom lengths."""
26+ for length in [43 , 64 , 128 ]:
27+ pkce = oauth2 ._generate_pkce_code_verifier (length = length )
28+ self .assertEqual (len (pkce ["code_verifier" ]), length )
29+
30+ def test_token_uniqueness (self ):
31+ """Verify generated tokens are unique (randomness test)."""
32+ # Generate multiple tokens - should all be different
33+ verifiers = [oauth2 ._generate_pkce_code_verifier ()["code_verifier" ]
34+ for _ in range (10 )]
35+ self .assertEqual (len (set (verifiers )), 10 , "Generated tokens should be unique" )
36+
37+ # Also test state generation
38+ from msal .oauth2cli .oauth2 import Client
39+ from unittest .mock import Mock
40+
41+ client = Client (
42+ server_configuration = {"authorization_endpoint" : "https://example.com/auth" },
43+ client_id = "test-client" ,
44+ http_client = Mock ()
45+ )
46+
47+ states = [client .initiate_auth_code_flow (scope = ["test" ])["state" ]
48+ for _ in range (10 )]
49+ self .assertEqual (len (set (states )), 10 , "Generated states should be unique" )
0 commit comments