Spaces:
Sleeping
Sleeping
| from datetime import datetime | |
| from passlib.context import CryptContext | |
| # API key hashing context | |
| pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") | |
| def hash_api_key(api_key: str) -> str: | |
| """Hash an API key using bcrypt. | |
| Bcrypt has a 72 byte limit, so we truncate if necessary. | |
| We use a safety margin of 60 bytes to avoid any edge cases. | |
| """ | |
| # Bcrypt limit is 72 bytes, use 60 as safety margin | |
| api_key_bytes = api_key.encode('utf-8') | |
| if len(api_key_bytes) > 60: | |
| # Truncate to 60 bytes for safety | |
| api_key_bytes = api_key_bytes[:60] | |
| # Decode back to string, ignoring any incomplete UTF-8 sequences | |
| api_key = api_key_bytes.decode('utf-8', errors='ignore') | |
| # Ensure we're passing a string that's definitely under 72 bytes | |
| return pwd_context.hash(api_key) | |
| def verify_api_key(plain_key: str, hashed_key: str) -> bool: | |
| """Verify an API key against its hash. | |
| Bcrypt has a 72 byte limit, so we truncate if necessary (same as hash). | |
| We use a safety margin of 60 bytes to match hash behavior. | |
| """ | |
| # Bcrypt limit is 72 bytes, use 60 as safety margin (must match hash behavior) | |
| plain_key_bytes = plain_key.encode('utf-8') | |
| if len(plain_key_bytes) > 60: | |
| plain_key_bytes = plain_key_bytes[:60] | |
| plain_key = plain_key_bytes.decode('utf-8', errors='ignore') | |
| return pwd_context.verify(plain_key, hashed_key) | |