Make default permissions use only : as separator.
This commit is contained in:
parent
326a7664d3
commit
d045e1c520
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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/",
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user