diff options
author | qwerty287 <80460567+qwerty287@users.noreply.github.com> | 2022-01-01 15:12:25 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-01 22:12:25 +0800 |
commit | 7db2f110adbd020e70c56497306cfbda8806d109 (patch) | |
tree | 2f5372cc0f1ffde0abb2899b8e262ee33fb84601 /routers/api/v1/repo | |
parent | 549fd03c0e9aa19850c8271cbd7cd62bbc884b34 (diff) | |
download | gitea-7db2f110adbd020e70c56497306cfbda8806d109.tar.gz gitea-7db2f110adbd020e70c56497306cfbda8806d109.zip |
Add API to get issue/pull comments and events (timeline) (#17403)
* Add API to get issue/pull comments and events (timeline)
Adds an API to get both comments and events in one endpoint with all required data.
Closes go-gitea/gitea#13250
* Fix swagger
* Don't show code comments (use review api instead)
* fmt
* Fix comment
* Time -> TrackedTime
* Use var directly
* Add logger
* Fix lint
* Fix test
* Add comments
* fmt
* [test] get issue directly by ID
* Update test
* Add description for changed refs
* Fix build issues + lint
* Fix build
* Use string enums
* Update swagger
* Support `page` and `limit` params
* fmt + swagger
* Use global slices
Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Diffstat (limited to 'routers/api/v1/repo')
-rw-r--r-- | routers/api/v1/repo/issue_comment.go | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 13e7de46b1..b929cec373 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -10,6 +10,8 @@ import ( "net/http" "code.gitea.io/gitea/models" + repo_model "code.gitea.io/gitea/models/repo" + user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" @@ -102,6 +104,115 @@ func ListIssueComments(ctx *context.APIContext) { ctx.JSON(http.StatusOK, &apiComments) } +// ListIssueCommentsAndTimeline list all the comments and events of an issue +func ListIssueCommentsAndTimeline(ctx *context.APIContext) { + // swagger:operation GET /repos/{owner}/{repo}/issues/{index}/timeline issue issueGetCommentsAndTimeline + // --- + // summary: List all comments and events 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 + // - name: index + // in: path + // description: index of the issue + // type: integer + // format: int64 + // required: true + // - name: since + // in: query + // description: if provided, only comments updated since the specified time are returned. + // type: string + // format: date-time + // - name: page + // in: query + // description: page number of results to return (1-based) + // type: integer + // - name: limit + // in: query + // description: page size of results + // type: integer + // - name: before + // in: query + // description: if provided, only comments updated before the provided time are returned. + // type: string + // format: date-time + // responses: + // "200": + // "$ref": "#/responses/TimelineList" + + before, since, err := utils.GetQueryBeforeSince(ctx) + if err != nil { + ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) + return + } + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + if err != nil { + ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err) + return + } + issue.Repo = ctx.Repo.Repository + + opts := &models.FindCommentsOptions{ + ListOptions: utils.GetListOptions(ctx), + IssueID: issue.ID, + Since: since, + Before: before, + Type: models.CommentTypeUnknown, + } + + comments, err := models.FindComments(opts) + if err != nil { + ctx.Error(http.StatusInternalServerError, "FindComments", err) + return + } + + if err := models.CommentList(comments).LoadPosters(); err != nil { + ctx.Error(http.StatusInternalServerError, "LoadPosters", err) + return + } + + var apiComments []*api.TimelineComment + for _, comment := range comments { + if comment.Type != models.CommentTypeCode && isXRefCommentAccessible(ctx.User, comment, issue.RepoID) { + comment.Issue = issue + apiComments = append(apiComments, convert.ToTimelineComment(comment, ctx.User)) + } + } + + ctx.SetTotalCountHeader(int64(len(apiComments))) + ctx.JSON(http.StatusOK, &apiComments) +} + +func isXRefCommentAccessible(user *user_model.User, c *models.Comment, issueRepoID int64) bool { + // Remove comments that the user has no permissions to see + if models.CommentTypeIsRef(c.Type) && c.RefRepoID != issueRepoID && c.RefRepoID != 0 { + var err error + // Set RefRepo for description in template + c.RefRepo, err = repo_model.GetRepositoryByID(c.RefRepoID) + if err != nil { + return false + } + perm, err := models.GetUserRepoPermission(c.RefRepo, user) + if err != nil { + return false + } + if !perm.CanReadIssuesOrPulls(c.RefIsPull) { + return false + } + } + return true +} + // ListRepoIssueComments returns all issue-comments for a repo func ListRepoIssueComments(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/issues/comments issue issueGetRepoComments |