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 }