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