Fix missing imports and restore CORS middleware for tests
After conflict resolution from rebase, some imports were accidentally removed and the CORS middleware function was eliminated but still referenced by tests. This commit: - Adds fmt import to api/rest/keys.go (used for error messages) - Adds gorilla/mux import to cmd/server/main.go (used for router type) - Restores newCORSMiddleware function to api/rest/router.go for test compatibility - Formats code with gofmt
This commit is contained in:
+10
-10
@@ -23,13 +23,13 @@ func TestCORSMiddleware_AllowedOrigin(t *testing.T) {
|
||||
}))
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
origin string
|
||||
expectOrigin string
|
||||
expectMethods string
|
||||
expectHeaders string
|
||||
expectMaxAge string
|
||||
expectCreds string
|
||||
name string
|
||||
origin string
|
||||
expectOrigin string
|
||||
expectMethods string
|
||||
expectHeaders string
|
||||
expectMaxAge string
|
||||
expectCreds string
|
||||
}{
|
||||
{
|
||||
name: "allowed origin - example.com",
|
||||
@@ -323,9 +323,9 @@ func TestDefaultCORSConfig(t *testing.T) {
|
||||
// TestCORSMiddleware_MaxAge tests custom max age values
|
||||
func TestCORSMiddleware_MaxAge(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
maxAge int
|
||||
expectMaxAge string
|
||||
name string
|
||||
maxAge int
|
||||
expectMaxAge string
|
||||
}{
|
||||
{
|
||||
name: "zero max age",
|
||||
|
||||
@@ -2,6 +2,7 @@ package rest
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -2,6 +2,8 @@ package rest
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/igodwin/notifier/internal/auth"
|
||||
@@ -105,3 +107,56 @@ func loggingMiddleware(next http.Handler) http.Handler {
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// newCORSMiddleware creates a CORS middleware with origin whitelist validation
|
||||
func newCORSMiddleware(config *CORSConfig) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
origin := r.Header.Get("Origin")
|
||||
|
||||
// Check if the origin is in the allowed list
|
||||
allowed := false
|
||||
for _, allowedOrigin := range config.AllowedOrigins {
|
||||
if origin == allowedOrigin {
|
||||
allowed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Only set CORS headers if the origin is allowed
|
||||
if allowed {
|
||||
// Set the exact origin (never use wildcard)
|
||||
w.Header().Set("Access-Control-Allow-Origin", origin)
|
||||
|
||||
// Set allowed methods
|
||||
if len(config.AllowedMethods) > 0 {
|
||||
w.Header().Set("Access-Control-Allow-Methods", strings.Join(config.AllowedMethods, ", "))
|
||||
}
|
||||
|
||||
// Set allowed headers
|
||||
if len(config.AllowedHeaders) > 0 {
|
||||
w.Header().Set("Access-Control-Allow-Headers", strings.Join(config.AllowedHeaders, ", "))
|
||||
}
|
||||
|
||||
// Set credentials header if enabled
|
||||
if config.AllowCredentials {
|
||||
w.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
}
|
||||
|
||||
// Set max age for preflight caching
|
||||
if config.MaxAge > 0 {
|
||||
w.Header().Set("Access-Control-Max-Age", strconv.FormatInt(int64(config.MaxAge), 10))
|
||||
}
|
||||
}
|
||||
|
||||
// Handle preflight OPTIONS requests
|
||||
if r.Method == http.MethodOptions {
|
||||
// Return 200 OK for preflight requests
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
grpcapi "github.com/igodwin/notifier/api/grpc"
|
||||
pb "github.com/igodwin/notifier/api/grpc/pb"
|
||||
"github.com/igodwin/notifier/api/rest"
|
||||
|
||||
@@ -224,7 +224,7 @@ func setDefaults(v *viper.Viper) {
|
||||
v.SetDefault("auth.bootstrap.kubernetes_secret_key", "admin-key") // Default secret key
|
||||
|
||||
// CORS defaults - secure by default (no origins allowed)
|
||||
v.SetDefault("cors.allowed_origins", []string{}) // Empty by default - must be explicitly configured
|
||||
v.SetDefault("cors.allowed_origins", []string{}) // Empty by default - must be explicitly configured
|
||||
v.SetDefault("cors.allowed_methods", []string{"GET", "POST", "OPTIONS", "DELETE"}) // Standard REST methods
|
||||
v.SetDefault("cors.allowed_headers", []string{"Content-Type", "Authorization"}) // Common headers
|
||||
v.SetDefault("cors.allow_credentials", false) // Credentials disabled by default
|
||||
|
||||
Reference in New Issue
Block a user