satdetect-dev / app /dda /rbac /models.py
coderuday21's picture
Cursor
Deploy satdetect-dev with Priyanka audit/exception logs.
d70361b
Raw
History Blame Contribute Delete
3.06 kB
"""SQLAlchemy models for the dynamic RBAC system: roles, modules, per-role
module permissions, and the DB-backed nav menu."""
from datetime import datetime, timezone
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, String, Text, UniqueConstraint
from sqlalchemy.orm import relationship
from ...database import Base
def _utcnow():
return datetime.now(timezone.utc)
class Role(Base):
__tablename__ = "dda_roles"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(64), nullable=False, unique=True, index=True)
description = Column(String(255), default="")
rank = Column(Integer, default=0)
# Seeded roles (viewer/uploader/analyst/admin) — protected from deletion
# so the built-in permission gates in dda_auth.py always have a role to
# resolve against.
is_system = Column(Boolean, default=False)
# Roles are never deleted (see rbac/routes.py) — deactivate instead.
# Informational only today, same as Module.status — not yet enforced in
# dda_auth.py/permissions.py.
is_active = Column(Boolean, default=True)
created_at = Column(DateTime, default=_utcnow)
class Module(Base):
__tablename__ = "dda_modules"
id = Column(Integer, primary_key=True, index=True)
key = Column(String(64), nullable=False, unique=True, index=True)
name = Column(String(128), nullable=False)
description = Column(String(255), default="")
status = Column(String(20), default="in_use") # in_use | deprecated
created_at = Column(DateTime, default=_utcnow)
class RolePermission(Base):
__tablename__ = "dda_role_permissions"
__table_args__ = (UniqueConstraint("role_id", "module_id", name="uq_role_module"),)
id = Column(Integer, primary_key=True, index=True)
role_id = Column(Integer, ForeignKey("dda_roles.id"), nullable=False, index=True)
module_id = Column(Integer, ForeignKey("dda_modules.id"), nullable=False, index=True)
can_view = Column(Boolean, default=False)
can_create = Column(Boolean, default=False)
can_edit = Column(Boolean, default=False)
can_delete = Column(Boolean, default=False)
role = relationship("Role")
module = relationship("Module")
class MenuItem(Base):
__tablename__ = "dda_menu_items"
id = Column(Integer, primary_key=True, index=True)
label = Column(String(128), nullable=False)
url = Column(String(255), nullable=False)
module_id = Column(Integer, ForeignKey("dda_modules.id"), nullable=True, index=True)
# Self-referential parent for one level of nesting — unused today (this
# app's nav is flat) but keeps the model ready without a later migration.
parent_id = Column(Integer, ForeignKey("dda_menu_items.id"), nullable=True)
sort_order = Column(Integer, default=0)
icon = Column(String(64), default="")
is_active = Column(Boolean, default=True)
created_at = Column(DateTime, default=_utcnow)
module = relationship("Module")
parent = relationship("MenuItem", remote_side=[id], backref="children")