llm-ready-data / app /core /auth /models.py
light-infer-chat's picture
ok
08919be
Raw
History Blame Contribute Delete
4.61 kB
from __future__ import annotations
import uuid
from datetime import datetime, timezone
from sqlalchemy import (
Boolean, Column, DateTime, ForeignKey, Integer, String, Text, Table,
)
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
class Base(DeclarativeBase):
pass
def _utcnow() -> datetime:
return datetime.now(timezone.utc)
def _uuid() -> str:
return str(uuid.uuid4())
user_roles = Table(
"user_roles",
Base.metadata,
Column("user_id", String(36), ForeignKey("users.id", ondelete="CASCADE"), primary_key=True),
Column("role_id", String(36), ForeignKey("roles.id", ondelete="CASCADE"), primary_key=True),
)
role_permissions = Table(
"role_permissions",
Base.metadata,
Column("role_id", String(36), ForeignKey("roles.id", ondelete="CASCADE"), primary_key=True),
Column("permission_id", String(36), ForeignKey("permissions.id", ondelete="CASCADE"), primary_key=True),
)
class Permission(Base):
__tablename__ = "permissions"
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=_uuid)
code: Mapped[str] = mapped_column(String(100), unique=True, index=True, nullable=False)
description: Mapped[str | None] = mapped_column(String(255), nullable=True)
roles: Mapped[list[Role]] = relationship(secondary=role_permissions, back_populates="permissions", lazy="selectin")
class Role(Base):
__tablename__ = "roles"
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=_uuid)
name: Mapped[str] = mapped_column(String(50), unique=True, nullable=False)
description: Mapped[str | None] = mapped_column(String(255), nullable=True)
users: Mapped[list[User]] = relationship(secondary=user_roles, back_populates="roles", lazy="selectin")
permissions: Mapped[list[Permission]] = relationship(secondary=role_permissions, back_populates="roles", lazy="selectin")
class User(Base):
__tablename__ = "users"
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=_uuid)
email: Mapped[str] = mapped_column(String(255), unique=True, index=True, nullable=False)
username: Mapped[str | None] = mapped_column(String(50), unique=True, index=True, nullable=True)
full_name: Mapped[str | None] = mapped_column(String(255), nullable=True)
password_hash: Mapped[str] = mapped_column(Text, nullable=False)
is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
is_verified: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
failed_login_attempts: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
locked_until: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
last_login: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
password_changed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow, nullable=False)
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow, onupdate=_utcnow, nullable=False)
deleted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
roles: Mapped[list[Role]] = relationship(secondary=user_roles, back_populates="users", lazy="selectin")
sessions: Mapped[list[RefreshSession]] = relationship(back_populates="user", cascade="all, delete-orphan", lazy="selectin")
class RefreshSession(Base):
__tablename__ = "refresh_sessions"
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=_uuid)
user_id: Mapped[str] = mapped_column(String(36), ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True)
token_key: Mapped[str] = mapped_column(String(64), unique=True, index=True, nullable=False)
token_hash: Mapped[str] = mapped_column(String(255), nullable=False)
device_info: Mapped[str | None] = mapped_column(String(255), nullable=True)
ip_address: Mapped[str | None] = mapped_column(String(45), nullable=True)
expires_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
revoked_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow, nullable=False)
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow, onupdate=_utcnow, nullable=False)
user: Mapped[User] = relationship(back_populates="sessions")