Files
gitea-mcp/internal/allowlist/allowlist_test.go
T
mathiasandClaude Sonnet 5 43714047be
CD / Lint / Test / Vet (push) Successful in 9s
CD / Build & Import (push) Successful in 25s
CD / Deploy via GitOps (push) Has been skipped
fix(auth): owner allowlist trusts pass-through-authenticated callers (#59)
Allowlist.Check now takes ctx: when the caller authenticated with
their own Gitea PAT (pass-through, v0.12.0), it skips the static
GITEA_MCP_ALLOWED_OWNERS check entirely — Gitea's own permission
model already gates that caller's access more precisely than a coarse
owner-name list can. The static list still applies unchanged for the
shared static-token/JWT path, where it's the only defense against the
service token's blast radius.

Mechanical: every tool call site already had ctx in scope, so this is
a signature-only change at 41 call sites, no other tool behavior
changes. Closes the "Deferred" item from #59.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 08:31:43 +02:00

37 lines
1.3 KiB
Go

package allowlist_test
import (
"context"
"testing"
"git.d-ma.be/mathias/gitea-mcp/internal/allowlist"
"git.d-ma.be/mathias/gitea-mcp/internal/gitea"
"github.com/stretchr/testify/assert"
)
func TestAllowlistCheck(t *testing.T) {
a := allowlist.New([]string{"mathias", "acme"})
ctx := context.Background()
assert.NoError(t, a.Check(ctx, "mathias"))
assert.NoError(t, a.Check(ctx, "acme"))
assert.Error(t, a.Check(ctx, "evil"))
assert.Error(t, a.Check(ctx, ""))
}
// A caller authenticated with their own Gitea PAT (pass-through, gitea-mcp#59)
// is gated by Gitea's own permission model, not the MCP's static owner list —
// otherwise a legitimate second user could never touch their own repos.
func TestAllowlistCheckTrustsPassthroughAuthenticatedCaller(t *testing.T) {
a := allowlist.New([]string{"mathias"})
ctx := gitea.WithToken(context.Background(), "someone-elses-pat")
assert.NoError(t, a.Check(ctx, "someone-else"))
}
// Empty owner is a structural input error, not an authz question — still
// rejected even on the pass-through path.
func TestAllowlistCheckStillRejectsEmptyOwnerOnPassthrough(t *testing.T) {
a := allowlist.New([]string{"mathias"})
ctx := gitea.WithToken(context.Background(), "someone-elses-pat")
assert.Error(t, a.Check(ctx, ""))
}