Earl Warren
41871ba3af
do not reuse the payload of the event that triggered the creation of the scheduled event. Create a new one instead that contains no other information than the event name in the action field ("schedule"). (cherry picked from commit 0b40ca1ea5e6b704bcb6c0d370a21f633facc7d6) (cherry picked from commit f86487432b3b5f2fd4e2bb0a2d737674d9a105a6) (cherry picked from commit 4bd5d2e9d0c7987a9d7cce495509c8790dcdcd3a) (cherry picked from commit d10830e238f35bcd0100a4de68d68b15402ec05a) (cherry picked from commit 53f5a3aa911fb63689ef018fe583eeb03f248517) (cherry picked from commit 9ed1487b73babe44d0b2855cc708184c55671ab0) (cherry picked from commit 6a399788516523bc52778f9d9df7f283d5b2c6d6)
507 lines
16 KiB
Go
507 lines
16 KiB
Go
// Copyright 2014 The Gogs Authors. All rights reserved.
|
|
// Copyright 2017 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package structs
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"time"
|
|
|
|
"code.gitea.io/gitea/modules/json"
|
|
)
|
|
|
|
// ErrInvalidReceiveHook FIXME
|
|
var ErrInvalidReceiveHook = errors.New("Invalid JSON payload received over webhook")
|
|
|
|
// Hook a hook is a web hook when one repository changed
|
|
type Hook struct {
|
|
ID int64 `json:"id"`
|
|
Type string `json:"type"`
|
|
BranchFilter string `json:"branch_filter"`
|
|
URL string `json:"-"`
|
|
Config map[string]string `json:"config"`
|
|
Events []string `json:"events"`
|
|
AuthorizationHeader string `json:"authorization_header"`
|
|
Active bool `json:"active"`
|
|
// swagger:strfmt date-time
|
|
Updated time.Time `json:"updated_at"`
|
|
// swagger:strfmt date-time
|
|
Created time.Time `json:"created_at"`
|
|
}
|
|
|
|
// HookList represents a list of API hook.
|
|
type HookList []*Hook
|
|
|
|
// CreateHookOptionConfig has all config options in it
|
|
// required are "content_type" and "url" Required
|
|
type CreateHookOptionConfig map[string]string
|
|
|
|
// CreateHookOption options when create a hook
|
|
type CreateHookOption struct {
|
|
// required: true
|
|
// enum: dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu,wechatwork,packagist
|
|
Type string `json:"type" binding:"Required"`
|
|
// required: true
|
|
Config CreateHookOptionConfig `json:"config" binding:"Required"`
|
|
Events []string `json:"events"`
|
|
BranchFilter string `json:"branch_filter" binding:"GlobPattern"`
|
|
AuthorizationHeader string `json:"authorization_header"`
|
|
// default: false
|
|
Active bool `json:"active"`
|
|
}
|
|
|
|
// EditHookOption options when modify one hook
|
|
type EditHookOption struct {
|
|
Config map[string]string `json:"config"`
|
|
Events []string `json:"events"`
|
|
BranchFilter string `json:"branch_filter" binding:"GlobPattern"`
|
|
AuthorizationHeader string `json:"authorization_header"`
|
|
Active *bool `json:"active"`
|
|
}
|
|
|
|
// Payloader payload is some part of one hook
|
|
type Payloader interface {
|
|
JSONPayload() ([]byte, error)
|
|
}
|
|
|
|
// PayloadUser represents the author or committer of a commit
|
|
type PayloadUser struct {
|
|
// Full name of the commit author
|
|
Name string `json:"name"`
|
|
// swagger:strfmt email
|
|
Email string `json:"email"`
|
|
UserName string `json:"username"`
|
|
}
|
|
|
|
// FIXME: consider using same format as API when commits API are added.
|
|
// applies to PayloadCommit and PayloadCommitVerification
|
|
|
|
// PayloadCommit represents a commit
|
|
type PayloadCommit struct {
|
|
// sha1 hash of the commit
|
|
ID string `json:"id"`
|
|
Message string `json:"message"`
|
|
URL string `json:"url"`
|
|
Author *PayloadUser `json:"author"`
|
|
Committer *PayloadUser `json:"committer"`
|
|
Verification *PayloadCommitVerification `json:"verification"`
|
|
// swagger:strfmt date-time
|
|
Timestamp time.Time `json:"timestamp"`
|
|
Added []string `json:"added"`
|
|
Removed []string `json:"removed"`
|
|
Modified []string `json:"modified"`
|
|
}
|
|
|
|
// PayloadCommitVerification represents the GPG verification of a commit
|
|
type PayloadCommitVerification struct {
|
|
Verified bool `json:"verified"`
|
|
Reason string `json:"reason"`
|
|
Signature string `json:"signature"`
|
|
Signer *PayloadUser `json:"signer"`
|
|
Payload string `json:"payload"`
|
|
}
|
|
|
|
var (
|
|
_ Payloader = &CreatePayload{}
|
|
_ Payloader = &DeletePayload{}
|
|
_ Payloader = &ForkPayload{}
|
|
_ Payloader = &PushPayload{}
|
|
_ Payloader = &IssuePayload{}
|
|
_ Payloader = &IssueCommentPayload{}
|
|
_ Payloader = &PullRequestPayload{}
|
|
_ Payloader = &RepositoryPayload{}
|
|
_ Payloader = &ReleasePayload{}
|
|
_ Payloader = &PackagePayload{}
|
|
)
|
|
|
|
// _________ __
|
|
// \_ ___ \_______ ____ _____ _/ |_ ____
|
|
// / \ \/\_ __ \_/ __ \\__ \\ __\/ __ \
|
|
// \ \____| | \/\ ___/ / __ \| | \ ___/
|
|
// \______ /|__| \___ >____ /__| \___ >
|
|
// \/ \/ \/ \/
|
|
|
|
// CreatePayload FIXME
|
|
type CreatePayload struct {
|
|
Sha string `json:"sha"`
|
|
Ref string `json:"ref"`
|
|
RefType string `json:"ref_type"`
|
|
Repo *Repository `json:"repository"`
|
|
Sender *User `json:"sender"`
|
|
}
|
|
|
|
// JSONPayload return payload information
|
|
func (p *CreatePayload) JSONPayload() ([]byte, error) {
|
|
return json.MarshalIndent(p, "", " ")
|
|
}
|
|
|
|
// ParseCreateHook parses create event hook content.
|
|
func ParseCreateHook(raw []byte) (*CreatePayload, error) {
|
|
hook := new(CreatePayload)
|
|
if err := json.Unmarshal(raw, hook); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// it is possible the JSON was parsed, however,
|
|
// was not from Gogs (maybe was from Bitbucket)
|
|
// So we'll check to be sure certain key fields
|
|
// were populated
|
|
switch {
|
|
case hook.Repo == nil:
|
|
return nil, ErrInvalidReceiveHook
|
|
case len(hook.Ref) == 0:
|
|
return nil, ErrInvalidReceiveHook
|
|
}
|
|
return hook, nil
|
|
}
|
|
|
|
// ________ .__ __
|
|
// \______ \ ____ | | _____/ |_ ____
|
|
// | | \_/ __ \| | _/ __ \ __\/ __ \
|
|
// | ` \ ___/| |_\ ___/| | \ ___/
|
|
// /_______ /\___ >____/\___ >__| \___ >
|
|
// \/ \/ \/ \/
|
|
|
|
// PusherType define the type to push
|
|
type PusherType string
|
|
|
|
// describe all the PusherTypes
|
|
const (
|
|
PusherTypeUser PusherType = "user"
|
|
)
|
|
|
|
// DeletePayload represents delete payload
|
|
type DeletePayload struct {
|
|
Ref string `json:"ref"`
|
|
RefType string `json:"ref_type"`
|
|
PusherType PusherType `json:"pusher_type"`
|
|
Repo *Repository `json:"repository"`
|
|
Sender *User `json:"sender"`
|
|
}
|
|
|
|
// JSONPayload implements Payload
|
|
func (p *DeletePayload) JSONPayload() ([]byte, error) {
|
|
return json.MarshalIndent(p, "", " ")
|
|
}
|
|
|
|
// ___________ __
|
|
// \_ _____/__________| | __
|
|
// | __)/ _ \_ __ \ |/ /
|
|
// | \( <_> ) | \/ <
|
|
// \___ / \____/|__| |__|_ \
|
|
// \/ \/
|
|
|
|
// ForkPayload represents fork payload
|
|
type ForkPayload struct {
|
|
Forkee *Repository `json:"forkee"`
|
|
Repo *Repository `json:"repository"`
|
|
Sender *User `json:"sender"`
|
|
}
|
|
|
|
// JSONPayload implements Payload
|
|
func (p *ForkPayload) JSONPayload() ([]byte, error) {
|
|
return json.MarshalIndent(p, "", " ")
|
|
}
|
|
|
|
// HookIssueCommentAction defines hook issue comment action
|
|
type HookIssueCommentAction string
|
|
|
|
// all issue comment actions
|
|
const (
|
|
HookIssueCommentCreated HookIssueCommentAction = "created"
|
|
HookIssueCommentEdited HookIssueCommentAction = "edited"
|
|
HookIssueCommentDeleted HookIssueCommentAction = "deleted"
|
|
)
|
|
|
|
// IssueCommentPayload represents a payload information of issue comment event.
|
|
type IssueCommentPayload struct {
|
|
Action HookIssueCommentAction `json:"action"`
|
|
Issue *Issue `json:"issue"`
|
|
Comment *Comment `json:"comment"`
|
|
Changes *ChangesPayload `json:"changes,omitempty"`
|
|
Repository *Repository `json:"repository"`
|
|
Sender *User `json:"sender"`
|
|
IsPull bool `json:"is_pull"`
|
|
}
|
|
|
|
// JSONPayload implements Payload
|
|
func (p *IssueCommentPayload) JSONPayload() ([]byte, error) {
|
|
return json.MarshalIndent(p, "", " ")
|
|
}
|
|
|
|
// __________ .__
|
|
// \______ \ ____ | | ____ _____ ______ ____
|
|
// | _// __ \| | _/ __ \\__ \ / ___// __ \
|
|
// | | \ ___/| |_\ ___/ / __ \_\___ \\ ___/
|
|
// |____|_ /\___ >____/\___ >____ /____ >\___ >
|
|
// \/ \/ \/ \/ \/ \/
|
|
|
|
// HookReleaseAction defines hook release action type
|
|
type HookReleaseAction string
|
|
|
|
// all release actions
|
|
const (
|
|
HookReleasePublished HookReleaseAction = "published"
|
|
HookReleaseUpdated HookReleaseAction = "updated"
|
|
HookReleaseDeleted HookReleaseAction = "deleted"
|
|
)
|
|
|
|
// ReleasePayload represents a payload information of release event.
|
|
type ReleasePayload struct {
|
|
Action HookReleaseAction `json:"action"`
|
|
Release *Release `json:"release"`
|
|
Repository *Repository `json:"repository"`
|
|
Sender *User `json:"sender"`
|
|
}
|
|
|
|
// JSONPayload implements Payload
|
|
func (p *ReleasePayload) JSONPayload() ([]byte, error) {
|
|
return json.MarshalIndent(p, "", " ")
|
|
}
|
|
|
|
// __________ .__
|
|
// \______ \__ __ _____| |__
|
|
// | ___/ | \/ ___/ | \
|
|
// | | | | /\___ \| Y \
|
|
// |____| |____//____ >___| /
|
|
// \/ \/
|
|
|
|
// PushPayload represents a payload information of push event.
|
|
type PushPayload struct {
|
|
Ref string `json:"ref"`
|
|
Before string `json:"before"`
|
|
After string `json:"after"`
|
|
CompareURL string `json:"compare_url"`
|
|
Commits []*PayloadCommit `json:"commits"`
|
|
TotalCommits int `json:"total_commits"`
|
|
HeadCommit *PayloadCommit `json:"head_commit"`
|
|
Repo *Repository `json:"repository"`
|
|
Pusher *User `json:"pusher"`
|
|
Sender *User `json:"sender"`
|
|
}
|
|
|
|
// JSONPayload FIXME
|
|
func (p *PushPayload) JSONPayload() ([]byte, error) {
|
|
return json.MarshalIndent(p, "", " ")
|
|
}
|
|
|
|
// ParsePushHook parses push event hook content.
|
|
func ParsePushHook(raw []byte) (*PushPayload, error) {
|
|
hook := new(PushPayload)
|
|
if err := json.Unmarshal(raw, hook); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
switch {
|
|
case hook.Repo == nil:
|
|
return nil, ErrInvalidReceiveHook
|
|
case len(hook.Ref) == 0:
|
|
return nil, ErrInvalidReceiveHook
|
|
}
|
|
return hook, nil
|
|
}
|
|
|
|
// Branch returns branch name from a payload
|
|
func (p *PushPayload) Branch() string {
|
|
return strings.ReplaceAll(p.Ref, "refs/heads/", "")
|
|
}
|
|
|
|
// .___
|
|
// | | ______ ________ __ ____
|
|
// | |/ ___// ___/ | \_/ __ \
|
|
// | |\___ \ \___ \| | /\ ___/
|
|
// |___/____ >____ >____/ \___ >
|
|
// \/ \/ \/
|
|
|
|
// HookIssueAction FIXME
|
|
type HookIssueAction string
|
|
|
|
const (
|
|
// HookIssueOpened opened
|
|
HookIssueOpened HookIssueAction = "opened"
|
|
// HookIssueClosed closed
|
|
HookIssueClosed HookIssueAction = "closed"
|
|
// HookIssueReOpened reopened
|
|
HookIssueReOpened HookIssueAction = "reopened"
|
|
// HookIssueEdited edited
|
|
HookIssueEdited HookIssueAction = "edited"
|
|
// HookIssueAssigned assigned
|
|
HookIssueAssigned HookIssueAction = "assigned"
|
|
// HookIssueUnassigned unassigned
|
|
HookIssueUnassigned HookIssueAction = "unassigned"
|
|
// HookIssueLabelUpdated label_updated
|
|
HookIssueLabelUpdated HookIssueAction = "label_updated"
|
|
// HookIssueLabelCleared label_cleared
|
|
HookIssueLabelCleared HookIssueAction = "label_cleared"
|
|
// HookIssueSynchronized synchronized
|
|
HookIssueSynchronized HookIssueAction = "synchronized"
|
|
// HookIssueMilestoned is an issue action for when a milestone is set on an issue.
|
|
HookIssueMilestoned HookIssueAction = "milestoned"
|
|
// HookIssueDemilestoned is an issue action for when a milestone is cleared on an issue.
|
|
HookIssueDemilestoned HookIssueAction = "demilestoned"
|
|
// HookIssueReviewed is an issue action for when a pull request is reviewed
|
|
HookIssueReviewed HookIssueAction = "reviewed"
|
|
// HookIssueReviewRequested is an issue action for when a reviewer is requested for a pull request.
|
|
HookIssueReviewRequested HookIssueAction = "review_requested"
|
|
// HookIssueReviewRequestRemoved is an issue action for removing a review request to someone on a pull request.
|
|
HookIssueReviewRequestRemoved HookIssueAction = "review_request_removed"
|
|
)
|
|
|
|
// IssuePayload represents the payload information that is sent along with an issue event.
|
|
type IssuePayload struct {
|
|
Action HookIssueAction `json:"action"`
|
|
Index int64 `json:"number"`
|
|
Changes *ChangesPayload `json:"changes,omitempty"`
|
|
Issue *Issue `json:"issue"`
|
|
Repository *Repository `json:"repository"`
|
|
Sender *User `json:"sender"`
|
|
CommitID string `json:"commit_id"`
|
|
}
|
|
|
|
// JSONPayload encodes the IssuePayload to JSON, with an indentation of two spaces.
|
|
func (p *IssuePayload) JSONPayload() ([]byte, error) {
|
|
return json.MarshalIndent(p, "", " ")
|
|
}
|
|
|
|
// ChangesFromPayload FIXME
|
|
type ChangesFromPayload struct {
|
|
From string `json:"from"`
|
|
}
|
|
|
|
// ChangesPayload represents the payload information of issue change
|
|
type ChangesPayload struct {
|
|
Title *ChangesFromPayload `json:"title,omitempty"`
|
|
Body *ChangesFromPayload `json:"body,omitempty"`
|
|
Ref *ChangesFromPayload `json:"ref,omitempty"`
|
|
}
|
|
|
|
// __________ .__ .__ __________ __
|
|
// \______ \__ __| | | | \______ \ ____ ________ __ ____ _______/ |_
|
|
// | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\
|
|
// | | | | / |_| |__ | | \ ___< <_| | | /\ ___/ \___ \ | |
|
|
// |____| |____/|____/____/ |____|_ /\___ >__ |____/ \___ >____ > |__|
|
|
// \/ \/ |__| \/ \/
|
|
|
|
// PullRequestPayload represents a payload information of pull request event.
|
|
type PullRequestPayload struct {
|
|
Action HookIssueAction `json:"action"`
|
|
Index int64 `json:"number"`
|
|
Changes *ChangesPayload `json:"changes,omitempty"`
|
|
PullRequest *PullRequest `json:"pull_request"`
|
|
RequestedReviewer *User `json:"requested_reviewer"`
|
|
Repository *Repository `json:"repository"`
|
|
Sender *User `json:"sender"`
|
|
CommitID string `json:"commit_id"`
|
|
Review *ReviewPayload `json:"review"`
|
|
}
|
|
|
|
// JSONPayload FIXME
|
|
func (p *PullRequestPayload) JSONPayload() ([]byte, error) {
|
|
return json.MarshalIndent(p, "", " ")
|
|
}
|
|
|
|
type HookScheduleAction string
|
|
|
|
const (
|
|
HookScheduleCreated HookScheduleAction = "schedule"
|
|
)
|
|
|
|
type SchedulePayload struct {
|
|
Action HookScheduleAction `json:"action"`
|
|
}
|
|
|
|
// ReviewPayload FIXME
|
|
type ReviewPayload struct {
|
|
Type string `json:"type"`
|
|
Content string `json:"content"`
|
|
}
|
|
|
|
// __ __.__ __ .__
|
|
// / \ / \__| | _|__|
|
|
// \ \/\/ / | |/ / |
|
|
// \ /| | <| |
|
|
// \__/\ / |__|__|_ \__|
|
|
// \/ \/
|
|
|
|
// HookWikiAction an action that happens to a wiki page
|
|
type HookWikiAction string
|
|
|
|
const (
|
|
// HookWikiCreated created
|
|
HookWikiCreated HookWikiAction = "created"
|
|
// HookWikiEdited edited
|
|
HookWikiEdited HookWikiAction = "edited"
|
|
// HookWikiDeleted deleted
|
|
HookWikiDeleted HookWikiAction = "deleted"
|
|
)
|
|
|
|
// WikiPayload payload for repository webhooks
|
|
type WikiPayload struct {
|
|
Action HookWikiAction `json:"action"`
|
|
Repository *Repository `json:"repository"`
|
|
Sender *User `json:"sender"`
|
|
Page string `json:"page"`
|
|
Comment string `json:"comment"`
|
|
}
|
|
|
|
// JSONPayload JSON representation of the payload
|
|
func (p *WikiPayload) JSONPayload() ([]byte, error) {
|
|
return json.MarshalIndent(p, "", " ")
|
|
}
|
|
|
|
//__________ .__ __
|
|
//\______ \ ____ ______ ____ _____|__|/ |_ ___________ ___.__.
|
|
// | _// __ \\____ \ / _ \/ ___/ \ __\/ _ \_ __ < | |
|
|
// | | \ ___/| |_> > <_> )___ \| || | ( <_> ) | \/\___ |
|
|
// |____|_ /\___ > __/ \____/____ >__||__| \____/|__| / ____|
|
|
// \/ \/|__| \/ \/
|
|
|
|
// HookRepoAction an action that happens to a repo
|
|
type HookRepoAction string
|
|
|
|
const (
|
|
// HookRepoCreated created
|
|
HookRepoCreated HookRepoAction = "created"
|
|
// HookRepoDeleted deleted
|
|
HookRepoDeleted HookRepoAction = "deleted"
|
|
)
|
|
|
|
// RepositoryPayload payload for repository webhooks
|
|
type RepositoryPayload struct {
|
|
Action HookRepoAction `json:"action"`
|
|
Repository *Repository `json:"repository"`
|
|
Organization *User `json:"organization"`
|
|
Sender *User `json:"sender"`
|
|
}
|
|
|
|
// JSONPayload JSON representation of the payload
|
|
func (p *RepositoryPayload) JSONPayload() ([]byte, error) {
|
|
return json.MarshalIndent(p, "", " ")
|
|
}
|
|
|
|
// HookPackageAction an action that happens to a package
|
|
type HookPackageAction string
|
|
|
|
const (
|
|
// HookPackageCreated created
|
|
HookPackageCreated HookPackageAction = "created"
|
|
// HookPackageDeleted deleted
|
|
HookPackageDeleted HookPackageAction = "deleted"
|
|
)
|
|
|
|
// PackagePayload represents a package payload
|
|
type PackagePayload struct {
|
|
Action HookPackageAction `json:"action"`
|
|
Repository *Repository `json:"repository"`
|
|
Package *Package `json:"package"`
|
|
Organization *User `json:"organization"`
|
|
Sender *User `json:"sender"`
|
|
}
|
|
|
|
// JSONPayload implements Payload
|
|
func (p *PackagePayload) JSONPayload() ([]byte, error) {
|
|
return json.MarshalIndent(p, "", " ")
|
|
}
|