mirror of
https://github.com/fosrl/badger.git
synced 2026-09-01 03:31:32 +02:00
feat: rename main.go to badger.go to allign with traefik best practices and add test coverage
Signed-off-by: Marc Schäfer <git@marcschaeferger.de>
This commit is contained in:
187
badger_test.go
Normal file
187
badger_test.go
Normal file
@@ -0,0 +1,187 @@
|
||||
package badger_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
badger "github.com/fosrl/badger"
|
||||
)
|
||||
|
||||
// newTestHandler builds a Badger handler with the given config, failing the test
|
||||
// if construction returns an unexpected error.
|
||||
func newTestHandler(t *testing.T, cfg *badger.Config, next http.Handler) http.Handler {
|
||||
t.Helper()
|
||||
h, err := badger.New(context.Background(), next, cfg, "test")
|
||||
if err != nil {
|
||||
t.Fatalf("New() returned unexpected error: %v", err)
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func TestCreateConfig(t *testing.T) {
|
||||
if badger.CreateConfig() == nil {
|
||||
t.Fatal("CreateConfig() returned nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewRequiresFieldsWhenForwardAuthEnabled(t *testing.T) {
|
||||
cases := map[string]*badger.Config{
|
||||
"missing apiBaseUrl": {
|
||||
UserSessionCookieName: "p_session_token",
|
||||
ResourceSessionRequestParam: "p_session_request",
|
||||
},
|
||||
"missing userSessionCookieName": {
|
||||
APIBaseUrl: "http://localhost:3001",
|
||||
ResourceSessionRequestParam: "p_session_request",
|
||||
},
|
||||
"missing resourceSessionRequestParam": {
|
||||
APIBaseUrl: "http://localhost:3001",
|
||||
UserSessionCookieName: "p_session_token",
|
||||
},
|
||||
}
|
||||
|
||||
for name, cfg := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
cfg.DisableDefaultCFIPs = true
|
||||
if _, err := badger.New(context.Background(), nil, cfg, "test"); err == nil {
|
||||
t.Fatalf("expected error for %q, got nil", name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewSucceedsWhenForwardAuthDisabled(t *testing.T) {
|
||||
cfg := &badger.Config{
|
||||
DisableForwardAuth: true,
|
||||
DisableDefaultCFIPs: true,
|
||||
}
|
||||
h, err := badger.New(context.Background(), http.NotFoundHandler(), cfg, "test")
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error, got %v", err)
|
||||
}
|
||||
if h == nil {
|
||||
t.Fatal("expected non-nil handler")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewRejectsInvalidCIDR(t *testing.T) {
|
||||
cfg := &badger.Config{
|
||||
DisableForwardAuth: true,
|
||||
DisableDefaultCFIPs: true,
|
||||
TrustIP: []string{"not-a-cidr"},
|
||||
}
|
||||
if _, err := badger.New(context.Background(), http.NotFoundHandler(), cfg, "test"); err == nil {
|
||||
t.Fatal("expected error for invalid CIDR, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeHTTPDisableForwardAuthCallsNext(t *testing.T) {
|
||||
called := false
|
||||
next := http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
|
||||
called = true
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
})
|
||||
cfg := &badger.Config{DisableForwardAuth: true, DisableDefaultCFIPs: true}
|
||||
h := newTestHandler(t, cfg, next)
|
||||
|
||||
rw := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "http://example.com/", nil)
|
||||
h.ServeHTTP(rw, req)
|
||||
|
||||
if !called {
|
||||
t.Fatal("expected next handler to be called")
|
||||
}
|
||||
if rw.Code != http.StatusOK {
|
||||
t.Fatalf("expected status %d, got %d", http.StatusOK, rw.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRealIPUntrustedUsesDirectIPAndStripsCFHeaders(t *testing.T) {
|
||||
var forwarded *http.Request
|
||||
next := http.HandlerFunc(func(_ http.ResponseWriter, req *http.Request) {
|
||||
forwarded = req
|
||||
})
|
||||
cfg := &badger.Config{DisableForwardAuth: true, DisableDefaultCFIPs: true}
|
||||
h := newTestHandler(t, cfg, next)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "http://example.com/", nil)
|
||||
req.RemoteAddr = "198.51.100.7:9999"
|
||||
req.Header.Set("CF-Connecting-IP", "1.2.3.4")
|
||||
h.ServeHTTP(httptest.NewRecorder(), req)
|
||||
|
||||
if got := forwarded.Header.Get("X-Real-Ip"); got != "198.51.100.7" {
|
||||
t.Fatalf("expected X-Real-Ip from direct remote addr, got %q", got)
|
||||
}
|
||||
if got := forwarded.Header.Get("CF-Connecting-IP"); got != "" {
|
||||
t.Fatalf("expected CF-Connecting-IP to be stripped for untrusted source, got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRealIPTrustedProxyUsesCustomHeader(t *testing.T) {
|
||||
var forwarded *http.Request
|
||||
next := http.HandlerFunc(func(_ http.ResponseWriter, req *http.Request) {
|
||||
forwarded = req
|
||||
})
|
||||
cfg := &badger.Config{
|
||||
DisableForwardAuth: true,
|
||||
DisableDefaultCFIPs: true,
|
||||
TrustIP: []string{"192.0.2.0/24"},
|
||||
CustomIPHeader: "X-Custom-IP",
|
||||
}
|
||||
h := newTestHandler(t, cfg, next)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "http://example.com/", nil)
|
||||
req.RemoteAddr = "192.0.2.10:12345"
|
||||
req.Header.Set("X-Custom-IP", "203.0.113.5")
|
||||
h.ServeHTTP(httptest.NewRecorder(), req)
|
||||
|
||||
if got := forwarded.Header.Get("X-Forwarded-For"); got != "203.0.113.5" {
|
||||
t.Fatalf("expected X-Forwarded-For from custom header, got %q", got)
|
||||
}
|
||||
if got := forwarded.Header.Get("X-Real-Ip"); got != "203.0.113.5" {
|
||||
t.Fatalf("expected X-Real-Ip from custom header, got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStripSessionCookiesPreservesUnrelated(t *testing.T) {
|
||||
verify := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
if req.URL.Path != "/badger/verify-session" {
|
||||
http.Error(rw, "unexpected path", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
rw.Header().Set("Content-Type", "application/json")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
_, _ = rw.Write([]byte(`{"data":{"valid":true}}`))
|
||||
}))
|
||||
defer verify.Close()
|
||||
|
||||
var forwarded *http.Request
|
||||
next := http.HandlerFunc(func(_ http.ResponseWriter, req *http.Request) {
|
||||
forwarded = req
|
||||
})
|
||||
cfg := &badger.Config{
|
||||
APIBaseUrl: verify.URL,
|
||||
UserSessionCookieName: "p_session_token",
|
||||
ResourceSessionRequestParam: "p_session_request",
|
||||
DisableDefaultCFIPs: true,
|
||||
}
|
||||
h := newTestHandler(t, cfg, next)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "http://example.com/", nil)
|
||||
req.Header.Set("Cookie", "p_session_token=secret; other=keep")
|
||||
h.ServeHTTP(httptest.NewRecorder(), req)
|
||||
|
||||
if forwarded == nil {
|
||||
t.Fatal("expected next handler to be called for valid session")
|
||||
}
|
||||
cookie := forwarded.Header.Get("Cookie")
|
||||
if strings.Contains(cookie, "p_session_token") {
|
||||
t.Fatalf("expected session cookie to be stripped, got %q", cookie)
|
||||
}
|
||||
if !strings.Contains(cookie, "other=keep") {
|
||||
t.Fatalf("expected unrelated cookie to be preserved, got %q", cookie)
|
||||
}
|
||||
}
|
||||
18
ips/ips_test.go
Normal file
18
ips/ips_test.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package ips
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCFIPs(t *testing.T) {
|
||||
cidrs := CFIPs()
|
||||
if len(cidrs) == 0 {
|
||||
t.Fatal("CFIPs() returned an empty list")
|
||||
}
|
||||
for _, cidr := range cidrs {
|
||||
if _, _, err := net.ParseCIDR(cidr); err != nil {
|
||||
t.Errorf("CFIPs() returned invalid CIDR %q: %v", cidr, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user