Move more webhook codes from models to webhook module (#8802)

* Move more webhook codes from models to webhook module
release/v1.15
Lunny Xiao 2019-11-04 06:13:25 +08:00 committed by zeripath
parent 491887d441
commit a966a0298e
12 changed files with 145 additions and 135 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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))
} }

View File

@ -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:

View File

@ -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))
} }

View File

@ -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)
} }

View File

@ -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))
} }

View File

@ -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)
} }

View File

@ -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())

View File

@ -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

View File

@ -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"],

View File

@ -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,
}) })