Add Gitea Webhook (#1755)
* Replace Gogs by Gitea * Fix missing changes * Create Gitea webhook and put Gogs webhook apart.
This commit is contained in:
		
							parent
							
								
									e67ece26f0
								
							
						
					
					
						commit
						e0c6ab2d44
					
				
					 11 changed files with 167 additions and 12 deletions
				
			
		|  | @ -1,4 +1,5 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved.
 | ||||
| // Copyright 2017 The Gitea Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a MIT-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
|  | @ -312,9 +313,11 @@ type HookTaskType int | |||
| const ( | ||||
| 	GOGS HookTaskType = iota + 1 | ||||
| 	SLACK | ||||
| 	GITEA | ||||
| ) | ||||
| 
 | ||||
| var hookTaskTypes = map[string]HookTaskType{ | ||||
| 	"gitea": GITEA, | ||||
| 	"gogs":  GOGS, | ||||
| 	"slack": SLACK, | ||||
| } | ||||
|  | @ -327,6 +330,8 @@ func ToHookTaskType(name string) HookTaskType { | |||
| // Name returns the name of an hook task type
 | ||||
| func (t HookTaskType) Name() string { | ||||
| 	switch t { | ||||
| 	case GITEA: | ||||
| 		return "gitea" | ||||
| 	case GOGS: | ||||
| 		return "gogs" | ||||
| 	case SLACK: | ||||
|  | @ -503,7 +508,7 @@ func PrepareWebhooks(repo *Repository, event HookEventType, p api.Payloader) err | |||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// Use separate objects so modifications won't be made on payload on non-Gogs type hooks.
 | ||||
| 		// Use separate objects so modifications won't be made on payload on non-Gogs/Gitea type hooks.
 | ||||
| 		switch w.HookTaskType { | ||||
| 		case SLACK: | ||||
| 			payloader, err = GetSlackPayload(p, event, w.Meta) | ||||
|  | @ -536,6 +541,8 @@ func (t *HookTask) deliver() { | |||
| 
 | ||||
| 	timeout := time.Duration(setting.Webhook.DeliverTimeout) * time.Second | ||||
| 	req := httplib.Post(t.URL).SetTimeout(timeout, timeout). | ||||
| 		Header("X-Gitea-Delivery", t.UUID). | ||||
| 		Header("X-Gitea-Event", string(t.EventType)). | ||||
| 		Header("X-Gogs-Delivery", t.UUID). | ||||
| 		Header("X-Gogs-Event", string(t.EventType)). | ||||
| 		Header("X-GitHub-Delivery", t.UUID). | ||||
|  |  | |||
|  | @ -191,16 +191,19 @@ func TestDeleteWebhookByOrgID(t *testing.T) { | |||
| func TestToHookTaskType(t *testing.T) { | ||||
| 	assert.Equal(t, GOGS, ToHookTaskType("gogs")) | ||||
| 	assert.Equal(t, SLACK, ToHookTaskType("slack")) | ||||
| 	assert.Equal(t, GITEA, ToHookTaskType("gitea")) | ||||
| } | ||||
| 
 | ||||
| func TestHookTaskType_Name(t *testing.T) { | ||||
| 	assert.Equal(t, "gogs", GOGS.Name()) | ||||
| 	assert.Equal(t, "slack", SLACK.Name()) | ||||
| 	assert.Equal(t, "gitea", GITEA.Name()) | ||||
| } | ||||
| 
 | ||||
| func TestIsValidHookTaskType(t *testing.T) { | ||||
| 	assert.True(t, IsValidHookTaskType("gogs")) | ||||
| 	assert.True(t, IsValidHookTaskType("slack")) | ||||
| 	assert.True(t, IsValidHookTaskType("gitea")) | ||||
| 	assert.False(t, IsValidHookTaskType("invalid")) | ||||
| } | ||||
| 
 | ||||
|  | @ -221,7 +224,7 @@ func TestCreateHookTask(t *testing.T) { | |||
| 	hookTask := &HookTask{ | ||||
| 		RepoID:    3, | ||||
| 		HookID:    3, | ||||
| 		Type:      GOGS, | ||||
| 		Type:      GITEA, | ||||
| 		URL:       "http://www.example.com/unit_test", | ||||
| 		Payloader: &api.PushPayload{}, | ||||
| 	} | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved.
 | ||||
| // Copyright 2017 The Gitea Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a MIT-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
|  | @ -154,6 +155,19 @@ func (f *NewWebhookForm) Validate(ctx *macaron.Context, errs binding.Errors) bin | |||
| 	return validate(errs, ctx.Data, f, ctx.Locale) | ||||
| } | ||||
| 
 | ||||
| // 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(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
| 	return validate(errs, ctx.Data, f, ctx.Locale) | ||||
| } | ||||
| 
 | ||||
| // NewSlackHookForm form for creating slack hook
 | ||||
| type NewSlackHookForm struct { | ||||
| 	PayloadURL string `binding:"Required;ValidUrl"` | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved.
 | ||||
| // Copyright 2017 The Gitea Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a MIT-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
|  | @ -1325,7 +1326,7 @@ func newWebhookService() { | |||
| 	Webhook.QueueLength = sec.Key("QUEUE_LENGTH").MustInt(1000) | ||||
| 	Webhook.DeliverTimeout = sec.Key("DELIVER_TIMEOUT").MustInt(5) | ||||
| 	Webhook.SkipTLSVerify = sec.Key("SKIP_TLS_VERIFY").MustBool() | ||||
| 	Webhook.Types = []string{"gogs", "slack"} | ||||
| 	Webhook.Types = []string{"gitea", "gogs", "slack"} | ||||
| 	Webhook.PagingNum = sec.Key("PAGING_NUM").MustInt(10) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										
											BIN
										
									
								
								public/img/gogs.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/img/gogs.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 28 KiB | 
|  | @ -1,4 +1,5 @@ | |||
| // Copyright 2015 The Gogs Authors. All rights reserved.
 | ||||
| // Copyright 2017 The Gitea Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a MIT-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
|  | @ -120,6 +121,53 @@ func ParseHookEvent(form auth.WebhookForm) *models.HookEvent { | |||
| 
 | ||||
| // WebHooksNewPost response for creating webhook
 | ||||
| func WebHooksNewPost(ctx *context.Context, form auth.NewWebhookForm) { | ||||
| 	ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook") | ||||
| 	ctx.Data["PageIsSettingsHooks"] = true | ||||
| 	ctx.Data["PageIsSettingsHooksNew"] = true | ||||
| 	ctx.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}} | ||||
| 	ctx.Data["HookType"] = "gitea" | ||||
| 
 | ||||
| 	orCtx, err := getOrgRepoCtx(ctx) | ||||
| 	if err != nil { | ||||
| 		ctx.Handle(500, "getOrgRepoCtx", err) | ||||
| 		return | ||||
| 	} | ||||
| 	ctx.Data["BaseLink"] = orCtx.Link | ||||
| 
 | ||||
| 	if ctx.HasError() { | ||||
| 		ctx.HTML(200, orCtx.NewTemplate) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	contentType := models.ContentTypeJSON | ||||
| 	if models.HookContentType(form.ContentType) == models.ContentTypeForm { | ||||
| 		contentType = models.ContentTypeForm | ||||
| 	} | ||||
| 
 | ||||
| 	w := &models.Webhook{ | ||||
| 		RepoID:       orCtx.RepoID, | ||||
| 		URL:          form.PayloadURL, | ||||
| 		ContentType:  contentType, | ||||
| 		Secret:       form.Secret, | ||||
| 		HookEvent:    ParseHookEvent(form.WebhookForm), | ||||
| 		IsActive:     form.Active, | ||||
| 		HookTaskType: models.GITEA, | ||||
| 		OrgID:        orCtx.OrgID, | ||||
| 	} | ||||
| 	if err := w.UpdateEvent(); err != nil { | ||||
| 		ctx.Handle(500, "UpdateEvent", err) | ||||
| 		return | ||||
| 	} else if err := models.CreateWebhook(w); err != nil { | ||||
| 		ctx.Handle(500, "CreateWebhook", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) | ||||
| 	ctx.Redirect(orCtx.Link + "/settings/hooks") | ||||
| } | ||||
| 
 | ||||
| // GogsHooksNewPost response for creating webhook
 | ||||
| func GogsHooksNewPost(ctx *context.Context, form auth.NewWebhookForm) { | ||||
| 	ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook") | ||||
| 	ctx.Data["PageIsSettingsHooks"] = true | ||||
| 	ctx.Data["PageIsSettingsHooksNew"] = true | ||||
|  | @ -150,7 +198,7 @@ func WebHooksNewPost(ctx *context.Context, form auth.NewWebhookForm) { | |||
| 		Secret:       form.Secret, | ||||
| 		HookEvent:    ParseHookEvent(form.WebhookForm), | ||||
| 		IsActive:     form.Active, | ||||
| 		HookTaskType: models.GOGS, | ||||
| 		HookTaskType: models.GITEA, | ||||
| 		OrgID:        orCtx.OrgID, | ||||
| 	} | ||||
| 	if err := w.UpdateEvent(); err != nil { | ||||
|  | @ -245,8 +293,10 @@ func checkWebhook(ctx *context.Context) (*orgRepoCtx, *models.Webhook) { | |||
| 	case models.SLACK: | ||||
| 		ctx.Data["SlackHook"] = w.GetSlackHook() | ||||
| 		ctx.Data["HookType"] = "slack" | ||||
| 	default: | ||||
| 	case models.GOGS: | ||||
| 		ctx.Data["HookType"] = "gogs" | ||||
| 	default: | ||||
| 		ctx.Data["HookType"] = "gitea" | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.Data["History"], err = w.History(1) | ||||
|  | @ -310,6 +360,45 @@ func WebHooksEditPost(ctx *context.Context, form auth.NewWebhookForm) { | |||
| 	ctx.Redirect(fmt.Sprintf("%s/settings/hooks/%d", orCtx.Link, w.ID)) | ||||
| } | ||||
| 
 | ||||
| // GogsHooksEditPost response for editing gogs hook
 | ||||
| func GogsHooksEditPost(ctx *context.Context, form auth.NewWebhookForm) { | ||||
| 	ctx.Data["Title"] = ctx.Tr("repo.settings.update_webhook") | ||||
| 	ctx.Data["PageIsSettingsHooks"] = true | ||||
| 	ctx.Data["PageIsSettingsHooksEdit"] = true | ||||
| 
 | ||||
| 	orCtx, w := checkWebhook(ctx) | ||||
| 	if ctx.Written() { | ||||
| 		return | ||||
| 	} | ||||
| 	ctx.Data["Webhook"] = w | ||||
| 
 | ||||
| 	if ctx.HasError() { | ||||
| 		ctx.HTML(200, orCtx.NewTemplate) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	contentType := models.ContentTypeJSON | ||||
| 	if models.HookContentType(form.ContentType) == models.ContentTypeForm { | ||||
| 		contentType = models.ContentTypeForm | ||||
| 	} | ||||
| 
 | ||||
| 	w.URL = form.PayloadURL | ||||
| 	w.ContentType = contentType | ||||
| 	w.Secret = form.Secret | ||||
| 	w.HookEvent = ParseHookEvent(form.WebhookForm) | ||||
| 	w.IsActive = form.Active | ||||
| 	if err := w.UpdateEvent(); err != nil { | ||||
| 		ctx.Handle(500, "UpdateEvent", err) | ||||
| 		return | ||||
| 	} else if err := models.UpdateWebhook(w); err != nil { | ||||
| 		ctx.Handle(500, "GogsHooksEditPost", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) | ||||
| 	ctx.Redirect(fmt.Sprintf("%s/settings/hooks/%d", orCtx.Link, w.ID)) | ||||
| } | ||||
| 
 | ||||
| // SlackHooksEditPost response for editing slack hook
 | ||||
| func SlackHooksEditPost(ctx *context.Context, form auth.NewSlackHookForm) { | ||||
| 	ctx.Data["Title"] = ctx.Tr("repo.settings") | ||||
|  |  | |||
|  | @ -379,10 +379,12 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| 					m.Get("", org.Webhooks) | ||||
| 					m.Post("/delete", org.DeleteWebhook) | ||||
| 					m.Get("/:type/new", repo.WebhooksNew) | ||||
| 					m.Post("/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost) | ||||
| 					m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost) | ||||
| 					m.Post("/gogs/new", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksNewPost) | ||||
| 					m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) | ||||
| 					m.Get("/:id", repo.WebHooksEdit) | ||||
| 					m.Post("/gogs/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) | ||||
| 					m.Post("/gitea/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) | ||||
| 					m.Post("/gogs/:id", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksEditPost) | ||||
| 					m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost) | ||||
| 				}) | ||||
| 
 | ||||
|  | @ -423,11 +425,13 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| 				m.Get("", repo.Webhooks) | ||||
| 				m.Post("/delete", repo.DeleteWebhook) | ||||
| 				m.Get("/:type/new", repo.WebhooksNew) | ||||
| 				m.Post("/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost) | ||||
| 				m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost) | ||||
| 				m.Post("/gogs/new", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksNewPost) | ||||
| 				m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) | ||||
| 				m.Get("/:id", repo.WebHooksEdit) | ||||
| 				m.Post("/:id/test", repo.TestWebhook) | ||||
| 				m.Post("/gogs/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) | ||||
| 				m.Post("/gitea/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) | ||||
| 				m.Post("/gogs/:id", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksNewPost) | ||||
| 				m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost) | ||||
| 
 | ||||
| 				m.Group("/git", func() { | ||||
|  |  | |||
|  | @ -9,14 +9,17 @@ | |||
| 				<h4 class="ui top attached header"> | ||||
| 					{{if .PageIsSettingsHooksNew}}{{.i18n.Tr "repo.settings.add_webhook"}}{{else}}{{.i18n.Tr "repo.settings.update_webhook"}}{{end}} | ||||
| 					<div class="ui right"> | ||||
| 						{{if eq .HookType "gogs"}} | ||||
| 						{{if eq .HookType "gitea"}} | ||||
| 							<img class="img-13" src="{{AppSubUrl}}/img/favicon.png"> | ||||
| 						{{else if eq .HookType "gogs"}} | ||||
| 							<img class="img-13" src="{{AppSubUrl}}/img/gogs.ico"> | ||||
| 						{{else if eq .HookType "slack"}} | ||||
| 							<img class="img-13" src="{{AppSubUrl}}/img/slack.png"> | ||||
| 						{{end}} | ||||
| 					</div> | ||||
| 				</h4> | ||||
| 				<div class="ui attached segment"> | ||||
| 					{{template "repo/settings/hook_gitea" .}} | ||||
| 					{{template "repo/settings/hook_gogs" .}} | ||||
| 					{{template "repo/settings/hook_slack" .}} | ||||
| 				</div> | ||||
|  |  | |||
							
								
								
									
										28
									
								
								templates/repo/settings/hook_gitea.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								templates/repo/settings/hook_gitea.tmpl
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,28 @@ | |||
| {{if eq .HookType "gitea"}} | ||||
| 	<p>{{.i18n.Tr "repo.settings.add_webhook_desc" "https://docs.gitea.io/features/webhook.html" | Str2html}}</p> | ||||
| 	<form class="ui form" action="{{.BaseLink}}/settings/hooks/gitea/{{if .PageIsSettingsHooksNew}}new{{else}}{{.Webhook.ID}}{{end}}" method="post"> | ||||
| 		{{.CsrfTokenHtml}} | ||||
| 		<div class="required field {{if .Err_PayloadURL}}error{{end}}"> | ||||
| 			<label for="payload_url">{{.i18n.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>{{.i18n.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}}application/json{{end}}"> | ||||
| 				<div class="default text"></div> | ||||
| 				<i class="dropdown icon"></i> | ||||
| 				<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> | ||||
| 		<input class="fake" type="password"> | ||||
| 		<div class="field {{if .Err_Secret}}error{{end}}"> | ||||
| 			<label for="secret">{{.i18n.Tr "repo.settings.secret"}}</label> | ||||
| 			<input id="secret" name="secret" type="password" value="{{.Webhook.Secret}}" autocomplete="off"> | ||||
| 		</div> | ||||
| 		{{template "repo/settings/hook_settings" .}} | ||||
| 	</form> | ||||
| {{end}} | ||||
|  | @ -5,9 +5,12 @@ | |||
| 		<div class="ui floating1 jump dropdown"> | ||||
| 			<div class="ui blue tiny button">{{.i18n.Tr "repo.settings.add_webhook"}}</div> | ||||
| 			<div class="menu"> | ||||
| 				<a class="item" href="{{.BaseLink}}/settings/hooks/gogs/new"> | ||||
| 				<a class="item" href="{{.BaseLink}}/settings/hooks/gitea/new"> | ||||
| 					<img class="img-10" src="{{AppSubUrl}}/img/favicon.png">Gitea | ||||
| 				</a> | ||||
| 				<a class="item" href="{{.BaseLink}}/settings/hooks/gogs/new"> | ||||
| 					<img class="img-10" src="{{AppSubUrl}}/img/gogs.ico">Gogs | ||||
| 				</a> | ||||
| 				<a class="item" href="{{.BaseLink}}/settings/hooks/slack/new"> | ||||
| 					<img class="img-10" src="{{AppSubUrl}}/img/slack.png">Slack | ||||
| 				</a> | ||||
|  |  | |||
|  | @ -7,14 +7,17 @@ | |||
| 		<h4 class="ui top attached header"> | ||||
| 			{{if .PageIsSettingsHooksNew}}{{.i18n.Tr "repo.settings.add_webhook"}}{{else}}{{.i18n.Tr "repo.settings.update_webhook"}}{{end}} | ||||
| 			<div class="ui right"> | ||||
| 				{{if eq .HookType "gogs"}} | ||||
| 				{{if eq .HookType "gitea"}} | ||||
| 					<img class="img-13" src="{{AppSubUrl}}/img/favicon.png"> | ||||
| 				{{else if eq .HookType "gogs"}} | ||||
| 					<img class="img-13" src="{{AppSubUrl}}/img/gogs.ico"> | ||||
| 				{{else if eq .HookType "slack"}} | ||||
| 					<img class="img-13" src="{{AppSubUrl}}/img/slack.png"> | ||||
| 				{{end}} | ||||
| 			</div> | ||||
| 		</h4> | ||||
| 		<div class="ui attached segment"> | ||||
| 			{{template "repo/settings/hook_gitea" .}} | ||||
| 			{{template "repo/settings/hook_gogs" .}} | ||||
| 			{{template "repo/settings/hook_slack" .}} | ||||
| 		</div> | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue