fix(webhook): explain why webhook edit needs an authorization choice

Gitea 28 drops a webhook's stored authorization header on every edit
that does not send it again, and never returns it, so tea cannot leave
it unchanged. The error offered --clear-authorization as an equal
alternative, which wiped credentials users still needed. It now says
the header is lost unless sent again, asks for it first, and reserves
--clear-authorization for hooks without one.

Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
bircni committed 2026-10-11 21:57:52 +02:00
1 parent 784423bd9d
commit fcfc497a77
3 files changed
+4 -4

No files matched your search

+1 -1
View File
@@ -233,7 +233,7 @@ func TestUsageErrorsPrecedeRequests(t *testing.T) {
{[]string{"webhook", "create", "https://host/path", "--authorization-header", "first\nsecond"}, "authorization header must be a single line"},
{[]string{"webhook", "create", "https://host/path", "--events", ""}, "--events needs at least one trigger"},
{[]string{"webhook", "create", "https://host/path", "--config", "secret=private"}, "--config cannot override the URL, secret, or webhook scope"},
{[]string{"webhook", "edit", "1", "--active=false"}, "editing requires --authorization-header, --authorization-header-file, or --clear-authorization because Gitea replaces authorization"},
{[]string{"webhook", "edit", "1", "--active=false"}, "editing a webhook drops its stored authorization header unless it is sent again, and Gitea never returns it: pass --authorization-header-file or --authorization-header (use --clear-authorization only for a hook without one)"},
{[]string{"webhook", "delete", "not-an-id"}, "invalid resource number \"not-an-id\""},
{[]string{"webhook", "list", "--org", "organization", "--account"}, "--org, --account, --global, and --repo select mutually exclusive scopes"},
{[]string{"webhook", "list", "--global", "-R", "owner/repo"}, "--org, --account, --global, and --repo select mutually exclusive scopes"},
+2 -2
View File
@@ -76,7 +76,7 @@ func (a *application) webhookCommand() *cobra.Command {
command.Flags().StringVar(&filter, "branch-filter", "", "Branch glob for push events")
command.Flags().StringVar(&authorization, "authorization-header", "", "Authorization value (prefer file input)")
command.Flags().StringVar(&authorizationFile, "authorization-header-file", "", "Read authorization value from file or -")
command.Flags().BoolVar(&clearAuthorization, "clear-authorization", false, "Explicitly clear delivery authorization")
command.Flags().BoolVar(&clearAuthorization, "clear-authorization", false, "Send no authorization header; on edit, this removes the stored one")
command.Flags().StringToStringVar(&config, "config", nil, "Adapter-specific configuration, for example channel=alerts")
if verb == "create" {
command.Flags().StringVar(&kind, "type", "gitea", "Webhook adapter type")
@@ -116,7 +116,7 @@ func (a *application) webhookCommand() *cobra.Command {
return clierr.Wrap(clierr.Usage, &services.CapabilityError{Feature: "webhook secret editing", Reason: "Gitea does not update signing secrets through its edit API; recreate the hook to rotate it"})
}
if verb == "edit" && authSources == 0 {
return clierr.Wrap(clierr.Usage, errors.New("editing requires --authorization-header, --authorization-header-file, or --clear-authorization because Gitea replaces authorization"))
return clierr.Wrap(clierr.Usage, errors.New("editing a webhook drops its stored authorization header unless it is sent again, and Gitea never returns it: pass --authorization-header-file or --authorization-header (use --clear-authorization only for a hook without one)"))
}
if len(args) > 0 && verb == "create" {
if cmd.Flags().Changed("url") {
+1 -1
View File
@@ -145,7 +145,7 @@ func (s Webhooks) Edit(ctx context.Context, id int64, opts WebhookOptions) (Webh
return Webhook{}, &CapabilityError{Feature: "webhook secret editing", Reason: "Gitea's edit API does not update the signing secret; recreate the hook to rotate it"}
}
if opts.Authorization == nil {
return Webhook{}, &CapabilityError{Feature: "webhook editing without an authorization choice", Reason: "Gitea replaces authorization and can hide its existing value; supply --authorization-header-file or --clear-authorization"}
return Webhook{}, &CapabilityError{Feature: "webhook editing without an authorization choice", Reason: "Gitea drops the stored authorization header on every edit and never returns it, so the caller must send it again or clear it"}
}
current, err := s.get(ctx, id)
if err != nil {