2015-12-05 21:24:13 +03:00
// Copyright 2015 The Gogs Authors. All rights reserved.
2017-05-29 10:17:15 +03:00
// Copyright 2017 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2015-12-05 21:24:13 +03:00
package repo
import (
"errors"
"fmt"
2021-04-05 18:30:52 +03:00
"net/http"
2021-11-16 21:18:25 +03:00
"net/url"
2019-03-19 05:33:20 +03:00
"path"
2015-12-05 21:24:13 +03:00
"strings"
2021-11-28 14:58:28 +03:00
"code.gitea.io/gitea/models/perm"
2021-11-24 12:49:20 +03:00
user_model "code.gitea.io/gitea/models/user"
2021-11-10 08:13:16 +03:00
"code.gitea.io/gitea/models/webhook"
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
2019-03-27 12:33:00 +03:00
"code.gitea.io/gitea/modules/git"
2021-07-24 19:03:58 +03:00
"code.gitea.io/gitea/modules/json"
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/modules/setting"
2019-05-11 13:21:34 +03:00
api "code.gitea.io/gitea/modules/structs"
2020-12-25 12:59:32 +03:00
"code.gitea.io/gitea/modules/util"
2021-01-26 18:36:53 +03:00
"code.gitea.io/gitea/modules/web"
2023-01-01 18:23:15 +03:00
webhook_module "code.gitea.io/gitea/modules/webhook"
2022-12-29 05:57:15 +03:00
"code.gitea.io/gitea/services/convert"
2021-04-06 22:44:05 +03:00
"code.gitea.io/gitea/services/forms"
2021-11-10 08:13:16 +03:00
webhook_service "code.gitea.io/gitea/services/webhook"
2015-12-05 21:24:13 +03:00
)
const (
2019-03-19 05:33:20 +03:00
tplHooks base . TplName = "repo/settings/webhook/base"
tplHookNew base . TplName = "repo/settings/webhook/new"
tplOrgHookNew base . TplName = "org/settings/hook_new"
tplAdminHookNew base . TplName = "admin/hook_new"
2015-12-05 21:24:13 +03:00
)
2016-11-24 10:04:31 +03:00
// Webhooks render web hooks list page
2016-03-11 19:56:52 +03:00
func Webhooks ( ctx * context . Context ) {
2015-12-05 21:24:13 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.settings.hooks" )
ctx . Data [ "PageIsSettingsHooks" ] = true
2019-03-19 05:33:20 +03:00
ctx . Data [ "BaseLink" ] = ctx . Repo . RepoLink + "/settings/hooks"
2021-01-15 02:24:03 +03:00
ctx . Data [ "BaseLinkNew" ] = ctx . Repo . RepoLink + "/settings/hooks"
2018-01-03 18:50:09 +03:00
ctx . Data [ "Description" ] = ctx . Tr ( "repo.settings.hooks_desc" , "https://docs.gitea.io/en-us/webhooks/" )
2015-12-05 21:24:13 +03:00
2022-05-20 17:08:52 +03:00
ws , err := webhook . ListWebhooksByOpts ( ctx , & webhook . ListWebhookOptions { RepoID : ctx . Repo . Repository . ID } )
2015-12-05 21:24:13 +03:00
if err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "GetWebhooksByRepoID" , err )
2015-12-05 21:24:13 +03:00
return
}
ctx . Data [ "Webhooks" ] = ws
2021-04-05 18:30:52 +03:00
ctx . HTML ( http . StatusOK , tplHooks )
2015-12-05 21:24:13 +03:00
}
2016-11-24 10:04:31 +03:00
type orgRepoCtx struct {
2020-03-09 01:08:05 +03:00
OrgID int64
RepoID int64
IsAdmin bool
IsSystemWebhook bool
Link string
2021-01-15 02:24:03 +03:00
LinkNew string
2020-03-09 01:08:05 +03:00
NewTemplate base . TplName
2015-12-05 21:24:13 +03:00
}
2020-03-09 01:08:05 +03:00
// getOrgRepoCtx determines whether this is a repo, organization, or admin (both default and system) context.
2016-11-24 10:04:31 +03:00
func getOrgRepoCtx ( ctx * context . Context ) ( * orgRepoCtx , error ) {
2015-12-05 21:24:13 +03:00
if len ( ctx . Repo . RepoLink ) > 0 {
2016-11-24 10:04:31 +03:00
return & orgRepoCtx {
2015-12-05 21:24:13 +03:00
RepoID : ctx . Repo . Repository . ID ,
2019-03-19 05:33:20 +03:00
Link : path . Join ( ctx . Repo . RepoLink , "settings/hooks" ) ,
2021-01-15 02:24:03 +03:00
LinkNew : path . Join ( ctx . Repo . RepoLink , "settings/hooks" ) ,
2016-11-07 23:58:22 +03:00
NewTemplate : tplHookNew ,
2015-12-05 21:24:13 +03:00
} , nil
}
if len ( ctx . Org . OrgLink ) > 0 {
2016-11-24 10:04:31 +03:00
return & orgRepoCtx {
2016-07-23 20:08:22 +03:00
OrgID : ctx . Org . Organization . ID ,
2019-03-19 05:33:20 +03:00
Link : path . Join ( ctx . Org . OrgLink , "settings/hooks" ) ,
2021-01-15 02:24:03 +03:00
LinkNew : path . Join ( ctx . Org . OrgLink , "settings/hooks" ) ,
2016-11-07 23:58:22 +03:00
NewTemplate : tplOrgHookNew ,
2015-12-05 21:24:13 +03:00
} , nil
}
2022-03-22 10:03:22 +03:00
if ctx . Doer . IsAdmin {
2020-03-09 01:08:05 +03:00
// Are we looking at default webhooks?
2021-01-15 02:24:03 +03:00
if ctx . Params ( ":configType" ) == "default-hooks" {
2020-03-09 01:08:05 +03:00
return & orgRepoCtx {
IsAdmin : true ,
Link : path . Join ( setting . AppSubURL , "/admin/hooks" ) ,
2021-01-15 02:24:03 +03:00
LinkNew : path . Join ( setting . AppSubURL , "/admin/default-hooks" ) ,
2020-03-09 01:08:05 +03:00
NewTemplate : tplAdminHookNew ,
} , nil
}
// Must be system webhooks instead
2019-03-19 05:33:20 +03:00
return & orgRepoCtx {
2020-03-09 01:08:05 +03:00
IsAdmin : true ,
IsSystemWebhook : true ,
2021-01-15 02:24:03 +03:00
Link : path . Join ( setting . AppSubURL , "/admin/hooks" ) ,
LinkNew : path . Join ( setting . AppSubURL , "/admin/system-hooks" ) ,
2020-03-09 01:08:05 +03:00
NewTemplate : tplAdminHookNew ,
2019-03-19 05:33:20 +03:00
} , nil
}
2022-02-26 15:15:32 +03:00
return nil , errors . New ( "unable to set OrgRepo context" )
2015-12-05 21:24:13 +03:00
}
2016-03-11 19:56:52 +03:00
func checkHookType ( ctx * context . Context ) string {
2015-12-05 21:24:13 +03:00
hookType := strings . ToLower ( ctx . Params ( ":type" ) )
2020-12-25 12:59:32 +03:00
if ! util . IsStringInSlice ( hookType , setting . Webhook . Types , true ) {
2018-01-11 00:34:17 +03:00
ctx . NotFound ( "checkHookType" , nil )
2015-12-05 21:24:13 +03:00
return ""
}
return hookType
}
2016-11-24 10:04:31 +03:00
// WebhooksNew render creating webhook page
2016-03-11 19:56:52 +03:00
func WebhooksNew ( ctx * context . Context ) {
2015-12-05 21:24:13 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.settings.add_webhook" )
2023-01-01 18:23:15 +03:00
ctx . Data [ "Webhook" ] = webhook . Webhook { HookEvent : & webhook_module . HookEvent { } }
2015-12-05 21:24:13 +03:00
orCtx , err := getOrgRepoCtx ( ctx )
if err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "getOrgRepoCtx" , err )
2015-12-05 21:24:13 +03:00
return
}
2020-03-09 01:08:05 +03:00
if orCtx . IsAdmin && orCtx . IsSystemWebhook {
ctx . Data [ "PageIsAdminSystemHooks" ] = true
ctx . Data [ "PageIsAdminSystemHooksNew" ] = true
} else if orCtx . IsAdmin {
2021-01-15 02:24:03 +03:00
ctx . Data [ "PageIsAdminDefaultHooks" ] = true
ctx . Data [ "PageIsAdminDefaultHooksNew" ] = true
2019-03-19 05:33:20 +03:00
} else {
ctx . Data [ "PageIsSettingsHooks" ] = true
ctx . Data [ "PageIsSettingsHooksNew" ] = true
}
2017-08-28 08:06:45 +03:00
hookType := checkHookType ( ctx )
ctx . Data [ "HookType" ] = hookType
2015-12-05 21:24:13 +03:00
if ctx . Written ( ) {
return
}
2017-08-28 08:06:45 +03:00
if hookType == "discord" {
ctx . Data [ "DiscordHook" ] = map [ string ] interface { } {
"Username" : "Gitea" ,
}
}
2021-01-15 02:24:03 +03:00
ctx . Data [ "BaseLink" ] = orCtx . LinkNew
2015-12-05 21:24:13 +03:00
2021-04-05 18:30:52 +03:00
ctx . HTML ( http . StatusOK , orCtx . NewTemplate )
2015-12-05 21:24:13 +03:00
}
2021-11-10 08:13:16 +03:00
// ParseHookEvent convert web form content to webhook.HookEvent
2023-01-01 18:23:15 +03:00
func ParseHookEvent ( form forms . WebhookForm ) * webhook_module . HookEvent {
return & webhook_module . HookEvent {
2015-12-05 21:24:13 +03:00
PushOnly : form . PushOnly ( ) ,
SendEverything : form . SendEverything ( ) ,
ChooseEvents : form . ChooseEvents ( ) ,
2023-01-01 18:23:15 +03:00
HookEvents : webhook_module . HookEvents {
2020-03-06 08:10:48 +03:00
Create : form . Create ,
Delete : form . Delete ,
Fork : form . Fork ,
Issues : form . Issues ,
IssueAssign : form . IssueAssign ,
IssueLabel : form . IssueLabel ,
IssueMilestone : form . IssueMilestone ,
IssueComment : form . IssueComment ,
Release : form . Release ,
Push : form . Push ,
PullRequest : form . PullRequest ,
PullRequestAssign : form . PullRequestAssign ,
PullRequestLabel : form . PullRequestLabel ,
PullRequestMilestone : form . PullRequestMilestone ,
PullRequestComment : form . PullRequestComment ,
PullRequestReview : form . PullRequestReview ,
PullRequestSync : form . PullRequestSync ,
2022-09-04 22:54:23 +03:00
Wiki : form . Wiki ,
2020-03-06 08:10:48 +03:00
Repository : form . Repository ,
2022-03-30 11:42:47 +03:00
Package : form . Package ,
2015-12-05 21:24:13 +03:00
} ,
2019-09-09 08:48:21 +03:00
BranchFilter : form . BranchFilter ,
2015-12-05 21:24:13 +03:00
}
}
2022-08-23 09:52:35 +03:00
type webhookParams struct {
// Type should be imported from webhook package (webhook.XXX)
Type string
2022-08-11 18:48:23 +03:00
URL string
ContentType webhook . HookContentType
Secret string
HTTPMethod string
WebhookForm forms . WebhookForm
Meta interface { }
}
2022-08-23 09:52:35 +03:00
func createWebhook ( ctx * context . Context , params webhookParams ) {
2017-05-29 10:17:15 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.settings.add_webhook" )
ctx . Data [ "PageIsSettingsHooks" ] = true
ctx . Data [ "PageIsSettingsHooksNew" ] = true
2023-01-01 18:23:15 +03:00
ctx . Data [ "Webhook" ] = webhook . Webhook { HookEvent : & webhook_module . HookEvent { } }
2022-08-11 18:48:23 +03:00
ctx . Data [ "HookType" ] = params . Type
2017-05-29 10:17:15 +03:00
orCtx , err := getOrgRepoCtx ( ctx )
if err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "getOrgRepoCtx" , err )
2017-05-29 10:17:15 +03:00
return
}
2021-01-15 02:24:03 +03:00
ctx . Data [ "BaseLink" ] = orCtx . LinkNew
2017-05-29 10:17:15 +03:00
if ctx . HasError ( ) {
2021-04-05 18:30:52 +03:00
ctx . HTML ( http . StatusOK , orCtx . NewTemplate )
2017-05-29 10:17:15 +03:00
return
}
2022-08-11 18:48:23 +03:00
var meta [ ] byte
if params . Meta != nil {
meta , err = json . Marshal ( params . Meta )
if err != nil {
ctx . ServerError ( "Marshal" , err )
return
}
2017-05-29 10:17:15 +03:00
}
2021-11-10 08:13:16 +03:00
w := & webhook . Webhook {
2020-03-09 01:08:05 +03:00
RepoID : orCtx . RepoID ,
2022-08-11 18:48:23 +03:00
URL : params . URL ,
HTTPMethod : params . HTTPMethod ,
ContentType : params . ContentType ,
Secret : params . Secret ,
HookEvent : ParseHookEvent ( params . WebhookForm ) ,
IsActive : params . WebhookForm . Active ,
Type : params . Type ,
Meta : string ( meta ) ,
2020-03-09 01:08:05 +03:00
OrgID : orCtx . OrgID ,
IsSystemWebhook : orCtx . IsSystemWebhook ,
2017-05-29 10:17:15 +03:00
}
2022-11-03 21:23:20 +03:00
err = w . SetHeaderAuthorization ( params . WebhookForm . AuthorizationHeader )
if err != nil {
ctx . ServerError ( "SetHeaderAuthorization" , err )
return
}
2017-05-29 10:17:15 +03:00
if err := w . UpdateEvent ( ) ; err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "UpdateEvent" , err )
2017-05-29 10:17:15 +03:00
return
2022-03-22 18:22:54 +03:00
} else if err := webhook . CreateWebhook ( ctx , w ) ; err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "CreateWebhook" , err )
2017-05-29 10:17:15 +03:00
return
}
ctx . Flash . Success ( ctx . Tr ( "repo.settings.add_hook_success" ) )
2019-03-19 05:33:20 +03:00
ctx . Redirect ( orCtx . Link )
2017-05-29 10:17:15 +03:00
}
2022-08-23 09:52:35 +03:00
func editWebhook ( ctx * context . Context , params webhookParams ) {
ctx . Data [ "Title" ] = ctx . Tr ( "repo.settings.update_webhook" )
ctx . Data [ "PageIsSettingsHooks" ] = true
ctx . Data [ "PageIsSettingsHooksEdit" ] = true
orCtx , w := checkWebhook ( ctx )
if ctx . Written ( ) {
return
}
ctx . Data [ "Webhook" ] = w
if ctx . HasError ( ) {
ctx . HTML ( http . StatusOK , orCtx . NewTemplate )
return
}
var meta [ ] byte
var err error
if params . Meta != nil {
meta , err = json . Marshal ( params . Meta )
if err != nil {
ctx . ServerError ( "Marshal" , err )
return
}
}
w . URL = params . URL
w . ContentType = params . ContentType
w . Secret = params . Secret
w . HookEvent = ParseHookEvent ( params . WebhookForm )
w . IsActive = params . WebhookForm . Active
w . HTTPMethod = params . HTTPMethod
w . Meta = string ( meta )
2022-11-03 21:23:20 +03:00
err = w . SetHeaderAuthorization ( params . WebhookForm . AuthorizationHeader )
if err != nil {
ctx . ServerError ( "SetHeaderAuthorization" , err )
return
}
2022-08-23 09:52:35 +03:00
if err := w . UpdateEvent ( ) ; err != nil {
ctx . ServerError ( "UpdateEvent" , err )
return
} else if err := webhook . UpdateWebhook ( w ) ; err != nil {
ctx . ServerError ( "UpdateWebhook" , err )
return
}
ctx . Flash . Success ( ctx . Tr ( "repo.settings.update_hook_success" ) )
ctx . Redirect ( fmt . Sprintf ( "%s/%d" , orCtx . Link , w . ID ) )
}
2022-08-11 18:48:23 +03:00
// GiteaHooksNewPost response for creating Gitea webhook
func GiteaHooksNewPost ( ctx * context . Context ) {
2022-08-23 09:52:35 +03:00
createWebhook ( ctx , giteaHookParams ( ctx ) )
}
// GiteaHooksEditPost response for editing Gitea webhook
func GiteaHooksEditPost ( ctx * context . Context ) {
editWebhook ( ctx , giteaHookParams ( ctx ) )
}
func giteaHookParams ( ctx * context . Context ) webhookParams {
2022-08-11 18:48:23 +03:00
form := web . GetForm ( ctx ) . ( * forms . NewWebhookForm )
2015-12-05 21:24:13 +03:00
2022-08-11 18:48:23 +03:00
contentType := webhook . ContentTypeJSON
if webhook . HookContentType ( form . ContentType ) == webhook . ContentTypeForm {
contentType = webhook . ContentTypeForm
2015-12-05 21:24:13 +03:00
}
2022-08-23 09:52:35 +03:00
return webhookParams {
2023-01-01 18:23:15 +03:00
Type : webhook_module . GITEA ,
2022-08-11 18:48:23 +03:00
URL : form . PayloadURL ,
ContentType : contentType ,
Secret : form . Secret ,
HTTPMethod : form . HTTPMethod ,
WebhookForm : form . WebhookForm ,
2022-08-23 09:52:35 +03:00
}
2022-08-11 18:48:23 +03:00
}
2022-08-23 09:52:35 +03:00
// GogsHooksNewPost response for creating Gogs webhook
2022-08-11 18:48:23 +03:00
func GogsHooksNewPost ( ctx * context . Context ) {
2022-08-23 09:52:35 +03:00
createWebhook ( ctx , gogsHookParams ( ctx ) )
}
// GogsHooksEditPost response for editing Gogs webhook
func GogsHooksEditPost ( ctx * context . Context ) {
editWebhook ( ctx , gogsHookParams ( ctx ) )
}
func gogsHookParams ( ctx * context . Context ) webhookParams {
2022-08-11 18:48:23 +03:00
form := web . GetForm ( ctx ) . ( * forms . NewGogshookForm )
2015-12-05 21:24:13 +03:00
2021-11-10 08:13:16 +03:00
contentType := webhook . ContentTypeJSON
if webhook . HookContentType ( form . ContentType ) == webhook . ContentTypeForm {
contentType = webhook . ContentTypeForm
2015-12-05 21:24:13 +03:00
}
2022-08-23 09:52:35 +03:00
return webhookParams {
2023-01-01 18:23:15 +03:00
Type : webhook_module . GOGS ,
2022-08-11 18:48:23 +03:00
URL : form . PayloadURL ,
ContentType : contentType ,
Secret : form . Secret ,
WebhookForm : form . WebhookForm ,
2022-08-23 09:52:35 +03:00
}
2015-12-05 21:24:13 +03:00
}
2022-08-23 09:52:35 +03:00
// DiscordHooksNewPost response for creating Discord webhook
2021-01-26 18:36:53 +03:00
func DiscordHooksNewPost ( ctx * context . Context ) {
2022-08-23 09:52:35 +03:00
createWebhook ( ctx , discordHookParams ( ctx ) )
}
// DiscordHooksEditPost response for editing Discord webhook
func DiscordHooksEditPost ( ctx * context . Context ) {
editWebhook ( ctx , discordHookParams ( ctx ) )
}
func discordHookParams ( ctx * context . Context ) webhookParams {
2021-04-06 22:44:05 +03:00
form := web . GetForm ( ctx ) . ( * forms . NewDiscordHookForm )
2017-08-28 08:06:45 +03:00
2022-08-23 09:52:35 +03:00
return webhookParams {
2023-01-01 18:23:15 +03:00
Type : webhook_module . DISCORD ,
2022-08-11 18:48:23 +03:00
URL : form . PayloadURL ,
ContentType : webhook . ContentTypeJSON ,
WebhookForm : form . WebhookForm ,
Meta : & webhook_service . DiscordMeta {
Username : form . Username ,
IconURL : form . IconURL ,
} ,
2022-08-23 09:52:35 +03:00
}
2017-08-28 08:06:45 +03:00
}
2022-08-23 09:52:35 +03:00
// DingtalkHooksNewPost response for creating Dingtalk webhook
2021-01-26 18:36:53 +03:00
func DingtalkHooksNewPost ( ctx * context . Context ) {
2022-08-23 09:52:35 +03:00
createWebhook ( ctx , dingtalkHookParams ( ctx ) )
}
// DingtalkHooksEditPost response for editing Dingtalk webhook
func DingtalkHooksEditPost ( ctx * context . Context ) {
editWebhook ( ctx , dingtalkHookParams ( ctx ) )
}
func dingtalkHookParams ( ctx * context . Context ) webhookParams {
2021-04-06 22:44:05 +03:00
form := web . GetForm ( ctx ) . ( * forms . NewDingtalkHookForm )
2017-11-21 07:26:43 +03:00
2022-08-23 09:52:35 +03:00
return webhookParams {
2023-01-01 18:23:15 +03:00
Type : webhook_module . DINGTALK ,
2022-08-11 18:48:23 +03:00
URL : form . PayloadURL ,
ContentType : webhook . ContentTypeJSON ,
WebhookForm : form . WebhookForm ,
2022-08-23 09:52:35 +03:00
}
2017-11-21 07:26:43 +03:00
}
2022-08-23 09:52:35 +03:00
// TelegramHooksNewPost response for creating Telegram webhook
2021-01-26 18:36:53 +03:00
func TelegramHooksNewPost ( ctx * context . Context ) {
2022-08-23 09:52:35 +03:00
createWebhook ( ctx , telegramHookParams ( ctx ) )
}
// TelegramHooksEditPost response for editing Telegram webhook
func TelegramHooksEditPost ( ctx * context . Context ) {
editWebhook ( ctx , telegramHookParams ( ctx ) )
}
func telegramHookParams ( ctx * context . Context ) webhookParams {
2021-04-06 22:44:05 +03:00
form := web . GetForm ( ctx ) . ( * forms . NewTelegramHookForm )
2019-04-19 05:45:02 +03:00
2022-08-23 09:52:35 +03:00
return webhookParams {
2023-01-01 18:23:15 +03:00
Type : webhook_module . TELEGRAM ,
2022-08-11 18:48:23 +03:00
URL : fmt . Sprintf ( "https://api.telegram.org/bot%s/sendMessage?chat_id=%s" , url . PathEscape ( form . BotToken ) , url . QueryEscape ( form . ChatID ) ) ,
ContentType : webhook . ContentTypeJSON ,
WebhookForm : form . WebhookForm ,
Meta : & webhook_service . TelegramMeta {
BotToken : form . BotToken ,
ChatID : form . ChatID ,
} ,
2022-08-23 09:52:35 +03:00
}
2019-04-19 05:45:02 +03:00
}
2022-08-23 09:52:35 +03:00
// MatrixHooksNewPost response for creating Matrix webhook
2021-01-26 18:36:53 +03:00
func MatrixHooksNewPost ( ctx * context . Context ) {
2022-08-23 09:52:35 +03:00
createWebhook ( ctx , matrixHookParams ( ctx ) )
}
// MatrixHooksEditPost response for editing Matrix webhook
func MatrixHooksEditPost ( ctx * context . Context ) {
editWebhook ( ctx , matrixHookParams ( ctx ) )
}
func matrixHookParams ( ctx * context . Context ) webhookParams {
2021-04-06 22:44:05 +03:00
form := web . GetForm ( ctx ) . ( * forms . NewMatrixHookForm )
2020-03-28 16:09:55 +03:00
2022-08-23 09:52:35 +03:00
return webhookParams {
2023-01-01 18:23:15 +03:00
Type : webhook_module . MATRIX ,
2022-08-11 18:48:23 +03:00
URL : fmt . Sprintf ( "%s/_matrix/client/r0/rooms/%s/send/m.room.message" , form . HomeserverURL , url . PathEscape ( form . RoomID ) ) ,
ContentType : webhook . ContentTypeJSON ,
HTTPMethod : http . MethodPut ,
WebhookForm : form . WebhookForm ,
Meta : & webhook_service . MatrixMeta {
HomeserverURL : form . HomeserverURL ,
Room : form . RoomID ,
MessageType : form . MessageType ,
} ,
2022-08-23 09:52:35 +03:00
}
2020-03-28 16:09:55 +03:00
}
2022-08-23 09:52:35 +03:00
// MSTeamsHooksNewPost response for creating MSTeams webhook
2021-01-26 18:36:53 +03:00
func MSTeamsHooksNewPost ( ctx * context . Context ) {
2022-08-23 09:52:35 +03:00
createWebhook ( ctx , mSTeamsHookParams ( ctx ) )
}
// MSTeamsHooksEditPost response for editing MSTeams webhook
func MSTeamsHooksEditPost ( ctx * context . Context ) {
editWebhook ( ctx , mSTeamsHookParams ( ctx ) )
}
func mSTeamsHookParams ( ctx * context . Context ) webhookParams {
2021-04-06 22:44:05 +03:00
form := web . GetForm ( ctx ) . ( * forms . NewMSTeamsHookForm )
2019-04-19 17:18:06 +03:00
2022-08-23 09:52:35 +03:00
return webhookParams {
2023-01-01 18:23:15 +03:00
Type : webhook_module . MSTEAMS ,
2022-08-11 18:48:23 +03:00
URL : form . PayloadURL ,
ContentType : webhook . ContentTypeJSON ,
WebhookForm : form . WebhookForm ,
2022-08-23 09:52:35 +03:00
}
2019-04-19 17:18:06 +03:00
}
2022-08-23 09:52:35 +03:00
// SlackHooksNewPost response for creating Slack webhook
2021-01-26 18:36:53 +03:00
func SlackHooksNewPost ( ctx * context . Context ) {
2022-08-23 09:52:35 +03:00
createWebhook ( ctx , slackHookParams ( ctx ) )
}
// SlackHooksEditPost response for editing Slack webhook
func SlackHooksEditPost ( ctx * context . Context ) {
editWebhook ( ctx , slackHookParams ( ctx ) )
}
func slackHookParams ( ctx * context . Context ) webhookParams {
2021-04-06 22:44:05 +03:00
form := web . GetForm ( ctx ) . ( * forms . NewSlackHookForm )
2015-12-05 21:24:13 +03:00
2022-08-23 09:52:35 +03:00
return webhookParams {
2023-01-01 18:23:15 +03:00
Type : webhook_module . SLACK ,
2022-08-11 18:48:23 +03:00
URL : form . PayloadURL ,
ContentType : webhook . ContentTypeJSON ,
WebhookForm : form . WebhookForm ,
Meta : & webhook_service . SlackMeta {
Channel : strings . TrimSpace ( form . Channel ) ,
Username : form . Username ,
IconURL : form . IconURL ,
Color : form . Color ,
} ,
2022-08-23 09:52:35 +03:00
}
2015-12-05 21:24:13 +03:00
}
2022-08-23 09:52:35 +03:00
// FeishuHooksNewPost response for creating Feishu webhook
2021-01-26 18:36:53 +03:00
func FeishuHooksNewPost ( ctx * context . Context ) {
2022-08-23 09:52:35 +03:00
createWebhook ( ctx , feishuHookParams ( ctx ) )
}
// FeishuHooksEditPost response for editing Feishu webhook
func FeishuHooksEditPost ( ctx * context . Context ) {
editWebhook ( ctx , feishuHookParams ( ctx ) )
}
func feishuHookParams ( ctx * context . Context ) webhookParams {
2021-04-06 22:44:05 +03:00
form := web . GetForm ( ctx ) . ( * forms . NewFeishuHookForm )
2020-02-12 11:48:28 +03:00
2022-08-23 09:52:35 +03:00
return webhookParams {
2023-01-01 18:23:15 +03:00
Type : webhook_module . FEISHU ,
2022-08-11 18:48:23 +03:00
URL : form . PayloadURL ,
ContentType : webhook . ContentTypeJSON ,
WebhookForm : form . WebhookForm ,
2022-08-23 09:52:35 +03:00
}
2020-02-12 11:48:28 +03:00
}
2022-08-23 09:52:35 +03:00
// WechatworkHooksNewPost response for creating Wechatwork webhook
2021-07-23 07:41:27 +03:00
func WechatworkHooksNewPost ( ctx * context . Context ) {
2022-08-23 09:52:35 +03:00
createWebhook ( ctx , wechatworkHookParams ( ctx ) )
}
// WechatworkHooksEditPost response for editing Wechatwork webhook
func WechatworkHooksEditPost ( ctx * context . Context ) {
editWebhook ( ctx , wechatworkHookParams ( ctx ) )
}
func wechatworkHookParams ( ctx * context . Context ) webhookParams {
2021-07-23 07:41:27 +03:00
form := web . GetForm ( ctx ) . ( * forms . NewWechatWorkHookForm )
2022-08-23 09:52:35 +03:00
return webhookParams {
2023-01-01 18:23:15 +03:00
Type : webhook_module . WECHATWORK ,
2022-08-11 18:48:23 +03:00
URL : form . PayloadURL ,
ContentType : webhook . ContentTypeJSON ,
WebhookForm : form . WebhookForm ,
2022-08-23 09:52:35 +03:00
}
2021-07-23 07:41:27 +03:00
}
2022-08-23 09:52:35 +03:00
// PackagistHooksNewPost response for creating Packagist webhook
2022-01-23 16:46:30 +03:00
func PackagistHooksNewPost ( ctx * context . Context ) {
2022-08-23 09:52:35 +03:00
createWebhook ( ctx , packagistHookParams ( ctx ) )
}
// PackagistHooksEditPost response for editing Packagist webhook
func PackagistHooksEditPost ( ctx * context . Context ) {
editWebhook ( ctx , packagistHookParams ( ctx ) )
}
func packagistHookParams ( ctx * context . Context ) webhookParams {
2022-01-23 16:46:30 +03:00
form := web . GetForm ( ctx ) . ( * forms . NewPackagistHookForm )
2022-08-23 09:52:35 +03:00
return webhookParams {
2023-01-01 18:23:15 +03:00
Type : webhook_module . PACKAGIST ,
2022-08-11 18:48:23 +03:00
URL : fmt . Sprintf ( "https://packagist.org/api/update-package?username=%s&apiToken=%s" , url . QueryEscape ( form . Username ) , url . QueryEscape ( form . APIToken ) ) ,
ContentType : webhook . ContentTypeJSON ,
WebhookForm : form . WebhookForm ,
Meta : & webhook_service . PackagistMeta {
Username : form . Username ,
APIToken : form . APIToken ,
PackageURL : form . PackageURL ,
} ,
2022-08-23 09:52:35 +03:00
}
2022-01-23 16:46:30 +03:00
}
2021-11-10 08:13:16 +03:00
func checkWebhook ( ctx * context . Context ) ( * orgRepoCtx , * webhook . Webhook ) {
2015-12-05 21:24:13 +03:00
orCtx , err := getOrgRepoCtx ( ctx )
if err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "getOrgRepoCtx" , err )
2015-12-05 21:24:13 +03:00
return nil , nil
}
ctx . Data [ "BaseLink" ] = orCtx . Link
2021-11-10 08:13:16 +03:00
var w * webhook . Webhook
2016-07-15 20:02:55 +03:00
if orCtx . RepoID > 0 {
2021-11-10 08:13:16 +03:00
w , err = webhook . GetWebhookByRepoID ( ctx . Repo . Repository . ID , ctx . ParamsInt64 ( ":id" ) )
2019-03-19 05:33:20 +03:00
} else if orCtx . OrgID > 0 {
2021-11-10 08:13:16 +03:00
w , err = webhook . GetWebhookByOrgID ( ctx . Org . Organization . ID , ctx . ParamsInt64 ( ":id" ) )
2021-01-15 02:24:03 +03:00
} else if orCtx . IsAdmin {
2021-11-10 08:13:16 +03:00
w , err = webhook . GetSystemOrDefaultWebhook ( ctx . ParamsInt64 ( ":id" ) )
2016-07-15 20:02:55 +03:00
}
2021-01-15 02:24:03 +03:00
if err != nil || w == nil {
2021-11-10 08:13:16 +03:00
if webhook . IsErrWebhookNotExist ( err ) {
2018-01-11 00:34:17 +03:00
ctx . NotFound ( "GetWebhookByID" , nil )
2015-12-05 21:24:13 +03:00
} else {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "GetWebhookByID" , err )
2015-12-05 21:24:13 +03:00
}
return nil , nil
}
2020-12-09 20:20:13 +03:00
ctx . Data [ "HookType" ] = w . Type
switch w . Type {
2023-01-01 18:23:15 +03:00
case webhook_module . SLACK :
2021-11-10 08:13:16 +03:00
ctx . Data [ "SlackHook" ] = webhook_service . GetSlackHook ( w )
2023-01-01 18:23:15 +03:00
case webhook_module . DISCORD :
2021-11-10 08:13:16 +03:00
ctx . Data [ "DiscordHook" ] = webhook_service . GetDiscordHook ( w )
2023-01-01 18:23:15 +03:00
case webhook_module . TELEGRAM :
2021-11-10 08:13:16 +03:00
ctx . Data [ "TelegramHook" ] = webhook_service . GetTelegramHook ( w )
2023-01-01 18:23:15 +03:00
case webhook_module . MATRIX :
2021-11-10 08:13:16 +03:00
ctx . Data [ "MatrixHook" ] = webhook_service . GetMatrixHook ( w )
2023-01-01 18:23:15 +03:00
case webhook_module . PACKAGIST :
2022-01-23 16:46:30 +03:00
ctx . Data [ "PackagistHook" ] = webhook_service . GetPackagistHook ( w )
2015-12-05 21:24:13 +03:00
}
ctx . Data [ "History" ] , err = w . History ( 1 )
if err != nil {
2018-01-11 00:34:17 +03:00
ctx . ServerError ( "History" , err )
2015-12-05 21:24:13 +03:00
}
return orCtx , w
}
2016-11-24 10:04:31 +03:00
// WebHooksEdit render editing web hook page
2016-03-11 19:56:52 +03:00
func WebHooksEdit ( ctx * context . Context ) {
2015-12-05 21:24:13 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.settings.update_webhook" )
ctx . Data [ "PageIsSettingsHooks" ] = true
ctx . Data [ "PageIsSettingsHooksEdit" ] = true
orCtx , w := checkWebhook ( ctx )
if ctx . Written ( ) {
return
}
ctx . Data [ "Webhook" ] = w
2021-04-05 18:30:52 +03:00
ctx . HTML ( http . StatusOK , orCtx . NewTemplate )
2015-12-05 21:24:13 +03:00
}
2016-11-24 10:04:31 +03:00
// TestWebhook test if web hook is work fine
2016-03-11 19:56:52 +03:00
func TestWebhook ( ctx * context . Context ) {
2017-08-29 17:55:24 +03:00
hookID := ctx . ParamsInt64 ( ":id" )
2021-11-10 08:13:16 +03:00
w , err := webhook . GetWebhookByRepoID ( ctx . Repo . Repository . ID , hookID )
2017-08-29 17:55:24 +03:00
if err != nil {
2022-10-21 19:21:56 +03:00
ctx . Flash . Error ( "GetWebhookByRepoID: " + err . Error ( ) )
2022-03-23 07:54:07 +03:00
ctx . Status ( http . StatusInternalServerError )
2017-08-29 17:55:24 +03:00
return
}
2016-08-15 15:53:47 +03:00
// Grab latest commit or fake one if it's empty repository.
commit := ctx . Repo . Commit
if commit == nil {
2021-11-24 12:49:20 +03:00
ghost := user_model . NewGhostUser ( )
2016-08-15 15:53:47 +03:00
commit = & git . Commit {
2016-12-22 12:30:52 +03:00
ID : git . MustIDFromString ( git . EmptySHA ) ,
2016-08-15 15:53:47 +03:00
Author : ghost . NewGitSig ( ) ,
Committer : ghost . NewGitSig ( ) ,
CommitMessage : "This is a fake commit" ,
}
}
2022-03-22 10:03:22 +03:00
apiUser := convert . ToUserWithAccessMode ( ctx . Doer , perm . AccessModeNone )
2021-06-29 16:34:03 +03:00
apiCommit := & api . PayloadCommit {
ID : commit . ID . String ( ) ,
Message : commit . Message ( ) ,
2021-11-16 21:18:25 +03:00
URL : ctx . Repo . Repository . HTMLURL ( ) + "/commit/" + url . PathEscape ( commit . ID . String ( ) ) ,
2021-06-29 16:34:03 +03:00
Author : & api . PayloadUser {
Name : commit . Author . Name ,
Email : commit . Author . Email ,
} ,
Committer : & api . PayloadUser {
Name : commit . Committer . Name ,
Email : commit . Committer . Email ,
2015-12-05 21:24:13 +03:00
} ,
2021-06-29 16:34:03 +03:00
}
2022-09-04 12:18:07 +03:00
commitID := commit . ID . String ( )
2021-06-29 16:34:03 +03:00
p := & api . PushPayload {
2022-10-16 19:22:34 +03:00
Ref : git . BranchPrefix + ctx . Repo . Repository . DefaultBranch ,
Before : commitID ,
After : commitID ,
CompareURL : setting . AppURL + ctx . Repo . Repository . ComposeCompareURL ( commitID , commitID ) ,
Commits : [ ] * api . PayloadCommit { apiCommit } ,
TotalCommits : 1 ,
HeadCommit : apiCommit ,
2022-12-03 05:48:26 +03:00
Repo : convert . ToRepo ( ctx , ctx . Repo . Repository , perm . AccessModeNone ) ,
2022-10-16 19:22:34 +03:00
Pusher : apiUser ,
Sender : apiUser ,
2015-12-05 21:24:13 +03:00
}
2023-01-01 18:23:15 +03:00
if err := webhook_service . PrepareWebhook ( ctx , w , webhook_module . HookEventPush , p ) ; err != nil {
2017-08-29 17:55:24 +03:00
ctx . Flash . Error ( "PrepareWebhook: " + err . Error ( ) )
2022-03-23 07:54:07 +03:00
ctx . Status ( http . StatusInternalServerError )
2015-12-05 21:24:13 +03:00
} else {
2022-01-06 00:00:20 +03:00
ctx . Flash . Info ( ctx . Tr ( "repo.settings.webhook.delivery.success" ) )
2022-03-23 07:54:07 +03:00
ctx . Status ( http . StatusOK )
2015-12-05 21:24:13 +03:00
}
}
2022-01-06 00:00:20 +03:00
// ReplayWebhook replays a webhook
func ReplayWebhook ( ctx * context . Context ) {
hookTaskUUID := ctx . Params ( ":uuid" )
orCtx , w := checkWebhook ( ctx )
if ctx . Written ( ) {
return
}
2022-10-21 19:21:56 +03:00
if err := webhook_service . ReplayHookTask ( ctx , w , hookTaskUUID ) ; err != nil {
2022-01-06 00:00:20 +03:00
if webhook . IsErrHookTaskNotExist ( err ) {
ctx . NotFound ( "ReplayHookTask" , nil )
} else {
ctx . ServerError ( "ReplayHookTask" , err )
}
return
}
ctx . Flash . Success ( ctx . Tr ( "repo.settings.webhook.delivery.success" ) )
ctx . Redirect ( fmt . Sprintf ( "%s/%d" , orCtx . Link , w . ID ) )
}
2016-11-24 10:04:31 +03:00
// DeleteWebhook delete a webhook
2016-03-11 19:56:52 +03:00
func DeleteWebhook ( ctx * context . Context ) {
2021-11-10 08:13:16 +03:00
if err := webhook . DeleteWebhookByRepoID ( ctx . Repo . Repository . ID , ctx . FormInt64 ( "id" ) ) ; err != nil {
2016-07-17 03:33:59 +03:00
ctx . Flash . Error ( "DeleteWebhookByRepoID: " + err . Error ( ) )
2015-12-05 21:24:13 +03:00
} else {
ctx . Flash . Success ( ctx . Tr ( "repo.settings.webhook_deletion_success" ) )
}
2021-04-05 18:30:52 +03:00
ctx . JSON ( http . StatusOK , map [ string ] interface { } {
2015-12-05 21:24:13 +03:00
"redirect" : ctx . Repo . RepoLink + "/settings/hooks" ,
} )
}