diff --git a/internal/auth/caller.go b/internal/auth/caller.go new file mode 100644 index 0000000..bcffed3 --- /dev/null +++ b/internal/auth/caller.go @@ -0,0 +1,26 @@ +package auth + +import ( + "context" + "net/http" +) + +type ctxKey struct{} + +func CallerMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + user := r.Header.Get("X-Auth-Request-User") + if user == "" { + user = r.Header.Get("X-Forwarded-User") + } + ctx := context.WithValue(r.Context(), ctxKey{}, user) + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} + +func Caller(ctx context.Context) string { + if v, ok := ctx.Value(ctxKey{}).(string); ok { + return v + } + return "" +} diff --git a/internal/auth/caller_test.go b/internal/auth/caller_test.go new file mode 100644 index 0000000..71db8b3 --- /dev/null +++ b/internal/auth/caller_test.go @@ -0,0 +1,28 @@ +package auth_test + +import ( + "context" + "net/http" + "net/http/httptest" + "testing" + + "gitea.d-ma.be/mathias/gitea-mcp/internal/auth" + "github.com/stretchr/testify/assert" +) + +func TestCallerFromContext(t *testing.T) { + called := false + h := auth.CallerMiddleware(http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) { + called = true + assert.Equal(t, "mathiasbq", auth.Caller(r.Context())) + })) + req := httptest.NewRequest(http.MethodPost, "/", nil) + req.Header.Set("X-Auth-Request-User", "mathiasbq") + rr := httptest.NewRecorder() + h.ServeHTTP(rr, req) + assert.True(t, called) +} + +func TestCallerEmptyWhenHeaderMissing(t *testing.T) { + assert.Equal(t, "", auth.Caller(context.Background())) +}