🧪 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>
This commit is contained in:
63
pkg/server/middleware.go
Normal file
63
pkg/server/middleware.go
Normal file
@@ -0,0 +1,63 @@
|
||||
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)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user