95 lines
2.8 KiB
Python
95 lines
2.8 KiB
Python
"""Application user session and permission scaffolding for the warehouse app."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
from datetime import datetime
|
|
from typing import FrozenSet
|
|
|
|
|
|
ALL_ACTIONS: FrozenSet[str] = frozenset(
|
|
{
|
|
"launcher.open_reset_corsie",
|
|
"launcher.open_layout",
|
|
"launcher.open_multi_udc",
|
|
"launcher.open_search",
|
|
"launcher.open_history_udc",
|
|
"launcher.open_pickinglist",
|
|
"launcher.open_history_pickinglist",
|
|
"launcher.arrange_windows",
|
|
"launcher.exit",
|
|
"reset_corsie.view",
|
|
"search.view",
|
|
"history_udc.view",
|
|
"history_pickinglist.view",
|
|
"multi_udc.view",
|
|
"layout.view",
|
|
"layout.carico",
|
|
"layout.scarico",
|
|
"layout.prenota",
|
|
"layout.libera_prenotazione",
|
|
"layout.disabilita_cella",
|
|
"layout.abilita_cella",
|
|
"pickinglist.view",
|
|
"pickinglist.prenota",
|
|
"pickinglist.sprenota",
|
|
}
|
|
)
|
|
|
|
|
|
def build_allowed_actions(_privilegio: int | None) -> FrozenSet[str]:
|
|
"""Return the currently enabled action set for the given operator profile.
|
|
|
|
For this first iteration every authenticated operator can execute every
|
|
function, but the explicit action map already exists so that a future admin
|
|
UI can refine profiles without refactoring the whole application.
|
|
"""
|
|
|
|
return ALL_ACTIONS
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class UserSession:
|
|
"""Minimal in-memory representation of one authenticated application user."""
|
|
|
|
operator_id: int
|
|
login: str
|
|
nominativo: str
|
|
privilegio: int | None = None
|
|
codice_unita: str = ""
|
|
session_started_at: datetime = field(default_factory=datetime.now)
|
|
allowed_actions: FrozenSet[str] = field(default_factory=lambda: ALL_ACTIONS)
|
|
|
|
def can(self, action: str) -> bool:
|
|
"""Return whether the current user can execute one named action."""
|
|
|
|
return action in self.allowed_actions
|
|
|
|
@property
|
|
def display_name(self) -> str:
|
|
"""Return the best human-readable identity for the current session."""
|
|
|
|
if str(self.nominativo or "").strip():
|
|
return str(self.nominativo).strip()
|
|
return str(self.login or "").strip()
|
|
|
|
|
|
def create_user_session(
|
|
*,
|
|
operator_id: int,
|
|
login: str,
|
|
nominativo: str,
|
|
privilegio: int | None,
|
|
codice_unita: str,
|
|
) -> UserSession:
|
|
"""Create one user session with the current default action set."""
|
|
|
|
return UserSession(
|
|
operator_id=int(operator_id),
|
|
login=str(login or "").strip(),
|
|
nominativo=str(nominativo or "").strip(),
|
|
privilegio=int(privilegio) if privilegio is not None else None,
|
|
codice_unita=str(codice_unita or "").strip(),
|
|
allowed_actions=build_allowed_actions(privilegio),
|
|
)
|