2018-03-06 04:22:16 +03:00
// 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 (
2019-12-20 20:07:12 +03:00
"net/http"
2018-03-29 16:32:40 +03:00
"strings"
2018-03-06 04:22:16 +03:00
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
2019-09-27 05:24:06 +03:00
"code.gitea.io/gitea/modules/log"
2018-03-06 04:22:16 +03:00
"code.gitea.io/gitea/modules/setting"
2019-05-11 13:21:34 +03:00
api "code.gitea.io/gitea/modules/structs"
2019-08-23 19:40:30 +03:00
"code.gitea.io/gitea/modules/upload"
2018-03-06 04:22:16 +03:00
)
// 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
2018-10-21 06:40:42 +03:00
// format: int64
2018-03-06 04:22:16 +03:00
// required: true
// - name: attachment_id
// in: path
// description: id of the attachment to get
// type: integer
2018-10-21 06:40:42 +03:00
// format: int64
2018-03-06 04:22:16 +03:00
// required: true
// responses:
// "200":
// "$ref": "#/responses/Attachment"
2019-12-20 20:07:12 +03:00
2018-03-06 04:22:16 +03:00
releaseID := ctx . ParamsInt64 ( ":id" )
attachID := ctx . ParamsInt64 ( ":asset" )
attach , err := models . GetAttachmentByID ( attachID )
if err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "GetAttachmentByID" , err )
2018-03-06 04:22:16 +03:00
return
}
if attach . ReleaseID != releaseID {
2019-09-27 05:24:06 +03:00
log . Info ( "User requested attachment is not in release, release_id %v, attachment_id: %v" , releaseID , attachID )
2019-03-19 05:29:43 +03:00
ctx . NotFound ( )
2018-03-06 04:22:16 +03:00
return
}
// FIXME Should prove the existence of the given repo, but results in unnecessary database requests
2019-12-20 20:07:12 +03:00
ctx . JSON ( http . StatusOK , attach . APIFormat ( ) )
2018-03-06 04:22:16 +03:00
}
// 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
2018-10-21 06:40:42 +03:00
// format: int64
2018-03-06 04:22:16 +03:00
// required: true
// responses:
// "200":
// "$ref": "#/responses/AttachmentList"
2019-12-20 20:07:12 +03:00
2018-03-06 04:22:16 +03:00
releaseID := ctx . ParamsInt64 ( ":id" )
release , err := models . GetReleaseByID ( releaseID )
if err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "GetReleaseByID" , err )
2018-03-06 04:22:16 +03:00
return
}
if release . RepoID != ctx . Repo . Repository . ID {
2019-03-19 05:29:43 +03:00
ctx . NotFound ( )
2018-03-06 04:22:16 +03:00
return
}
if err := release . LoadAttributes ( ) ; err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "LoadAttributes" , err )
2018-03-06 04:22:16 +03:00
return
}
2019-12-20 20:07:12 +03:00
ctx . JSON ( http . StatusOK , release . APIFormat ( ) . Attachments )
2018-03-06 04:22:16 +03:00
}
// 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
2018-10-21 06:40:42 +03:00
// format: int64
2018-03-06 04:22:16 +03:00
// 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"
2019-12-20 20:07:12 +03:00
// "400":
// "$ref": "#/responses/error"
2018-03-06 04:22:16 +03:00
// Check if attachments are enabled
2020-08-18 07:23:45 +03:00
if ! setting . Attachment . Enabled {
2019-03-19 05:29:43 +03:00
ctx . NotFound ( "Attachment is not enabled" )
2018-03-06 04:22:16 +03:00
return
}
// Check if release exists an load release
releaseID := ctx . ParamsInt64 ( ":id" )
release , err := models . GetReleaseByID ( releaseID )
if err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "GetReleaseByID" , err )
2018-03-06 04:22:16 +03:00
return
}
// Get uploaded file from request
file , header , err := ctx . GetFile ( "attachment" )
if err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "GetFile" , err )
2018-03-06 04:22:16 +03:00
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
2020-08-18 07:23:45 +03:00
err = upload . VerifyAllowedContentType ( buf , strings . Split ( setting . Attachment . AllowedTypes , "," ) )
2019-07-07 05:25:05 +03:00
if err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusBadRequest , "DetectContentType" , err )
2018-03-06 04:22:16 +03:00
return
}
var filename = header . Filename
if query := ctx . Query ( "name" ) ; query != "" {
filename = query
}
// Create a new attachment and save the file
2019-04-02 22:25:05 +03:00
attach , err := models . NewAttachment ( & models . Attachment {
UploaderID : ctx . User . ID ,
Name : filename ,
ReleaseID : release . ID ,
} , buf , file )
2018-03-06 04:22:16 +03:00
if err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "NewAttachment" , err )
2018-03-06 04:22:16 +03:00
return
}
2019-04-02 22:25:05 +03:00
2019-12-20 20:07:12 +03:00
ctx . JSON ( http . StatusCreated , attach . APIFormat ( ) )
2018-03-06 04:22:16 +03:00
}
// 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
2018-10-21 06:40:42 +03:00
// format: int64
2018-03-06 04:22:16 +03:00
// required: true
// - name: attachment_id
// in: path
// description: id of the attachment to edit
// type: integer
2018-10-21 06:40:42 +03:00
// format: int64
2018-03-06 04:22:16 +03:00
// 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" )
2019-09-27 05:24:06 +03:00
attachID := ctx . ParamsInt64 ( ":asset" )
2018-03-06 04:22:16 +03:00
attach , err := models . GetAttachmentByID ( attachID )
if err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "GetAttachmentByID" , err )
2018-03-06 04:22:16 +03:00
return
}
if attach . ReleaseID != releaseID {
2019-09-27 05:24:06 +03:00
log . Info ( "User requested attachment is not in release, release_id %v, attachment_id: %v" , releaseID , attachID )
2019-03-19 05:29:43 +03:00
ctx . NotFound ( )
2018-03-06 04:22:16 +03:00
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 {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "UpdateAttachment" , attach )
2018-03-06 04:22:16 +03:00
}
2019-12-20 20:07:12 +03:00
ctx . JSON ( http . StatusCreated , attach . APIFormat ( ) )
2018-03-06 04:22:16 +03:00
}
// 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
2018-10-21 06:40:42 +03:00
// format: int64
2018-03-06 04:22:16 +03:00
// required: true
// - name: attachment_id
// in: path
// description: id of the attachment to delete
// type: integer
2018-10-21 06:40:42 +03:00
// format: int64
2018-03-06 04:22:16 +03:00
// required: true
// responses:
// "204":
// "$ref": "#/responses/empty"
// Check if release exists an load release
releaseID := ctx . ParamsInt64 ( ":id" )
2019-09-27 05:24:06 +03:00
attachID := ctx . ParamsInt64 ( ":asset" )
2018-03-06 04:22:16 +03:00
attach , err := models . GetAttachmentByID ( attachID )
if err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "GetAttachmentByID" , err )
2018-03-06 04:22:16 +03:00
return
}
if attach . ReleaseID != releaseID {
2019-09-27 05:24:06 +03:00
log . Info ( "User requested attachment is not in release, release_id %v, attachment_id: %v" , releaseID , attachID )
2019-03-19 05:29:43 +03:00
ctx . NotFound ( )
2018-03-06 04:22:16 +03:00
return
}
// FIXME Should prove the existence of the given repo, but results in unnecessary database requests
if err := models . DeleteAttachment ( attach , true ) ; err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "DeleteAttachment" , err )
2018-03-06 04:22:16 +03:00
return
}
2019-12-20 20:07:12 +03:00
ctx . Status ( http . StatusNoContent )
2018-03-06 04:22:16 +03:00
}