Make default permissions use only : as separator.

This commit is contained in:
Leo Vasanko 2025-08-30 18:43:49 -06:00
parent 326a7664d3
commit d045e1c520
6 changed files with 17 additions and 21 deletions

View File

@ -66,7 +66,7 @@ async def bootstrap_system(
dict: Contains information about created entities and reset link
"""
# Create permission first - will fail if already exists
perm0 = Permission(id="auth/admin", display_name="Master Admin")
perm0 = Permission(id="auth:admin", display_name="Master Admin")
await globals.db.instance.create_permission(perm0)
org = Org(uuid7.create(), org_name or "Organization")
@ -122,7 +122,7 @@ async def check_admin_credentials() -> bool:
try:
# Get permission organizations to find admin users
permission_orgs = await globals.db.instance.get_permission_organizations(
"auth/admin"
"auth:admin"
)
if not permission_orgs:
@ -173,7 +173,7 @@ async def bootstrap_if_needed(
"""
try:
# Check if the admin permission exists - if it does, system is already bootstrapped
await globals.db.instance.get_permission("auth/admin")
await globals.db.instance.get_permission("auth:admin")
# Permission exists, system is already bootstrapped
# Check if admin needs credentials (only for already-bootstrapped systems)
await check_admin_credentials()

View File

@ -462,8 +462,7 @@ class DB(DatabaseInterface):
)
# Automatically create an organization admin permission if not present.
# Pattern: auth/org:<org-uuid>
auto_perm_id = f"auth/org:{org.uuid}"
auto_perm_id = f"auth:org:{org.uuid}"
# Only create if it does not already exist (in case caller passed it)
existing_perm = await session.execute(
select(PermissionModel).where(PermissionModel.id == auto_perm_id)

View File

@ -10,7 +10,7 @@ This module contains all the HTTP API endpoints for:
from uuid import UUID, uuid4
from fastapi import Body, Cookie, Depends, FastAPI, HTTPException, Response
from fastapi import Body, Cookie, Depends, FastAPI, HTTPException, Query, Response
from fastapi.security import HTTPBearer
from passkey.util import passphrase
@ -38,14 +38,12 @@ def register_api_routes(app: FastAPI):
raise ValueError("Not authenticated")
role_perm_ids = set(ctx.role.permissions or [])
org_uuid_str = str(ctx.org.uuid)
is_global_admin = "auth/admin" in role_perm_ids
is_org_admin = f"auth/org:{org_uuid_str}" in role_perm_ids
is_global_admin = "auth:admin" in role_perm_ids
is_org_admin = f"auth:org:{org_uuid_str}" in role_perm_ids
return ctx, is_global_admin, is_org_admin
@app.post("/auth/validate")
async def validate_token(
response: Response, perm: list[str] | None = None, auth=Cookie(None)
):
async def validate_token(perm=Query(None), auth=Cookie(None)):
"""Lightweight token validation endpoint.
Query Params:
@ -137,9 +135,9 @@ def register_api_routes(app: FastAPI):
"permissions": ctx.org.permissions,
}
effective_permissions = [p.id for p in (ctx.permissions or [])]
is_global_admin = "auth/admin" in role_info["permissions"]
is_global_admin = "auth:admin" in role_info["permissions"]
is_org_admin = (
f"auth/org:{org_info['uuid']}" in role_info["permissions"]
f"auth:org:{org_info['uuid']}" in role_info["permissions"]
if org_info
else False
)

View File

@ -12,7 +12,7 @@ from ..globals import db
from ..util.tokens import session_key
async def verify(auth: str | None, perms: list[str] | None):
async def verify(auth: str | None, perm: list[str] | str | None):
"""Validate session token and optional list of required permissions.
Returns the Session object on success. Raises HTTPException on failure.
@ -22,14 +22,16 @@ async def verify(auth: str | None, perms: list[str] | None):
if not auth:
raise HTTPException(status_code=401, detail="Authentication required")
session = await get_session(auth)
if perms:
if perm is not None:
if isinstance(perm, str):
perm = [perm]
ctx = await db.instance.get_session_context(session_key(auth))
if not ctx:
raise HTTPException(status_code=401, detail="Session not found")
available = set(ctx.role.permissions or []) | (
set(ctx.org.permissions or []) if ctx.org else set()
)
if any(p not in available for p in perms):
if any(p not in available for p in perm):
raise HTTPException(status_code=403, detail="Permission required")
return session

View File

@ -4,7 +4,7 @@ import os
from contextlib import asynccontextmanager
from pathlib import Path
from fastapi import Cookie, FastAPI, HTTPException, Request, Response
from fastapi import Cookie, FastAPI, HTTPException, Query, Request, Response
from fastapi.responses import FileResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
@ -72,9 +72,7 @@ app.mount("/auth/ws", ws.app)
@app.get("/auth/forward-auth")
async def forward_authentication(
request: Request, perm: list[str] | None = None, auth=Cookie(None)
):
async def forward_authentication(request: Request, perm=Query(None), auth=Cookie(None)):
"""A validation endpoint to use with Caddy forward_auth or Nginx auth_request.
Query Params:

View File

@ -30,5 +30,4 @@ def set_session_cookie(response: Response, token: str) -> None:
max_age=int(EXPIRES.total_seconds()),
httponly=True,
secure=True,
path="/auth/",
)