feat(auth): Authentik OIDC sign-in + Gravatar avatars

Adds optional SSO via Authentik (or any OIDC provider) alongside the
existing password flow, and pulls profile images from the provider's
`picture` claim or Gravatar so the sharing UI stops looking anonymous.
Password login stays available as a recovery path; JIT provisioning and
admin-group mapping are env-configurable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-22 21:06:32 +02:00
parent 319be20389
commit e8e1adcf37
20 changed files with 852 additions and 60 deletions

View File

@@ -6,6 +6,7 @@ from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from starlette.middleware.sessions import SessionMiddleware
import logging
import os
@@ -80,6 +81,19 @@ app.add_middleware(
allow_headers=["*"],
)
# Session middleware — only used by Authlib to hold PKCE state during
# the OIDC round-trip. max_age is short because the cookie is only
# meaningful between /auth/oidc/login and /auth/oidc/callback; the app
# itself still runs on JWTs.
app.add_middleware(
SessionMiddleware,
secret_key=settings.effective_session_secret,
session_cookie="mulita_oidc",
max_age=600,
same_site="lax",
https_only=False,
)
# Mount static files for serving thumbnails (with X-Accel-Redirect support)
if os.path.exists("/data/thumbs"):
app.mount("/thumbs", StaticFiles(directory="/data/thumbs"), name="thumbs")