From 0f12ca9222243e05ae992515125f13f2b39ca7da Mon Sep 17 00:00:00 2001 From: Earl Warren <contact@earl-warren.org> Date: Sat, 14 Jan 2023 10:07:01 +0100 Subject: [PATCH] [BRANDING] define the forgejo webhook type templates/swagger/v1_json.tmpl updated with `make generate-swagger` (cherry picked from commit 0f9842fc582057068e907ef2c7b3129848288f56) --- models/webhook/webhook.go | 1 + modules/setting/webhook.go | 2 +- modules/structs/hook.go | 2 +- routers/web/repo/webhook.go | 28 +++++++++++++ routers/web/web.go | 6 +++ services/webhook/webhook.go | 4 +- templates/admin/hook_new.tmpl | 7 +++- templates/org/settings/hook_new.tmpl | 6 ++- .../repo/settings/webhook/base_list.tmpl | 5 ++- templates/repo/settings/webhook/forgejo.tmpl | 40 +++++++++++++++++++ templates/repo/settings/webhook/new.tmpl | 7 +++- templates/swagger/v1_json.tmpl | 1 + tests/integration/links_test.go | 38 ++++++++++++++++++ 13 files changed, 136 insertions(+), 11 deletions(-) create mode 100644 templates/repo/settings/webhook/forgejo.tmpl diff --git a/models/webhook/webhook.go b/models/webhook/webhook.go index aebe0d6e72..108330bca2 100644 --- a/models/webhook/webhook.go +++ b/models/webhook/webhook.go @@ -155,6 +155,7 @@ type HookType = string // Types of webhooks const ( + FORGEJO HookType = "forgejo" GITEA HookType = "gitea" GOGS HookType = "gogs" SLACK HookType = "slack" diff --git a/modules/setting/webhook.go b/modules/setting/webhook.go index 0bfd7dcb4d..be78066a3d 100644 --- a/modules/setting/webhook.go +++ b/modules/setting/webhook.go @@ -36,7 +36,7 @@ func newWebhookService() { Webhook.DeliverTimeout = sec.Key("DELIVER_TIMEOUT").MustInt(5) Webhook.SkipTLSVerify = sec.Key("SKIP_TLS_VERIFY").MustBool() Webhook.AllowedHostList = sec.Key("ALLOWED_HOST_LIST").MustString("") - Webhook.Types = []string{"gitea", "gogs", "slack", "discord", "dingtalk", "telegram", "msteams", "feishu", "matrix", "wechatwork", "packagist"} + Webhook.Types = []string{"forgejo", "gitea", "gogs", "slack", "discord", "dingtalk", "telegram", "msteams", "feishu", "matrix", "wechatwork", "packagist"} Webhook.PagingNum = sec.Key("PAGING_NUM").MustInt(10) Webhook.ProxyURL = sec.Key("PROXY_URL").MustString("") if Webhook.ProxyURL != "" { diff --git a/modules/structs/hook.go b/modules/structs/hook.go index 8321a15a8f..503f983151 100644 --- a/modules/structs/hook.go +++ b/modules/structs/hook.go @@ -40,7 +40,7 @@ type CreateHookOptionConfig map[string]string // CreateHookOption options when create a hook type CreateHookOption struct { // required: true - // enum: dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu,wechatwork,packagist + // enum: forgejo,dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu,wechatwork,packagist Type string `json:"type" binding:"Required"` // required: true Config CreateHookOptionConfig `json:"config" binding:"Required"` diff --git a/routers/web/repo/webhook.go b/routers/web/repo/webhook.go index ee980333b7..f37454a42c 100644 --- a/routers/web/repo/webhook.go +++ b/routers/web/repo/webhook.go @@ -297,6 +297,34 @@ func editWebhook(ctx *context.Context, params webhookParams) { ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) } +// ForgejoHooksNewPost response for creating Forgejo webhook +func ForgejoHooksNewPost(ctx *context.Context) { + createWebhook(ctx, forgejoHookParams(ctx)) +} + +// ForgejoHooksEditPost response for editing Forgejo webhook +func ForgejoHooksEditPost(ctx *context.Context) { + editWebhook(ctx, forgejoHookParams(ctx)) +} + +func forgejoHookParams(ctx *context.Context) webhookParams { + form := web.GetForm(ctx).(*forms.NewWebhookForm) + + contentType := webhook.ContentTypeJSON + if webhook.HookContentType(form.ContentType) == webhook.ContentTypeForm { + contentType = webhook.ContentTypeForm + } + + return webhookParams{ + Type: webhook.FORGEJO, + URL: form.PayloadURL, + ContentType: contentType, + Secret: form.Secret, + HTTPMethod: form.HTTPMethod, + WebhookForm: form.WebhookForm, + } +} + // GiteaHooksNewPost response for creating Gitea webhook func GiteaHooksNewPost(ctx *context.Context) { createWebhook(ctx, giteaHookParams(ctx)) diff --git a/routers/web/web.go b/routers/web/web.go index 7757e9c30c..3f41592a17 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -534,6 +534,7 @@ func RegisterRoutes(m *web.Route) { m.Get("", repo.WebHooksEdit) m.Post("/replay/{uuid}", repo.ReplayWebhook) }) + m.Post("/forgejo/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.ForgejoHooksEditPost) m.Post("/gitea/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.GiteaHooksEditPost) m.Post("/gogs/{id}", bindIgnErr(forms.NewGogshookForm{}), repo.GogsHooksEditPost) m.Post("/slack/{id}", bindIgnErr(forms.NewSlackHookForm{}), repo.SlackHooksEditPost) @@ -549,6 +550,7 @@ func RegisterRoutes(m *web.Route) { m.Group("/{configType:default-hooks|system-hooks}", func() { m.Get("/{type}/new", repo.WebhooksNew) + m.Post("/forgejo/new", bindIgnErr(forms.NewWebhookForm{}), repo.ForgejoHooksNewPost) m.Post("/gitea/new", bindIgnErr(forms.NewWebhookForm{}), repo.GiteaHooksNewPost) m.Post("/gogs/new", bindIgnErr(forms.NewGogshookForm{}), repo.GogsHooksNewPost) m.Post("/slack/new", bindIgnErr(forms.NewSlackHookForm{}), repo.SlackHooksNewPost) @@ -712,6 +714,7 @@ func RegisterRoutes(m *web.Route) { m.Get("", org.Webhooks) m.Post("/delete", org.DeleteWebhook) m.Get("/{type}/new", repo.WebhooksNew) + m.Post("/forgejo/new", bindIgnErr(forms.NewWebhookForm{}), repo.ForgejoHooksNewPost) m.Post("/gitea/new", bindIgnErr(forms.NewWebhookForm{}), repo.GiteaHooksNewPost) m.Post("/gogs/new", bindIgnErr(forms.NewGogshookForm{}), repo.GogsHooksNewPost) m.Post("/slack/new", bindIgnErr(forms.NewSlackHookForm{}), repo.SlackHooksNewPost) @@ -726,6 +729,7 @@ func RegisterRoutes(m *web.Route) { m.Get("", repo.WebHooksEdit) m.Post("/replay/{uuid}", repo.ReplayWebhook) }) + m.Post("/forgejo/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.ForgejoHooksEditPost) m.Post("/gitea/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.GiteaHooksEditPost) m.Post("/gogs/{id}", bindIgnErr(forms.NewGogshookForm{}), repo.GogsHooksEditPost) m.Post("/slack/{id}", bindIgnErr(forms.NewSlackHookForm{}), repo.SlackHooksEditPost) @@ -835,6 +839,7 @@ func RegisterRoutes(m *web.Route) { m.Get("", repo.Webhooks) m.Post("/delete", repo.DeleteWebhook) m.Get("/{type}/new", repo.WebhooksNew) + m.Post("/forgejo/new", bindIgnErr(forms.NewWebhookForm{}), repo.ForgejoHooksNewPost) m.Post("/gitea/new", bindIgnErr(forms.NewWebhookForm{}), repo.GiteaHooksNewPost) m.Post("/gogs/new", bindIgnErr(forms.NewGogshookForm{}), repo.GogsHooksNewPost) m.Post("/slack/new", bindIgnErr(forms.NewSlackHookForm{}), repo.SlackHooksNewPost) @@ -851,6 +856,7 @@ func RegisterRoutes(m *web.Route) { m.Post("/test", repo.TestWebhook) m.Post("/replay/{uuid}", repo.ReplayWebhook) }) + m.Post("/forgejo/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.ForgejoHooksEditPost) m.Post("/gitea/{id}", bindIgnErr(forms.NewWebhookForm{}), repo.GiteaHooksEditPost) m.Post("/gogs/{id}", bindIgnErr(forms.NewGogshookForm{}), repo.GogsHooksEditPost) m.Post("/slack/{id}", bindIgnErr(forms.NewSlackHookForm{}), repo.SlackHooksEditPost) diff --git a/services/webhook/webhook.go b/services/webhook/webhook.go index 342e764f4d..5205cbcdc8 100644 --- a/services/webhook/webhook.go +++ b/services/webhook/webhook.go @@ -74,7 +74,7 @@ func RegisterWebhook(name string, webhook *webhook) { // IsValidHookTaskType returns true if a webhook registered func IsValidHookTaskType(name string) bool { - if name == webhook_model.GITEA || name == webhook_model.GOGS { + if name == webhook_model.FORGEJO || name == webhook_model.GITEA || name == webhook_model.GOGS { return true } _, ok := webhooks[name] @@ -170,7 +170,7 @@ func PrepareWebhook(ctx context.Context, w *webhook_model.Webhook, event webhook // Avoid sending "0 new commits" to non-integration relevant webhooks (e.g. slack, discord, etc.). // Integration webhooks (e.g. drone) still receive the required data. if pushEvent, ok := p.(*api.PushPayload); ok && - w.Type != webhook_model.GITEA && w.Type != webhook_model.GOGS && + w.Type != webhook_model.FORGEJO && w.Type != webhook_model.GITEA && w.Type != webhook_model.GOGS && len(pushEvent.Commits) == 0 { return nil } diff --git a/templates/admin/hook_new.tmpl b/templates/admin/hook_new.tmpl index c5196fce4e..f197dda55f 100644 --- a/templates/admin/hook_new.tmpl +++ b/templates/admin/hook_new.tmpl @@ -14,8 +14,10 @@ {{.locale.Tr "admin.defaulthooks.update_webhook"}} {{end}} <div class="ui right"> - {{if eq .HookType "gitea"}} - <img width="26" height="26" src="{{AssetUrlPrefix}}/img/gitea.svg"> + {{if eq .HookType "forgejo"}} + <img width="26" height="26" src="{{AssetUrlPrefix}}/img/forgejo.svg"> + {{else if eq .HookType "gitea"}} + <img width="26" height="26" src="{{AssetUrlPrefix}}/img/gitea-original.svg"> {{else if eq .HookType "gogs"}} <img width="26" height="26" src="{{AssetUrlPrefix}}/img/gogs.ico"> {{else if eq .HookType "slack"}} @@ -40,6 +42,7 @@ </div> </h4> <div class="ui attached segment"> + {{template "repo/settings/webhook/forgejo" .}} {{template "repo/settings/webhook/gitea" .}} {{template "repo/settings/webhook/gogs" .}} {{template "repo/settings/webhook/slack" .}} diff --git a/templates/org/settings/hook_new.tmpl b/templates/org/settings/hook_new.tmpl index 7308cafa20..a30ed6dfd9 100644 --- a/templates/org/settings/hook_new.tmpl +++ b/templates/org/settings/hook_new.tmpl @@ -9,8 +9,10 @@ <h4 class="ui top attached header"> {{if .PageIsSettingsHooksNew}}{{.locale.Tr "repo.settings.add_webhook"}}{{else}}{{.locale.Tr "repo.settings.update_webhook"}}{{end}} <div class="ui right"> - {{if eq .HookType "gitea"}} - <img width="26" height="26" src="{{AssetUrlPrefix}}/img/gitea.svg"> + {{if eq .HookType "forgejo"}} + <img width="26" height="26" src="{{AssetUrlPrefix}}/img/forgejo.svg"> + {{else if eq .HookType "gitea"}} + <img width="26" height="26" src="{{AssetUrlPrefix}}/img/gitea-original.svg"> {{else if eq .HookType "gogs"}} <img width="26" height="26" src="{{AssetUrlPrefix}}/img/gogs.ico"> {{else if eq .HookType "slack"}} diff --git a/templates/repo/settings/webhook/base_list.tmpl b/templates/repo/settings/webhook/base_list.tmpl index fa68e12ce9..c9f0a3bd7b 100644 --- a/templates/repo/settings/webhook/base_list.tmpl +++ b/templates/repo/settings/webhook/base_list.tmpl @@ -4,8 +4,11 @@ <div class="ui floating1 jump dropdown"> <div class="ui primary tiny button">{{.locale.Tr "repo.settings.add_webhook"}}</div> <div class="menu"> + <a class="item" href="{{.BaseLinkNew}}/forgejo/new"> + <img width="20" height="20" src="{{AssetUrlPrefix}}/img/forgejo.svg">{{.locale.Tr "repo.settings.web_hook_name_forgejo"}} + </a> <a class="item" href="{{.BaseLinkNew}}/gitea/new"> - <img width="20" height="20" src="{{AssetUrlPrefix}}/img/gitea.svg">{{.locale.Tr "repo.settings.web_hook_name_gitea"}} + <img width="20" height="20" src="{{AssetUrlPrefix}}/img/gitea-original.svg">{{.locale.Tr "repo.settings.web_hook_name_gitea"}} </a> <a class="item" href="{{.BaseLinkNew}}/gogs/new"> <img width="20" height="20" src="{{AssetUrlPrefix}}/img/gogs.ico">{{.locale.Tr "repo.settings.web_hook_name_gogs"}} diff --git a/templates/repo/settings/webhook/forgejo.tmpl b/templates/repo/settings/webhook/forgejo.tmpl new file mode 100644 index 0000000000..0d733f3362 --- /dev/null +++ b/templates/repo/settings/webhook/forgejo.tmpl @@ -0,0 +1,40 @@ +{{if eq .HookType "forgejo"}} + <p>{{.locale.Tr "repo.settings.add_web_hook_desc" "https://docs.gitea.io/en-us/webhooks/" (.locale.Tr "repo.settings.web_hook_name_forgejo") | Str2html}}</p> + <form class="ui form" action="{{.BaseLink}}/forgejo/{{or .Webhook.ID "new"}}" method="post"> + {{template "base/disable_form_autofill"}} + {{.CsrfTokenHtml}} + <div class="required field {{if .Err_PayloadURL}}error{{end}}"> + <label for="payload_url">{{.locale.Tr "repo.settings.payload_url"}}</label> + <input id="payload_url" name="payload_url" type="url" value="{{.Webhook.URL}}" autofocus required> + </div> + <div class="field"> + <label>{{.locale.Tr "repo.settings.http_method"}}</label> + <div class="ui selection dropdown"> + <input type="hidden" id="http_method" name="http_method" value="{{if .Webhook.HTTPMethod}}{{.Webhook.HTTPMethod}}{{else}}POST{{end}}"> + <div class="default text"></div> + {{svg "octicon-triangle-down" 14 "dropdown icon"}} + <div class="menu"> + <div class="item" data-value="POST">POST</div> + <div class="item" data-value="GET">GET</div> + </div> + </div> + </div> + <div class="field"> + <label>{{.locale.Tr "repo.settings.content_type"}}</label> + <div class="ui selection dropdown"> + <input type="hidden" id="content_type" name="content_type" value="{{if .Webhook.ContentType}}{{.Webhook.ContentType}}{{else}}1{{end}}"> + <div class="default text"></div> + {{svg "octicon-triangle-down" 14 "dropdown icon"}} + <div class="menu"> + <div class="item" data-value="1">application/json</div> + <div class="item" data-value="2">application/x-www-form-urlencoded</div> + </div> + </div> + </div> + <div class="field {{if .Err_Secret}}error{{end}}"> + <label for="secret">{{.locale.Tr "repo.settings.secret"}}</label> + <input id="secret" name="secret" type="password" value="{{.Webhook.Secret}}" autocomplete="off"> + </div> + {{template "repo/settings/webhook/settings" .}} + </form> +{{end}} diff --git a/templates/repo/settings/webhook/new.tmpl b/templates/repo/settings/webhook/new.tmpl index ea5a3eca3c..066d0045d0 100644 --- a/templates/repo/settings/webhook/new.tmpl +++ b/templates/repo/settings/webhook/new.tmpl @@ -7,8 +7,10 @@ <h4 class="ui top attached header"> {{if .PageIsSettingsHooksNew}}{{.locale.Tr "repo.settings.add_webhook"}}{{else}}{{.locale.Tr "repo.settings.update_webhook"}}{{end}} <div class="ui right"> - {{if eq .HookType "gitea"}} - <img width="26" height="26" src="{{AssetUrlPrefix}}/img/gitea.svg"> + {{if eq .HookType "forgejo"}} + <img width="26" height="26" src="{{AssetUrlPrefix}}/img/forgejo.svg"> + {{else if eq .HookType "gitea"}} + <img width="26" height="26" src="{{AssetUrlPrefix}}/img/gitea-original.svg"> {{else if eq .HookType "gogs"}} <img width="26" height="26" src="{{AssetUrlPrefix}}/img/gogs.ico"> {{else if eq .HookType "slack"}} @@ -33,6 +35,7 @@ </div> </h4> <div class="ui attached segment"> + {{template "repo/settings/webhook/forgejo" .}} {{template "repo/settings/webhook/gitea" .}} {{template "repo/settings/webhook/gogs" .}} {{template "repo/settings/webhook/slack" .}} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 9ce8a02e9d..7080e7e794 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -14465,6 +14465,7 @@ "type": { "type": "string", "enum": [ + "forgejo", "dingtalk", "discord", "gitea", diff --git a/tests/integration/links_test.go b/tests/integration/links_test.go index 4eb29f0cee..d40419a018 100644 --- a/tests/integration/links_test.go +++ b/tests/integration/links_test.go @@ -174,3 +174,41 @@ func TestLinksLogin(t *testing.T) { testLinksAsUser("user2", t) } + +func TestRedirectsWebhooks(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + // + // A redirect means the route exists but not if it performs as intended. + // + for _, kind := range []string{"forgejo", "gitea"} { + { + redirects := map[string]string{ + "/user2/repo1/settings/hooks/" + kind + "/new": "/user/login", + "/admin/system-hooks/" + kind + "/new": "/user/login", + "/admin/default-hooks/" + kind + "/new": "/user/login", + } + for link, redirectLink := range redirects { + req := NewRequest(t, "GET", link) + resp := MakeRequest(t, req, http.StatusSeeOther) + assert.EqualValues(t, path.Join(setting.AppSubURL, redirectLink), test.RedirectURL(resp)) + } + } + + { + redirects := map[string]string{ + "/user2/repo1/settings/hooks/" + kind + "/new": "/", + "/admin/system-hooks/" + kind + "/new": "/", + "/admin/default-hooks/" + kind + "/new": "/", + + "/user2/repo1/settings/hooks/" + kind + "/1": "/", + "/admin/hooks/" + kind + "/1": "/", + } + for link, redirectLink := range redirects { + req := NewRequest(t, "POST", link) + resp := MakeRequest(t, req, http.StatusSeeOther) + assert.EqualValues(t, path.Join(setting.AppSubURL, redirectLink), test.RedirectURL(resp)) + } + } + } +}