You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

hook.go 15KB

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