From ebc35f2b2e700b30d288b622cd9409a0f741e928 Mon Sep 17 00:00:00 2001
From: Cornel <github@codejuggle.dj>
Date: Thu, 25 Jun 2020 06:39:43 +0300
Subject: [PATCH] Fix comments webhook panic (#12046)

* Fix webhook comment handling type cast panic

* Handle HookIssueReviewed action in webhook

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
---
 modules/webhook/dingtalk.go |  6 +++++-
 modules/webhook/discord.go  |  6 +++++-
 modules/webhook/feishu.go   | 10 +++++++---
 modules/webhook/general.go  |  2 ++
 modules/webhook/matrix.go   |  6 +++++-
 modules/webhook/msteams.go  |  6 +++++-
 modules/webhook/slack.go    |  6 +++++-
 modules/webhook/telegram.go |  6 +++++-
 8 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/modules/webhook/dingtalk.go b/modules/webhook/dingtalk.go
index f2dd5a79ed..4e0e52451a 100644
--- a/modules/webhook/dingtalk.go
+++ b/modules/webhook/dingtalk.go
@@ -264,7 +264,11 @@ func GetDingtalkPayload(p api.Payloader, event models.HookEventType, meta string
 	case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
 		return getDingtalkIssuesPayload(p.(*api.IssuePayload))
 	case models.HookEventIssueComment, models.HookEventPullRequestComment:
-		return getDingtalkIssueCommentPayload(p.(*api.IssueCommentPayload))
+		pl, ok := p.(*api.IssueCommentPayload)
+		if ok {
+			return getDingtalkIssueCommentPayload(pl)
+		}
+		return getDingtalkPullRequestPayload(p.(*api.PullRequestPayload))
 	case models.HookEventPush:
 		return getDingtalkPushPayload(p.(*api.PushPayload))
 	case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
diff --git a/modules/webhook/discord.go b/modules/webhook/discord.go
index e455a102bd..761129d8d9 100644
--- a/modules/webhook/discord.go
+++ b/modules/webhook/discord.go
@@ -408,7 +408,11 @@ func GetDiscordPayload(p api.Payloader, event models.HookEventType, meta string)
 	case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
 		return getDiscordIssuesPayload(p.(*api.IssuePayload), discord)
 	case models.HookEventIssueComment, models.HookEventPullRequestComment:
-		return getDiscordIssueCommentPayload(p.(*api.IssueCommentPayload), discord)
+		pl, ok := p.(*api.IssueCommentPayload)
+		if ok {
+			return getDiscordIssueCommentPayload(pl, discord)
+		}
+		return getDiscordPullRequestPayload(p.(*api.PullRequestPayload), discord)
 	case models.HookEventPush:
 		return getDiscordPushPayload(p.(*api.PushPayload), discord)
 	case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
diff --git a/modules/webhook/feishu.go b/modules/webhook/feishu.go
index 57eb909c48..4beda9014c 100644
--- a/modules/webhook/feishu.go
+++ b/modules/webhook/feishu.go
@@ -183,13 +183,17 @@ func GetFeishuPayload(p api.Payloader, event models.HookEventType, meta string)
 		return getFeishuForkPayload(p.(*api.ForkPayload))
 	case models.HookEventIssues:
 		return getFeishuIssuesPayload(p.(*api.IssuePayload))
-	case models.HookEventIssueComment:
-		return getFeishuIssueCommentPayload(p.(*api.IssueCommentPayload))
+	case models.HookEventIssueComment, models.HookEventPullRequestComment:
+		pl, ok := p.(*api.IssueCommentPayload)
+		if ok {
+			return getFeishuIssueCommentPayload(pl)
+		}
+		return getFeishuPullRequestPayload(p.(*api.PullRequestPayload))
 	case models.HookEventPush:
 		return getFeishuPushPayload(p.(*api.PushPayload))
 	case models.HookEventPullRequest:
 		return getFeishuPullRequestPayload(p.(*api.PullRequestPayload))
-	case models.HookEventPullRequestReviewApproved, models.HookEventPullRequestReviewRejected, models.HookEventPullRequestComment:
+	case models.HookEventPullRequestReviewApproved, models.HookEventPullRequestReviewRejected:
 		return getFeishuPullRequestApprovalPayload(p.(*api.PullRequestPayload), event)
 	case models.HookEventRepository:
 		return getFeishuRepositoryPayload(p.(*api.RepositoryPayload))
diff --git a/modules/webhook/general.go b/modules/webhook/general.go
index bc9a10b529..ec247a2410 100644
--- a/modules/webhook/general.go
+++ b/modules/webhook/general.go
@@ -119,6 +119,8 @@ func getPullRequestPayloadInfo(p *api.PullRequestPayload, linkFormatter linkForm
 			linkFormatter(mileStoneLink, p.PullRequest.Milestone.Title), titleLink)
 	case api.HookIssueDemilestoned:
 		text = fmt.Sprintf("[%s] Pull request milestone cleared: %s", repoLink, titleLink)
+	case api.HookIssueReviewed:
+		text = fmt.Sprintf("[%s] Pull request reviewed: %s", repoLink, titleLink)
 	}
 	if withSender {
 		text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName))
