diff options
author | Jonas Franz <info@jonasfranz.software> | 2018-03-06 02:22:16 +0100 |
---|---|---|
committer | Bo-Yi Wu <appleboy.tw@gmail.com> | 2018-03-06 09:22:16 +0800 |
commit | 9a5e628a7e8bc8e7de6ed05f3621442de3388086 (patch) | |
tree | 07bd2cc6c22bae9ea976f5c23359d9b5cbf0bd8c /routers/api/v1/repo/release_attachment.go | |
parent | 69ea5e438538863056af3bd70d182096b68f0d4a (diff) | |
download | gitea-9a5e628a7e8bc8e7de6ed05f3621442de3388086.tar.gz gitea-9a5e628a7e8bc8e7de6ed05f3621442de3388086.zip |
Add Attachment API (#3478)
* Add Attachment API
* repos/:owner/:repo/releases (add attachments)
* repos/:owner/:repo/releases/:id (add attachments)
* repos/:owner/:repo/releases/:id/attachments
* repos/:owner/:repo/releases/:id/attachments/:attachment_id
Signed-off-by: Jonas Franz <info@jonasfranz.de>
* Add unit tests for new attachment functions
Fix comments
Signed-off-by: Jonas Franz <info@jonasfranz.software>
* fix lint
* Update vendor.json
Signed-off-by: Jonas Franz <info@jonasfranz.software>
* remove version of sdk
Signed-off-by: Jonas Franz <info@jonasfranz.software>
* Fix unit tests
Add missing license header
Signed-off-by: Jonas Franz <info@jonasfranz.software>
* Add CreateReleaseAttachment
Add EditReleaseAttachment
Add DeleteReleaseAttachment
Signed-off-by: Jonas Franz <info@jonasfranz.software>
* Add filename query parameter for choosing another name for an attachment
Signed-off-by: Jonas Franz <info@jonasfranz.software>
* Fix order of imports
Signed-off-by: Jonas Franz <info@jonasfranz.software>
* Restricting updatable attachment columns
Signed-off-by: Jonas Franz <info@jonasfranz.software>
* gofmt
Signed-off-by: Jonas Franz <info@jonasfranz.software>
* Update go-sdk
Replace Attachments with Assets
Signed-off-by: Jonas Franz <info@jonasfranz.de>
* Update go-sdk
Signed-off-by: Jonas Franz <info@jonasfranz.de>
* Updating go-sdk and regenerating swagger
Signed-off-by: Jonas Franz <info@jonasfranz.software>
* Add missing file of go-sdk
Signed-off-by: Jonas Franz <info@jonasfranz.software>
* Change origin of code.gitea.io/sdk to code.gitea.io/sdk
Update code.gitea.io/sdk
Signed-off-by: Jonas Franz <info@jonasfranz.software>
* Update swagger
Signed-off-by: Jonas Franz <info@jonasfranz.software>
* Update updateAttachment
Diffstat (limited to 'routers/api/v1/repo/release_attachment.go')
-rw-r--r-- | routers/api/v1/repo/release_attachment.go | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go new file mode 100644 index 0000000000..80b2064df0 --- /dev/null +++ b/routers/api/v1/repo/release_attachment.go @@ -0,0 +1,322 @@ +// Copyright 2018 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package repo + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/setting" + api "code.gitea.io/sdk/gitea" + "errors" + "net/http" + "strings" +) + +// GetReleaseAttachment gets a single attachment of the release +func GetReleaseAttachment(ctx *context.APIContext) { + // swagger:operation GET /repos/{owner}/{repo}/releases/{id}/assets/{attachment_id} repository repoGetReleaseAttachment + // --- + // summary: Get a release attachment + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: id + // in: path + // description: id of the release + // type: integer + // required: true + // - name: attachment_id + // in: path + // description: id of the attachment to get + // type: integer + // required: true + // responses: + // "200": + // "$ref": "#/responses/Attachment" + releaseID := ctx.ParamsInt64(":id") + attachID := ctx.ParamsInt64(":asset") + attach, err := models.GetAttachmentByID(attachID) + if err != nil { + ctx.Error(500, "GetAttachmentByID", err) + return + } + if attach.ReleaseID != releaseID { + ctx.Status(404) + return + } + // FIXME Should prove the existence of the given repo, but results in unnecessary database requests + ctx.JSON(200, attach.APIFormat()) +} + +// ListReleaseAttachments lists all attachments of the release +func ListReleaseAttachments(ctx *context.APIContext) { + // swagger:operation GET /repos/{owner}/{repo}/releases/{id}/assets repository repoListReleaseAttachments + // --- + // summary: List release's attachments + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: id + // in: path + // description: id of the release + // type: integer + // required: true + // responses: + // "200": + // "$ref": "#/responses/AttachmentList" + releaseID := ctx.ParamsInt64(":id") + release, err := models.GetReleaseByID(releaseID) + if err != nil { + ctx.Error(500, "GetReleaseByID", err) + return + } + if release.RepoID != ctx.Repo.Repository.ID { + ctx.Status(404) + return + } + if err := release.LoadAttributes(); err != nil { + ctx.Error(500, "LoadAttributes", err) + return + } + ctx.JSON(200, release.APIFormat().Attachments) +} + +// CreateReleaseAttachment creates an attachment and saves the given file +func CreateReleaseAttachment(ctx *context.APIContext) { + // swagger:operation POST /repos/{owner}/{repo}/releases/{id}/assets repository repoCreateReleaseAttachment + // --- + // summary: Create a release attachment + // produces: + // - application/json + // consumes: + // - multipart/form-data + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: id + // in: path + // description: id of the release + // type: integer + // required: true + // - name: name + // in: query + // description: name of the attachment + // type: string + // required: false + // - name: attachment + // in: formData + // description: attachment to upload + // type: file + // required: true + // responses: + // "201": + // "$ref": "#/responses/Attachment" + + // Check if attachments are enabled + if !setting.AttachmentEnabled { + ctx.Error(404, "AttachmentEnabled", errors.New("attachment is not enabled")) + return + } + + // Check if release exists an load release + releaseID := ctx.ParamsInt64(":id") + release, err := models.GetReleaseByID(releaseID) + if err != nil { + ctx.Error(500, "GetReleaseByID", err) + return + } + + // Get uploaded file from request + file, header, err := ctx.GetFile("attachment") + if err != nil { + ctx.Error(500, "GetFile", err) + return + } + defer file.Close() + + buf := make([]byte, 1024) + n, _ := file.Read(buf) + if n > 0 { + buf = buf[:n] + } + + // Check if the filetype is allowed by the settings + fileType := http.DetectContentType(buf) + + allowedTypes := strings.Split(setting.AttachmentAllowedTypes, ",") + allowed := false + for _, t := range allowedTypes { + t := strings.Trim(t, " ") + if t == "*/*" || t == fileType { + allowed = true + break + } + } + + if !allowed { + ctx.Error(400, "DetectContentType", errors.New("File type is not allowed")) + return + } + + var filename = header.Filename + if query := ctx.Query("name"); query != "" { + filename = query + } + + // Create a new attachment and save the file + attach, err := models.NewAttachment(filename, buf, file) + if err != nil { + ctx.Error(500, "NewAttachment", err) + return + } + attach.ReleaseID = release.ID + if err := models.UpdateAttachment(attach); err != nil { + ctx.Error(500, "UpdateAttachment", err) + return + } + ctx.JSON(201, attach.APIFormat()) +} + +// EditReleaseAttachment updates the given attachment +func EditReleaseAttachment(ctx *context.APIContext, form api.EditAttachmentOptions) { + // swagger:operation PATCH /repos/{owner}/{repo}/releases/{id}/assets/{attachment_id} repository repoEditReleaseAttachment + // --- + // summary: Edit a release attachment + // produces: + // - application/json + // consumes: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: id + // in: path + // description: id of the release + // type: integer + // required: true + // - name: attachment_id + // in: path + // description: id of the attachment to edit + // type: integer + // required: true + // - name: body + // in: body + // schema: + // "$ref": "#/definitions/EditAttachmentOptions" + // responses: + // "201": + // "$ref": "#/responses/Attachment" + + // Check if release exists an load release + releaseID := ctx.ParamsInt64(":id") + attachID := ctx.ParamsInt64(":attachment") + attach, err := models.GetAttachmentByID(attachID) + if err != nil { + ctx.Error(500, "GetAttachmentByID", err) + return + } + if attach.ReleaseID != releaseID { + ctx.Status(404) + return + } + // FIXME Should prove the existence of the given repo, but results in unnecessary database requests + if form.Name != "" { + attach.Name = form.Name + } + + if err := models.UpdateAttachment(attach); err != nil { + ctx.Error(500, "UpdateAttachment", attach) + } + ctx.JSON(201, attach.APIFormat()) +} + +// DeleteReleaseAttachment delete a given attachment +func DeleteReleaseAttachment(ctx *context.APIContext) { + // swagger:operation DELETE /repos/{owner}/{repo}/releases/{id}/assets/{attachment_id} repository repoDeleteReleaseAttachment + // --- + // summary: Delete a release attachment + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: id + // in: path + // description: id of the release + // type: integer + // required: true + // - name: attachment_id + // in: path + // description: id of the attachment to delete + // type: integer + // required: true + // responses: + // "204": + // "$ref": "#/responses/empty" + + // Check if release exists an load release + releaseID := ctx.ParamsInt64(":id") + attachID := ctx.ParamsInt64(":attachment") + attach, err := models.GetAttachmentByID(attachID) + if err != nil { + ctx.Error(500, "GetAttachmentByID", err) + return + } + if attach.ReleaseID != releaseID { + ctx.Status(404) + return + } + // FIXME Should prove the existence of the given repo, but results in unnecessary database requests + + if err := models.DeleteAttachment(attach, true); err != nil { + ctx.Error(500, "DeleteAttachment", err) + return + } + ctx.Status(204) +} |