From 2b79d3fd520c4f8f9d9e61894f3fcca6c2258efe Mon Sep 17 00:00:00 2001 From: Giteabot Date: Mon, 10 Jul 2023 08:56:16 -0400 Subject: [PATCH] For API attachments, use API URL (#25639) (#25814) Backport #25639 by @lunny Fix #25257 Co-authored-by: Lunny Xiao --- models/repo/attachment.go | 7 ---- routers/api/v1/api.go | 6 +-- routers/api/v1/repo/issue_attachment.go | 8 ++-- routers/api/v1/repo/issue_comment.go | 12 +++--- .../api/v1/repo/issue_comment_attachment.go | 10 ++--- routers/api/v1/repo/release.go | 10 ++--- routers/api/v1/repo/release_attachment.go | 14 +++---- routers/api/v1/repo/release_tags.go | 2 +- routers/web/repo/issue.go | 10 ++--- services/actions/notifier.go | 4 +- services/actions/notifier_helper.go | 2 +- services/convert/activity.go | 2 +- services/convert/attachment.go | 40 ++++++++++++++++--- services/convert/issue.go | 19 ++++++++- services/convert/issue_comment.go | 10 ++--- services/convert/release.go | 6 +-- services/webhook/notifier.go | 8 ++-- .../api_comment_attachment_test.go | 3 +- tests/integration/api_comment_test.go | 2 +- 19 files changed, 108 insertions(+), 67 deletions(-) diff --git a/models/repo/attachment.go b/models/repo/attachment.go index 93b83aae8a8..df3b9cd2137 100644 --- a/models/repo/attachment.go +++ b/models/repo/attachment.go @@ -65,13 +65,6 @@ func (a *Attachment) DownloadURL() string { return setting.AppURL + "attachments/" + url.PathEscape(a.UUID) } -// _____ __ __ .__ __ -// / _ \_/ |__/ |______ ____ | |__ _____ ____ _____/ |_ -// / /_\ \ __\ __\__ \ _/ ___\| | \ / \_/ __ \ / \ __\ -// / | \ | | | / __ \\ \___| Y \ Y Y \ ___/| | \ | -// \____|__ /__| |__| (____ /\___ >___| /__|_| /\___ >___| /__| -// \/ \/ \/ \/ \/ \/ \/ - // ErrAttachmentNotExist represents a "AttachmentNotExist" kind of error. type ErrAttachmentNotExist struct { ID int64 diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 52323cef76d..3a1203628a6 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1035,7 +1035,7 @@ func Routes(ctx gocontext.Context) *web.Route { m.Group("/assets", func() { m.Combo("").Get(repo.ListReleaseAttachments). Post(reqToken(), reqRepoWriter(unit.TypeReleases), repo.CreateReleaseAttachment) - m.Combo("/{asset}").Get(repo.GetReleaseAttachment). + m.Combo("/{attachment_id}").Get(repo.GetReleaseAttachment). Patch(reqToken(), reqRepoWriter(unit.TypeReleases), bind(api.EditAttachmentOptions{}), repo.EditReleaseAttachment). Delete(reqToken(), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseAttachment) }) @@ -1176,7 +1176,7 @@ func Routes(ctx gocontext.Context) *web.Route { m.Combo(""). Get(repo.ListIssueCommentAttachments). Post(reqToken(), mustNotBeArchived, repo.CreateIssueCommentAttachment) - m.Combo("/{asset}"). + m.Combo("/{attachment_id}"). Get(repo.GetIssueCommentAttachment). Patch(reqToken(), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueCommentAttachment). Delete(reqToken(), mustNotBeArchived, repo.DeleteIssueCommentAttachment) @@ -1228,7 +1228,7 @@ func Routes(ctx gocontext.Context) *web.Route { m.Combo(""). Get(repo.ListIssueAttachments). Post(reqToken(), mustNotBeArchived, repo.CreateIssueAttachment) - m.Combo("/{asset}"). + m.Combo("/{attachment_id}"). Get(repo.GetIssueAttachment). Patch(reqToken(), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueAttachment). Delete(reqToken(), mustNotBeArchived, repo.DeleteIssueAttachment) diff --git a/routers/api/v1/repo/issue_attachment.go b/routers/api/v1/repo/issue_attachment.go index 92e11386882..779da9fd7f8 100644 --- a/routers/api/v1/repo/issue_attachment.go +++ b/routers/api/v1/repo/issue_attachment.go @@ -64,7 +64,7 @@ func GetIssueAttachment(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, convert.ToAttachment(attach)) + ctx.JSON(http.StatusOK, convert.ToAPIAttachment(ctx.Repo.Repository, attach)) } // ListIssueAttachments lists all attachments of the issue @@ -194,7 +194,7 @@ func CreateIssueAttachment(ctx *context.APIContext) { return } - ctx.JSON(http.StatusCreated, convert.ToAttachment(attachment)) + ctx.JSON(http.StatusCreated, convert.ToAPIAttachment(ctx.Repo.Repository, attachment)) } // EditIssueAttachment updates the given attachment @@ -254,7 +254,7 @@ func EditIssueAttachment(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "UpdateAttachment", err) } - ctx.JSON(http.StatusCreated, convert.ToAttachment(attachment)) + ctx.JSON(http.StatusCreated, convert.ToAPIAttachment(ctx.Repo.Repository, attachment)) } // DeleteIssueAttachment delete a given attachment @@ -332,7 +332,7 @@ func getIssueAttachmentSafeWrite(ctx *context.APIContext) *repo_model.Attachment } func getIssueAttachmentSafeRead(ctx *context.APIContext, issue *issues_model.Issue) *repo_model.Attachment { - attachment, err := repo_model.GetAttachmentByID(ctx, ctx.ParamsInt64("asset")) + attachment, err := repo_model.GetAttachmentByID(ctx, ctx.ParamsInt64("attachment_id")) if err != nil { ctx.NotFoundOrServerError("GetAttachmentByID", repo_model.IsErrAttachmentNotExist, err) return nil diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 5616e255ad8..c2392126db9 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -103,7 +103,7 @@ func ListIssueComments(ctx *context.APIContext) { apiComments := make([]*api.Comment, len(comments)) for i, comment := range comments { comment.Issue = issue - apiComments[i] = convert.ToComment(ctx, comments[i]) + apiComments[i] = convert.ToAPIComment(ctx, ctx.Repo.Repository, comments[i]) } ctx.SetTotalCountHeader(totalCount) @@ -191,7 +191,7 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) { for _, comment := range comments { if comment.Type != issues_model.CommentTypeCode && isXRefCommentAccessible(ctx, ctx.Doer, comment, issue.RepoID) { comment.Issue = issue - apiComments = append(apiComments, convert.ToTimelineComment(ctx, comment, ctx.Doer)) + apiComments = append(apiComments, convert.ToTimelineComment(ctx, issue.Repo, comment, ctx.Doer)) } } @@ -308,7 +308,7 @@ func ListRepoIssueComments(ctx *context.APIContext) { return } for i := range comments { - apiComments[i] = convert.ToComment(ctx, comments[i]) + apiComments[i] = convert.ToAPIComment(ctx, ctx.Repo.Repository, comments[i]) } ctx.SetTotalCountHeader(totalCount) @@ -368,7 +368,7 @@ func CreateIssueComment(ctx *context.APIContext) { return } - ctx.JSON(http.StatusCreated, convert.ToComment(ctx, comment)) + ctx.JSON(http.StatusCreated, convert.ToAPIComment(ctx, ctx.Repo.Repository, comment)) } // GetIssueComment Get a comment by ID @@ -436,7 +436,7 @@ func GetIssueComment(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, convert.ToComment(ctx, comment)) + ctx.JSON(http.StatusOK, convert.ToAPIComment(ctx, ctx.Repo.Repository, comment)) } // EditIssueComment modify a comment of an issue @@ -561,7 +561,7 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) return } - ctx.JSON(http.StatusOK, convert.ToComment(ctx, comment)) + ctx.JSON(http.StatusOK, convert.ToAPIComment(ctx, ctx.Repo.Repository, comment)) } // DeleteIssueComment delete a comment from an issue diff --git a/routers/api/v1/repo/issue_comment_attachment.go b/routers/api/v1/repo/issue_comment_attachment.go index 6fe4dbc9771..121e3f10e0d 100644 --- a/routers/api/v1/repo/issue_comment_attachment.go +++ b/routers/api/v1/repo/issue_comment_attachment.go @@ -68,7 +68,7 @@ func GetIssueCommentAttachment(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, convert.ToAttachment(attachment)) + ctx.JSON(http.StatusOK, convert.ToAPIAttachment(ctx.Repo.Repository, attachment)) } // ListIssueCommentAttachments lists all attachments of the comment @@ -110,7 +110,7 @@ func ListIssueCommentAttachments(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, convert.ToAttachments(comment.Attachments)) + ctx.JSON(http.StatusOK, convert.ToAPIAttachments(ctx.Repo.Repository, comment.Attachments)) } // CreateIssueCommentAttachment creates an attachment and saves the given file @@ -201,7 +201,7 @@ func CreateIssueCommentAttachment(ctx *context.APIContext) { return } - ctx.JSON(http.StatusCreated, convert.ToAttachment(attachment)) + ctx.JSON(http.StatusCreated, convert.ToAPIAttachment(ctx.Repo.Repository, attachment)) } // EditIssueCommentAttachment updates the given attachment @@ -259,7 +259,7 @@ func EditIssueCommentAttachment(ctx *context.APIContext) { if err := repo_model.UpdateAttachment(ctx, attach); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateAttachment", attach) } - ctx.JSON(http.StatusCreated, convert.ToAttachment(attach)) + ctx.JSON(http.StatusCreated, convert.ToAPIAttachment(ctx.Repo.Repository, attach)) } // DeleteIssueCommentAttachment delete a given attachment @@ -352,7 +352,7 @@ func canUserWriteIssueCommentAttachment(ctx *context.APIContext, comment *issues } func getIssueCommentAttachmentSafeRead(ctx *context.APIContext, comment *issues_model.Comment) *repo_model.Attachment { - attachment, err := repo_model.GetAttachmentByID(ctx, ctx.ParamsInt64("asset")) + attachment, err := repo_model.GetAttachmentByID(ctx, ctx.ParamsInt64("attachment_id")) if err != nil { ctx.NotFoundOrServerError("GetAttachmentByID", repo_model.IsErrAttachmentNotExist, err) return nil diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index e9693dd053b..af7199d1d63 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -64,7 +64,7 @@ func GetRelease(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } - ctx.JSON(http.StatusOK, convert.ToRelease(ctx, release)) + ctx.JSON(http.StatusOK, convert.ToAPIRelease(ctx, ctx.Repo.Repository, release)) } // GetLatestRelease gets the most recent non-prerelease, non-draft release of a repository, sorted by created_at @@ -105,7 +105,7 @@ func GetLatestRelease(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } - ctx.JSON(http.StatusOK, convert.ToRelease(ctx, release)) + ctx.JSON(http.StatusOK, convert.ToAPIRelease(ctx, ctx.Repo.Repository, release)) } // ListReleases list a repository's releases @@ -174,7 +174,7 @@ func ListReleases(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } - rels[i] = convert.ToRelease(ctx, release) + rels[i] = convert.ToAPIRelease(ctx, ctx.Repo.Repository, release) } filteredCount, err := repo_model.CountReleasesByRepoID(ctx.Repo.Repository.ID, opts) @@ -272,7 +272,7 @@ func CreateRelease(ctx *context.APIContext) { return } } - ctx.JSON(http.StatusCreated, convert.ToRelease(ctx, rel)) + ctx.JSON(http.StatusCreated, convert.ToAPIRelease(ctx, ctx.Repo.Repository, rel)) } // EditRelease edit a release @@ -357,7 +357,7 @@ func EditRelease(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } - ctx.JSON(http.StatusOK, convert.ToRelease(ctx, rel)) + ctx.JSON(http.StatusOK, convert.ToAPIRelease(ctx, ctx.Repo.Repository, rel)) } // DeleteRelease delete a release from a repository diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go index 305b2808df5..a7d73acceb9 100644 --- a/routers/api/v1/repo/release_attachment.go +++ b/routers/api/v1/repo/release_attachment.go @@ -52,7 +52,7 @@ func GetReleaseAttachment(ctx *context.APIContext) { // "$ref": "#/responses/Attachment" releaseID := ctx.ParamsInt64(":id") - attachID := ctx.ParamsInt64(":asset") + attachID := ctx.ParamsInt64(":attachment_id") attach, err := repo_model.GetAttachmentByID(ctx, attachID) if err != nil { if repo_model.IsErrAttachmentNotExist(err) { @@ -68,7 +68,7 @@ func GetReleaseAttachment(ctx *context.APIContext) { return } // FIXME Should prove the existence of the given repo, but results in unnecessary database requests - ctx.JSON(http.StatusOK, convert.ToAttachment(attach)) + ctx.JSON(http.StatusOK, convert.ToAPIAttachment(ctx.Repo.Repository, attach)) } // ListReleaseAttachments lists all attachments of the release @@ -117,7 +117,7 @@ func ListReleaseAttachments(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } - ctx.JSON(http.StatusOK, convert.ToRelease(ctx, release).Attachments) + ctx.JSON(http.StatusOK, convert.ToAPIRelease(ctx, ctx.Repo.Repository, release).Attachments) } // CreateReleaseAttachment creates an attachment and saves the given file @@ -209,7 +209,7 @@ func CreateReleaseAttachment(ctx *context.APIContext) { return } - ctx.JSON(http.StatusCreated, convert.ToAttachment(attach)) + ctx.JSON(http.StatusCreated, convert.ToAPIAttachment(ctx.Repo.Repository, attach)) } // EditReleaseAttachment updates the given attachment @@ -256,7 +256,7 @@ func EditReleaseAttachment(ctx *context.APIContext) { // Check if release exists an load release releaseID := ctx.ParamsInt64(":id") - attachID := ctx.ParamsInt64(":asset") + attachID := ctx.ParamsInt64(":attachment_id") attach, err := repo_model.GetAttachmentByID(ctx, attachID) if err != nil { if repo_model.IsErrAttachmentNotExist(err) { @@ -279,7 +279,7 @@ func EditReleaseAttachment(ctx *context.APIContext) { if err := repo_model.UpdateAttachment(ctx, attach); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateAttachment", attach) } - ctx.JSON(http.StatusCreated, convert.ToAttachment(attach)) + ctx.JSON(http.StatusCreated, convert.ToAPIAttachment(ctx.Repo.Repository, attach)) } // DeleteReleaseAttachment delete a given attachment @@ -318,7 +318,7 @@ func DeleteReleaseAttachment(ctx *context.APIContext) { // Check if release exists an load release releaseID := ctx.ParamsInt64(":id") - attachID := ctx.ParamsInt64(":asset") + attachID := ctx.ParamsInt64(":attachment_id") attach, err := repo_model.GetAttachmentByID(ctx, attachID) if err != nil { if repo_model.IsErrAttachmentNotExist(err) { diff --git a/routers/api/v1/repo/release_tags.go b/routers/api/v1/repo/release_tags.go index 051ee8f22ec..a03edfafcf5 100644 --- a/routers/api/v1/repo/release_tags.go +++ b/routers/api/v1/repo/release_tags.go @@ -63,7 +63,7 @@ func GetReleaseByTag(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } - ctx.JSON(http.StatusOK, convert.ToRelease(ctx, release)) + ctx.JSON(http.StatusOK, convert.ToAPIRelease(ctx, ctx.Repo.Repository, release)) } // DeleteReleaseByTag delete a release from a repository by tag name diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 52ccc0efa8a..d436abba2f0 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -2036,7 +2036,7 @@ func GetIssueInfo(ctx *context.Context) { } } - ctx.JSON(http.StatusOK, convert.ToAPIIssue(ctx, issue)) + ctx.JSON(http.StatusOK, convert.ToIssue(ctx, issue)) } // UpdateIssueTitle change issue's title @@ -2541,7 +2541,7 @@ func SearchIssues(ctx *context.Context) { } ctx.SetTotalCountHeader(filteredCount) - ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, issues)) + ctx.JSON(http.StatusOK, convert.ToIssueList(ctx, issues)) } func getUserIDForFilter(ctx *context.Context, queryName string) int64 { @@ -2702,7 +2702,7 @@ func ListIssues(ctx *context.Context) { } ctx.SetTotalCountHeader(filteredCount) - ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, issues)) + ctx.JSON(http.StatusOK, convert.ToIssueList(ctx, issues)) } // UpdateIssueStatus change issue's status @@ -3263,7 +3263,7 @@ func GetIssueAttachments(ctx *context.Context) { } attachments := make([]*api.Attachment, len(issue.Attachments)) for i := 0; i < len(issue.Attachments); i++ { - attachments[i] = convert.ToAttachment(issue.Attachments[i]) + attachments[i] = convert.ToAttachment(ctx.Repo.Repository, issue.Attachments[i]) } ctx.JSON(http.StatusOK, attachments) } @@ -3287,7 +3287,7 @@ func GetCommentAttachments(ctx *context.Context) { return } for i := 0; i < len(comment.Attachments); i++ { - attachments = append(attachments, convert.ToAttachment(comment.Attachments[i])) + attachments = append(attachments, convert.ToAttachment(ctx.Repo.Repository, comment.Attachments[i])) } ctx.JSON(http.StatusOK, attachments) } diff --git a/services/actions/notifier.go b/services/actions/notifier.go index 507eeaacf6c..cfe2e284dac 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -171,7 +171,7 @@ func (n *actionsNotifier) NotifyCreateIssueComment(ctx context.Context, doer *us WithPayload(&api.IssueCommentPayload{ Action: api.HookIssueCommentCreated, Issue: convert.ToAPIIssue(ctx, issue), - Comment: convert.ToComment(ctx, comment), + Comment: convert.ToAPIComment(ctx, repo, comment), Repository: convert.ToRepo(ctx, repo, permission), Sender: convert.ToUser(ctx, doer, nil), IsPull: true, @@ -185,7 +185,7 @@ func (n *actionsNotifier) NotifyCreateIssueComment(ctx context.Context, doer *us WithPayload(&api.IssueCommentPayload{ Action: api.HookIssueCommentCreated, Issue: convert.ToAPIIssue(ctx, issue), - Comment: convert.ToComment(ctx, comment), + Comment: convert.ToAPIComment(ctx, repo, comment), Repository: convert.ToRepo(ctx, repo, permission), Sender: convert.ToUser(ctx, doer, nil), IsPull: false, diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 69c23656f29..b9fe41d449d 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -228,7 +228,7 @@ func notifyRelease(ctx context.Context, doer *user_model.User, rel *repo_model.R WithRef(git.RefNameFromTag(rel.TagName).String()). WithPayload(&api.ReleasePayload{ Action: action, - Release: convert.ToRelease(ctx, rel), + Release: convert.ToAPIRelease(ctx, rel.Repo, rel), Repository: convert.ToRepo(ctx, rel.Repo, permission), Sender: convert.ToUser(ctx, doer, nil), }). diff --git a/services/convert/activity.go b/services/convert/activity.go index 71a2722a493..01fef73e589 100644 --- a/services/convert/activity.go +++ b/services/convert/activity.go @@ -37,7 +37,7 @@ func ToActivity(ctx context.Context, ac *activities_model.Action, doer *user_mod if ac.Comment != nil { result.CommentID = ac.CommentID - result.Comment = ToComment(ctx, ac.Comment) + result.Comment = ToAPIComment(ctx, ac.Repo, ac.Comment) } return result diff --git a/services/convert/attachment.go b/services/convert/attachment.go index ddba181a120..ab36a1c5778 100644 --- a/services/convert/attachment.go +++ b/services/convert/attachment.go @@ -4,12 +4,38 @@ package convert import ( + "strconv" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" ) -// ToAttachment converts models.Attachment to api.Attachment -func ToAttachment(a *repo_model.Attachment) *api.Attachment { +func WebAssetDownloadURL(repo *repo_model.Repository, attach *repo_model.Attachment) string { + return attach.DownloadURL() +} + +func APIAssetDownloadURL(repo *repo_model.Repository, attach *repo_model.Attachment) string { + if attach.CustomDownloadURL != "" { + return attach.CustomDownloadURL + } + + // /repos/{owner}/{repo}/releases/{id}/assets/{attachment_id} + return setting.AppURL + "api/repos/" + repo.FullName() + "/releases/" + strconv.FormatInt(attach.ReleaseID, 10) + "/assets/" + strconv.FormatInt(attach.ID, 10) +} + +// ToAttachment converts models.Attachment to api.Attachment for API usage +func ToAttachment(repo *repo_model.Repository, a *repo_model.Attachment) *api.Attachment { + return toAttachment(repo, a, WebAssetDownloadURL) +} + +// ToAPIAttachment converts models.Attachment to api.Attachment for API usage +func ToAPIAttachment(repo *repo_model.Repository, a *repo_model.Attachment) *api.Attachment { + return toAttachment(repo, a, APIAssetDownloadURL) +} + +// toAttachment converts models.Attachment to api.Attachment for API usage +func toAttachment(repo *repo_model.Repository, a *repo_model.Attachment, getDownloadURL func(repo *repo_model.Repository, attach *repo_model.Attachment) string) *api.Attachment { return &api.Attachment{ ID: a.ID, Name: a.Name, @@ -17,14 +43,18 @@ func ToAttachment(a *repo_model.Attachment) *api.Attachment { DownloadCount: a.DownloadCount, Size: a.Size, UUID: a.UUID, - DownloadURL: a.DownloadURL(), + DownloadURL: getDownloadURL(repo, a), // for web request json and api request json, return different download urls } } -func ToAttachments(attachments []*repo_model.Attachment) []*api.Attachment { +func ToAPIAttachments(repo *repo_model.Repository, attachments []*repo_model.Attachment) []*api.Attachment { + return toAttachments(repo, attachments, APIAssetDownloadURL) +} + +func toAttachments(repo *repo_model.Repository, attachments []*repo_model.Attachment, getDownloadURL func(repo *repo_model.Repository, attach *repo_model.Attachment) string) []*api.Attachment { converted := make([]*api.Attachment, 0, len(attachments)) for _, attachment := range attachments { - converted = append(converted, ToAttachment(attachment)) + converted = append(converted, toAttachment(repo, attachment, getDownloadURL)) } return converted } diff --git a/services/convert/issue.go b/services/convert/issue.go index bcb1618e8fa..d81840f0252 100644 --- a/services/convert/issue.go +++ b/services/convert/issue.go @@ -19,11 +19,19 @@ import ( api "code.gitea.io/gitea/modules/structs" ) +func ToIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue { + return toIssue(ctx, issue, WebAssetDownloadURL) +} + // ToAPIIssue converts an Issue to API format // it assumes some fields assigned with values: // Required - Poster, Labels, // Optional - Milestone, Assignee, PullRequest func ToAPIIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue { + return toIssue(ctx, issue, APIAssetDownloadURL) +} + +func toIssue(ctx context.Context, issue *issues_model.Issue, getDownloadURL func(repo *repo_model.Repository, attach *repo_model.Attachment) string) *api.Issue { if err := issue.LoadLabels(ctx); err != nil { return &api.Issue{} } @@ -40,7 +48,7 @@ func ToAPIIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue { Poster: ToUser(ctx, issue.Poster, nil), Title: issue.Title, Body: issue.Content, - Attachments: ToAttachments(issue.Attachments), + Attachments: toAttachments(issue.Repo, issue.Attachments, getDownloadURL), Ref: issue.Ref, State: issue.State(), IsLocked: issue.IsLocked, @@ -105,6 +113,15 @@ func ToAPIIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue { return apiIssue } +// ToIssueList converts an IssueList to API format +func ToIssueList(ctx context.Context, il issues_model.IssueList) []*api.Issue { + result := make([]*api.Issue, len(il)) + for i := range il { + result[i] = ToIssue(ctx, il[i]) + } + return result +} + // ToAPIIssueList converts an IssueList to API format func ToAPIIssueList(ctx context.Context, il issues_model.IssueList) []*api.Issue { result := make([]*api.Issue, len(il)) diff --git a/services/convert/issue_comment.go b/services/convert/issue_comment.go index 2810c6c9bc9..261198cf0f1 100644 --- a/services/convert/issue_comment.go +++ b/services/convert/issue_comment.go @@ -13,8 +13,8 @@ import ( api "code.gitea.io/gitea/modules/structs" ) -// ToComment converts a issues_model.Comment to the api.Comment format -func ToComment(ctx context.Context, c *issues_model.Comment) *api.Comment { +// ToAPIComment converts a issues_model.Comment to the api.Comment format for API usage +func ToAPIComment(ctx context.Context, repo *repo_model.Repository, c *issues_model.Comment) *api.Comment { return &api.Comment{ ID: c.ID, Poster: ToUser(ctx, c.Poster, nil), @@ -22,14 +22,14 @@ func ToComment(ctx context.Context, c *issues_model.Comment) *api.Comment { IssueURL: c.IssueURL(), PRURL: c.PRURL(), Body: c.Content, - Attachments: ToAttachments(c.Attachments), + Attachments: ToAPIAttachments(repo, c.Attachments), Created: c.CreatedUnix.AsTime(), Updated: c.UpdatedUnix.AsTime(), } } // ToTimelineComment converts a issues_model.Comment to the api.TimelineComment format -func ToTimelineComment(ctx context.Context, c *issues_model.Comment, doer *user_model.User) *api.TimelineComment { +func ToTimelineComment(ctx context.Context, repo *repo_model.Repository, c *issues_model.Comment, doer *user_model.User) *api.TimelineComment { err := c.LoadMilestone(ctx) if err != nil { log.Error("LoadMilestone: %v", err) @@ -131,7 +131,7 @@ func ToTimelineComment(ctx context.Context, c *issues_model.Comment, doer *user_ log.Error("LoadPoster: %v", err) return nil } - comment.RefComment = ToComment(ctx, com) + comment.RefComment = ToAPIComment(ctx, repo, com) } if c.Label != nil { diff --git a/services/convert/release.go b/services/convert/release.go index ca28aa0d6b0..d8aa46d4326 100644 --- a/services/convert/release.go +++ b/services/convert/release.go @@ -10,8 +10,8 @@ import ( api "code.gitea.io/gitea/modules/structs" ) -// ToRelease convert a repo_model.Release to api.Release -func ToRelease(ctx context.Context, r *repo_model.Release) *api.Release { +// ToAPIRelease convert a repo_model.Release to api.Release +func ToAPIRelease(ctx context.Context, repo *repo_model.Repository, r *repo_model.Release) *api.Release { return &api.Release{ ID: r.ID, TagName: r.TagName, @@ -27,6 +27,6 @@ func ToRelease(ctx context.Context, r *repo_model.Release) *api.Release { CreatedAt: r.CreatedUnix.AsTime(), PublishedAt: r.CreatedUnix.AsTime(), Publisher: ToUser(ctx, r.Publisher, nil), - Attachments: ToAttachments(r.Attachments), + Attachments: ToAPIAttachments(repo, r.Attachments), } } diff --git a/services/webhook/notifier.go b/services/webhook/notifier.go index 3332d5d4aa1..23080a5a351 100644 --- a/services/webhook/notifier.go +++ b/services/webhook/notifier.go @@ -386,7 +386,7 @@ func (m *webhookNotifier) NotifyUpdateComment(ctx context.Context, doer *user_mo if err := PrepareWebhooks(ctx, EventSource{Repository: c.Issue.Repo}, eventType, &api.IssueCommentPayload{ Action: api.HookIssueCommentEdited, Issue: convert.ToAPIIssue(ctx, c.Issue), - Comment: convert.ToComment(ctx, c), + Comment: convert.ToAPIComment(ctx, c.Issue.Repo, c), Changes: &api.ChangesPayload{ Body: &api.ChangesFromPayload{ From: oldContent, @@ -414,7 +414,7 @@ func (m *webhookNotifier) NotifyCreateIssueComment(ctx context.Context, doer *us if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, eventType, &api.IssueCommentPayload{ Action: api.HookIssueCommentCreated, Issue: convert.ToAPIIssue(ctx, issue), - Comment: convert.ToComment(ctx, comment), + Comment: convert.ToAPIComment(ctx, repo, comment), Repository: convert.ToRepo(ctx, repo, permission), Sender: convert.ToUser(ctx, doer, nil), IsPull: issue.IsPull, @@ -451,7 +451,7 @@ func (m *webhookNotifier) NotifyDeleteComment(ctx context.Context, doer *user_mo if err := PrepareWebhooks(ctx, EventSource{Repository: comment.Issue.Repo}, eventType, &api.IssueCommentPayload{ Action: api.HookIssueCommentDeleted, Issue: convert.ToAPIIssue(ctx, comment.Issue), - Comment: convert.ToComment(ctx, comment), + Comment: convert.ToAPIComment(ctx, comment.Issue.Repo, comment), Repository: convert.ToRepo(ctx, comment.Issue.Repo, permission), Sender: convert.ToUser(ctx, doer, nil), IsPull: comment.Issue.IsPull, @@ -808,7 +808,7 @@ func sendReleaseHook(ctx context.Context, doer *user_model.User, rel *repo_model permission, _ := access_model.GetUserRepoPermission(ctx, rel.Repo, doer) if err := PrepareWebhooks(ctx, EventSource{Repository: rel.Repo}, webhook_module.HookEventRelease, &api.ReleasePayload{ Action: action, - Release: convert.ToRelease(ctx, rel), + Release: convert.ToAPIRelease(ctx, rel.Repo, rel), Repository: convert.ToRepo(ctx, rel.Repo, permission), Sender: convert.ToUser(ctx, doer, nil), }); err != nil { diff --git a/tests/integration/api_comment_attachment_test.go b/tests/integration/api_comment_attachment_test.go index 8aa73dd3688..e211376c3c8 100644 --- a/tests/integration/api_comment_attachment_test.go +++ b/tests/integration/api_comment_attachment_test.go @@ -45,11 +45,12 @@ func TestAPIGetCommentAttachment(t *testing.T) { var apiAttachment api.Attachment DecodeJSON(t, resp, &apiAttachment) - expect := convert.ToAttachment(attachment) + expect := convert.ToAPIAttachment(repo, attachment) assert.Equal(t, expect.ID, apiAttachment.ID) assert.Equal(t, expect.Name, apiAttachment.Name) assert.Equal(t, expect.UUID, apiAttachment.UUID) assert.Equal(t, expect.Created.Unix(), apiAttachment.Created.Unix()) + assert.Equal(t, expect.DownloadURL, apiAttachment.DownloadURL) } func TestAPIListCommentAttachments(t *testing.T) { diff --git a/tests/integration/api_comment_test.go b/tests/integration/api_comment_test.go index c773afab3d6..ee648210e5e 100644 --- a/tests/integration/api_comment_test.go +++ b/tests/integration/api_comment_test.go @@ -128,7 +128,7 @@ func TestAPIGetComment(t *testing.T) { DecodeJSON(t, resp, &apiComment) assert.NoError(t, comment.LoadPoster(db.DefaultContext)) - expect := convert.ToComment(db.DefaultContext, comment) + expect := convert.ToAPIComment(db.DefaultContext, repo, comment) assert.Equal(t, expect.ID, apiComment.ID) assert.Equal(t, expect.Poster.FullName, apiComment.Poster.FullName)