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