From 8b2407371365fc123fc368bfd46b15f55ba8ae6a Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Sun, 5 Jan 2020 00:20:08 +0100 Subject: Only serve attachments when linked to issue/release and if accessible by user (#9340) * test: add current attachement responses * refactor: check if attachement is linked and accessible by user * chore: clean TODO * fix: typo attachement -> attachment * revert un-needed go.sum change * refactor: move models logic to models * fix TestCreateIssueAttachment which was wrongly successful * fix unit tests with unittype added * fix unit tests with changes * use a valid uuid format for pgsql int. test * test: add unit test TestLinkedRepository * refactor: allow uploader to access unlinked attachement * add missing blank line * refactor: move to a separate function repo.GetAttachment * typo * test: remove err test return * refactor: use repo perm for access checking generally + 404 for all reject --- routers/repo/attachment.go | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'routers/repo') diff --git a/routers/repo/attachment.go b/routers/repo/attachment.go index 0d496230e1..96dc28a23a 100644 --- a/routers/repo/attachment.go +++ b/routers/repo/attachment.go @@ -6,6 +6,8 @@ package repo import ( "fmt" + "net/http" + "os" "strings" "code.gitea.io/gitea/models" @@ -85,3 +87,57 @@ func DeleteAttachment(ctx *context.Context) { "uuid": attach.UUID, }) } + +// GetAttachment serve attachements +func GetAttachment(ctx *context.Context) { + attach, err := models.GetAttachmentByUUID(ctx.Params(":uuid")) + if err != nil { + if models.IsErrAttachmentNotExist(err) { + ctx.Error(404) + } else { + ctx.ServerError("GetAttachmentByUUID", err) + } + return + } + + repository, unitType, err := attach.LinkedRepository() + if err != nil { + ctx.ServerError("LinkedRepository", err) + return + } + + if repository == nil { //If not linked + if !(ctx.IsSigned && attach.UploaderID == ctx.User.ID) { //We block if not the uploader + ctx.Error(http.StatusNotFound) + return + } + } else { //If we have the repository we check access + perm, err := models.GetUserRepoPermission(repository, ctx.User) + if err != nil { + ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err.Error()) + return + } + if !perm.CanRead(unitType) { + ctx.Error(http.StatusNotFound) + return + } + } + + //If we have matched and access to release or issue + fr, err := os.Open(attach.LocalPath()) + if err != nil { + ctx.ServerError("Open", err) + return + } + defer fr.Close() + + if err := attach.IncreaseDownloadCount(); err != nil { + ctx.ServerError("Update", err) + return + } + + if err = ServeData(ctx, attach.Name, fr); err != nil { + ctx.ServerError("ServeData", err) + return + } +} -- cgit v1.2.3