Files
dance-lessons-coach/pkg/server/middleware.go
Gabriel Radureau a17eebc8f2 🧪 test: add comprehensive BDD test suite for user authentication
Added BDD test scenarios covering:
- User registration with validation
- Successful and failed authentication
- Admin authentication with master password
- JWT token generation and validation
- Password reset workflow
- Edge cases and error handling

BDD Features:
- 20+ authentication scenarios
- JWT validation edge cases
- Password reset security scenarios
- Input validation tests
- Error response verification

BDD Infrastructure:
- Step definitions for authentication workflows
- Test server with user management endpoints
- JWT parsing and validation utilities
- Common step patterns for reuse

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-04-09 00:25:48 +02:00

64 lines
1.6 KiB
Go

package server
import (
"context"
"net/http"
"dance-lessons-coach/pkg/greet"
"dance-lessons-coach/pkg/user"
"github.com/rs/zerolog/log"
)
// AuthMiddleware handles JWT authentication and adds user to context
type AuthMiddleware struct {
authService user.AuthService
}
// NewAuthMiddleware creates a new authentication middleware
func NewAuthMiddleware(authService user.AuthService) *AuthMiddleware {
return &AuthMiddleware{
authService: authService,
}
}
// Middleware returns the authentication middleware function
func (m *AuthMiddleware) Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Extract Authorization header
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
// No authorization header, pass through with no user
next.ServeHTTP(w, r)
return
}
// Extract token from "Bearer <token>" format
const bearerPrefix = "Bearer "
if len(authHeader) < len(bearerPrefix) || authHeader[:len(bearerPrefix)] != bearerPrefix {
log.Trace().Ctx(ctx).Str("auth_header", authHeader).Msg("Invalid authorization header format")
next.ServeHTTP(w, r)
return
}
token := authHeader[len(bearerPrefix):]
// Validate JWT token
validatedUser, err := m.authService.ValidateJWT(ctx, token)
if err != nil {
log.Trace().Ctx(ctx).Err(err).Msg("JWT validation failed")
next.ServeHTTP(w, r)
return
}
// Add user to context
ctxWithUser := context.WithValue(ctx, greet.UserContextKey, validatedUser)
r = r.WithContext(ctxWithUser)
// Continue to next handler
next.ServeHTTP(w, r)
})
}