From ed6220fc7dc272c46e553018139a1b199edc73a7 Mon Sep 17 00:00:00 2001 From: Derrick Hammer Date: Mon, 22 May 2023 11:00:24 -0400 Subject: [PATCH] refactor: optionally compare passed hash with computed one and reject if they don't match --- controller/files.go | 2 +- service/files/files.go | 10 +++++++++- tus/tus.go | 16 +++++++++++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/controller/files.go b/controller/files.go index b1da413..28b0a04 100644 --- a/controller/files.go +++ b/controller/files.go @@ -26,7 +26,7 @@ func (f *FilesController) PostUpload() { return } - upload, err := files.Upload(file, meta.Size) + upload, err := files.Upload(file, meta.Size, nil) if internalError(ctx, err) { shared.GetLogger().Debug("failed uploading file", zap.Error(err)) diff --git a/service/files/files.go b/service/files/files.go index a40767a..89135c9 100644 --- a/service/files/files.go +++ b/service/files/files.go @@ -1,6 +1,7 @@ package files import ( + "bytes" "context" "encoding/hex" "errors" @@ -25,7 +26,7 @@ func Init() { client.SetDisableWarn(true) } -func Upload(r io.ReadSeeker, size int64) (model.Upload, error) { +func Upload(r io.ReadSeeker, size int64, hash []byte) (model.Upload, error) { var upload model.Upload tree, hashBytes, err := bao.ComputeTree(r, size) @@ -35,6 +36,13 @@ func Upload(r io.ReadSeeker, size int64) (model.Upload, error) { return upload, err } + if hash != nil { + if bytes.Compare(hashBytes[:], hash) != 0 { + shared.GetLogger().Error("File hash does not match provided file hash") + return upload, err + } + } + hashHex := hex.EncodeToString(hashBytes[:]) _, err = r.Seek(0, io.SeekStart) diff --git a/tus/tus.go b/tus/tus.go index d058dd4..909684b 100644 --- a/tus/tus.go +++ b/tus/tus.go @@ -147,7 +147,21 @@ func tusWorker(upload *tusd.Upload) error { return err } - _, err = files.Upload(file.(io.ReadSeeker), info.Size) + hashHex := info.MetaData[HASH_META_HEADER] + + hashBytes, err := hex.DecodeString(hashHex) + + if err != nil { + shared.GetLogger().Error("failed decoding hash", zap.Error(err)) + tErr := terminateUpload(*upload) + + if tErr != nil { + return tErr + } + return err + } + + _, err = files.Upload(file.(io.ReadSeeker), info.Size, hashBytes) tErr := terminateUpload(*upload) if tErr != nil {