feat(flow): unify member-group-permission admin workflow and docs

This commit is contained in:
Chris
2026-03-30 03:54:22 +08:00
parent cc9ad16311
commit 35ffff1d19
6 changed files with 288 additions and 3 deletions

View File

@@ -1,4 +1,4 @@
from sqlalchemy import and_, delete, literal, or_, select
from sqlalchemy import and_, delete, func, literal, or_, select
from sqlalchemy.orm import Session
from app.models.company import Company
@@ -6,6 +6,7 @@ from app.models.module import Module
from app.models.permission_group_member import PermissionGroupMember
from app.models.permission_group_permission import PermissionGroupPermission
from app.models.site import Site
from app.models.user import User
from app.models.user_scope_permission import UserScopePermission
@@ -119,3 +120,101 @@ class PermissionsRepository:
result = self.db.execute(stmt)
self.db.commit()
return int(result.rowcount or 0)
def list_direct_permissions(
self,
*,
keyword: str | None = None,
scope_type: str | None = None,
limit: int = 200,
offset: int = 0,
) -> tuple[list[dict], int]:
stmt = (
select(
UserScopePermission.id,
User.authentik_sub,
User.email,
User.display_name,
UserScopePermission.scope_type,
Company.company_key,
Site.site_key,
Module.module_key,
UserScopePermission.action,
UserScopePermission.created_at,
)
.select_from(UserScopePermission)
.join(User, User.id == UserScopePermission.user_id)
.join(Module, Module.id == UserScopePermission.module_id)
.join(Company, Company.id == UserScopePermission.company_id, isouter=True)
.join(Site, Site.id == UserScopePermission.site_id, isouter=True)
)
count_stmt = (
select(func.count())
.select_from(UserScopePermission)
.join(User, User.id == UserScopePermission.user_id)
.join(Module, Module.id == UserScopePermission.module_id)
.join(Company, Company.id == UserScopePermission.company_id, isouter=True)
.join(Site, Site.id == UserScopePermission.site_id, isouter=True)
)
if scope_type in {"company", "site"}:
stmt = stmt.where(UserScopePermission.scope_type == scope_type)
count_stmt = count_stmt.where(UserScopePermission.scope_type == scope_type)
if keyword:
pattern = f"%{keyword}%"
cond = or_(
User.authentik_sub.ilike(pattern),
User.email.ilike(pattern),
User.display_name.ilike(pattern),
Module.module_key.ilike(pattern),
Company.company_key.ilike(pattern),
Site.site_key.ilike(pattern),
UserScopePermission.action.ilike(pattern),
)
stmt = stmt.where(cond)
count_stmt = count_stmt.where(cond)
stmt = stmt.order_by(UserScopePermission.created_at.desc()).limit(limit).offset(offset)
rows = self.db.execute(stmt).all()
total = int(self.db.scalar(count_stmt) or 0)
items: list[dict] = []
for row in rows:
(
permission_id,
authentik_sub,
email,
display_name,
row_scope_type,
company_key,
site_key,
module_key,
action,
created_at,
) = row
scope_id = company_key if row_scope_type == "company" else site_key
system_key = module_key.split(".", 1)[0] if isinstance(module_key, str) and "." in module_key else None
module_name = module_key.split(".", 1)[1] if isinstance(module_key, str) and "." in module_key else module_key
if module_name == "__system__":
module_name = None
items.append(
{
"permission_id": permission_id,
"authentik_sub": authentik_sub,
"email": email,
"display_name": display_name,
"scope_type": row_scope_type,
"scope_id": scope_id,
"system": system_key,
"module": module_name,
"action": action,
"created_at": created_at,
}
)
return items, total
def revoke_by_permission_id(self, permission_id: str) -> int:
stmt = delete(UserScopePermission).where(UserScopePermission.id == permission_id)
result = self.db.execute(stmt)
self.db.commit()
return int(result.rowcount or 0)