from sqlalchemy import select from sqlalchemy.orm import Session, selectinload from app.models.rbac import Permission, Role from app.schemas.rbac import RoleCreate, RolePermissionUpdate, RoleUpdate class RbacRepository: @staticmethod def get_roles(db: Session) -> list[Role]: return list( db.scalars( select(Role) .options(selectinload(Role.permissions)) .order_by(Role.name) ) ) @staticmethod def get_role_by_id(db: Session, role_id: int) -> Role | None: return db.scalar( select(Role) .where(Role.id == role_id) .options(selectinload(Role.permissions)) ) @staticmethod def get_role_by_name(db: Session, name: str) -> Role | None: return db.scalar( select(Role) .where(Role.name == name) .options(selectinload(Role.permissions)) ) @staticmethod def get_permissions(db: Session) -> list[Permission]: return list(db.scalars(select(Permission).order_by(Permission.module, Permission.name))) @staticmethod def get_permissions_by_ids(db: Session, permission_ids: list[int]) -> list[Permission]: if not permission_ids: return [] return list(db.scalars(select(Permission).where(Permission.id.in_(permission_ids)))) @staticmethod def create_role(db: Session, role: RoleCreate) -> Role: db_role = Role( name=role.name, display_name=role.display_name, description=role.description, is_system=False, ) db_role.permissions = RbacRepository.get_permissions_by_ids(db, role.permission_ids) db.add(db_role) db.commit() db.refresh(db_role) return RbacRepository.get_role_by_id(db, db_role.id) or db_role @staticmethod def update_role(db: Session, db_role: Role, role: RoleUpdate) -> Role: db_role.name = role.name db_role.display_name = role.display_name db_role.description = role.description db_role.permissions = RbacRepository.get_permissions_by_ids(db, role.permission_ids) db.commit() db.refresh(db_role) return RbacRepository.get_role_by_id(db, db_role.id) or db_role @staticmethod def update_role_permissions( db: Session, db_role: Role, permission_update: RolePermissionUpdate, ) -> Role: db_role.permissions = RbacRepository.get_permissions_by_ids( db, permission_update.permission_ids, ) db.commit() db.refresh(db_role) return RbacRepository.get_role_by_id(db, db_role.id) or db_role @staticmethod def delete_role(db: Session, db_role: Role) -> None: db.delete(db_role) db.commit()