Skip to content

Commit c8c4d1e

Browse files
committed
fix lint issue, added more tests
1 parent 4f9e5cd commit c8c4d1e

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

mauth_client/utils.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,32 @@ def decode(byte_string: bytes) -> str:
3333
encoding = charset_normalizer.detect(byte_string)["encoding"]
3434
return byte_string.decode(encoding)
3535

36+
3637
def is_exempt_request_path(path: str, exempt: set) -> bool:
38+
"""
39+
Check if a request path should be exempt from authentication based on prefix matching.
40+
41+
This function performs prefix matching with path separator boundary checking to prevent
42+
false positives. A path matches an exempt prefix only if it starts with the exempt path
43+
followed by a path separator ('/').
44+
45+
:param str path: The request path to check (e.g., '/health/live', '/api/users')
46+
:param set exempt: Set of exempt path prefixes (e.g., {'/health', '/metrics'})
47+
:return: True if the path matches any exempt prefix, False otherwise
48+
:rtype: bool
49+
50+
Examples:
51+
Matching cases (returns True):
52+
- path='/health/live', exempt={'/health'} -> True
53+
- path='/health/ready', exempt={'/health'} -> True
54+
- path='/metrics/prometheus', exempt={'/metrics'} -> True
55+
56+
Non-matching cases (returns False):
57+
- path='/health', exempt={'/health'} -> False (exact match without trailing slash)
58+
- path='/api-admin', exempt={'/api'} -> False (not a path separator boundary)
59+
- path='/app_status_admin', exempt={'/app_status'} -> False (underscore, not separator)
60+
- path='/healthcare', exempt={'/health'} -> False (different path)
61+
"""
3762
for exempt_path in exempt:
3863
# Exact match or prefix match with path separator
3964
# For instance this prevents /api matching /api-admin or /app_status matching /app_status_admin

tests/utils_test.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,19 @@ def test_real_world_monitoring_paths(self):
154154
self.assertTrue(is_exempt_request_path("/status/app", exempt))
155155
self.assertTrue(is_exempt_request_path("/actuator/health", exempt))
156156
self.assertFalse(is_exempt_request_path("/api/metrics", exempt))
157+
158+
def test_long_nested_paths(self):
159+
"""Test deeply nested paths with multiple levels."""
160+
exempt = {"/api"}
161+
# Test very long nested paths
162+
self.assertTrue(is_exempt_request_path("/api/v1/organizations/123/projects/456/resources/789/items", exempt))
163+
self.assertTrue(is_exempt_request_path("/api/internal/admin/users/settings/preferences/notifications", exempt))
164+
165+
exempt_nested = {"/admin/dashboard"}
166+
self.assertTrue(is_exempt_request_path(
167+
"/admin/dashboard/analytics/reports/monthly/2024/november/summary",
168+
exempt_nested
169+
))
170+
171+
# Should not match similar but non-matching long paths
172+
self.assertFalse(is_exempt_request_path("/api-v1/dashboard-v2/analytics", exempt_nested))

0 commit comments

Comments
 (0)