2016-08-27 01:23:21 +07:00
// Copyright 2015 The Gogs Authors. All rights reserved.
2020-01-24 19:00:29 +00:00
// Copyright 2020 The Gitea Authors.
2016-08-27 01:23:21 +07:00
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2016-11-24 15:04:31 +08:00
2016-08-27 01:23:21 +07:00
package repo
import (
2019-02-18 21:55:04 +01:00
"errors"
2019-12-20 18:07:12 +01:00
"net/http"
2016-08-27 01:23:21 +07:00
2016-11-10 17:24:48 +01:00
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
2020-10-17 06:23:08 +02:00
"code.gitea.io/gitea/modules/convert"
2019-05-11 18:21:34 +08:00
api "code.gitea.io/gitea/modules/structs"
2021-01-26 23:36:53 +08:00
"code.gitea.io/gitea/modules/web"
2020-01-13 17:02:24 +01:00
"code.gitea.io/gitea/routers/api/v1/utils"
2019-09-25 01:39:50 +08:00
comment_service "code.gitea.io/gitea/services/comments"
2016-08-27 01:23:21 +07:00
)
2016-11-24 15:04:31 +08:00
// ListIssueComments list all the comments of an issue
2016-08-27 01:23:21 +07:00
func ListIssueComments ( ctx * context . APIContext ) {
2018-05-08 08:05:18 +02:00
// swagger:operation GET /repos/{owner}/{repo}/issues/{index}/comments issue issueGetComments
2017-11-12 23:02:25 -08:00
// ---
// summary: List all comments on an issue
// 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
2018-06-12 16:59:22 +02:00
// - name: index
2017-11-12 23:02:25 -08:00
// in: path
// description: index of the issue
// type: integer
2018-10-21 04:40:42 +01:00
// format: int64
2017-11-12 23:02:25 -08:00
// required: true
2018-07-12 16:40:41 +03:00
// - name: since
2017-11-12 23:02:25 -08:00
// in: query
// description: if provided, only comments updated since the specified time are returned.
// type: string
2020-01-13 17:02:24 +01:00
// format: date-time
// - name: before
// in: query
// description: if provided, only comments updated before the provided time are returned.
// type: string
// format: date-time
2017-11-12 23:02:25 -08:00
// responses:
// "200":
// "$ref": "#/responses/CommentList"
2019-12-20 18:07:12 +01:00
2020-01-13 17:02:24 +01:00
before , since , err := utils . GetQueryBeforeSince ( ctx )
if err != nil {
2020-11-14 15:05:40 +01:00
ctx . Error ( http . StatusUnprocessableEntity , "GetQueryBeforeSince" , err )
2020-01-13 17:02:24 +01:00
return
2016-08-26 13:40:53 -07:00
}
2018-12-13 23:55:43 +08:00
issue , err := models . GetIssueByIndex ( ctx . Repo . Repository . ID , ctx . ParamsInt64 ( ":index" ) )
2016-08-27 01:23:21 +07:00
if err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "GetRawIssueByIndex" , err )
2016-08-27 01:23:21 +07:00
return
}
2019-04-18 13:00:03 +08:00
issue . Repo = ctx . Repo . Repository
2016-08-27 01:23:21 +07:00
2017-06-21 09:00:44 +08:00
comments , err := models . FindComments ( models . FindCommentsOptions {
IssueID : issue . ID ,
2020-01-13 17:02:24 +01:00
Since : since ,
Before : before ,
2017-06-21 09:00:44 +08:00
Type : models . CommentTypeComment ,
} )
2016-08-26 13:40:53 -07:00
if err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "FindComments" , err )
2016-08-26 13:40:53 -07:00
return
2016-08-27 01:23:21 +07:00
}
2019-04-18 13:00:03 +08:00
if err := models . CommentList ( comments ) . LoadPosters ( ) ; err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "LoadPosters" , err )
2018-12-13 23:55:43 +08:00
return
}
2019-04-18 13:00:03 +08:00
apiComments := make ( [ ] * api . Comment , len ( comments ) )
for i , comment := range comments {
comment . Issue = issue
2020-10-17 06:23:08 +02:00
apiComments [ i ] = convert . ToComment ( comments [ i ] )
2016-08-27 01:23:21 +07:00
}
2019-12-20 18:07:12 +01:00
ctx . JSON ( http . StatusOK , & apiComments )
2016-08-27 01:23:21 +07:00
}
2017-11-12 23:02:25 -08:00
// ListRepoIssueComments returns all issue-comments for a repo
2016-12-22 09:29:26 +01:00
func ListRepoIssueComments ( ctx * context . APIContext ) {
2017-11-12 23:02:25 -08:00
// swagger:operation GET /repos/{owner}/{repo}/issues/comments issue issueGetRepoComments
// ---
// summary: List all comments in a repository
// 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
2018-07-12 16:40:41 +03:00
// - name: since
2017-11-12 23:02:25 -08:00
// in: query
// description: if provided, only comments updated since the provided time are returned.
// type: string
2020-01-13 17:02:24 +01:00
// format: date-time
// - name: before
// in: query
// description: if provided, only comments updated before the provided time are returned.
// type: string
// format: date-time
2020-01-24 19:00:29 +00:00
// - name: page
// in: query
// description: page number of results to return (1-based)
// type: integer
// - name: limit
// in: query
2020-06-09 06:57:38 +02:00
// description: page size of results
2020-01-24 19:00:29 +00:00
// type: integer
2017-11-12 23:02:25 -08:00
// responses:
// "200":
// "$ref": "#/responses/CommentList"
2019-12-20 18:07:12 +01:00
2020-01-13 17:02:24 +01:00
before , since , err := utils . GetQueryBeforeSince ( ctx )
if err != nil {
2020-11-14 15:05:40 +01:00
ctx . Error ( http . StatusUnprocessableEntity , "GetQueryBeforeSince" , err )
2020-01-13 17:02:24 +01:00
return
2016-12-22 09:29:26 +01:00
}
2017-06-21 09:00:44 +08:00
comments , err := models . FindComments ( models . FindCommentsOptions {
2020-01-24 19:00:29 +00:00
ListOptions : utils . GetListOptions ( ctx ) ,
RepoID : ctx . Repo . Repository . ID ,
Type : models . CommentTypeComment ,
Since : since ,
Before : before ,
2017-06-21 09:00:44 +08:00
} )
2016-12-22 09:29:26 +01:00
if err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "FindComments" , err )
2016-12-22 09:29:26 +01:00
return
}
2018-12-13 23:55:43 +08:00
if err = models . CommentList ( comments ) . LoadPosters ( ) ; err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "LoadPosters" , err )
2018-12-13 23:55:43 +08:00
return
}
2016-12-22 09:29:26 +01:00
apiComments := make ( [ ] * api . Comment , len ( comments ) )
2019-04-18 13:00:03 +08:00
if err := models . CommentList ( comments ) . LoadIssues ( ) ; err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "LoadIssues" , err )
2019-04-18 13:00:03 +08:00
return
}
if err := models . CommentList ( comments ) . LoadPosters ( ) ; err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "LoadPosters" , err )
2019-04-18 13:00:03 +08:00
return
}
if _ , err := models . CommentList ( comments ) . Issues ( ) . LoadRepositories ( ) ; err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "LoadRepositories" , err )
2019-04-18 13:00:03 +08:00
return
}
2016-12-22 09:29:26 +01:00
for i := range comments {
2020-10-17 06:23:08 +02:00
apiComments [ i ] = convert . ToComment ( comments [ i ] )
2016-12-22 09:29:26 +01:00
}
2019-12-20 18:07:12 +01:00
ctx . JSON ( http . StatusOK , & apiComments )
2016-12-22 09:29:26 +01:00
}
2016-11-24 15:04:31 +08:00
// CreateIssueComment create a comment for an issue
2021-01-26 23:36:53 +08:00
func CreateIssueComment ( ctx * context . APIContext ) {
2017-11-12 23:02:25 -08:00
// swagger:operation POST /repos/{owner}/{repo}/issues/{index}/comments issue issueCreateComment
// ---
// summary: Add a comment to an issue
// consumes:
// - application/json
// 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
2018-06-12 16:59:22 +02:00
// - name: index
2017-11-12 23:02:25 -08:00
// in: path
// description: index of the issue
// type: integer
2018-10-21 04:40:42 +01:00
// format: int64
2017-11-12 23:02:25 -08:00
// required: true
// - name: body
// in: body
// schema:
2018-06-15 00:47:13 -07:00
// "$ref": "#/definitions/CreateIssueCommentOption"
2017-11-12 23:02:25 -08:00
// responses:
// "201":
// "$ref": "#/responses/Comment"
2019-12-20 18:07:12 +01:00
// "403":
// "$ref": "#/responses/forbidden"
2021-01-26 23:36:53 +08:00
form := web . GetForm ( ctx ) . ( * api . CreateIssueCommentOption )
2016-08-27 01:23:21 +07:00
issue , err := models . GetIssueByIndex ( ctx . Repo . Repository . ID , ctx . ParamsInt64 ( ":index" ) )
if err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "GetIssueByIndex" , err )
2016-08-27 01:23:21 +07:00
return
}
2020-01-20 20:00:32 +08:00
if issue . IsLocked && ! ctx . Repo . CanWriteIssuesOrPulls ( issue . IsPull ) && ! ctx . User . IsAdmin {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusForbidden , "CreateIssueComment" , errors . New ( ctx . Tr ( "repo.issues.comment_on_locked" ) ) )
2019-02-18 21:55:04 +01:00
return
}
2019-09-25 01:39:50 +08:00
comment , err := comment_service . CreateIssueComment ( ctx . User , ctx . Repo . Repository , issue , form . Body , nil )
2016-08-27 01:23:21 +07:00
if err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "CreateIssueComment" , err )
2016-08-27 01:23:21 +07:00
return
}
2020-10-17 06:23:08 +02:00
ctx . JSON ( http . StatusCreated , convert . ToComment ( comment ) )
2016-08-27 01:23:21 +07:00
}
2020-01-08 08:00:59 +01:00
// GetIssueComment Get a comment by ID
func GetIssueComment ( ctx * context . APIContext ) {
// swagger:operation GET /repos/{owner}/{repo}/issues/comments/{id} issue issueGetComment
// ---
// summary: Get a comment
// consumes:
// - application/json
// 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 comment
// type: integer
// format: int64
// required: true
// responses:
// "200":
// "$ref": "#/responses/Comment"
// "204":
// "$ref": "#/responses/empty"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
comment , err := models . GetCommentByID ( ctx . ParamsInt64 ( ":id" ) )
if err != nil {
if models . IsErrCommentNotExist ( err ) {
ctx . NotFound ( err )
} else {
ctx . Error ( http . StatusInternalServerError , "GetCommentByID" , err )
}
return
}
if err = comment . LoadIssue ( ) ; err != nil {
ctx . InternalServerError ( err )
return
}
if comment . Issue . RepoID != ctx . Repo . Repository . ID {
ctx . Status ( http . StatusNotFound )
return
}
if comment . Type != models . CommentTypeComment {
ctx . Status ( http . StatusNoContent )
return
}
if err := comment . LoadPoster ( ) ; err != nil {
ctx . Error ( http . StatusInternalServerError , "comment.LoadPoster" , err )
return
}
2020-10-17 06:23:08 +02:00
ctx . JSON ( http . StatusOK , convert . ToComment ( comment ) )
2020-01-08 08:00:59 +01:00
}
2016-11-24 15:04:31 +08:00
// EditIssueComment modify a comment of an issue
2021-01-26 23:36:53 +08:00
func EditIssueComment ( ctx * context . APIContext ) {
2017-11-19 23:24:07 -08:00
// swagger:operation PATCH /repos/{owner}/{repo}/issues/comments/{id} issue issueEditComment
2017-11-12 23:02:25 -08:00
// ---
// summary: Edit a comment
// consumes:
// - application/json
// 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 comment to edit
// type: integer
2018-10-21 04:40:42 +01:00
// format: int64
2017-11-12 23:02:25 -08:00
// required: true
// - name: body
// in: body
// schema:
// "$ref": "#/definitions/EditIssueCommentOption"
// responses:
// "200":
// "$ref": "#/responses/Comment"
2020-01-08 08:00:59 +01:00
// "204":
// "$ref": "#/responses/empty"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
2021-01-26 23:36:53 +08:00
form := web . GetForm ( ctx ) . ( * api . EditIssueCommentOption )
editIssueComment ( ctx , * form )
2017-11-19 23:24:07 -08:00
}
// EditIssueCommentDeprecated modify a comment of an issue
2021-01-26 23:36:53 +08:00
func EditIssueCommentDeprecated ( ctx * context . APIContext ) {
2017-11-19 23:24:07 -08:00
// swagger:operation PATCH /repos/{owner}/{repo}/issues/{index}/comments/{id} issue issueEditCommentDeprecated
// ---
// summary: Edit a comment
// deprecated: true
// consumes:
// - application/json
// 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: index
// in: path
// description: this parameter is ignored
// type: integer
// required: true
// - name: id
// in: path
// description: id of the comment to edit
// type: integer
2018-10-21 04:40:42 +01:00
// format: int64
2017-11-19 23:24:07 -08:00
// required: true
// - name: body
// in: body
// schema:
// "$ref": "#/definitions/EditIssueCommentOption"
// responses:
// "200":
// "$ref": "#/responses/Comment"
2019-12-20 18:07:12 +01:00
// "204":
// "$ref": "#/responses/empty"
// "403":
// "$ref": "#/responses/forbidden"
2020-01-08 08:00:59 +01:00
// "404":
// "$ref": "#/responses/notFound"
2019-12-20 18:07:12 +01:00
2021-01-26 23:36:53 +08:00
form := web . GetForm ( ctx ) . ( * api . EditIssueCommentOption )
editIssueComment ( ctx , * form )
2017-11-19 23:24:07 -08:00
}
func editIssueComment ( ctx * context . APIContext , form api . EditIssueCommentOption ) {
2016-08-27 01:23:21 +07:00
comment , err := models . GetCommentByID ( ctx . ParamsInt64 ( ":id" ) )
if err != nil {
if models . IsErrCommentNotExist ( err ) {
2019-03-18 21:29:43 -05:00
ctx . NotFound ( err )
2016-08-27 01:23:21 +07:00
} else {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "GetCommentByID" , err )
2016-08-27 01:23:21 +07:00
}
return
}
if ! ctx . IsSigned || ( ctx . User . ID != comment . PosterID && ! ctx . Repo . IsAdmin ( ) ) {
2019-12-20 18:07:12 +01:00
ctx . Status ( http . StatusForbidden )
2016-08-27 01:23:21 +07:00
return
2016-11-07 17:30:04 +01:00
} else if comment . Type != models . CommentTypeComment {
2019-12-20 18:07:12 +01:00
ctx . Status ( http . StatusNoContent )
2016-08-27 01:23:21 +07:00
return
}
2018-05-16 22:01:55 +08:00
oldContent := comment . Content
2016-08-27 01:23:21 +07:00
comment . Content = form . Body
2019-09-25 01:39:50 +08:00
if err := comment_service . UpdateComment ( comment , ctx . User , oldContent ) ; err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "UpdateComment" , err )
2016-08-27 01:23:21 +07:00
return
}
2019-01-17 22:23:22 +08:00
2020-10-17 06:23:08 +02:00
ctx . JSON ( http . StatusOK , convert . ToComment ( comment ) )
2016-08-27 01:23:21 +07:00
}
2016-12-22 09:29:26 +01:00
// DeleteIssueComment delete a comment from an issue
func DeleteIssueComment ( ctx * context . APIContext ) {
2017-11-19 23:24:07 -08:00
// swagger:operation DELETE /repos/{owner}/{repo}/issues/comments/{id} issue issueDeleteComment
// ---
// summary: Delete a comment
// 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 comment to delete
// type: integer
2018-10-21 04:40:42 +01:00
// format: int64
2017-11-19 23:24:07 -08:00
// required: true
// responses:
// "204":
// "$ref": "#/responses/empty"
2019-12-20 18:07:12 +01:00
// "403":
// "$ref": "#/responses/forbidden"
2020-01-08 08:00:59 +01:00
// "404":
// "$ref": "#/responses/notFound"
2019-12-20 18:07:12 +01:00
2017-11-19 23:24:07 -08:00
deleteIssueComment ( ctx )
}
// DeleteIssueCommentDeprecated delete a comment from an issue
func DeleteIssueCommentDeprecated ( ctx * context . APIContext ) {
// swagger:operation DELETE /repos/{owner}/{repo}/issues/{index}/comments/{id} issue issueDeleteCommentDeprecated
2017-11-12 23:02:25 -08:00
// ---
// summary: Delete a comment
2017-11-19 23:24:07 -08:00
// deprecated: true
2017-11-12 23:02:25 -08:00
// 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
2017-11-19 23:24:07 -08:00
// - name: index
// in: path
// description: this parameter is ignored
// type: integer
// required: true
2017-11-12 23:02:25 -08:00
// - name: id
// in: path
// description: id of comment to delete
// type: integer
2018-10-21 04:40:42 +01:00
// format: int64
2017-11-12 23:02:25 -08:00
// required: true
// responses:
// "204":
// "$ref": "#/responses/empty"
2019-12-20 18:07:12 +01:00
// "403":
// "$ref": "#/responses/forbidden"
2020-01-08 08:00:59 +01:00
// "404":
// "$ref": "#/responses/notFound"
2019-12-20 18:07:12 +01:00
2017-11-19 23:24:07 -08:00
deleteIssueComment ( ctx )
}
func deleteIssueComment ( ctx * context . APIContext ) {
2016-12-22 09:29:26 +01:00
comment , err := models . GetCommentByID ( ctx . ParamsInt64 ( ":id" ) )
if err != nil {
if models . IsErrCommentNotExist ( err ) {
2019-03-18 21:29:43 -05:00
ctx . NotFound ( err )
2016-12-22 09:29:26 +01:00
} else {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "GetCommentByID" , err )
2016-12-22 09:29:26 +01:00
}
return
}
if ! ctx . IsSigned || ( ctx . User . ID != comment . PosterID && ! ctx . Repo . IsAdmin ( ) ) {
2019-12-20 18:07:12 +01:00
ctx . Status ( http . StatusForbidden )
2016-12-22 09:29:26 +01:00
return
} else if comment . Type != models . CommentTypeComment {
2019-12-20 18:07:12 +01:00
ctx . Status ( http . StatusNoContent )
2016-12-22 09:29:26 +01:00
return
}
2021-01-22 03:56:19 +01:00
if err = comment_service . DeleteComment ( ctx . User , comment ) ; err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "DeleteCommentByID" , err )
2016-12-22 09:29:26 +01:00
return
}
2019-01-17 22:23:22 +08:00
2019-12-20 18:07:12 +01:00
ctx . Status ( http . StatusNoContent )
2016-12-22 09:29:26 +01:00
}