Compare commits

...
2 Commits
Author SHA1 Message Date
mathiasandClaude Sonnet 5 43714047be fix(auth): owner allowlist trusts pass-through-authenticated callers (#59)
CD / Lint / Test / Vet (push) Successful in 9s
CD / Build & Import (push) Successful in 25s
CD / Deploy via GitOps (push) Has been skipped
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
mathiasandClaude Sonnet 5 5601927dc8 feat(auth): per-caller Gitea PAT pass-through (#59)
CD / Lint / Test / Vet (push) Successful in 10s
CD / Build & Import (push) Successful in 26s
CD / Deploy via GitOps (push) Has been skipped
Replaces the shared GITEA_MCP_DEFAULT_TOKEN for all callers. When a
request's bearer validates directly against Gitea's own /api/v1/user,
that token is used for every upstream call this request makes instead
of the service PAT, and the caller identity comes from Gitea's own
login rather than the proxy header. Any other bearer (static token,
JWT, none) falls through unchanged to the existing chassis auth.

Prep: Authentik now SSOs into Gitea (infra a32801c), so each real user
can mint their own PAT from their own linked account.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 08:22:50 +02:00
49 changed files with 289 additions and 52 deletions
+2
View File
@@ -92,9 +92,11 @@ func main() {
mux := http.NewServeMux()
mux.Handle("/mcp", mcp.OriginAllowlist(cfg.OriginAllowlist)(
auth.PassthroughMiddleware(giteaClient, mcpSrv,
chassisauth.BearerMiddleware(cfg.StaticToken, jwtValidator, "gitea", resourceMetadataURL,
auth.CallerMiddleware(logger, mcpSrv),
),
),
))
mux.Handle("/healthz", newHealthzHandler(cfg.DexIssuerURL != "", jwtValidator != nil, jwtInitErr))
if cfg.DexIssuerURL != "" {
+14 -2
View File
@@ -1,6 +1,11 @@
package allowlist
import "fmt"
import (
"context"
"fmt"
"git.d-ma.be/mathias/gitea-mcp/internal/gitea"
)
type Allowlist struct {
owners map[string]struct{}
@@ -14,10 +19,17 @@ func New(owners []string) *Allowlist {
return &Allowlist{owners: m}
}
func (a *Allowlist) Check(owner string) error {
// Check gates owner access to the static list — except for a caller
// authenticated with their own Gitea PAT (pass-through, gitea-mcp#59), whose
// access Gitea's own permission model already gates more precisely than a
// coarse owner name list ever could.
func (a *Allowlist) Check(ctx context.Context, owner string) error {
if owner == "" {
return fmt.Errorf("owner required")
}
if _, ok := gitea.TokenFromContext(ctx); ok {
return nil
}
if _, ok := a.owners[owner]; !ok {
return fmt.Errorf("owner %q not in allowlist", owner)
}
+24 -4
View File
@@ -1,16 +1,36 @@
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"})
assert.NoError(t, a.Check("mathias"))
assert.NoError(t, a.Check("acme"))
assert.Error(t, a.Check("evil"))
assert.Error(t, a.Check(""))
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, ""))
}
+5 -2
View File
@@ -36,11 +36,14 @@ func CallerMiddleware(logger *slog.Logger, next http.Handler) http.Handler {
"x_forwarded_user", fwdUser)
}
ctx := context.WithValue(r.Context(), ctxKey{}, user)
next.ServeHTTP(w, r.WithContext(ctx))
next.ServeHTTP(w, r.WithContext(withCaller(r.Context(), user)))
})
}
func withCaller(ctx context.Context, user string) context.Context {
return context.WithValue(ctx, ctxKey{}, user)
}
func Caller(ctx context.Context) string {
if v, ok := ctx.Value(ctxKey{}).(string); ok {
return v
+36
View File
@@ -0,0 +1,36 @@
package auth
import (
"context"
"net/http"
"strings"
"git.d-ma.be/mathias/gitea-mcp/internal/gitea"
)
// TokenValidator asks the upstream service who a bearer token belongs to.
type TokenValidator interface {
ValidateToken(ctx context.Context, token string) (username string, ok bool)
}
// PassthroughMiddleware lets a caller authenticate with their own Gitea PAT:
// if the request's bearer token validates directly against Gitea, it's used
// as-is for every upstream call this request makes (gitea-mcp#59), instead of
// the server's shared default token. Any other bearer (static token, JWT, or
// none) falls through to fallback unchanged — this only adds a capability, it
// never removes the existing auth paths.
func PassthroughMiddleware(validator TokenValidator, onValid, fallback http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
authz := r.Header.Get("Authorization")
token, hasBearer := strings.CutPrefix(authz, "Bearer ")
if hasBearer && token != "" {
if login, ok := validator.ValidateToken(r.Context(), token); ok {
ctx := withCaller(r.Context(), login)
ctx = gitea.WithToken(ctx, token)
onValid.ServeHTTP(w, r.WithContext(ctx))
return
}
}
fallback.ServeHTTP(w, r)
})
}
+82
View File
@@ -0,0 +1,82 @@
package auth_test
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"git.d-ma.be/mathias/gitea-mcp/internal/auth"
"git.d-ma.be/mathias/gitea-mcp/internal/gitea"
"github.com/stretchr/testify/assert"
)
type fakeValidator struct {
login string
ok bool
calls int
}
func (f *fakeValidator) ValidateToken(_ context.Context, _ string) (string, bool) {
f.calls++
return f.login, f.ok
}
func TestPassthroughMiddleware_ValidPATGoesStraightToOnValid(t *testing.T) {
validator := &fakeValidator{login: "alice", ok: true}
var gotCaller string
var gotToken string
var gotOK bool
onValid := http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) {
gotCaller = auth.Caller(r.Context())
gotToken, gotOK = gitea.TokenFromContext(r.Context())
})
fallback := http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
t.Fatal("fallback should not be called for a valid PAT")
})
h := auth.PassthroughMiddleware(validator, onValid, fallback)
req := httptest.NewRequest(http.MethodPost, "/mcp", nil)
req.Header.Set("Authorization", "Bearer alices-pat")
h.ServeHTTP(httptest.NewRecorder(), req)
assert.Equal(t, "alice", gotCaller)
assert.True(t, gotOK)
assert.Equal(t, "alices-pat", gotToken)
}
func TestPassthroughMiddleware_InvalidTokenFallsThrough(t *testing.T) {
validator := &fakeValidator{ok: false}
fallbackCalled := false
onValid := http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
t.Fatal("onValid should not be called for an invalid token")
})
fallback := http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
fallbackCalled = true
})
h := auth.PassthroughMiddleware(validator, onValid, fallback)
req := httptest.NewRequest(http.MethodPost, "/mcp", nil)
req.Header.Set("Authorization", "Bearer not-a-gitea-pat")
h.ServeHTTP(httptest.NewRecorder(), req)
assert.True(t, fallbackCalled)
}
func TestPassthroughMiddleware_NoBearerFallsThroughWithoutCallingValidator(t *testing.T) {
validator := &fakeValidator{ok: true, login: "alice"}
fallbackCalled := false
onValid := http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
t.Fatal("onValid should not be called with no Authorization header")
})
fallback := http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
fallbackCalled = true
})
h := auth.PassthroughMiddleware(validator, onValid, fallback)
req := httptest.NewRequest(http.MethodPost, "/mcp", nil)
h.ServeHTTP(httptest.NewRecorder(), req)
assert.True(t, fallbackCalled)
assert.Equal(t, 0, validator.calls, "validator should not be invoked when there's no bearer to check")
}
+39
View File
@@ -3,6 +3,7 @@ package gitea
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
@@ -19,6 +20,21 @@ type Client struct {
branchCache *expirable.LRU[string, string]
}
type ctxTokenKey struct{}
// WithToken overrides the token used for upstream Gitea calls made with the
// returned context, taking precedence over the Client's configured default
// token. Used for per-caller PAT pass-through (gitea-mcp#59).
func WithToken(ctx context.Context, token string) context.Context {
return context.WithValue(ctx, ctxTokenKey{}, token)
}
// TokenFromContext returns the token set by WithToken, if any.
func TokenFromContext(ctx context.Context) (string, bool) {
v, ok := ctx.Value(ctxTokenKey{}).(string)
return v, ok
}
func NewClient(baseURL, token string) *Client {
return &Client{
baseURL: baseURL,
@@ -28,6 +44,23 @@ func NewClient(baseURL, token string) *Client {
}
}
// ValidateToken asks Gitea who a given token belongs to (GET /api/v1/user
// using that token, not the client's configured default token) and returns
// its login name. Used for per-caller PAT pass-through (gitea-mcp#59).
func (c *Client) ValidateToken(ctx context.Context, token string) (string, bool) {
body, status, err := c.doOnce(WithToken(ctx, token), http.MethodGet, "/api/v1/user", nil)
if err != nil || status != http.StatusOK {
return "", false
}
var user struct {
Login string `json:"login"`
}
if err := json.Unmarshal(body, &user); err != nil || user.Login == "" {
return "", false
}
return user.Login, true
}
// DefaultBranch returns the default branch for a repo. Cached for 60s.
func (c *Client) DefaultBranch(ctx context.Context, owner, name string) (string, error) {
key := owner + "/" + name
@@ -66,6 +99,9 @@ func (c *Client) doOnce(ctx context.Context, method, path string, body []byte) (
return nil, 0, err
}
token := c.token
if override, ok := TokenFromContext(ctx); ok {
token = override
}
if token != "" {
req.Header.Set("Authorization", "token "+token)
}
@@ -135,6 +171,9 @@ func (c *Client) doRaw(ctx context.Context, method, path string, body []byte) (*
return nil, err
}
token := c.token
if override, ok := TokenFromContext(ctx); ok {
token = override
}
if token != "" {
req.Header.Set("Authorization", "token "+token)
}
+43
View File
@@ -50,6 +50,49 @@ func TestRetryOn5xxGetSucceedsOnSecondAttempt(t *testing.T) {
assert.Equal(t, int32(2), atomic.LoadInt32(&attempts))
}
func TestClientPrefersTokenFromContextOverDefaultToken(t *testing.T) {
var gotAuth string
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gotAuth = r.Header.Get("Authorization")
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"ok":true}`))
}))
defer srv.Close()
c := gitea.NewClient(srv.URL, "default-token")
ctx := gitea.WithToken(context.Background(), "caller-token")
_, status, err := c.GetJSON(ctx, "/api/v1/user")
require.NoError(t, err)
assert.Equal(t, 200, status)
assert.Equal(t, "token caller-token", gotAuth)
}
func TestValidateTokenReturnsLoginOnSuccess(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "token candidate-token", r.Header.Get("Authorization"))
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"login":"alice"}`))
}))
defer srv.Close()
c := gitea.NewClient(srv.URL, "default-token")
login, ok := c.ValidateToken(context.Background(), "candidate-token")
assert.True(t, ok)
assert.Equal(t, "alice", login)
}
func TestValidateTokenReturnsFalseOn401(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
http.Error(w, "unauthorized", http.StatusUnauthorized)
}))
defer srv.Close()
c := gitea.NewClient(srv.URL, "default-token")
login, ok := c.ValidateToken(context.Background(), "bad-token")
assert.False(t, ok)
assert.Empty(t, login)
}
func TestRetryOnPostNotRetried(t *testing.T) {
var attempts int32
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
+1 -1
View File
@@ -46,7 +46,7 @@ func (t *BranchDelete) Call(ctx context.Context, raw json.RawMessage) (json.RawM
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Branch == "" {
+1 -1
View File
@@ -47,7 +47,7 @@ func (t *BranchList) Call(ctx context.Context, raw json.RawMessage) (json.RawMes
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
+1 -1
View File
@@ -45,7 +45,7 @@ func (t *BranchProtectionGet) Call(ctx context.Context, raw json.RawMessage) (js
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
+1 -1
View File
@@ -70,7 +70,7 @@ func (t *CodeSearch) Call(ctx context.Context, raw json.RawMessage) (json.RawMes
if args.Q == "" {
return nil, fmt.Errorf("q is required: %w", gitea.ErrValidation)
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Page < 1 {
@@ -111,7 +111,7 @@ func (t *CreateProjectFromTemplate) Call(ctx context.Context, raw json.RawMessag
}
// Allowlist check first.
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
+1 -1
View File
@@ -47,7 +47,7 @@ func (t *DirList) Call(ctx context.Context, raw json.RawMessage) (json.RawMessag
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
+1 -1
View File
@@ -52,7 +52,7 @@ func (t *FileDelete) Call(ctx context.Context, raw json.RawMessage) (json.RawMes
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Sha == "" {
+1 -1
View File
@@ -51,7 +51,7 @@ func (t *FileRead) Call(ctx context.Context, raw json.RawMessage) (json.RawMessa
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
+1 -1
View File
@@ -57,7 +57,7 @@ func (t *FileWriteBranch) Call(ctx context.Context, raw json.RawMessage) (json.R
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Branch == "" {
+1 -1
View File
@@ -45,7 +45,7 @@ func (t *IssueClose) Call(ctx context.Context, raw json.RawMessage) (json.RawMes
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
iss, err := t.c.SetIssueState(ctx, args.Owner, args.Repo, args.Number, "closed")
+1 -1
View File
@@ -50,7 +50,7 @@ func (t *IssueComment) Call(ctx context.Context, raw json.RawMessage) (json.RawM
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Number < 1 {
+1 -1
View File
@@ -56,7 +56,7 @@ func (t *IssueCreate) Call(ctx context.Context, raw json.RawMessage) (json.RawMe
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Title == "" {
+1 -1
View File
@@ -53,7 +53,7 @@ func (t *IssueEdit) Call(ctx context.Context, raw json.RawMessage) (json.RawMess
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Number < 1 {
+1 -1
View File
@@ -43,7 +43,7 @@ func (t *IssueGet) Call(ctx context.Context, raw json.RawMessage) (json.RawMessa
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
iss, err := t.c.GetIssue(ctx, args.Owner, args.Repo, args.Number)
+1 -1
View File
@@ -50,7 +50,7 @@ func (t *IssueLabel) Call(ctx context.Context, raw json.RawMessage) (json.RawMes
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Number < 1 {
+1 -1
View File
@@ -53,7 +53,7 @@ func (t *IssueList) Call(ctx context.Context, raw json.RawMessage) (json.RawMess
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.State == "" {
+1 -1
View File
@@ -45,7 +45,7 @@ func (t *IssueListComments) Call(ctx context.Context, raw json.RawMessage) (json
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
comments, err := t.c.ListIssueComments(ctx, args.Owner, args.Repo, args.Number)
+1 -1
View File
@@ -45,7 +45,7 @@ func (t *IssueReopen) Call(ctx context.Context, raw json.RawMessage) (json.RawMe
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
iss, err := t.c.SetIssueState(ctx, args.Owner, args.Repo, args.Number, "open")
+1 -1
View File
@@ -43,7 +43,7 @@ func (t *LabelList) Call(ctx context.Context, raw json.RawMessage) (json.RawMess
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
labels, err := t.c.ListLabels(ctx, args.Owner, args.Repo)
+1 -1
View File
@@ -50,7 +50,7 @@ func (t *PRComment) Call(ctx context.Context, raw json.RawMessage) (json.RawMess
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Number < 1 {
+1 -1
View File
@@ -56,7 +56,7 @@ func (t *PRCreate) Call(ctx context.Context, raw json.RawMessage) (json.RawMessa
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Title == "" {
+1 -1
View File
@@ -63,7 +63,7 @@ func (t *PRFilesDiff) Call(ctx context.Context, raw json.RawMessage) (json.RawMe
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Number < 1 {
+1 -1
View File
@@ -44,7 +44,7 @@ func (t *PRGet) Call(ctx context.Context, raw json.RawMessage) (json.RawMessage,
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Number < 1 {
+1 -1
View File
@@ -51,7 +51,7 @@ func (t *PRList) Call(ctx context.Context, raw json.RawMessage) (json.RawMessage
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
state := args.State
+1 -1
View File
@@ -52,7 +52,7 @@ func (t *PRMerge) Call(ctx context.Context, raw json.RawMessage) (json.RawMessag
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Number < 1 {
+1 -1
View File
@@ -55,7 +55,7 @@ func (t *ReleaseCreate) Call(ctx context.Context, raw json.RawMessage) (json.Raw
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
rel, err := t.c.CreateRelease(ctx, args.Owner, args.Repo, gitea.CreateReleaseArgs{
+1 -1
View File
@@ -53,7 +53,7 @@ func (t *RepoCreate) Call(ctx context.Context, raw json.RawMessage) (json.RawMes
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
createArgs := gitea.CreateRepoArgs{
+1 -1
View File
@@ -46,7 +46,7 @@ func (t *RepoDelete) Call(ctx context.Context, raw json.RawMessage) (json.RawMes
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Confirm != args.Repo {
+1 -1
View File
@@ -38,7 +38,7 @@ func (t *RepoGet) Call(ctx context.Context, raw json.RawMessage) (json.RawMessag
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
r, err := t.c.GetRepo(ctx, args.Owner, args.Repo)
+1 -1
View File
@@ -45,7 +45,7 @@ func (t *RepoList) Call(ctx context.Context, raw json.RawMessage) (json.RawMessa
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
args.Limit = capLimit(args.Limit, 30)
+1 -1
View File
@@ -96,7 +96,7 @@ func (t *RepoMirrorPush) Call(ctx context.Context, raw json.RawMessage) (json.Ra
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
switch args.Action {
+2 -2
View File
@@ -53,7 +53,7 @@ func (t *RepoSearch) Call(ctx context.Context, raw json.RawMessage) (json.RawMes
return nil, fmt.Errorf("q is required: %w", gitea.ErrValidation)
}
if args.Owner != "" {
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
}
@@ -75,7 +75,7 @@ func (t *RepoSearch) Call(ctx context.Context, raw json.RawMessage) (json.RawMes
if len(parts) != 2 {
continue
}
if t.a.Check(parts[0]) == nil {
if t.a.Check(ctx, parts[0]) == nil {
filtered = append(filtered, r)
}
}
+1 -1
View File
@@ -45,7 +45,7 @@ func (t *RepoStatus) Call(ctx context.Context, raw json.RawMessage) (json.RawMes
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
+1 -1
View File
@@ -45,7 +45,7 @@ func (t *RepoTopicsUpdate) Call(ctx context.Context, raw json.RawMessage) (json.
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if err := t.c.UpdateTopics(ctx, args.Owner, args.Repo, args.Topics); err != nil {
+1 -1
View File
@@ -45,7 +45,7 @@ func (t *RepoTree) Call(ctx context.Context, raw json.RawMessage) (json.RawMessa
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
tree, err := t.c.GetTree(ctx, args.Owner, args.Repo, args.Ref, true)
+1 -1
View File
@@ -60,7 +60,7 @@ func (t *RepoUpdate) Call(ctx context.Context, raw json.RawMessage) (json.RawMes
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
+1 -1
View File
@@ -50,7 +50,7 @@ func (t *TagCreate) Call(ctx context.Context, raw json.RawMessage) (json.RawMess
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Tag == "" {
+1 -1
View File
@@ -145,7 +145,7 @@ func (t *TBDShip) Call(ctx context.Context, raw json.RawMessage) (json.RawMessag
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Path == "" || args.Content == "" || args.Message == "" {
+1 -1
View File
@@ -57,7 +57,7 @@ func (t *WorkflowRunList) Call(ctx context.Context, raw json.RawMessage) (json.R
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
args.Limit = capLimit(args.Limit, 10)
+1 -1
View File
@@ -47,7 +47,7 @@ func (t *WorkflowRunStatus) Call(ctx context.Context, raw json.RawMessage) (json
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.RunID < 1 {
+1 -1
View File
@@ -62,7 +62,7 @@ func (t *WorkflowRunTrigger) Call(ctx context.Context, raw json.RawMessage) (jso
if err := parseArgs(raw, &args); err != nil {
return nil, err
}
if err := t.a.Check(args.Owner); err != nil {
if err := t.a.Check(ctx, args.Owner); err != nil {
return nil, err
}
if args.Workflow == "" {