|
6 | 6 | import asyncio |
7 | 7 | import json |
8 | 8 | import time |
9 | | -import unicodedata |
10 | 9 | from collections import OrderedDict |
11 | 10 | from typing import Any, Callable, Generic, Optional, TypeVar, Union |
12 | 11 | from urllib.parse import parse_qs, urlencode, urlparse, urlunparse |
|
63 | 62 | from auth0_server_python.utils import PKCE, URL, State |
64 | 63 | from auth0_server_python.utils.helpers import ( |
65 | 64 | build_domain_resolver_context, |
| 65 | + validate_org_claims, |
66 | 66 | validate_resolved_domain_value, |
67 | 67 | ) |
68 | 68 |
|
@@ -215,39 +215,7 @@ def _normalize_url(self, value: str) -> str: |
215 | 215 | return value.rstrip('/') |
216 | 216 |
|
217 | 217 | def _validate_org_claims(self, claims: dict, expected_org: str) -> None: |
218 | | - """ |
219 | | - Validate org_id or org_name in token claims against the requested organization. |
220 | | -
|
221 | | - Uses expected_org prefix to determine which claim to check: |
222 | | - - 'org_' prefix → validate claims['org_id'] exact match |
223 | | - - no prefix → validate claims['org_name'] case-insensitive match |
224 | | -
|
225 | | - Raises: |
226 | | - OrganizationTokenValidationError: if the claim is missing or mismatched. |
227 | | - """ |
228 | | - if expected_org.startswith("org_"): |
229 | | - actual = claims.get("org_id") |
230 | | - if not isinstance(actual, str): |
231 | | - raise OrganizationTokenValidationError( |
232 | | - "Organization Id (org_id) claim must be a string present in the ID token" |
233 | | - ) |
234 | | - if actual != expected_org: |
235 | | - raise OrganizationTokenValidationError( |
236 | | - "Organization Id (org_id) claim value mismatch in the ID token" |
237 | | - ) |
238 | | - else: |
239 | | - actual = claims.get("org_name") |
240 | | - if not isinstance(actual, str): |
241 | | - raise OrganizationTokenValidationError( |
242 | | - "Organization Name (org_name) claim must be a string present in the ID token" |
243 | | - ) |
244 | | - # NFC-normalize before comparison: the same visual character (e.g. é) can have |
245 | | - # multiple byte representations in Unicode. Normalizing both sides prevents |
246 | | - # false rejections without risk of false matches. |
247 | | - if unicodedata.normalize("NFC", actual).lower() != unicodedata.normalize("NFC", expected_org).lower(): |
248 | | - raise OrganizationTokenValidationError( |
249 | | - "Organization Name (org_name) claim value mismatch in the ID token" |
250 | | - ) |
| 218 | + validate_org_claims(claims, expected_org) |
251 | 219 |
|
252 | 220 | async def _resolve_current_domain(self, store_options=None) -> str: |
253 | 221 | """Resolve domain from resolver function or return static domain.""" |
|
0 commit comments