|
@ -0,0 +1,394 @@ |
|
|
|
|
|
// 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" |
|
|
|
|
|
|
|
|
|
|
|
"code.gitea.io/gitea/models" |
|
|
|
|
|
"code.gitea.io/gitea/modules/context" |
|
|
|
|
|
api "code.gitea.io/gitea/modules/structs" |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
// GetIssueCommentReactions list reactions of a issue comment
|
|
|
|
|
|
func GetIssueCommentReactions(ctx *context.APIContext) { |
|
|
|
|
|
// swagger:operation GET /repos/{owner}/{repo}/issues/comments/{id}/reactions issue issueGetCommentReactions
|
|
|
|
|
|
// ---
|
|
|
|
|
|
// summary: Get a list reactions of a issue 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
|
|
|
|
|
|
// format: int64
|
|
|
|
|
|
// required: true
|
|
|
|
|
|
// responses:
|
|
|
|
|
|
// "200":
|
|
|
|
|
|
// "$ref": "#/responses/ReactionResponseList"
|
|
|
|
|
|
comment, err := models.GetCommentByID(ctx.ParamsInt64(":id")) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
if models.IsErrCommentNotExist(err) { |
|
|
|
|
|
ctx.NotFound(err) |
|
|
|
|
|
} else { |
|
|
|
|
|
ctx.Error(500, "GetCommentByID", err) |
|
|
|
|
|
} |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if !ctx.Repo.CanRead(models.UnitTypeIssues) && !ctx.User.IsAdmin { |
|
|
|
|
|
ctx.Error(403, "GetIssueCommentReactions", errors.New("no permission to get reactions")) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
reactions, err := models.FindCommentReactions(comment) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
ctx.Error(500, "FindIssueReactions", err) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
_, err = reactions.LoadUsers() |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
ctx.Error(500, "ReactionList.LoadUsers()", err) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var result []api.ReactionResponse |
|
|
|
|
|
for _, r := range reactions { |
|
|
|
|
|
result = append(result, api.ReactionResponse{ |
|
|
|
|
|
User: r.User.APIFormat(), |
|
|
|
|
|
Reaction: r.Type, |
|
|
|
|
|
Created: r.CreatedUnix.AsTime(), |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ctx.JSON(200, result) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// PostIssueCommentReaction add a reaction to a comment of a issue
|
|
|
|
|
|
func PostIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOption) { |
|
|
|
|
|
// swagger:operation POST /repos/{owner}/{repo}/issues/comments/{id}/reactions issue issuePostCommentReaction
|
|
|
|
|
|
// ---
|
|
|
|
|
|
// summary: Add a reaction to a comment of a issue 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
|
|
|
|
|
|
// format: int64
|
|
|
|
|
|
// required: true
|
|
|
|
|
|
// - name: content
|
|
|
|
|
|
// in: body
|
|
|
|
|
|
// schema:
|
|
|
|
|
|
// "$ref": "#/definitions/EditReactionOption"
|
|
|
|
|
|
// responses:
|
|
|
|
|
|
// "201":
|
|
|
|
|
|
// "$ref": "#/responses/ReactionResponse"
|
|
|
|
|
|
changeIssueCommentReaction(ctx, form, true) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// DeleteIssueCommentReaction list reactions of a issue comment
|
|
|
|
|
|
func DeleteIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOption) { |
|
|
|
|
|
// swagger:operation DELETE /repos/{owner}/{repo}/issues/comments/{id}/reactions issue issueDeleteCommentReaction
|
|
|
|
|
|
// ---
|
|
|
|
|
|
// summary: Remove a reaction from a comment of a issue 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
|
|
|
|
|
|
// format: int64
|
|
|
|
|
|
// required: true
|
|
|
|
|
|
// - name: content
|
|
|
|
|
|
// in: body
|
|
|
|
|
|
// schema:
|
|
|
|
|
|
// "$ref": "#/definitions/EditReactionOption"
|
|
|
|
|
|
// responses:
|
|
|
|
|
|
// "200":
|
|
|
|
|
|
// "$ref": "#/responses/empty"
|
|
|
|
|
|
changeIssueCommentReaction(ctx, form, false) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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 { |
|
|
|
|
|
ctx.Error(500, "GetCommentByID", err) |
|
|
|
|
|
} |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
err = comment.LoadIssue() |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
ctx.Error(500, "comment.LoadIssue() failed", err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if comment.Issue.IsLocked && !ctx.Repo.CanWrite(models.UnitTypeIssues) && !ctx.User.IsAdmin { |
|
|
|
|
|
ctx.Error(403, "ChangeIssueCommentReaction", errors.New("no permission to change reaction")) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if isCreateType { |
|
|
|
|
|
// PostIssueCommentReaction part
|
|
|
|
|
|
reaction, err := models.CreateCommentReaction(ctx.User, comment.Issue, comment, form.Reaction) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
if models.IsErrForbiddenIssueReaction(err) { |
|
|
|
|
|
ctx.Error(403, err.Error(), err) |
|
|
|
|
|
} else { |
|
|
|
|
|
ctx.Error(500, "CreateCommentReaction", err) |
|
|
|
|
|
} |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
_, err = reaction.LoadUser() |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
ctx.Error(500, "Reaction.LoadUser()", err) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ctx.JSON(201, api.ReactionResponse{ |
|
|
|
|
|
User: reaction.User.APIFormat(), |
|
|
|
|
|
Reaction: reaction.Type, |
|
|
|
|
|
Created: reaction.CreatedUnix.AsTime(), |
|
|
|
|
|
}) |
|
|
|
|
|
} else { |
|
|
|
|
|
// DeleteIssueCommentReaction part
|
|
|
|
|
|
err = models.DeleteCommentReaction(ctx.User, comment.Issue, comment, form.Reaction) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
ctx.Error(500, "DeleteCommentReaction", err) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
ctx.Status(200) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GetIssueReactions list reactions of a issue comment
|
|
|
|
|
|
func GetIssueReactions(ctx *context.APIContext) { |
|
|
|
|
|
// swagger:operation GET /repos/{owner}/{repo}/issues/{index}/reactions issue issueGetIssueReactions
|
|
|
|
|
|
// ---
|
|
|
|
|
|
// summary: Get a list reactions of a 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
|
|
|
|
|
|
// - name: index
|
|
|
|
|
|
// in: path
|
|
|
|
|
|
// description: index of the issue
|
|
|
|
|
|
// type: integer
|
|
|
|
|
|
// format: int64
|
|
|
|
|
|
// required: true
|
|
|
|
|
|
// responses:
|
|
|
|
|
|
// "200":
|
|
|
|
|
|
// "$ref": "#/responses/ReactionResponseList"
|
|
|
|
|
|
issue, err := models.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
if models.IsErrIssueNotExist(err) { |
|
|
|
|
|
ctx.NotFound() |
|
|
|
|
|
} else { |
|
|
|
|
|
ctx.Error(500, "GetIssueByIndex", err) |
|
|
|
|
|
} |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if !ctx.Repo.CanRead(models.UnitTypeIssues) && !ctx.User.IsAdmin { |
|
|
|
|
|
ctx.Error(403, "GetIssueReactions", errors.New("no permission to get reactions")) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
reactions, err := models.FindIssueReactions(issue) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
ctx.Error(500, "FindIssueReactions", err) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
_, err = reactions.LoadUsers() |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
ctx.Error(500, "ReactionList.LoadUsers()", err) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var result []api.ReactionResponse |
|
|
|
|
|
for _, r := range reactions { |
|
|
|
|
|
result = append(result, api.ReactionResponse{ |
|
|
|
|
|
User: r.User.APIFormat(), |
|
|
|
|
|
Reaction: r.Type, |
|
|
|
|
|
Created: r.CreatedUnix.AsTime(), |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ctx.JSON(200, result) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// PostIssueReaction add a reaction to a comment of a issue
|
|
|
|
|
|
func PostIssueReaction(ctx *context.APIContext, form api.EditReactionOption) { |
|
|
|
|
|
// swagger:operation POST /repos/{owner}/{repo}/issues/{index}/reactions issue issuePostIssueReaction
|
|
|
|
|
|
// ---
|
|
|
|
|
|
// summary: Add a reaction to a comment of a 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
|
|
|
|
|
|
// - name: index
|
|
|
|
|
|
// in: path
|
|
|
|
|
|
// description: index of the issue
|
|
|
|
|
|
// type: integer
|
|
|
|
|
|
// format: int64
|
|
|
|
|
|
// required: true
|
|
|
|
|
|
// - name: content
|
|
|
|
|
|
// in: body
|
|
|
|
|
|
// schema:
|
|
|
|
|
|
// "$ref": "#/definitions/EditReactionOption"
|
|
|
|
|
|
// responses:
|
|
|
|
|
|
// "201":
|
|
|
|
|
|
// "$ref": "#/responses/ReactionResponse"
|
|
|
|
|
|
changeIssueReaction(ctx, form, true) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// DeleteIssueReaction list reactions of a issue comment
|
|
|
|
|
|
func DeleteIssueReaction(ctx *context.APIContext, form api.EditReactionOption) { |
|
|
|
|
|
// swagger:operation DELETE /repos/{owner}/{repo}/issues/{index}/reactions issue issueDeleteIssueReaction
|
|
|
|
|
|
// ---
|
|
|
|
|
|
// summary: Remove a reaction from a comment of a 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
|
|
|
|
|
|
// - 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"
|
|
|
|
|
|
changeIssueReaction(ctx, form, false) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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 { |
|
|
|
|
|
ctx.Error(500, "GetIssueByIndex", err) |
|
|
|
|
|
} |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if issue.IsLocked && !ctx.Repo.CanWrite(models.UnitTypeIssues) && !ctx.User.IsAdmin { |
|
|
|
|
|
ctx.Error(403, "ChangeIssueCommentReaction", errors.New("no permission to change reaction")) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if isCreateType { |
|
|
|
|
|
// PostIssueReaction part
|
|
|
|
|
|
reaction, err := models.CreateIssueReaction(ctx.User, issue, form.Reaction) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
if models.IsErrForbiddenIssueReaction(err) { |
|
|
|
|
|
ctx.Error(403, err.Error(), err) |
|
|
|
|
|
} else { |
|
|
|
|
|
ctx.Error(500, "CreateCommentReaction", err) |
|
|
|
|
|
} |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
_, err = reaction.LoadUser() |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
ctx.Error(500, "Reaction.LoadUser()", err) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ctx.JSON(201, api.ReactionResponse{ |
|
|
|
|
|
User: reaction.User.APIFormat(), |
|
|
|
|
|
Reaction: reaction.Type, |
|
|
|
|
|
Created: reaction.CreatedUnix.AsTime(), |
|
|
|
|
|
}) |
|
|
|
|
|
} else { |
|
|
|
|
|
// DeleteIssueReaction part
|
|
|
|
|
|
err = models.DeleteIssueReaction(ctx.User, issue, form.Reaction) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
ctx.Error(500, "DeleteIssueReaction", err) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
ctx.Status(200) |
|
|
|
|
|
} |
|
|
|
|
|
} |