""" User Model Represents users synced from Authentik SSO. """ import uuid from datetime import datetime from typing import TYPE_CHECKING, List from sqlalchemy import String, Boolean, DateTime, func from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column, relationship from src.db.database import Base if TYPE_CHECKING: from src.db.models.role import Role from src.db.models.user_preferences import UserPreferences from src.db.models.api_key import ApiKey class User(Base): """ User model synced from Authentik Users are created/updated when they authenticate via OIDC. The authentik_id links to the Authentik user record. """ __tablename__ = "users" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, ) authentik_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), unique=True, nullable=False, index=True, ) email: Mapped[str] = mapped_column( String(255), unique=True, nullable=False, index=True, ) name: Mapped[str] = mapped_column( String(255), nullable=False, ) avatar_url: Mapped[str | None] = mapped_column( String(500), nullable=True, ) api_keys_enabled: Mapped[bool] = mapped_column( Boolean, default=True, nullable=False, ) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), nullable=False, ) last_login: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True, ) # Relationships roles: Mapped[List["Role"]] = relationship( "Role", secondary="user_roles", back_populates="users", lazy="selectin", ) preferences: Mapped["UserPreferences"] = relationship( "UserPreferences", back_populates="user", uselist=False, lazy="selectin", cascade="all, delete-orphan", ) api_keys: Mapped[List["ApiKey"]] = relationship( "ApiKey", back_populates="user", lazy="selectin", cascade="all, delete-orphan", ) def __repr__(self) -> str: return f""