Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System Hooks API confused with Default Hooks API #23139

Closed
kousu opened this issue Feb 25, 2023 · 5 comments
Closed

System Hooks API confused with Default Hooks API #23139

kousu opened this issue Feb 25, 2023 · 5 comments
Labels
topic/api Concerns mainly the API type/bug

Comments

@kousu
Copy link
Contributor

kousu commented Feb 25, 2023

Description

GET /admin/hooks lists hooks with is_system_webhook = true, but POST /admin/hooks creates them without. There does not currently seem to be a way to create a system webhook from the API -- only default webhooks; meanwhile there is no way to list default webhooks from the API.

I see that /admin/hooks was only added less than a month ago with #14537. It's an niche but extremely helpful feature for what I'm trying to do with Gitea, so I want to help get it working.

Gitea Version

1.19.0+dev-586-g10cdcb9ea

Can you reproduce the bug on the Gitea demo site?

No -- but only because I don't have admin rights there

Log Gist

https://gist.github.com/kousu/1f0be0c81dce500caef0b0af3e985196

Screenshots

Under http://localhost:3000/admin/hooks I start with an empty slate

Screenshot 2023-02-25 at 01-27-23 Gitea Git with a cup of tea

I go to http://localhost:3000/api/swagger and log in:

Screenshot 2023-02-25 at 01-26-31 Gitea API

http://localhost:3000/api/swagger#/admin/adminGetHook gives an empty list

Screenshot 2023-02-25 at 01-30-46 Gitea API

I create a hook:

Screenshot 2023-02-25 at 01-30-26 Gitea API

Back on the UI at http://localhost:3000/admin/hooks I can see it, but it's a Default Hook:

Screenshot 2023-02-25 at 01-31-25 Gitea Git with a cup of tea

But using the API gets me an empty list still:

Screenshot 2023-02-25 at 01-32-07 Gitea API

If I make a system webhook with the UI

Screenshot 2023-02-25 at 01-33-16 Gitea Git with a cup of tea

it adds to the UI

Screenshot 2023-02-25 at 01-33-31 Gitea Git with a cup of tea

and the API can see it:

Screenshot 2023-02-25 at 01-33-59 Gitea API

If I add another Default Webhook

Screenshot 2023-02-25 at 01-34-33 Gitea Git with a cup of tea

The API cannot see it

Screenshot 2023-02-25 at 01-34-58 Gitea API

...unless I specifically ask for hook 20

Screenshot 2023-02-25 at 01-35-44 Gitea API

19 also works, but there's nothing to distinguish that it is a system hook:

Screenshot 2023-02-25 at 01-36-12 Gitea API

Git Version

2.34.1

Operating System

Ubuntu 22.04

How are you running Gitea?

user@dev:~/src/gitea$ TAGS="bindata sqlite sqlite_unlock_notify" make build
user@dev:~/src/gitea$ ./gitea

Database

SQLite

@kousu
Copy link
Contributor Author

kousu commented Feb 25, 2023

CreateHook calls

utils.AddSystemHook(ctx, form)

"AddSystemHook", which sounds like it should add a system hook

// AddSystemHook add a system hook
func AddSystemHook(ctx *context.APIContext, form *api.CreateHookOption) {
hook, ok := addHook(ctx, form, 0, 0)
if ok {
h, err := webhook_service.ToHook(setting.AppSubURL+"/admin", hook)
if err != nil {
ctx.Error(http.StatusInternalServerError, "convert.ToHook", err)
return
}
ctx.JSON(http.StatusCreated, h)
}
}

but the object it creates is here

w := &webhook.Webhook{
OrgID: orgID,
RepoID: repoID,
URL: form.Config["url"],
ContentType: webhook.ToHookContentType(form.Config["content_type"]),
Secret: form.Config["secret"],
HTTPMethod: "POST",
HookEvent: &webhook_module.HookEvent{
ChooseEvents: true,
HookEvents: webhook_module.HookEvents{
Create: util.SliceContainsString(form.Events, string(webhook_module.HookEventCreate), true),
Delete: util.SliceContainsString(form.Events, string(webhook_module.HookEventDelete), true),
Fork: util.SliceContainsString(form.Events, string(webhook_module.HookEventFork), true),
Issues: issuesHook(form.Events, "issues_only"),
IssueAssign: issuesHook(form.Events, string(webhook_module.HookEventIssueAssign)),
IssueLabel: issuesHook(form.Events, string(webhook_module.HookEventIssueLabel)),
IssueMilestone: issuesHook(form.Events, string(webhook_module.HookEventIssueMilestone)),
IssueComment: issuesHook(form.Events, string(webhook_module.HookEventIssueComment)),
Push: util.SliceContainsString(form.Events, string(webhook_module.HookEventPush), true),
PullRequest: pullHook(form.Events, "pull_request_only"),
PullRequestAssign: pullHook(form.Events, string(webhook_module.HookEventPullRequestAssign)),
PullRequestLabel: pullHook(form.Events, string(webhook_module.HookEventPullRequestLabel)),
PullRequestMilestone: pullHook(form.Events, string(webhook_module.HookEventPullRequestMilestone)),
PullRequestComment: pullHook(form.Events, string(webhook_module.HookEventPullRequestComment)),
PullRequestReview: pullHook(form.Events, "pull_request_review"),
PullRequestSync: pullHook(form.Events, string(webhook_module.HookEventPullRequestSync)),
Wiki: util.SliceContainsString(form.Events, string(webhook_module.HookEventWiki), true),
Repository: util.SliceContainsString(form.Events, string(webhook_module.HookEventRepository), true),
Release: util.SliceContainsString(form.Events, string(webhook_module.HookEventRelease), true),
},
BranchFilter: form.BranchFilter,
},
IsActive: form.Active,
Type: form.Type,
}

