diff options
author | Unknwon <u@gogs.io> | 2015-08-28 23:36:13 +0800 |
---|---|---|
committer | Unknwon <u@gogs.io> | 2015-08-28 23:36:13 +0800 |
commit | f509c59ac13dffdff6a246572de04150ee295314 (patch) | |
tree | 3be3923779cedce3058f28f1d32604226985be03 /models/webhook.go | |
parent | a541ca16b67d492340ac55b84ff190d2a52fc39d (diff) | |
download | gitea-f509c59ac13dffdff6a246572de04150ee295314.tar.gz gitea-f509c59ac13dffdff6a246572de04150ee295314.zip |
new create webhook event
Diffstat (limited to 'models/webhook.go')
-rw-r--r-- | models/webhook.go | 164 |
1 files changed, 98 insertions, 66 deletions
diff --git a/models/webhook.go b/models/webhook.go index debe46e5ec..b2fecb8d3c 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -15,6 +15,8 @@ import ( "github.com/go-xorm/xorm" + api "github.com/gogits/go-gogs-client" + "github.com/gogits/gogs/modules/httplib" "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" @@ -54,9 +56,18 @@ func IsValidHookContentType(name string) bool { return ok } +type HookEvents struct { + Create bool `json:"create"` + Push bool `json:"push"` +} + // HookEvent represents events that will delivery hook. type HookEvent struct { - PushOnly bool `json:"push_only"` + PushOnly bool `json:"push_only"` + SendEverything bool `json:"send_everything"` + ChooseEvents bool `json:"choose_events"` + + HookEvents `json:"events"` } type HookStatus int @@ -94,8 +105,8 @@ func (w *Webhook) GetEvent() { } } -func (w *Webhook) GetSlackHook() *Slack { - s := &Slack{} +func (w *Webhook) GetSlackHook() *SlackMeta { + s := &SlackMeta{} if err := json.Unmarshal([]byte(w.Meta), s); err != nil { log.Error(4, "webhook.GetSlackHook(%d): %v", w.ID, err) } @@ -114,12 +125,16 @@ func (w *Webhook) UpdateEvent() error { return err } +// HasCreateEvent returns true if hook enabled create event. +func (w *Webhook) HasCreateEvent() bool { + return w.SendEverything || + (w.ChooseEvents && w.HookEvents.Create) +} + // HasPushEvent returns true if hook enabled push event. func (w *Webhook) HasPushEvent() bool { - if w.PushOnly { - return true - } - return false + return w.PushOnly || w.SendEverything || + (w.ChooseEvents && w.HookEvents.Push) } // CreateWebhook creates a new web hook. @@ -140,9 +155,9 @@ func GetWebhookByID(id int64) (*Webhook, error) { return w, nil } -// GetActiveWebhooksByRepoId returns all active webhooks of repository. -func GetActiveWebhooksByRepoId(repoId int64) (ws []*Webhook, err error) { - err = x.Where("repo_id=?", repoId).And("is_active=?", true).Find(&ws) +// GetActiveWebhooksByRepoID returns all active webhooks of repository. +func GetActiveWebhooksByRepoID(repoID int64) (ws []*Webhook, err error) { + err = x.Where("repo_id=?", repoID).And("is_active=?", true).Find(&ws) return ws, err } @@ -181,9 +196,9 @@ func GetWebhooksByOrgId(orgID int64) (ws []*Webhook, err error) { return ws, err } -// GetActiveWebhooksByOrgId returns all active webhooks for an organization. -func GetActiveWebhooksByOrgId(orgId int64) (ws []*Webhook, err error) { - err = x.Where("org_id=?", orgId).And("is_active=?", true).Find(&ws) +// GetActiveWebhooksByOrgID returns all active webhooks for an organization. +func GetActiveWebhooksByOrgID(orgID int64) (ws []*Webhook, err error) { + err = x.Where("org_id=?", orgID).And("is_active=?", true).Find(&ws) return ws, err } @@ -230,58 +245,10 @@ func IsValidHookTaskType(name string) bool { type HookEventType string const ( - HOOK_EVENT_PUSH HookEventType = "push" + HOOK_EVENT_CREATE HookEventType = "create" + HOOK_EVENT_PUSH HookEventType = "push" ) -// FIXME: just use go-gogs-client structs maybe? -type PayloadAuthor struct { - Name string `json:"name"` - Email string `json:"email"` - UserName string `json:"username"` -} - -type PayloadCommit struct { - Id string `json:"id"` - Message string `json:"message"` - Url string `json:"url"` - Author *PayloadAuthor `json:"author"` -} - -type PayloadRepo struct { - Id int64 `json:"id"` - Name string `json:"name"` - Url string `json:"url"` - Description string `json:"description"` - Website string `json:"website"` - Watchers int `json:"watchers"` - Owner *PayloadAuthor `json:"owner"` - Private bool `json:"private"` -} - -type BasePayload interface { - GetJSONPayload() ([]byte, error) -} - -// Payload represents a payload information of hook. -type Payload struct { - Secret string `json:"secret"` - Ref string `json:"ref"` - Commits []*PayloadCommit `json:"commits"` - Repo *PayloadRepo `json:"repository"` - Pusher *PayloadAuthor `json:"pusher"` - Before string `json:"before"` - After string `json:"after"` - CompareUrl string `json:"compare_url"` -} - -func (p Payload) GetJSONPayload() ([]byte, error) { - data, err := json.MarshalIndent(p, "", " ") - if err != nil { - return []byte{}, err - } - return data, nil -} - // HookRequest represents hook task request information. type HookRequest struct { Headers map[string]string `json:"headers"` @@ -302,7 +269,7 @@ type HookTask struct { UUID string Type HookTaskType URL string - BasePayload `xorm:"-"` + api.Payloader `xorm:"-"` PayloadContent string `xorm:"TEXT"` ContentType HookContentType EventType HookEventType @@ -367,13 +334,13 @@ func (t *HookTask) MarshalJSON(v interface{}) string { // HookTasks returns a list of hook tasks by given conditions. func HookTasks(hookID int64, page int) ([]*HookTask, error) { tasks := make([]*HookTask, 0, setting.Webhook.PagingNum) - return tasks, x.Limit(setting.Webhook.PagingNum, (page-1)*setting.Webhook.PagingNum).Desc("id").Find(&tasks) + return tasks, x.Limit(setting.Webhook.PagingNum, (page-1)*setting.Webhook.PagingNum).Where("hook_id=?", hookID).Desc("id").Find(&tasks) } // CreateHookTask creates a new hook task, // it handles conversion from Payload to PayloadContent. func CreateHookTask(t *HookTask) error { - data, err := t.BasePayload.GetJSONPayload() + data, err := t.Payloader.JSONPayload() if err != nil { return err } @@ -389,6 +356,71 @@ func UpdateHookTask(t *HookTask) error { return err } +// PrepareWebhooks adds new webhooks to task queue for given payload. +func PrepareWebhooks(repo *Repository, event HookEventType, p api.Payloader) error { + if err := repo.GetOwner(); err != nil { + return fmt.Errorf("GetOwner: %v", err) + } + + ws, err := GetActiveWebhooksByRepoID(repo.ID) + if err != nil { + return fmt.Errorf("GetActiveWebhooksByRepoID: %v", err) + } + + // check if repo belongs to org and append additional webhooks + if repo.Owner.IsOrganization() { + // get hooks for org + orgws, err := GetActiveWebhooksByOrgID(repo.OwnerID) + if err != nil { + return fmt.Errorf("GetActiveWebhooksByOrgID: %v", err) + } + ws = append(ws, orgws...) + } + + if len(ws) == 0 { + return nil + } + + for _, w := range ws { + w.GetEvent() + + switch event { + case HOOK_EVENT_CREATE: + if !w.HasCreateEvent() { + continue + } + case HOOK_EVENT_PUSH: + if !w.HasPushEvent() { + continue + } + } + + switch w.HookTaskType { + case SLACK: + p, err = GetSlackPayload(p, event, w.Meta) + if err != nil { + return fmt.Errorf("GetSlackPayload: %v", err) + } + default: + p.SetSecret(w.Secret) + } + + if err = CreateHookTask(&HookTask{ + RepoID: repo.ID, + HookID: w.ID, + Type: w.HookTaskType, + URL: w.URL, + Payloader: p, + ContentType: w.ContentType, + EventType: HOOK_EVENT_PUSH, + IsSSL: w.IsSSL, + }); err != nil { + return fmt.Errorf("CreateHookTask: %v", err) + } + } + return nil +} + type hookQueue struct { // Make sure one repository only occur once in the queue. lock sync.Mutex |