sprint14-19: ABAC UI rule editor + permission templates + bulk share + analytics + delegation + resolution strategies + migrations 0056-0058
This commit is contained in:
@@ -715,6 +715,83 @@ async def list_all_permissions(
|
||||
return [_serialize_permission(p, names.get(p.principal_id)) for p in perms]
|
||||
|
||||
|
||||
async def get_permission_analytics(
|
||||
db: AsyncSession,
|
||||
tenant_id: uuid.UUID,
|
||||
) -> dict:
|
||||
"""Get permission analytics for a tenant.
|
||||
|
||||
Returns:
|
||||
total_permissions: Total number of permission entries
|
||||
total_shared_entities: Number of unique entities with permissions
|
||||
permissions_by_level: Breakdown by permission level
|
||||
permissions_by_entity_type: Breakdown by entity type
|
||||
recent_changes: Last 10 permission changes
|
||||
"""
|
||||
from sqlalchemy import func as sa_func
|
||||
|
||||
# Total permissions
|
||||
total_q = await db.execute(
|
||||
select(sa_func.count(EntityPermission.id))
|
||||
.where(EntityPermission.tenant_id == tenant_id)
|
||||
)
|
||||
total_permissions = total_q.scalar() or 0
|
||||
|
||||
# Total unique shared entities
|
||||
unique_q = await db.execute(
|
||||
select(sa_func.count(sa_func.distinct(
|
||||
EntityPermission.entity_type + ":" + EntityPermission.entity_id.cast(String)
|
||||
)))
|
||||
.where(EntityPermission.tenant_id == tenant_id)
|
||||
)
|
||||
total_shared_entities = unique_q.scalar() or 0
|
||||
|
||||
# Permissions by level
|
||||
level_q = await db.execute(
|
||||
select(EntityPermission.permission_level, sa_func.count(EntityPermission.id))
|
||||
.where(EntityPermission.tenant_id == tenant_id)
|
||||
.group_by(EntityPermission.permission_level)
|
||||
)
|
||||
permissions_by_level = {row[0]: row[1] for row in level_q}
|
||||
|
||||
# Permissions by entity type
|
||||
type_q = await db.execute(
|
||||
select(EntityPermission.entity_type, sa_func.count(EntityPermission.id))
|
||||
.where(EntityPermission.tenant_id == tenant_id)
|
||||
.group_by(EntityPermission.entity_type)
|
||||
)
|
||||
permissions_by_entity_type = {row[0]: row[1] for row in type_q}
|
||||
|
||||
# Recent changes (last 10)
|
||||
recent_q = await db.execute(
|
||||
select(EntityPermission)
|
||||
.where(EntityPermission.tenant_id == tenant_id)
|
||||
.order_by(EntityPermission.updated_at.desc())
|
||||
.limit(10)
|
||||
)
|
||||
recent = recent_q.scalars().all()
|
||||
recent_changes = [
|
||||
{
|
||||
"id": str(p.id),
|
||||
"entity_type": p.entity_type,
|
||||
"entity_id": str(p.entity_id),
|
||||
"principal_type": p.principal_type,
|
||||
"principal_id": str(p.principal_id),
|
||||
"permission_level": p.permission_level,
|
||||
"updated_at": p.updated_at.isoformat() if p.updated_at else None,
|
||||
}
|
||||
for p in recent
|
||||
]
|
||||
|
||||
return {
|
||||
"total_permissions": total_permissions,
|
||||
"total_shared_entities": total_shared_entities,
|
||||
"permissions_by_level": permissions_by_level,
|
||||
"permissions_by_entity_type": permissions_by_entity_type,
|
||||
"recent_changes": recent_changes,
|
||||
}
|
||||
|
||||
|
||||
async def cleanup_expired_permissions(db: AsyncSession) -> int:
|
||||
"""Delete all expired permission entries. Returns count deleted."""
|
||||
now = datetime.now(UTC)
|
||||
|
||||
Reference in New Issue
Block a user