For API attachments, use API URL (#25639)

Fix #25257

---------

Co-authored-by: Giteabot <teabot@gitea.io>
This commit is contained in:
Lunny Xiao 2023-07-10 17:31:19 +08:00 committed by GitHub
parent 5489962aac
commit 0fd1672ae4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 108 additions and 67 deletions

View File

@ -65,13 +65,6 @@ func (a *Attachment) DownloadURL() string {
return setting.AppURL + "attachments/" + url.PathEscape(a.UUID) return setting.AppURL + "attachments/" + url.PathEscape(a.UUID)
} }
// _____ __ __ .__ __
// / _ \_/ |__/ |______ ____ | |__ _____ ____ _____/ |_
// / /_\ \ __\ __\__ \ _/ ___\| | \ / \_/ __ \ / \ __\
// / | \ | | | / __ \\ \___| Y \ Y Y \ ___/| | \ |
// \____|__ /__| |__| (____ /\___ >___| /__|_| /\___ >___| /__|
// \/ \/ \/ \/ \/ \/ \/
// ErrAttachmentNotExist represents a "AttachmentNotExist" kind of error. // ErrAttachmentNotExist represents a "AttachmentNotExist" kind of error.
type ErrAttachmentNotExist struct { type ErrAttachmentNotExist struct {
ID int64 ID int64

View File

@ -1034,7 +1034,7 @@ func Routes() *web.Route {
m.Group("/assets", func() { m.Group("/assets", func() {
m.Combo("").Get(repo.ListReleaseAttachments). m.Combo("").Get(repo.ListReleaseAttachments).
Post(reqToken(), reqRepoWriter(unit.TypeReleases), repo.CreateReleaseAttachment) 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). Patch(reqToken(), reqRepoWriter(unit.TypeReleases), bind(api.EditAttachmentOptions{}), repo.EditReleaseAttachment).
Delete(reqToken(), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseAttachment) Delete(reqToken(), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseAttachment)
}) })
@ -1179,7 +1179,7 @@ func Routes() *web.Route {
m.Combo(""). m.Combo("").
Get(repo.ListIssueCommentAttachments). Get(repo.ListIssueCommentAttachments).
Post(reqToken(), mustNotBeArchived, repo.CreateIssueCommentAttachment) Post(reqToken(), mustNotBeArchived, repo.CreateIssueCommentAttachment)
m.Combo("/{asset}"). m.Combo("/{attachment_id}").
Get(repo.GetIssueCommentAttachment). Get(repo.GetIssueCommentAttachment).
Patch(reqToken(), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueCommentAttachment). Patch(reqToken(), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueCommentAttachment).
Delete(reqToken(), mustNotBeArchived, repo.DeleteIssueCommentAttachment) Delete(reqToken(), mustNotBeArchived, repo.DeleteIssueCommentAttachment)
@ -1231,7 +1231,7 @@ func Routes() *web.Route {
m.Combo(""). m.Combo("").
Get(repo.ListIssueAttachments). Get(repo.ListIssueAttachments).
Post(reqToken(), mustNotBeArchived, repo.CreateIssueAttachment) Post(reqToken(), mustNotBeArchived, repo.CreateIssueAttachment)
m.Combo("/{asset}"). m.Combo("/{attachment_id}").
Get(repo.GetIssueAttachment). Get(repo.GetIssueAttachment).
Patch(reqToken(), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueAttachment). Patch(reqToken(), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueAttachment).
Delete(reqToken(), mustNotBeArchived, repo.DeleteIssueAttachment) Delete(reqToken(), mustNotBeArchived, repo.DeleteIssueAttachment)

View File

@ -64,7 +64,7 @@ func GetIssueAttachment(ctx *context.APIContext) {
return 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 // ListIssueAttachments lists all attachments of the issue
@ -194,7 +194,7 @@ func CreateIssueAttachment(ctx *context.APIContext) {
return return
} }
ctx.JSON(http.StatusCreated, convert.ToAttachment(attachment)) ctx.JSON(http.StatusCreated, convert.ToAPIAttachment(ctx.Repo.Repository, attachment))
} }
// EditIssueAttachment updates the given attachment // EditIssueAttachment updates the given attachment
@ -254,7 +254,7 @@ func EditIssueAttachment(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "UpdateAttachment", err) 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 // 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 { 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 { if err != nil {
ctx.NotFoundOrServerError("GetAttachmentByID", repo_model.IsErrAttachmentNotExist, err) ctx.NotFoundOrServerError("GetAttachmentByID", repo_model.IsErrAttachmentNotExist, err)
return nil return nil

View File

@ -103,7 +103,7 @@ func ListIssueComments(ctx *context.APIContext) {
apiComments := make([]*api.Comment, len(comments)) apiComments := make([]*api.Comment, len(comments))
for i, comment := range comments { for i, comment := range comments {
comment.Issue = issue comment.Issue = issue
apiComments[i] = convert.ToComment(ctx, comments[i]) apiComments[i] = convert.ToAPIComment(ctx, ctx.Repo.Repository, comments[i])
} }
ctx.SetTotalCountHeader(totalCount) ctx.SetTotalCountHeader(totalCount)
@ -191,7 +191,7 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) {
for _, comment := range comments { for _, comment := range comments {
if comment.Type != issues_model.CommentTypeCode && isXRefCommentAccessible(ctx, ctx.Doer, comment, issue.RepoID) { if comment.Type != issues_model.CommentTypeCode && isXRefCommentAccessible(ctx, ctx.Doer, comment, issue.RepoID) {
comment.Issue = issue 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 return
} }
for i := range comments { for i := range comments {
apiComments[i] = convert.ToComment(ctx, comments[i]) apiComments[i] = convert.ToAPIComment(ctx, ctx.Repo.Repository, comments[i])
} }
ctx.SetTotalCountHeader(totalCount) ctx.SetTotalCountHeader(totalCount)
@ -368,7 +368,7 @@ func CreateIssueComment(ctx *context.APIContext) {
return 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 // GetIssueComment Get a comment by ID
@ -436,7 +436,7 @@ func GetIssueComment(ctx *context.APIContext) {
return 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 // EditIssueComment modify a comment of an issue
@ -561,7 +561,7 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption)
return 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 // DeleteIssueComment delete a comment from an issue

View File

@ -68,7 +68,7 @@ func GetIssueCommentAttachment(ctx *context.APIContext) {
return 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 // ListIssueCommentAttachments lists all attachments of the comment
@ -110,7 +110,7 @@ func ListIssueCommentAttachments(ctx *context.APIContext) {
return 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 // CreateIssueCommentAttachment creates an attachment and saves the given file
@ -201,7 +201,7 @@ func CreateIssueCommentAttachment(ctx *context.APIContext) {
return return
} }
ctx.JSON(http.StatusCreated, convert.ToAttachment(attachment)) ctx.JSON(http.StatusCreated, convert.ToAPIAttachment(ctx.Repo.Repository, attachment))
} }
// EditIssueCommentAttachment updates the given attachment // EditIssueCommentAttachment updates the given attachment
@ -259,7 +259,7 @@ func EditIssueCommentAttachment(ctx *context.APIContext) {
if err := repo_model.UpdateAttachment(ctx, attach); err != nil { if err := repo_model.UpdateAttachment(ctx, attach); err != nil {
ctx.Error(http.StatusInternalServerError, "UpdateAttachment", attach) 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 // 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 { 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 { if err != nil {
ctx.NotFoundOrServerError("GetAttachmentByID", repo_model.IsErrAttachmentNotExist, err) ctx.NotFoundOrServerError("GetAttachmentByID", repo_model.IsErrAttachmentNotExist, err)
return nil return nil

View File

@ -64,7 +64,7 @@ func GetRelease(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return 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 // 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) ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return 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 // ListReleases list a repository's releases
@ -174,7 +174,7 @@ func ListReleases(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return 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) filteredCount, err := repo_model.CountReleasesByRepoID(ctx.Repo.Repository.ID, opts)
@ -272,7 +272,7 @@ func CreateRelease(ctx *context.APIContext) {
return return
} }
} }
ctx.JSON(http.StatusCreated, convert.ToRelease(ctx, rel)) ctx.JSON(http.StatusCreated, convert.ToAPIRelease(ctx, ctx.Repo.Repository, rel))
} }
// EditRelease edit a release // EditRelease edit a release
@ -357,7 +357,7 @@ func EditRelease(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return 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 // DeleteRelease delete a release from a repository

View File

@ -52,7 +52,7 @@ func GetReleaseAttachment(ctx *context.APIContext) {
// "$ref": "#/responses/Attachment" // "$ref": "#/responses/Attachment"
releaseID := ctx.ParamsInt64(":id") releaseID := ctx.ParamsInt64(":id")
attachID := ctx.ParamsInt64(":asset") attachID := ctx.ParamsInt64(":attachment_id")
attach, err := repo_model.GetAttachmentByID(ctx, attachID) attach, err := repo_model.GetAttachmentByID(ctx, attachID)
if err != nil { if err != nil {
if repo_model.IsErrAttachmentNotExist(err) { if repo_model.IsErrAttachmentNotExist(err) {
@ -68,7 +68,7 @@ func GetReleaseAttachment(ctx *context.APIContext) {
return return
} }
// FIXME Should prove the existence of the given repo, but results in unnecessary database requests // 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 // ListReleaseAttachments lists all attachments of the release
@ -117,7 +117,7 @@ func ListReleaseAttachments(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return 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 // CreateReleaseAttachment creates an attachment and saves the given file
@ -209,7 +209,7 @@ func CreateReleaseAttachment(ctx *context.APIContext) {
return return
} }
ctx.JSON(http.StatusCreated, convert.ToAttachment(attach)) ctx.JSON(http.StatusCreated, convert.ToAPIAttachment(ctx.Repo.Repository, attach))
} }
// EditReleaseAttachment updates the given attachment // EditReleaseAttachment updates the given attachment
@ -256,7 +256,7 @@ func EditReleaseAttachment(ctx *context.APIContext) {
// Check if release exists an load release // Check if release exists an load release
releaseID := ctx.ParamsInt64(":id") releaseID := ctx.ParamsInt64(":id")
attachID := ctx.ParamsInt64(":asset") attachID := ctx.ParamsInt64(":attachment_id")
attach, err := repo_model.GetAttachmentByID(ctx, attachID) attach, err := repo_model.GetAttachmentByID(ctx, attachID)
if err != nil { if err != nil {
if repo_model.IsErrAttachmentNotExist(err) { if repo_model.IsErrAttachmentNotExist(err) {
@ -279,7 +279,7 @@ func EditReleaseAttachment(ctx *context.APIContext) {
if err := repo_model.UpdateAttachment(ctx, attach); err != nil { if err := repo_model.UpdateAttachment(ctx, attach); err != nil {
ctx.Error(http.StatusInternalServerError, "UpdateAttachment", attach) 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 // DeleteReleaseAttachment delete a given attachment
@ -318,7 +318,7 @@ func DeleteReleaseAttachment(ctx *context.APIContext) {
// Check if release exists an load release // Check if release exists an load release
releaseID := ctx.ParamsInt64(":id") releaseID := ctx.ParamsInt64(":id")
attachID := ctx.ParamsInt64(":asset") attachID := ctx.ParamsInt64(":attachment_id")
attach, err := repo_model.GetAttachmentByID(ctx, attachID) attach, err := repo_model.GetAttachmentByID(ctx, attachID)
if err != nil { if err != nil {
if repo_model.IsErrAttachmentNotExist(err) { if repo_model.IsErrAttachmentNotExist(err) {

View File

@ -63,7 +63,7 @@ func GetReleaseByTag(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return 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 // DeleteReleaseByTag delete a release from a repository by tag name

View File

@ -2058,7 +2058,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 // UpdateIssueTitle change issue's title
@ -2563,7 +2563,7 @@ func SearchIssues(ctx *context.Context) {
} }
ctx.SetTotalCountHeader(filteredCount) 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 { func getUserIDForFilter(ctx *context.Context, queryName string) int64 {
@ -2724,7 +2724,7 @@ func ListIssues(ctx *context.Context) {
} }
ctx.SetTotalCountHeader(filteredCount) ctx.SetTotalCountHeader(filteredCount)
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(ctx, issues)) ctx.JSON(http.StatusOK, convert.ToIssueList(ctx, issues))
} }
func BatchDeleteIssues(ctx *context.Context) { func BatchDeleteIssues(ctx *context.Context) {
@ -3290,7 +3290,7 @@ func GetIssueAttachments(ctx *context.Context) {
} }
attachments := make([]*api.Attachment, len(issue.Attachments)) attachments := make([]*api.Attachment, len(issue.Attachments))
for i := 0; i < len(issue.Attachments); i++ { 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) ctx.JSON(http.StatusOK, attachments)
} }
@ -3314,7 +3314,7 @@ func GetCommentAttachments(ctx *context.Context) {
return return
} }
for i := 0; i < len(comment.Attachments); i++ { 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) ctx.JSON(http.StatusOK, attachments)
} }

View File

@ -171,7 +171,7 @@ func (n *actionsNotifier) NotifyCreateIssueComment(ctx context.Context, doer *us
WithPayload(&api.IssueCommentPayload{ WithPayload(&api.IssueCommentPayload{
Action: api.HookIssueCommentCreated, Action: api.HookIssueCommentCreated,
Issue: convert.ToAPIIssue(ctx, issue), Issue: convert.ToAPIIssue(ctx, issue),
Comment: convert.ToComment(ctx, comment), Comment: convert.ToAPIComment(ctx, repo, comment),
Repository: convert.ToRepo(ctx, repo, permission), Repository: convert.ToRepo(ctx, repo, permission),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
IsPull: true, IsPull: true,
@ -185,7 +185,7 @@ func (n *actionsNotifier) NotifyCreateIssueComment(ctx context.Context, doer *us
WithPayload(&api.IssueCommentPayload{ WithPayload(&api.IssueCommentPayload{
Action: api.HookIssueCommentCreated, Action: api.HookIssueCommentCreated,
Issue: convert.ToAPIIssue(ctx, issue), Issue: convert.ToAPIIssue(ctx, issue),
Comment: convert.ToComment(ctx, comment), Comment: convert.ToAPIComment(ctx, repo, comment),
Repository: convert.ToRepo(ctx, repo, permission), Repository: convert.ToRepo(ctx, repo, permission),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
IsPull: false, IsPull: false,

View File

@ -260,7 +260,7 @@ func notifyRelease(ctx context.Context, doer *user_model.User, rel *repo_model.R
WithRef(git.RefNameFromTag(rel.TagName).String()). WithRef(git.RefNameFromTag(rel.TagName).String()).
WithPayload(&api.ReleasePayload{ WithPayload(&api.ReleasePayload{
Action: action, Action: action,
Release: convert.ToRelease(ctx, rel), Release: convert.ToAPIRelease(ctx, rel.Repo, rel),
Repository: convert.ToRepo(ctx, rel.Repo, permission), Repository: convert.ToRepo(ctx, rel.Repo, permission),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
}). }).

View File

@ -37,7 +37,7 @@ func ToActivity(ctx context.Context, ac *activities_model.Action, doer *user_mod
if ac.Comment != nil { if ac.Comment != nil {
result.CommentID = ac.CommentID result.CommentID = ac.CommentID
result.Comment = ToComment(ctx, ac.Comment) result.Comment = ToAPIComment(ctx, ac.Repo, ac.Comment)
} }
return result return result

View File

@ -4,12 +4,38 @@
package convert package convert
import ( import (
"strconv"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
) )
// ToAttachment converts models.Attachment to api.Attachment func WebAssetDownloadURL(repo *repo_model.Repository, attach *repo_model.Attachment) string {
func ToAttachment(a *repo_model.Attachment) *api.Attachment { 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{ return &api.Attachment{
ID: a.ID, ID: a.ID,
Name: a.Name, Name: a.Name,
@ -17,14 +43,18 @@ func ToAttachment(a *repo_model.Attachment) *api.Attachment {
DownloadCount: a.DownloadCount, DownloadCount: a.DownloadCount,
Size: a.Size, Size: a.Size,
UUID: a.UUID, 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)) converted := make([]*api.Attachment, 0, len(attachments))
for _, attachment := range attachments { for _, attachment := range attachments {
converted = append(converted, ToAttachment(attachment)) converted = append(converted, toAttachment(repo, attachment, getDownloadURL))
} }
return converted return converted
} }

View File

@ -19,11 +19,19 @@ import (
api "code.gitea.io/gitea/modules/structs" 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 // ToAPIIssue converts an Issue to API format
// it assumes some fields assigned with values: // it assumes some fields assigned with values:
// Required - Poster, Labels, // Required - Poster, Labels,
// Optional - Milestone, Assignee, PullRequest // Optional - Milestone, Assignee, PullRequest
func ToAPIIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue { 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 { if err := issue.LoadLabels(ctx); err != nil {
return &api.Issue{} return &api.Issue{}
} }
@ -40,7 +48,7 @@ func ToAPIIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue {
Poster: ToUser(ctx, issue.Poster, nil), Poster: ToUser(ctx, issue.Poster, nil),
Title: issue.Title, Title: issue.Title,
Body: issue.Content, Body: issue.Content,
Attachments: ToAttachments(issue.Attachments), Attachments: toAttachments(issue.Repo, issue.Attachments, getDownloadURL),
Ref: issue.Ref, Ref: issue.Ref,
State: issue.State(), State: issue.State(),
IsLocked: issue.IsLocked, IsLocked: issue.IsLocked,
@ -105,6 +113,15 @@ func ToAPIIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue {
return apiIssue 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 // ToAPIIssueList converts an IssueList to API format
func ToAPIIssueList(ctx context.Context, il issues_model.IssueList) []*api.Issue { func ToAPIIssueList(ctx context.Context, il issues_model.IssueList) []*api.Issue {
result := make([]*api.Issue, len(il)) result := make([]*api.Issue, len(il))

View File

@ -14,8 +14,8 @@ import (
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
) )
// ToComment converts a issues_model.Comment to the api.Comment format // ToAPIComment converts a issues_model.Comment to the api.Comment format for API usage
func ToComment(ctx context.Context, c *issues_model.Comment) *api.Comment { func ToAPIComment(ctx context.Context, repo *repo_model.Repository, c *issues_model.Comment) *api.Comment {
return &api.Comment{ return &api.Comment{
ID: c.ID, ID: c.ID,
Poster: ToUser(ctx, c.Poster, nil), Poster: ToUser(ctx, c.Poster, nil),
@ -23,14 +23,14 @@ func ToComment(ctx context.Context, c *issues_model.Comment) *api.Comment {
IssueURL: c.IssueURL(), IssueURL: c.IssueURL(),
PRURL: c.PRURL(), PRURL: c.PRURL(),
Body: c.Content, Body: c.Content,
Attachments: ToAttachments(c.Attachments), Attachments: ToAPIAttachments(repo, c.Attachments),
Created: c.CreatedUnix.AsTime(), Created: c.CreatedUnix.AsTime(),
Updated: c.UpdatedUnix.AsTime(), Updated: c.UpdatedUnix.AsTime(),
} }
} }
// ToTimelineComment converts a issues_model.Comment to the api.TimelineComment format // 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) err := c.LoadMilestone(ctx)
if err != nil { if err != nil {
log.Error("LoadMilestone: %v", err) log.Error("LoadMilestone: %v", err)
@ -143,7 +143,7 @@ func ToTimelineComment(ctx context.Context, c *issues_model.Comment, doer *user_
log.Error("LoadPoster: %v", err) log.Error("LoadPoster: %v", err)
return nil return nil
} }
comment.RefComment = ToComment(ctx, com) comment.RefComment = ToAPIComment(ctx, repo, com)
} }
if c.Label != nil { if c.Label != nil {

View File

@ -10,8 +10,8 @@ import (
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
) )
// ToRelease convert a repo_model.Release to api.Release // ToAPIRelease convert a repo_model.Release to api.Release
func ToRelease(ctx context.Context, r *repo_model.Release) *api.Release { func ToAPIRelease(ctx context.Context, repo *repo_model.Repository, r *repo_model.Release) *api.Release {
return &api.Release{ return &api.Release{
ID: r.ID, ID: r.ID,
TagName: r.TagName, TagName: r.TagName,
@ -27,6 +27,6 @@ func ToRelease(ctx context.Context, r *repo_model.Release) *api.Release {
CreatedAt: r.CreatedUnix.AsTime(), CreatedAt: r.CreatedUnix.AsTime(),
PublishedAt: r.CreatedUnix.AsTime(), PublishedAt: r.CreatedUnix.AsTime(),
Publisher: ToUser(ctx, r.Publisher, nil), Publisher: ToUser(ctx, r.Publisher, nil),
Attachments: ToAttachments(r.Attachments), Attachments: ToAPIAttachments(repo, r.Attachments),
} }
} }

View File

@ -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{ if err := PrepareWebhooks(ctx, EventSource{Repository: c.Issue.Repo}, eventType, &api.IssueCommentPayload{
Action: api.HookIssueCommentEdited, Action: api.HookIssueCommentEdited,
Issue: convert.ToAPIIssue(ctx, c.Issue), Issue: convert.ToAPIIssue(ctx, c.Issue),
Comment: convert.ToComment(ctx, c), Comment: convert.ToAPIComment(ctx, c.Issue.Repo, c),
Changes: &api.ChangesPayload{ Changes: &api.ChangesPayload{
Body: &api.ChangesFromPayload{ Body: &api.ChangesFromPayload{
From: oldContent, 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{ if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, eventType, &api.IssueCommentPayload{
Action: api.HookIssueCommentCreated, Action: api.HookIssueCommentCreated,
Issue: convert.ToAPIIssue(ctx, issue), Issue: convert.ToAPIIssue(ctx, issue),
Comment: convert.ToComment(ctx, comment), Comment: convert.ToAPIComment(ctx, repo, comment),
Repository: convert.ToRepo(ctx, repo, permission), Repository: convert.ToRepo(ctx, repo, permission),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
IsPull: issue.IsPull, 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{ if err := PrepareWebhooks(ctx, EventSource{Repository: comment.Issue.Repo}, eventType, &api.IssueCommentPayload{
Action: api.HookIssueCommentDeleted, Action: api.HookIssueCommentDeleted,
Issue: convert.ToAPIIssue(ctx, comment.Issue), 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), Repository: convert.ToRepo(ctx, comment.Issue.Repo, permission),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
IsPull: comment.Issue.IsPull, 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) permission, _ := access_model.GetUserRepoPermission(ctx, rel.Repo, doer)
if err := PrepareWebhooks(ctx, EventSource{Repository: rel.Repo}, webhook_module.HookEventRelease, &api.ReleasePayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: rel.Repo}, webhook_module.HookEventRelease, &api.ReleasePayload{
Action: action, Action: action,
Release: convert.ToRelease(ctx, rel), Release: convert.ToAPIRelease(ctx, rel.Repo, rel),
Repository: convert.ToRepo(ctx, rel.Repo, permission), Repository: convert.ToRepo(ctx, rel.Repo, permission),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
}); err != nil { }); err != nil {

View File

@ -45,11 +45,12 @@ func TestAPIGetCommentAttachment(t *testing.T) {
var apiAttachment api.Attachment var apiAttachment api.Attachment
DecodeJSON(t, resp, &apiAttachment) DecodeJSON(t, resp, &apiAttachment)
expect := convert.ToAttachment(attachment) expect := convert.ToAPIAttachment(repo, attachment)
assert.Equal(t, expect.ID, apiAttachment.ID) assert.Equal(t, expect.ID, apiAttachment.ID)
assert.Equal(t, expect.Name, apiAttachment.Name) assert.Equal(t, expect.Name, apiAttachment.Name)
assert.Equal(t, expect.UUID, apiAttachment.UUID) assert.Equal(t, expect.UUID, apiAttachment.UUID)
assert.Equal(t, expect.Created.Unix(), apiAttachment.Created.Unix()) assert.Equal(t, expect.Created.Unix(), apiAttachment.Created.Unix())
assert.Equal(t, expect.DownloadURL, apiAttachment.DownloadURL)
} }
func TestAPIListCommentAttachments(t *testing.T) { func TestAPIListCommentAttachments(t *testing.T) {

View File

@ -128,7 +128,7 @@ func TestAPIGetComment(t *testing.T) {
DecodeJSON(t, resp, &apiComment) DecodeJSON(t, resp, &apiComment)
assert.NoError(t, comment.LoadPoster(db.DefaultContext)) 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.ID, apiComment.ID)
assert.Equal(t, expect.Poster.FullName, apiComment.Poster.FullName) assert.Equal(t, expect.Poster.FullName, apiComment.Poster.FullName)