""" src/auth.py — Demo authentication and role management. IMPORTANT: These credentials are intentionally visible for demo/review purposes. Replace with a proper identity provider and hashed credential store for production. """ import hashlib from dataclasses import dataclass from typing import Optional @dataclass class User: user_id: str username: str display_name: str role: str # "user" | "admin" # ─── Demo credential definitions ───────────────────────────────────────────── # Stored as plain text here ONLY so the UI can surface them in the demo panel. DEMO_CREDENTIALS: list[dict] = [ {"username": "alice", "password": "pharma123", "role": "User"}, {"username": "bob", "password": "medbot456", "role": "User"}, {"username": "carol", "password": "health789", "role": "User"}, {"username": "admin", "password": "AdminPass!1","role": "Admin"}, ] # ─── User registry ──────────────────────────────────────────────────────────── _USERS: dict[str, User] = { "alice": User("u001", "alice", "Alice Johnson", "user"), "bob": User("u002", "bob", "Bob Smith", "user"), "carol": User("u003", "carol", "Carol White", "user"), "admin": User("u000", "admin", "Administrator", "admin"), } # ─── Internal: SHA-256 password map ────────────────────────────────────────── def _sha256(text: str) -> str: return hashlib.sha256(text.encode("utf-8")).hexdigest() _CREDENTIAL_MAP: dict[str, str] = { c["username"]: _sha256(c["password"]) for c in DEMO_CREDENTIALS } # ─── Public API ─────────────────────────────────────────────────────────────── def authenticate(username: str, password: str) -> Optional[User]: """Return the User object if credentials match, otherwise None.""" key = username.strip().lower() if _CREDENTIAL_MAP.get(key) == _sha256(password): return _USERS.get(key) return None def is_admin(user: User) -> bool: return user.role == "admin"