215 lines
No EOL
8.7 KiB
Python
215 lines
No EOL
8.7 KiB
Python
"""
|
|
Models for User Service
|
|
"""
|
|
|
|
import uuid
|
|
from pydantic import BaseModel, Field, EmailStr
|
|
from typing import List, Dict, Any, Optional
|
|
from datetime import datetime
|
|
from enum import Enum
|
|
from modules.shared.attributeUtils import register_model_labels, AttributeDefinition, ModelMixin
|
|
|
|
class AuthAuthority(str, Enum):
|
|
"""Authentication authority enum"""
|
|
LOCAL = "local"
|
|
GOOGLE = "google"
|
|
MSFT = "msft"
|
|
|
|
class UserPrivilege(str, Enum):
|
|
"""User privilege levels"""
|
|
SYSADMIN = "sysadmin"
|
|
ADMIN = "admin"
|
|
USER = "user"
|
|
|
|
class ConnectionStatus(str, Enum):
|
|
"""Connection status"""
|
|
ACTIVE = "active"
|
|
EXPIRED = "expired"
|
|
REVOKED = "revoked"
|
|
PENDING = "pending"
|
|
|
|
class Mandate(BaseModel, ModelMixin):
|
|
"""Data model for a mandate"""
|
|
id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Unique ID of the mandate")
|
|
name: str = Field(description="Name of the mandate")
|
|
language: str = Field(default="en", description="Default language of the mandate")
|
|
enabled: bool = Field(default=True, description="Indicates whether the mandate is enabled")
|
|
|
|
# Register labels for Mandate
|
|
register_model_labels(
|
|
"Mandate",
|
|
{"en": "Mandate", "fr": "Mandat"},
|
|
{
|
|
"id": {"en": "ID", "fr": "ID"},
|
|
"name": {"en": "Name", "fr": "Nom"},
|
|
"language": {"en": "Language", "fr": "Langue"},
|
|
"enabled": {"en": "Enabled", "fr": "Activé"}
|
|
}
|
|
)
|
|
|
|
class UserConnection(BaseModel, ModelMixin):
|
|
"""Data model for a user's connection to an external service"""
|
|
id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Unique ID of the connection")
|
|
authority: AuthAuthority = Field(description="Authentication authority")
|
|
externalId: str = Field(description="User ID in the external system")
|
|
externalUsername: str = Field(description="Username in the external system")
|
|
externalEmail: Optional[EmailStr] = Field(None, description="Email in the external system")
|
|
status: ConnectionStatus = Field(default=ConnectionStatus.ACTIVE, description="Connection status")
|
|
connectedAt: datetime = Field(default_factory=datetime.now, description="When the connection was established")
|
|
lastChecked: datetime = Field(default_factory=datetime.now, description="When the connection was last verified")
|
|
expiresAt: Optional[datetime] = Field(None, description="When the connection expires")
|
|
|
|
# Register labels for UserConnection
|
|
register_model_labels(
|
|
"UserConnection",
|
|
{"en": "User Connection", "fr": "Connexion utilisateur"},
|
|
{
|
|
"id": {"en": "ID", "fr": "ID"},
|
|
"authority": {"en": "Authority", "fr": "Autorité"},
|
|
"externalId": {"en": "External ID", "fr": "ID externe"},
|
|
"externalUsername": {"en": "External Username", "fr": "Nom d'utilisateur externe"},
|
|
"externalEmail": {"en": "External Email", "fr": "Email externe"},
|
|
"status": {"en": "Status", "fr": "Statut"},
|
|
"connectedAt": {"en": "Connected At", "fr": "Connecté le"},
|
|
"lastChecked": {"en": "Last Checked", "fr": "Dernière vérification"},
|
|
"expiresAt": {"en": "Expires At", "fr": "Expire le"}
|
|
}
|
|
)
|
|
|
|
class Session(BaseModel, ModelMixin):
|
|
"""Data model for user sessions"""
|
|
id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Unique session ID")
|
|
userId: str = Field(description="ID of the user")
|
|
tokenId: str = Field(description="ID of the associated token")
|
|
lastActivity: datetime = Field(default_factory=datetime.now, description="Last activity timestamp")
|
|
expiresAt: datetime = Field(description="When the session expires")
|
|
ipAddress: Optional[str] = Field(None, description="IP address of the session")
|
|
userAgent: Optional[str] = Field(None, description="User agent of the session")
|
|
|
|
# Register labels for Session
|
|
register_model_labels(
|
|
"Session",
|
|
{"en": "Session", "fr": "Session"},
|
|
{
|
|
"id": {"en": "ID", "fr": "ID"},
|
|
"userId": {"en": "User ID", "fr": "ID utilisateur"},
|
|
"tokenId": {"en": "Token ID", "fr": "ID du token"},
|
|
"lastActivity": {"en": "Last Activity", "fr": "Dernière activité"},
|
|
"expiresAt": {"en": "Expires At", "fr": "Expire le"},
|
|
"ipAddress": {"en": "IP Address", "fr": "Adresse IP"},
|
|
"userAgent": {"en": "User Agent", "fr": "User Agent"}
|
|
}
|
|
)
|
|
|
|
class AuthEvent(BaseModel, ModelMixin):
|
|
"""Data model for authentication events"""
|
|
id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Unique event ID")
|
|
userId: str = Field(description="ID of the user")
|
|
eventType: str = Field(description="Type of event (login, logout, etc.)")
|
|
details: Dict[str, Any] = Field(description="Event details")
|
|
timestamp: datetime = Field(default_factory=datetime.now, description="When the event occurred")
|
|
ipAddress: Optional[str] = Field(None, description="IP address of the event")
|
|
userAgent: Optional[str] = Field(None, description="User agent of the event")
|
|
|
|
# Register labels for AuthEvent
|
|
register_model_labels(
|
|
"AuthEvent",
|
|
{"en": "Auth Event", "fr": "Événement d'authentification"},
|
|
{
|
|
"id": {"en": "ID", "fr": "ID"},
|
|
"userId": {"en": "User ID", "fr": "ID utilisateur"},
|
|
"eventType": {"en": "Event Type", "fr": "Type d'événement"},
|
|
"details": {"en": "Details", "fr": "Détails"},
|
|
"timestamp": {"en": "Timestamp", "fr": "Horodatage"},
|
|
"ipAddress": {"en": "IP Address", "fr": "Adresse IP"},
|
|
"userAgent": {"en": "User Agent", "fr": "User Agent"}
|
|
}
|
|
)
|
|
|
|
class User(BaseModel, ModelMixin):
|
|
"""Data model for a user"""
|
|
id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Unique ID of the user")
|
|
username: str = Field(description="Username for login")
|
|
email: Optional[EmailStr] = Field(None, description="Email address of the user")
|
|
fullName: Optional[str] = Field(None, description="Full name of the user")
|
|
language: str = Field(default="en", description="Preferred language of the user")
|
|
enabled: bool = Field(default=True, description="Indicates whether the user is enabled")
|
|
privilege: UserPrivilege = Field(default=UserPrivilege.USER, description="Permission level")
|
|
authenticationAuthority: AuthAuthority = Field(default=AuthAuthority.LOCAL, description="Primary authentication authority")
|
|
mandateId: Optional[str] = Field(None, description="ID of the mandate this user belongs to")
|
|
connections: List[UserConnection] = Field(default_factory=list, description="List of external service connections")
|
|
|
|
# Register labels for User
|
|
register_model_labels(
|
|
"User",
|
|
{"en": "User", "fr": "Utilisateur"},
|
|
{
|
|
"id": {"en": "ID", "fr": "ID"},
|
|
"username": {"en": "Username", "fr": "Nom d'utilisateur"},
|
|
"email": {"en": "Email", "fr": "Email"},
|
|
"fullName": {"en": "Full Name", "fr": "Nom complet"},
|
|
"language": {"en": "Language", "fr": "Langue"},
|
|
"enabled": {"en": "Enabled", "fr": "Activé"},
|
|
"privilege": {"en": "Privilege", "fr": "Privilège"},
|
|
"authenticationAuthority": {"en": "Auth Authority", "fr": "Autorité d'authentification"},
|
|
"mandateId": {"en": "Mandate ID", "fr": "ID de mandat"},
|
|
"connections": {"en": "Connections", "fr": "Connexions"}
|
|
}
|
|
)
|
|
|
|
class UserInDB(User):
|
|
"""Extended user class with password hash"""
|
|
hashedPassword: Optional[str] = Field(None, description="Hash of the user password")
|
|
|
|
# Register labels for UserInDB
|
|
register_model_labels(
|
|
"UserInDB",
|
|
{"en": "User Access", "fr": "Accès de l'utilisateur"},
|
|
{
|
|
"hashedPassword": {"en": "Password hash", "fr": "Hachage de mot de passe"}
|
|
}
|
|
)
|
|
|
|
# Token Models
|
|
class Token(BaseModel, ModelMixin):
|
|
"""Token model for all authentication types"""
|
|
id: Optional[str] = None
|
|
userId: str
|
|
authority: AuthAuthority
|
|
tokenAccess: str
|
|
tokenType: str = "bearer"
|
|
expiresAt: float
|
|
tokenRefresh: Optional[str] = None
|
|
createdAt: Optional[datetime] = None
|
|
|
|
class Config:
|
|
useEnumValues = True
|
|
|
|
# Register labels for Token
|
|
register_model_labels(
|
|
"Token",
|
|
{"en": "Token", "fr": "Jeton"},
|
|
{
|
|
"id": {"en": "ID", "fr": "ID"},
|
|
"userId": {"en": "User ID", "fr": "ID utilisateur"},
|
|
"authority": {"en": "Authority", "fr": "Autorité"},
|
|
"tokenAccess": {"en": "Access Token", "fr": "Jeton d'accès"},
|
|
"tokenType": {"en": "Token Type", "fr": "Type de jeton"},
|
|
"expiresAt": {"en": "Expires At", "fr": "Expire le"},
|
|
"tokenRefresh": {"en": "Refresh Token", "fr": "Jeton de rafraîchissement"},
|
|
"createdAt": {"en": "Created At", "fr": "Créé le"}
|
|
}
|
|
)
|
|
|
|
class LocalToken(Token):
|
|
"""Local authentication token model"""
|
|
pass
|
|
|
|
class GoogleToken(Token):
|
|
"""Google OAuth token model"""
|
|
pass
|
|
|
|
class MsftToken(Token):
|
|
"""Microsoft OAuth token model"""
|
|
pass
|
|
|