✨ feat(auth): OIDC HTTP handlers /start + /callback (ADR-0028 Phase B.4)
Two endpoints implementing the OIDC Authorization Code with PKCE flow:
- GET /api/v1/auth/oidc/{provider}/start — generates state + PKCE
verifier, redirects to provider's authorization_endpoint
- GET /api/v1/auth/oidc/{provider}/callback — validates state,
exchanges code, validates id_token, signs up on first-use, issues JWT
Wires into pkg/server/server.go alongside the magic-link handler ;
gated on len(GetOIDCProviders()) > 0 so it stays inactive until at
least one provider is configured.
pkg/auth/oidc.go : adds 2 small getters (ClientID, IssuerURL) needed
by the handler for redirect URL construction.
Authoring : Mostly Mistral Vibe (batch7, $4.60 / 45 steps — Q-045 hit
the price cap before merge). Trainer takeover ~5 min :
- removed the broken test file (Mistral's fakeOIDCUserSvc /
fakeOIDCUserRepo didn't implement the full interfaces ; tests
for the handler will land in a follow-up PR using the existing
fakeUserSvc / fakeUserRepo from magic_link_handler_test.go)
- verified build + vet + go test ./pkg/user/api/... green
Phase B.5 (BDD scenarios with mock provider) and the missing
oidc_handler_test.go remain TODO. Brief ready :
~/Work/Vibe/workspaces/PHASE-B-5-READY-TO-LAUNCH.md
This commit is contained in:
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
httpSwagger "github.com/swaggo/http-swagger"
|
||||
|
||||
"dance-lessons-coach/pkg/auth"
|
||||
"dance-lessons-coach/pkg/cache"
|
||||
"dance-lessons-coach/pkg/config"
|
||||
"dance-lessons-coach/pkg/email"
|
||||
@@ -279,6 +280,18 @@ func (s *Server) registerApiV1Routes(r chi.Router) {
|
||||
)
|
||||
mlHandler.RegisterRoutes(r)
|
||||
}
|
||||
|
||||
// OIDC handlers (ADR-0028 Phase B.4)
|
||||
oidcProviders := s.config.GetOIDCProviders()
|
||||
if len(oidcProviders) > 0 {
|
||||
oidcClients := make(map[string]*auth.OIDCClient, len(oidcProviders))
|
||||
for name, p := range oidcProviders {
|
||||
oidcClients[name] = auth.NewOIDCClient(p.IssuerURL, p.ClientID, p.ClientSecret)
|
||||
}
|
||||
redirectBase := s.config.GetMagicLinkConfig().BaseURL
|
||||
oidcHandler := userapi.NewOIDCHandler(oidcClients, s.userService, s.userRepo, redirectBase)
|
||||
oidcHandler.RegisterRoutes(r)
|
||||
}
|
||||
})
|
||||
|
||||
// Register admin routes
|
||||
|
||||
Reference in New Issue
Block a user