code.gitea.io/gitea@v1.22.3/modules/structs/hook.go (about)

     1  // Copyright 2014 The Gogs Authors. All rights reserved.
     2  // Copyright 2017 The Gitea Authors. All rights reserved.
     3  // SPDX-License-Identifier: MIT
     4  
     5  package structs
     6  
     7  import (
     8  	"errors"
     9  	"strings"
    10  	"time"
    11  
    12  	"code.gitea.io/gitea/modules/json"
    13  )
    14  
    15  // ErrInvalidReceiveHook FIXME
    16  var ErrInvalidReceiveHook = errors.New("Invalid JSON payload received over webhook")
    17  
    18  // Hook a hook is a web hook when one repository changed
    19  type Hook struct {
    20  	ID                  int64             `json:"id"`
    21  	Type                string            `json:"type"`
    22  	BranchFilter        string            `json:"branch_filter"`
    23  	URL                 string            `json:"-"`
    24  	Config              map[string]string `json:"config"`
    25  	Events              []string          `json:"events"`
    26  	AuthorizationHeader string            `json:"authorization_header"`
    27  	Active              bool              `json:"active"`
    28  	// swagger:strfmt date-time
    29  	Updated time.Time `json:"updated_at"`
    30  	// swagger:strfmt date-time
    31  	Created time.Time `json:"created_at"`
    32  }
    33  
    34  // HookList represents a list of API hook.
    35  type HookList []*Hook
    36  
    37  // CreateHookOptionConfig has all config options in it
    38  // required are "content_type" and "url" Required
    39  type CreateHookOptionConfig map[string]string
    40  
    41  // CreateHookOption options when create a hook
    42  type CreateHookOption struct {
    43  	// required: true
    44  	// enum: dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu,wechatwork,packagist
    45  	Type string `json:"type" binding:"Required"`
    46  	// required: true
    47  	Config              CreateHookOptionConfig `json:"config" binding:"Required"`
    48  	Events              []string               `json:"events"`
    49  	BranchFilter        string                 `json:"branch_filter" binding:"GlobPattern"`
    50  	AuthorizationHeader string                 `json:"authorization_header"`
    51  	// default: false
    52  	Active bool `json:"active"`
    53  }
    54  
    55  // EditHookOption options when modify one hook
    56  type EditHookOption struct {
    57  	Config              map[string]string `json:"config"`
    58  	Events              []string          `json:"events"`
    59  	BranchFilter        string            `json:"branch_filter" binding:"GlobPattern"`
    60  	AuthorizationHeader string            `json:"authorization_header"`
    61  	Active              *bool             `json:"active"`
    62  }
    63  
    64  // Payloader payload is some part of one hook
    65  type Payloader interface {
    66  	JSONPayload() ([]byte, error)
    67  }
    68  
    69  // PayloadUser represents the author or committer of a commit
    70  type PayloadUser struct {
    71  	// Full name of the commit author
    72  	Name string `json:"name"`
    73  	// swagger:strfmt email
    74  	Email    string `json:"email"`
    75  	UserName string `json:"username"`
    76  }
    77  
    78  // FIXME: consider using same format as API when commits API are added.
    79  //        applies to PayloadCommit and PayloadCommitVerification
    80  
    81  // PayloadCommit represents a commit
    82  type PayloadCommit struct {
    83  	// sha1 hash of the commit
    84  	ID           string                     `json:"id"`
    85  	Message      string                     `json:"message"`
    86  	URL          string                     `json:"url"`
    87  	Author       *PayloadUser               `json:"author"`
    88  	Committer    *PayloadUser               `json:"committer"`
    89  	Verification *PayloadCommitVerification `json:"verification"`
    90  	// swagger:strfmt date-time
    91  	Timestamp time.Time `json:"timestamp"`
    92  	Added     []string  `json:"added"`
    93  	Removed   []string  `json:"removed"`
    94  	Modified  []string  `json:"modified"`
    95  }
    96  
    97  // PayloadCommitVerification represents the GPG verification of a commit
    98  type PayloadCommitVerification struct {
    99  	Verified  bool         `json:"verified"`
   100  	Reason    string       `json:"reason"`
   101  	Signature string       `json:"signature"`
   102  	Signer    *PayloadUser `json:"signer"`
   103  	Payload   string       `json:"payload"`
   104  }
   105  
   106  var (
   107  	_ Payloader = &CreatePayload{}
   108  	_ Payloader = &DeletePayload{}
   109  	_ Payloader = &ForkPayload{}
   110  	_ Payloader = &PushPayload{}
   111  	_ Payloader = &IssuePayload{}
   112  	_ Payloader = &IssueCommentPayload{}
   113  	_ Payloader = &PullRequestPayload{}
   114  	_ Payloader = &RepositoryPayload{}
   115  	_ Payloader = &ReleasePayload{}
   116  	_ Payloader = &PackagePayload{}
   117  )
   118  
   119  // _________                        __
   120  // \_   ___ \_______   ____ _____ _/  |_  ____
   121  // /    \  \/\_  __ \_/ __ \\__  \\   __\/ __ \
   122  // \     \____|  | \/\  ___/ / __ \|  | \  ___/
   123  //  \______  /|__|    \___  >____  /__|  \___  >
   124  //         \/             \/     \/          \/
   125  
   126  // CreatePayload FIXME
   127  type CreatePayload struct {
   128  	Sha     string      `json:"sha"`
   129  	Ref     string      `json:"ref"`
   130  	RefType string      `json:"ref_type"`
   131  	Repo    *Repository `json:"repository"`
   132  	Sender  *User       `json:"sender"`
   133  }
   134  
   135  // JSONPayload return payload information
   136  func (p *CreatePayload) JSONPayload() ([]byte, error) {
   137  	return json.MarshalIndent(p, "", "  ")
   138  }
   139  
   140  // ParseCreateHook parses create event hook content.
   141  func ParseCreateHook(raw []byte) (*CreatePayload, error) {
   142  	hook := new(CreatePayload)
   143  	if err := json.Unmarshal(raw, hook); err != nil {
   144  		return nil, err
   145  	}
   146  
   147  	// it is possible the JSON was parsed, however,
   148  	// was not from Gogs (maybe was from Bitbucket)
   149  	// So we'll check to be sure certain key fields
   150  	// were populated
   151  	switch {
   152  	case hook.Repo == nil:
   153  		return nil, ErrInvalidReceiveHook
   154  	case len(hook.Ref) == 0:
   155  		return nil, ErrInvalidReceiveHook
   156  	}
   157  	return hook, nil
   158  }
   159  
   160  // ________         .__          __
   161  // \______ \   ____ |  |   _____/  |_  ____
   162  //  |    |  \_/ __ \|  | _/ __ \   __\/ __ \
   163  //  |    `   \  ___/|  |_\  ___/|  | \  ___/
   164  // /_______  /\___  >____/\___  >__|  \___  >
   165  //         \/     \/          \/          \/
   166  
   167  // PusherType define the type to push
   168  type PusherType string
   169  
   170  // describe all the PusherTypes
   171  const (
   172  	PusherTypeUser PusherType = "user"
   173  )
   174  
   175  // DeletePayload represents delete payload
   176  type DeletePayload struct {
   177  	Ref        string      `json:"ref"`
   178  	RefType    string      `json:"ref_type"`
   179  	PusherType PusherType  `json:"pusher_type"`
   180  	Repo       *Repository `json:"repository"`
   181  	Sender     *User       `json:"sender"`
   182  }
   183  
   184  // JSONPayload implements Payload
   185  func (p *DeletePayload) JSONPayload() ([]byte, error) {
   186  	return json.MarshalIndent(p, "", "  ")
   187  }
   188  
   189  // ___________           __
   190  // \_   _____/__________|  | __
   191  //  |    __)/  _ \_  __ \  |/ /
   192  //  |     \(  <_> )  | \/    <
   193  //  \___  / \____/|__|  |__|_ \
   194  //      \/                   \/
   195  
   196  // ForkPayload represents fork payload
   197  type ForkPayload struct {
   198  	Forkee *Repository `json:"forkee"`
   199  	Repo   *Repository `json:"repository"`
   200  	Sender *User       `json:"sender"`
   201  }
   202  
   203  // JSONPayload implements Payload
   204  func (p *ForkPayload) JSONPayload() ([]byte, error) {
   205  	return json.MarshalIndent(p, "", "  ")
   206  }
   207  
   208  // HookIssueCommentAction defines hook issue comment action
   209  type HookIssueCommentAction string
   210  
   211  // all issue comment actions
   212  const (
   213  	HookIssueCommentCreated HookIssueCommentAction = "created"
   214  	HookIssueCommentEdited  HookIssueCommentAction = "edited"
   215  	HookIssueCommentDeleted HookIssueCommentAction = "deleted"
   216  )
   217  
   218  // IssueCommentPayload represents a payload information of issue comment event.
   219  type IssueCommentPayload struct {
   220  	Action     HookIssueCommentAction `json:"action"`
   221  	Issue      *Issue                 `json:"issue"`
   222  	Comment    *Comment               `json:"comment"`
   223  	Changes    *ChangesPayload        `json:"changes,omitempty"`
   224  	Repository *Repository            `json:"repository"`
   225  	Sender     *User                  `json:"sender"`
   226  	IsPull     bool                   `json:"is_pull"`
   227  }
   228  
   229  // JSONPayload implements Payload
   230  func (p *IssueCommentPayload) JSONPayload() ([]byte, error) {
   231  	return json.MarshalIndent(p, "", "  ")
   232  }
   233  
   234  // __________       .__
   235  // \______   \ ____ |  |   ____ _____    ______ ____
   236  //  |       _// __ \|  | _/ __ \\__  \  /  ___// __ \
   237  //  |    |   \  ___/|  |_\  ___/ / __ \_\___ \\  ___/
   238  //  |____|_  /\___  >____/\___  >____  /____  >\___  >
   239  //         \/     \/          \/     \/     \/     \/
   240  
   241  // HookReleaseAction defines hook release action type
   242  type HookReleaseAction string
   243  
   244  // all release actions
   245  const (
   246  	HookReleasePublished HookReleaseAction = "published"
   247  	HookReleaseUpdated   HookReleaseAction = "updated"
   248  	HookReleaseDeleted   HookReleaseAction = "deleted"
   249  )
   250  
   251  // ReleasePayload represents a payload information of release event.
   252  type ReleasePayload struct {
   253  	Action     HookReleaseAction `json:"action"`
   254  	Release    *Release          `json:"release"`
   255  	Repository *Repository       `json:"repository"`
   256  	Sender     *User             `json:"sender"`
   257  }
   258  
   259  // JSONPayload implements Payload
   260  func (p *ReleasePayload) JSONPayload() ([]byte, error) {
   261  	return json.MarshalIndent(p, "", "  ")
   262  }
   263  
   264  // __________             .__
   265  // \______   \__ __  _____|  |__
   266  //  |     ___/  |  \/  ___/  |  \
   267  //  |    |   |  |  /\___ \|   Y  \
   268  //  |____|   |____//____  >___|  /
   269  //                      \/     \/
   270  
   271  // PushPayload represents a payload information of push event.
   272  type PushPayload struct {
   273  	Ref          string           `json:"ref"`
   274  	Before       string           `json:"before"`
   275  	After        string           `json:"after"`
   276  	CompareURL   string           `json:"compare_url"`
   277  	Commits      []*PayloadCommit `json:"commits"`
   278  	TotalCommits int              `json:"total_commits"`
   279  	HeadCommit   *PayloadCommit   `json:"head_commit"`
   280  	Repo         *Repository      `json:"repository"`
   281  	Pusher       *User            `json:"pusher"`
   282  	Sender       *User            `json:"sender"`
   283  }
   284  
   285  // JSONPayload FIXME
   286  func (p *PushPayload) JSONPayload() ([]byte, error) {
   287  	return json.MarshalIndent(p, "", "  ")
   288  }
   289  
   290  // ParsePushHook parses push event hook content.
   291  func ParsePushHook(raw []byte) (*PushPayload, error) {
   292  	hook := new(PushPayload)
   293  	if err := json.Unmarshal(raw, hook); err != nil {
   294  		return nil, err
   295  	}
   296  
   297  	switch {
   298  	case hook.Repo == nil:
   299  		return nil, ErrInvalidReceiveHook
   300  	case len(hook.Ref) == 0:
   301  		return nil, ErrInvalidReceiveHook
   302  	}
   303  	return hook, nil
   304  }
   305  
   306  // Branch returns branch name from a payload
   307  func (p *PushPayload) Branch() string {
   308  	return strings.ReplaceAll(p.Ref, "refs/heads/", "")
   309  }
   310  
   311  // .___
   312  // |   | ______ ________ __   ____
   313  // |   |/  ___//  ___/  |  \_/ __ \
   314  // |   |\___ \ \___ \|  |  /\  ___/
   315  // |___/____  >____  >____/  \___  >
   316  //          \/     \/            \/
   317  
   318  // HookIssueAction FIXME
   319  type HookIssueAction string
   320  
   321  const (
   322  	// HookIssueOpened opened
   323  	HookIssueOpened HookIssueAction = "opened"
   324  	// HookIssueClosed closed
   325  	HookIssueClosed HookIssueAction = "closed"
   326  	// HookIssueReOpened reopened
   327  	HookIssueReOpened HookIssueAction = "reopened"
   328  	// HookIssueEdited edited
   329  	HookIssueEdited HookIssueAction = "edited"
   330  	// HookIssueAssigned assigned
   331  	HookIssueAssigned HookIssueAction = "assigned"
   332  	// HookIssueUnassigned unassigned
   333  	HookIssueUnassigned HookIssueAction = "unassigned"
   334  	// HookIssueLabelUpdated label_updated
   335  	HookIssueLabelUpdated HookIssueAction = "label_updated"
   336  	// HookIssueLabelCleared label_cleared
   337  	HookIssueLabelCleared HookIssueAction = "label_cleared"
   338  	// HookIssueSynchronized synchronized
   339  	HookIssueSynchronized HookIssueAction = "synchronized"
   340  	// HookIssueMilestoned is an issue action for when a milestone is set on an issue.
   341  	HookIssueMilestoned HookIssueAction = "milestoned"
   342  	// HookIssueDemilestoned is an issue action for when a milestone is cleared on an issue.
   343  	HookIssueDemilestoned HookIssueAction = "demilestoned"
   344  	// HookIssueReviewed is an issue action for when a pull request is reviewed
   345  	HookIssueReviewed HookIssueAction = "reviewed"
   346  	// HookIssueReviewRequested is an issue action for when a reviewer is requested for a pull request.
   347  	HookIssueReviewRequested HookIssueAction = "review_requested"
   348  	// HookIssueReviewRequestRemoved is an issue action for removing a review request to someone on a pull request.
   349  	HookIssueReviewRequestRemoved HookIssueAction = "review_request_removed"
   350  )
   351  
   352  // IssuePayload represents the payload information that is sent along with an issue event.
   353  type IssuePayload struct {
   354  	Action     HookIssueAction `json:"action"`
   355  	Index      int64           `json:"number"`
   356  	Changes    *ChangesPayload `json:"changes,omitempty"`
   357  	Issue      *Issue          `json:"issue"`
   358  	Repository *Repository     `json:"repository"`
   359  	Sender     *User           `json:"sender"`
   360  	CommitID   string          `json:"commit_id"`
   361  }
   362  
   363  // JSONPayload encodes the IssuePayload to JSON, with an indentation of two spaces.
   364  func (p *IssuePayload) JSONPayload() ([]byte, error) {
   365  	return json.MarshalIndent(p, "", "  ")
   366  }
   367  
   368  // ChangesFromPayload FIXME
   369  type ChangesFromPayload struct {
   370  	From string `json:"from"`
   371  }
   372  
   373  // ChangesPayload represents the payload information of issue change
   374  type ChangesPayload struct {
   375  	Title *ChangesFromPayload `json:"title,omitempty"`
   376  	Body  *ChangesFromPayload `json:"body,omitempty"`
   377  	Ref   *ChangesFromPayload `json:"ref,omitempty"`
   378  }
   379  
   380  // __________      .__  .__    __________                                     __
   381  // \______   \__ __|  | |  |   \______   \ ____  ________ __   ____   _______/  |_
   382  //  |     ___/  |  \  | |  |    |       _// __ \/ ____/  |  \_/ __ \ /  ___/\   __\
   383  //  |    |   |  |  /  |_|  |__  |    |   \  ___< <_|  |  |  /\  ___/ \___ \  |  |
   384  //  |____|   |____/|____/____/  |____|_  /\___  >__   |____/  \___  >____  > |__|
   385  //                                     \/     \/   |__|           \/     \/
   386  
   387  // PullRequestPayload represents a payload information of pull request event.
   388  type PullRequestPayload struct {
   389  	Action            HookIssueAction `json:"action"`
   390  	Index             int64           `json:"number"`
   391  	Changes           *ChangesPayload `json:"changes,omitempty"`
   392  	PullRequest       *PullRequest    `json:"pull_request"`
   393  	RequestedReviewer *User           `json:"requested_reviewer"`
   394  	Repository        *Repository     `json:"repository"`
   395  	Sender            *User           `json:"sender"`
   396  	CommitID          string          `json:"commit_id"`
   397  	Review            *ReviewPayload  `json:"review"`
   398  }
   399  
   400  // JSONPayload FIXME
   401  func (p *PullRequestPayload) JSONPayload() ([]byte, error) {
   402  	return json.MarshalIndent(p, "", "  ")
   403  }
   404  
   405  // ReviewPayload FIXME
   406  type ReviewPayload struct {
   407  	Type    string `json:"type"`
   408  	Content string `json:"content"`
   409  }
   410  
   411  //  __      __.__ __   .__
   412  // /  \    /  \__|  | _|__|
   413  // \   \/\/   /  |  |/ /  |
   414  //  \        /|  |    <|  |
   415  //   \__/\  / |__|__|_ \__|
   416  //        \/          \/
   417  
   418  // HookWikiAction an action that happens to a wiki page
   419  type HookWikiAction string
   420  
   421  const (
   422  	// HookWikiCreated created
   423  	HookWikiCreated HookWikiAction = "created"
   424  	// HookWikiEdited edited
   425  	HookWikiEdited HookWikiAction = "edited"
   426  	// HookWikiDeleted deleted
   427  	HookWikiDeleted HookWikiAction = "deleted"
   428  )
   429  
   430  // WikiPayload payload for repository webhooks
   431  type WikiPayload struct {
   432  	Action     HookWikiAction `json:"action"`
   433  	Repository *Repository    `json:"repository"`
   434  	Sender     *User          `json:"sender"`
   435  	Page       string         `json:"page"`
   436  	Comment    string         `json:"comment"`
   437  }
   438  
   439  // JSONPayload JSON representation of the payload
   440  func (p *WikiPayload) JSONPayload() ([]byte, error) {
   441  	return json.MarshalIndent(p, "", " ")
   442  }
   443  
   444  //__________                           .__  __
   445  //\______   \ ____ ______   ____  _____|__|/  |_  ___________ ___.__.
   446  // |       _// __ \\____ \ /  _ \/  ___/  \   __\/  _ \_  __ <   |  |
   447  // |    |   \  ___/|  |_> >  <_> )___ \|  ||  | (  <_> )  | \/\___  |
   448  // |____|_  /\___  >   __/ \____/____  >__||__|  \____/|__|   / ____|
   449  //        \/     \/|__|              \/                       \/
   450  
   451  // HookRepoAction an action that happens to a repo
   452  type HookRepoAction string
   453  
   454  const (
   455  	// HookRepoCreated created
   456  	HookRepoCreated HookRepoAction = "created"
   457  	// HookRepoDeleted deleted
   458  	HookRepoDeleted HookRepoAction = "deleted"
   459  )
   460  
   461  // RepositoryPayload payload for repository webhooks
   462  type RepositoryPayload struct {
   463  	Action       HookRepoAction `json:"action"`
   464  	Repository   *Repository    `json:"repository"`
   465  	Organization *User          `json:"organization"`
   466  	Sender       *User          `json:"sender"`
   467  }
   468  
   469  // JSONPayload JSON representation of the payload
   470  func (p *RepositoryPayload) JSONPayload() ([]byte, error) {
   471  	return json.MarshalIndent(p, "", " ")
   472  }
   473  
   474  // HookPackageAction an action that happens to a package
   475  type HookPackageAction string
   476  
   477  const (
   478  	// HookPackageCreated created
   479  	HookPackageCreated HookPackageAction = "created"
   480  	// HookPackageDeleted deleted
   481  	HookPackageDeleted HookPackageAction = "deleted"
   482  )
   483  
   484  // PackagePayload represents a package payload
   485  type PackagePayload struct {
   486  	Action       HookPackageAction `json:"action"`
   487  	Repository   *Repository       `json:"repository"`
   488  	Package      *Package          `json:"package"`
   489  	Organization *User             `json:"organization"`
   490  	Sender       *User             `json:"sender"`
   491  }
   492  
   493  // JSONPayload implements Payload
   494  func (p *PackagePayload) JSONPayload() ([]byte, error) {
   495  	return json.MarshalIndent(p, "", "  ")
   496  }