124 lines
5.8 KiB
Python
124 lines
5.8 KiB
Python
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)
|
|
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)
|