* Move more webhook codes from models to webhook moduletags/v1.21.12.1
| @@ -118,33 +118,6 @@ func (w *Webhook) AfterLoad() { | |||||
| } | } | ||||
| } | } | ||||
| // GetSlackHook returns slack metadata | |||||
| func (w *Webhook) GetSlackHook() *SlackMeta { | |||||
| s := &SlackMeta{} | |||||
| if err := json.Unmarshal([]byte(w.Meta), s); err != nil { | |||||
| log.Error("webhook.GetSlackHook(%d): %v", w.ID, err) | |||||
| } | |||||
| return s | |||||
| } | |||||
| // GetDiscordHook returns discord metadata | |||||
| func (w *Webhook) GetDiscordHook() *DiscordMeta { | |||||
| s := &DiscordMeta{} | |||||
| if err := json.Unmarshal([]byte(w.Meta), s); err != nil { | |||||
| log.Error("webhook.GetDiscordHook(%d): %v", w.ID, err) | |||||
| } | |||||
| return s | |||||
| } | |||||
| // GetTelegramHook returns telegram metadata | |||||
| func (w *Webhook) GetTelegramHook() *TelegramMeta { | |||||
| s := &TelegramMeta{} | |||||
| if err := json.Unmarshal([]byte(w.Meta), s); err != nil { | |||||
| log.Error("webhook.GetTelegramHook(%d): %v", w.ID, err) | |||||
| } | |||||
| return s | |||||
| } | |||||
| // History returns history of webhook by given conditions. | // History returns history of webhook by given conditions. | ||||
| func (w *Webhook) History(page int) ([]*HookTask, error) { | func (w *Webhook) History(page int) ([]*HookTask, error) { | ||||
| return HookTasks(w.ID, page) | return HookTasks(w.ID, page) | ||||
| @@ -24,18 +24,6 @@ func TestIsValidHookContentType(t *testing.T) { | |||||
| assert.False(t, IsValidHookContentType("invalid")) | assert.False(t, IsValidHookContentType("invalid")) | ||||
| } | } | ||||
| func TestWebhook_GetSlackHook(t *testing.T) { | |||||
| w := &Webhook{ | |||||
| Meta: `{"channel": "foo", "username": "username", "color": "blue"}`, | |||||
| } | |||||
| slackHook := w.GetSlackHook() | |||||
| assert.Equal(t, *slackHook, SlackMeta{ | |||||
| Channel: "foo", | |||||
| Username: "username", | |||||
| Color: "blue", | |||||
| }) | |||||
| } | |||||
| func TestWebhook_History(t *testing.T) { | func TestWebhook_History(t *testing.T) { | ||||
| assert.NoError(t, PrepareTestDatabase()) | assert.NoError(t, PrepareTestDatabase()) | ||||
| webhook := AssertExistsAndLoadBean(t, &Webhook{ID: 1}).(*Webhook) | webhook := AssertExistsAndLoadBean(t, &Webhook{ID: 1}).(*Webhook) | ||||
| @@ -2,13 +2,14 @@ | |||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| package models | |||||
| package webhook | |||||
| import ( | import ( | ||||
| "encoding/json" | "encoding/json" | ||||
| "fmt" | "fmt" | ||||
| "strings" | "strings" | ||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/git" | "code.gitea.io/gitea/modules/git" | ||||
| api "code.gitea.io/gitea/modules/structs" | api "code.gitea.io/gitea/modules/structs" | ||||
| @@ -184,7 +185,7 @@ func getDingtalkIssuesPayload(p *api.IssuePayload) (*DingtalkPayload, error) { | |||||
| func getDingtalkIssueCommentPayload(p *api.IssueCommentPayload) (*DingtalkPayload, error) { | func getDingtalkIssueCommentPayload(p *api.IssueCommentPayload) (*DingtalkPayload, error) { | ||||
| title := fmt.Sprintf("#%d: %s", p.Issue.Index, p.Issue.Title) | title := fmt.Sprintf("#%d: %s", p.Issue.Index, p.Issue.Title) | ||||
| url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID)) | |||||
| url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, models.CommentHashTag(p.Comment.ID)) | |||||
| var content string | var content string | ||||
| switch p.Action { | switch p.Action { | ||||
| case api.HookIssueCommentCreated: | case api.HookIssueCommentCreated: | ||||
| @@ -286,7 +287,7 @@ func getDingtalkPullRequestPayload(p *api.PullRequestPayload) (*DingtalkPayload, | |||||
| }, nil | }, nil | ||||
| } | } | ||||
| func getDingtalkPullRequestApprovalPayload(p *api.PullRequestPayload, event HookEventType) (*DingtalkPayload, error) { | |||||
| func getDingtalkPullRequestApprovalPayload(p *api.PullRequestPayload, event models.HookEventType) (*DingtalkPayload, error) { | |||||
| var text, title string | var text, title string | ||||
| switch p.Action { | switch p.Action { | ||||
| case api.HookIssueSynchronized: | case api.HookIssueSynchronized: | ||||
| @@ -392,29 +393,29 @@ func getDingtalkReleasePayload(p *api.ReleasePayload) (*DingtalkPayload, error) | |||||
| } | } | ||||
| // GetDingtalkPayload converts a ding talk webhook into a DingtalkPayload | // GetDingtalkPayload converts a ding talk webhook into a DingtalkPayload | ||||
| func GetDingtalkPayload(p api.Payloader, event HookEventType, meta string) (*DingtalkPayload, error) { | |||||
| func GetDingtalkPayload(p api.Payloader, event models.HookEventType, meta string) (*DingtalkPayload, error) { | |||||
| s := new(DingtalkPayload) | s := new(DingtalkPayload) | ||||
| switch event { | switch event { | ||||
| case HookEventCreate: | |||||
| case models.HookEventCreate: | |||||
| return getDingtalkCreatePayload(p.(*api.CreatePayload)) | return getDingtalkCreatePayload(p.(*api.CreatePayload)) | ||||
| case HookEventDelete: | |||||
| case models.HookEventDelete: | |||||
| return getDingtalkDeletePayload(p.(*api.DeletePayload)) | return getDingtalkDeletePayload(p.(*api.DeletePayload)) | ||||
| case HookEventFork: | |||||
| case models.HookEventFork: | |||||
| return getDingtalkForkPayload(p.(*api.ForkPayload)) | return getDingtalkForkPayload(p.(*api.ForkPayload)) | ||||
| case HookEventIssues: | |||||
| case models.HookEventIssues: | |||||
| return getDingtalkIssuesPayload(p.(*api.IssuePayload)) | return getDingtalkIssuesPayload(p.(*api.IssuePayload)) | ||||
| case HookEventIssueComment: | |||||
| case models.HookEventIssueComment: | |||||
| return getDingtalkIssueCommentPayload(p.(*api.IssueCommentPayload)) | return getDingtalkIssueCommentPayload(p.(*api.IssueCommentPayload)) | ||||
| case HookEventPush: | |||||
| case models.HookEventPush: | |||||
| return getDingtalkPushPayload(p.(*api.PushPayload)) | return getDingtalkPushPayload(p.(*api.PushPayload)) | ||||
| case HookEventPullRequest: | |||||
| case models.HookEventPullRequest: | |||||
| return getDingtalkPullRequestPayload(p.(*api.PullRequestPayload)) | return getDingtalkPullRequestPayload(p.(*api.PullRequestPayload)) | ||||
| case HookEventPullRequestApproved, HookEventPullRequestRejected, HookEventPullRequestComment: | |||||
| case models.HookEventPullRequestApproved, models.HookEventPullRequestRejected, models.HookEventPullRequestComment: | |||||
| return getDingtalkPullRequestApprovalPayload(p.(*api.PullRequestPayload), event) | return getDingtalkPullRequestApprovalPayload(p.(*api.PullRequestPayload), event) | ||||
| case HookEventRepository: | |||||
| case models.HookEventRepository: | |||||
| return getDingtalkRepositoryPayload(p.(*api.RepositoryPayload)) | return getDingtalkRepositoryPayload(p.(*api.RepositoryPayload)) | ||||
| case HookEventRelease: | |||||
| case models.HookEventRelease: | |||||
| return getDingtalkReleasePayload(p.(*api.ReleasePayload)) | return getDingtalkReleasePayload(p.(*api.ReleasePayload)) | ||||
| } | } | ||||
| @@ -2,7 +2,7 @@ | |||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| package models | |||||
| package webhook | |||||
| import ( | import ( | ||||
| "encoding/json" | "encoding/json" | ||||
| @@ -11,7 +11,9 @@ import ( | |||||
| "strconv" | "strconv" | ||||
| "strings" | "strings" | ||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/git" | "code.gitea.io/gitea/modules/git" | ||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| api "code.gitea.io/gitea/modules/structs" | api "code.gitea.io/gitea/modules/structs" | ||||
| ) | ) | ||||
| @@ -63,6 +65,15 @@ type ( | |||||
| } | } | ||||
| ) | ) | ||||
| // GetDiscordHook returns discord metadata | |||||
| func GetDiscordHook(w *models.Webhook) *DiscordMeta { | |||||
| s := &DiscordMeta{} | |||||
| if err := json.Unmarshal([]byte(w.Meta), s); err != nil { | |||||
| log.Error("webhook.GetDiscordHook(%d): %v", w.ID, err) | |||||
| } | |||||
| return s | |||||
| } | |||||
| func color(clr string) int { | func color(clr string) int { | ||||
| if clr != "" { | if clr != "" { | ||||
| clr = strings.TrimLeft(clr, "#") | clr = strings.TrimLeft(clr, "#") | ||||
| @@ -288,7 +299,7 @@ func getDiscordIssuesPayload(p *api.IssuePayload, meta *DiscordMeta) (*DiscordPa | |||||
| func getDiscordIssueCommentPayload(p *api.IssueCommentPayload, discord *DiscordMeta) (*DiscordPayload, error) { | func getDiscordIssueCommentPayload(p *api.IssueCommentPayload, discord *DiscordMeta) (*DiscordPayload, error) { | ||||
| title := fmt.Sprintf("#%d: %s", p.Issue.Index, p.Issue.Title) | title := fmt.Sprintf("#%d: %s", p.Issue.Index, p.Issue.Title) | ||||
| url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID)) | |||||
| url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, models.CommentHashTag(p.Comment.ID)) | |||||
| content := "" | content := "" | ||||
| var color int | var color int | ||||
| switch p.Action { | switch p.Action { | ||||
| @@ -421,7 +432,7 @@ func getDiscordPullRequestPayload(p *api.PullRequestPayload, meta *DiscordMeta) | |||||
| }, nil | }, nil | ||||
| } | } | ||||
| func getDiscordPullRequestApprovalPayload(p *api.PullRequestPayload, meta *DiscordMeta, event HookEventType) (*DiscordPayload, error) { | |||||
| func getDiscordPullRequestApprovalPayload(p *api.PullRequestPayload, meta *DiscordMeta, event models.HookEventType) (*DiscordPayload, error) { | |||||
| var text, title string | var text, title string | ||||
| var color int | var color int | ||||
| switch p.Action { | switch p.Action { | ||||
| @@ -435,11 +446,11 @@ func getDiscordPullRequestApprovalPayload(p *api.PullRequestPayload, meta *Disco | |||||
| text = p.Review.Content | text = p.Review.Content | ||||
| switch event { | switch event { | ||||
| case HookEventPullRequestApproved: | |||||
| case models.HookEventPullRequestApproved: | |||||
| color = greenColor | color = greenColor | ||||
| case HookEventPullRequestRejected: | |||||
| case models.HookEventPullRequestRejected: | |||||
| color = redColor | color = redColor | ||||
| case HookEventPullRequestComment: | |||||
| case models.HookEventPullRequestComment: | |||||
| color = greyColor | color = greyColor | ||||
| default: | default: | ||||
| color = yellowColor | color = yellowColor | ||||
| @@ -534,7 +545,7 @@ func getDiscordReleasePayload(p *api.ReleasePayload, meta *DiscordMeta) (*Discor | |||||
| } | } | ||||
| // GetDiscordPayload converts a discord webhook into a DiscordPayload | // GetDiscordPayload converts a discord webhook into a DiscordPayload | ||||
| func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (*DiscordPayload, error) { | |||||
| func GetDiscordPayload(p api.Payloader, event models.HookEventType, meta string) (*DiscordPayload, error) { | |||||
| s := new(DiscordPayload) | s := new(DiscordPayload) | ||||
| discord := &DiscordMeta{} | discord := &DiscordMeta{} | ||||
| @@ -543,40 +554,40 @@ func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (*Disc | |||||
| } | } | ||||
| switch event { | switch event { | ||||
| case HookEventCreate: | |||||
| case models.HookEventCreate: | |||||
| return getDiscordCreatePayload(p.(*api.CreatePayload), discord) | return getDiscordCreatePayload(p.(*api.CreatePayload), discord) | ||||
| case HookEventDelete: | |||||
| case models.HookEventDelete: | |||||
| return getDiscordDeletePayload(p.(*api.DeletePayload), discord) | return getDiscordDeletePayload(p.(*api.DeletePayload), discord) | ||||
| case HookEventFork: | |||||
| case models.HookEventFork: | |||||
| return getDiscordForkPayload(p.(*api.ForkPayload), discord) | return getDiscordForkPayload(p.(*api.ForkPayload), discord) | ||||
| case HookEventIssues: | |||||
| case models.HookEventIssues: | |||||
| return getDiscordIssuesPayload(p.(*api.IssuePayload), discord) | return getDiscordIssuesPayload(p.(*api.IssuePayload), discord) | ||||
| case HookEventIssueComment: | |||||
| case models.HookEventIssueComment: | |||||
| return getDiscordIssueCommentPayload(p.(*api.IssueCommentPayload), discord) | return getDiscordIssueCommentPayload(p.(*api.IssueCommentPayload), discord) | ||||
| case HookEventPush: | |||||
| case models.HookEventPush: | |||||
| return getDiscordPushPayload(p.(*api.PushPayload), discord) | return getDiscordPushPayload(p.(*api.PushPayload), discord) | ||||
| case HookEventPullRequest: | |||||
| case models.HookEventPullRequest: | |||||
| return getDiscordPullRequestPayload(p.(*api.PullRequestPayload), discord) | return getDiscordPullRequestPayload(p.(*api.PullRequestPayload), discord) | ||||
| case HookEventPullRequestRejected, HookEventPullRequestApproved, HookEventPullRequestComment: | |||||
| case models.HookEventPullRequestRejected, models.HookEventPullRequestApproved, models.HookEventPullRequestComment: | |||||
| return getDiscordPullRequestApprovalPayload(p.(*api.PullRequestPayload), discord, event) | return getDiscordPullRequestApprovalPayload(p.(*api.PullRequestPayload), discord, event) | ||||
| case HookEventRepository: | |||||
| case models.HookEventRepository: | |||||
| return getDiscordRepositoryPayload(p.(*api.RepositoryPayload), discord) | return getDiscordRepositoryPayload(p.(*api.RepositoryPayload), discord) | ||||
| case HookEventRelease: | |||||
| case models.HookEventRelease: | |||||
| return getDiscordReleasePayload(p.(*api.ReleasePayload), discord) | return getDiscordReleasePayload(p.(*api.ReleasePayload), discord) | ||||
| } | } | ||||
| return s, nil | return s, nil | ||||
| } | } | ||||
| func parseHookPullRequestEventType(event HookEventType) (string, error) { | |||||
| func parseHookPullRequestEventType(event models.HookEventType) (string, error) { | |||||
| switch event { | switch event { | ||||
| case HookEventPullRequestApproved: | |||||
| case models.HookEventPullRequestApproved: | |||||
| return "approved", nil | return "approved", nil | ||||
| case HookEventPullRequestRejected: | |||||
| case models.HookEventPullRequestRejected: | |||||
| return "rejected", nil | return "rejected", nil | ||||
| case HookEventPullRequestComment: | |||||
| case models.HookEventPullRequestComment: | |||||
| return "comment", nil | return "comment", nil | ||||
| default: | default: | ||||
| @@ -2,13 +2,14 @@ | |||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| package models | |||||
| package webhook | |||||
| import ( | import ( | ||||
| "encoding/json" | "encoding/json" | ||||
| "fmt" | "fmt" | ||||
| "strings" | "strings" | ||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/git" | "code.gitea.io/gitea/modules/git" | ||||
| api "code.gitea.io/gitea/modules/structs" | api "code.gitea.io/gitea/modules/structs" | ||||
| ) | ) | ||||
| @@ -357,7 +358,7 @@ func getMSTeamsIssuesPayload(p *api.IssuePayload) (*MSTeamsPayload, error) { | |||||
| func getMSTeamsIssueCommentPayload(p *api.IssueCommentPayload) (*MSTeamsPayload, error) { | func getMSTeamsIssueCommentPayload(p *api.IssueCommentPayload) (*MSTeamsPayload, error) { | ||||
| title := fmt.Sprintf("#%d: %s", p.Issue.Index, p.Issue.Title) | title := fmt.Sprintf("#%d: %s", p.Issue.Index, p.Issue.Title) | ||||
| url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID)) | |||||
| url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, models.CommentHashTag(p.Comment.ID)) | |||||
| content := "" | content := "" | ||||
| var color int | var color int | ||||
| switch p.Action { | switch p.Action { | ||||
| @@ -530,7 +531,7 @@ func getMSTeamsPullRequestPayload(p *api.PullRequestPayload) (*MSTeamsPayload, e | |||||
| }, nil | }, nil | ||||
| } | } | ||||
| func getMSTeamsPullRequestApprovalPayload(p *api.PullRequestPayload, event HookEventType) (*MSTeamsPayload, error) { | |||||
| func getMSTeamsPullRequestApprovalPayload(p *api.PullRequestPayload, event models.HookEventType) (*MSTeamsPayload, error) { | |||||
| var text, title string | var text, title string | ||||
| var color int | var color int | ||||
| switch p.Action { | switch p.Action { | ||||
| @@ -544,11 +545,11 @@ func getMSTeamsPullRequestApprovalPayload(p *api.PullRequestPayload, event HookE | |||||
| text = p.Review.Content | text = p.Review.Content | ||||
| switch event { | switch event { | ||||
| case HookEventPullRequestApproved: | |||||
| case models.HookEventPullRequestApproved: | |||||
| color = greenColor | color = greenColor | ||||
| case HookEventPullRequestRejected: | |||||
| case models.HookEventPullRequestRejected: | |||||
| color = redColor | color = redColor | ||||
| case HookEventPullRequestComment: | |||||
| case models.HookEventPullRequestComment: | |||||
| color = greyColor | color = greyColor | ||||
| default: | default: | ||||
| color = yellowColor | color = yellowColor | ||||
| @@ -699,29 +700,29 @@ func getMSTeamsReleasePayload(p *api.ReleasePayload) (*MSTeamsPayload, error) { | |||||
| } | } | ||||
| // GetMSTeamsPayload converts a MSTeams webhook into a MSTeamsPayload | // GetMSTeamsPayload converts a MSTeams webhook into a MSTeamsPayload | ||||
| func GetMSTeamsPayload(p api.Payloader, event HookEventType, meta string) (*MSTeamsPayload, error) { | |||||
| func GetMSTeamsPayload(p api.Payloader, event models.HookEventType, meta string) (*MSTeamsPayload, error) { | |||||
| s := new(MSTeamsPayload) | s := new(MSTeamsPayload) | ||||
| switch event { | switch event { | ||||
| case HookEventCreate: | |||||
| case models.HookEventCreate: | |||||
| return getMSTeamsCreatePayload(p.(*api.CreatePayload)) | return getMSTeamsCreatePayload(p.(*api.CreatePayload)) | ||||
| case HookEventDelete: | |||||
| case models.HookEventDelete: | |||||
| return getMSTeamsDeletePayload(p.(*api.DeletePayload)) | return getMSTeamsDeletePayload(p.(*api.DeletePayload)) | ||||
| case HookEventFork: | |||||
| case models.HookEventFork: | |||||
| return getMSTeamsForkPayload(p.(*api.ForkPayload)) | return getMSTeamsForkPayload(p.(*api.ForkPayload)) | ||||
| case HookEventIssues: | |||||
| case models.HookEventIssues: | |||||
| return getMSTeamsIssuesPayload(p.(*api.IssuePayload)) | return getMSTeamsIssuesPayload(p.(*api.IssuePayload)) | ||||
| case HookEventIssueComment: | |||||
| case models.HookEventIssueComment: | |||||
| return getMSTeamsIssueCommentPayload(p.(*api.IssueCommentPayload)) | return getMSTeamsIssueCommentPayload(p.(*api.IssueCommentPayload)) | ||||
| case HookEventPush: | |||||
| case models.HookEventPush: | |||||
| return getMSTeamsPushPayload(p.(*api.PushPayload)) | return getMSTeamsPushPayload(p.(*api.PushPayload)) | ||||
| case HookEventPullRequest: | |||||
| case models.HookEventPullRequest: | |||||
| return getMSTeamsPullRequestPayload(p.(*api.PullRequestPayload)) | return getMSTeamsPullRequestPayload(p.(*api.PullRequestPayload)) | ||||
| case HookEventPullRequestRejected, HookEventPullRequestApproved, HookEventPullRequestComment: | |||||
| case models.HookEventPullRequestRejected, models.HookEventPullRequestApproved, models.HookEventPullRequestComment: | |||||
| return getMSTeamsPullRequestApprovalPayload(p.(*api.PullRequestPayload), event) | return getMSTeamsPullRequestApprovalPayload(p.(*api.PullRequestPayload), event) | ||||
| case HookEventRepository: | |||||
| case models.HookEventRepository: | |||||
| return getMSTeamsRepositoryPayload(p.(*api.RepositoryPayload)) | return getMSTeamsRepositoryPayload(p.(*api.RepositoryPayload)) | ||||
| case HookEventRelease: | |||||
| case models.HookEventRelease: | |||||
| return getMSTeamsReleasePayload(p.(*api.ReleasePayload)) | return getMSTeamsReleasePayload(p.(*api.ReleasePayload)) | ||||
| } | } | ||||
| @@ -2,7 +2,7 @@ | |||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| package models | |||||
| package webhook | |||||
| import ( | import ( | ||||
| "encoding/json" | "encoding/json" | ||||
| @@ -10,7 +10,9 @@ import ( | |||||
| "fmt" | "fmt" | ||||
| "strings" | "strings" | ||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/git" | "code.gitea.io/gitea/modules/git" | ||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| api "code.gitea.io/gitea/modules/structs" | api "code.gitea.io/gitea/modules/structs" | ||||
| ) | ) | ||||
| @@ -23,6 +25,15 @@ type SlackMeta struct { | |||||
| Color string `json:"color"` | Color string `json:"color"` | ||||
| } | } | ||||
| // GetSlackHook returns slack metadata | |||||
| func GetSlackHook(w *models.Webhook) *SlackMeta { | |||||
| s := &SlackMeta{} | |||||
| if err := json.Unmarshal([]byte(w.Meta), s); err != nil { | |||||
| log.Error("webhook.GetSlackHook(%d): %v", w.ID, err) | |||||
| } | |||||
| return s | |||||
| } | |||||
| // SlackPayload contains the information about the slack channel | // SlackPayload contains the information about the slack channel | ||||
| type SlackPayload struct { | type SlackPayload struct { | ||||
| Channel string `json:"channel"` | Channel string `json:"channel"` | ||||
| @@ -181,7 +192,7 @@ func getSlackIssuesPayload(p *api.IssuePayload, slack *SlackMeta) (*SlackPayload | |||||
| func getSlackIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) (*SlackPayload, error) { | func getSlackIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) (*SlackPayload, error) { | ||||
| senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName) | senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName) | ||||
| titleLink := SlackLinkFormatter(fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID)), | |||||
| titleLink := SlackLinkFormatter(fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, models.CommentHashTag(p.Comment.ID)), | |||||
| fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title)) | fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title)) | ||||
| var text, title, attachmentText string | var text, title, attachmentText string | ||||
| switch p.Action { | switch p.Action { | ||||
| @@ -335,7 +346,7 @@ func getSlackPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) (*S | |||||
| }, nil | }, nil | ||||
| } | } | ||||
| func getSlackPullRequestApprovalPayload(p *api.PullRequestPayload, slack *SlackMeta, event HookEventType) (*SlackPayload, error) { | |||||
| func getSlackPullRequestApprovalPayload(p *api.PullRequestPayload, slack *SlackMeta, event models.HookEventType) (*SlackPayload, error) { | |||||
| senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName) | senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName) | ||||
| titleLink := SlackLinkFormatter(fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index), | titleLink := SlackLinkFormatter(fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index), | ||||
| fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title)) | fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title)) | ||||
| @@ -388,7 +399,7 @@ func getSlackRepositoryPayload(p *api.RepositoryPayload, slack *SlackMeta) (*Sla | |||||
| } | } | ||||
| // GetSlackPayload converts a slack webhook into a SlackPayload | // GetSlackPayload converts a slack webhook into a SlackPayload | ||||
| func GetSlackPayload(p api.Payloader, event HookEventType, meta string) (*SlackPayload, error) { | |||||
| func GetSlackPayload(p api.Payloader, event models.HookEventType, meta string) (*SlackPayload, error) { | |||||
| s := new(SlackPayload) | s := new(SlackPayload) | ||||
| slack := &SlackMeta{} | slack := &SlackMeta{} | ||||
| @@ -397,25 +408,25 @@ func GetSlackPayload(p api.Payloader, event HookEventType, meta string) (*SlackP | |||||
| } | } | ||||
| switch event { | switch event { | ||||
| case HookEventCreate: | |||||
| case models.HookEventCreate: | |||||
| return getSlackCreatePayload(p.(*api.CreatePayload), slack) | return getSlackCreatePayload(p.(*api.CreatePayload), slack) | ||||
| case HookEventDelete: | |||||
| case models.HookEventDelete: | |||||
| return getSlackDeletePayload(p.(*api.DeletePayload), slack) | return getSlackDeletePayload(p.(*api.DeletePayload), slack) | ||||
| case HookEventFork: | |||||
| case models.HookEventFork: | |||||
| return getSlackForkPayload(p.(*api.ForkPayload), slack) | return getSlackForkPayload(p.(*api.ForkPayload), slack) | ||||
| case HookEventIssues: | |||||
| case models.HookEventIssues: | |||||
| return getSlackIssuesPayload(p.(*api.IssuePayload), slack) | return getSlackIssuesPayload(p.(*api.IssuePayload), slack) | ||||
| case HookEventIssueComment: | |||||
| case models.HookEventIssueComment: | |||||
| return getSlackIssueCommentPayload(p.(*api.IssueCommentPayload), slack) | return getSlackIssueCommentPayload(p.(*api.IssueCommentPayload), slack) | ||||
| case HookEventPush: | |||||
| case models.HookEventPush: | |||||
| return getSlackPushPayload(p.(*api.PushPayload), slack) | return getSlackPushPayload(p.(*api.PushPayload), slack) | ||||
| case HookEventPullRequest: | |||||
| case models.HookEventPullRequest: | |||||
| return getSlackPullRequestPayload(p.(*api.PullRequestPayload), slack) | return getSlackPullRequestPayload(p.(*api.PullRequestPayload), slack) | ||||
| case HookEventPullRequestRejected, HookEventPullRequestApproved, HookEventPullRequestComment: | |||||
| case models.HookEventPullRequestRejected, models.HookEventPullRequestApproved, models.HookEventPullRequestComment: | |||||
| return getSlackPullRequestApprovalPayload(p.(*api.PullRequestPayload), slack, event) | return getSlackPullRequestApprovalPayload(p.(*api.PullRequestPayload), slack, event) | ||||
| case HookEventRepository: | |||||
| case models.HookEventRepository: | |||||
| return getSlackRepositoryPayload(p.(*api.RepositoryPayload), slack) | return getSlackRepositoryPayload(p.(*api.RepositoryPayload), slack) | ||||
| case HookEventRelease: | |||||
| case models.HookEventRelease: | |||||
| return getSlackReleasePayload(p.(*api.ReleasePayload), slack) | return getSlackReleasePayload(p.(*api.ReleasePayload), slack) | ||||
| } | } | ||||
| @@ -2,7 +2,7 @@ | |||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| package models | |||||
| package webhook | |||||
| import ( | import ( | ||||
| "encoding/json" | "encoding/json" | ||||
| @@ -10,7 +10,9 @@ import ( | |||||
| "html" | "html" | ||||
| "strings" | "strings" | ||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/git" | "code.gitea.io/gitea/modules/git" | ||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/markup" | "code.gitea.io/gitea/modules/markup" | ||||
| api "code.gitea.io/gitea/modules/structs" | api "code.gitea.io/gitea/modules/structs" | ||||
| ) | ) | ||||
| @@ -30,6 +32,15 @@ type ( | |||||
| } | } | ||||
| ) | ) | ||||
| // GetTelegramHook returns telegram metadata | |||||
| func GetTelegramHook(w *models.Webhook) *TelegramMeta { | |||||
| s := &TelegramMeta{} | |||||
| if err := json.Unmarshal([]byte(w.Meta), s); err != nil { | |||||
| log.Error("webhook.GetTelegramHook(%d): %v", w.ID, err) | |||||
| } | |||||
| return s | |||||
| } | |||||
| // SetSecret sets the telegram secret | // SetSecret sets the telegram secret | ||||
| func (p *TelegramPayload) SetSecret(_ string) {} | func (p *TelegramPayload) SetSecret(_ string) {} | ||||
| @@ -169,7 +180,7 @@ func getTelegramIssuesPayload(p *api.IssuePayload) (*TelegramPayload, error) { | |||||
| } | } | ||||
| func getTelegramIssueCommentPayload(p *api.IssueCommentPayload) (*TelegramPayload, error) { | func getTelegramIssueCommentPayload(p *api.IssueCommentPayload) (*TelegramPayload, error) { | ||||
| url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID)) | |||||
| url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, models.CommentHashTag(p.Comment.ID)) | |||||
| title := fmt.Sprintf(`<a href="%s">#%d %s</a>`, url, p.Issue.Index, html.EscapeString(p.Issue.Title)) | title := fmt.Sprintf(`<a href="%s">#%d %s</a>`, url, p.Issue.Index, html.EscapeString(p.Issue.Title)) | ||||
| var text string | var text string | ||||
| switch p.Action { | switch p.Action { | ||||
| @@ -214,7 +225,7 @@ func getTelegramPullRequestPayload(p *api.PullRequestPayload) (*TelegramPayload, | |||||
| p.PullRequest.HTMLURL, p.Index, p.PullRequest.Title) | p.PullRequest.HTMLURL, p.Index, p.PullRequest.Title) | ||||
| text = p.PullRequest.Body | text = p.PullRequest.Body | ||||
| case api.HookIssueAssigned: | case api.HookIssueAssigned: | ||||
| list, err := MakeAssigneeList(&Issue{ID: p.PullRequest.ID}) | |||||
| list, err := models.MakeAssigneeList(&models.Issue{ID: p.PullRequest.ID}) | |||||
| if err != nil { | if err != nil { | ||||
| return &TelegramPayload{}, err | return &TelegramPayload{}, err | ||||
| } | } | ||||
| @@ -297,27 +308,27 @@ func getTelegramReleasePayload(p *api.ReleasePayload) (*TelegramPayload, error) | |||||
| } | } | ||||
| // GetTelegramPayload converts a telegram webhook into a TelegramPayload | // GetTelegramPayload converts a telegram webhook into a TelegramPayload | ||||
| func GetTelegramPayload(p api.Payloader, event HookEventType, meta string) (*TelegramPayload, error) { | |||||
| func GetTelegramPayload(p api.Payloader, event models.HookEventType, meta string) (*TelegramPayload, error) { | |||||
| s := new(TelegramPayload) | s := new(TelegramPayload) | ||||
| switch event { | switch event { | ||||
| case HookEventCreate: | |||||
| case models.HookEventCreate: | |||||
| return getTelegramCreatePayload(p.(*api.CreatePayload)) | return getTelegramCreatePayload(p.(*api.CreatePayload)) | ||||
| case HookEventDelete: | |||||
| case models.HookEventDelete: | |||||
| return getTelegramDeletePayload(p.(*api.DeletePayload)) | return getTelegramDeletePayload(p.(*api.DeletePayload)) | ||||
| case HookEventFork: | |||||
| case models.HookEventFork: | |||||
| return getTelegramForkPayload(p.(*api.ForkPayload)) | return getTelegramForkPayload(p.(*api.ForkPayload)) | ||||
| case HookEventIssues: | |||||
| case models.HookEventIssues: | |||||
| return getTelegramIssuesPayload(p.(*api.IssuePayload)) | return getTelegramIssuesPayload(p.(*api.IssuePayload)) | ||||
| case HookEventIssueComment: | |||||
| case models.HookEventIssueComment: | |||||
| return getTelegramIssueCommentPayload(p.(*api.IssueCommentPayload)) | return getTelegramIssueCommentPayload(p.(*api.IssueCommentPayload)) | ||||
| case HookEventPush: | |||||
| case models.HookEventPush: | |||||
| return getTelegramPushPayload(p.(*api.PushPayload)) | return getTelegramPushPayload(p.(*api.PushPayload)) | ||||
| case HookEventPullRequest: | |||||
| case models.HookEventPullRequest: | |||||
| return getTelegramPullRequestPayload(p.(*api.PullRequestPayload)) | return getTelegramPullRequestPayload(p.(*api.PullRequestPayload)) | ||||
| case HookEventRepository: | |||||
| case models.HookEventRepository: | |||||
| return getTelegramRepositoryPayload(p.(*api.RepositoryPayload)) | return getTelegramRepositoryPayload(p.(*api.RepositoryPayload)) | ||||
| case HookEventRelease: | |||||
| case models.HookEventRelease: | |||||
| return getTelegramReleasePayload(p.(*api.ReleasePayload)) | return getTelegramReleasePayload(p.(*api.ReleasePayload)) | ||||
| } | } | ||||
| @@ -90,27 +90,27 @@ func prepareWebhook(w *models.Webhook, repo *models.Repository, event models.Hoo | |||||
| // Use separate objects so modifications won't be made on payload on non-Gogs/Gitea type hooks. | // Use separate objects so modifications won't be made on payload on non-Gogs/Gitea type hooks. | ||||
| switch w.HookTaskType { | switch w.HookTaskType { | ||||
| case models.SLACK: | case models.SLACK: | ||||
| payloader, err = models.GetSlackPayload(p, event, w.Meta) | |||||
| payloader, err = GetSlackPayload(p, event, w.Meta) | |||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("GetSlackPayload: %v", err) | return fmt.Errorf("GetSlackPayload: %v", err) | ||||
| } | } | ||||
| case models.DISCORD: | case models.DISCORD: | ||||
| payloader, err = models.GetDiscordPayload(p, event, w.Meta) | |||||
| payloader, err = GetDiscordPayload(p, event, w.Meta) | |||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("GetDiscordPayload: %v", err) | return fmt.Errorf("GetDiscordPayload: %v", err) | ||||
| } | } | ||||
| case models.DINGTALK: | case models.DINGTALK: | ||||
| payloader, err = models.GetDingtalkPayload(p, event, w.Meta) | |||||
| payloader, err = GetDingtalkPayload(p, event, w.Meta) | |||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("GetDingtalkPayload: %v", err) | return fmt.Errorf("GetDingtalkPayload: %v", err) | ||||
| } | } | ||||
| case models.TELEGRAM: | case models.TELEGRAM: | ||||
| payloader, err = models.GetTelegramPayload(p, event, w.Meta) | |||||
| payloader, err = GetTelegramPayload(p, event, w.Meta) | |||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("GetTelegramPayload: %v", err) | return fmt.Errorf("GetTelegramPayload: %v", err) | ||||
| } | } | ||||
| case models.MSTEAMS: | case models.MSTEAMS: | ||||
| payloader, err = models.GetMSTeamsPayload(p, event, w.Meta) | |||||
| payloader, err = GetMSTeamsPayload(p, event, w.Meta) | |||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("GetMSTeamsPayload: %v", err) | return fmt.Errorf("GetMSTeamsPayload: %v", err) | ||||
| } | } | ||||
| @@ -12,6 +12,18 @@ import ( | |||||
| "github.com/stretchr/testify/assert" | "github.com/stretchr/testify/assert" | ||||
| ) | ) | ||||
| func TestWebhook_GetSlackHook(t *testing.T) { | |||||
| w := &models.Webhook{ | |||||
| Meta: `{"channel": "foo", "username": "username", "color": "blue"}`, | |||||
| } | |||||
| slackHook := GetSlackHook(w) | |||||
| assert.Equal(t, *slackHook, SlackMeta{ | |||||
| Channel: "foo", | |||||
| Username: "username", | |||||
| Color: "blue", | |||||
| }) | |||||
| } | |||||
| func TestPrepareWebhooks(t *testing.T) { | func TestPrepareWebhooks(t *testing.T) { | ||||
| assert.NoError(t, models.PrepareTestDatabase()) | assert.NoError(t, models.PrepareTestDatabase()) | ||||
| @@ -15,6 +15,7 @@ import ( | |||||
| "code.gitea.io/gitea/modules/structs" | "code.gitea.io/gitea/modules/structs" | ||||
| api "code.gitea.io/gitea/modules/structs" | api "code.gitea.io/gitea/modules/structs" | ||||
| "code.gitea.io/gitea/modules/util" | "code.gitea.io/gitea/modules/util" | ||||
| "code.gitea.io/gitea/modules/webhook" | |||||
| "github.com/unknwon/com" | "github.com/unknwon/com" | ||||
| ) | ) | ||||
| @@ -166,7 +167,7 @@ func ToHook(repoLink string, w *models.Webhook) *api.Hook { | |||||
| "content_type": w.ContentType.Name(), | "content_type": w.ContentType.Name(), | ||||
| } | } | ||||
| if w.HookTaskType == models.SLACK { | if w.HookTaskType == models.SLACK { | ||||
| s := w.GetSlackHook() | |||||
| s := webhook.GetSlackHook(w) | |||||
| config["channel"] = s.Channel | config["channel"] = s.Channel | ||||
| config["username"] = s.Username | config["username"] = s.Username | ||||
| config["icon_url"] = s.IconURL | config["icon_url"] = s.IconURL | ||||
| @@ -12,6 +12,7 @@ import ( | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| api "code.gitea.io/gitea/modules/structs" | api "code.gitea.io/gitea/modules/structs" | ||||
| "code.gitea.io/gitea/modules/webhook" | |||||
| "code.gitea.io/gitea/routers/api/v1/convert" | "code.gitea.io/gitea/routers/api/v1/convert" | ||||
| "code.gitea.io/gitea/routers/utils" | "code.gitea.io/gitea/routers/utils" | ||||
| @@ -129,7 +130,7 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, orgID, repoID | |||||
| return nil, false | return nil, false | ||||
| } | } | ||||
| meta, err := json.Marshal(&models.SlackMeta{ | |||||
| meta, err := json.Marshal(&webhook.SlackMeta{ | |||||
| Channel: strings.TrimSpace(channel), | Channel: strings.TrimSpace(channel), | ||||
| Username: form.Config["username"], | Username: form.Config["username"], | ||||
| IconURL: form.Config["icon_url"], | IconURL: form.Config["icon_url"], | ||||
| @@ -203,7 +204,7 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *models.Webho | |||||
| if w.HookTaskType == models.SLACK { | if w.HookTaskType == models.SLACK { | ||||
| if channel, ok := form.Config["channel"]; ok { | if channel, ok := form.Config["channel"]; ok { | ||||
| meta, err := json.Marshal(&models.SlackMeta{ | |||||
| meta, err := json.Marshal(&webhook.SlackMeta{ | |||||
| Channel: channel, | Channel: channel, | ||||
| Username: form.Config["username"], | Username: form.Config["username"], | ||||
| IconURL: form.Config["icon_url"], | IconURL: form.Config["icon_url"], | ||||
| @@ -268,7 +268,7 @@ func DiscordHooksNewPost(ctx *context.Context, form auth.NewDiscordHookForm) { | |||||
| return | return | ||||
| } | } | ||||
| meta, err := json.Marshal(&models.DiscordMeta{ | |||||
| meta, err := json.Marshal(&webhook.DiscordMeta{ | |||||
| Username: form.Username, | Username: form.Username, | ||||
| IconURL: form.IconURL, | IconURL: form.IconURL, | ||||
| }) | }) | ||||
| @@ -357,7 +357,7 @@ func TelegramHooksNewPost(ctx *context.Context, form auth.NewTelegramHookForm) { | |||||
| return | return | ||||
| } | } | ||||
| meta, err := json.Marshal(&models.TelegramMeta{ | |||||
| meta, err := json.Marshal(&webhook.TelegramMeta{ | |||||
| BotToken: form.BotToken, | BotToken: form.BotToken, | ||||
| ChatID: form.ChatID, | ChatID: form.ChatID, | ||||
| }) | }) | ||||
| @@ -452,7 +452,7 @@ func SlackHooksNewPost(ctx *context.Context, form auth.NewSlackHookForm) { | |||||
| return | return | ||||
| } | } | ||||
| meta, err := json.Marshal(&models.SlackMeta{ | |||||
| meta, err := json.Marshal(&webhook.SlackMeta{ | |||||
| Channel: strings.TrimSpace(form.Channel), | Channel: strings.TrimSpace(form.Channel), | ||||
| Username: form.Username, | Username: form.Username, | ||||
| IconURL: form.IconURL, | IconURL: form.IconURL, | ||||
| @@ -515,11 +515,11 @@ func checkWebhook(ctx *context.Context) (*orgRepoCtx, *models.Webhook) { | |||||
| ctx.Data["HookType"] = w.HookTaskType.Name() | ctx.Data["HookType"] = w.HookTaskType.Name() | ||||
| switch w.HookTaskType { | switch w.HookTaskType { | ||||
| case models.SLACK: | case models.SLACK: | ||||
| ctx.Data["SlackHook"] = w.GetSlackHook() | |||||
| ctx.Data["SlackHook"] = webhook.GetSlackHook(w) | |||||
| case models.DISCORD: | case models.DISCORD: | ||||
| ctx.Data["DiscordHook"] = w.GetDiscordHook() | |||||
| ctx.Data["DiscordHook"] = webhook.GetDiscordHook(w) | |||||
| case models.TELEGRAM: | case models.TELEGRAM: | ||||
| ctx.Data["TelegramHook"] = w.GetTelegramHook() | |||||
| ctx.Data["TelegramHook"] = webhook.GetTelegramHook(w) | |||||
| } | } | ||||
| ctx.Data["History"], err = w.History(1) | ctx.Data["History"], err = w.History(1) | ||||
| @@ -646,7 +646,7 @@ func SlackHooksEditPost(ctx *context.Context, form auth.NewSlackHookForm) { | |||||
| return | return | ||||
| } | } | ||||
| meta, err := json.Marshal(&models.SlackMeta{ | |||||
| meta, err := json.Marshal(&webhook.SlackMeta{ | |||||
| Channel: strings.TrimSpace(form.Channel), | Channel: strings.TrimSpace(form.Channel), | ||||
| Username: form.Username, | Username: form.Username, | ||||
| IconURL: form.IconURL, | IconURL: form.IconURL, | ||||
| @@ -690,7 +690,7 @@ func DiscordHooksEditPost(ctx *context.Context, form auth.NewDiscordHookForm) { | |||||
| return | return | ||||
| } | } | ||||
| meta, err := json.Marshal(&models.DiscordMeta{ | |||||
| meta, err := json.Marshal(&webhook.DiscordMeta{ | |||||
| Username: form.Username, | Username: form.Username, | ||||
| IconURL: form.IconURL, | IconURL: form.IconURL, | ||||
| }) | }) | ||||
| @@ -763,7 +763,7 @@ func TelegramHooksEditPost(ctx *context.Context, form auth.NewTelegramHookForm) | |||||
| ctx.HTML(200, orCtx.NewTemplate) | ctx.HTML(200, orCtx.NewTemplate) | ||||
| return | return | ||||
| } | } | ||||
| meta, err := json.Marshal(&models.TelegramMeta{ | |||||
| meta, err := json.Marshal(&webhook.TelegramMeta{ | |||||
| BotToken: form.BotToken, | BotToken: form.BotToken, | ||||
| ChatID: form.ChatID, | ChatID: form.ChatID, | ||||
| }) | }) | ||||