from __future__ import annotations import secrets from typing import Any from fastapi import Depends, HTTPException, Request from Groups import AdminGroupName, GetGroupsForUser, GuestGroupName, IsUserInGroup from Users import GetUser ActiveSessions: dict[str, str] = {} SessionCookieName = "SaraViewSession" GuestUser: dict[str, Any] = { "Username": None, "IsAdmin": False, "IsGuest": True, "Groups": [GuestGroupName], "Colour": "Purple", } def CreateSession(Username: str) -> str: Token = secrets.token_urlsafe(32) ActiveSessions[Token] = Username return Token def DeleteSession(Token: str) -> None: ActiveSessions.pop(Token, None) def _BuildUserRecord(Username: str, User: dict[str, Any]) -> dict[str, Any]: UserGroups = GetGroupsForUser(Username) if GuestGroupName not in UserGroups: UserGroups = [*UserGroups, GuestGroupName] return { "Username": Username, "IsAdmin": AdminGroupName in UserGroups, "IsGuest": False, "Groups": UserGroups, "Colour": User.get("Colour", "Purple"), } def GetCurrentUser(request: Request) -> dict[str, Any]: Token = request.cookies.get(SessionCookieName) Username = ActiveSessions.get(Token) if Token else None if Username is None: raise HTTPException(status_code=401, detail="Not logged in.") User = GetUser(Username) if User is None: raise HTTPException(status_code=401, detail="Session user no longer exists.") return _BuildUserRecord(Username, User) def GetCurrentUserOrGuest(request: Request) -> dict[str, Any]: Token = request.cookies.get(SessionCookieName) Username = ActiveSessions.get(Token) if Token else None if Username is None: return dict(GuestUser) User = GetUser(Username) if User is None: return dict(GuestUser) return _BuildUserRecord(Username, User) def RequireAdmin(CurrentUser: dict = Depends(GetCurrentUser)) -> dict: if not CurrentUser.get("IsAdmin"): raise HTTPException(status_code=403, detail="Admin access required.") return CurrentUser