which leaves IsSystemWebhook nil.

The only place in the code that's set to true is in the code that handles the UI:

// Must be system webhooks instead
return &orgRepoCtx{
IsAdmin: true,
IsSystemWebhook: true,
Link: path.Join(setting.AppSubURL, "/admin/hooks"),
LinkNew: path.Join(setting.AppSubURL, "/admin/system-hooks"),
NewTemplate: tplAdminHookNew,
}, nil

w := &webhook.Webhook{
RepoID: orCtx.RepoID,
URL: params.URL,
HTTPMethod: params.HTTPMethod,
ContentType: params.ContentType,
Secret: params.Secret,
HookEvent: ParseHookEvent(params.WebhookForm),
IsActive: params.WebhookForm.Active,
Type: params.Type,
Meta: string(meta),
OrgID: orCtx.OrgID,
IsSystemWebhook: orCtx.IsSystemWebhook,
}

@kousu
Copy link
Contributor Author

kousu commented Feb 25, 2023

Also there's no way to set a hook secret with the API, which makes it unusable (unless your hooks all disable signature verification).

@kousu
Copy link
Contributor Author

kousu commented Feb 25, 2023

Also there's no way to set events = {"push_only":true} with the API; with the UI, the default is

Screenshot 2023-02-25 at 03-31-01 Gitea Git with a cup of tea

but with the API you always get

Screenshot 2023-02-25 at 03-31-09 Gitea Git with a cup of tea

kousu added a commit to neuropoly/gitea that referenced this issue Mar 28, 2023
Fixes go-gitea#23139, hopefully.

Also, allow creating/editing (but not viewing) the _secret_ associated with each hook.
kousu added a commit to neuropoly/gitea that referenced this issue Jul 2, 2023
…/admin/default-hooks

This should better address the ambiguity that led to go-gitea#23139.

Rename parts of the supporting module to match this naming convention.
kousu added a commit to neuropoly/gitea that referenced this issue Aug 9, 2023
Fixes go-gitea#23139, hopefully.

Also, allow creating/editing (but not viewing) the _secret_ associated with each hook.
kousu added a commit to neuropoly/gitea that referenced this issue Aug 9, 2023
…/admin/default-hooks

This should better address the ambiguity that led to go-gitea#23139.

Rename parts of the supporting module to match this naming convention.
kousu added a commit to neuropoly/gitea that referenced this issue Aug 11, 2023
"System" webhooks -- webhooks run on all repos on a Gitea instance --
were added in go-gitea#14537 (I believe?)
but managing them by the API is buggy.

- In routers/api/v1/utils/hook.go, correctly handle the
  distinction between system and default webhooks.
  This enables actually creating, editing and deleting both kinds.
- In routers/api/, move `/api/v1/admin/hooks` to `/api/v1/admin/hooks/{system,default}`.
  This allows users to access the code in the previous point.
- In routers/web/, move `/admin/{system,default}-hooks` and most of
  `/admin/hooks/` into `/admin/hooks/{system,default}` to match API.
- In model/, normalize vocabulary. Since the new sub-type, the terminology has
  been a confusing mix of "SystemWebhook", "DefaultSystemWebhook",
  "SystemOrDefaultWebhook" and "DefaultWebhook". Standardize on "AdminWebhook"
  everywhere with `isSystemWebhook bool` to separate the two sub-types.
    - Using a bool made it easier to handle both cases without
      duplicating the router endpoints
- Make PATCH /admin/hooks/{system,default}/:id appropriately return 404.

Fixes go-gitea#23139.

Supersedes go-gitea#23142.
@deliciouslytyped
Copy link

deliciouslytyped commented Oct 22, 2023

I ran into this. Thanks for working on it.
FWIW the push_only / custom thing is also reported at #20178

Any idea how far this is from being complete?

@silverwind silverwind added the topic/api Concerns mainly the API label Mar 3, 2024
@philipparndt
Copy link

I think this can be closed as of #33180

GET /admin/hooks does now have a parameter type

- type: string
  enum:
    - system
    - default
    - all
  description: system, default or both kinds of webhooks
  name: type
  default: system
  in: query

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic/api Concerns mainly the API type/bug
Projects
None yet
5 participants