87 lines
3.1 KiB
Python
87 lines
3.1 KiB
Python
from collections import OrderedDict
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy import delete, select
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.db import get_db
|
|
from app.deps import require_admin
|
|
from app.models import Permission, User
|
|
from app.models.user import role_permissions
|
|
from app.schemas.role import (
|
|
PermissionCreate,
|
|
PermissionGroup,
|
|
PermissionResponse,
|
|
PermissionUpdate,
|
|
)
|
|
from app.services.audit_service import write_audit
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
def _serialize(p: Permission) -> PermissionResponse:
|
|
return PermissionResponse(id=p.id, code=p.code, name=p.name, module=p.module)
|
|
|
|
|
|
@router.get("", response_model=list[PermissionGroup])
|
|
def list_permissions(db: Session = Depends(get_db), _: User = Depends(require_admin)) -> list[PermissionGroup]:
|
|
permissions = db.scalars(select(Permission).order_by(Permission.module, Permission.id)).all()
|
|
grouped: "OrderedDict[str, list[PermissionResponse]]" = OrderedDict()
|
|
for p in permissions:
|
|
grouped.setdefault(p.module or "其他", []).append(_serialize(p))
|
|
return [PermissionGroup(module=m, items=items) for m, items in grouped.items()]
|
|
|
|
|
|
@router.post("", response_model=PermissionResponse)
|
|
def create_permission(
|
|
payload: PermissionCreate,
|
|
db: Session = Depends(get_db),
|
|
admin: User = Depends(require_admin),
|
|
) -> PermissionResponse:
|
|
if db.scalar(select(Permission).where(Permission.code == payload.code)):
|
|
raise HTTPException(status_code=409, detail="权限 code 已存在")
|
|
p = Permission(code=payload.code, name=payload.name, module=payload.module)
|
|
db.add(p)
|
|
db.flush()
|
|
write_audit(db, "permission.create", actor_id=admin.id, target_type="permission", target_id=str(p.id))
|
|
db.commit()
|
|
db.refresh(p)
|
|
return _serialize(p)
|
|
|
|
|
|
@router.patch("/{permission_id}", response_model=PermissionResponse)
|
|
def update_permission(
|
|
permission_id: int,
|
|
payload: PermissionUpdate,
|
|
db: Session = Depends(get_db),
|
|
admin: User = Depends(require_admin),
|
|
) -> PermissionResponse:
|
|
p = db.get(Permission, permission_id)
|
|
if not p:
|
|
raise HTTPException(status_code=404, detail="权限不存在")
|
|
if payload.name is not None:
|
|
p.name = payload.name
|
|
if payload.module is not None:
|
|
p.module = payload.module
|
|
write_audit(db, "permission.update", actor_id=admin.id, target_type="permission", target_id=str(p.id))
|
|
db.commit()
|
|
db.refresh(p)
|
|
return _serialize(p)
|
|
|
|
|
|
@router.delete("/{permission_id}")
|
|
def delete_permission(
|
|
permission_id: int,
|
|
db: Session = Depends(get_db),
|
|
admin: User = Depends(require_admin),
|
|
) -> dict:
|
|
p = db.get(Permission, permission_id)
|
|
if not p:
|
|
raise HTTPException(status_code=404, detail="权限不存在")
|
|
db.execute(delete(role_permissions).where(role_permissions.c.permission_id == permission_id))
|
|
write_audit(db, "permission.delete", actor_id=admin.id, target_type="permission", target_id=str(permission_id),
|
|
detail={"code": p.code, "name": p.name})
|
|
db.delete(p)
|
|
db.commit()
|
|
return {"deleted": True, "id": permission_id}
|