101 lines
2.7 KiB
Python
101 lines
2.7 KiB
Python
|
|
"""Role management service."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import uuid
|
||
|
|
from typing import Any
|
||
|
|
|
||
|
|
from sqlalchemy import select
|
||
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||
|
|
|
||
|
|
from app.models.role import Role
|
||
|
|
|
||
|
|
|
||
|
|
class RoleService:
|
||
|
|
"""Handles role CRUD operations."""
|
||
|
|
|
||
|
|
async def list_roles(
|
||
|
|
self,
|
||
|
|
db: AsyncSession,
|
||
|
|
tenant_id: uuid.UUID,
|
||
|
|
) -> list[dict[str, Any]]:
|
||
|
|
"""List all roles in a tenant."""
|
||
|
|
q = select(Role).where(Role.tenant_id == tenant_id)
|
||
|
|
result = await db.execute(q)
|
||
|
|
roles = result.scalars().all()
|
||
|
|
return [self._role_to_dict(r) for r in roles]
|
||
|
|
|
||
|
|
async def create_role(
|
||
|
|
self,
|
||
|
|
db: AsyncSession,
|
||
|
|
tenant_id: uuid.UUID,
|
||
|
|
name: str,
|
||
|
|
permissions: dict[str, Any],
|
||
|
|
field_permissions: dict[str, Any] | None = None,
|
||
|
|
) -> Role:
|
||
|
|
"""Create a new custom role."""
|
||
|
|
role = Role(
|
||
|
|
tenant_id=tenant_id,
|
||
|
|
name=name,
|
||
|
|
permissions=permissions,
|
||
|
|
field_permissions=field_permissions or {},
|
||
|
|
)
|
||
|
|
db.add(role)
|
||
|
|
await db.flush()
|
||
|
|
return role
|
||
|
|
|
||
|
|
async def update_role(
|
||
|
|
self,
|
||
|
|
db: AsyncSession,
|
||
|
|
tenant_id: uuid.UUID,
|
||
|
|
role_id: uuid.UUID,
|
||
|
|
name: str | None = None,
|
||
|
|
permissions: dict[str, Any] | None = None,
|
||
|
|
field_permissions: dict[str, Any] | None = None,
|
||
|
|
) -> Role | None:
|
||
|
|
"""Update a role."""
|
||
|
|
q = select(Role).where(Role.id == role_id, Role.tenant_id == tenant_id)
|
||
|
|
result = await db.execute(q)
|
||
|
|
role = result.scalar_one_or_none()
|
||
|
|
if role is None:
|
||
|
|
return None
|
||
|
|
|
||
|
|
if name is not None:
|
||
|
|
role.name = name
|
||
|
|
if permissions is not None:
|
||
|
|
role.permissions = permissions
|
||
|
|
if field_permissions is not None:
|
||
|
|
role.field_permissions = field_permissions
|
||
|
|
|
||
|
|
await db.flush()
|
||
|
|
return role
|
||
|
|
|
||
|
|
async def delete_role(
|
||
|
|
self,
|
||
|
|
db: AsyncSession,
|
||
|
|
tenant_id: uuid.UUID,
|
||
|
|
role_id: uuid.UUID,
|
||
|
|
) -> bool:
|
||
|
|
"""Delete a role."""
|
||
|
|
q = select(Role).where(Role.id == role_id, Role.tenant_id == tenant_id)
|
||
|
|
result = await db.execute(q)
|
||
|
|
role = result.scalar_one_or_none()
|
||
|
|
if role is None:
|
||
|
|
return False
|
||
|
|
|
||
|
|
await db.delete(role)
|
||
|
|
await db.flush()
|
||
|
|
return True
|
||
|
|
|
||
|
|
def _role_to_dict(self, role: Role) -> dict[str, Any]:
|
||
|
|
"""Convert role to response dict."""
|
||
|
|
return {
|
||
|
|
"id": str(role.id),
|
||
|
|
"name": role.name,
|
||
|
|
"permissions": role.permissions,
|
||
|
|
"field_permissions": role.field_permissions,
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
role_service = RoleService()
|