sprint6+7: permission notifications + audit trail + notification entity filter + mail account permissions + migration 0053
Check Cross-Plugin Imports / check (push) Has been cancelled

This commit is contained in:
Agent Zero
2026-07-29 02:18:17 +02:00
parent 71ed592aa2
commit 88c04286af
7 changed files with 240 additions and 64 deletions
+68
View File
@@ -21,6 +21,8 @@ import redis.asyncio as aioredis
from sqlalchemy import and_, func, or_, select, text
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.audit import log_audit
from app.core.notifications import create_notification
from app.models.entity_permission import EntityPermission
from app.models.group import Group, UserGroup
from app.models.role import Role
@@ -129,6 +131,24 @@ async def create_permission(
await db.commit()
await db.refresh(existing)
names = await _load_principal_names(db, [existing])
# Audit log for permission update
await log_audit(
db, tenant_id, created_by,
action='permission_update',
entity_type='entity_permission',
entity_id=existing.id,
changes={'permission_level': permission_level, 'principal_type': principal_type, 'principal_id': principal_id}
)
# Notify user if direct permission
if principal_type == 'user':
await create_notification(
db, tenant_id, principal_uuid,
type='permission_granted',
title='Neue Berechtigung',
body=f'{entity_type} wurde mit dir geteilt',
entity_type=entity_type,
entity_id=entity_uuid,
)
return _serialize_permission(existing, names.get(existing.principal_id))
perm = EntityPermission(
@@ -158,6 +178,25 @@ async def create_permission(
for (uid,) in members_q:
await _invalidate_user_cache(None, tenant_id, uid, entity_type)
# Audit log for new permission
await log_audit(
db, tenant_id, created_by,
action='permission_grant',
entity_type='entity_permission',
entity_id=perm.id,
changes={'permission_level': permission_level, 'principal_type': principal_type, 'principal_id': principal_id}
)
# Notify user if direct permission
if principal_type == 'user':
await create_notification(
db, tenant_id, principal_uuid,
type='permission_granted',
title='Neue Berechtigung',
body=f'{entity_type} wurde mit dir geteilt',
entity_type=entity_type,
entity_id=entity_uuid,
)
names = await _load_principal_names(db, [perm])
return _serialize_permission(perm, names.get(perm.principal_id))
@@ -203,6 +242,15 @@ async def update_permission(
for (uid,) in members_q:
await _invalidate_user_cache(None, tenant_id, uid, old_entity_type)
# Audit log for permission update
await log_audit(
db, tenant_id, None,
action='permission_update',
entity_type='entity_permission',
entity_id=perm.id,
changes={'permission_level': permission_level, 'principal_type': old_principal_type, 'principal_id': str(old_principal_id)}
)
names = await _load_principal_names(db, [perm])
return _serialize_permission(perm, names.get(perm.principal_id))
@@ -224,6 +272,26 @@ async def delete_permission(
old_principal_type = perm.principal_type
old_principal_id = perm.principal_id
old_entity_type = perm.entity_type
old_entity_id = perm.entity_id
# Audit log for permission revoke
await log_audit(
db, tenant_id, None,
action='permission_revoke',
entity_type='entity_permission',
entity_id=perm.id,
changes={'permission_level': perm.permission_level, 'principal_type': old_principal_type, 'principal_id': str(old_principal_id)}
)
# Notify user if direct permission
if old_principal_type == 'user':
await create_notification(
db, tenant_id, old_principal_id,
type='permission_revoked',
title='Berechtigung entfernt',
body=f'{old_entity_type} wurde nicht mehr mit dir geteilt',
entity_type=old_entity_type,
entity_id=old_entity_id,
)
await db.delete(perm)
await db.commit()