diff --git a/modules/webhook/matrix.go b/modules/webhook/matrix.go
index bf72e6e340..68c65623f7 100644
--- a/modules/webhook/matrix.go
+++ b/modules/webhook/matrix.go
@@ -230,7 +230,11 @@ func GetMatrixPayload(p api.Payloader, event models.HookEventType, meta string)
 	case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
 		return getMatrixIssuesPayload(p.(*api.IssuePayload), matrix)
 	case models.HookEventIssueComment, models.HookEventPullRequestComment:
-		return getMatrixIssueCommentPayload(p.(*api.IssueCommentPayload), matrix)
+		pl, ok := p.(*api.IssueCommentPayload)
+		if ok {
+			return getMatrixIssueCommentPayload(pl, matrix)
+		}
+		return getMatrixPullRequestPayload(p.(*api.PullRequestPayload), matrix)
 	case models.HookEventPush:
 		return getMatrixPushPayload(p.(*api.PushPayload), matrix)
 	case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
diff --git a/modules/webhook/msteams.go b/modules/webhook/msteams.go
index a0925010d6..e7ec396f29 100644
--- a/modules/webhook/msteams.go
+++ b/modules/webhook/msteams.go
@@ -558,7 +558,11 @@ func GetMSTeamsPayload(p api.Payloader, event models.HookEventType, meta string)
 	case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
 		return getMSTeamsIssuesPayload(p.(*api.IssuePayload))
 	case models.HookEventIssueComment, models.HookEventPullRequestComment:
-		return getMSTeamsIssueCommentPayload(p.(*api.IssueCommentPayload))
+		pl, ok := p.(*api.IssueCommentPayload)
+		if ok {
+			return getMSTeamsIssueCommentPayload(pl)
+		}
+		return getMSTeamsPullRequestPayload(p.(*api.PullRequestPayload))
 	case models.HookEventPush:
 		return getMSTeamsPushPayload(p.(*api.PushPayload))
 	case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
diff --git a/modules/webhook/slack.go b/modules/webhook/slack.go
index 1e9413efd6..4177bd1250 100644
--- a/modules/webhook/slack.go
+++ b/modules/webhook/slack.go
@@ -321,7 +321,11 @@ func GetSlackPayload(p api.Payloader, event models.HookEventType, meta string) (
 	case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
 		return getSlackIssuesPayload(p.(*api.IssuePayload), slack)
 	case models.HookEventIssueComment, models.HookEventPullRequestComment:
-		return getSlackIssueCommentPayload(p.(*api.IssueCommentPayload), slack)
+		pl, ok := p.(*api.IssueCommentPayload)
+		if ok {
+			return getSlackIssueCommentPayload(pl, slack)
+		}
+		return getSlackPullRequestPayload(p.(*api.PullRequestPayload), slack)
 	case models.HookEventPush:
 		return getSlackPushPayload(p.(*api.PushPayload), slack)
 	case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,
diff --git a/modules/webhook/telegram.go b/modules/webhook/telegram.go
index cf096e2c66..6d2f804a70 100644
--- a/modules/webhook/telegram.go
+++ b/modules/webhook/telegram.go
@@ -206,7 +206,11 @@ func GetTelegramPayload(p api.Payloader, event models.HookEventType, meta string
 	case models.HookEventIssues, models.HookEventIssueAssign, models.HookEventIssueLabel, models.HookEventIssueMilestone:
 		return getTelegramIssuesPayload(p.(*api.IssuePayload))
 	case models.HookEventIssueComment, models.HookEventPullRequestComment:
-		return getTelegramIssueCommentPayload(p.(*api.IssueCommentPayload))
+		pl, ok := p.(*api.IssueCommentPayload)
+		if ok {
+			return getTelegramIssueCommentPayload(pl)
+		}
+		return getTelegramPullRequestPayload(p.(*api.PullRequestPayload))
 	case models.HookEventPush:
 		return getTelegramPushPayload(p.(*api.PushPayload))
 	case models.HookEventPullRequest, models.HookEventPullRequestAssign, models.HookEventPullRequestLabel,