sprint14-19: ABAC UI rule editor + permission templates + bulk share + analytics + delegation + resolution strategies + migrations 0056-0058

This commit is contained in:
Agent Zero
2026-07-29 02:47:03 +02:00
parent e0003b9384
commit ddf73ee42e
21 changed files with 2399 additions and 4 deletions
+77
View File
@@ -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)