Fixes for public mode authentication flows.

This commit is contained in:
2026-01-31 04:48:44 +00:00
parent 232fd92b22
commit 8f76d770ee
4 changed files with 30 additions and 31 deletions
+6 -1
View File
@@ -95,8 +95,13 @@ async def control(req, ws):
async def watch(req, ws):
# Build user info from either built-in auth or SSO
user_info = None
if sso.paskia_enabled():
# SSO auth: call validation to get user info (don't enforce auth in public mode)
try:
await sso.validate_sso_request(req)
except Exception:
pass # Ignore auth errors, user_info stays None
if sso_user := getattr(req.ctx, "sso_user", None):
# SSO auth (paskia mode): extract from validation response
ctx = sso_user.get("ctx", {})
perms = ctx.get("permissions", [])
user_info = {
+1 -4
View File
@@ -257,10 +257,7 @@ def get_files(wanted: set) -> list[tuple[PurePosixPath, Path]]:
@app.get("/zip/<keys>/<zipfile:ext=zip>")
async def zip_download(req, keys, zipfile, ext):
"""Download a zip archive of the given keys"""
if config.config.authentication == "paskia":
await auth.verify_sso(req)
else:
auth.verify(req)
await auth.verify(req)
wanted = set(keys.split("+"))
files = get_files(wanted)
+8 -11
View File
@@ -236,39 +236,36 @@ async def verify(request, *, privileged=False):
For paskia mode (PASKIA_BACKEND_URL set), validates against the SSO backend.
For built-in mode, checks session-based authentication.
For public mode (config.public=True), allows all requests.
All 401/403 responses include auth.iframe URL for consistent frontend handling
via the paskia library's showAuthIframe().
For public mode (config.public=True), skips auth unless privileged is required.
Args:
request: The Sanic request object
privileged: If True, requires admin privileges
privileged: If True, requires admin privileges (always enforced even in public mode)
Raises:
Unauthorized: If authentication is required
Forbidden: If access is denied
"""
# Public mode: skip auth unless privileged access is required
if config.config.public and not privileged:
return
sso = _get_sso()
if sso.paskia_enabled():
# SSO validation against auth backend
# Always check cista:login; privileged flag comes from response perm list
perm = "cista:admin" if privileged else "cista:login"
await sso.validate_sso_request(request, perm=perm)
return
user = getattr(request.ctx, "user", None)
if privileged:
if user:
if user.privileged:
if user and user.privileged:
return
raise Forbidden(
"Access Forbidden: Only for privileged users",
quiet=True,
)
elif config.config.public or user:
if user:
return
# Return iframe URL for paskia library to show login dialog
raise Unauthorized(
f"Login required for {request.path}",
"cookie",
+3 -3
View File
@@ -94,11 +94,11 @@ const settingsMenu = (e: Event) => {
if (store.user.isLoggedIn) {
items.push({ label: '🚪 Logout', onClick: () => store.logout() })
} else if (!ssoStore.isExternalAuth) {
// Show login in paskia iframe overlay
} else if (store.server.public) {
// Show login option only in public mode (non-public modes trigger auth automatically)
items.push({ label: '🔐 Login', onClick: async () => {
try {
await showAuthIframe('/auth/restricted')
await showAuthIframe('/auth/restricted#theme=light')
resumeWatching()
} catch (e) {
console.log('Login cancelled')