- internal/auth/jwt.go: JWTValidator via lestrrat-go/jwx/v2, JWKS auto-refresh - internal/auth/bearer.go: replace Gitea PAT validation with JWT->static->default chain - internal/gitea/client.go: always use service PAT; remove TokenFromContext lookup - internal/config/config.go: add DexIssuerURL, MCPAudience, MCPResourceURL, StaticToken - cmd/gitea-mcp/main.go: wire validator, fix /.well-known to return real AS list - bearer_test.go: rewrite for new API
100 lines
3.0 KiB
Go
100 lines
3.0 KiB
Go
package auth_test
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"gitea.d-ma.be/mathias/gitea-mcp/internal/auth"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// helper: BearerMiddleware with no JWT validator and no static token
|
|
func noJWTMiddleware(defaultToken string, next http.Handler) http.Handler {
|
|
return auth.BearerMiddleware(nil, "", defaultToken, next)
|
|
}
|
|
|
|
func TestBearerMiddleware_NoAuthHeader_NoDefault(t *testing.T) {
|
|
srv := httptest.NewServer(noJWTMiddleware("",
|
|
http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
}),
|
|
))
|
|
defer srv.Close()
|
|
|
|
resp, err := http.Post(srv.URL+"/mcp", "application/json", nil)
|
|
require.NoError(t, err)
|
|
defer func() { _ = resp.Body.Close() }()
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
}
|
|
|
|
func TestBearerMiddleware_NoAuthHeader_WithDefault(t *testing.T) {
|
|
called := false
|
|
srv := httptest.NewServer(noJWTMiddleware("default-pat",
|
|
http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
called = true
|
|
w.WriteHeader(http.StatusOK)
|
|
}),
|
|
))
|
|
defer srv.Close()
|
|
|
|
resp, err := http.Post(srv.URL+"/mcp", "application/json", nil)
|
|
require.NoError(t, err)
|
|
defer func() { _ = resp.Body.Close() }()
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
assert.True(t, called)
|
|
}
|
|
|
|
func TestBearerMiddleware_StaticToken_Valid(t *testing.T) {
|
|
const staticToken = "my-static-token"
|
|
called := false
|
|
srv := httptest.NewServer(auth.BearerMiddleware(nil, staticToken, "",
|
|
http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
called = true
|
|
w.WriteHeader(http.StatusOK)
|
|
}),
|
|
))
|
|
defer srv.Close()
|
|
|
|
req, _ := http.NewRequest(http.MethodPost, srv.URL+"/mcp", nil)
|
|
req.Header.Set("Authorization", "Bearer "+staticToken)
|
|
resp, err := http.DefaultClient.Do(req)
|
|
require.NoError(t, err)
|
|
defer func() { _ = resp.Body.Close() }()
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
assert.True(t, called)
|
|
}
|
|
|
|
func TestBearerMiddleware_StaticToken_Invalid(t *testing.T) {
|
|
srv := httptest.NewServer(auth.BearerMiddleware(nil, "correct-token", "",
|
|
http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
}),
|
|
))
|
|
defer srv.Close()
|
|
|
|
req, _ := http.NewRequest(http.MethodPost, srv.URL+"/mcp", nil)
|
|
req.Header.Set("Authorization", "Bearer wrong-token")
|
|
resp, err := http.DefaultClient.Do(req)
|
|
require.NoError(t, err)
|
|
defer func() { _ = resp.Body.Close() }()
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
}
|
|
|
|
func TestBearerMiddleware_UnknownBearer_NoJWT(t *testing.T) {
|
|
srv := httptest.NewServer(noJWTMiddleware("",
|
|
http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
}),
|
|
))
|
|
defer srv.Close()
|
|
|
|
req, _ := http.NewRequest(http.MethodPost, srv.URL+"/mcp", nil)
|
|
req.Header.Set("Authorization", "Bearer random-unknown-token")
|
|
resp, err := http.DefaultClient.Do(req)
|
|
require.NoError(t, err)
|
|
defer func() { _ = resp.Body.Close() }()
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
}
|