aboutsummaryrefslogtreecommitdiffstats
path: root/models/webhook.go
diff options
context:
space:
mode:
authorWGH <wgh@torlan.ru>2019-09-09 08:48:21 +0300
committerLauris BH <lauris.buksis@zzdats.lv>2019-09-09 08:48:21 +0300
commit6ddd3b0b470d16dfe62caf5fff21011cfff44a76 (patch)
tree05d4c7fedf8af21b489003890be000f839f69a51 /models/webhook.go
parent0118b6aaf8ada3edd67cb975c776f6f124178ad2 (diff)
downloadgitea-6ddd3b0b470d16dfe62caf5fff21011cfff44a76.tar.gz
gitea-6ddd3b0b470d16dfe62caf5fff21011cfff44a76.zip
Implement webhook branch filter (#7791)
* Fix validate() function to handle errors in embedded anon structs * Implement webhook branch filter See #2025, #3998.
Diffstat (limited to 'models/webhook.go')
-rw-r--r--models/webhook.go52
1 files changed, 49 insertions, 3 deletions
diff --git a/models/webhook.go b/models/webhook.go
index 4eda08fdb5..67ae783759 100644
--- a/models/webhook.go
+++ b/models/webhook.go
@@ -19,12 +19,14 @@ import (
"strings"
"time"
+ "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/sync"
"code.gitea.io/gitea/modules/timeutil"
+ "github.com/gobwas/glob"
gouuid "github.com/satori/go.uuid"
"github.com/unknwon/com"
)
@@ -84,9 +86,10 @@ type HookEvents struct {
// HookEvent represents events that will delivery hook.
type HookEvent struct {
- PushOnly bool `json:"push_only"`
- SendEverything bool `json:"send_everything"`
- ChooseEvents bool `json:"choose_events"`
+ PushOnly bool `json:"push_only"`
+ SendEverything bool `json:"send_everything"`
+ ChooseEvents bool `json:"choose_events"`
+ BranchFilter string `json:"branch_filter"`
HookEvents `json:"events"`
}
@@ -256,6 +259,21 @@ func (w *Webhook) EventsArray() []string {
return events
}
+func (w *Webhook) checkBranch(branch string) bool {
+ if w.BranchFilter == "" || w.BranchFilter == "*" {
+ return true
+ }
+
+ g, err := glob.Compile(w.BranchFilter)
+ if err != nil {
+ // should not really happen as BranchFilter is validated
+ log.Error("CheckBranch failed: %s", err)
+ return false
+ }
+
+ return g.Match(branch)
+}
+
// CreateWebhook creates a new web hook.
func CreateWebhook(w *Webhook) error {
return createWebhook(x, w)
@@ -651,6 +669,25 @@ func PrepareWebhook(w *Webhook, repo *Repository, event HookEventType, p api.Pay
return prepareWebhook(x, w, repo, event, p)
}
+// getPayloadBranch returns branch for hook event, if applicable.
+func getPayloadBranch(p api.Payloader) string {
+ switch pp := p.(type) {
+ case *api.CreatePayload:
+ if pp.RefType == "branch" {
+ return pp.Ref
+ }
+ case *api.DeletePayload:
+ if pp.RefType == "branch" {
+ return pp.Ref
+ }
+ case *api.PushPayload:
+ if strings.HasPrefix(pp.Ref, git.BranchPrefix) {
+ return pp.Ref[len(git.BranchPrefix):]
+ }
+ }
+ return ""
+}
+
func prepareWebhook(e Engine, w *Webhook, repo *Repository, event HookEventType, p api.Payloader) error {
for _, e := range w.eventCheckers() {
if event == e.typ {
@@ -660,6 +697,15 @@ func prepareWebhook(e Engine, w *Webhook, repo *Repository, event HookEventType,
}
}
+ // If payload has no associated branch (e.g. it's a new tag, issue, etc.),
+ // branch filter has no effect.
+ if branch := getPayloadBranch(p); branch != "" {
+ if !w.checkBranch(branch) {
+ log.Info("Branch %q doesn't match branch filter %q, skipping", branch, w.BranchFilter)
+ return nil
+ }
+ }
+
var payloader api.Payloader
var err error
// Use separate objects so modifications won't be made on payload on non-Gogs/Gitea type hooks.