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 | |
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')
-rw-r--r-- | routers/api/v1/api.go | 1 | ||||
-rw-r--r-- | routers/api/v1/repo/issue_comment.go | 111 | ||||
-rw-r--r-- | routers/api/v1/swagger/issue.go | 7 |
3 files changed, 119 insertions, 0 deletions
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index c587907d4b..7a2347650a 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -842,6 +842,7 @@ func Routes(sessioner func(http.Handler) http.Handler) *web.Route { m.Combo("/{id}", reqToken()).Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueCommentDeprecated). Delete(repo.DeleteIssueCommentDeprecated) }) + m.Get("/timeline", repo.ListIssueCommentsAndTimeline) m.Group("/labels", func() { m.Combo("").Get(repo.ListIssueLabels). Post(reqToken(), bind(api.IssueLabelsOption{}), repo.AddIssueLabels). 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 diff --git a/routers/api/v1/swagger/issue.go b/routers/api/v1/swagger/issue.go index 0f2f572020..09e7077b20 100644 --- a/routers/api/v1/swagger/issue.go +++ b/routers/api/v1/swagger/issue.go @@ -36,6 +36,13 @@ type swaggerResponseCommentList struct { Body []api.Comment `json:"body"` } +// TimelineList +// swagger:response TimelineList +type swaggerResponseTimelineList struct { + // in:body + Body []api.TimelineComment `json:"body"` +} + // Label // swagger:response Label type swaggerResponseLabel struct { |