from pydantic import BaseModel from typing import Optional from enum import Enum class Role(str, Enum): sysadmin = "sysadmin" admin = "admin" editor = "editor" user = "user" class SectionPermissions(BaseModel): view: bool = False add: bool = False edit: bool = False delete: bool = False class StaffPermissions(BaseModel): melodies: SectionPermissions = SectionPermissions() devices: SectionPermissions = SectionPermissions() app_users: SectionPermissions = SectionPermissions() equipment: SectionPermissions = SectionPermissions() manufacturing: SectionPermissions = SectionPermissions() mqtt: bool = False # Default permissions per role def default_permissions_for_role(role: str) -> Optional[dict]: if role in ("sysadmin", "admin"): return None # Full access, permissions field not used full = {"view": True, "add": True, "edit": True, "delete": True} view_only = {"view": True, "add": False, "edit": False, "delete": False} if role == "editor": return { "melodies": full, "devices": full, "app_users": full, "equipment": full, "manufacturing": view_only, "mqtt": True, } # user role - view only return { "melodies": view_only, "devices": view_only, "app_users": view_only, "equipment": view_only, "manufacturing": {"view": False, "add": False, "edit": False, "delete": False}, "mqtt": False, } class AdminUserInDB(BaseModel): uid: str email: str hashed_password: str name: str role: Role is_active: bool = True permissions: Optional[StaffPermissions] = None class LoginRequest(BaseModel): email: str password: str class TokenResponse(BaseModel): access_token: str token_type: str = "bearer" role: str name: str permissions: Optional[dict] = None class TokenPayload(BaseModel): sub: str email: str role: str name: str exp: Optional[int] = None