From 396c0fbc084cf5a601f8ba553c7e5eae6fcac915 Mon Sep 17 00:00:00 2001 From: celogeek Date: Thu, 26 May 2022 16:53:13 +0200 Subject: [PATCH] utils to encode sha256 --- .gitignore | 1 + cmd/photos-api-cli/upload.go | 10 ++++------ internal/photos/api/account.go | 8 +++----- internal/photos/api/file.go | 2 +- internal/photos/api/upload.go | 28 ++++++++++++++++++++-------- internal/photos/api/utils.go | 27 +++++++++++++++++++++++++++ 6 files changed, 56 insertions(+), 20 deletions(-) create mode 100644 internal/photos/api/utils.go diff --git a/.gitignore b/.gitignore index 4653a27..1149240 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ data .DS_Store .kopiaignore +.vscode diff --git a/cmd/photos-api-cli/upload.go b/cmd/photos-api-cli/upload.go index ad1c02c..a8707b5 100644 --- a/cmd/photos-api-cli/upload.go +++ b/cmd/photos-api-cli/upload.go @@ -1,8 +1,6 @@ package main import ( - "crypto/sha256" - "encoding/hex" "fmt" "io" "os" @@ -53,7 +51,7 @@ func (c *UploadCommand) Execute(args []string) error { b := make([]byte, photosapi.MaxUploadPartSize) parts := 0 - completesha256 := sha256.New() + completesha256 := photosapi.NewChecksum() for { n, err := tee.Read(b) if err != nil { @@ -65,7 +63,7 @@ func (c *UploadCommand) Execute(args []string) error { } parts++ - partsha256 := sha256.New() + partsha256 := photosapi.NewChecksum() partsha256.Write(b[:n]) completesha256.Write(b[:n]) @@ -73,7 +71,7 @@ func (c *UploadCommand) Execute(args []string) error { R(). SetError(&photosapi.ErrorWithDetails{}). SetQueryParam("part", fmt.Sprint(parts)). - SetQueryParam("sha256", hex.EncodeToString(partsha256.Sum(nil))). + SetQueryParam("sha256", partsha256.String()). SetBody(b[:n]). SetPathParam("id", uploadId). Put("/upload/{id}") @@ -88,7 +86,7 @@ func (c *UploadCommand) Execute(args []string) error { } completeRequest := &photosapi.UploadCompleteRequest{ - Sha256: hex.EncodeToString(completesha256.Sum(nil)), + Sha256: completesha256.String(), Parts: uint(parts), Name: filepath.Base(c.File), } diff --git a/internal/photos/api/account.go b/internal/photos/api/account.go index dca457e..a73fe2e 100644 --- a/internal/photos/api/account.go +++ b/internal/photos/api/account.go @@ -1,8 +1,6 @@ package photosapi import ( - "crypto" - "encoding/base64" "errors" "net/http" "time" @@ -35,9 +33,9 @@ func (a *Account) BeforeCreate(tx *gorm.DB) error { } func (a *Account) EncryptPassword() { - sha1 := crypto.SHA256.New() - sha1.Write([]byte(a.Password)) - a.EncryptedPassword = base64.StdEncoding.EncodeToString(sha1.Sum(nil)) + ch := NewChecksum() + ch.Write([]byte(a.Password)) + a.EncryptedPassword = ch.String() } func NewAccount(login string, password string) *Account { diff --git a/internal/photos/api/file.go b/internal/photos/api/file.go index bbed964..04ceb65 100644 --- a/internal/photos/api/file.go +++ b/internal/photos/api/file.go @@ -7,7 +7,7 @@ import ( // Error var ( // Store - ErrStoreBadChecksum = errors.New("checksum should be sha1 in hex format") + ErrStoreBadChecksum = errors.New("checksum should be sha256 in hex format") ErrStoreBadChunkSize = errors.New("part file size should be 1MB max") ErrStoreMissingChunks = errors.New("part checksum missing") ErrStoreWrongChecksum = errors.New("wrong checksum") diff --git a/internal/photos/api/upload.go b/internal/photos/api/upload.go index baea353..d6341b2 100644 --- a/internal/photos/api/upload.go +++ b/internal/photos/api/upload.go @@ -1,8 +1,6 @@ package photosapi import ( - "crypto/sha256" - "encoding/hex" "errors" "fmt" "io" @@ -132,7 +130,7 @@ func (s *Service) UploadPart(c *gin.Context) { return } - sha := sha256.New() + sha := NewChecksum() t := io.TeeReader(c.Request.Body, sha) _, err = io.Copy(f, t) if err != nil { @@ -143,8 +141,7 @@ func (s *Service) UploadPart(c *gin.Context) { } f.Close() - shastr := hex.EncodeToString(sha.Sum(nil)) - if shastr != uploadPart.PartSha256 { + if !sha.Match(uploadPart.PartSha256) { os.Remove(tmp_file) c.AbortWithError(http.StatusBadRequest, ErrUploadPartWrongSha256) return @@ -203,8 +200,9 @@ func (s *Service) UploadComplete(c *gin.Context) { c.AbortWithError(http.StatusInternalServerError, err) return } - fsha := sha256.New() + fsha := NewChecksum() ft := io.MultiWriter(f, fsha) + size := uint64(0) defer f.Close() for part := uint(1); part <= uploadCompleteRequest.Parts; part++ { @@ -213,14 +211,15 @@ func (s *Service) UploadComplete(c *gin.Context) { c.AbortWithError(http.StatusNotFound, fmt.Errorf("upload part %d missing", part)) return } - _, err = io.Copy(ft, p) + w, err := io.Copy(ft, p) if err != nil { c.AbortWithError(http.StatusInternalServerError, err) return } + size += uint64(w) } - if uploadCompleteRequest.Sha256 != hex.EncodeToString(fsha.Sum(nil)) { + if !fsha.Match(uploadCompleteRequest.Sha256) { c.AbortWithError(http.StatusExpectationFailed, ErrUploadPartsCombineWrongSha256) return } @@ -234,6 +233,19 @@ func (s *Service) UploadComplete(c *gin.Context) { return } + sess := s.CurrentSession(c) + record := &File{ + Name: uploadCompleteRequest.Name, + Checksum: uploadCompleteRequest.Sha256, + AuthorId: &sess.Account.ID, + Size: size, + } + + if err := s.DB.Create(record).Error; err != nil { + c.AbortWithError(http.StatusConflict, err) + return + } + c.Status(http.StatusNoContent) } diff --git a/internal/photos/api/utils.go b/internal/photos/api/utils.go new file mode 100644 index 0000000..4e0bbbe --- /dev/null +++ b/internal/photos/api/utils.go @@ -0,0 +1,27 @@ +package photosapi + +import ( + "crypto/sha256" + "encoding/base64" + "hash" +) + +type Checksum struct { + s hash.Hash +} + +func NewChecksum() *Checksum { + return &Checksum{sha256.New()} +} + +func (c *Checksum) Write(b []byte) (int, error) { + return c.s.Write(b) +} + +func (c *Checksum) String() string { + return base64.URLEncoding.EncodeToString(c.s.Sum(nil)) +} + +func (c *Checksum) Match(sha string) bool { + return c.String() == sha +}