// oidc_handlers.go — OIDC sign-in handlers. Public routes when oidc // is configured (s.deps.OIDC != nil), otherwise not mounted. package http import ( "log/slog" stdhttp "net/http" "time" "gitea.dcglab.co.uk/steve/restic-manager/internal/server/oidc" ) // handleOIDCLogin generates state + PKCE pair, persists them, and // redirects to the IdP authorization endpoint. func (s *Server) handleOIDCLogin(w stdhttp.ResponseWriter, r *stdhttp.Request) { state, err := oidc.RandomState() if err != nil { slog.Error("oidc login: state", "err", err) stdhttp.Error(w, "internal", stdhttp.StatusInternalServerError) return } verifier, challenge, err := oidc.PKCEPair() if err != nil { slog.Error("oidc login: pkce", "err", err) stdhttp.Error(w, "internal", stdhttp.StatusInternalServerError) return } if err := s.deps.Store.PutOIDCState(r.Context(), oidc.HashState(state), verifier, time.Now().UTC()); err != nil { slog.Error("oidc login: persist state", "err", err) stdhttp.Error(w, "internal", stdhttp.StatusInternalServerError) return } stdhttp.Redirect(w, r, s.deps.OIDC.AuthURL(state, challenge), stdhttp.StatusSeeOther) }