Couche pure, sans FastAPI ni session : rôles ordonnés, `Principal`, encodage et décodage des jetons d'accès, empreinte des jetons de rafraîchissement, et hachage Argon2id poussé dans un fil borné. Aucun de ces modules ne lit `get_settings()`, mis en cache par `lru_cache` et donc contaminé entre tests : les paramètres arrivent par `TokenPolicy` et par `build_hasher()`. Argon2id est calibré à m=19456 KiB, t=2, p=1, soit 17 ms mesurés sur un poste de développement.
27 lines
612 B
Python
27 lines
612 B
Python
from enum import StrEnum
|
|
from typing import Final
|
|
|
|
|
|
class Role(StrEnum):
|
|
# Contrainte : ces valeurs voyagent en base, en JSON et dans les jetons. Elles restent
|
|
# en ASCII, contrairement au libellé « opérateur » affiché à l'utilisateur.
|
|
LECTEUR = "lecteur"
|
|
OPERATEUR = "operateur"
|
|
ADMIN = "admin"
|
|
|
|
|
|
class AccountKind(StrEnum):
|
|
HUMAIN = "human"
|
|
SERVICE = "service"
|
|
|
|
|
|
ROLE_RANK: Final[dict[Role, int]] = {
|
|
Role.LECTEUR: 0,
|
|
Role.OPERATEUR: 1,
|
|
Role.ADMIN: 2,
|
|
}
|
|
|
|
|
|
def has_at_least(actual: Role, required: Role) -> bool:
|
|
return ROLE_RANK[actual] >= ROLE_RANK[required]
|