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

webhook.go 23 kB

11 years ago
11 years ago
8 years ago
8 years ago
8 years ago
11 years ago
11 years ago
Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
6 years ago
11 years ago
9 years ago
9 years ago
11 years ago
API add/generalize pagination (#9452) * paginate results * fixed deadlock * prevented breaking change * updated swagger * go fmt * fixed find topic * go mod tidy * go mod vendor with go1.13.5 * fixed repo find topics * fixed unit test * added Limit method to Engine struct; use engine variable when provided; fixed gitignore * use ItemsPerPage for default pagesize; fix GetWatchers, getOrgUsersByOrgID and GetStargazers; fix GetAllCommits headers; reverted some changed behaviors * set Page value on Home route * improved memory allocations * fixed response headers * removed logfiles * fixed import order * import order * improved swagger * added function to get models.ListOptions from context * removed pagesize diff on unit test * fixed imports * removed unnecessary struct field * fixed go fmt * scoped PR * code improvements * code improvements * go mod tidy * fixed import order * fixed commit statuses session * fixed files headers * fixed headers; added pagination for notifications * go mod tidy * go fmt * removed Private from user search options; added setting.UI.IssuePagingNum as default valeu on repo's issues list * Apply suggestions from code review Co-Authored-By: 6543 <6543@obermui.de> Co-Authored-By: zeripath <art27@cantab.net> * fixed build error * CI.restart() * fixed merge conflicts resolve * fixed conflicts resolve * improved FindTrackedTimesOptions.ToOptions() method * added backwards compatibility on ListReleases request; fixed issue tracked time ToSession * fixed build error; fixed swagger template * fixed swagger template * fixed ListReleases backwards compatibility * added page to user search route Co-authored-by: techknowlogick <matti@mdranta.net> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: zeripath <art27@cantab.net>
5 years ago
API add/generalize pagination (#9452) * paginate results * fixed deadlock * prevented breaking change * updated swagger * go fmt * fixed find topic * go mod tidy * go mod vendor with go1.13.5 * fixed repo find topics * fixed unit test * added Limit method to Engine struct; use engine variable when provided; fixed gitignore * use ItemsPerPage for default pagesize; fix GetWatchers, getOrgUsersByOrgID and GetStargazers; fix GetAllCommits headers; reverted some changed behaviors * set Page value on Home route * improved memory allocations * fixed response headers * removed logfiles * fixed import order * import order * improved swagger * added function to get models.ListOptions from context * removed pagesize diff on unit test * fixed imports * removed unnecessary struct field * fixed go fmt * scoped PR * code improvements * code improvements * go mod tidy * fixed import order * fixed commit statuses session * fixed files headers * fixed headers; added pagination for notifications * go mod tidy * go fmt * removed Private from user search options; added setting.UI.IssuePagingNum as default valeu on repo's issues list * Apply suggestions from code review Co-Authored-By: 6543 <6543@obermui.de> Co-Authored-By: zeripath <art27@cantab.net> * fixed build error * CI.restart() * fixed merge conflicts resolve * fixed conflicts resolve * improved FindTrackedTimesOptions.ToOptions() method * added backwards compatibility on ListReleases request; fixed issue tracked time ToSession * fixed build error; fixed swagger template * fixed swagger template * fixed ListReleases backwards compatibility * added page to user search route Co-authored-by: techknowlogick <matti@mdranta.net> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: zeripath <art27@cantab.net>
5 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
6 years ago
Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
6 years ago
Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
6 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  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 models
  6. import (
  7. "encoding/json"
  8. "fmt"
  9. "strings"
  10. "time"
  11. "code.gitea.io/gitea/modules/log"
  12. "code.gitea.io/gitea/modules/setting"
  13. api "code.gitea.io/gitea/modules/structs"
  14. "code.gitea.io/gitea/modules/timeutil"
  15. gouuid "github.com/google/uuid"
  16. )
  17. // HookContentType is the content type of a web hook
  18. type HookContentType int
  19. const (
  20. // ContentTypeJSON is a JSON payload for web hooks
  21. ContentTypeJSON HookContentType = iota + 1
  22. // ContentTypeForm is an url-encoded form payload for web hook
  23. ContentTypeForm
  24. )
  25. var hookContentTypes = map[string]HookContentType{
  26. "json": ContentTypeJSON,
  27. "form": ContentTypeForm,
  28. }
  29. // ToHookContentType returns HookContentType by given name.
  30. func ToHookContentType(name string) HookContentType {
  31. return hookContentTypes[name]
  32. }
  33. // Name returns the name of a given web hook's content type
  34. func (t HookContentType) Name() string {
  35. switch t {
  36. case ContentTypeJSON:
  37. return "json"
  38. case ContentTypeForm:
  39. return "form"
  40. }
  41. return ""
  42. }
  43. // IsValidHookContentType returns true if given name is a valid hook content type.
  44. func IsValidHookContentType(name string) bool {
  45. _, ok := hookContentTypes[name]
  46. return ok
  47. }
  48. // HookEvents is a set of web hook events
  49. type HookEvents struct {
  50. Create bool `json:"create"`
  51. Delete bool `json:"delete"`
  52. Fork bool `json:"fork"`
  53. Issues bool `json:"issues"`
  54. IssueAssign bool `json:"issue_assign"`
  55. IssueLabel bool `json:"issue_label"`
  56. IssueMilestone bool `json:"issue_milestone"`
  57. IssueComment bool `json:"issue_comment"`
  58. Push bool `json:"push"`
  59. PullRequest bool `json:"pull_request"`
  60. PullRequestAssign bool `json:"pull_request_assign"`
  61. PullRequestLabel bool `json:"pull_request_label"`
  62. PullRequestMilestone bool `json:"pull_request_milestone"`
  63. PullRequestComment bool `json:"pull_request_comment"`
  64. PullRequestReview bool `json:"pull_request_review"`
  65. PullRequestSync bool `json:"pull_request_sync"`
  66. Repository bool `json:"repository"`
  67. Release bool `json:"release"`
  68. }
  69. // HookEvent represents events that will delivery hook.
  70. type HookEvent struct {
  71. PushOnly bool `json:"push_only"`
  72. SendEverything bool `json:"send_everything"`
  73. ChooseEvents bool `json:"choose_events"`
  74. BranchFilter string `json:"branch_filter"`
  75. HookEvents `json:"events"`
  76. }
  77. // HookStatus is the status of a web hook
  78. type HookStatus int
  79. // Possible statuses of a web hook
  80. const (
  81. HookStatusNone = iota
  82. HookStatusSucceed
  83. HookStatusFail
  84. )
  85. // Webhook represents a web hook object.
  86. type Webhook struct {
  87. ID int64 `xorm:"pk autoincr"`
  88. RepoID int64 `xorm:"INDEX"` // An ID of 0 indicates either a default or system webhook
  89. OrgID int64 `xorm:"INDEX"`
  90. IsSystemWebhook bool
  91. URL string `xorm:"url TEXT"`
  92. Signature string `xorm:"TEXT"`
  93. HTTPMethod string `xorm:"http_method"`
  94. ContentType HookContentType
  95. Secret string `xorm:"TEXT"`
  96. Events string `xorm:"TEXT"`
  97. *HookEvent `xorm:"-"`
  98. IsSSL bool `xorm:"is_ssl"`
  99. IsActive bool `xorm:"INDEX"`
  100. Type HookTaskType `xorm:"char(16) 'type'"`
  101. Meta string `xorm:"TEXT"` // store hook-specific attributes
  102. LastStatus HookStatus // Last delivery status
  103. CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
  104. UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
  105. }
  106. // AfterLoad updates the webhook object upon setting a column
  107. func (w *Webhook) AfterLoad() {
  108. w.HookEvent = &HookEvent{}
  109. if err := json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil {
  110. log.Error("Unmarshal[%d]: %v", w.ID, err)
  111. }
  112. }
  113. // History returns history of webhook by given conditions.
  114. func (w *Webhook) History(page int) ([]*HookTask, error) {
  115. return HookTasks(w.ID, page)
  116. }
  117. // UpdateEvent handles conversion from HookEvent to Events.
  118. func (w *Webhook) UpdateEvent() error {
  119. data, err := json.Marshal(w.HookEvent)
  120. w.Events = string(data)
  121. return err
  122. }
  123. // HasCreateEvent returns true if hook enabled create event.
  124. func (w *Webhook) HasCreateEvent() bool {
  125. return w.SendEverything ||
  126. (w.ChooseEvents && w.HookEvents.Create)
  127. }
  128. // HasDeleteEvent returns true if hook enabled delete event.
  129. func (w *Webhook) HasDeleteEvent() bool {
  130. return w.SendEverything ||
  131. (w.ChooseEvents && w.HookEvents.Delete)
  132. }
  133. // HasForkEvent returns true if hook enabled fork event.
  134. func (w *Webhook) HasForkEvent() bool {
  135. return w.SendEverything ||
  136. (w.ChooseEvents && w.HookEvents.Fork)
  137. }
  138. // HasIssuesEvent returns true if hook enabled issues event.
  139. func (w *Webhook) HasIssuesEvent() bool {
  140. return w.SendEverything ||
  141. (w.ChooseEvents && w.HookEvents.Issues)
  142. }
  143. // HasIssuesAssignEvent returns true if hook enabled issues assign event.
  144. func (w *Webhook) HasIssuesAssignEvent() bool {
  145. return w.SendEverything ||
  146. (w.ChooseEvents && w.HookEvents.IssueAssign)
  147. }
  148. // HasIssuesLabelEvent returns true if hook enabled issues label event.
  149. func (w *Webhook) HasIssuesLabelEvent() bool {
  150. return w.SendEverything ||
  151. (w.ChooseEvents && w.HookEvents.IssueLabel)
  152. }
  153. // HasIssuesMilestoneEvent returns true if hook enabled issues milestone event.
  154. func (w *Webhook) HasIssuesMilestoneEvent() bool {
  155. return w.SendEverything ||
  156. (w.ChooseEvents && w.HookEvents.IssueMilestone)
  157. }
  158. // HasIssueCommentEvent returns true if hook enabled issue_comment event.
  159. func (w *Webhook) HasIssueCommentEvent() bool {
  160. return w.SendEverything ||
  161. (w.ChooseEvents && w.HookEvents.IssueComment)
  162. }
  163. // HasPushEvent returns true if hook enabled push event.
  164. func (w *Webhook) HasPushEvent() bool {
  165. return w.PushOnly || w.SendEverything ||
  166. (w.ChooseEvents && w.HookEvents.Push)
  167. }
  168. // HasPullRequestEvent returns true if hook enabled pull request event.
  169. func (w *Webhook) HasPullRequestEvent() bool {
  170. return w.SendEverything ||
  171. (w.ChooseEvents && w.HookEvents.PullRequest)
  172. }
  173. // HasPullRequestAssignEvent returns true if hook enabled pull request assign event.
  174. func (w *Webhook) HasPullRequestAssignEvent() bool {
  175. return w.SendEverything ||
  176. (w.ChooseEvents && w.HookEvents.PullRequestAssign)
  177. }
  178. // HasPullRequestLabelEvent returns true if hook enabled pull request label event.
  179. func (w *Webhook) HasPullRequestLabelEvent() bool {
  180. return w.SendEverything ||
  181. (w.ChooseEvents && w.HookEvents.PullRequestLabel)
  182. }
  183. // HasPullRequestMilestoneEvent returns true if hook enabled pull request milestone event.
  184. func (w *Webhook) HasPullRequestMilestoneEvent() bool {
  185. return w.SendEverything ||
  186. (w.ChooseEvents && w.HookEvents.PullRequestMilestone)
  187. }
  188. // HasPullRequestCommentEvent returns true if hook enabled pull_request_comment event.
  189. func (w *Webhook) HasPullRequestCommentEvent() bool {
  190. return w.SendEverything ||
  191. (w.ChooseEvents && w.HookEvents.PullRequestComment)
  192. }
  193. // HasPullRequestApprovedEvent returns true if hook enabled pull request review event.
  194. func (w *Webhook) HasPullRequestApprovedEvent() bool {
  195. return w.SendEverything ||
  196. (w.ChooseEvents && w.HookEvents.PullRequestReview)
  197. }
  198. // HasPullRequestRejectedEvent returns true if hook enabled pull request review event.
  199. func (w *Webhook) HasPullRequestRejectedEvent() bool {
  200. return w.SendEverything ||
  201. (w.ChooseEvents && w.HookEvents.PullRequestReview)
  202. }
  203. // HasPullRequestReviewCommentEvent returns true if hook enabled pull request review event.
  204. func (w *Webhook) HasPullRequestReviewCommentEvent() bool {
  205. return w.SendEverything ||
  206. (w.ChooseEvents && w.HookEvents.PullRequestReview)
  207. }
  208. // HasPullRequestSyncEvent returns true if hook enabled pull request sync event.
  209. func (w *Webhook) HasPullRequestSyncEvent() bool {
  210. return w.SendEverything ||
  211. (w.ChooseEvents && w.HookEvents.PullRequestSync)
  212. }
  213. // HasReleaseEvent returns if hook enabled release event.
  214. func (w *Webhook) HasReleaseEvent() bool {
  215. return w.SendEverything ||
  216. (w.ChooseEvents && w.HookEvents.Release)
  217. }
  218. // HasRepositoryEvent returns if hook enabled repository event.
  219. func (w *Webhook) HasRepositoryEvent() bool {
  220. return w.SendEverything ||
  221. (w.ChooseEvents && w.HookEvents.Repository)
  222. }
  223. // EventCheckers returns event checkers
  224. func (w *Webhook) EventCheckers() []struct {
  225. Has func() bool
  226. Type HookEventType
  227. } {
  228. return []struct {
  229. Has func() bool
  230. Type HookEventType
  231. }{
  232. {w.HasCreateEvent, HookEventCreate},
  233. {w.HasDeleteEvent, HookEventDelete},
  234. {w.HasForkEvent, HookEventFork},
  235. {w.HasPushEvent, HookEventPush},
  236. {w.HasIssuesEvent, HookEventIssues},
  237. {w.HasIssuesAssignEvent, HookEventIssueAssign},
  238. {w.HasIssuesLabelEvent, HookEventIssueLabel},
  239. {w.HasIssuesMilestoneEvent, HookEventIssueMilestone},
  240. {w.HasIssueCommentEvent, HookEventIssueComment},
  241. {w.HasPullRequestEvent, HookEventPullRequest},
  242. {w.HasPullRequestAssignEvent, HookEventPullRequestAssign},
  243. {w.HasPullRequestLabelEvent, HookEventPullRequestLabel},
  244. {w.HasPullRequestMilestoneEvent, HookEventPullRequestMilestone},
  245. {w.HasPullRequestCommentEvent, HookEventPullRequestComment},
  246. {w.HasPullRequestApprovedEvent, HookEventPullRequestReviewApproved},
  247. {w.HasPullRequestRejectedEvent, HookEventPullRequestReviewRejected},
  248. {w.HasPullRequestCommentEvent, HookEventPullRequestReviewComment},
  249. {w.HasPullRequestSyncEvent, HookEventPullRequestSync},
  250. {w.HasRepositoryEvent, HookEventRepository},
  251. {w.HasReleaseEvent, HookEventRelease},
  252. }
  253. }
  254. // EventsArray returns an array of hook events
  255. func (w *Webhook) EventsArray() []string {
  256. events := make([]string, 0, 7)
  257. for _, c := range w.EventCheckers() {
  258. if c.Has() {
  259. events = append(events, string(c.Type))
  260. }
  261. }
  262. return events
  263. }
  264. // CreateWebhook creates a new web hook.
  265. func CreateWebhook(w *Webhook) error {
  266. return createWebhook(x, w)
  267. }
  268. func createWebhook(e Engine, w *Webhook) error {
  269. w.Type = strings.TrimSpace(w.Type)
  270. _, err := e.Insert(w)
  271. return err
  272. }
  273. // getWebhook uses argument bean as query condition,
  274. // ID must be specified and do not assign unnecessary fields.
  275. func getWebhook(bean *Webhook) (*Webhook, error) {
  276. has, err := x.Get(bean)
  277. if err != nil {
  278. return nil, err
  279. } else if !has {
  280. return nil, ErrWebhookNotExist{bean.ID}
  281. }
  282. return bean, nil
  283. }
  284. // GetWebhookByID returns webhook of repository by given ID.
  285. func GetWebhookByID(id int64) (*Webhook, error) {
  286. return getWebhook(&Webhook{
  287. ID: id,
  288. })
  289. }
  290. // GetWebhookByRepoID returns webhook of repository by given ID.
  291. func GetWebhookByRepoID(repoID, id int64) (*Webhook, error) {
  292. return getWebhook(&Webhook{
  293. ID: id,
  294. RepoID: repoID,
  295. })
  296. }
  297. // GetWebhookByOrgID returns webhook of organization by given ID.
  298. func GetWebhookByOrgID(orgID, id int64) (*Webhook, error) {
  299. return getWebhook(&Webhook{
  300. ID: id,
  301. OrgID: orgID,
  302. })
  303. }
  304. // GetActiveWebhooksByRepoID returns all active webhooks of repository.
  305. func GetActiveWebhooksByRepoID(repoID int64) ([]*Webhook, error) {
  306. return getActiveWebhooksByRepoID(x, repoID)
  307. }
  308. func getActiveWebhooksByRepoID(e Engine, repoID int64) ([]*Webhook, error) {
  309. webhooks := make([]*Webhook, 0, 5)
  310. return webhooks, e.Where("is_active=?", true).
  311. Find(&webhooks, &Webhook{RepoID: repoID})
  312. }
  313. // GetWebhooksByRepoID returns all webhooks of a repository.
  314. func GetWebhooksByRepoID(repoID int64, listOptions ListOptions) ([]*Webhook, error) {
  315. if listOptions.Page == 0 {
  316. webhooks := make([]*Webhook, 0, 5)
  317. return webhooks, x.Find(&webhooks, &Webhook{RepoID: repoID})
  318. }
  319. sess := listOptions.getPaginatedSession()
  320. webhooks := make([]*Webhook, 0, listOptions.PageSize)
  321. return webhooks, sess.Find(&webhooks, &Webhook{RepoID: repoID})
  322. }
  323. // GetActiveWebhooksByOrgID returns all active webhooks for an organization.
  324. func GetActiveWebhooksByOrgID(orgID int64) (ws []*Webhook, err error) {
  325. return getActiveWebhooksByOrgID(x, orgID)
  326. }
  327. func getActiveWebhooksByOrgID(e Engine, orgID int64) (ws []*Webhook, err error) {
  328. err = e.
  329. Where("org_id=?", orgID).
  330. And("is_active=?", true).
  331. Find(&ws)
  332. return ws, err
  333. }
  334. // GetWebhooksByOrgID returns paginated webhooks for an organization.
  335. func GetWebhooksByOrgID(orgID int64, listOptions ListOptions) ([]*Webhook, error) {
  336. if listOptions.Page == 0 {
  337. ws := make([]*Webhook, 0, 5)
  338. return ws, x.Find(&ws, &Webhook{OrgID: orgID})
  339. }
  340. sess := listOptions.getPaginatedSession()
  341. ws := make([]*Webhook, 0, listOptions.PageSize)
  342. return ws, sess.Find(&ws, &Webhook{OrgID: orgID})
  343. }
  344. // GetDefaultWebhook returns admin-default webhook by given ID.
  345. func GetDefaultWebhook(id int64) (*Webhook, error) {
  346. webhook := &Webhook{ID: id}
  347. has, err := x.
  348. Where("repo_id=? AND org_id=? AND is_system_webhook=?", 0, 0, false).
  349. Get(webhook)
  350. if err != nil {
  351. return nil, err
  352. } else if !has {
  353. return nil, ErrWebhookNotExist{id}
  354. }
  355. return webhook, nil
  356. }
  357. // GetDefaultWebhooks returns all admin-default webhooks.
  358. func GetDefaultWebhooks() ([]*Webhook, error) {
  359. return getDefaultWebhooks(x)
  360. }
  361. func getDefaultWebhooks(e Engine) ([]*Webhook, error) {
  362. webhooks := make([]*Webhook, 0, 5)
  363. return webhooks, e.
  364. Where("repo_id=? AND org_id=? AND is_system_webhook=?", 0, 0, false).
  365. Find(&webhooks)
  366. }
  367. // GetSystemWebhook returns admin system webhook by given ID.
  368. func GetSystemWebhook(id int64) (*Webhook, error) {
  369. webhook := &Webhook{ID: id}
  370. has, err := x.
  371. Where("repo_id=? AND org_id=? AND is_system_webhook=?", 0, 0, true).
  372. Get(webhook)
  373. if err != nil {
  374. return nil, err
  375. } else if !has {
  376. return nil, ErrWebhookNotExist{id}
  377. }
  378. return webhook, nil
  379. }
  380. // GetSystemWebhooks returns all admin system webhooks.
  381. func GetSystemWebhooks() ([]*Webhook, error) {
  382. return getSystemWebhooks(x)
  383. }
  384. func getSystemWebhooks(e Engine) ([]*Webhook, error) {
  385. webhooks := make([]*Webhook, 0, 5)
  386. return webhooks, e.
  387. Where("repo_id=? AND org_id=? AND is_system_webhook=?", 0, 0, true).
  388. Find(&webhooks)
  389. }
  390. // UpdateWebhook updates information of webhook.
  391. func UpdateWebhook(w *Webhook) error {
  392. _, err := x.ID(w.ID).AllCols().Update(w)
  393. return err
  394. }
  395. // UpdateWebhookLastStatus updates last status of webhook.
  396. func UpdateWebhookLastStatus(w *Webhook) error {
  397. _, err := x.ID(w.ID).Cols("last_status").Update(w)
  398. return err
  399. }
  400. // deleteWebhook uses argument bean as query condition,
  401. // ID must be specified and do not assign unnecessary fields.
  402. func deleteWebhook(bean *Webhook) (err error) {
  403. sess := x.NewSession()
  404. defer sess.Close()
  405. if err = sess.Begin(); err != nil {
  406. return err
  407. }
  408. if count, err := sess.Delete(bean); err != nil {
  409. return err
  410. } else if count == 0 {
  411. return ErrWebhookNotExist{ID: bean.ID}
  412. } else if _, err = sess.Delete(&HookTask{HookID: bean.ID}); err != nil {
  413. return err
  414. }
  415. return sess.Commit()
  416. }
  417. // DeleteWebhookByRepoID deletes webhook of repository by given ID.
  418. func DeleteWebhookByRepoID(repoID, id int64) error {
  419. return deleteWebhook(&Webhook{
  420. ID: id,
  421. RepoID: repoID,
  422. })
  423. }
  424. // DeleteWebhookByOrgID deletes webhook of organization by given ID.
  425. func DeleteWebhookByOrgID(orgID, id int64) error {
  426. return deleteWebhook(&Webhook{
  427. ID: id,
  428. OrgID: orgID,
  429. })
  430. }
  431. // DeleteDefaultSystemWebhook deletes an admin-configured default or system webhook (where Org and Repo ID both 0)
  432. func DeleteDefaultSystemWebhook(id int64) error {
  433. sess := x.NewSession()
  434. defer sess.Close()
  435. if err := sess.Begin(); err != nil {
  436. return err
  437. }
  438. count, err := sess.
  439. Where("repo_id=? AND org_id=?", 0, 0).
  440. Delete(&Webhook{ID: id})
  441. if err != nil {
  442. return err
  443. } else if count == 0 {
  444. return ErrWebhookNotExist{ID: id}
  445. }
  446. if _, err := sess.Delete(&HookTask{HookID: id}); err != nil {
  447. return err
  448. }
  449. return sess.Commit()
  450. }
  451. // copyDefaultWebhooksToRepo creates copies of the default webhooks in a new repo
  452. func copyDefaultWebhooksToRepo(e Engine, repoID int64) error {
  453. ws, err := getDefaultWebhooks(e)
  454. if err != nil {
  455. return fmt.Errorf("GetDefaultWebhooks: %v", err)
  456. }
  457. for _, w := range ws {
  458. w.ID = 0
  459. w.RepoID = repoID
  460. if err := createWebhook(e, w); err != nil {
  461. return fmt.Errorf("CreateWebhook: %v", err)
  462. }
  463. }
  464. return nil
  465. }
  466. // ___ ___ __ ___________ __
  467. // / | \ ____ ____ | | _\__ ___/____ _____| | __
  468. // / ~ \/ _ \ / _ \| |/ / | | \__ \ / ___/ |/ /
  469. // \ Y ( <_> | <_> ) < | | / __ \_\___ \| <
  470. // \___|_ / \____/ \____/|__|_ \ |____| (____ /____ >__|_ \
  471. // \/ \/ \/ \/ \/
  472. // HookTaskType is the type of an hook task
  473. type HookTaskType = string
  474. // Types of hook tasks
  475. const (
  476. GITEA HookTaskType = "gitea"
  477. GOGS HookTaskType = "gogs"
  478. SLACK HookTaskType = "slack"
  479. DISCORD HookTaskType = "discord"
  480. DINGTALK HookTaskType = "dingtalk"
  481. TELEGRAM HookTaskType = "telegram"
  482. MSTEAMS HookTaskType = "msteams"
  483. FEISHU HookTaskType = "feishu"
  484. MATRIX HookTaskType = "matrix"
  485. )
  486. // HookEventType is the type of an hook event
  487. type HookEventType string
  488. // Types of hook events
  489. const (
  490. HookEventCreate HookEventType = "create"
  491. HookEventDelete HookEventType = "delete"
  492. HookEventFork HookEventType = "fork"
  493. HookEventPush HookEventType = "push"
  494. HookEventIssues HookEventType = "issues"
  495. HookEventIssueAssign HookEventType = "issue_assign"
  496. HookEventIssueLabel HookEventType = "issue_label"
  497. HookEventIssueMilestone HookEventType = "issue_milestone"
  498. HookEventIssueComment HookEventType = "issue_comment"
  499. HookEventPullRequest HookEventType = "pull_request"
  500. HookEventPullRequestAssign HookEventType = "pull_request_assign"
  501. HookEventPullRequestLabel HookEventType = "pull_request_label"
  502. HookEventPullRequestMilestone HookEventType = "pull_request_milestone"
  503. HookEventPullRequestComment HookEventType = "pull_request_comment"
  504. HookEventPullRequestReviewApproved HookEventType = "pull_request_review_approved"
  505. HookEventPullRequestReviewRejected HookEventType = "pull_request_review_rejected"
  506. HookEventPullRequestReviewComment HookEventType = "pull_request_review_comment"
  507. HookEventPullRequestSync HookEventType = "pull_request_sync"
  508. HookEventRepository HookEventType = "repository"
  509. HookEventRelease HookEventType = "release"
  510. )
  511. // Event returns the HookEventType as an event string
  512. func (h HookEventType) Event() string {
  513. switch h {
  514. case HookEventCreate:
  515. return "create"
  516. case HookEventDelete:
  517. return "delete"
  518. case HookEventFork:
  519. return "fork"
  520. case HookEventPush:
  521. return "push"
  522. case HookEventIssues, HookEventIssueAssign, HookEventIssueLabel, HookEventIssueMilestone:
  523. return "issues"
  524. case HookEventPullRequest, HookEventPullRequestAssign, HookEventPullRequestLabel, HookEventPullRequestMilestone,
  525. HookEventPullRequestSync:
  526. return "pull_request"
  527. case HookEventIssueComment, HookEventPullRequestComment:
  528. return "issue_comment"
  529. case HookEventPullRequestReviewApproved:
  530. return "pull_request_approved"
  531. case HookEventPullRequestReviewRejected:
  532. return "pull_request_rejected"
  533. case HookEventPullRequestReviewComment:
  534. return "pull_request_comment"
  535. case HookEventRepository:
  536. return "repository"
  537. case HookEventRelease:
  538. return "release"
  539. }
  540. return ""
  541. }
  542. // HookRequest represents hook task request information.
  543. type HookRequest struct {
  544. Headers map[string]string `json:"headers"`
  545. }
  546. // HookResponse represents hook task response information.
  547. type HookResponse struct {
  548. Status int `json:"status"`
  549. Headers map[string]string `json:"headers"`
  550. Body string `json:"body"`
  551. }
  552. // HookTask represents a hook task.
  553. type HookTask struct {
  554. ID int64 `xorm:"pk autoincr"`
  555. RepoID int64 `xorm:"INDEX"`
  556. HookID int64
  557. UUID string
  558. Typ HookTaskType
  559. URL string `xorm:"TEXT"`
  560. Signature string `xorm:"TEXT"`
  561. api.Payloader `xorm:"-"`
  562. PayloadContent string `xorm:"TEXT"`
  563. HTTPMethod string `xorm:"http_method"`
  564. ContentType HookContentType
  565. EventType HookEventType
  566. IsSSL bool
  567. IsDelivered bool
  568. Delivered int64
  569. DeliveredString string `xorm:"-"`
  570. // History info.
  571. IsSucceed bool
  572. RequestContent string `xorm:"TEXT"`
  573. RequestInfo *HookRequest `xorm:"-"`
  574. ResponseContent string `xorm:"TEXT"`
  575. ResponseInfo *HookResponse `xorm:"-"`
  576. }
  577. // BeforeUpdate will be invoked by XORM before updating a record
  578. // representing this object
  579. func (t *HookTask) BeforeUpdate() {
  580. if t.RequestInfo != nil {
  581. t.RequestContent = t.simpleMarshalJSON(t.RequestInfo)
  582. }
  583. if t.ResponseInfo != nil {
  584. t.ResponseContent = t.simpleMarshalJSON(t.ResponseInfo)
  585. }
  586. }
  587. // AfterLoad updates the webhook object upon setting a column
  588. func (t *HookTask) AfterLoad() {
  589. t.DeliveredString = time.Unix(0, t.Delivered).Format("2006-01-02 15:04:05 MST")
  590. if len(t.RequestContent) == 0 {
  591. return
  592. }
  593. t.RequestInfo = &HookRequest{}
  594. if err := json.Unmarshal([]byte(t.RequestContent), t.RequestInfo); err != nil {
  595. log.Error("Unmarshal RequestContent[%d]: %v", t.ID, err)
  596. }
  597. if len(t.ResponseContent) > 0 {
  598. t.ResponseInfo = &HookResponse{}
  599. if err := json.Unmarshal([]byte(t.ResponseContent), t.ResponseInfo); err != nil {
  600. log.Error("Unmarshal ResponseContent[%d]: %v", t.ID, err)
  601. }
  602. }
  603. }
  604. func (t *HookTask) simpleMarshalJSON(v interface{}) string {
  605. p, err := json.Marshal(v)
  606. if err != nil {
  607. log.Error("Marshal [%d]: %v", t.ID, err)
  608. }
  609. return string(p)
  610. }
  611. // HookTasks returns a list of hook tasks by given conditions.
  612. func HookTasks(hookID int64, page int) ([]*HookTask, error) {
  613. tasks := make([]*HookTask, 0, setting.Webhook.PagingNum)
  614. return tasks, x.
  615. Limit(setting.Webhook.PagingNum, (page-1)*setting.Webhook.PagingNum).
  616. Where("hook_id=?", hookID).
  617. Desc("id").
  618. Find(&tasks)
  619. }
  620. // CreateHookTask creates a new hook task,
  621. // it handles conversion from Payload to PayloadContent.
  622. func CreateHookTask(t *HookTask) error {
  623. return createHookTask(x, t)
  624. }
  625. func createHookTask(e Engine, t *HookTask) error {
  626. data, err := t.Payloader.JSONPayload()
  627. if err != nil {
  628. return err
  629. }
  630. t.UUID = gouuid.New().String()
  631. t.PayloadContent = string(data)
  632. _, err = e.Insert(t)
  633. return err
  634. }
  635. // UpdateHookTask updates information of hook task.
  636. func UpdateHookTask(t *HookTask) error {
  637. _, err := x.ID(t.ID).AllCols().Update(t)
  638. return err
  639. }
  640. // FindUndeliveredHookTasks represents find the undelivered hook tasks
  641. func FindUndeliveredHookTasks() ([]*HookTask, error) {
  642. tasks := make([]*HookTask, 0, 10)
  643. if err := x.Where("is_delivered=?", false).Find(&tasks); err != nil {
  644. return nil, err
  645. }
  646. return tasks, nil
  647. }
  648. // FindRepoUndeliveredHookTasks represents find the undelivered hook tasks of one repository
  649. func FindRepoUndeliveredHookTasks(repoID int64) ([]*HookTask, error) {
  650. tasks := make([]*HookTask, 0, 5)
  651. if err := x.Where("repo_id=? AND is_delivered=?", repoID, false).Find(&tasks); err != nil {
  652. return nil, err
  653. }
  654. return tasks, nil
  655. }