Fix Bug 3+4+6: permission_version bump, denied_permissions, soft-delete
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import uuid
|
import uuid
|
||||||
|
from datetime import UTC, datetime
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
@@ -20,7 +21,7 @@ class RoleService:
|
|||||||
tenant_id: uuid.UUID,
|
tenant_id: uuid.UUID,
|
||||||
) -> list[dict[str, Any]]:
|
) -> list[dict[str, Any]]:
|
||||||
"""List all roles in a tenant."""
|
"""List all roles in a tenant."""
|
||||||
q = select(Role).where(Role.tenant_id == tenant_id)
|
q = select(Role).where(Role.tenant_id == tenant_id, Role.deleted_at.is_(None))
|
||||||
result = await db.execute(q)
|
result = await db.execute(q)
|
||||||
roles = result.scalars().all()
|
roles = result.scalars().all()
|
||||||
return [self._role_to_dict(r) for r in roles]
|
return [self._role_to_dict(r) for r in roles]
|
||||||
@@ -31,6 +32,7 @@ class RoleService:
|
|||||||
tenant_id: uuid.UUID,
|
tenant_id: uuid.UUID,
|
||||||
name: str,
|
name: str,
|
||||||
permissions: dict[str, Any],
|
permissions: dict[str, Any],
|
||||||
|
denied_permissions: list[str] | None = None,
|
||||||
field_permissions: dict[str, Any] | None = None,
|
field_permissions: dict[str, Any] | None = None,
|
||||||
) -> Role:
|
) -> Role:
|
||||||
"""Create a new custom role."""
|
"""Create a new custom role."""
|
||||||
@@ -38,6 +40,7 @@ class RoleService:
|
|||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
name=name,
|
name=name,
|
||||||
permissions=permissions,
|
permissions=permissions,
|
||||||
|
denied_permissions=denied_permissions or [],
|
||||||
field_permissions=field_permissions or {},
|
field_permissions=field_permissions or {},
|
||||||
)
|
)
|
||||||
db.add(role)
|
db.add(role)
|
||||||
@@ -51,21 +54,35 @@ class RoleService:
|
|||||||
role_id: uuid.UUID,
|
role_id: uuid.UUID,
|
||||||
name: str | None = None,
|
name: str | None = None,
|
||||||
permissions: dict[str, Any] | None = None,
|
permissions: dict[str, Any] | None = None,
|
||||||
|
denied_permissions: list[str] | None = None,
|
||||||
field_permissions: dict[str, Any] | None = None,
|
field_permissions: dict[str, Any] | None = None,
|
||||||
) -> Role | None:
|
) -> Role | None:
|
||||||
"""Update a role."""
|
"""Update a role. Increments permission_version on permission changes."""
|
||||||
q = select(Role).where(Role.id == role_id, Role.tenant_id == tenant_id)
|
q = select(Role).where(
|
||||||
|
Role.id == role_id,
|
||||||
|
Role.tenant_id == tenant_id,
|
||||||
|
Role.deleted_at.is_(None),
|
||||||
|
)
|
||||||
result = await db.execute(q)
|
result = await db.execute(q)
|
||||||
role = result.scalar_one_or_none()
|
role = result.scalar_one_or_none()
|
||||||
if role is None:
|
if role is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
version_bump = False
|
||||||
if name is not None:
|
if name is not None:
|
||||||
role.name = name
|
role.name = name
|
||||||
if permissions is not None:
|
if permissions is not None:
|
||||||
role.permissions = permissions
|
role.permissions = permissions
|
||||||
|
version_bump = True
|
||||||
|
if denied_permissions is not None:
|
||||||
|
role.denied_permissions = denied_permissions
|
||||||
|
version_bump = True
|
||||||
if field_permissions is not None:
|
if field_permissions is not None:
|
||||||
role.field_permissions = field_permissions
|
role.field_permissions = field_permissions
|
||||||
|
version_bump = True
|
||||||
|
|
||||||
|
if version_bump:
|
||||||
|
role.permission_version += 1
|
||||||
|
|
||||||
await db.flush()
|
await db.flush()
|
||||||
return role
|
return role
|
||||||
@@ -76,14 +93,18 @@ class RoleService:
|
|||||||
tenant_id: uuid.UUID,
|
tenant_id: uuid.UUID,
|
||||||
role_id: uuid.UUID,
|
role_id: uuid.UUID,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Delete a role."""
|
"""Soft-delete a role."""
|
||||||
q = select(Role).where(Role.id == role_id, Role.tenant_id == tenant_id)
|
q = select(Role).where(
|
||||||
|
Role.id == role_id,
|
||||||
|
Role.tenant_id == tenant_id,
|
||||||
|
Role.deleted_at.is_(None),
|
||||||
|
)
|
||||||
result = await db.execute(q)
|
result = await db.execute(q)
|
||||||
role = result.scalar_one_or_none()
|
role = result.scalar_one_or_none()
|
||||||
if role is None:
|
if role is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
await db.delete(role)
|
role.deleted_at = datetime.now(UTC)
|
||||||
await db.flush()
|
await db.flush()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -93,7 +114,9 @@ class RoleService:
|
|||||||
"id": str(role.id),
|
"id": str(role.id),
|
||||||
"name": role.name,
|
"name": role.name,
|
||||||
"permissions": role.permissions,
|
"permissions": role.permissions,
|
||||||
|
"denied_permissions": role.denied_permissions,
|
||||||
"field_permissions": role.field_permissions,
|
"field_permissions": role.field_permissions,
|
||||||
|
"permission_version": role.permission_version,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user