Skip to content

Commit a90af22

Browse files
authored
Let API create and edit system webhooks, attempt 2 (#33180)
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 ```
1 parent 348b707 commit a90af22

File tree

5 files changed

+103
-1
lines changed

5 files changed

+103
-1
lines changed

models/fixtures/webhook.yml

+21
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,31 @@
2222
content_type: 1 # json
2323
events: '{"push_only":false,"send_everything":false,"choose_events":false,"events":{"create":false,"push":true,"pull_request":true}}'
2424
is_active: true
25+
2526
-
2627
id: 4
2728
repo_id: 2
2829
url: www.example.com/url4
2930
content_type: 1 # json
3031
events: '{"push_only":true,"branch_filter":"{master,feature*}"}'
3132
is_active: true
33+
34+
-
35+
id: 5
36+
repo_id: 0
37+
owner_id: 0
38+
url: www.example.com/url5
39+
content_type: 1 # json
40+
events: '{"push_only":true,"branch_filter":"{master,feature*}"}'
41+
is_active: true
42+
is_system_webhook: true
43+
44+
-
45+
id: 6
46+
repo_id: 0
47+
owner_id: 0
48+
url: www.example.com/url6
49+
content_type: 1 # json
50+
events: '{"push_only":true,"branch_filter":"{master,feature*}"}'
51+
is_active: true
52+
is_system_webhook: false

models/webhook/webhook_system.go

+13
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ import (
1111
"code.gitea.io/gitea/modules/optional"
1212
)
1313

14+
// GetSystemOrDefaultWebhooks returns webhooks by given argument or all if argument is missing.
15+
func GetSystemOrDefaultWebhooks(ctx context.Context, isSystemWebhook optional.Option[bool]) ([]*Webhook, error) {
16+
webhooks := make([]*Webhook, 0, 5)
17+
if !isSystemWebhook.Has() {
18+
return webhooks, db.GetEngine(ctx).Where("repo_id=? AND owner_id=?", 0, 0).
19+
Find(&webhooks)
20+
}
21+
22+
return webhooks, db.GetEngine(ctx).
23+
Where("repo_id=? AND owner_id=? AND is_system_webhook=?", 0, 0, isSystemWebhook.Value()).
24+
Find(&webhooks)
25+
}
26+
1427
// GetDefaultWebhooks returns all admin-default webhooks.
1528
func GetDefaultWebhooks(ctx context.Context) ([]*Webhook, error) {
1629
webhooks := make([]*Webhook, 0, 5)

models/webhook/webhook_system_test.go

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2017 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package webhook
5+
6+
import (
7+
"testing"
8+
9+
"code.gitea.io/gitea/models/db"
10+
"code.gitea.io/gitea/models/unittest"
11+
"code.gitea.io/gitea/modules/optional"
12+
13+
"github.com/stretchr/testify/assert"
14+
)
15+
16+
func TestGetSystemOrDefaultWebhooks(t *testing.T) {
17+
assert.NoError(t, unittest.PrepareTestDatabase())
18+
19+
hooks, err := GetSystemOrDefaultWebhooks(db.DefaultContext, optional.None[bool]())
20+
assert.NoError(t, err)
21+
if assert.Len(t, hooks, 2) {
22+
assert.Equal(t, int64(5), hooks[0].ID)
23+
assert.Equal(t, int64(6), hooks[1].ID)
24+
}
25+
26+
hooks, err = GetSystemOrDefaultWebhooks(db.DefaultContext, optional.Some(true))
27+
assert.NoError(t, err)
28+
if assert.Len(t, hooks, 1) {
29+
assert.Equal(t, int64(5), hooks[0].ID)
30+
}
31+
32+
hooks, err = GetSystemOrDefaultWebhooks(db.DefaultContext, optional.Some(false))
33+
assert.NoError(t, err)
34+
if assert.Len(t, hooks, 1) {
35+
assert.Equal(t, int64(6), hooks[0].ID)
36+
}
37+
}

routers/api/v1/admin/hooks.go

+20-1
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,30 @@ func ListHooks(ctx *context.APIContext) {
3434
// in: query
3535
// description: page size of results
3636
// type: integer
37+
// - type: string
38+
// enum:
39+
// - system
40+
// - default
41+
// - all
42+
// description: system, default or both kinds of webhooks
43+
// name: type
44+
// default: system
45+
// in: query
46+
//
3747
// responses:
3848
// "200":
3949
// "$ref": "#/responses/HookList"
4050

41-
sysHooks, err := webhook.GetSystemWebhooks(ctx, optional.None[bool]())
51+
// for compatibility the default value is true
52+
isSystemWebhook := optional.Some(true)
53+
typeValue := ctx.FormString("type")
54+
if typeValue == "default" {
55+
isSystemWebhook = optional.Some(false)
56+
} else if typeValue == "all" {
57+
isSystemWebhook = optional.None[bool]()
58+
}
59+
60+
sysHooks, err := webhook.GetSystemOrDefaultWebhooks(ctx, isSystemWebhook)
4261
if err != nil {
4362
ctx.Error(http.StatusInternalServerError, "GetSystemWebhooks", err)
4463
return

templates/swagger/v1_json.tmpl

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)