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

Let API create and edit system webhooks #26418

Closed
wants to merge 4 commits into from

Conversation

kousu
Copy link
Contributor

@kousu kousu commented Aug 9, 2023

"System" webhooks -- webhooks run on all repos on a Gitea instance -- were added in #14537 but managing them by the API is buggy:

  • PATCH /api/v1/admin/hooks/:id edits either kind (?)
  • DELETE /api/v1/admin/hooks/:id deletes either kind

but

  • POST /api/v1/admin/hooks/ creates "default" webhooks
  • GET /api/v1/admin/hooks/ and GET/api/v1/admin/hooks/:id return "system" webhooks

To fix the confusion:

  • In routers/api/v1/utils/hook.go, correctly handle the distinction between system and default webhooks. This allows actually creating, editing and deleting both kinds.
  • In routers/api/, split /api/v1/admin/hooks to /api/v1/admin/hooks/{system,default}.
  • 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 a isSystemWebhook bool parameter to separate the two sub-types.
    • Using a bool made it easier to handle both cases without duplicating the router endpoints. I hope that's okay.
  • Make PATCH /admin/hooks/{system,default}/:id return 404 instead of 500 when appropriate to do so.

Fixes #23139.

Supersedes #23142.

@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Aug 9, 2023
@pull-request-size pull-request-size bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Aug 9, 2023
@@ -1381,7 +1381,7 @@ func Routes() *web.Route {
m.Post("/{username}/{reponame}", admin.AdoptRepository)
m.Delete("/{username}/{reponame}", admin.DeleteUnadoptedRepository)
})
m.Group("/hooks", func() {
m.Group("/hooks/{configType:system|default}", func() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the core change. Almost everything else is fall-out from making this one line change.

Copy link
Contributor Author

@kousu kousu Aug 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In #23142 (comment), lunny suggested what I added as /api/v1/admin/hooks/default, but also wanted to keep the old behaviour too.

Respectfully, I think we must not. The old behaviour was inconsistent:

For "backwards compatibility", we could chose to keep the POST /hooks == POST /hooks/default, but then we would have to break GET /hooks; we could choose to keep GET /hooks == GET /hooks/system, but then we would have to break POST /hooks.

The confused behaviour was in the original version of /api/v1/admin/hooks, so I doubt anyone is using it in the wild -- I was probably the first person to try and immediately hit this bug. Anyone else who tried would have hit it too.

URL: form.Config["url"],
ContentType: webhook.ToHookContentType(form.Config["content_type"]),
Secret: form.Config["secret"],
IsSystemWebhook: isSystemWebhook,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is what communicates the one line change above into the backend.

@kousu kousu force-pushed the system-webhooks-api-2 branch 5 times, most recently from edebde3 to 9344314 Compare August 11, 2023 13:58
Comment on lines +264 to +265
if errors.Is(err, util.ErrNotExist) {
ctx.NotFound()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what adds the correct 404 to the PATCH method.

if err != nil {
ctx.ServerError("GetWebhooksAdmin", err)
ctx.ServerError("GetSystemWebhooks", err)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error message was mislabelled.

if err != nil {
ctx.ServerError("GetWebhooksAdmin", err)
ctx.ServerError("GetDefaultWebhooks", err)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also mislabelled

@kousu kousu force-pushed the system-webhooks-api-2 branch from 9344314 to bfd6258 Compare August 11, 2023 14:06
@@ -62,7 +62,7 @@
<span class="text {{if eq .LastStatus 1}}green{{else if eq .LastStatus 2}}red{{else}}grey{{end}} gt-mr-3">{{svg "octicon-dot-fill" 22}}</span>
<a class="text truncate gt-f1 gt-mr-3" title="{{.URL}}" href="{{$.BaseLink}}/{{.ID}}">{{.URL}}</a>
<a class="muted gt-p-3" href="{{$.BaseLink}}/{{.ID}}">{{svg "octicon-pencil"}}</a>
<a class="delete-button gt-p-3" data-url="{{$.Link}}/delete" data-id="{{.ID}}">{{svg "octicon-trash"}}</a>
<a class="delete-button gt-p-3" data-url="{{$.BaseLink}}/delete" data-id="{{.ID}}">{{svg "octicon-trash"}}</a>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because POST /admin/hooks/delete was moved to POST /admin/hooks/{configType:system|default}/delete

@kousu kousu force-pushed the system-webhooks-api-2 branch from bfd6258 to b4f3909 Compare August 11, 2023 14:10
"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.
@kousu kousu force-pushed the system-webhooks-api-2 branch from b4f3909 to 8d6a9a0 Compare August 11, 2023 14:24
@kousu kousu marked this pull request as ready for review August 11, 2023 15:31
@lunny lunny added the modifies/api This PR adds API routes or modifies them label Aug 12, 2023
@lunny lunny added this to the 1.21.0 milestone Aug 12, 2023
@lunny lunny modified the milestones: 1.21.0, 1.22.0 Sep 21, 2023
@kousu
Copy link
Contributor Author

kousu commented Oct 2, 2023

I see that there's a lot of other issues competing for attention in https://github.com/go-gitea/gitea/milestone/148. Is there anything I can do to make it easier to review? I'm hoping to help get this in before the original bug hits its first birthday 🍰

// in: query
// description: page size of results
// type: integer
// - name: configType
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a break change and with no deprecated mark?

@lunny
Copy link
Member

lunny commented Nov 3, 2023

Maybe we can use /admin/hooks as global hooks but /admin/hooks/{configType} as default hooks?
Is that compatible with before? Otherwise, we need a breaking change. For API breaking change, we need to do more things.

@lunny lunny modified the milestones: 1.22.0, 1.23.0 Mar 29, 2024
@lunny lunny removed this from the 1.23.0 milestone Sep 24, 2024
@philipparndt
Copy link

Hi @lunny,

My team would like to have this issue fixed so that it is possible to set up Gitea in an automated way. Is there a good chance to get it merged if we find a way to fix it in a manner that keeps the current API and has some additional API to define the default hook type? Or would you prefer to have a breaking change that also removes the old behavior, like this one? What additional work needs to be done, and how can I (or someone from my scrum team) help fix this bug?

@kousu is this issue still relevant for you?

@lunny
Copy link
Member

lunny commented Nov 27, 2024

Hi @lunny,

My team would like to have this issue fixed so that it is possible to set up Gitea in an automated way. Is there a good chance to get it merged if we find a way to fix it in a manner that keeps the current API and has some additional API to define the default hook type? Or would you prefer to have a breaking change that also removes the old behavior, like this one? What additional work needs to be done, and how can I (or someone from my scrum team) help fix this bug?

@kousu is this issue still relevant for you?

I would like to continue the review if it can resolve the API-breaking problem. If the breaking is necessary, we at least need to add deprecated for several versions until we remove it.

@kousu
Copy link
Contributor Author

kousu commented Nov 28, 2024

Yes I would like to still see this for the same reason as @philipparndt. But the code has drifted very far now and I suspect it needs a full rewrite, especially if the purpose of the surrounding APIs may have changed. I won't be offended if you close this and submit a replacement.

@philipparndt
Copy link

All right, I have planned to implement this and let you know when it is ready.

@mbollmann-v
Copy link
Contributor

Hi @lunny & @kousu,
Do you have any objections to moving the configType to an optional query parameter (system/default/any)?
This way we should be able to configure the default value on the various endpoints to match the old inconsistent behaviour avoiding a breaking change while also allowing api users to explicitly configure which kind of hook they want to interact with.
It's probably not the prettiest solution but maybe an appropriate tradeoff.

@kousu
Copy link
Contributor Author

kousu commented Jan 6, 2025

Not the prettiest no, but I think if it gets things going then it's good 🌠

@mbollmann-v
Copy link
Contributor

Hi @lunny & @kousu,

After reading the source I think I found a simple and compatible way to fix the issue.
I've opened another PR for it at #33180.
I hope that enables us to finally resolve this topic.

@wxiaoguang
Copy link
Contributor

Replaced by #33180

@wxiaoguang wxiaoguang closed this Jan 13, 2025
lunny pushed a commit that referenced this pull request Jan 13, 2025
This PR fixes inconsistencies between system and default webhooks in the
Gitea API. (See also #26418)
- A system webhook is a webhook that captures events for all
repositories.
- A default webhook is copied to a new repository when it is created. 

Before this PR `POST /api/v1/admin/hooks/` creates default webhooks (if
not configured otherwise) and `GET /api/v1/admin/hooks/` returns system
webhooks.

The PR introduces an optional query parameter to `GET
/api/v1/admin/hooks/` to enable selecting if either default, system or
both kind of webhooks should be retrieved. By default the flag is set to
return system webhooks keep current behaviour.

## Examples

### System Webhooks

#### Create

```
POST /api/v1/admin/hooks/

{
  "type": "gitea",
  "active": false,
  "branch_filter": "*",
  "events": [ "create", "..." ],
  "config": {
    "url": "http://...",
    "content_type": "json",
    "secret": "secret",
    "is_system_webhook": true // <-- controls hook type
  }
}
```

#### List
```
GET/api/v1/admin/hooks?type=system //type argument is optional here since it's the default
```

#### Others
The other relevant endpoints work as expected by referencing the hook by
id
```
GET /api/v1/admin/hooks/:id
PATCH /api/v1/admin/hooks/:id
DELETE /api/v1/admin/hooks/:id
```


### Default Webhooks

#### Create
```
POST /api/v1/admin/hooks/

{
  "type": "gitea",
  "active": false,
  "branch_filter": "*",
  "events": [ "create", "..." ],
  "config": {
    "url": "http://...",
    "content_type": "json",
    "secret": "secret",
    "is_system_webhook": false // optional, as false is the default value
  }
}
```

#### List
```
GET/api/v1/admin/hooks?type=default
```

#### Others
The other relevant endpoints work as expected by referencing the hook by
id
```
GET /api/v1/admin/hooks/:id
PATCH /api/v1/admin/hooks/:id
DELETE /api/v1/admin/hooks/:id
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. modifies/api This PR adds API routes or modifies them size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

System Hooks API confused with Default Hooks API
6 participants