From 8dfbbfef07bb35f921e4ab4228c8006ce26dd183 Mon Sep 17 00:00:00 2001 From: oliverpool Date: Thu, 21 Mar 2024 13:23:27 +0100 Subject: [PATCH 01/11] [REFACTOR] webhook matrix endpoints --- modules/web/middleware/binding.go | 4 +- routers/web/repo/setting/webhook.go | 76 +++++++++++++++++--------- routers/web/web.go | 4 +- services/forms/repo_form.go | 14 ----- services/webhook/default.go | 4 ++ services/webhook/dingtalk.go | 3 + services/webhook/discord.go | 4 ++ services/webhook/feishu.go | 7 ++- services/webhook/matrix.go | 28 ++++++++++ services/webhook/msteams.go | 4 ++ services/webhook/packagist.go | 4 ++ services/webhook/slack.go | 4 ++ services/webhook/telegram.go | 4 ++ services/webhook/webhook.go | 15 ++++- services/webhook/wechatwork.go | 4 ++ tests/integration/repo_webhook_test.go | 4 +- 16 files changed, 134 insertions(+), 49 deletions(-) diff --git a/modules/web/middleware/binding.go b/modules/web/middleware/binding.go index 4891e43f27..8fa71a81bd 100644 --- a/modules/web/middleware/binding.go +++ b/modules/web/middleware/binding.go @@ -79,8 +79,8 @@ func GetInclude(field reflect.StructField) string { return getRuleBody(field, "Include(") } -// Validate validate TODO: -func Validate(errs binding.Errors, data map[string]any, f Form, l translation.Locale) binding.Errors { +// Validate populates the data with validation error (if any). +func Validate(errs binding.Errors, data map[string]any, f any, l translation.Locale) binding.Errors { if errs.Len() == 0 { return errs } diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index 1f78681dae..f41752e470 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -24,11 +24,14 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/modules/web/middleware" webhook_module "code.gitea.io/gitea/modules/webhook" "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/forms" webhook_service "code.gitea.io/gitea/services/webhook" + + "gitea.com/go-chi/binding" ) const ( @@ -201,6 +204,29 @@ type webhookParams struct { Meta any } +func WebhookCreate(ctx *context.Context) { + typ := ctx.Params(":type") + handler := webhook_service.GetWebhookHandler(typ) + if handler == nil { + ctx.NotFound("GetWebhookHandler", nil) + return + } + + fields := handler.FormFields(func(form any) { + errs := binding.Bind(ctx.Req, form) + middleware.Validate(errs, ctx.Data, form, ctx.Locale) // error will be checked later in ctx.HasError + }) + createWebhook(ctx, webhookParams{ + Type: typ, + URL: fields.URL, + ContentType: fields.ContentType, + Secret: fields.Secret, + HTTPMethod: fields.HTTPMethod, + WebhookForm: fields.WebhookForm, + Meta: fields.Metadata, + }) +} + func createWebhook(ctx *context.Context, params webhookParams) { ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook") ctx.Data["PageIsSettingsHooks"] = true @@ -260,6 +286,29 @@ func createWebhook(ctx *context.Context, params webhookParams) { ctx.Redirect(orCtx.Link) } +func WebhookUpdate(ctx *context.Context) { + typ := ctx.Params(":type") + handler := webhook_service.GetWebhookHandler(typ) + if handler == nil { + ctx.NotFound("GetWebhookHandler", nil) + return + } + + fields := handler.FormFields(func(form any) { + errs := binding.Bind(ctx.Req, form) + middleware.Validate(errs, ctx.Data, form, ctx.Locale) // error will be checked later in ctx.HasError + }) + editWebhook(ctx, webhookParams{ + Type: typ, + URL: fields.URL, + ContentType: fields.ContentType, + Secret: fields.Secret, + HTTPMethod: fields.HTTPMethod, + WebhookForm: fields.WebhookForm, + Meta: fields.Metadata, + }) +} + func editWebhook(ctx *context.Context, params webhookParams) { ctx.Data["Title"] = ctx.Tr("repo.settings.update_webhook") ctx.Data["PageIsSettingsHooks"] = true @@ -467,33 +516,6 @@ func telegramHookParams(ctx *context.Context) webhookParams { } } -// MatrixHooksNewPost response for creating Matrix webhook -func MatrixHooksNewPost(ctx *context.Context) { - createWebhook(ctx, matrixHookParams(ctx)) -} - -// MatrixHooksEditPost response for editing Matrix webhook -func MatrixHooksEditPost(ctx *context.Context) { - editWebhook(ctx, matrixHookParams(ctx)) -} - -func matrixHookParams(ctx *context.Context) webhookParams { - form := web.GetForm(ctx).(*forms.NewMatrixHookForm) - - return webhookParams{ - Type: webhook_module.MATRIX, - URL: fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, url.PathEscape(form.RoomID)), - ContentType: webhook.ContentTypeJSON, - HTTPMethod: http.MethodPut, - WebhookForm: form.WebhookForm, - Meta: &webhook_service.MatrixMeta{ - HomeserverURL: form.HomeserverURL, - Room: form.RoomID, - MessageType: form.MessageType, - }, - } -} - // MSTeamsHooksNewPost response for creating MSTeams webhook func MSTeamsHooksNewPost(ctx *context.Context) { createWebhook(ctx, mSTeamsHookParams(ctx)) diff --git a/routers/web/web.go b/routers/web/web.go index 50a73e9b85..b23068a29d 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -409,11 +409,11 @@ func registerRoutes(m *web.Route) { m.Post("/discord/new", web.Bind(forms.NewDiscordHookForm{}), repo_setting.DiscordHooksNewPost) m.Post("/dingtalk/new", web.Bind(forms.NewDingtalkHookForm{}), repo_setting.DingtalkHooksNewPost) m.Post("/telegram/new", web.Bind(forms.NewTelegramHookForm{}), repo_setting.TelegramHooksNewPost) - m.Post("/matrix/new", web.Bind(forms.NewMatrixHookForm{}), repo_setting.MatrixHooksNewPost) m.Post("/msteams/new", web.Bind(forms.NewMSTeamsHookForm{}), repo_setting.MSTeamsHooksNewPost) m.Post("/feishu/new", web.Bind(forms.NewFeishuHookForm{}), repo_setting.FeishuHooksNewPost) m.Post("/wechatwork/new", web.Bind(forms.NewWechatWorkHookForm{}), repo_setting.WechatworkHooksNewPost) m.Post("/packagist/new", web.Bind(forms.NewPackagistHookForm{}), repo_setting.PackagistHooksNewPost) + m.Post("/{type}/new", repo_setting.WebhookCreate) } addWebhookEditRoutes := func() { @@ -424,11 +424,11 @@ func registerRoutes(m *web.Route) { m.Post("/discord/{id}", web.Bind(forms.NewDiscordHookForm{}), repo_setting.DiscordHooksEditPost) m.Post("/dingtalk/{id}", web.Bind(forms.NewDingtalkHookForm{}), repo_setting.DingtalkHooksEditPost) m.Post("/telegram/{id}", web.Bind(forms.NewTelegramHookForm{}), repo_setting.TelegramHooksEditPost) - m.Post("/matrix/{id}", web.Bind(forms.NewMatrixHookForm{}), repo_setting.MatrixHooksEditPost) m.Post("/msteams/{id}", web.Bind(forms.NewMSTeamsHookForm{}), repo_setting.MSTeamsHooksEditPost) m.Post("/feishu/{id}", web.Bind(forms.NewFeishuHookForm{}), repo_setting.FeishuHooksEditPost) m.Post("/wechatwork/{id}", web.Bind(forms.NewWechatWorkHookForm{}), repo_setting.WechatworkHooksEditPost) m.Post("/packagist/{id}", web.Bind(forms.NewPackagistHookForm{}), repo_setting.PackagistHooksEditPost) + m.Post("/{type}/{id:[0-9]+}", repo_setting.WebhookUpdate) } addSettingsVariablesRoutes := func() { diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index f9ebb6ebaf..35d465bdd7 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -371,20 +371,6 @@ func (f *NewTelegramHookForm) Validate(req *http.Request, errs binding.Errors) b return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } -// NewMatrixHookForm form for creating Matrix hook -type NewMatrixHookForm struct { - HomeserverURL string `binding:"Required;ValidUrl"` - RoomID string `binding:"Required"` - MessageType int - WebhookForm -} - -// Validate validates the fields -func (f *NewMatrixHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { - ctx := context.GetValidateContext(req) - return middleware.Validate(errs, ctx.Data, f, ctx.Locale) -} - // NewMSTeamsHookForm form for creating MS Teams hook type NewMSTeamsHookForm struct { PayloadURL string `binding:"Required;ValidUrl"` diff --git a/services/webhook/default.go b/services/webhook/default.go index 874668bb40..d61e316a68 100644 --- a/services/webhook/default.go +++ b/services/webhook/default.go @@ -35,6 +35,10 @@ func (dh defaultHandler) Type() webhook_module.HookType { func (defaultHandler) Metadata(*webhook_model.Webhook) any { return nil } +func (defaultHandler) FormFields(bind func(any)) FormFields { + panic("TODO") +} + func (defaultHandler) NewRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (req *http.Request, body []byte, err error) { switch w.HTTPMethod { case "": diff --git a/services/webhook/dingtalk.go b/services/webhook/dingtalk.go index 4e7bef89f8..12c04d2251 100644 --- a/services/webhook/dingtalk.go +++ b/services/webhook/dingtalk.go @@ -23,6 +23,9 @@ type dingtalkHandler struct{} func (dingtalkHandler) Type() webhook_module.HookType { return webhook_module.DINGTALK } func (dingtalkHandler) Metadata(*webhook_model.Webhook) any { return nil } +func (dingtalkHandler) FormFields(bind func(any)) FormFields { + panic("TODO") +} type ( // DingtalkPayload represents diff --git a/services/webhook/discord.go b/services/webhook/discord.go index a84aa9d7b2..8ddbb13738 100644 --- a/services/webhook/discord.go +++ b/services/webhook/discord.go @@ -26,6 +26,10 @@ type discordHandler struct{} func (discordHandler) Type() webhook_module.HookType { return webhook_module.DISCORD } +func (discordHandler) FormFields(bind func(any)) FormFields { + panic("TODO") +} + type ( // DiscordEmbedFooter for Embed Footer Structure. DiscordEmbedFooter struct { diff --git a/services/webhook/feishu.go b/services/webhook/feishu.go index 2c3508e3cc..19a3a0cc03 100644 --- a/services/webhook/feishu.go +++ b/services/webhook/feishu.go @@ -17,7 +17,12 @@ import ( type feishuHandler struct{} -func (feishuHandler) Type() webhook_module.HookType { return webhook_module.FEISHU } +func (feishuHandler) Type() webhook_module.HookType { return webhook_module.FEISHU } + +func (feishuHandler) FormFields(bind func(any)) FormFields { + panic("TODO") +} + func (feishuHandler) Metadata(*webhook_model.Webhook) any { return nil } type ( diff --git a/services/webhook/matrix.go b/services/webhook/matrix.go index d1c0ec33fe..d04f0f367f 100644 --- a/services/webhook/matrix.go +++ b/services/webhook/matrix.go @@ -22,12 +22,40 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" webhook_module "code.gitea.io/gitea/modules/webhook" + "code.gitea.io/gitea/services/forms" ) type matrixHandler struct{} func (matrixHandler) Type() webhook_module.HookType { return webhook_module.MATRIX } +func (matrixHandler) FormFields(bind func(any)) FormFields { + var form struct { + forms.WebhookForm + HomeserverURL string `binding:"Required;ValidUrl"` + RoomID string `binding:"Required"` + MessageType int + + // enforce requirement of authorization_header + // (value will still be set in the embedded WebhookForm) + AuthorizationHeader string `binding:"Required"` + } + bind(&form) + + return FormFields{ + WebhookForm: form.WebhookForm, + URL: fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, url.PathEscape(form.RoomID)), + ContentType: webhook_model.ContentTypeJSON, + Secret: "", + HTTPMethod: http.MethodPut, + Metadata: &MatrixMeta{ + HomeserverURL: form.HomeserverURL, + Room: form.RoomID, + MessageType: form.MessageType, + }, + } +} + func (matrixHandler) NewRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) { meta := &MatrixMeta{} if err := json.Unmarshal([]byte(w.Meta), meta); err != nil { diff --git a/services/webhook/msteams.go b/services/webhook/msteams.go index 6d9070d088..5799884898 100644 --- a/services/webhook/msteams.go +++ b/services/webhook/msteams.go @@ -22,6 +22,10 @@ type msteamsHandler struct{} func (msteamsHandler) Type() webhook_module.HookType { return webhook_module.MSTEAMS } func (msteamsHandler) Metadata(*webhook_model.Webhook) any { return nil } +func (msteamsHandler) FormFields(bind func(any)) FormFields { + panic("TODO") +} + type ( // MSTeamsFact for Fact Structure MSTeamsFact struct { diff --git a/services/webhook/packagist.go b/services/webhook/packagist.go index d8d1937e62..9b07fe025b 100644 --- a/services/webhook/packagist.go +++ b/services/webhook/packagist.go @@ -18,6 +18,10 @@ type packagistHandler struct{} func (packagistHandler) Type() webhook_module.HookType { return webhook_module.PACKAGIST } +func (packagistHandler) FormFields(bind func(any)) FormFields { + panic("TODO") +} + type ( // PackagistPayload represents a packagist payload // as expected by https://packagist.org/about diff --git a/services/webhook/slack.go b/services/webhook/slack.go index 9b1c367e34..fdc10730de 100644 --- a/services/webhook/slack.go +++ b/services/webhook/slack.go @@ -23,6 +23,10 @@ type slackHandler struct{} func (slackHandler) Type() webhook_module.HookType { return webhook_module.SLACK } +func (slackHandler) FormFields(bind func(any)) FormFields { + panic("TODO") +} + // SlackMeta contains the slack metadata type SlackMeta struct { Channel string `json:"channel"` diff --git a/services/webhook/telegram.go b/services/webhook/telegram.go index 84e2c038f0..4179437a80 100644 --- a/services/webhook/telegram.go +++ b/services/webhook/telegram.go @@ -21,6 +21,10 @@ type telegramHandler struct{} func (telegramHandler) Type() webhook_module.HookType { return webhook_module.TELEGRAM } +func (telegramHandler) FormFields(bind func(any)) FormFields { + panic("TODO") +} + type ( // TelegramPayload represents TelegramPayload struct { diff --git a/services/webhook/webhook.go b/services/webhook/webhook.go index 62e5374fcb..a7802d27dc 100644 --- a/services/webhook/webhook.go +++ b/services/webhook/webhook.go @@ -23,14 +23,27 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" webhook_module "code.gitea.io/gitea/modules/webhook" + "code.gitea.io/gitea/services/forms" "github.com/gobwas/glob" ) type Handler interface { Type() webhook_module.HookType - NewRequest(context.Context, *webhook_model.Webhook, *webhook_model.HookTask) (req *http.Request, body []byte, err error) Metadata(*webhook_model.Webhook) any + // FormFields provides a function to bind the request to the form. + // If form implements the [binding.Validator] interface, the Validate method will be called + FormFields(bind func(form any)) FormFields + NewRequest(context.Context, *webhook_model.Webhook, *webhook_model.HookTask) (req *http.Request, body []byte, err error) +} + +type FormFields struct { + forms.WebhookForm + URL string + ContentType webhook_model.HookContentType + Secret string + HTTPMethod string + Metadata any } var webhookHandlers = []Handler{ diff --git a/services/webhook/wechatwork.go b/services/webhook/wechatwork.go index 184d83308d..6d0b12b84b 100644 --- a/services/webhook/wechatwork.go +++ b/services/webhook/wechatwork.go @@ -20,6 +20,10 @@ type wechatworkHandler struct{} func (wechatworkHandler) Type() webhook_module.HookType { return webhook_module.WECHATWORK } func (wechatworkHandler) Metadata(*webhook_model.Webhook) any { return nil } +func (wechatworkHandler) FormFields(bind func(any)) FormFields { + panic("TODO") +} + type ( // WechatworkPayload represents WechatworkPayload struct { diff --git a/tests/integration/repo_webhook_test.go b/tests/integration/repo_webhook_test.go index 3a2fa48c93..47c7a1e436 100644 --- a/tests/integration/repo_webhook_test.go +++ b/tests/integration/repo_webhook_test.go @@ -203,8 +203,8 @@ func TestWebhookForms(t *testing.T) { "homeserver_url": "https://matrix.example.com", "room_id": "123", "authorization_header": "Bearer 123456", - // }, map[string]string{ // authorization_header is actually required, but not enforced (yet) - // "authorization_header": "", + }, map[string]string{ + "authorization_header": "", })) t.Run("matrix/optional", testWebhookForms("matrix", session, map[string]string{ "homeserver_url": "https://matrix.example.com", From 7e0965b02c8cf9ecb14cdaeaeec7b1612010a603 Mon Sep 17 00:00:00 2001 From: oliverpool Date: Thu, 21 Mar 2024 13:42:40 +0100 Subject: [PATCH 02/11] [REFACTOR] webhook forgejo/gitea endpoints --- routers/web/repo/setting/webhook.go | 56 ----------------------------- routers/web/web.go | 4 --- services/forms/repo_form.go | 15 -------- services/webhook/default.go | 23 +++++++++++- 4 files changed, 22 insertions(+), 76 deletions(-) diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index f41752e470..8900942190 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -361,62 +361,6 @@ 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_module.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)) -} - -// GiteaHooksEditPost response for editing Gitea webhook -func GiteaHooksEditPost(ctx *context.Context) { - editWebhook(ctx, giteaHookParams(ctx)) -} - -func giteaHookParams(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_module.GITEA, - URL: form.PayloadURL, - ContentType: contentType, - Secret: form.Secret, - HTTPMethod: form.HTTPMethod, - WebhookForm: form.WebhookForm, - } -} - // GogsHooksNewPost response for creating Gogs webhook func GogsHooksNewPost(ctx *context.Context) { createWebhook(ctx, gogsHookParams(ctx)) diff --git a/routers/web/web.go b/routers/web/web.go index b23068a29d..06ef485422 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -402,8 +402,6 @@ func registerRoutes(m *web.Route) { addWebhookAddRoutes := func() { m.Get("/{type}/new", repo_setting.WebhooksNew) - m.Post("/forgejo/new", web.Bind(forms.NewWebhookForm{}), repo_setting.ForgejoHooksNewPost) - m.Post("/gitea/new", web.Bind(forms.NewWebhookForm{}), repo_setting.GiteaHooksNewPost) m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksNewPost) m.Post("/slack/new", web.Bind(forms.NewSlackHookForm{}), repo_setting.SlackHooksNewPost) m.Post("/discord/new", web.Bind(forms.NewDiscordHookForm{}), repo_setting.DiscordHooksNewPost) @@ -417,8 +415,6 @@ func registerRoutes(m *web.Route) { } addWebhookEditRoutes := func() { - m.Post("/forgejo/{id}", web.Bind(forms.NewWebhookForm{}), repo_setting.ForgejoHooksEditPost) - m.Post("/gitea/{id}", web.Bind(forms.NewWebhookForm{}), repo_setting.GiteaHooksEditPost) m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksEditPost) m.Post("/slack/{id}", web.Bind(forms.NewSlackHookForm{}), repo_setting.SlackHooksEditPost) m.Post("/discord/{id}", web.Bind(forms.NewDiscordHookForm{}), repo_setting.DiscordHooksEditPost) diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 35d465bdd7..5a372ab67c 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -279,21 +279,6 @@ func (f WebhookForm) ChooseEvents() bool { return f.Events == "choose_events" } -// NewWebhookForm form for creating web hook -type NewWebhookForm struct { - PayloadURL string `binding:"Required;ValidUrl"` - HTTPMethod string `binding:"Required;In(POST,GET)"` - ContentType int `binding:"Required"` - Secret string - WebhookForm -} - -// Validate validates the fields -func (f *NewWebhookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { - ctx := context.GetValidateContext(req) - return middleware.Validate(errs, ctx.Data, f, ctx.Locale) -} - // NewGogshookForm form for creating gogs hook type NewGogshookForm struct { PayloadURL string `binding:"Required;ValidUrl"` diff --git a/services/webhook/default.go b/services/webhook/default.go index d61e316a68..f725f8a783 100644 --- a/services/webhook/default.go +++ b/services/webhook/default.go @@ -18,6 +18,7 @@ import ( webhook_model "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/log" webhook_module "code.gitea.io/gitea/modules/webhook" + "code.gitea.io/gitea/services/forms" ) var _ Handler = defaultHandler{} @@ -36,7 +37,27 @@ func (dh defaultHandler) Type() webhook_module.HookType { func (defaultHandler) Metadata(*webhook_model.Webhook) any { return nil } func (defaultHandler) FormFields(bind func(any)) FormFields { - panic("TODO") + var form struct { + forms.WebhookForm + PayloadURL string `binding:"Required;ValidUrl"` + HTTPMethod string `binding:"Required;In(POST,GET)"` + ContentType int `binding:"Required"` + Secret string + } + bind(&form) + + contentType := webhook_model.ContentTypeJSON + if webhook_model.HookContentType(form.ContentType) == webhook_model.ContentTypeForm { + contentType = webhook_model.ContentTypeForm + } + return FormFields{ + WebhookForm: form.WebhookForm, + URL: form.PayloadURL, + ContentType: contentType, + Secret: form.Secret, + HTTPMethod: form.HTTPMethod, + Metadata: nil, + } } func (defaultHandler) NewRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (req *http.Request, body []byte, err error) { From 6f00821f3d3aa1eee39af93071d44433c6ff1d66 Mon Sep 17 00:00:00 2001 From: oliverpool Date: Thu, 21 Mar 2024 13:51:35 +0100 Subject: [PATCH 03/11] [REFACTOR] webhook slack endpoints --- routers/web/repo/setting/webhook.go | 27 ----------------- routers/web/web.go | 2 -- services/forms/repo_form.go | 24 --------------- services/webhook/slack.go | 45 ++++++++++++++++++++++++++++- 4 files changed, 44 insertions(+), 54 deletions(-) diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index 8900942190..ca686cac63 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -481,33 +481,6 @@ func mSTeamsHookParams(ctx *context.Context) webhookParams { } } -// SlackHooksNewPost response for creating Slack webhook -func SlackHooksNewPost(ctx *context.Context) { - createWebhook(ctx, slackHookParams(ctx)) -} - -// SlackHooksEditPost response for editing Slack webhook -func SlackHooksEditPost(ctx *context.Context) { - editWebhook(ctx, slackHookParams(ctx)) -} - -func slackHookParams(ctx *context.Context) webhookParams { - form := web.GetForm(ctx).(*forms.NewSlackHookForm) - - return webhookParams{ - Type: webhook_module.SLACK, - URL: form.PayloadURL, - ContentType: webhook.ContentTypeJSON, - WebhookForm: form.WebhookForm, - Meta: &webhook_service.SlackMeta{ - Channel: strings.TrimSpace(form.Channel), - Username: form.Username, - IconURL: form.IconURL, - Color: form.Color, - }, - } -} - // FeishuHooksNewPost response for creating Feishu webhook func FeishuHooksNewPost(ctx *context.Context) { createWebhook(ctx, feishuHookParams(ctx)) diff --git a/routers/web/web.go b/routers/web/web.go index 06ef485422..92f2680657 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -403,7 +403,6 @@ func registerRoutes(m *web.Route) { addWebhookAddRoutes := func() { m.Get("/{type}/new", repo_setting.WebhooksNew) m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksNewPost) - m.Post("/slack/new", web.Bind(forms.NewSlackHookForm{}), repo_setting.SlackHooksNewPost) m.Post("/discord/new", web.Bind(forms.NewDiscordHookForm{}), repo_setting.DiscordHooksNewPost) m.Post("/dingtalk/new", web.Bind(forms.NewDingtalkHookForm{}), repo_setting.DingtalkHooksNewPost) m.Post("/telegram/new", web.Bind(forms.NewTelegramHookForm{}), repo_setting.TelegramHooksNewPost) @@ -416,7 +415,6 @@ func registerRoutes(m *web.Route) { addWebhookEditRoutes := func() { m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksEditPost) - m.Post("/slack/{id}", web.Bind(forms.NewSlackHookForm{}), repo_setting.SlackHooksEditPost) m.Post("/discord/{id}", web.Bind(forms.NewDiscordHookForm{}), repo_setting.DiscordHooksEditPost) m.Post("/dingtalk/{id}", web.Bind(forms.NewDingtalkHookForm{}), repo_setting.DingtalkHooksEditPost) m.Post("/telegram/{id}", web.Bind(forms.NewTelegramHookForm{}), repo_setting.TelegramHooksEditPost) diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 5a372ab67c..d251faf225 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -16,7 +16,6 @@ import ( "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/services/context" - "code.gitea.io/gitea/services/webhook" "gitea.com/go-chi/binding" ) @@ -293,29 +292,6 @@ func (f *NewGogshookForm) Validate(req *http.Request, errs binding.Errors) bindi return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } -// NewSlackHookForm form for creating slack hook -type NewSlackHookForm struct { - PayloadURL string `binding:"Required;ValidUrl"` - Channel string `binding:"Required"` - Username string - IconURL string - Color string - WebhookForm -} - -// Validate validates the fields -func (f *NewSlackHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { - ctx := context.GetValidateContext(req) - if !webhook.IsValidSlackChannel(strings.TrimSpace(f.Channel)) { - errs = append(errs, binding.Error{ - FieldNames: []string{"Channel"}, - Classification: "", - Message: ctx.Locale.TrString("repo.settings.add_webhook.invalid_channel_name"), - }) - } - return middleware.Validate(errs, ctx.Data, f, ctx.Locale) -} - // NewDiscordHookForm form for creating discord hook type NewDiscordHookForm struct { PayloadURL string `binding:"Required;ValidUrl"` diff --git a/services/webhook/slack.go b/services/webhook/slack.go index fdc10730de..683ef41019 100644 --- a/services/webhook/slack.go +++ b/services/webhook/slack.go @@ -17,14 +17,57 @@ import ( "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" webhook_module "code.gitea.io/gitea/modules/webhook" + gitea_context "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/forms" + + "gitea.com/go-chi/binding" ) type slackHandler struct{} func (slackHandler) Type() webhook_module.HookType { return webhook_module.SLACK } +type slackForm struct { + forms.WebhookForm + PayloadURL string `binding:"Required;ValidUrl"` + Channel string `binding:"Required"` + Username string + IconURL string + Color string +} + +var _ binding.Validator = &slackForm{} + +// Validate implements binding.Validator. +func (s *slackForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := gitea_context.GetWebContext(req) + if !IsValidSlackChannel(strings.TrimSpace(s.Channel)) { + errs = append(errs, binding.Error{ + FieldNames: []string{"Channel"}, + Classification: "", + Message: ctx.Locale.TrString("repo.settings.add_webhook.invalid_channel_name"), + }) + } + return errs +} + func (slackHandler) FormFields(bind func(any)) FormFields { - panic("TODO") + var form slackForm + bind(&form) + + return FormFields{ + WebhookForm: form.WebhookForm, + URL: form.PayloadURL, + ContentType: webhook_model.ContentTypeJSON, + Secret: "", + HTTPMethod: http.MethodPost, + Metadata: &SlackMeta{ + Channel: strings.TrimSpace(form.Channel), + Username: form.Username, + IconURL: form.IconURL, + Color: form.Color, + }, + } } // SlackMeta contains the slack metadata From c3f8e6ed604e3b1a88b8d8d03440e2f5b7d96288 Mon Sep 17 00:00:00 2001 From: oliverpool Date: Thu, 21 Mar 2024 13:54:27 +0100 Subject: [PATCH 04/11] [REFACTOR] webhook discord endpoint --- routers/web/repo/setting/webhook.go | 25 ------------------------- routers/web/web.go | 2 -- services/forms/repo_form.go | 14 -------------- services/webhook/discord.go | 21 ++++++++++++++++++++- 4 files changed, 20 insertions(+), 42 deletions(-) diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index ca686cac63..50ff6698f2 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -388,31 +388,6 @@ func gogsHookParams(ctx *context.Context) webhookParams { } } -// DiscordHooksNewPost response for creating Discord webhook -func DiscordHooksNewPost(ctx *context.Context) { - createWebhook(ctx, discordHookParams(ctx)) -} - -// DiscordHooksEditPost response for editing Discord webhook -func DiscordHooksEditPost(ctx *context.Context) { - editWebhook(ctx, discordHookParams(ctx)) -} - -func discordHookParams(ctx *context.Context) webhookParams { - form := web.GetForm(ctx).(*forms.NewDiscordHookForm) - - return webhookParams{ - Type: webhook_module.DISCORD, - URL: form.PayloadURL, - ContentType: webhook.ContentTypeJSON, - WebhookForm: form.WebhookForm, - Meta: &webhook_service.DiscordMeta{ - Username: form.Username, - IconURL: form.IconURL, - }, - } -} - // DingtalkHooksNewPost response for creating Dingtalk webhook func DingtalkHooksNewPost(ctx *context.Context) { createWebhook(ctx, dingtalkHookParams(ctx)) diff --git a/routers/web/web.go b/routers/web/web.go index 92f2680657..9d4e07df24 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -403,7 +403,6 @@ func registerRoutes(m *web.Route) { addWebhookAddRoutes := func() { m.Get("/{type}/new", repo_setting.WebhooksNew) m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksNewPost) - m.Post("/discord/new", web.Bind(forms.NewDiscordHookForm{}), repo_setting.DiscordHooksNewPost) m.Post("/dingtalk/new", web.Bind(forms.NewDingtalkHookForm{}), repo_setting.DingtalkHooksNewPost) m.Post("/telegram/new", web.Bind(forms.NewTelegramHookForm{}), repo_setting.TelegramHooksNewPost) m.Post("/msteams/new", web.Bind(forms.NewMSTeamsHookForm{}), repo_setting.MSTeamsHooksNewPost) @@ -415,7 +414,6 @@ func registerRoutes(m *web.Route) { addWebhookEditRoutes := func() { m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksEditPost) - m.Post("/discord/{id}", web.Bind(forms.NewDiscordHookForm{}), repo_setting.DiscordHooksEditPost) m.Post("/dingtalk/{id}", web.Bind(forms.NewDingtalkHookForm{}), repo_setting.DingtalkHooksEditPost) m.Post("/telegram/{id}", web.Bind(forms.NewTelegramHookForm{}), repo_setting.TelegramHooksEditPost) m.Post("/msteams/{id}", web.Bind(forms.NewMSTeamsHookForm{}), repo_setting.MSTeamsHooksEditPost) diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index d251faf225..0614ea4c28 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -292,20 +292,6 @@ func (f *NewGogshookForm) Validate(req *http.Request, errs binding.Errors) bindi return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } -// NewDiscordHookForm form for creating discord hook -type NewDiscordHookForm struct { - PayloadURL string `binding:"Required;ValidUrl"` - Username string - IconURL string - WebhookForm -} - -// Validate validates the fields -func (f *NewDiscordHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { - ctx := context.GetValidateContext(req) - return middleware.Validate(errs, ctx.Data, f, ctx.Locale) -} - // NewDingtalkHookForm form for creating dingtalk hook type NewDingtalkHookForm struct { PayloadURL string `binding:"Required;ValidUrl"` diff --git a/services/webhook/discord.go b/services/webhook/discord.go index 8ddbb13738..3a0a973860 100644 --- a/services/webhook/discord.go +++ b/services/webhook/discord.go @@ -20,6 +20,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" webhook_module "code.gitea.io/gitea/modules/webhook" + "code.gitea.io/gitea/services/forms" ) type discordHandler struct{} @@ -27,7 +28,25 @@ type discordHandler struct{} func (discordHandler) Type() webhook_module.HookType { return webhook_module.DISCORD } func (discordHandler) FormFields(bind func(any)) FormFields { - panic("TODO") + var form struct { + forms.WebhookForm + PayloadURL string `binding:"Required;ValidUrl"` + Username string + IconURL string + } + bind(&form) + + return FormFields{ + WebhookForm: form.WebhookForm, + URL: form.PayloadURL, + ContentType: webhook_model.ContentTypeJSON, + Secret: "", + HTTPMethod: http.MethodPost, + Metadata: &DiscordMeta{ + Username: form.Username, + IconURL: form.IconURL, + }, + } } type ( From 9dff719523d0db7599262760a099a69194e187a4 Mon Sep 17 00:00:00 2001 From: oliverpool Date: Thu, 21 Mar 2024 13:57:14 +0100 Subject: [PATCH 05/11] [REFACTOR] webhook dingtalk endpoint --- routers/web/repo/setting/webhook.go | 21 --------------------- routers/web/web.go | 2 -- services/forms/repo_form.go | 12 ------------ services/webhook/dingtalk.go | 16 +++++++++++++++- 4 files changed, 15 insertions(+), 36 deletions(-) diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index 50ff6698f2..29b28cfd30 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -388,27 +388,6 @@ func gogsHookParams(ctx *context.Context) webhookParams { } } -// DingtalkHooksNewPost response for creating Dingtalk webhook -func DingtalkHooksNewPost(ctx *context.Context) { - createWebhook(ctx, dingtalkHookParams(ctx)) -} - -// DingtalkHooksEditPost response for editing Dingtalk webhook -func DingtalkHooksEditPost(ctx *context.Context) { - editWebhook(ctx, dingtalkHookParams(ctx)) -} - -func dingtalkHookParams(ctx *context.Context) webhookParams { - form := web.GetForm(ctx).(*forms.NewDingtalkHookForm) - - return webhookParams{ - Type: webhook_module.DINGTALK, - URL: form.PayloadURL, - ContentType: webhook.ContentTypeJSON, - WebhookForm: form.WebhookForm, - } -} - // TelegramHooksNewPost response for creating Telegram webhook func TelegramHooksNewPost(ctx *context.Context) { createWebhook(ctx, telegramHookParams(ctx)) diff --git a/routers/web/web.go b/routers/web/web.go index 9d4e07df24..116ffccad5 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -403,7 +403,6 @@ func registerRoutes(m *web.Route) { addWebhookAddRoutes := func() { m.Get("/{type}/new", repo_setting.WebhooksNew) m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksNewPost) - m.Post("/dingtalk/new", web.Bind(forms.NewDingtalkHookForm{}), repo_setting.DingtalkHooksNewPost) m.Post("/telegram/new", web.Bind(forms.NewTelegramHookForm{}), repo_setting.TelegramHooksNewPost) m.Post("/msteams/new", web.Bind(forms.NewMSTeamsHookForm{}), repo_setting.MSTeamsHooksNewPost) m.Post("/feishu/new", web.Bind(forms.NewFeishuHookForm{}), repo_setting.FeishuHooksNewPost) @@ -414,7 +413,6 @@ func registerRoutes(m *web.Route) { addWebhookEditRoutes := func() { m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksEditPost) - m.Post("/dingtalk/{id}", web.Bind(forms.NewDingtalkHookForm{}), repo_setting.DingtalkHooksEditPost) m.Post("/telegram/{id}", web.Bind(forms.NewTelegramHookForm{}), repo_setting.TelegramHooksEditPost) m.Post("/msteams/{id}", web.Bind(forms.NewMSTeamsHookForm{}), repo_setting.MSTeamsHooksEditPost) m.Post("/feishu/{id}", web.Bind(forms.NewFeishuHookForm{}), repo_setting.FeishuHooksEditPost) diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 0614ea4c28..891d52493c 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -292,18 +292,6 @@ func (f *NewGogshookForm) Validate(req *http.Request, errs binding.Errors) bindi return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } -// NewDingtalkHookForm form for creating dingtalk hook -type NewDingtalkHookForm struct { - PayloadURL string `binding:"Required;ValidUrl"` - WebhookForm -} - -// Validate validates the fields -func (f *NewDingtalkHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { - ctx := context.GetValidateContext(req) - return middleware.Validate(errs, ctx.Data, f, ctx.Locale) -} - // NewTelegramHookForm form for creating telegram hook type NewTelegramHookForm struct { BotToken string `binding:"Required"` diff --git a/services/webhook/dingtalk.go b/services/webhook/dingtalk.go index 12c04d2251..562e3e86eb 100644 --- a/services/webhook/dingtalk.go +++ b/services/webhook/dingtalk.go @@ -15,6 +15,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" webhook_module "code.gitea.io/gitea/modules/webhook" + "code.gitea.io/gitea/services/forms" dingtalk "gitea.com/lunny/dingtalk_webhook" ) @@ -24,7 +25,20 @@ type dingtalkHandler struct{} func (dingtalkHandler) Type() webhook_module.HookType { return webhook_module.DINGTALK } func (dingtalkHandler) Metadata(*webhook_model.Webhook) any { return nil } func (dingtalkHandler) FormFields(bind func(any)) FormFields { - panic("TODO") + var form struct { + forms.WebhookForm + PayloadURL string `binding:"Required;ValidUrl"` + } + bind(&form) + + return FormFields{ + WebhookForm: form.WebhookForm, + URL: form.PayloadURL, + ContentType: webhook_model.ContentTypeJSON, + Secret: "", + HTTPMethod: http.MethodPost, + Metadata: nil, + } } type ( From 46b71ec709de88e7dc2addcb8ca33b97535549f6 Mon Sep 17 00:00:00 2001 From: oliverpool Date: Thu, 21 Mar 2024 13:59:24 +0100 Subject: [PATCH 06/11] [REFACTOR] webhook telegram endpoint --- routers/web/repo/setting/webhook.go | 26 -------------------------- routers/web/web.go | 2 -- services/forms/repo_form.go | 14 -------------- services/webhook/telegram.go | 23 ++++++++++++++++++++++- 4 files changed, 22 insertions(+), 43 deletions(-) diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index 29b28cfd30..dc82475aae 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -388,32 +388,6 @@ func gogsHookParams(ctx *context.Context) webhookParams { } } -// TelegramHooksNewPost response for creating Telegram webhook -func TelegramHooksNewPost(ctx *context.Context) { - createWebhook(ctx, telegramHookParams(ctx)) -} - -// TelegramHooksEditPost response for editing Telegram webhook -func TelegramHooksEditPost(ctx *context.Context) { - editWebhook(ctx, telegramHookParams(ctx)) -} - -func telegramHookParams(ctx *context.Context) webhookParams { - form := web.GetForm(ctx).(*forms.NewTelegramHookForm) - - return webhookParams{ - Type: webhook_module.TELEGRAM, - URL: fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s&message_thread_id=%s", url.PathEscape(form.BotToken), url.QueryEscape(form.ChatID), url.QueryEscape(form.ThreadID)), - ContentType: webhook.ContentTypeJSON, - WebhookForm: form.WebhookForm, - Meta: &webhook_service.TelegramMeta{ - BotToken: form.BotToken, - ChatID: form.ChatID, - ThreadID: form.ThreadID, - }, - } -} - // MSTeamsHooksNewPost response for creating MSTeams webhook func MSTeamsHooksNewPost(ctx *context.Context) { createWebhook(ctx, mSTeamsHookParams(ctx)) diff --git a/routers/web/web.go b/routers/web/web.go index 116ffccad5..7e41d7ed49 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -403,7 +403,6 @@ func registerRoutes(m *web.Route) { addWebhookAddRoutes := func() { m.Get("/{type}/new", repo_setting.WebhooksNew) m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksNewPost) - m.Post("/telegram/new", web.Bind(forms.NewTelegramHookForm{}), repo_setting.TelegramHooksNewPost) m.Post("/msteams/new", web.Bind(forms.NewMSTeamsHookForm{}), repo_setting.MSTeamsHooksNewPost) m.Post("/feishu/new", web.Bind(forms.NewFeishuHookForm{}), repo_setting.FeishuHooksNewPost) m.Post("/wechatwork/new", web.Bind(forms.NewWechatWorkHookForm{}), repo_setting.WechatworkHooksNewPost) @@ -413,7 +412,6 @@ func registerRoutes(m *web.Route) { addWebhookEditRoutes := func() { m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksEditPost) - m.Post("/telegram/{id}", web.Bind(forms.NewTelegramHookForm{}), repo_setting.TelegramHooksEditPost) m.Post("/msteams/{id}", web.Bind(forms.NewMSTeamsHookForm{}), repo_setting.MSTeamsHooksEditPost) m.Post("/feishu/{id}", web.Bind(forms.NewFeishuHookForm{}), repo_setting.FeishuHooksEditPost) m.Post("/wechatwork/{id}", web.Bind(forms.NewWechatWorkHookForm{}), repo_setting.WechatworkHooksEditPost) diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 891d52493c..3c800d86ee 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -292,20 +292,6 @@ func (f *NewGogshookForm) Validate(req *http.Request, errs binding.Errors) bindi return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } -// NewTelegramHookForm form for creating telegram hook -type NewTelegramHookForm struct { - BotToken string `binding:"Required"` - ChatID string `binding:"Required"` - ThreadID string - WebhookForm -} - -// Validate validates the fields -func (f *NewTelegramHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { - ctx := context.GetValidateContext(req) - return middleware.Validate(errs, ctx.Data, f, ctx.Locale) -} - // NewMSTeamsHookForm form for creating MS Teams hook type NewMSTeamsHookForm struct { PayloadURL string `binding:"Required;ValidUrl"` diff --git a/services/webhook/telegram.go b/services/webhook/telegram.go index 4179437a80..2ede28dbd2 100644 --- a/services/webhook/telegram.go +++ b/services/webhook/telegram.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "net/http" + "net/url" "strings" webhook_model "code.gitea.io/gitea/models/webhook" @@ -15,6 +16,7 @@ import ( "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" webhook_module "code.gitea.io/gitea/modules/webhook" + "code.gitea.io/gitea/services/forms" ) type telegramHandler struct{} @@ -22,7 +24,26 @@ type telegramHandler struct{} func (telegramHandler) Type() webhook_module.HookType { return webhook_module.TELEGRAM } func (telegramHandler) FormFields(bind func(any)) FormFields { - panic("TODO") + var form struct { + forms.WebhookForm + BotToken string `binding:"Required"` + ChatID string `binding:"Required"` + ThreadID string + } + bind(&form) + + return FormFields{ + WebhookForm: form.WebhookForm, + URL: fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s&message_thread_id=%s", url.PathEscape(form.BotToken), url.QueryEscape(form.ChatID), url.QueryEscape(form.ThreadID)), + ContentType: webhook_model.ContentTypeJSON, + Secret: "", + HTTPMethod: http.MethodPost, + Metadata: &TelegramMeta{ + BotToken: form.BotToken, + ChatID: form.ChatID, + ThreadID: form.ThreadID, + }, + } } type ( From 97f0ad49ff6245c026265d50da788b8437c7b52f Mon Sep 17 00:00:00 2001 From: oliverpool Date: Thu, 21 Mar 2024 14:01:02 +0100 Subject: [PATCH 07/11] [REFACTOR] webhook msteams endpoint --- routers/web/repo/setting/webhook.go | 21 --------------------- routers/web/web.go | 2 -- services/forms/repo_form.go | 12 ------------ services/webhook/msteams.go | 16 +++++++++++++++- 4 files changed, 15 insertions(+), 36 deletions(-) diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index dc82475aae..ead24614f1 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -388,27 +388,6 @@ func gogsHookParams(ctx *context.Context) webhookParams { } } -// MSTeamsHooksNewPost response for creating MSTeams webhook -func MSTeamsHooksNewPost(ctx *context.Context) { - createWebhook(ctx, mSTeamsHookParams(ctx)) -} - -// MSTeamsHooksEditPost response for editing MSTeams webhook -func MSTeamsHooksEditPost(ctx *context.Context) { - editWebhook(ctx, mSTeamsHookParams(ctx)) -} - -func mSTeamsHookParams(ctx *context.Context) webhookParams { - form := web.GetForm(ctx).(*forms.NewMSTeamsHookForm) - - return webhookParams{ - Type: webhook_module.MSTEAMS, - URL: form.PayloadURL, - ContentType: webhook.ContentTypeJSON, - WebhookForm: form.WebhookForm, - } -} - // FeishuHooksNewPost response for creating Feishu webhook func FeishuHooksNewPost(ctx *context.Context) { createWebhook(ctx, feishuHookParams(ctx)) diff --git a/routers/web/web.go b/routers/web/web.go index 7e41d7ed49..6d2e380e06 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -403,7 +403,6 @@ func registerRoutes(m *web.Route) { addWebhookAddRoutes := func() { m.Get("/{type}/new", repo_setting.WebhooksNew) m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksNewPost) - m.Post("/msteams/new", web.Bind(forms.NewMSTeamsHookForm{}), repo_setting.MSTeamsHooksNewPost) m.Post("/feishu/new", web.Bind(forms.NewFeishuHookForm{}), repo_setting.FeishuHooksNewPost) m.Post("/wechatwork/new", web.Bind(forms.NewWechatWorkHookForm{}), repo_setting.WechatworkHooksNewPost) m.Post("/packagist/new", web.Bind(forms.NewPackagistHookForm{}), repo_setting.PackagistHooksNewPost) @@ -412,7 +411,6 @@ func registerRoutes(m *web.Route) { addWebhookEditRoutes := func() { m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksEditPost) - m.Post("/msteams/{id}", web.Bind(forms.NewMSTeamsHookForm{}), repo_setting.MSTeamsHooksEditPost) m.Post("/feishu/{id}", web.Bind(forms.NewFeishuHookForm{}), repo_setting.FeishuHooksEditPost) m.Post("/wechatwork/{id}", web.Bind(forms.NewWechatWorkHookForm{}), repo_setting.WechatworkHooksEditPost) m.Post("/packagist/{id}", web.Bind(forms.NewPackagistHookForm{}), repo_setting.PackagistHooksEditPost) diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 3c800d86ee..2e30106ea2 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -292,18 +292,6 @@ func (f *NewGogshookForm) Validate(req *http.Request, errs binding.Errors) bindi return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } -// NewMSTeamsHookForm form for creating MS Teams hook -type NewMSTeamsHookForm struct { - PayloadURL string `binding:"Required;ValidUrl"` - WebhookForm -} - -// Validate validates the fields -func (f *NewMSTeamsHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { - ctx := context.GetValidateContext(req) - return middleware.Validate(errs, ctx.Data, f, ctx.Locale) -} - // NewFeishuHookForm form for creating feishu hook type NewFeishuHookForm struct { PayloadURL string `binding:"Required;ValidUrl"` diff --git a/services/webhook/msteams.go b/services/webhook/msteams.go index 5799884898..849093e9bf 100644 --- a/services/webhook/msteams.go +++ b/services/webhook/msteams.go @@ -15,6 +15,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" webhook_module "code.gitea.io/gitea/modules/webhook" + "code.gitea.io/gitea/services/forms" ) type msteamsHandler struct{} @@ -23,7 +24,20 @@ func (msteamsHandler) Type() webhook_module.HookType { return webhook_modu func (msteamsHandler) Metadata(*webhook_model.Webhook) any { return nil } func (msteamsHandler) FormFields(bind func(any)) FormFields { - panic("TODO") + var form struct { + forms.WebhookForm + PayloadURL string `binding:"Required;ValidUrl"` + } + bind(&form) + + return FormFields{ + WebhookForm: form.WebhookForm, + URL: form.PayloadURL, + ContentType: webhook_model.ContentTypeJSON, + Secret: "", + HTTPMethod: http.MethodPost, + Metadata: nil, + } } type ( From 6b719f08d0fed21502925d86cfd94cad19510b2c Mon Sep 17 00:00:00 2001 From: oliverpool Date: Thu, 21 Mar 2024 14:02:14 +0100 Subject: [PATCH 08/11] [REFACTOR] webhook feishu endpoint --- routers/web/repo/setting/webhook.go | 21 --------------------- routers/web/web.go | 2 -- services/forms/repo_form.go | 12 ------------ services/webhook/feishu.go | 16 +++++++++++++++- 4 files changed, 15 insertions(+), 36 deletions(-) diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index ead24614f1..b44da2510b 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -388,27 +388,6 @@ func gogsHookParams(ctx *context.Context) webhookParams { } } -// FeishuHooksNewPost response for creating Feishu webhook -func FeishuHooksNewPost(ctx *context.Context) { - createWebhook(ctx, feishuHookParams(ctx)) -} - -// FeishuHooksEditPost response for editing Feishu webhook -func FeishuHooksEditPost(ctx *context.Context) { - editWebhook(ctx, feishuHookParams(ctx)) -} - -func feishuHookParams(ctx *context.Context) webhookParams { - form := web.GetForm(ctx).(*forms.NewFeishuHookForm) - - return webhookParams{ - Type: webhook_module.FEISHU, - URL: form.PayloadURL, - ContentType: webhook.ContentTypeJSON, - WebhookForm: form.WebhookForm, - } -} - // WechatworkHooksNewPost response for creating Wechatwork webhook func WechatworkHooksNewPost(ctx *context.Context) { createWebhook(ctx, wechatworkHookParams(ctx)) diff --git a/routers/web/web.go b/routers/web/web.go index 6d2e380e06..fb4510af5b 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -403,7 +403,6 @@ func registerRoutes(m *web.Route) { addWebhookAddRoutes := func() { m.Get("/{type}/new", repo_setting.WebhooksNew) m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksNewPost) - m.Post("/feishu/new", web.Bind(forms.NewFeishuHookForm{}), repo_setting.FeishuHooksNewPost) m.Post("/wechatwork/new", web.Bind(forms.NewWechatWorkHookForm{}), repo_setting.WechatworkHooksNewPost) m.Post("/packagist/new", web.Bind(forms.NewPackagistHookForm{}), repo_setting.PackagistHooksNewPost) m.Post("/{type}/new", repo_setting.WebhookCreate) @@ -411,7 +410,6 @@ func registerRoutes(m *web.Route) { addWebhookEditRoutes := func() { m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksEditPost) - m.Post("/feishu/{id}", web.Bind(forms.NewFeishuHookForm{}), repo_setting.FeishuHooksEditPost) m.Post("/wechatwork/{id}", web.Bind(forms.NewWechatWorkHookForm{}), repo_setting.WechatworkHooksEditPost) m.Post("/packagist/{id}", web.Bind(forms.NewPackagistHookForm{}), repo_setting.PackagistHooksEditPost) m.Post("/{type}/{id:[0-9]+}", repo_setting.WebhookUpdate) diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 2e30106ea2..a5c5bf3d16 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -292,18 +292,6 @@ func (f *NewGogshookForm) Validate(req *http.Request, errs binding.Errors) bindi return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } -// NewFeishuHookForm form for creating feishu hook -type NewFeishuHookForm struct { - PayloadURL string `binding:"Required;ValidUrl"` - WebhookForm -} - -// Validate validates the fields -func (f *NewFeishuHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { - ctx := context.GetValidateContext(req) - return middleware.Validate(errs, ctx.Data, f, ctx.Locale) -} - // NewWechatWorkHookForm form for creating wechatwork hook type NewWechatWorkHookForm struct { PayloadURL string `binding:"Required;ValidUrl"` diff --git a/services/webhook/feishu.go b/services/webhook/feishu.go index 19a3a0cc03..b27acc9070 100644 --- a/services/webhook/feishu.go +++ b/services/webhook/feishu.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" webhook_module "code.gitea.io/gitea/modules/webhook" + "code.gitea.io/gitea/services/forms" ) type feishuHandler struct{} @@ -20,7 +21,20 @@ type feishuHandler struct{} func (feishuHandler) Type() webhook_module.HookType { return webhook_module.FEISHU } func (feishuHandler) FormFields(bind func(any)) FormFields { - panic("TODO") + var form struct { + forms.WebhookForm + PayloadURL string `binding:"Required;ValidUrl"` + } + bind(&form) + + return FormFields{ + WebhookForm: form.WebhookForm, + URL: form.PayloadURL, + ContentType: webhook_model.ContentTypeJSON, + Secret: "", + HTTPMethod: http.MethodPost, + Metadata: nil, + } } func (feishuHandler) Metadata(*webhook_model.Webhook) any { return nil } From 36a1d375326293b176768d11a82937db30e63d92 Mon Sep 17 00:00:00 2001 From: oliverpool Date: Thu, 21 Mar 2024 14:03:15 +0100 Subject: [PATCH 09/11] [REFACTOR] webhook wechatwork endpoint --- routers/web/repo/setting/webhook.go | 21 --------------------- routers/web/web.go | 2 -- services/forms/repo_form.go | 12 ------------ services/webhook/wechatwork.go | 16 +++++++++++++++- 4 files changed, 15 insertions(+), 36 deletions(-) diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index b44da2510b..a1021c1967 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -388,27 +388,6 @@ func gogsHookParams(ctx *context.Context) webhookParams { } } -// WechatworkHooksNewPost response for creating Wechatwork webhook -func WechatworkHooksNewPost(ctx *context.Context) { - createWebhook(ctx, wechatworkHookParams(ctx)) -} - -// WechatworkHooksEditPost response for editing Wechatwork webhook -func WechatworkHooksEditPost(ctx *context.Context) { - editWebhook(ctx, wechatworkHookParams(ctx)) -} - -func wechatworkHookParams(ctx *context.Context) webhookParams { - form := web.GetForm(ctx).(*forms.NewWechatWorkHookForm) - - return webhookParams{ - Type: webhook_module.WECHATWORK, - URL: form.PayloadURL, - ContentType: webhook.ContentTypeJSON, - WebhookForm: form.WebhookForm, - } -} - // PackagistHooksNewPost response for creating Packagist webhook func PackagistHooksNewPost(ctx *context.Context) { createWebhook(ctx, packagistHookParams(ctx)) diff --git a/routers/web/web.go b/routers/web/web.go index fb4510af5b..81ff59499d 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -403,14 +403,12 @@ func registerRoutes(m *web.Route) { addWebhookAddRoutes := func() { m.Get("/{type}/new", repo_setting.WebhooksNew) m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksNewPost) - m.Post("/wechatwork/new", web.Bind(forms.NewWechatWorkHookForm{}), repo_setting.WechatworkHooksNewPost) m.Post("/packagist/new", web.Bind(forms.NewPackagistHookForm{}), repo_setting.PackagistHooksNewPost) m.Post("/{type}/new", repo_setting.WebhookCreate) } addWebhookEditRoutes := func() { m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksEditPost) - m.Post("/wechatwork/{id}", web.Bind(forms.NewWechatWorkHookForm{}), repo_setting.WechatworkHooksEditPost) m.Post("/packagist/{id}", web.Bind(forms.NewPackagistHookForm{}), repo_setting.PackagistHooksEditPost) m.Post("/{type}/{id:[0-9]+}", repo_setting.WebhookUpdate) } diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index a5c5bf3d16..e1d29943a0 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -292,18 +292,6 @@ func (f *NewGogshookForm) Validate(req *http.Request, errs binding.Errors) bindi return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } -// NewWechatWorkHookForm form for creating wechatwork hook -type NewWechatWorkHookForm struct { - PayloadURL string `binding:"Required;ValidUrl"` - WebhookForm -} - -// Validate validates the fields -func (f *NewWechatWorkHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { - ctx := context.GetValidateContext(req) - return middleware.Validate(errs, ctx.Data, f, ctx.Locale) -} - // NewPackagistHookForm form for creating packagist hook type NewPackagistHookForm struct { Username string `binding:"Required"` diff --git a/services/webhook/wechatwork.go b/services/webhook/wechatwork.go index 6d0b12b84b..2ad2acd018 100644 --- a/services/webhook/wechatwork.go +++ b/services/webhook/wechatwork.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" webhook_module "code.gitea.io/gitea/modules/webhook" + "code.gitea.io/gitea/services/forms" ) type wechatworkHandler struct{} @@ -21,7 +22,20 @@ func (wechatworkHandler) Type() webhook_module.HookType { return webhook_m func (wechatworkHandler) Metadata(*webhook_model.Webhook) any { return nil } func (wechatworkHandler) FormFields(bind func(any)) FormFields { - panic("TODO") + var form struct { + forms.WebhookForm + PayloadURL string `binding:"Required;ValidUrl"` + } + bind(&form) + + return FormFields{ + WebhookForm: form.WebhookForm, + URL: form.PayloadURL, + ContentType: webhook_model.ContentTypeJSON, + Secret: "", + HTTPMethod: http.MethodPost, + Metadata: nil, + } } type ( From dce754cde180903d349fbca611ec1b8ab90ea5e2 Mon Sep 17 00:00:00 2001 From: oliverpool Date: Thu, 21 Mar 2024 14:04:37 +0100 Subject: [PATCH 10/11] [REFACTOR] webhook packagist endpoint --- routers/web/repo/setting/webhook.go | 26 -------------------------- routers/web/web.go | 2 -- services/forms/repo_form.go | 14 -------------- services/webhook/packagist.go | 23 ++++++++++++++++++++++- 4 files changed, 22 insertions(+), 43 deletions(-) diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index a1021c1967..ea36da649f 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -388,32 +388,6 @@ func gogsHookParams(ctx *context.Context) webhookParams { } } -// PackagistHooksNewPost response for creating Packagist webhook -func PackagistHooksNewPost(ctx *context.Context) { - createWebhook(ctx, packagistHookParams(ctx)) -} - -// PackagistHooksEditPost response for editing Packagist webhook -func PackagistHooksEditPost(ctx *context.Context) { - editWebhook(ctx, packagistHookParams(ctx)) -} - -func packagistHookParams(ctx *context.Context) webhookParams { - form := web.GetForm(ctx).(*forms.NewPackagistHookForm) - - return webhookParams{ - Type: webhook_module.PACKAGIST, - URL: fmt.Sprintf("https://packagist.org/api/update-package?username=%s&apiToken=%s", url.QueryEscape(form.Username), url.QueryEscape(form.APIToken)), - ContentType: webhook.ContentTypeJSON, - WebhookForm: form.WebhookForm, - Meta: &webhook_service.PackagistMeta{ - Username: form.Username, - APIToken: form.APIToken, - PackageURL: form.PackageURL, - }, - } -} - func checkWebhook(ctx *context.Context) (*ownerRepoCtx, *webhook.Webhook) { orCtx, err := getOwnerRepoCtx(ctx) if err != nil { diff --git a/routers/web/web.go b/routers/web/web.go index 81ff59499d..4b44a8eac5 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -403,13 +403,11 @@ func registerRoutes(m *web.Route) { addWebhookAddRoutes := func() { m.Get("/{type}/new", repo_setting.WebhooksNew) m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksNewPost) - m.Post("/packagist/new", web.Bind(forms.NewPackagistHookForm{}), repo_setting.PackagistHooksNewPost) m.Post("/{type}/new", repo_setting.WebhookCreate) } addWebhookEditRoutes := func() { m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksEditPost) - m.Post("/packagist/{id}", web.Bind(forms.NewPackagistHookForm{}), repo_setting.PackagistHooksEditPost) m.Post("/{type}/{id:[0-9]+}", repo_setting.WebhookUpdate) } diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index e1d29943a0..7613feabda 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -292,20 +292,6 @@ func (f *NewGogshookForm) Validate(req *http.Request, errs binding.Errors) bindi return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } -// NewPackagistHookForm form for creating packagist hook -type NewPackagistHookForm struct { - Username string `binding:"Required"` - APIToken string `binding:"Required"` - PackageURL string `binding:"Required;ValidUrl"` - WebhookForm -} - -// Validate validates the fields -func (f *NewPackagistHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { - ctx := context.GetValidateContext(req) - return middleware.Validate(errs, ctx.Data, f, ctx.Locale) -} - // .___ // | | ______ ________ __ ____ // | |/ ___// ___/ | \_/ __ \ diff --git a/services/webhook/packagist.go b/services/webhook/packagist.go index 9b07fe025b..d8bf9ea23a 100644 --- a/services/webhook/packagist.go +++ b/services/webhook/packagist.go @@ -7,11 +7,13 @@ import ( "context" "fmt" "net/http" + "net/url" webhook_model "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" webhook_module "code.gitea.io/gitea/modules/webhook" + "code.gitea.io/gitea/services/forms" ) type packagistHandler struct{} @@ -19,7 +21,26 @@ type packagistHandler struct{} func (packagistHandler) Type() webhook_module.HookType { return webhook_module.PACKAGIST } func (packagistHandler) FormFields(bind func(any)) FormFields { - panic("TODO") + var form struct { + forms.WebhookForm + Username string `binding:"Required"` + APIToken string `binding:"Required"` + PackageURL string `binding:"Required;ValidUrl"` + } + bind(&form) + + return FormFields{ + WebhookForm: form.WebhookForm, + URL: fmt.Sprintf("https://packagist.org/api/update-package?username=%s&apiToken=%s", url.QueryEscape(form.Username), url.QueryEscape(form.APIToken)), + ContentType: webhook_model.ContentTypeJSON, + Secret: "", + HTTPMethod: http.MethodPost, + Metadata: &PackagistMeta{ + Username: form.Username, + APIToken: form.APIToken, + PackageURL: form.PackageURL, + }, + } } type ( From 4ab341e9714b59fa009af44fb7de61642b6e6e86 Mon Sep 17 00:00:00 2001 From: oliverpool Date: Thu, 21 Mar 2024 14:09:49 +0100 Subject: [PATCH 11/11] [REFACTOR] webhook gogs endpoint --- routers/web/repo/setting/webhook.go | 28 ---------------------------- routers/web/web.go | 2 -- services/forms/repo_form.go | 14 -------------- services/webhook/gogs.go | 27 +++++++++++++++++++++++++++ 4 files changed, 27 insertions(+), 44 deletions(-) diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index ea36da649f..e89fcef39a 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -23,7 +23,6 @@ import ( "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" - "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web/middleware" webhook_module "code.gitea.io/gitea/modules/webhook" "code.gitea.io/gitea/services/context" @@ -361,33 +360,6 @@ func editWebhook(ctx *context.Context, params webhookParams) { ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID)) } -// GogsHooksNewPost response for creating Gogs webhook -func GogsHooksNewPost(ctx *context.Context) { - createWebhook(ctx, gogsHookParams(ctx)) -} - -// GogsHooksEditPost response for editing Gogs webhook -func GogsHooksEditPost(ctx *context.Context) { - editWebhook(ctx, gogsHookParams(ctx)) -} - -func gogsHookParams(ctx *context.Context) webhookParams { - form := web.GetForm(ctx).(*forms.NewGogshookForm) - - contentType := webhook.ContentTypeJSON - if webhook.HookContentType(form.ContentType) == webhook.ContentTypeForm { - contentType = webhook.ContentTypeForm - } - - return webhookParams{ - Type: webhook_module.GOGS, - URL: form.PayloadURL, - ContentType: contentType, - Secret: form.Secret, - WebhookForm: form.WebhookForm, - } -} - func checkWebhook(ctx *context.Context) (*ownerRepoCtx, *webhook.Webhook) { orCtx, err := getOwnerRepoCtx(ctx) if err != nil { diff --git a/routers/web/web.go b/routers/web/web.go index 4b44a8eac5..348b9546c7 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -402,12 +402,10 @@ func registerRoutes(m *web.Route) { addWebhookAddRoutes := func() { m.Get("/{type}/new", repo_setting.WebhooksNew) - m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksNewPost) m.Post("/{type}/new", repo_setting.WebhookCreate) } addWebhookEditRoutes := func() { - m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksEditPost) m.Post("/{type}/{id:[0-9]+}", repo_setting.WebhookUpdate) } diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 7613feabda..0f7665804d 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -278,20 +278,6 @@ func (f WebhookForm) ChooseEvents() bool { return f.Events == "choose_events" } -// NewGogshookForm form for creating gogs hook -type NewGogshookForm struct { - PayloadURL string `binding:"Required;ValidUrl"` - ContentType int `binding:"Required"` - Secret string - WebhookForm -} - -// Validate validates the fields -func (f *NewGogshookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { - ctx := context.GetValidateContext(req) - return middleware.Validate(errs, ctx.Data, f, ctx.Locale) -} - // .___ // | | ______ ________ __ ____ // | |/ ___// ___/ | \_/ __ \ diff --git a/services/webhook/gogs.go b/services/webhook/gogs.go index 2ecd9e6d09..e23673ed35 100644 --- a/services/webhook/gogs.go +++ b/services/webhook/gogs.go @@ -4,9 +4,36 @@ package webhook import ( + "net/http" + + webhook_model "code.gitea.io/gitea/models/webhook" webhook_module "code.gitea.io/gitea/modules/webhook" + "code.gitea.io/gitea/services/forms" ) type gogsHandler struct{ defaultHandler } func (gogsHandler) Type() webhook_module.HookType { return webhook_module.GOGS } + +func (gogsHandler) FormFields(bind func(any)) FormFields { + var form struct { + forms.WebhookForm + PayloadURL string `binding:"Required;ValidUrl"` + ContentType int `binding:"Required"` + Secret string + } + bind(&form) + + contentType := webhook_model.ContentTypeJSON + if webhook_model.HookContentType(form.ContentType) == webhook_model.ContentTypeForm { + contentType = webhook_model.ContentTypeForm + } + return FormFields{ + WebhookForm: form.WebhookForm, + URL: form.PayloadURL, + ContentType: contentType, + Secret: form.Secret, + HTTPMethod: http.MethodPost, + Metadata: nil, + } +}