import datetime as dt import enum from typing import Optional from sqlalchemy import ( Boolean, DateTime, Enum, ForeignKey, Integer, String, Text, UniqueConstraint, ) from sqlalchemy.orm import Mapped, mapped_column from database import Base class ServiceType(str, enum.Enum): WEB = "WEB" VNC = "VNC" RDP = "RDP" class SessionStatus(str, enum.Enum): ACTIVE = "ACTIVE" EXPIRED = "EXPIRED" TERMINATED = "TERMINATED" ROTATED = "ROTATED" class User(Base): __tablename__ = "users" id: Mapped[int] = mapped_column(Integer, primary_key=True) username: Mapped[str] = mapped_column(String(64), unique=True, index=True) password_hash: Mapped[str] = mapped_column(String(255)) expires_at: Mapped[dt.datetime] = mapped_column(DateTime(timezone=True), index=True) active: Mapped[bool] = mapped_column(Boolean, default=True, index=True) is_admin: Mapped[bool] = mapped_column(Boolean, default=False) first_name: Mapped[str] = mapped_column(String(64), default="") last_name: Mapped[str] = mapped_column(String(64), default="") created_at: Mapped[dt.datetime] = mapped_column(DateTime(timezone=True), default=lambda: dt.datetime.now(dt.timezone.utc)) class Service(Base): __tablename__ = "services" id: Mapped[int] = mapped_column(Integer, primary_key=True) name: Mapped[str] = mapped_column(String(128)) slug: Mapped[str] = mapped_column(String(64), unique=True, index=True) type: Mapped[ServiceType] = mapped_column(Enum(ServiceType), index=True) target: Mapped[str] = mapped_column(Text) comment: Mapped[str] = mapped_column(Text, default="") svc_login: Mapped[str] = mapped_column(String(256), default="") svc_password: Mapped[str] = mapped_column(String(256), default="") svc_cred_hint: Mapped[str] = mapped_column(Text, default="") icon_path: Mapped[str] = mapped_column(Text, default="") active: Mapped[bool] = mapped_column(Boolean, default=True) warm_pool_size: Mapped[int] = mapped_column(Integer, default=0) first_name: Mapped[str] = mapped_column(String(64), default="") last_name: Mapped[str] = mapped_column(String(64), default="") created_at: Mapped[dt.datetime] = mapped_column(DateTime(timezone=True), default=lambda: dt.datetime.now(dt.timezone.utc)) class Category(Base): __tablename__ = "categories" id: Mapped[int] = mapped_column(Integer, primary_key=True) name: Mapped[str] = mapped_column(String(128), unique=True, index=True) slug: Mapped[str] = mapped_column(String(64), unique=True, index=True) first_name: Mapped[str] = mapped_column(String(64), default="") last_name: Mapped[str] = mapped_column(String(64), default="") created_at: Mapped[dt.datetime] = mapped_column(DateTime(timezone=True), default=lambda: dt.datetime.now(dt.timezone.utc)) class ServiceCategory(Base): __tablename__ = "service_categories" __table_args__ = (UniqueConstraint("service_id", "category_id", name="uq_service_category"),) id: Mapped[int] = mapped_column(Integer, primary_key=True) service_id: Mapped[int] = mapped_column(ForeignKey("services.id", ondelete="CASCADE"), index=True) category_id: Mapped[int] = mapped_column(ForeignKey("categories.id", ondelete="CASCADE"), index=True) first_name: Mapped[str] = mapped_column(String(64), default="") last_name: Mapped[str] = mapped_column(String(64), default="") created_at: Mapped[dt.datetime] = mapped_column(DateTime(timezone=True), default=lambda: dt.datetime.now(dt.timezone.utc)) class UserServiceAccess(Base): __tablename__ = "user_service_access" __table_args__ = (UniqueConstraint("user_id", "service_id", name="uq_user_service"),) id: Mapped[int] = mapped_column(Integer, primary_key=True) user_id: Mapped[int] = mapped_column(ForeignKey("users.id", ondelete="CASCADE"), index=True) service_id: Mapped[int] = mapped_column(ForeignKey("services.id", ondelete="CASCADE"), index=True) granted_at: Mapped[dt.datetime] = mapped_column(DateTime(timezone=True), default=lambda: dt.datetime.now(dt.timezone.utc)) class RdpSlot(Base): __tablename__ = "rdp_slots" id: Mapped[int] = mapped_column(Integer, primary_key=True) service_id: Mapped[int] = mapped_column(ForeignKey("services.id", ondelete="CASCADE"), index=True) rdp_username: Mapped[str] = mapped_column(String(128)) rdp_password: Mapped[str] = mapped_column(String(256), default="") container_name: Mapped[Optional[str]] = mapped_column(String(128), nullable=True) first_name: Mapped[str] = mapped_column(String(64), default="") last_name: Mapped[str] = mapped_column(String(64), default="") created_at: Mapped[dt.datetime] = mapped_column(DateTime(timezone=True), default=lambda: dt.datetime.now(dt.timezone.utc)) class SessionModel(Base): __tablename__ = "sessions" id: Mapped[str] = mapped_column(String(36), primary_key=True) user_id: Mapped[int] = mapped_column(ForeignKey("users.id", ondelete="CASCADE"), index=True) service_id: Mapped[int] = mapped_column(ForeignKey("services.id", ondelete="CASCADE"), index=True) status: Mapped[SessionStatus] = mapped_column(Enum(SessionStatus), default=SessionStatus.ACTIVE, index=True) created_at: Mapped[dt.datetime] = mapped_column(DateTime(timezone=True), default=lambda: dt.datetime.now(dt.timezone.utc), index=True) last_access_at: Mapped[dt.datetime] = mapped_column(DateTime(timezone=True), default=lambda: dt.datetime.now(dt.timezone.utc), index=True) container_id: Mapped[Optional[str]] = mapped_column(String(128), nullable=True) class AuditLog(Base): __tablename__ = "audit_logs" id: Mapped[int] = mapped_column(Integer, primary_key=True) user_id: Mapped[Optional[int]] = mapped_column(Integer, nullable=True, index=True) action: Mapped[str] = mapped_column(String(128), index=True) details: Mapped[str] = mapped_column(Text) created_at: Mapped[dt.datetime] = mapped_column(DateTime(timezone=True), default=lambda: dt.datetime.now(dt.timezone.utc), index=True)