Refer permissions by UUID rather than scope.
This commit is contained in:
@@ -299,13 +299,13 @@ async function performPermissionDeletion(permissionScope) {
|
||||
}
|
||||
|
||||
function deletePermission(p) {
|
||||
const userCount = permissionSummary.value[p.scope]?.userCount || 0
|
||||
const userCount = permissionSummary.value[p.uuid]?.userCount || 0
|
||||
|
||||
// Count roles that have this permission
|
||||
let roleCount = 0
|
||||
for (const org of orgs.value) {
|
||||
for (const role of org.roles) {
|
||||
if (role.permissions.includes(p.scope)) {
|
||||
if (role.permissions.includes(p.uuid)) {
|
||||
roleCount++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,12 @@ const sortedRoles = computed(() => {
|
||||
})
|
||||
})
|
||||
|
||||
// Get org's grantable permissions as full permission objects (with UUIDs)
|
||||
const orgPermissions = computed(() => {
|
||||
const uuidSet = new Set(props.selectedOrg.permissions || [])
|
||||
return props.permissions.filter(p => uuidSet.has(p.uuid))
|
||||
})
|
||||
|
||||
function permissionDisplayName(scope) {
|
||||
return props.permissions.find(p => p.scope === scope)?.display_name || scope
|
||||
}
|
||||
@@ -302,17 +308,17 @@ defineExpose({ focusFirstElement })
|
||||
</div>
|
||||
<div class="grid-head role-head add-role-head" title="Add role" @click="$emit('createRole', selectedOrg)" role="button" tabindex="0" @keydown.enter="$emit('createRole', selectedOrg)">➕</div>
|
||||
|
||||
<template v-for="pid in selectedOrg.permissions" :key="pid">
|
||||
<div class="perm-name" :title="pid">{{ permissionDisplayName(pid) }}</div>
|
||||
<template v-for="p in orgPermissions" :key="p.uuid">
|
||||
<div class="perm-name" :title="p.scope">{{ p.display_name }}</div>
|
||||
<div
|
||||
v-for="r in sortedRoles"
|
||||
:key="r.uuid + '-' + pid"
|
||||
:key="r.uuid + '-' + p.uuid"
|
||||
class="matrix-cell"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="r.permissions.includes(pid)"
|
||||
@change="e => toggleRolePermission(r, pid, e.target.checked)"
|
||||
:checked="r.permissions.includes(p.uuid)"
|
||||
@change="e => toggleRolePermission(r, p.uuid, e.target.checked)"
|
||||
/>
|
||||
</div>
|
||||
<div class="matrix-cell add-role-cell" />
|
||||
|
||||
@@ -296,19 +296,19 @@ defineExpose({ focusFirstElement })
|
||||
<span>{{ o.display_name }}</span>
|
||||
</div>
|
||||
|
||||
<template v-for="p in sortedPermissions" :key="p.scope">
|
||||
<template v-for="p in sortedPermissions" :key="p.uuid">
|
||||
<div class="perm-name" :title="p.scope">
|
||||
<span class="display-text">{{ p.display_name }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-for="o in sortedOrgs"
|
||||
:key="o.uuid + '-' + p.scope"
|
||||
:key="o.uuid + '-' + p.uuid"
|
||||
class="matrix-cell"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="o.permissions.includes(p.scope)"
|
||||
@change="e => $emit('toggleOrgPermission', o, p.scope, e.target.checked)"
|
||||
:checked="o.permissions.includes(p.uuid)"
|
||||
@change="e => $emit('toggleOrgPermission', o, p.uuid, e.target.checked)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -329,7 +329,7 @@ defineExpose({ focusFirstElement })
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="p in sortedPermissions" :key="p.scope">
|
||||
<tr v-for="p in sortedPermissions" :key="p.uuid">
|
||||
<td class="perm-name-cell">
|
||||
<div class="perm-title">
|
||||
<span class="display-text">{{ p.display_name }}</span>
|
||||
@@ -340,7 +340,7 @@ defineExpose({ focusFirstElement })
|
||||
</div>
|
||||
</td>
|
||||
<td class="perm-domain">{{ p.domain || '—' }}</td>
|
||||
<td class="perm-members center">{{ permissionSummary[p.scope]?.userCount || 0 }}</td>
|
||||
<td class="perm-members center">{{ permissionSummary[p.uuid]?.userCount || 0 }}</td>
|
||||
<td class="perm-actions center">
|
||||
<button @click="$emit('deletePermission', p)" class="icon-btn delete-icon" aria-label="Delete permission" title="Delete permission">❌</button>
|
||||
</td>
|
||||
|
||||
+90
-51
@@ -170,14 +170,14 @@ def build_role(uuid: UUID) -> Role:
|
||||
uuid=uuid,
|
||||
org_uuid=r.org,
|
||||
display_name=r.display_name,
|
||||
permissions=list(r.permissions.keys()),
|
||||
permissions=[str(pid) for pid in r.permissions.keys()],
|
||||
)
|
||||
|
||||
|
||||
def build_org(uuid: UUID, include_roles: bool = False) -> Org:
|
||||
o = _db._data.orgs[uuid]
|
||||
perm_scopes = [p.scope for p in _db._data.permissions.values() if uuid in p.orgs]
|
||||
org = Org(uuid=uuid, display_name=o.display_name, permissions=perm_scopes)
|
||||
perm_uuids = [str(pid) for pid, p in _db._data.permissions.items() if uuid in p.orgs]
|
||||
org = Org(uuid=uuid, display_name=o.display_name, permissions=perm_uuids)
|
||||
if include_roles:
|
||||
org.roles = [
|
||||
build_role(rid) for rid, r in _db._data.roles.items() if r.org == uuid
|
||||
@@ -461,24 +461,24 @@ def get_session_context(
|
||||
else None
|
||||
)
|
||||
|
||||
# Effective permissions: role's permission scopes that the org can grant
|
||||
# Effective permissions: role's permissions that the org can grant
|
||||
# Also filter by domain if host is provided
|
||||
org_scopes = set(org.permissions)
|
||||
org_perm_uuids = set(org.permissions) # Set of permission UUID strings
|
||||
normalized_host = normalize_host(host)
|
||||
host_without_port = normalized_host.rsplit(":", 1)[0] if normalized_host else None
|
||||
|
||||
effective_perms = []
|
||||
for scope in role.permissions:
|
||||
if scope not in org_scopes:
|
||||
for perm_uuid_str in role.permissions:
|
||||
if perm_uuid_str not in org_perm_uuids:
|
||||
continue
|
||||
# Find permission by scope
|
||||
for pid, p in _db._data.permissions.items():
|
||||
if p.scope == scope:
|
||||
# Check domain restriction
|
||||
if p.domain is not None and p.domain != host_without_port:
|
||||
continue
|
||||
effective_perms.append(build_permission(pid))
|
||||
break
|
||||
perm_uuid = UUID(perm_uuid_str)
|
||||
if perm_uuid not in _db._data.permissions:
|
||||
continue
|
||||
p = _db._data.permissions[perm_uuid]
|
||||
# Check domain restriction
|
||||
if p.domain is not None and p.domain != host_without_port:
|
||||
continue
|
||||
effective_perms.append(build_permission(perm_uuid))
|
||||
|
||||
return SessionContext(
|
||||
session=session,
|
||||
@@ -527,7 +527,7 @@ def rename_permission(
|
||||
) -> None:
|
||||
"""Rename a permission's scope. The UUID remains the same.
|
||||
|
||||
Also updates all role references to use the new scope.
|
||||
Since roles reference permissions by UUID, no role updates are needed.
|
||||
Note: Scopes do not need to be unique (same scope with different domains is valid).
|
||||
"""
|
||||
# Find permission by old scope
|
||||
@@ -545,21 +545,17 @@ def rename_permission(
|
||||
_db._data.permissions[key].display_name = display_name
|
||||
_db._data.permissions[key].domain = domain
|
||||
|
||||
# Update role references if scope changed
|
||||
if old_scope != new_scope:
|
||||
for r in _db._data.roles.values():
|
||||
if old_scope in r.permissions:
|
||||
del r.permissions[old_scope]
|
||||
r.permissions[new_scope] = True
|
||||
|
||||
|
||||
def delete_permission(uuid: str | UUID, actor: str = "system") -> None:
|
||||
"""Delete a permission."""
|
||||
"""Delete a permission and remove it from all roles."""
|
||||
if isinstance(uuid, str):
|
||||
uuid = UUID(uuid)
|
||||
if uuid not in _db._data.permissions:
|
||||
raise ValueError(f"Permission {uuid} not found")
|
||||
with _db.transaction(actor):
|
||||
# Remove this permission from all roles
|
||||
for role in _db._data.roles.values():
|
||||
role.permissions.pop(uuid, None)
|
||||
del _db._data.permissions[uuid]
|
||||
|
||||
|
||||
@@ -574,19 +570,26 @@ def create_organization(org: Org, actor: str = "system") -> None:
|
||||
_db._data.orgs[org.uuid] = _OrgData(
|
||||
display_name=org.display_name, created_at=datetime.now(timezone.utc)
|
||||
)
|
||||
# Grant listed permissions to this org
|
||||
for scope in org.permissions:
|
||||
for pid, p in _db._data.permissions.items():
|
||||
if p.scope == scope:
|
||||
p.orgs[org.uuid] = True
|
||||
# Grant listed permissions to this org (org.permissions contains UUIDs now)
|
||||
for perm_uuid_str in org.permissions:
|
||||
perm_uuid = UUID(perm_uuid_str) if isinstance(perm_uuid_str, str) else perm_uuid_str
|
||||
if perm_uuid in _db._data.permissions:
|
||||
_db._data.permissions[perm_uuid].orgs[org.uuid] = True
|
||||
# Create Administration role with org admin permission
|
||||
import uuid7
|
||||
|
||||
admin_role_uuid = uuid7.create()
|
||||
# Find the auth:org:admin permission UUID
|
||||
org_admin_perm_uuid = None
|
||||
for pid, p in _db._data.permissions.items():
|
||||
if p.scope == "auth:org:admin":
|
||||
org_admin_perm_uuid = pid
|
||||
break
|
||||
role_permissions = {org_admin_perm_uuid: True} if org_admin_perm_uuid else {}
|
||||
_db._data.roles[admin_role_uuid] = _RoleData(
|
||||
org=org.uuid,
|
||||
display_name="Administration",
|
||||
permissions={"auth:org:admin": True},
|
||||
permissions=role_permissions,
|
||||
)
|
||||
|
||||
|
||||
@@ -624,35 +627,65 @@ def delete_organization(uuid: str | UUID, actor: str = "system") -> None:
|
||||
|
||||
|
||||
def add_permission_to_organization(
|
||||
org_uuid: str | UUID, permission_scope: str, actor: str = "system"
|
||||
org_uuid: str | UUID, permission_id: str | UUID, actor: str = "system"
|
||||
) -> None:
|
||||
"""Grant a permission scope to an organization."""
|
||||
"""Grant a permission to an organization by UUID."""
|
||||
if isinstance(org_uuid, str):
|
||||
org_uuid = UUID(org_uuid)
|
||||
if org_uuid not in _db._data.orgs:
|
||||
raise ValueError(f"Organization {org_uuid} not found")
|
||||
found = False
|
||||
|
||||
# Convert permission_id to UUID
|
||||
if isinstance(permission_id, str):
|
||||
try:
|
||||
permission_uuid = UUID(permission_id)
|
||||
except ValueError:
|
||||
# It's a scope - look up the UUID (backwards compat)
|
||||
for pid, p in _db._data.permissions.items():
|
||||
if p.scope == permission_id:
|
||||
permission_uuid = pid
|
||||
break
|
||||
else:
|
||||
raise ValueError(f"Permission {permission_id} not found")
|
||||
else:
|
||||
permission_uuid = permission_id
|
||||
|
||||
if permission_uuid not in _db._data.permissions:
|
||||
raise ValueError(f"Permission {permission_uuid} not found")
|
||||
|
||||
with _db.transaction(actor):
|
||||
for p in _db._data.permissions.values():
|
||||
if p.scope == permission_scope:
|
||||
p.orgs[org_uuid] = True
|
||||
found = True
|
||||
if not found:
|
||||
raise ValueError(f"Permission scope {permission_scope} not found")
|
||||
_db._data.permissions[permission_uuid].orgs[org_uuid] = True
|
||||
|
||||
|
||||
def remove_permission_from_organization(
|
||||
org_uuid: str | UUID, permission_scope: str, actor: str = "system"
|
||||
org_uuid: str | UUID, permission_id: str | UUID, actor: str = "system"
|
||||
) -> None:
|
||||
"""Remove a permission scope from an organization."""
|
||||
"""Remove a permission from an organization by UUID."""
|
||||
if isinstance(org_uuid, str):
|
||||
org_uuid = UUID(org_uuid)
|
||||
if org_uuid not in _db._data.orgs:
|
||||
raise ValueError(f"Organization {org_uuid} not found")
|
||||
|
||||
# Convert permission_id to UUID
|
||||
if isinstance(permission_id, str):
|
||||
try:
|
||||
permission_uuid = UUID(permission_id)
|
||||
except ValueError:
|
||||
# It's a scope - look up the UUID (backwards compat)
|
||||
for pid, p in _db._data.permissions.items():
|
||||
if p.scope == permission_id:
|
||||
permission_uuid = pid
|
||||
break
|
||||
else:
|
||||
return # Permission not found, silently return
|
||||
else:
|
||||
permission_uuid = permission_id
|
||||
|
||||
if permission_uuid not in _db._data.permissions:
|
||||
return # Permission not found, silently return
|
||||
|
||||
with _db.transaction(actor):
|
||||
for p in _db._data.permissions.values():
|
||||
if p.scope == permission_scope:
|
||||
p.orgs.pop(org_uuid, None)
|
||||
_db._data.permissions[permission_uuid].orgs.pop(org_uuid, None)
|
||||
|
||||
|
||||
def create_role(role: Role, actor: str = "system") -> None:
|
||||
@@ -665,7 +698,7 @@ def create_role(role: Role, actor: str = "system") -> None:
|
||||
_db._data.roles[role.uuid] = _RoleData(
|
||||
org=role.org_uuid,
|
||||
display_name=role.display_name,
|
||||
permissions={scope: True for scope in role.permissions},
|
||||
permissions={UUID(pid): True for pid in role.permissions},
|
||||
)
|
||||
|
||||
|
||||
@@ -682,27 +715,33 @@ def update_role_name(
|
||||
|
||||
|
||||
def add_permission_to_role(
|
||||
role_uuid: str | UUID, permission_scope: str, actor: str = "system"
|
||||
role_uuid: str | UUID, permission_uuid: str | UUID, actor: str = "system"
|
||||
) -> None:
|
||||
"""Add permission scope to role."""
|
||||
"""Add permission to role by UUID."""
|
||||
if isinstance(role_uuid, str):
|
||||
role_uuid = UUID(role_uuid)
|
||||
if isinstance(permission_uuid, str):
|
||||
permission_uuid = UUID(permission_uuid)
|
||||
if role_uuid not in _db._data.roles:
|
||||
raise ValueError(f"Role {role_uuid} not found")
|
||||
if permission_uuid not in _db._data.permissions:
|
||||
raise ValueError(f"Permission {permission_uuid} not found")
|
||||
with _db.transaction(actor):
|
||||
_db._data.roles[role_uuid].permissions[permission_scope] = True
|
||||
_db._data.roles[role_uuid].permissions[permission_uuid] = True
|
||||
|
||||
|
||||
def remove_permission_from_role(
|
||||
role_uuid: str | UUID, permission_scope: str, actor: str = "system"
|
||||
role_uuid: str | UUID, permission_uuid: str | UUID, actor: str = "system"
|
||||
) -> None:
|
||||
"""Remove permission scope from role."""
|
||||
"""Remove permission from role by UUID."""
|
||||
if isinstance(role_uuid, str):
|
||||
role_uuid = UUID(role_uuid)
|
||||
if isinstance(permission_uuid, str):
|
||||
permission_uuid = UUID(permission_uuid)
|
||||
if role_uuid not in _db._data.roles:
|
||||
raise ValueError(f"Role {role_uuid} not found")
|
||||
with _db.transaction(actor):
|
||||
_db._data.roles[role_uuid].permissions.pop(permission_scope, None)
|
||||
_db._data.roles[role_uuid].permissions.pop(permission_uuid, None)
|
||||
|
||||
|
||||
def delete_role(uuid: str | UUID, actor: str = "system") -> None:
|
||||
|
||||
@@ -15,13 +15,13 @@ class Role(msgspec.Struct):
|
||||
uuid: UUID
|
||||
org_uuid: UUID
|
||||
display_name: str
|
||||
permissions: list[str] = [] # permission IDs this role grants
|
||||
permissions: list[str] = [] # permission UUIDs this role grants
|
||||
|
||||
|
||||
class Org(msgspec.Struct):
|
||||
uuid: UUID
|
||||
display_name: str
|
||||
permissions: list[str] = [] # permission IDs this org can grant
|
||||
permissions: list[str] = [] # permission UUIDs this org can grant
|
||||
roles: list[Role] = [] # roles belonging to this org
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ class _OrgData(msgspec.Struct):
|
||||
class _RoleData(msgspec.Struct):
|
||||
org: UUID
|
||||
display_name: str
|
||||
permissions: dict[str, bool] # permission_id -> True
|
||||
permissions: dict[UUID, bool] # permission_uuid -> True
|
||||
|
||||
|
||||
class _UserData(msgspec.Struct):
|
||||
|
||||
+22
-14
@@ -319,11 +319,11 @@ async def admin_update_role_name(
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
@app.post("/orgs/{org_uuid}/roles/{role_uuid}/permissions/{permission_id}")
|
||||
@app.post("/orgs/{org_uuid}/roles/{role_uuid}/permissions/{permission_uuid}")
|
||||
async def admin_add_role_permission(
|
||||
org_uuid: UUID,
|
||||
role_uuid: UUID,
|
||||
permission_id: str,
|
||||
permission_uuid: UUID,
|
||||
request: Request,
|
||||
auth=AUTH_COOKIE,
|
||||
):
|
||||
@@ -344,20 +344,22 @@ async def admin_add_role_permission(
|
||||
raise HTTPException(status_code=404, detail="Role not found in organization")
|
||||
|
||||
# Verify permission exists and org can grant it
|
||||
db.get_permission(permission_id)
|
||||
perm = db.get_permission(permission_uuid)
|
||||
if not perm:
|
||||
raise HTTPException(status_code=404, detail="Permission not found")
|
||||
org = db.get_organization(str(org_uuid))
|
||||
if permission_id not in org.permissions:
|
||||
if str(permission_uuid) not in org.permissions:
|
||||
raise ValueError("Permission not grantable by organization")
|
||||
|
||||
db.add_permission_to_role(role_uuid, permission_id, actor=str(ctx.user.uuid))
|
||||
db.add_permission_to_role(role_uuid, permission_uuid, actor=str(ctx.user.uuid))
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
@app.delete("/orgs/{org_uuid}/roles/{role_uuid}/permissions/{permission_id}")
|
||||
@app.delete("/orgs/{org_uuid}/roles/{role_uuid}/permissions/{permission_uuid}")
|
||||
async def admin_remove_role_permission(
|
||||
org_uuid: UUID,
|
||||
role_uuid: UUID,
|
||||
permission_id: str,
|
||||
permission_uuid: UUID,
|
||||
request: Request,
|
||||
auth=AUTH_COOKIE,
|
||||
):
|
||||
@@ -378,17 +380,23 @@ async def admin_remove_role_permission(
|
||||
raise HTTPException(status_code=404, detail="Role not found in organization")
|
||||
|
||||
# Sanity check: prevent admin from removing their own access
|
||||
# Find auth:admin and auth:org:admin permission UUIDs
|
||||
perm_uuid_str = str(permission_uuid)
|
||||
perm = db.get_permission(permission_uuid)
|
||||
if ctx.org.uuid == org_uuid and ctx.role.uuid == role_uuid:
|
||||
if permission_id in ["auth:admin", "auth:org:admin"]:
|
||||
if perm and perm.scope in ["auth:admin", "auth:org:admin"]:
|
||||
# Check if removing this permission would leave no admin access
|
||||
remaining_perms = set(role.permissions) - {permission_id}
|
||||
if (
|
||||
"auth:admin" not in remaining_perms
|
||||
and "auth:org:admin" not in remaining_perms
|
||||
):
|
||||
remaining_perms = set(role.permissions) - {perm_uuid_str}
|
||||
has_admin = False
|
||||
for rp_uuid in remaining_perms:
|
||||
rp = db.get_permission(rp_uuid)
|
||||
if rp and rp.scope in ["auth:admin", "auth:org:admin"]:
|
||||
has_admin = True
|
||||
break
|
||||
if not has_admin:
|
||||
raise ValueError("Cannot remove your own admin permissions")
|
||||
|
||||
db.remove_permission_from_role(role_uuid, permission_id, actor=str(ctx.user.uuid))
|
||||
db.remove_permission_from_role(role_uuid, permission_uuid, actor=str(ctx.user.uuid))
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
|
||||
+15
-17
@@ -96,19 +96,19 @@ async def migrate_from_sql(
|
||||
orgs={},
|
||||
)
|
||||
|
||||
# Mapping from old permission ID to new scope
|
||||
perm_id_to_scope: dict[str, str] = {}
|
||||
# Mapping from old permission ID to new permission UUID
|
||||
perm_id_to_uuid: dict[str, UUID] = {}
|
||||
|
||||
for perm in permissions:
|
||||
# Skip old org-specific admin permissions (auth:org:{uuid}) - they map to auth:org:admin
|
||||
match = old_org_admin_pattern.match(perm.id)
|
||||
if match:
|
||||
perm_id_to_scope[perm.id] = "auth:org:admin"
|
||||
perm_id_to_uuid[perm.id] = org_admin_perm_uuid
|
||||
continue
|
||||
|
||||
# Skip if this is already auth:org:admin - we created one above
|
||||
if perm.id == "auth:org:admin":
|
||||
perm_id_to_scope[perm.id] = "auth:org:admin"
|
||||
perm_id_to_uuid[perm.id] = org_admin_perm_uuid
|
||||
continue
|
||||
|
||||
# Regular permission - create with UUID key
|
||||
@@ -118,7 +118,7 @@ async def migrate_from_sql(
|
||||
display_name=perm.display_name,
|
||||
orgs={},
|
||||
)
|
||||
perm_id_to_scope[perm.id] = perm.id # Scope same as old ID
|
||||
perm_id_to_uuid[perm.id] = perm_uuid
|
||||
print(
|
||||
f" Migrated {len(permissions)} permissions (with {len(org_admin_uuids)} org-specific admins consolidated to auth:org:admin)"
|
||||
)
|
||||
@@ -130,28 +130,26 @@ async def migrate_from_sql(
|
||||
json_db._data.orgs[org_key] = _OrgData(
|
||||
display_name=org.display_name,
|
||||
)
|
||||
# Update permissions to allow this org to grant them (by scope)
|
||||
# Update permissions to allow this org to grant them (by UUID)
|
||||
for old_perm_id in org.permissions:
|
||||
new_scope = perm_id_to_scope.get(old_perm_id, old_perm_id)
|
||||
# Find permission with this scope and add org
|
||||
for pid, p in json_db._data.permissions.items():
|
||||
if p.scope == new_scope:
|
||||
p.orgs[org_key] = True
|
||||
break
|
||||
perm_uuid = perm_id_to_uuid.get(old_perm_id)
|
||||
if perm_uuid and perm_uuid in json_db._data.permissions:
|
||||
json_db._data.permissions[perm_uuid].orgs[org_key] = True
|
||||
# Ensure every org can grant auth:org:admin
|
||||
json_db._data.permissions[org_admin_perm_uuid].orgs[org_key] = True
|
||||
print(f" Migrated {len(orgs)} organizations")
|
||||
|
||||
# Migrate roles - convert old permission IDs to scopes
|
||||
# Migrate roles - convert old permission IDs to UUIDs
|
||||
role_count = 0
|
||||
for org in orgs:
|
||||
for role in org.roles:
|
||||
role_key: UUID = role.uuid
|
||||
# Convert old permission IDs to scopes
|
||||
new_permissions = {}
|
||||
# Convert old permission IDs to UUIDs
|
||||
new_permissions: dict[UUID, bool] = {}
|
||||
for old_perm_id in role.permissions or []:
|
||||
new_scope = perm_id_to_scope.get(old_perm_id, old_perm_id)
|
||||
new_permissions[new_scope] = True
|
||||
perm_uuid = perm_id_to_uuid.get(old_perm_id)
|
||||
if perm_uuid:
|
||||
new_permissions[perm_uuid] = True
|
||||
json_db._data.roles[role_key] = _RoleData(
|
||||
org=role.org_uuid,
|
||||
display_name=role.display_name,
|
||||
|
||||
Reference in New Issue
Block a user