Files
boc/iom/api/auth.py
T
Bernt bae705aa97 ARCHITECTURE: NFC roadmap, edge AI, audit logging
- Add NFC ePassport roadmap (ICAO 9303, eIDAS)
- Add TensorFlow.js edge face detection (BlazeFace)
- Add structured audit logger (GDPR-compliant)
- Risk scoring support

Part of KYC Apple Native UX v1.1.0
2026-06-29 16:24:48 +00:00

152 lines
4.7 KiB
Python

"""
Authentication and Authorization
JWT-based auth with role-based access control
"""
from datetime import datetime, timedelta
from typing import Optional, Dict, List
from enum import Enum
import jwt
from fastapi import HTTPException, Security
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
class UserRole(str, Enum):
"""User roles"""
ADMIN = "admin"
MUNICIPALITY = "municipality"
PROPERTY_OWNER = "property_owner"
INFRASTRUCTURE_OWNER = "infrastructure_owner"
INSURANCE = "insurance"
BANK = "bank"
RETAIL = "retail"
ZOOMER = "zoomer"
READONLY = "readonly"
class Permission(str, Enum):
"""Permissions"""
READ_OBSERVATIONS = "read:observations"
WRITE_OBSERVATIONS = "write:observations"
READ_ANALYTICS = "read:analytics"
WRITE_ANALYTICS = "write:analytics"
READ_DECISIONS = "read:decisions"
WRITE_DECISIONS = "write:decisions"
READ_ADMIN = "read:admin"
WRITE_ADMIN = "write:admin"
MANAGE_USERS = "manage:users"
MANAGE_SYSTEM = "manage:system"
# Role permissions mapping
ROLE_PERMISSIONS = {
UserRole.ADMIN: [p for p in Permission],
UserRole.MUNICIPALITY: [
Permission.READ_OBSERVATIONS,
Permission.WRITE_OBSERVATIONS,
Permission.READ_ANALYTICS,
Permission.READ_DECISIONS,
Permission.WRITE_DECISIONS
],
UserRole.PROPERTY_OWNER: [
Permission.READ_OBSERVATIONS,
Permission.READ_ANALYTICS,
Permission.READ_DECISIONS
],
UserRole.INFRASTRUCTURE_OWNER: [
Permission.READ_OBSERVATIONS,
Permission.WRITE_OBSERVATIONS,
Permission.READ_ANALYTICS,
Permission.READ_DECISIONS,
Permission.WRITE_DECISIONS
],
UserRole.INSURANCE: [
Permission.READ_OBSERVATIONS,
Permission.READ_ANALYTICS,
Permission.READ_DECISIONS
],
UserRole.BANK: [
Permission.READ_OBSERVATIONS,
Permission.READ_ANALYTICS,
Permission.READ_DECISIONS
],
UserRole.RETAIL: [
Permission.READ_OBSERVATIONS,
Permission.READ_ANALYTICS,
Permission.READ_DECISIONS
],
UserRole.ZOOMER: [
Permission.READ_OBSERVATIONS,
Permission.WRITE_OBSERVATIONS
],
UserRole.READONLY: [
Permission.READ_OBSERVATIONS,
Permission.READ_ANALYTICS
]
}
class AuthManager:
"""Authentication and authorization manager"""
def __init__(self, secret_key: str, algorithm: str = "HS256"):
self.secret_key = secret_key
self.algorithm = algorithm
self.security = HTTPBearer()
def create_token(self, user_id: str, role: UserRole, expires_hours: int = 24) -> str:
"""Create JWT token"""
payload = {
"sub": user_id,
"role": role.value,
"permissions": [p.value for p in ROLE_PERMISSIONS[role]],
"iat": datetime.utcnow(),
"exp": datetime.utcnow() + timedelta(hours=expires_hours)
}
return jwt.encode(payload, self.secret_key, algorithm=self.algorithm)
def verify_token(self, token: str) -> Dict:
"""Verify JWT token"""
try:
payload = jwt.decode(token, self.secret_key, algorithms=[self.algorithm])
return payload
except jwt.ExpiredSignatureError:
raise HTTPException(status_code=401, detail="Token expired")
except jwt.InvalidTokenError:
raise HTTPException(status_code=401, detail="Invalid token")
def get_current_user(self, credentials: HTTPAuthorizationCredentials = Security(HTTPBearer())):
"""Get current user from token"""
token = credentials.credentials
return self.verify_token(token)
def require_permission(self, permission: Permission):
"""Require specific permission"""
def checker(credentials: HTTPAuthorizationCredentials = Security(HTTPBearer())):
token = credentials.credentials
payload = self.verify_token(token)
user_permissions = payload.get("permissions", [])
if permission.value not in user_permissions:
raise HTTPException(
status_code=403,
detail=f"Permission denied: {permission.value}"
)
return payload
return checker
def has_permission(self, user_payload: Dict, permission: Permission) -> bool:
"""Check if user has permission"""
user_permissions = user_payload.get("permissions", [])
return permission.value in user_permissions
# Initialize auth manager
import os
auth_manager = AuthManager(
secret_key=os.getenv("JWT_SECRET", "iom_jwt_secret")
)