feat(flow): unify member-group-permission admin workflow and docs
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from sqlalchemy import delete, func, select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -16,6 +18,12 @@ class PermissionGroupsRepository:
|
||||
def get_by_id(self, group_id: str) -> PermissionGroup | None:
|
||||
return self.db.scalar(select(PermissionGroup).where(PermissionGroup.id == group_id))
|
||||
|
||||
def get_by_keys(self, group_keys: list[str]) -> list[PermissionGroup]:
|
||||
if not group_keys:
|
||||
return []
|
||||
stmt = select(PermissionGroup).where(PermissionGroup.group_key.in_(group_keys))
|
||||
return list(self.db.scalars(stmt).all())
|
||||
|
||||
def list(self, limit: int = 100, offset: int = 0) -> tuple[list[PermissionGroup], int]:
|
||||
stmt = select(PermissionGroup).order_by(PermissionGroup.created_at.desc()).limit(limit).offset(offset)
|
||||
count_stmt = select(func.count()).select_from(PermissionGroup)
|
||||
@@ -60,6 +68,22 @@ class PermissionGroupsRepository:
|
||||
self.db.commit()
|
||||
return int(result.rowcount or 0)
|
||||
|
||||
def list_group_keys_by_member_sub(self, authentik_sub: str) -> list[str]:
|
||||
stmt = (
|
||||
select(PermissionGroup.group_key)
|
||||
.select_from(PermissionGroupMember)
|
||||
.join(PermissionGroup, PermissionGroup.id == PermissionGroupMember.group_id)
|
||||
.where(PermissionGroupMember.authentik_sub == authentik_sub)
|
||||
.order_by(PermissionGroup.group_key.asc())
|
||||
)
|
||||
return [row[0] for row in self.db.execute(stmt).all()]
|
||||
|
||||
def replace_member_groups(self, authentik_sub: str, group_ids: list[str]) -> None:
|
||||
self.db.execute(delete(PermissionGroupMember).where(PermissionGroupMember.authentik_sub == authentik_sub))
|
||||
for group_id in group_ids:
|
||||
self.db.add(PermissionGroupMember(group_id=group_id, authentik_sub=authentik_sub))
|
||||
self.db.commit()
|
||||
|
||||
def grant_group_permission(
|
||||
self,
|
||||
group_id: str,
|
||||
@@ -93,6 +117,14 @@ class PermissionGroupsRepository:
|
||||
self.db.refresh(row)
|
||||
return row
|
||||
|
||||
def list_group_permissions(self, group_id: str) -> list[PermissionGroupPermission]:
|
||||
stmt = (
|
||||
select(PermissionGroupPermission)
|
||||
.where(PermissionGroupPermission.group_id == group_id)
|
||||
.order_by(PermissionGroupPermission.scope_type.asc(), PermissionGroupPermission.scope_id.asc(), PermissionGroupPermission.system.asc(), PermissionGroupPermission.module.asc(), PermissionGroupPermission.action.asc())
|
||||
)
|
||||
return list(self.db.scalars(stmt).all())
|
||||
|
||||
def revoke_group_permission(
|
||||
self,
|
||||
group_id: str,
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user