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 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Copyright 2020 The Gitea Authors.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package repo
  6. import (
  7. "net/http"
  8. "code.gitea.io/gitea/models"
  9. "code.gitea.io/gitea/modules/context"
  10. "code.gitea.io/gitea/modules/convert"
  11. "code.gitea.io/gitea/modules/git"
  12. api "code.gitea.io/gitea/modules/structs"
  13. "code.gitea.io/gitea/modules/web"
  14. "code.gitea.io/gitea/routers/api/v1/utils"
  15. "code.gitea.io/gitea/services/webhook"
  16. )
  17. // ListHooks list all hooks of a repository
  18. func ListHooks(ctx *context.APIContext) {
  19. // swagger:operation GET /repos/{owner}/{repo}/hooks repository repoListHooks
  20. // ---
  21. // summary: List the hooks in a repository
  22. // produces:
  23. // - application/json
  24. // parameters:
  25. // - name: owner
  26. // in: path
  27. // description: owner of the repo
  28. // type: string
  29. // required: true
  30. // - name: repo
  31. // in: path
  32. // description: name of the repo
  33. // type: string
  34. // required: true
  35. // - name: page
  36. // in: query
  37. // description: page number of results to return (1-based)
  38. // type: integer
  39. // - name: limit
  40. // in: query
  41. // description: page size of results
  42. // type: integer
  43. // responses:
  44. // "200":
  45. // "$ref": "#/responses/HookList"
  46. opts := &models.ListWebhookOptions{
  47. ListOptions: utils.GetListOptions(ctx),
  48. RepoID: ctx.Repo.Repository.ID,
  49. }
  50. count, err := models.CountWebhooksByOpts(opts)
  51. if err != nil {
  52. ctx.InternalServerError(err)
  53. return
  54. }
  55. hooks, err := models.ListWebhooksByOpts(opts)
  56. if err != nil {
  57. ctx.InternalServerError(err)
  58. return
  59. }
  60. apiHooks := make([]*api.Hook, len(hooks))
  61. for i := range hooks {
  62. apiHooks[i] = convert.ToHook(ctx.Repo.RepoLink, hooks[i])
  63. }
  64. ctx.SetTotalCountHeader(count)
  65. ctx.JSON(http.StatusOK, &apiHooks)
  66. }
  67. // GetHook get a repo's hook by id
  68. func GetHook(ctx *context.APIContext) {
  69. // swagger:operation GET /repos/{owner}/{repo}/hooks/{id} repository repoGetHook
  70. // ---
  71. // summary: Get a hook
  72. // produces:
  73. // - application/json
  74. // parameters:
  75. // - name: owner
  76. // in: path
  77. // description: owner of the repo
  78. // type: string
  79. // required: true
  80. // - name: repo
  81. // in: path
  82. // description: name of the repo
  83. // type: string
  84. // required: true
  85. // - name: id
  86. // in: path
  87. // description: id of the hook to get
  88. // type: integer
  89. // format: int64
  90. // required: true
  91. // responses:
  92. // "200":
  93. // "$ref": "#/responses/Hook"
  94. // "404":
  95. // "$ref": "#/responses/notFound"
  96. repo := ctx.Repo
  97. hookID := ctx.ParamsInt64(":id")
  98. hook, err := utils.GetRepoHook(ctx, repo.Repository.ID, hookID)
  99. if err != nil {
  100. return
  101. }
  102. ctx.JSON(http.StatusOK, convert.ToHook(repo.RepoLink, hook))
  103. }
  104. // TestHook tests a hook
  105. func TestHook(ctx *context.APIContext) {
  106. // swagger:operation POST /repos/{owner}/{repo}/hooks/{id}/tests repository repoTestHook
  107. // ---
  108. // summary: Test a push webhook
  109. // produces:
  110. // - application/json
  111. // parameters:
  112. // - name: owner
  113. // in: path
  114. // description: owner of the repo
  115. // type: string
  116. // required: true
  117. // - name: repo
  118. // in: path
  119. // description: name of the repo
  120. // type: string
  121. // required: true
  122. // - name: id
  123. // in: path
  124. // description: id of the hook to test
  125. // type: integer
  126. // format: int64
  127. // required: true
  128. // responses:
  129. // "204":
  130. // "$ref": "#/responses/empty"
  131. if ctx.Repo.Commit == nil {
  132. // if repo does not have any commits, then don't send a webhook
  133. ctx.Status(http.StatusNoContent)
  134. return
  135. }
  136. hookID := ctx.ParamsInt64(":id")
  137. hook, err := utils.GetRepoHook(ctx, ctx.Repo.Repository.ID, hookID)
  138. if err != nil {
  139. return
  140. }
  141. commit := convert.ToPayloadCommit(ctx.Repo.Repository, ctx.Repo.Commit)
  142. if err := webhook.PrepareWebhook(hook, ctx.Repo.Repository, models.HookEventPush, &api.PushPayload{
  143. Ref: git.BranchPrefix + ctx.Repo.Repository.DefaultBranch,
  144. Before: ctx.Repo.Commit.ID.String(),
  145. After: ctx.Repo.Commit.ID.String(),
  146. Commits: []*api.PayloadCommit{commit},
  147. HeadCommit: commit,
  148. Repo: convert.ToRepo(ctx.Repo.Repository, models.AccessModeNone),
  149. Pusher: convert.ToUserWithAccessMode(ctx.User, models.AccessModeNone),
  150. Sender: convert.ToUserWithAccessMode(ctx.User, models.AccessModeNone),
  151. }); err != nil {
  152. ctx.Error(http.StatusInternalServerError, "PrepareWebhook: ", err)
  153. return
  154. }
  155. ctx.Status(http.StatusNoContent)
  156. }
  157. // CreateHook create a hook for a repository
  158. func CreateHook(ctx *context.APIContext) {
  159. // swagger:operation POST /repos/{owner}/{repo}/hooks repository repoCreateHook
  160. // ---
  161. // summary: Create a hook
  162. // consumes:
  163. // - application/json
  164. // produces:
  165. // - application/json
  166. // parameters:
  167. // - name: owner
  168. // in: path
  169. // description: owner of the repo
  170. // type: string
  171. // required: true
  172. // - name: repo
  173. // in: path
  174. // description: name of the repo
  175. // type: string
  176. // required: true
  177. // - name: body
  178. // in: body
  179. // schema:
  180. // "$ref": "#/definitions/CreateHookOption"
  181. // responses:
  182. // "201":
  183. // "$ref": "#/responses/Hook"
  184. form := web.GetForm(ctx).(*api.CreateHookOption)
  185. if !utils.CheckCreateHookOption(ctx, form) {
  186. return
  187. }
  188. utils.AddRepoHook(ctx, form)
  189. }
  190. // EditHook modify a hook of a repository
  191. func EditHook(ctx *context.APIContext) {
  192. // swagger:operation PATCH /repos/{owner}/{repo}/hooks/{id} repository repoEditHook
  193. // ---
  194. // summary: Edit a hook in a repository
  195. // produces:
  196. // - application/json
  197. // parameters:
  198. // - name: owner
  199. // in: path
  200. // description: owner of the repo
  201. // type: string
  202. // required: true
  203. // - name: repo
  204. // in: path
  205. // description: name of the repo
  206. // type: string
  207. // required: true
  208. // - name: id
  209. // in: path
  210. // description: index of the hook
  211. // type: integer
  212. // format: int64
  213. // required: true
  214. // - name: body
  215. // in: body
  216. // schema:
  217. // "$ref": "#/definitions/EditHookOption"
  218. // responses:
  219. // "200":
  220. // "$ref": "#/responses/Hook"
  221. form := web.GetForm(ctx).(*api.EditHookOption)
  222. hookID := ctx.ParamsInt64(":id")
  223. utils.EditRepoHook(ctx, form, hookID)
  224. }
  225. // DeleteHook delete a hook of a repository
  226. func DeleteHook(ctx *context.APIContext) {
  227. // swagger:operation DELETE /repos/{owner}/{repo}/hooks/{id} repository repoDeleteHook
  228. // ---
  229. // summary: Delete a hook in a repository
  230. // produces:
  231. // - application/json
  232. // parameters:
  233. // - name: owner
  234. // in: path
  235. // description: owner of the repo
  236. // type: string
  237. // required: true
  238. // - name: repo
  239. // in: path
  240. // description: name of the repo
  241. // type: string
  242. // required: true
  243. // - name: id
  244. // in: path
  245. // description: id of the hook to delete
  246. // type: integer
  247. // format: int64
  248. // required: true
  249. // responses:
  250. // "204":
  251. // "$ref": "#/responses/empty"
  252. // "404":
  253. // "$ref": "#/responses/notFound"
  254. if err := models.DeleteWebhookByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")); err != nil {
  255. if models.IsErrWebhookNotExist(err) {
  256. ctx.NotFound()
  257. } else {
  258. ctx.Error(http.StatusInternalServerError, "DeleteWebhookByRepoID", err)
  259. }
  260. return
  261. }
  262. ctx.Status(http.StatusNoContent)
  263. }