mirror of
				https://github.com/bunny-lab-io/Borealis.git
				synced 2025-10-26 15:21:57 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			73 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """Builders for operator authentication payloads."""
 | |
| 
 | |
| from __future__ import annotations
 | |
| 
 | |
| import hashlib
 | |
| from dataclasses import dataclass
 | |
| from typing import Mapping
 | |
| 
 | |
| 
 | |
| @dataclass(frozen=True, slots=True)
 | |
| class OperatorLoginRequest:
 | |
|     """Normalized operator login credentials."""
 | |
| 
 | |
|     username: str
 | |
|     password_sha512: str
 | |
| 
 | |
| 
 | |
| @dataclass(frozen=True, slots=True)
 | |
| class OperatorMFAVerificationRequest:
 | |
|     """Normalized MFA verification payload."""
 | |
| 
 | |
|     pending_token: str
 | |
|     code: str
 | |
| 
 | |
| 
 | |
| def _sha512_hex(raw: str) -> str:
 | |
|     digest = hashlib.sha512()
 | |
|     digest.update(raw.encode("utf-8"))
 | |
|     return digest.hexdigest()
 | |
| 
 | |
| 
 | |
| def build_login_request(payload: Mapping[str, object]) -> OperatorLoginRequest:
 | |
|     """Validate and normalize the login *payload*."""
 | |
| 
 | |
|     username = str(payload.get("username") or "").strip()
 | |
|     password_sha512 = str(payload.get("password_sha512") or "").strip().lower()
 | |
|     password = payload.get("password")
 | |
| 
 | |
|     if not username:
 | |
|         raise ValueError("username is required")
 | |
| 
 | |
|     if password_sha512:
 | |
|         normalized_hash = password_sha512
 | |
|     else:
 | |
|         if not isinstance(password, str) or not password:
 | |
|             raise ValueError("password is required")
 | |
|         normalized_hash = _sha512_hex(password)
 | |
| 
 | |
|     return OperatorLoginRequest(username=username, password_sha512=normalized_hash)
 | |
| 
 | |
| 
 | |
| def build_mfa_request(payload: Mapping[str, object]) -> OperatorMFAVerificationRequest:
 | |
|     """Validate and normalize the MFA verification *payload*."""
 | |
| 
 | |
|     pending_token = str(payload.get("pending_token") or "").strip()
 | |
|     raw_code = str(payload.get("code") or "").strip()
 | |
|     digits = "".join(ch for ch in raw_code if ch.isdigit())
 | |
| 
 | |
|     if not pending_token:
 | |
|         raise ValueError("pending_token is required")
 | |
|     if len(digits) < 6:
 | |
|         raise ValueError("code must contain 6 digits")
 | |
| 
 | |
|     return OperatorMFAVerificationRequest(pending_token=pending_token, code=digits)
 | |
| 
 | |
| 
 | |
| __all__ = [
 | |
|     "OperatorLoginRequest",
 | |
|     "OperatorMFAVerificationRequest",
 | |
|     "build_login_request",
 | |
|     "build_mfa_request",
 | |
| ]
 |