* Create system webhook column (and migration)
* Create system webhook DB methods
Based on the default webhook ones
* Modify router to handle system webhooks and default ones
* Remove old unused admin nav template
* Adjust orgRepoCtx to differentiate system and default webhook URLs
* Assign IsSystemWebhook when creating webhooks
* Correctly use booleans for IsSystemWebhook
* Use system webhooks when preparing webhooks for payload
* Add UI and locale changes
* Use router params to differentiate admin hook pages
* Fix deleting admin webhooks and rename method
* Add clarity to webhook docs
* Revert "Remove old unused admin nav template"
This reverts commit 191a20a738
.
* Rename WebHooksNewPost to GiteaHooksNewPost for clarity
* Reintroduce blank line lost during merge conflict
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Lauris BH <lauris@nix.lv>
tags/v1.12.0-dev
@@ -15,24 +15,24 @@ menu: | |||
# Webhooks | |||
Gitea supports web hooks for repository events. This can be found in the settings | |||
page `/:username/:reponame/settings/hooks`. All event pushes are POST requests. | |||
The methods currently supported are: | |||
Gitea supports web hooks for repository events. This can be configured in the settings | |||
page `/:username/:reponame/settings/hooks` by a repository admin. Webhooks can also be configured on a per-organization and whole system basis. | |||
All event pushes are POST requests. The methods currently supported are: | |||
- Gitea | |||
- Gitea (can also be a GET request) | |||
- Gogs | |||
- Slack | |||
- Discord | |||
- Dingtalk | |||
- Telegram | |||
- Microsoft Teams | |||
- Feishu | |||
### Event information | |||
The following is an example of event information that will be sent by Gitea to | |||
a Payload URL: | |||
``` | |||
X-GitHub-Delivery: f6266f16-1bf3-46a5-9ea4-602e06ead473 | |||
X-GitHub-Event: push |
@@ -194,6 +194,8 @@ var migrations = []Migration{ | |||
NewMigration("remove dependencies from deleted repositories", purgeUnusedDependencies), | |||
// v130 -> v131 | |||
NewMigration("Expand webhooks for more granularity", expandWebhooks), | |||
// v131 -> v132 | |||
NewMigration("Add IsSystemWebhook column to webhooks table", addSystemWebhookColumn), | |||
} | |||
// Migrate database to current version |
@@ -0,0 +1,22 @@ | |||
// Copyright 2020 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. | |||
package migrations | |||
import ( | |||
"fmt" | |||
"xorm.io/xorm" | |||
) | |||
func addSystemWebhookColumn(x *xorm.Engine) error { | |||
type Webhook struct { | |||
IsSystemWebhook bool `xorm:"NOT NULL DEFAULT false"` | |||
} | |||
if err := x.Sync2(new(Webhook)); err != nil { | |||
return fmt.Errorf("Sync2: %v", err) | |||
} | |||
return nil | |||
} |
@@ -99,21 +99,22 @@ const ( | |||
// Webhook represents a web hook object. | |||
type Webhook struct { | |||
ID int64 `xorm:"pk autoincr"` | |||
RepoID int64 `xorm:"INDEX"` | |||
OrgID int64 `xorm:"INDEX"` | |||
URL string `xorm:"url TEXT"` | |||
Signature string `xorm:"TEXT"` | |||
HTTPMethod string `xorm:"http_method"` | |||
ContentType HookContentType | |||
Secret string `xorm:"TEXT"` | |||
Events string `xorm:"TEXT"` | |||
*HookEvent `xorm:"-"` | |||
IsSSL bool `xorm:"is_ssl"` | |||
IsActive bool `xorm:"INDEX"` | |||
HookTaskType HookTaskType | |||
Meta string `xorm:"TEXT"` // store hook-specific attributes | |||
LastStatus HookStatus // Last delivery status | |||
ID int64 `xorm:"pk autoincr"` | |||
RepoID int64 `xorm:"INDEX"` // An ID of 0 indicates either a default or system webhook | |||
OrgID int64 `xorm:"INDEX"` | |||
IsSystemWebhook bool | |||
URL string `xorm:"url TEXT"` | |||
Signature string `xorm:"TEXT"` | |||
HTTPMethod string `xorm:"http_method"` | |||
ContentType HookContentType | |||
Secret string `xorm:"TEXT"` | |||
Events string `xorm:"TEXT"` | |||
*HookEvent `xorm:"-"` | |||
IsSSL bool `xorm:"is_ssl"` | |||
IsActive bool `xorm:"INDEX"` | |||
HookTaskType HookTaskType | |||
Meta string `xorm:"TEXT"` // store hook-specific attributes | |||
LastStatus HookStatus // Last delivery status | |||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | |||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | |||
@@ -401,7 +402,7 @@ func GetWebhooksByOrgID(orgID int64, listOptions ListOptions) ([]*Webhook, error | |||
func GetDefaultWebhook(id int64) (*Webhook, error) { | |||
webhook := &Webhook{ID: id} | |||
has, err := x. | |||
Where("repo_id=? AND org_id=?", 0, 0). | |||
Where("repo_id=? AND org_id=? AND is_system_webhook=?", 0, 0, false). | |||
Get(webhook) | |||
if err != nil { | |||
return nil, err | |||
@@ -419,7 +420,33 @@ func GetDefaultWebhooks() ([]*Webhook, error) { | |||
func getDefaultWebhooks(e Engine) ([]*Webhook, error) { | |||
webhooks := make([]*Webhook, 0, 5) | |||
return webhooks, e. | |||
Where("repo_id=? AND org_id=?", 0, 0). | |||
Where("repo_id=? AND org_id=? AND is_system_webhook=?", 0, 0, false). | |||
Find(&webhooks) | |||
} | |||
// GetSystemWebhook returns admin system webhook by given ID. | |||
func GetSystemWebhook(id int64) (*Webhook, error) { | |||
webhook := &Webhook{ID: id} | |||
has, err := x. | |||
Where("repo_id=? AND org_id=? AND is_system_webhook=?", 0, 0, true). | |||
Get(webhook) | |||
if err != nil { | |||
return nil, err | |||
} else if !has { | |||
return nil, ErrWebhookNotExist{id} | |||
} | |||
return webhook, nil | |||
} | |||
// GetSystemWebhooks returns all admin system webhooks. | |||
func GetSystemWebhooks() ([]*Webhook, error) { | |||
return getSystemWebhooks(x) | |||
} | |||
func getSystemWebhooks(e Engine) ([]*Webhook, error) { | |||
webhooks := make([]*Webhook, 0, 5) | |||
return webhooks, e. | |||
Where("repo_id=? AND org_id=? AND is_system_webhook=?", 0, 0, true). | |||
Find(&webhooks) | |||
} | |||
@@ -471,8 +498,8 @@ func DeleteWebhookByOrgID(orgID, id int64) error { | |||
}) | |||
} | |||
// DeleteDefaultWebhook deletes an admin-default webhook by given ID. | |||
func DeleteDefaultWebhook(id int64) error { | |||
// DeleteDefaultSystemWebhook deletes an admin-configured default or system webhook (where Org and Repo ID both 0) | |||
func DeleteDefaultSystemWebhook(id int64) error { | |||
sess := x.NewSession() | |||
defer sess.Close() | |||
if err := sess.Begin(); err != nil { |
@@ -181,6 +181,13 @@ func prepareWebhooks(repo *models.Repository, event models.HookEventType, p api. | |||
ws = append(ws, orgHooks...) | |||
} | |||
// Add any admin-defined system webhooks | |||
systemHooks, err := models.GetSystemWebhooks() | |||
if err != nil { | |||
return fmt.Errorf("GetSystemWebhooks: %v", err) | |||
} | |||
ws = append(ws, systemHooks...) | |||
if len(ws) == 0 { | |||
return nil | |||
} |
@@ -1753,6 +1753,7 @@ users = User Accounts | |||
organizations = Organizations | |||
repositories = Repositories | |||
hooks = Default Webhooks | |||
systemhooks = System Webhooks | |||
authentication = Authentication Sources | |||
emails = User Emails | |||
config = Configuration | |||
@@ -1889,6 +1890,10 @@ hooks.desc = Webhooks automatically make HTTP POST requests to a server when cer | |||
hooks.add_webhook = Add Default Webhook | |||
hooks.update_webhook = Update Default Webhook | |||
systemhooks.desc = Webhooks automatically make HTTP POST requests to a server when certain Gitea events trigger. Webhooks defined will act on all repositories on the system, so please consider any performance implications this may have. Read more in the <a target="_blank" rel="noopener" href="https://docs.gitea.io/en-us/webhooks/">webhooks guide</a>. | |||
systemhooks.add_webhook = Add System Webhook | |||
systemhooks.update_webhook = Update System Webhook | |||
auths.auth_manage_panel = Authentication Source Management | |||
auths.new = Add Authentication Source | |||
auths.name = Name |
@@ -12,20 +12,32 @@ import ( | |||
) | |||
const ( | |||
// tplAdminHooks template path for render hook settings | |||
// tplAdminHooks template path to render hook settings | |||
tplAdminHooks base.TplName = "admin/hooks" | |||
) | |||
// DefaultWebhooks render admin-default webhook list page | |||
func DefaultWebhooks(ctx *context.Context) { | |||
ctx.Data["Title"] = ctx.Tr("admin.hooks") | |||
ctx.Data["PageIsAdminHooks"] = true | |||
ctx.Data["BaseLink"] = setting.AppSubURL + "/admin/hooks" | |||
ctx.Data["Description"] = ctx.Tr("admin.hooks.desc") | |||
// DefaultOrSystemWebhooks renders both admin default and system webhook list pages | |||
func DefaultOrSystemWebhooks(ctx *context.Context) { | |||
var ws []*models.Webhook | |||
var err error | |||
// Are we looking at default webhooks? | |||
if ctx.Params(":configType") == "hooks" { | |||
ctx.Data["Title"] = ctx.Tr("admin.hooks") | |||
ctx.Data["Description"] = ctx.Tr("admin.hooks.desc") | |||
ctx.Data["PageIsAdminHooks"] = true | |||
ctx.Data["BaseLink"] = setting.AppSubURL + "/admin/hooks" | |||
ws, err = models.GetDefaultWebhooks() | |||
} else { | |||
ctx.Data["Title"] = ctx.Tr("admin.systemhooks") | |||
ctx.Data["Description"] = ctx.Tr("admin.systemhooks.desc") | |||
ctx.Data["PageIsAdminSystemHooks"] = true | |||
ctx.Data["BaseLink"] = setting.AppSubURL + "/admin/system-hooks" | |||
ws, err = models.GetSystemWebhooks() | |||
} | |||
ws, err := models.GetDefaultWebhooks() | |||
if err != nil { | |||
ctx.ServerError("GetWebhooksDefaults", err) | |||
ctx.ServerError("GetWebhooksAdmin", err) | |||
return | |||
} | |||
@@ -33,15 +45,22 @@ func DefaultWebhooks(ctx *context.Context) { | |||
ctx.HTML(200, tplAdminHooks) | |||
} | |||
// DeleteDefaultWebhook response for delete admin-default webhook | |||
func DeleteDefaultWebhook(ctx *context.Context) { | |||
if err := models.DeleteDefaultWebhook(ctx.QueryInt64("id")); err != nil { | |||
// DeleteDefaultOrSystemWebhook handler to delete an admin-defined system or default webhook | |||
func DeleteDefaultOrSystemWebhook(ctx *context.Context) { | |||
if err := models.DeleteDefaultSystemWebhook(ctx.QueryInt64("id")); err != nil { | |||
ctx.Flash.Error("DeleteDefaultWebhook: " + err.Error()) | |||
} else { | |||
ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success")) | |||
} | |||
ctx.JSON(200, map[string]interface{}{ | |||
"redirect": setting.AppSubURL + "/admin/hooks", | |||
}) | |||
// Are we looking at default webhooks? | |||
if ctx.Params(":configType") == "hooks" { | |||
ctx.JSON(200, map[string]interface{}{ | |||
"redirect": setting.AppSubURL + "/admin/hooks", | |||
}) | |||
} else { | |||
ctx.JSON(200, map[string]interface{}{ | |||
"redirect": setting.AppSubURL + "/admin/system-hooks", | |||
}) | |||
} | |||
} |
@@ -49,14 +49,15 @@ func Webhooks(ctx *context.Context) { | |||
} | |||
type orgRepoCtx struct { | |||
OrgID int64 | |||
RepoID int64 | |||
IsAdmin bool | |||
Link string | |||
NewTemplate base.TplName | |||
OrgID int64 | |||
RepoID int64 | |||
IsAdmin bool | |||
IsSystemWebhook bool | |||
Link string | |||
NewTemplate base.TplName | |||
} | |||
// getOrgRepoCtx determines whether this is a repo, organization, or admin context. | |||
// getOrgRepoCtx determines whether this is a repo, organization, or admin (both default and system) context. | |||
func getOrgRepoCtx(ctx *context.Context) (*orgRepoCtx, error) { | |||
if len(ctx.Repo.RepoLink) > 0 { | |||
return &orgRepoCtx{ | |||
@@ -75,10 +76,21 @@ func getOrgRepoCtx(ctx *context.Context) (*orgRepoCtx, error) { | |||
} | |||
if ctx.User.IsAdmin { | |||
// Are we looking at default webhooks? | |||
if ctx.Params(":configType") == "hooks" { | |||
return &orgRepoCtx{ | |||
IsAdmin: true, | |||
Link: path.Join(setting.AppSubURL, "/admin/hooks"), | |||
NewTemplate: tplAdminHookNew, | |||
}, nil | |||
} | |||
// Must be system webhooks instead | |||
return &orgRepoCtx{ | |||
IsAdmin: true, | |||
Link: path.Join(setting.AppSubURL, "/admin/hooks"), | |||
NewTemplate: tplAdminHookNew, | |||
IsAdmin: true, | |||
IsSystemWebhook: true, | |||
Link: path.Join(setting.AppSubURL, "/admin/system-hooks"), | |||
NewTemplate: tplAdminHookNew, | |||
}, nil | |||
} | |||
@@ -105,7 +117,10 @@ func WebhooksNew(ctx *context.Context) { | |||
return | |||
} | |||
if orCtx.IsAdmin { | |||
if orCtx.IsAdmin && orCtx.IsSystemWebhook { | |||
ctx.Data["PageIsAdminSystemHooks"] = true | |||
ctx.Data["PageIsAdminSystemHooksNew"] = true | |||
} else if orCtx.IsAdmin { | |||
ctx.Data["PageIsAdminHooks"] = true | |||
ctx.Data["PageIsAdminHooksNew"] = true | |||
} else { | |||
@@ -159,8 +174,8 @@ func ParseHookEvent(form auth.WebhookForm) *models.HookEvent { | |||
} | |||
} | |||
// WebHooksNewPost response for creating webhook | |||
func WebHooksNewPost(ctx *context.Context, form auth.NewWebhookForm) { | |||
// GiteaHooksNewPost response for creating Gitea webhook | |||
func GiteaHooksNewPost(ctx *context.Context, form auth.NewWebhookForm) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook") | |||
ctx.Data["PageIsSettingsHooks"] = true | |||
ctx.Data["PageIsSettingsHooksNew"] = true | |||
@@ -185,15 +200,16 @@ func WebHooksNewPost(ctx *context.Context, form auth.NewWebhookForm) { | |||
} | |||
w := &models.Webhook{ | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
HTTPMethod: form.HTTPMethod, | |||
ContentType: contentType, | |||
Secret: form.Secret, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.GITEA, | |||
OrgID: orCtx.OrgID, | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
HTTPMethod: form.HTTPMethod, | |||
ContentType: contentType, | |||
Secret: form.Secret, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.GITEA, | |||
OrgID: orCtx.OrgID, | |||
IsSystemWebhook: orCtx.IsSystemWebhook, | |||
} | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.ServerError("UpdateEvent", err) | |||
@@ -238,14 +254,15 @@ func newGogsWebhookPost(ctx *context.Context, form auth.NewGogshookForm, kind mo | |||
} | |||
w := &models.Webhook{ | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: contentType, | |||
Secret: form.Secret, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: kind, | |||
OrgID: orCtx.OrgID, | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: contentType, | |||
Secret: form.Secret, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: kind, | |||
OrgID: orCtx.OrgID, | |||
IsSystemWebhook: orCtx.IsSystemWebhook, | |||
} | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.ServerError("UpdateEvent", err) | |||
@@ -287,14 +304,15 @@ func DiscordHooksNewPost(ctx *context.Context, form auth.NewDiscordHookForm) { | |||
} | |||
w := &models.Webhook{ | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: models.ContentTypeJSON, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.DISCORD, | |||
Meta: string(meta), | |||
OrgID: orCtx.OrgID, | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: models.ContentTypeJSON, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.DISCORD, | |||
Meta: string(meta), | |||
OrgID: orCtx.OrgID, | |||
IsSystemWebhook: orCtx.IsSystemWebhook, | |||
} | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.ServerError("UpdateEvent", err) | |||
@@ -327,14 +345,15 @@ func DingtalkHooksNewPost(ctx *context.Context, form auth.NewDingtalkHookForm) { | |||
} | |||
w := &models.Webhook{ | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: models.ContentTypeJSON, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.DINGTALK, | |||
Meta: "", | |||
OrgID: orCtx.OrgID, | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: models.ContentTypeJSON, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.DINGTALK, | |||
Meta: "", | |||
OrgID: orCtx.OrgID, | |||
IsSystemWebhook: orCtx.IsSystemWebhook, | |||
} | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.ServerError("UpdateEvent", err) | |||
@@ -376,14 +395,15 @@ func TelegramHooksNewPost(ctx *context.Context, form auth.NewTelegramHookForm) { | |||
} | |||
w := &models.Webhook{ | |||
RepoID: orCtx.RepoID, | |||
URL: fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s", form.BotToken, form.ChatID), | |||
ContentType: models.ContentTypeJSON, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.TELEGRAM, | |||
Meta: string(meta), | |||
OrgID: orCtx.OrgID, | |||
RepoID: orCtx.RepoID, | |||
URL: fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s", form.BotToken, form.ChatID), | |||
ContentType: models.ContentTypeJSON, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.TELEGRAM, | |||
Meta: string(meta), | |||
OrgID: orCtx.OrgID, | |||
IsSystemWebhook: orCtx.IsSystemWebhook, | |||
} | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.ServerError("UpdateEvent", err) | |||
@@ -416,14 +436,15 @@ func MSTeamsHooksNewPost(ctx *context.Context, form auth.NewMSTeamsHookForm) { | |||
} | |||
w := &models.Webhook{ | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: models.ContentTypeJSON, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.MSTEAMS, | |||
Meta: "", | |||
OrgID: orCtx.OrgID, | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: models.ContentTypeJSON, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.MSTEAMS, | |||
Meta: "", | |||
OrgID: orCtx.OrgID, | |||
IsSystemWebhook: orCtx.IsSystemWebhook, | |||
} | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.ServerError("UpdateEvent", err) | |||
@@ -473,14 +494,15 @@ func SlackHooksNewPost(ctx *context.Context, form auth.NewSlackHookForm) { | |||
} | |||
w := &models.Webhook{ | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: models.ContentTypeJSON, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.SLACK, | |||
Meta: string(meta), | |||
OrgID: orCtx.OrgID, | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: models.ContentTypeJSON, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.SLACK, | |||
Meta: string(meta), | |||
OrgID: orCtx.OrgID, | |||
IsSystemWebhook: orCtx.IsSystemWebhook, | |||
} | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.ServerError("UpdateEvent", err) | |||
@@ -513,14 +535,15 @@ func FeishuHooksNewPost(ctx *context.Context, form auth.NewFeishuHookForm) { | |||
} | |||
w := &models.Webhook{ | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: models.ContentTypeJSON, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.FEISHU, | |||
Meta: "", | |||
OrgID: orCtx.OrgID, | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: models.ContentTypeJSON, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.FEISHU, | |||
Meta: "", | |||
OrgID: orCtx.OrgID, | |||
IsSystemWebhook: orCtx.IsSystemWebhook, | |||
} | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.ServerError("UpdateEvent", err) | |||
@@ -549,6 +572,8 @@ func checkWebhook(ctx *context.Context) (*orgRepoCtx, *models.Webhook) { | |||
w, err = models.GetWebhookByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")) | |||
} else if orCtx.OrgID > 0 { | |||
w, err = models.GetWebhookByOrgID(ctx.Org.Organization.ID, ctx.ParamsInt64(":id")) | |||
} else if orCtx.IsSystemWebhook { | |||
w, err = models.GetSystemWebhook(ctx.ParamsInt64(":id")) | |||
} else { | |||
w, err = models.GetDefaultWebhook(ctx.ParamsInt64(":id")) | |||
} |
@@ -458,11 +458,11 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
m.Post("/delete", admin.DeleteRepo) | |||
}) | |||
m.Group("/hooks", func() { | |||
m.Get("", admin.DefaultWebhooks) | |||
m.Post("/delete", admin.DeleteDefaultWebhook) | |||
m.Group("/^:configType(hooks|system-hooks)$", func() { | |||
m.Get("", admin.DefaultOrSystemWebhooks) | |||
m.Post("/delete", admin.DeleteDefaultOrSystemWebhook) | |||
m.Get("/:type/new", repo.WebhooksNew) | |||
m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost) | |||
m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.GiteaHooksNewPost) | |||
m.Post("/gogs/new", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksNewPost) | |||
m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) | |||
m.Post("/discord/new", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksNewPost) | |||
@@ -569,7 +569,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
m.Get("", org.Webhooks) | |||
m.Post("/delete", org.DeleteWebhook) | |||
m.Get("/:type/new", repo.WebhooksNew) | |||
m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost) | |||
m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.GiteaHooksNewPost) | |||
m.Post("/gogs/new", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksNewPost) | |||
m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) | |||
m.Post("/discord/new", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksNewPost) | |||
@@ -635,7 +635,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
m.Get("", repo.Webhooks) | |||
m.Post("/delete", repo.DeleteWebhook) | |||
m.Get("/:type/new", repo.WebhooksNew) | |||
m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost) | |||
m.Post("/gitea/new", bindIgnErr(auth.NewWebhookForm{}), repo.GiteaHooksNewPost) | |||
m.Post("/gogs/new", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksNewPost) | |||
m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) | |||
m.Post("/discord/new", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksNewPost) |
@@ -14,6 +14,9 @@ | |||
<a class="{{if .PageIsAdminHooks}}active{{end}} item" href="{{AppSubUrl}}/admin/hooks"> | |||
{{.i18n.Tr "admin.hooks"}} | |||
</a> | |||
<a class="{{if .PageIsAdminSystemHooks}}active{{end}} item" href="{{AppSubUrl}}/admin/system-hooks"> | |||
{{.i18n.Tr "admin.systemhooks"}} | |||
</a> | |||
<a class="{{if .PageIsAdminAuthentications}}active{{end}} item" href="{{AppSubUrl}}/admin/auths"> | |||
{{.i18n.Tr "admin.authentication"}} | |||
</a> |