Files
2026-02-04 09:28:01 +01:00

154 lines
4.2 KiB
Python

"""
Focolari Voting System - API Routes
"""
import time
from fastapi import APIRouter, HTTPException
from schemas import (
LoginRequest,
EntryRequest,
UserResponse,
RoomInfoResponse,
LoginResponse,
EntryResponse,
)
router = APIRouter()
# Timestamp di avvio del server (per invalidare sessioni frontend)
SERVER_START_TIME = int(time.time() * 1000)
# Dati caricati dinamicamente dal main
_data = {
"validator_password": "",
"room": {"room_name": "", "meeting_id": ""},
"users": []
}
# Caratteri sentinel da pulire (tutti i layout supportati)
SENTINEL_CHARS = [";", "?", "ò", "_", "ç", "+"]
def init_data(data: dict):
"""Inizializza i dati caricati dal file JSON"""
global _data
_data = data
def clean_badge(badge: str) -> str:
"""Rimuove i caratteri sentinel dal badge"""
clean = badge.strip()
for char in SENTINEL_CHARS:
clean = clean.replace(char, "")
return clean
def find_user(badge_code: str) -> dict | None:
"""Cerca un utente per badge code (confronto esatto come stringa)"""
clean = clean_badge(badge_code)
for user in _data["users"]:
# Confronto esatto: il badge è una stringa, non un numero
if user["badge_code"] == clean:
return user
return None
@router.get("/api/info-room", response_model=RoomInfoResponse)
async def get_room_info():
"""Restituisce le informazioni sulla sala e la riunione corrente."""
return RoomInfoResponse(
room_name=_data["room"]["room_name"],
meeting_id=_data["room"]["meeting_id"],
server_start_time=SERVER_START_TIME
)
@router.post("/api/login-validate", response_model=LoginResponse)
async def login_validate(request: LoginRequest):
"""
Valida la password del validatore.
Il badge viene passato dal frontend ma attualmente non viene verificato
lato server - serve solo per essere memorizzato nella sessione frontend.
TODO: Concordare con committenti se il badge debba essere verificato
anche lato server (es. lista badge validatori autorizzati).
"""
if request.password != _data["validator_password"]:
raise HTTPException(
status_code=401,
detail="Password non corretta"
)
# Il badge viene restituito per conferma, ma non è validato lato server
clean = clean_badge(request.badge) if request.badge else "unknown"
return LoginResponse(
success=True,
message="Login validatore effettuato con successo"
)
@router.get("/api/anagrafica/{badge_code}", response_model=UserResponse)
async def get_user_anagrafica(badge_code: str):
"""
Cerca un utente tramite il suo badge code.
"""
user = find_user(badge_code)
if not user:
clean = clean_badge(badge_code)
raise HTTPException(
status_code=404,
detail=f"Utente con badge {clean} non trovato nel sistema"
)
response = UserResponse(
badge_code=user["badge_code"],
nome=user["nome"],
cognome=user["cognome"],
url_foto=user["url_foto"],
ruolo=user["ruolo"],
ammesso=user["ammesso"]
)
if not user["ammesso"]:
response.warning = "ATTENZIONE: Questo utente NON è autorizzato all'ingresso!"
return response
@router.post("/api/entry-request", response_model=EntryResponse)
async def process_entry_request(request: EntryRequest):
"""
Processa una richiesta di ingresso.
Risposta asettica senza messaggi multilingua.
"""
if request.validator_password != _data["validator_password"]:
raise HTTPException(
status_code=401,
detail="Password validatore non corretta"
)
user = find_user(request.user_badge)
if not user:
clean = clean_badge(request.user_badge)
raise HTTPException(
status_code=404,
detail=f"Utente con badge {clean} non trovato"
)
if not user["ammesso"]:
raise HTTPException(
status_code=403,
detail=f"L'utente {user['nome']} {user['cognome']} NON è autorizzato all'ingresso"
)
return EntryResponse(
success=True,
message=f"Ingresso registrato per {user['nome']} {user['cognome']}"
)