2019-12-07 23:04:19 +01:00
// Copyright 2019 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 (
"errors"
2019-12-20 18:07:12 +01:00
"net/http"
2019-12-07 23:04:19 +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-12-07 23:04:19 +01:00
api "code.gitea.io/gitea/modules/structs"
2021-01-26 23:36:53 +08:00
"code.gitea.io/gitea/modules/web"
2020-01-24 19:00:29 +00:00
"code.gitea.io/gitea/routers/api/v1/utils"
2019-12-07 23:04:19 +01:00
)
2020-01-06 05:58:13 +01:00
// GetIssueCommentReactions list reactions of a comment from an issue
2019-12-07 23:04:19 +01:00
func GetIssueCommentReactions ( ctx * context . APIContext ) {
// swagger:operation GET /repos/{owner}/{repo}/issues/comments/{id}/reactions issue issueGetCommentReactions
// ---
2020-01-06 05:58:13 +01:00
// summary: Get a list of reactions from a comment of an issue
2019-12-07 23:04:19 +01:00
// 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
// format: int64
// required: true
// responses:
// "200":
2019-12-31 09:21:21 +01:00
// "$ref": "#/responses/ReactionList"
2019-12-20 18:07:12 +01:00
// "403":
// "$ref": "#/responses/forbidden"
2019-12-07 23:04:19 +01:00
comment , err := models . GetCommentByID ( ctx . ParamsInt64 ( ":id" ) )
if err != nil {
if models . IsErrCommentNotExist ( err ) {
ctx . NotFound ( err )
} else {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "GetCommentByID" , err )
2019-12-07 23:04:19 +01:00
}
return
}
2020-10-29 12:48:07 +00:00
if err := comment . LoadIssue ( ) ; err != nil {
ctx . Error ( http . StatusInternalServerError , "comment.LoadIssue" , err )
}
if ! ctx . Repo . CanReadIssuesOrPulls ( comment . Issue . IsPull ) {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusForbidden , "GetIssueCommentReactions" , errors . New ( "no permission to get reactions" ) )
2019-12-07 23:04:19 +01:00
return
}
2021-12-15 06:39:34 +01:00
reactions , _ , err := models . FindCommentReactions ( comment )
2019-12-07 23:04:19 +01:00
if err != nil {
2021-12-15 06:39:34 +01:00
ctx . Error ( http . StatusInternalServerError , "FindCommentReactions" , err )
2019-12-07 23:04:19 +01:00
return
}
2020-01-15 19:14:07 +08:00
_ , err = reactions . LoadUsers ( ctx . Repo . Repository )
2019-12-07 23:04:19 +01:00
if err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "ReactionList.LoadUsers()" , err )
2019-12-07 23:04:19 +01:00
return
}
2019-12-31 09:21:21 +01:00
var result [ ] api . Reaction
2019-12-07 23:04:19 +01:00
for _ , r := range reactions {
2019-12-31 09:21:21 +01:00
result = append ( result , api . Reaction {
2022-03-22 08:03:22 +01:00
User : convert . ToUser ( r . User , ctx . Doer ) ,
2019-12-07 23:04:19 +01:00
Reaction : r . Type ,
Created : r . CreatedUnix . AsTime ( ) ,
} )
}
2019-12-20 18:07:12 +01:00
ctx . JSON ( http . StatusOK , result )
2019-12-07 23:04:19 +01:00
}
2020-01-06 05:58:13 +01:00
// PostIssueCommentReaction add a reaction to a comment of an issue
2021-01-26 23:36:53 +08:00
func PostIssueCommentReaction ( ctx * context . APIContext ) {
2019-12-07 23:04:19 +01:00
// swagger:operation POST /repos/{owner}/{repo}/issues/comments/{id}/reactions issue issuePostCommentReaction
// ---
2020-01-06 05:58:13 +01:00
// summary: Add a reaction to a comment of an issue
2019-12-07 23:04:19 +01:00
// 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
// format: int64
// required: true
// - name: content
// in: body
// schema:
// "$ref": "#/definitions/EditReactionOption"
// responses:
2019-12-31 09:21:21 +01:00
// "200":
// "$ref": "#/responses/Reaction"
2019-12-07 23:04:19 +01:00
// "201":
2019-12-31 09:21:21 +01:00
// "$ref": "#/responses/Reaction"
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 . EditReactionOption )
changeIssueCommentReaction ( ctx , * form , true )
2019-12-07 23:04:19 +01:00
}
2020-01-06 05:58:13 +01:00
// DeleteIssueCommentReaction remove a reaction from a comment of an issue
2021-01-26 23:36:53 +08:00
func DeleteIssueCommentReaction ( ctx * context . APIContext ) {
2019-12-07 23:04:19 +01:00
// swagger:operation DELETE /repos/{owner}/{repo}/issues/comments/{id}/reactions issue issueDeleteCommentReaction
// ---
2020-01-06 05:58:13 +01:00
// summary: Remove a reaction from a comment of an issue
2019-12-07 23:04:19 +01:00
// 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
// format: int64
// required: true
// - name: content
// in: body
// schema:
// "$ref": "#/definitions/EditReactionOption"
// responses:
// "200":
// "$ref": "#/responses/empty"
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 . EditReactionOption )
changeIssueCommentReaction ( ctx , * form , false )
2019-12-07 23:04:19 +01:00
}
func changeIssueCommentReaction ( ctx * context . APIContext , form api . EditReactionOption , isCreateType bool ) {
comment , err := models . GetCommentByID ( ctx . ParamsInt64 ( ":id" ) )
if err != nil {
if models . IsErrCommentNotExist ( err ) {
ctx . NotFound ( err )
} else {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "GetCommentByID" , err )
2019-12-07 23:04:19 +01:00
}
return
}
err = comment . LoadIssue ( )
if err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "comment.LoadIssue() failed" , err )
2019-12-07 23:04:19 +01:00
}
2020-01-20 20:00:32 +08:00
if comment . Issue . IsLocked && ! ctx . Repo . CanWriteIssuesOrPulls ( comment . Issue . IsPull ) {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusForbidden , "ChangeIssueCommentReaction" , errors . New ( "no permission to change reaction" ) )
2019-12-07 23:04:19 +01:00
return
}
if isCreateType {
// PostIssueCommentReaction part
2022-03-22 08:03:22 +01:00
reaction , err := models . CreateCommentReaction ( ctx . Doer , comment . Issue , comment , form . Reaction )
2019-12-07 23:04:19 +01:00
if err != nil {
if models . IsErrForbiddenIssueReaction ( err ) {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusForbidden , err . Error ( ) , err )
2019-12-31 09:21:21 +01:00
} else if models . IsErrReactionAlreadyExist ( err ) {
ctx . JSON ( http . StatusOK , api . Reaction {
2022-03-22 08:03:22 +01:00
User : convert . ToUser ( ctx . Doer , ctx . Doer ) ,
2019-12-31 09:21:21 +01:00
Reaction : reaction . Type ,
Created : reaction . CreatedUnix . AsTime ( ) ,
} )
2019-12-07 23:04:19 +01:00
} else {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "CreateCommentReaction" , err )
2019-12-07 23:04:19 +01:00
}
return
}
2019-12-31 09:21:21 +01:00
ctx . JSON ( http . StatusCreated , api . Reaction {
2022-03-22 08:03:22 +01:00
User : convert . ToUser ( ctx . Doer , ctx . Doer ) ,
2019-12-07 23:04:19 +01:00
Reaction : reaction . Type ,
Created : reaction . CreatedUnix . AsTime ( ) ,
} )
} else {
// DeleteIssueCommentReaction part
2022-03-22 08:03:22 +01:00
err = models . DeleteCommentReaction ( ctx . Doer , comment . Issue , comment , form . Reaction )
2019-12-07 23:04:19 +01:00
if err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "DeleteCommentReaction" , err )
2019-12-07 23:04:19 +01:00
return
}
2022-01-20 18:46:10 +01:00
// ToDo respond 204
2019-12-20 18:07:12 +01:00
ctx . Status ( http . StatusOK )
2019-12-07 23:04:19 +01:00
}
}
2020-01-06 05:58:13 +01:00
// GetIssueReactions list reactions of an issue
2019-12-07 23:04:19 +01:00
func GetIssueReactions ( ctx * context . APIContext ) {
// swagger:operation GET /repos/{owner}/{repo}/issues/{index}/reactions issue issueGetIssueReactions
// ---
2020-01-06 05:58:13 +01:00
// summary: Get a list reactions of an issue
2019-12-07 23:04:19 +01:00
// 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: index of the issue
// type: integer
// format: int64
// required: true
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
2019-12-07 23:04:19 +01:00
// responses:
// "200":
2019-12-31 09:21:21 +01:00
// "$ref": "#/responses/ReactionList"
2019-12-20 18:07:12 +01:00
// "403":
// "$ref": "#/responses/forbidden"
2019-12-07 23:04:19 +01:00
issue , err := models . GetIssueWithAttrsByIndex ( ctx . Repo . Repository . ID , ctx . ParamsInt64 ( ":index" ) )
if err != nil {
if models . IsErrIssueNotExist ( err ) {
ctx . NotFound ( )
} else {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "GetIssueByIndex" , err )
2019-12-07 23:04:19 +01:00
}
return
}
2020-10-29 02:23:31 +00:00
if ! ctx . Repo . CanReadIssuesOrPulls ( issue . IsPull ) {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusForbidden , "GetIssueReactions" , errors . New ( "no permission to get reactions" ) )
2019-12-07 23:04:19 +01:00
return
}
2021-12-15 06:39:34 +01:00
reactions , count , err := models . FindIssueReactions ( issue , utils . GetListOptions ( ctx ) )
2019-12-07 23:04:19 +01:00
if err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "FindIssueReactions" , err )
2019-12-07 23:04:19 +01:00
return
}
2020-01-15 19:14:07 +08:00
_ , err = reactions . LoadUsers ( ctx . Repo . Repository )
2019-12-07 23:04:19 +01:00
if err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "ReactionList.LoadUsers()" , err )
2019-12-07 23:04:19 +01:00
return
}
2019-12-31 09:21:21 +01:00
var result [ ] api . Reaction
2019-12-07 23:04:19 +01:00
for _ , r := range reactions {
2019-12-31 09:21:21 +01:00
result = append ( result , api . Reaction {
2022-03-22 08:03:22 +01:00
User : convert . ToUser ( r . User , ctx . Doer ) ,
2019-12-07 23:04:19 +01:00
Reaction : r . Type ,
Created : r . CreatedUnix . AsTime ( ) ,
} )
}
2021-12-15 06:39:34 +01:00
ctx . SetTotalCountHeader ( count )
2019-12-20 18:07:12 +01:00
ctx . JSON ( http . StatusOK , result )
2019-12-07 23:04:19 +01:00
}
2020-01-06 05:58:13 +01:00
// PostIssueReaction add a reaction to an issue
2021-01-26 23:36:53 +08:00
func PostIssueReaction ( ctx * context . APIContext ) {
2019-12-07 23:04:19 +01:00
// swagger:operation POST /repos/{owner}/{repo}/issues/{index}/reactions issue issuePostIssueReaction
// ---
2020-01-06 05:58:13 +01:00
// summary: Add a reaction to an issue
2019-12-07 23:04:19 +01:00
// 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: index of the issue
// type: integer
// format: int64
// required: true
// - name: content
// in: body
// schema:
// "$ref": "#/definitions/EditReactionOption"
// responses:
2019-12-31 09:21:21 +01:00
// "200":
// "$ref": "#/responses/Reaction"
2019-12-07 23:04:19 +01:00
// "201":
2019-12-31 09:21:21 +01:00
// "$ref": "#/responses/Reaction"
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 . EditReactionOption )
changeIssueReaction ( ctx , * form , true )
2019-12-07 23:04:19 +01:00
}
2020-01-06 05:58:13 +01:00
// DeleteIssueReaction remove a reaction from an issue
2021-01-26 23:36:53 +08:00
func DeleteIssueReaction ( ctx * context . APIContext ) {
2019-12-07 23:04:19 +01:00
// swagger:operation DELETE /repos/{owner}/{repo}/issues/{index}/reactions issue issueDeleteIssueReaction
// ---
2020-01-06 05:58:13 +01:00
// summary: Remove a reaction from an issue
2019-12-07 23:04:19 +01:00
// 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: index of the issue
// type: integer
// format: int64
// required: true
// - name: content
// in: body
// schema:
// "$ref": "#/definitions/EditReactionOption"
// responses:
// "200":
// "$ref": "#/responses/empty"
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 . EditReactionOption )
changeIssueReaction ( ctx , * form , false )
2019-12-07 23:04:19 +01:00
}
func changeIssueReaction ( ctx * context . APIContext , form api . EditReactionOption , isCreateType bool ) {
issue , err := models . GetIssueWithAttrsByIndex ( ctx . Repo . Repository . ID , ctx . ParamsInt64 ( ":index" ) )
if err != nil {
if models . IsErrIssueNotExist ( err ) {
ctx . NotFound ( )
} else {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "GetIssueByIndex" , err )
2019-12-07 23:04:19 +01:00
}
return
}
2020-01-20 20:00:32 +08:00
if issue . IsLocked && ! ctx . Repo . CanWriteIssuesOrPulls ( issue . IsPull ) {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusForbidden , "ChangeIssueCommentReaction" , errors . New ( "no permission to change reaction" ) )
2019-12-07 23:04:19 +01:00
return
}
if isCreateType {
// PostIssueReaction part
2022-03-22 08:03:22 +01:00
reaction , err := models . CreateIssueReaction ( ctx . Doer , issue , form . Reaction )
2019-12-07 23:04:19 +01:00
if err != nil {
if models . IsErrForbiddenIssueReaction ( err ) {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusForbidden , err . Error ( ) , err )
2019-12-31 09:21:21 +01:00
} else if models . IsErrReactionAlreadyExist ( err ) {
ctx . JSON ( http . StatusOK , api . Reaction {
2022-03-22 08:03:22 +01:00
User : convert . ToUser ( ctx . Doer , ctx . Doer ) ,
2019-12-31 09:21:21 +01:00
Reaction : reaction . Type ,
Created : reaction . CreatedUnix . AsTime ( ) ,
} )
2019-12-07 23:04:19 +01:00
} else {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "CreateCommentReaction" , err )
2019-12-07 23:04:19 +01:00
}
return
}
2019-12-31 09:21:21 +01:00
ctx . JSON ( http . StatusCreated , api . Reaction {
2022-03-22 08:03:22 +01:00
User : convert . ToUser ( ctx . Doer , ctx . Doer ) ,
2019-12-07 23:04:19 +01:00
Reaction : reaction . Type ,
Created : reaction . CreatedUnix . AsTime ( ) ,
} )
} else {
// DeleteIssueReaction part
2022-03-22 08:03:22 +01:00
err = models . DeleteIssueReaction ( ctx . Doer , issue , form . Reaction )
2019-12-07 23:04:19 +01:00
if err != nil {
2019-12-20 18:07:12 +01:00
ctx . Error ( http . StatusInternalServerError , "DeleteIssueReaction" , err )
2019-12-07 23:04:19 +01:00
return
}
2022-01-20 18:46:10 +01:00
// ToDo respond 204
2019-12-20 18:07:12 +01:00
ctx . Status ( http . StatusOK )
2019-12-07 23:04:19 +01:00
}
}