Major refactoring of admin API (permissions, paths)
This commit is contained in:
parent
bfc777fb56
commit
c9f9b28bf4
@ -147,7 +147,7 @@ async function loadOrgs() {
|
||||
if (data.detail) throw new Error(data.detail)
|
||||
// Restructure to attach users to roles instead of flat user list at org level
|
||||
orgs.value = data.map(o => {
|
||||
const roles = o.roles.map(r => ({ ...r, users: [] }))
|
||||
const roles = o.roles.map(r => ({ ...r, org_uuid: o.uuid, users: [] }))
|
||||
const roleMap = Object.fromEntries(roles.map(r => [r.display_name, r]))
|
||||
for (const u of o.users || []) {
|
||||
if (roleMap[u.role]) roleMap[u.role].users.push(u)
|
||||
@ -250,7 +250,7 @@ function updateRole(role) { openDialog('role-update', { role }) }
|
||||
|
||||
function deleteRole(role) {
|
||||
openDialog('confirm', { message: `Delete role ${role.display_name}?`, action: async () => {
|
||||
const res = await fetch(`/auth/admin/roles/${role.uuid}`, { method: 'DELETE' })
|
||||
const res = await fetch(`/auth/admin/orgs/${role.org_uuid}/roles/${role.uuid}`, { method: 'DELETE' })
|
||||
const data = await res.json(); if (data.detail) throw new Error(data.detail)
|
||||
await loadOrgs()
|
||||
} })
|
||||
@ -321,7 +321,7 @@ const pageHeading = computed(() => {
|
||||
watch(selectedUser, async (u) => {
|
||||
if (!u) { userDetail.value = null; return }
|
||||
try {
|
||||
const res = await fetch(`/auth/admin/users/${u.uuid}`)
|
||||
const res = await fetch(`/auth/admin/orgs/${u.org_uuid}/users/${u.uuid}`)
|
||||
const data = await res.json()
|
||||
if (data.detail) throw new Error(data.detail)
|
||||
userDetail.value = data
|
||||
@ -359,7 +359,7 @@ async function toggleRolePermission(role, permId, checked) {
|
||||
const prev = [...role.permissions]
|
||||
role.permissions = next
|
||||
try {
|
||||
const res = await fetch(`/auth/admin/roles/${role.uuid}`, {
|
||||
const res = await fetch(`/auth/admin/orgs/${role.org_uuid}/roles/${role.uuid}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
body: JSON.stringify({ display_name: role.display_name, permissions: next })
|
||||
@ -379,7 +379,7 @@ async function onUserNameSaved() {
|
||||
await loadOrgs()
|
||||
if (selectedUser.value) {
|
||||
try {
|
||||
const r = await fetch(`/auth/admin/users/${selectedUser.value.uuid}`)
|
||||
const r = await fetch(`/auth/admin/orgs/${selectedUser.value.org_uuid}/users/${selectedUser.value.uuid}`)
|
||||
const jd = await r.json()
|
||||
if (!r.ok || jd.detail) throw new Error(jd.detail || 'Reload failed')
|
||||
userDetail.value = jd
|
||||
@ -409,7 +409,7 @@ async function submitDialog() {
|
||||
const { role } = dialog.value.data; const name = dialog.value.data.name?.trim(); if (!name) throw new Error('Name required')
|
||||
const permsCsv = dialog.value.data.perms || ''
|
||||
const perms = permsCsv.split(',').map(s=>s.trim()).filter(Boolean)
|
||||
const res = await fetch(`/auth/admin/roles/${role.uuid}`, { method: 'PUT', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ display_name: name, permissions: perms }) })
|
||||
const res = await fetch(`/auth/admin/orgs/${role.org_uuid}/roles/${role.uuid}`, { method: 'PUT', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ display_name: name, permissions: perms }) })
|
||||
const d = await res.json(); if (d.detail) throw new Error(d.detail); await loadOrgs()
|
||||
} else if (t === 'user-create') {
|
||||
const { org, role } = dialog.value.data; const name = dialog.value.data.name?.trim(); if (!name) throw new Error('Name required')
|
||||
@ -496,7 +496,7 @@ async function submitDialog() {
|
||||
:loading="loading"
|
||||
:org-display-name="userDetail.org.display_name"
|
||||
:role-name="userDetail.role"
|
||||
:update-endpoint="`/auth/admin/users/${selectedUser.uuid}/display-name`"
|
||||
:update-endpoint="`/auth/admin/orgs/${selectedUser.org_uuid}/users/${selectedUser.uuid}/display-name`"
|
||||
@saved="onUserNameSaved"
|
||||
/>
|
||||
<div v-else-if="userDetail?.error" class="error small">{{ userDetail.error }}</div>
|
||||
@ -512,7 +512,7 @@ async function submitDialog() {
|
||||
<p class="matrix-hint muted">Use the token dialog to register a new credential for the member.</p>
|
||||
<RegistrationLinkModal
|
||||
v-if="showRegModal"
|
||||
:endpoint="`/auth/admin/users/${selectedUser.uuid}/create-link`"
|
||||
:endpoint="`/auth/admin/orgs/${selectedUser.org_uuid}/users/${selectedUser.uuid}/create-link`"
|
||||
:auto-copy="false"
|
||||
@close="showRegModal = false"
|
||||
@copied="onLinkCopied"
|
||||
|
@ -8,6 +8,7 @@ from ..authsession import expires
|
||||
from ..globals import db
|
||||
from ..globals import passkey as global_passkey
|
||||
from ..util import frontend, passphrase, permutil, querysafe, tokens
|
||||
from . import authz
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
@ -25,10 +26,11 @@ async def general_exception_handler(_request, exc: Exception):
|
||||
|
||||
@app.get("/")
|
||||
async def admin_frontend(auth=Cookie(None)):
|
||||
ctx = await permutil.session_context(auth)
|
||||
if permutil.has_any(ctx, ["auth:admin", "auth:org:*"]):
|
||||
try:
|
||||
await authz.verify(auth, ["auth:admin", "auth:org:*"], match=permutil.has_any)
|
||||
return FileResponse(frontend.file("admin/index.html"))
|
||||
return FileResponse(frontend.file("index.html"), status_code=401 if ctx else 403)
|
||||
except HTTPException as e:
|
||||
return FileResponse(frontend.file("index.html"), status_code=e.status_code)
|
||||
|
||||
|
||||
# -------------------- Organizations --------------------
|
||||
@ -36,12 +38,10 @@ async def admin_frontend(auth=Cookie(None)):
|
||||
|
||||
@app.get("/orgs")
|
||||
async def admin_list_orgs(auth=Cookie(None)):
|
||||
ctx = await permutil.session_context(auth)
|
||||
if not permutil.has_any(ctx, ["auth:admin", "auth:org:*"]):
|
||||
raise ValueError("Insufficient permissions")
|
||||
ctx = await authz.verify(auth, ["auth:admin", "auth:org:*"], match=permutil.has_any)
|
||||
orgs = await db.instance.list_organizations()
|
||||
if not permutil.has_any(ctx, ["auth:admin"]): # limit org admin to their own org
|
||||
orgs = [o for o in orgs if o.uuid == ctx.org.uuid]
|
||||
if "auth:admin" not in ctx.role.permissions:
|
||||
orgs = [o for o in orgs if f"auth:org:{o.uuid}" in ctx.role.permissions]
|
||||
|
||||
def role_to_dict(r):
|
||||
return {
|
||||
@ -75,9 +75,7 @@ async def admin_list_orgs(auth=Cookie(None)):
|
||||
|
||||
@app.post("/orgs")
|
||||
async def admin_create_org(payload: dict = Body(...), auth=Cookie(None)):
|
||||
ctx = await permutil.session_context(auth)
|
||||
if not permutil.has_any(ctx, ["auth:admin"]):
|
||||
raise ValueError("Global admin required")
|
||||
await authz.verify(auth, ["auth:admin"])
|
||||
from ..db import Org as OrgDC # local import to avoid cycles
|
||||
|
||||
org_uuid = uuid4()
|
||||
@ -92,9 +90,9 @@ async def admin_create_org(payload: dict = Body(...), auth=Cookie(None)):
|
||||
async def admin_update_org(
|
||||
org_uuid: UUID, payload: dict = Body(...), auth=Cookie(None)
|
||||
):
|
||||
ctx = await permutil.session_context(auth)
|
||||
if not permutil.has_any(ctx, ["auth:admin"]):
|
||||
raise ValueError("Global admin required")
|
||||
await authz.verify(
|
||||
auth, ["auth:admin", f"auth:org:{org_uuid}"], match=permutil.has_any
|
||||
)
|
||||
from ..db import Org as OrgDC # local import to avoid cycles
|
||||
|
||||
current = await db.instance.get_organization(str(org_uuid))
|
||||
@ -107,14 +105,10 @@ async def admin_update_org(
|
||||
|
||||
@app.delete("/orgs/{org_uuid}")
|
||||
async def admin_delete_org(org_uuid: UUID, auth=Cookie(None)):
|
||||
ctx = await permutil.session_context(auth)
|
||||
if not permutil.has_any(ctx, ["auth:admin"]):
|
||||
raise ValueError("Global admin required")
|
||||
try:
|
||||
acting_org_uuid = ctx.org.uuid if ctx.org else None
|
||||
except Exception: # pragma: no cover - defensive
|
||||
acting_org_uuid = None
|
||||
if acting_org_uuid and acting_org_uuid == org_uuid:
|
||||
ctx = await authz.verify(
|
||||
auth, ["auth:admin", f"auth:org:{org_uuid}"], match=permutil.has_any
|
||||
)
|
||||
if ctx.org.uuid == org_uuid:
|
||||
raise ValueError("Cannot delete the organization you belong to")
|
||||
await db.instance.delete_organization(org_uuid)
|
||||
return {"status": "ok"}
|
||||
@ -124,15 +118,7 @@ async def admin_delete_org(org_uuid: UUID, auth=Cookie(None)):
|
||||
async def admin_add_org_permission(
|
||||
org_uuid: UUID, permission_id: str, auth=Cookie(None)
|
||||
):
|
||||
ctx = await permutil.session_context(auth)
|
||||
if not (
|
||||
permutil.has_any(ctx, ["auth:admin"])
|
||||
or (
|
||||
permutil.has_any(ctx, [f"auth:org:{org_uuid}"]) and ctx.org.uuid == org_uuid
|
||||
)
|
||||
):
|
||||
raise ValueError("Insufficient permissions")
|
||||
querysafe.assert_safe(permission_id, field="permission_id")
|
||||
await authz.verify(auth, ["auth:admin"])
|
||||
await db.instance.add_permission_to_organization(str(org_uuid), permission_id)
|
||||
return {"status": "ok"}
|
||||
|
||||
@ -141,16 +127,7 @@ async def admin_add_org_permission(
|
||||
async def admin_remove_org_permission(
|
||||
org_uuid: UUID, permission_id: str, auth=Cookie(None)
|
||||
):
|
||||
ctx = await permutil.session_context(auth)
|
||||
if not ctx or not (
|
||||
permutil.has_any(ctx, ["auth:admin"])
|
||||
or (
|
||||
permutil.has_any(ctx, [f"auth:org:{org_uuid}"])
|
||||
and getattr(ctx.org, "uuid", None) == org_uuid
|
||||
)
|
||||
):
|
||||
raise ValueError("Insufficient permissions")
|
||||
querysafe.assert_safe(permission_id, field="permission_id")
|
||||
await authz.verify(auth, ["auth:admin"])
|
||||
await db.instance.remove_permission_from_organization(str(org_uuid), permission_id)
|
||||
return {"status": "ok"}
|
||||
|
||||
@ -162,15 +139,7 @@ async def admin_remove_org_permission(
|
||||
async def admin_create_role(
|
||||
org_uuid: UUID, payload: dict = Body(...), auth=Cookie(None)
|
||||
):
|
||||
ctx = await permutil.session_context(auth)
|
||||
if not ctx or not (
|
||||
permutil.has_any(ctx, ["auth:admin"])
|
||||
or (
|
||||
permutil.has_any(ctx, [f"auth:org:{org_uuid}"])
|
||||
and getattr(ctx.org, "uuid", None) == org_uuid
|
||||
)
|
||||
):
|
||||
raise ValueError("Insufficient permissions")
|
||||
await authz.verify(auth, ["auth:admin", f"auth:org:{org_uuid}"])
|
||||
from ..db import Role as RoleDC
|
||||
|
||||
role_uuid = uuid4()
|
||||
@ -192,25 +161,22 @@ async def admin_create_role(
|
||||
return {"uuid": str(role_uuid)}
|
||||
|
||||
|
||||
@app.put("/roles/{role_uuid}")
|
||||
@app.put("/orgs/{org_uuid}/roles/{role_uuid}")
|
||||
async def admin_update_role(
|
||||
role_uuid: UUID, payload: dict = Body(...), auth=Cookie(None)
|
||||
org_uuid: UUID, role_uuid: UUID, payload: dict = Body(...), auth=Cookie(None)
|
||||
):
|
||||
ctx = await permutil.session_context(auth)
|
||||
role = await db.instance.get_role(role_uuid)
|
||||
if not ctx or not (
|
||||
permutil.has_any(ctx, ["auth:admin"])
|
||||
or (
|
||||
permutil.has_any(ctx, [f"auth:org:{role.org_uuid}"])
|
||||
and getattr(ctx.org, "uuid", None) == role.org_uuid
|
||||
# Verify caller is global admin or admin of provided org
|
||||
await authz.verify(
|
||||
auth, ["auth:admin", f"auth:org:{org_uuid}"], match=permutil.has_any
|
||||
)
|
||||
):
|
||||
raise ValueError("Insufficient permissions")
|
||||
role = await db.instance.get_role(role_uuid)
|
||||
if role.org_uuid != org_uuid:
|
||||
raise HTTPException(status_code=404, detail="Role not found in organization")
|
||||
from ..db import Role as RoleDC
|
||||
|
||||
display_name = payload.get("display_name") or role.display_name
|
||||
permissions = payload.get("permissions") or role.permissions
|
||||
org = await db.instance.get_organization(str(role.org_uuid))
|
||||
org = await db.instance.get_organization(str(org_uuid))
|
||||
grantable = set(org.permissions or [])
|
||||
for pid in permissions:
|
||||
await db.instance.get_permission(pid)
|
||||
@ -218,7 +184,7 @@ async def admin_update_role(
|
||||
raise ValueError(f"Permission not grantable by org: {pid}")
|
||||
updated = RoleDC(
|
||||
uuid=role_uuid,
|
||||
org_uuid=role.org_uuid,
|
||||
org_uuid=org_uuid,
|
||||
display_name=display_name,
|
||||
permissions=permissions,
|
||||
)
|
||||
@ -226,18 +192,14 @@ async def admin_update_role(
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
@app.delete("/roles/{role_uuid}")
|
||||
async def admin_delete_role(role_uuid: UUID, auth=Cookie(None)):
|
||||
ctx = await permutil.session_context(auth)
|
||||
role = await db.instance.get_role(role_uuid)
|
||||
if not ctx or not (
|
||||
permutil.has_any(ctx, ["auth:admin"])
|
||||
or (
|
||||
permutil.has_any(ctx, [f"auth:org:{role.org_uuid}"])
|
||||
and getattr(ctx.org, "uuid", None) == role.org_uuid
|
||||
@app.delete("/orgs/{org_uuid}/roles/{role_uuid}")
|
||||
async def admin_delete_role(org_uuid: UUID, role_uuid: UUID, auth=Cookie(None)):
|
||||
await authz.verify(
|
||||
auth, ["auth:admin", f"auth:org:{org_uuid}"], match=permutil.has_any
|
||||
)
|
||||
):
|
||||
raise ValueError("Insufficient permissions")
|
||||
role = await db.instance.get_role(role_uuid)
|
||||
if role.org_uuid != org_uuid:
|
||||
raise HTTPException(status_code=404, detail="Role not found in organization")
|
||||
await db.instance.delete_role(role_uuid)
|
||||
return {"status": "ok"}
|
||||
|
||||
@ -249,15 +211,9 @@ async def admin_delete_role(role_uuid: UUID, auth=Cookie(None)):
|
||||
async def admin_create_user(
|
||||
org_uuid: UUID, payload: dict = Body(...), auth=Cookie(None)
|
||||
):
|
||||
ctx = await permutil.session_context(auth)
|
||||
if not ctx or not (
|
||||
permutil.has_any(ctx, ["auth:admin"])
|
||||
or (
|
||||
permutil.has_any(ctx, [f"auth:org:{org_uuid}"])
|
||||
and getattr(ctx.org, "uuid", None) == org_uuid
|
||||
await authz.verify(
|
||||
auth, ["auth:admin", f"auth:org:{org_uuid}"], match=permutil.has_any
|
||||
)
|
||||
):
|
||||
raise ValueError("Insufficient permissions")
|
||||
display_name = payload.get("display_name")
|
||||
role_name = payload.get("role")
|
||||
if not display_name or not role_name:
|
||||
@ -284,15 +240,9 @@ async def admin_create_user(
|
||||
async def admin_update_user_role(
|
||||
org_uuid: UUID, user_uuid: UUID, payload: dict = Body(...), auth=Cookie(None)
|
||||
):
|
||||
ctx = await permutil.session_context(auth)
|
||||
if not ctx or not (
|
||||
permutil.has_any(ctx, ["auth:admin"])
|
||||
or (
|
||||
permutil.has_any(ctx, [f"auth:org:{org_uuid}"])
|
||||
and getattr(ctx.org, "uuid", None) == org_uuid
|
||||
await authz.verify(
|
||||
auth, ["auth:admin", f"auth:org:{org_uuid}"], match=permutil.has_any
|
||||
)
|
||||
):
|
||||
raise ValueError("Insufficient permissions")
|
||||
new_role = payload.get("role")
|
||||
if not new_role:
|
||||
raise ValueError("role is required")
|
||||
@ -309,19 +259,22 @@ async def admin_update_user_role(
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
@app.post("/users/{user_uuid}/create-link")
|
||||
async def admin_create_user_registration_link(user_uuid: UUID, auth=Cookie(None)):
|
||||
ctx = await permutil.session_context(auth)
|
||||
@app.post("/orgs/{org_uuid}/users/{user_uuid}/create-link")
|
||||
async def admin_create_user_registration_link(
|
||||
org_uuid: UUID, user_uuid: UUID, auth=Cookie(None)
|
||||
):
|
||||
try:
|
||||
user_org, _role_name = await db.instance.get_user_organization(user_uuid)
|
||||
except ValueError:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
if not ctx or not (
|
||||
permutil.has_any(ctx, ["auth:admin"])
|
||||
or (
|
||||
permutil.has_any(ctx, [f"auth:org:{user_org.uuid}"])
|
||||
and getattr(ctx.org, "uuid", None) == user_org.uuid
|
||||
if user_org.uuid != org_uuid:
|
||||
raise HTTPException(status_code=404, detail="User not found in organization")
|
||||
ctx = await authz.verify(
|
||||
auth, ["auth:admin", f"auth:org:{org_uuid}"], match=permutil.has_any
|
||||
)
|
||||
if (
|
||||
"auth:admin" not in ctx.role.permissions
|
||||
and f"auth:org:{org_uuid}" not in ctx.role.permissions
|
||||
):
|
||||
raise HTTPException(status_code=403, detail="Insufficient permissions")
|
||||
token = passphrase.generate()
|
||||
@ -336,19 +289,20 @@ async def admin_create_user_registration_link(user_uuid: UUID, auth=Cookie(None)
|
||||
return {"url": url, "expires": expires().isoformat()}
|
||||
|
||||
|
||||
@app.get("/users/{user_uuid}")
|
||||
async def admin_get_user_detail(user_uuid: UUID, auth=Cookie(None)):
|
||||
ctx = await permutil.session_context(auth)
|
||||
@app.get("/orgs/{org_uuid}/users/{user_uuid}")
|
||||
async def admin_get_user_detail(org_uuid: UUID, user_uuid: UUID, auth=Cookie(None)):
|
||||
try:
|
||||
user_org, role_name = await db.instance.get_user_organization(user_uuid)
|
||||
except ValueError:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
if not ctx or not (
|
||||
permutil.has_any(ctx, ["auth:admin"])
|
||||
or (
|
||||
permutil.has_any(ctx, [f"auth:org:{user_org.uuid}"])
|
||||
and getattr(ctx.org, "uuid", None) == user_org.uuid
|
||||
if user_org.uuid != org_uuid:
|
||||
raise HTTPException(status_code=404, detail="User not found in organization")
|
||||
ctx = await authz.verify(
|
||||
auth, ["auth:admin", f"auth:org:{org_uuid}"], match=permutil.has_any
|
||||
)
|
||||
if (
|
||||
"auth:admin" not in ctx.role.permissions
|
||||
and f"auth:org:{org_uuid}" not in ctx.role.permissions
|
||||
):
|
||||
raise HTTPException(status_code=403, detail="Insufficient permissions")
|
||||
user = await db.instance.get_user_by_uuid(user_uuid)
|
||||
@ -389,21 +343,22 @@ async def admin_get_user_detail(user_uuid: UUID, auth=Cookie(None)):
|
||||
}
|
||||
|
||||
|
||||
@app.put("/users/{user_uuid}/display-name")
|
||||
@app.put("/orgs/{org_uuid}/users/{user_uuid}/display-name")
|
||||
async def admin_update_user_display_name(
|
||||
user_uuid: UUID, payload: dict = Body(...), auth=Cookie(None)
|
||||
org_uuid: UUID, user_uuid: UUID, payload: dict = Body(...), auth=Cookie(None)
|
||||
):
|
||||
ctx = await permutil.session_context(auth)
|
||||
try:
|
||||
user_org, _role_name = await db.instance.get_user_organization(user_uuid)
|
||||
except ValueError:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
if not ctx or not (
|
||||
permutil.has_any(ctx, ["auth:admin"])
|
||||
or (
|
||||
permutil.has_any(ctx, [f"auth:org:{user_org.uuid}"])
|
||||
and getattr(ctx.org, "uuid", None) == user_org.uuid
|
||||
if user_org.uuid != org_uuid:
|
||||
raise HTTPException(status_code=404, detail="User not found in organization")
|
||||
ctx = await authz.verify(
|
||||
auth, ["auth:admin", f"auth:org:{org_uuid}"], match=permutil.has_any
|
||||
)
|
||||
if (
|
||||
"auth:admin" not in ctx.role.permissions
|
||||
and f"auth:org:{org_uuid}" not in ctx.role.permissions
|
||||
):
|
||||
raise HTTPException(status_code=403, detail="Insufficient permissions")
|
||||
new_name = (payload.get("display_name") or "").strip()
|
||||
@ -420,18 +375,14 @@ async def admin_update_user_display_name(
|
||||
|
||||
@app.get("/permissions")
|
||||
async def admin_list_permissions(auth=Cookie(None)):
|
||||
ctx = await permutil.session_context(auth)
|
||||
if not ctx or not permutil.has_any(ctx, ["auth:admin", "auth:org:*"]):
|
||||
raise ValueError("Insufficient permissions")
|
||||
await authz.verify(auth, ["auth:admin"], match=permutil.has_any)
|
||||
perms = await db.instance.list_permissions()
|
||||
return [{"id": p.id, "display_name": p.display_name} for p in perms]
|
||||
|
||||
|
||||
@app.post("/permissions")
|
||||
async def admin_create_permission(payload: dict = Body(...), auth=Cookie(None)):
|
||||
ctx = await permutil.session_context(auth)
|
||||
if not ctx or not permutil.has_any(ctx, ["auth:admin"]):
|
||||
raise ValueError("Global admin required")
|
||||
await authz.verify(auth, ["auth:admin"])
|
||||
from ..db import Permission as PermDC
|
||||
|
||||
perm_id = payload.get("id")
|
||||
@ -447,9 +398,7 @@ async def admin_create_permission(payload: dict = Body(...), auth=Cookie(None)):
|
||||
async def admin_update_permission(
|
||||
permission_id: str, display_name: str, auth=Cookie(None)
|
||||
):
|
||||
ctx = await permutil.session_context(auth)
|
||||
if not ctx or not permutil.has_any(ctx, ["auth:admin"]):
|
||||
raise ValueError("Global admin required")
|
||||
await authz.verify(auth, ["auth:admin"])
|
||||
from ..db import Permission as PermDC
|
||||
|
||||
if not display_name:
|
||||
@ -463,9 +412,7 @@ async def admin_update_permission(
|
||||
|
||||
@app.post("/permission/rename")
|
||||
async def admin_rename_permission(payload: dict = Body(...), auth=Cookie(None)):
|
||||
ctx = await permutil.session_context(auth)
|
||||
if not ctx or not permutil.has_any(ctx, ["auth:admin"]):
|
||||
raise ValueError("Global admin required")
|
||||
await authz.verify(auth, ["auth:admin"])
|
||||
old_id = payload.get("old_id")
|
||||
new_id = payload.get("new_id")
|
||||
display_name = payload.get("display_name")
|
||||
@ -485,9 +432,7 @@ async def admin_rename_permission(payload: dict = Body(...), auth=Cookie(None)):
|
||||
|
||||
@app.delete("/permission")
|
||||
async def admin_delete_permission(permission_id: str, auth=Cookie(None)):
|
||||
ctx = await permutil.session_context(auth)
|
||||
if not ctx or not permutil.has_any(ctx, ["auth:admin"]):
|
||||
raise ValueError("Global admin required")
|
||||
await authz.verify(auth, ["auth:admin"])
|
||||
querysafe.assert_safe(permission_id, field="permission_id")
|
||||
await db.instance.delete_permission(permission_id)
|
||||
return {"status": "ok"}
|
||||
|
Loading…
x
Reference in New Issue
Block a user