"""RBAC configurable : rĂ´les, permissions et exceptions utilisateur.""" from datetime import datetime, timezone from ...extensions import db def utcnow(): return datetime.now(timezone.utc) class Role(db.Model): __tablename__ = "roles" id = db.Column(db.Integer, primary_key=True) slug = db.Column(db.String(80), nullable=False, unique=True) name = db.Column(db.String(120), nullable=False) description = db.Column(db.Text) is_system = db.Column(db.Boolean, nullable=False, default=False) is_active = db.Column(db.Boolean, nullable=False, default=True) created_at = db.Column(db.DateTime, nullable=False, default=utcnow) updated_at = db.Column(db.DateTime, nullable=False, default=utcnow, onupdate=utcnow) user_links = db.relationship("UserRole", back_populates="role", cascade="all, delete-orphan") permission_links = db.relationship("RolePermission", back_populates="role", cascade="all, delete-orphan") class Permission(db.Model): __tablename__ = "permissions" id = db.Column(db.Integer, primary_key=True) code = db.Column(db.String(120), nullable=False, unique=True) name = db.Column(db.String(160), nullable=False) module = db.Column(db.String(80), nullable=False, index=True) action = db.Column(db.String(40), nullable=False) description = db.Column(db.Text) is_active = db.Column(db.Boolean, nullable=False, default=True) role_links = db.relationship("RolePermission", back_populates="permission", cascade="all, delete-orphan") user_links = db.relationship("UserPermission", back_populates="permission", cascade="all, delete-orphan") class UserRole(db.Model): __tablename__ = "user_roles" __table_args__ = (db.UniqueConstraint("user_id", "role_id", name="uq_user_role"),) id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True) role_id = db.Column(db.Integer, db.ForeignKey("roles.id", ondelete="CASCADE"), nullable=False, index=True) assigned_at = db.Column(db.DateTime, nullable=False, default=utcnow) assigned_by_id = db.Column(db.Integer, db.ForeignKey("users.id", ondelete="SET NULL")) user = db.relationship("User", foreign_keys=[user_id], back_populates="role_links") role = db.relationship("Role", back_populates="user_links") assigned_by = db.relationship("User", foreign_keys=[assigned_by_id]) class RolePermission(db.Model): __tablename__ = "role_permissions" __table_args__ = (db.UniqueConstraint("role_id", "permission_id", name="uq_role_permission"),) id = db.Column(db.Integer, primary_key=True) role_id = db.Column(db.Integer, db.ForeignKey("roles.id", ondelete="CASCADE"), nullable=False, index=True) permission_id = db.Column(db.Integer, db.ForeignKey("permissions.id", ondelete="CASCADE"), nullable=False, index=True) effect = db.Column(db.String(10), nullable=False, default="allow") role = db.relationship("Role", back_populates="permission_links") permission = db.relationship("Permission", back_populates="role_links") class UserPermission(db.Model): __tablename__ = "user_permissions" __table_args__ = (db.UniqueConstraint("user_id", "permission_id", name="uq_user_permission"),) id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True) permission_id = db.Column(db.Integer, db.ForeignKey("permissions.id", ondelete="CASCADE"), nullable=False, index=True) effect = db.Column(db.String(10), nullable=False, default="allow") expires_at = db.Column(db.DateTime) note = db.Column(db.String(255)) user = db.relationship("User", back_populates="permission_links") permission = db.relationship("Permission", back_populates="user_links")