From f369788347167a47a8fc162e086b92048ff0a43f Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Sun, 7 Jul 2019 04:25:05 +0200 Subject: [PATCH] Refactor filetype is not allowed errors (#7309) --- modules/upload/filetype.go | 49 +++++++++++++++++++++++ routers/api/v1/repo/release_attachment.go | 20 ++------- routers/repo/attachment.go | 19 ++------- routers/repo/editor.go | 17 ++------ routers/repo/issue.go | 2 - 5 files changed, 61 insertions(+), 46 deletions(-) create mode 100644 modules/upload/filetype.go diff --git a/modules/upload/filetype.go b/modules/upload/filetype.go new file mode 100644 index 000000000..1ec7324ed --- /dev/null +++ b/modules/upload/filetype.go @@ -0,0 +1,49 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package upload + +import ( + "fmt" + "net/http" + "strings" + + "code.gitea.io/gitea/modules/log" +) + +// ErrFileTypeForbidden not allowed file type error +type ErrFileTypeForbidden struct { + Type string +} + +// IsErrFileTypeForbidden checks if an error is a ErrFileTypeForbidden. +func IsErrFileTypeForbidden(err error) bool { + _, ok := err.(ErrFileTypeForbidden) + return ok +} + +func (err ErrFileTypeForbidden) Error() string { + return fmt.Sprintf("File type is not allowed: %s", err.Type) +} + +// VerifyAllowedContentType validates a file is allowed to be uploaded. +func VerifyAllowedContentType(buf []byte, allowedTypes []string) error { + fileType := http.DetectContentType(buf) + + allowed := false + for _, t := range allowedTypes { + t := strings.Trim(t, " ") + if t == "*/*" || t == fileType { + allowed = true + break + } + } + + if !allowed { + log.Info("Attachment with type %s blocked from upload", fileType) + return ErrFileTypeForbidden{Type: fileType} + } + + return nil +} diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go index f85787bc5..d0eb3d4ae 100644 --- a/routers/api/v1/repo/release_attachment.go +++ b/routers/api/v1/repo/release_attachment.go @@ -5,13 +5,12 @@ package repo import ( - "errors" - "net/http" "strings" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/upload" api "code.gitea.io/gitea/modules/structs" ) @@ -177,20 +176,9 @@ func CreateReleaseAttachment(ctx *context.APIContext) { } // Check if the filetype is allowed by the settings - fileType := http.DetectContentType(buf) - - allowedTypes := strings.Split(setting.AttachmentAllowedTypes, ",") - allowed := false - for _, t := range allowedTypes { - t := strings.Trim(t, " ") - if t == "*/*" || t == fileType { - allowed = true - break - } - } - - if !allowed { - ctx.Error(400, "DetectContentType", errors.New("File type is not allowed")) + err = upload.VerifyAllowedContentType(buf, strings.Split(setting.AttachmentAllowedTypes, ",")) + if err != nil { + ctx.Error(400, "DetectContentType", err) return } diff --git a/routers/repo/attachment.go b/routers/repo/attachment.go index 8913e6301..a07a2a8ac 100644 --- a/routers/repo/attachment.go +++ b/routers/repo/attachment.go @@ -6,13 +6,13 @@ package repo import ( "fmt" - "net/http" "strings" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/upload" ) func renderAttachmentSettings(ctx *context.Context) { @@ -42,21 +42,10 @@ func UploadAttachment(ctx *context.Context) { if n > 0 { buf = buf[:n] } - fileType := http.DetectContentType(buf) - allowedTypes := strings.Split(setting.AttachmentAllowedTypes, ",") - allowed := false - for _, t := range allowedTypes { - t := strings.Trim(t, " ") - if t == "*/*" || t == fileType { - allowed = true - break - } - } - - if !allowed { - log.Info("Attachment with type %s blocked from upload", fileType) - ctx.Error(400, ErrFileTypeForbidden.Error()) + err = upload.VerifyAllowedContentType(buf, strings.Split(setting.AttachmentAllowedTypes, ",")) + if err != nil { + ctx.Error(400, err.Error()) return } diff --git a/routers/repo/editor.go b/routers/repo/editor.go index 062ecfebf..f3327017e 100644 --- a/routers/repo/editor.go +++ b/routers/repo/editor.go @@ -7,7 +7,6 @@ package repo import ( "fmt" "io/ioutil" - "net/http" "path" "strings" @@ -20,6 +19,7 @@ import ( "code.gitea.io/gitea/modules/repofiles" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/templates" + "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/util" ) @@ -594,20 +594,11 @@ func UploadFileToServer(ctx *context.Context) { if n > 0 { buf = buf[:n] } - fileType := http.DetectContentType(buf) if len(setting.Repository.Upload.AllowedTypes) > 0 { - allowed := false - for _, t := range setting.Repository.Upload.AllowedTypes { - t := strings.Trim(t, " ") - if t == "*/*" || t == fileType { - allowed = true - break - } - } - - if !allowed { - ctx.Error(400, ErrFileTypeForbidden.Error()) + err = upload.VerifyAllowedContentType(buf, setting.Repository.Upload.AllowedTypes) + if err != nil { + ctx.Error(400, err.Error()) return } } diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 3904d2953..72e0357e6 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -41,8 +41,6 @@ const ( ) var ( - // ErrFileTypeForbidden not allowed file type error - ErrFileTypeForbidden = errors.New("File type is not allowed") // ErrTooManyFiles upload too many files ErrTooManyFiles = errors.New("Maximum number of files to upload exceeded") // IssueTemplateCandidates issue templates