Commit graph

8 commits

Author SHA1 Message Date
Michael Mayer
656dc31d08 Logging: Report backend internals on the console-only system log
Routes the remaining credential-file, identity-provider, and
database-connection messages through event.System*, as specified in
specs/platform/logging.md: the standard logger is broadcast to the web UI log
viewer and persisted, which is the wrong audience for server paths and
identity-provider details. Covers the database password, OIDC client secret
and provider URI, cluster join token, node client secret, the OIDC
session-signal key, and closing the database connection.

Sanitizes the values these messages interpolate with clean.Log and
clean.Error, raises them from Trace so a real failure stays visible, and
corrects two misleading texts: a cluster join token is reported as invalid
rather than too short, since the format is checked as well, and the JWT
diagnostic labels the value it prints as the token scope.

Adds context and sanitization to the smart album lookup warning in the file
selection query, which logged a bare error with no indication of what failed.
2026-07-25 07:02:17 +00:00
Michael Mayer
a9f7ae32e2 API: Resolve pre-existing gosec and gocritic lint warnings
Suppress gosec false positives with justified //nolint directives and
rewrite an if-else chain as a switch:

- G117: test forms marshaled with a password field to build request bodies
- G124: OIDC session cookie sets HttpOnly/SameSite, Secure is caller-controlled
- G304: OIDC key read from a config-derived path, not user input
- G703: test writes to temp paths under the test's control
- gocritic: OIDC redirect role selection if-else -> switch
2026-07-24 11:26:24 +00:00
Michael Mayer
b88429f557 Cluster: Compact code comments in the OIDC follow-up changes 2026-06-09 10:20:17 +00:00
Michael Mayer
872af5d8fd Cluster: Add cluster OIDC, branded authorize errors, and sign-out
Implements three OIDC follow-ups from specs/portal/cluster-oidc.md:

- Zero-touch instance OIDC RP config: PHOTOPRISM_CLUSTER_OIDC derives the
  OIDC RP client_id/secret from the node client credentials and defaults
  the issuer to the instance's own origin (scheme.OriginURL), so a single
  boot reaches a working Portal login. Explicit oidc-client/secret/uri win.
- Human-friendly authorize errors: redirectable errors 302 back to the
  validated redirect_uri; non-redirectable ones content-negotiate a
  branded HTML page (oauth-error.gohtml) vs JSON via shared helpers in
  internal/api/oauth_error.go. The RP callback surfaces inbound ?error=.
- Cluster-wide Sign-Out (Tier 2): session.logoutEverywhere fans out a
  best-effort DELETE per peer session, clears their storage, then signs
  out locally; session-delete clears the OP cookie on any shared-domain
  OIDC-against-Portal node (OIDCSessionCookieClearPath).
2026-06-09 09:39:01 +00:00
Ömer Duran
3e5522aa80
Auth: Set the OIDC OP session cookie for user sessions only
Skip user-less sessions whose signal NoUser() rejects, warn on the ephemeral key fallback, and keep a manager's delete-by-ref-id from wiping its own OP cookie.
2026-06-05 21:03:38 +02:00
Michael Mayer
368ef7912b Auth: Store a signed session reference in the OP cookie, not the token
The OP session cookie stored the raw bearer token with a full-session lifetime,
so a leak of the cookie value was a usable credential against the whole API. It
now carries an HMAC-signed reference to the session id (a hash of the token,
useless as a bearer) with a 10-minute TTL refreshed on each session GET. The key
is persisted under the Portal config keys directory. The authorize handler
resolves the session via OIDCSessionCookieSession. Needs a coordinated SSO e2e
round in the Portal test env before merge.
2026-06-03 19:15:45 +00:00
Michael Mayer
51c4eed71e Auth: Serve Portal OIDC OP endpoints under /api/v1/oauth/* #4368 #4369
Move the Portal OIDC OP authorize/token/userinfo onto the shared CE
/api/v1/oauth/* routes (the reserved #4368/#4369 stubs) and drop the parallel
root /oauth/* set.

- Add overridable handler hooks (oauth_handlers.go) mirroring
  server.WebDAVHandler; OAuthToken delegates only the authorization_code grant
  (gated on a form content type) and keeps client_credentials/password/session
  unchanged; userinfo now serves GET and POST.
- Scope the OP session cookie to /api/v1/oauth (base-path aware) so the browser
  still sends it to the moved authorize endpoint instead of looping.
- Stop the proxy re-scoping instance->Portal authorize redirects
  (portalRootPathPrefixes -> /api/v1/oauth/).
- Point discovery at issuer + /api/v1/oauth/*; fix the JWKS URL base-path
  doubling for sub-path deployments (also in CE openid.go).
2026-06-03 15:28:05 +00:00
Michael Mayer
62da6ce738 Auth: Add OIDC OP session cookie for top-level navigations 2026-06-03 17:12:59 +02:00