141 lines
4.0 KiB
Go
141 lines
4.0 KiB
Go
package middleware
|
|
|
|
import (
|
|
"bytes"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/alicebob/miniredis/v2"
|
|
"github.com/gin-gonic/gin"
|
|
goredis "github.com/redis/go-redis/v9"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
|
|
sharedauth "github.com/geo-platform/tenant-api/internal/shared/auth"
|
|
)
|
|
|
|
func TestLoggerIncludesDetailedAuthFailureContext(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
var logBuffer bytes.Buffer
|
|
encoderConfig := zap.NewProductionEncoderConfig()
|
|
encoderConfig.TimeKey = ""
|
|
logger := zap.New(zapcore.NewCore(
|
|
zapcore.NewJSONEncoder(encoderConfig),
|
|
zapcore.AddSync(&logBuffer),
|
|
zapcore.DebugLevel,
|
|
))
|
|
|
|
mr := miniredis.RunT(t)
|
|
rdb := goredis.NewClient(&goredis.Options{Addr: mr.Addr()})
|
|
mgr := sharedauth.NewManager("logger-test-secret", -1*time.Minute, 7*24*time.Hour)
|
|
sessions := sharedauth.NewSessionStore(rdb)
|
|
|
|
pair, err := mgr.Issue(7, 42, 420, "editor")
|
|
require.NoError(t, err)
|
|
|
|
router := gin.New()
|
|
router.Use(RequestID())
|
|
router.Use(Logger(logger))
|
|
router.Use(sharedauth.Middleware(mgr, sessions))
|
|
router.GET("/test", func(c *gin.Context) {
|
|
c.Status(http.StatusOK)
|
|
})
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/test?tab=cards", nil)
|
|
req.Header.Set("Authorization", "Bearer "+pair.AccessToken)
|
|
req.Header.Set("User-Agent", "geo-rankly-test/1.0")
|
|
resp := httptest.NewRecorder()
|
|
|
|
router.ServeHTTP(resp, req)
|
|
|
|
require.Equal(t, http.StatusUnauthorized, resp.Code)
|
|
|
|
logLine := logBuffer.String()
|
|
t.Log(logLine)
|
|
|
|
require.Contains(t, logLine, `"msg":"request"`)
|
|
require.Contains(t, logLine, `"status":401`)
|
|
require.Contains(t, logLine, `"route":"/test"`)
|
|
require.Contains(t, logLine, `"query":"tab=cards"`)
|
|
require.Contains(t, logLine, `"user_agent":"geo-rankly-test/1.0"`)
|
|
require.Contains(t, logLine, `"app_message":"invalid_access_token"`)
|
|
require.Contains(t, logLine, `"auth_header_present":true`)
|
|
require.Contains(t, logLine, `"auth_scheme":"Bearer"`)
|
|
require.Contains(t, logLine, `"auth_failure_stage":"parse_access_token"`)
|
|
require.Contains(t, logLine, `"auth_failure_reason":"expired"`)
|
|
require.Contains(t, logLine, `"auth_parse_error":"token has invalid claims: token is expired"`)
|
|
require.Contains(t, logLine, `"auth_token_fingerprint":"`)
|
|
}
|
|
|
|
func TestLoggerUsesForwardedClientIPFromTrustedProxy(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
var logBuffer bytes.Buffer
|
|
encoderConfig := zap.NewProductionEncoderConfig()
|
|
encoderConfig.TimeKey = ""
|
|
logger := zap.New(zapcore.NewCore(
|
|
zapcore.NewJSONEncoder(encoderConfig),
|
|
zapcore.AddSync(&logBuffer),
|
|
zapcore.DebugLevel,
|
|
))
|
|
|
|
router := gin.New()
|
|
require.NoError(t, router.SetTrustedProxies([]string{"10.42.0.0/16"}))
|
|
router.Use(RequestID())
|
|
router.Use(Logger(logger))
|
|
router.GET("/test", func(c *gin.Context) {
|
|
c.Status(http.StatusOK)
|
|
})
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/test", nil)
|
|
req.RemoteAddr = "10.42.0.128:51234"
|
|
req.Header.Set("X-Forwarded-For", "106.14.89.27")
|
|
resp := httptest.NewRecorder()
|
|
|
|
router.ServeHTTP(resp, req)
|
|
|
|
require.Equal(t, http.StatusOK, resp.Code)
|
|
require.Contains(t, logBuffer.String(), `"client_ip":"106.14.89.27"`)
|
|
}
|
|
|
|
func TestLoggerRedactsSensitiveQueryValues(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
var logBuffer bytes.Buffer
|
|
encoderConfig := zap.NewProductionEncoderConfig()
|
|
encoderConfig.TimeKey = ""
|
|
logger := zap.New(zapcore.NewCore(
|
|
zapcore.NewJSONEncoder(encoderConfig),
|
|
zapcore.AddSync(&logBuffer),
|
|
zapcore.DebugLevel,
|
|
))
|
|
|
|
router := gin.New()
|
|
router.Use(RequestID())
|
|
router.Use(Logger(logger))
|
|
router.GET("/test", func(c *gin.Context) {
|
|
c.Status(http.StatusOK)
|
|
})
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/test?password=secret&tab=cards&token=abc", nil)
|
|
resp := httptest.NewRecorder()
|
|
|
|
router.ServeHTTP(resp, req)
|
|
|
|
require.Equal(t, http.StatusOK, resp.Code)
|
|
logLine := logBuffer.String()
|
|
require.Contains(t, logLine, `"query":"password=%5BREDACTED%5D&tab=cards&token=%5BREDACTED%5D"`)
|
|
require.NotContains(t, logLine, "secret")
|
|
require.NotContains(t, logLine, "token=abc")
|
|
}
|