utils to encode sha256

This commit is contained in:
celogeek 2022-05-26 16:53:13 +02:00
parent f35c18027e
commit 396c0fbc08
Signed by: celogeek
GPG Key ID: E6B7BDCFC446233A
6 changed files with 56 additions and 20 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
data data
.DS_Store .DS_Store
.kopiaignore .kopiaignore
.vscode

View File

@ -1,8 +1,6 @@
package main package main
import ( import (
"crypto/sha256"
"encoding/hex"
"fmt" "fmt"
"io" "io"
"os" "os"
@ -53,7 +51,7 @@ func (c *UploadCommand) Execute(args []string) error {
b := make([]byte, photosapi.MaxUploadPartSize) b := make([]byte, photosapi.MaxUploadPartSize)
parts := 0 parts := 0
completesha256 := sha256.New() completesha256 := photosapi.NewChecksum()
for { for {
n, err := tee.Read(b) n, err := tee.Read(b)
if err != nil { if err != nil {
@ -65,7 +63,7 @@ func (c *UploadCommand) Execute(args []string) error {
} }
parts++ parts++
partsha256 := sha256.New() partsha256 := photosapi.NewChecksum()
partsha256.Write(b[:n]) partsha256.Write(b[:n])
completesha256.Write(b[:n]) completesha256.Write(b[:n])
@ -73,7 +71,7 @@ func (c *UploadCommand) Execute(args []string) error {
R(). R().
SetError(&photosapi.ErrorWithDetails{}). SetError(&photosapi.ErrorWithDetails{}).
SetQueryParam("part", fmt.Sprint(parts)). SetQueryParam("part", fmt.Sprint(parts)).
SetQueryParam("sha256", hex.EncodeToString(partsha256.Sum(nil))). SetQueryParam("sha256", partsha256.String()).
SetBody(b[:n]). SetBody(b[:n]).
SetPathParam("id", uploadId). SetPathParam("id", uploadId).
Put("/upload/{id}") Put("/upload/{id}")
@ -88,7 +86,7 @@ func (c *UploadCommand) Execute(args []string) error {
} }
completeRequest := &photosapi.UploadCompleteRequest{ completeRequest := &photosapi.UploadCompleteRequest{
Sha256: hex.EncodeToString(completesha256.Sum(nil)), Sha256: completesha256.String(),
Parts: uint(parts), Parts: uint(parts),
Name: filepath.Base(c.File), Name: filepath.Base(c.File),
} }

View File

@ -1,8 +1,6 @@
package photosapi package photosapi
import ( import (
"crypto"
"encoding/base64"
"errors" "errors"
"net/http" "net/http"
"time" "time"
@ -35,9 +33,9 @@ func (a *Account) BeforeCreate(tx *gorm.DB) error {
} }
func (a *Account) EncryptPassword() { func (a *Account) EncryptPassword() {
sha1 := crypto.SHA256.New() ch := NewChecksum()
sha1.Write([]byte(a.Password)) ch.Write([]byte(a.Password))
a.EncryptedPassword = base64.StdEncoding.EncodeToString(sha1.Sum(nil)) a.EncryptedPassword = ch.String()
} }
func NewAccount(login string, password string) *Account { func NewAccount(login string, password string) *Account {

View File

@ -7,7 +7,7 @@ import (
// Error // Error
var ( var (
// Store // 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") ErrStoreBadChunkSize = errors.New("part file size should be 1MB max")
ErrStoreMissingChunks = errors.New("part checksum missing") ErrStoreMissingChunks = errors.New("part checksum missing")
ErrStoreWrongChecksum = errors.New("wrong checksum") ErrStoreWrongChecksum = errors.New("wrong checksum")

View File

@ -1,8 +1,6 @@
package photosapi package photosapi
import ( import (
"crypto/sha256"
"encoding/hex"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -132,7 +130,7 @@ func (s *Service) UploadPart(c *gin.Context) {
return return
} }
sha := sha256.New() sha := NewChecksum()
t := io.TeeReader(c.Request.Body, sha) t := io.TeeReader(c.Request.Body, sha)
_, err = io.Copy(f, t) _, err = io.Copy(f, t)
if err != nil { if err != nil {
@ -143,8 +141,7 @@ func (s *Service) UploadPart(c *gin.Context) {
} }
f.Close() f.Close()
shastr := hex.EncodeToString(sha.Sum(nil)) if !sha.Match(uploadPart.PartSha256) {
if shastr != uploadPart.PartSha256 {
os.Remove(tmp_file) os.Remove(tmp_file)
c.AbortWithError(http.StatusBadRequest, ErrUploadPartWrongSha256) c.AbortWithError(http.StatusBadRequest, ErrUploadPartWrongSha256)
return return
@ -203,8 +200,9 @@ func (s *Service) UploadComplete(c *gin.Context) {
c.AbortWithError(http.StatusInternalServerError, err) c.AbortWithError(http.StatusInternalServerError, err)
return return
} }
fsha := sha256.New() fsha := NewChecksum()
ft := io.MultiWriter(f, fsha) ft := io.MultiWriter(f, fsha)
size := uint64(0)
defer f.Close() defer f.Close()
for part := uint(1); part <= uploadCompleteRequest.Parts; part++ { 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)) c.AbortWithError(http.StatusNotFound, fmt.Errorf("upload part %d missing", part))
return return
} }
_, err = io.Copy(ft, p) w, err := io.Copy(ft, p)
if err != nil { if err != nil {
c.AbortWithError(http.StatusInternalServerError, err) c.AbortWithError(http.StatusInternalServerError, err)
return return
} }
size += uint64(w)
} }
if uploadCompleteRequest.Sha256 != hex.EncodeToString(fsha.Sum(nil)) { if !fsha.Match(uploadCompleteRequest.Sha256) {
c.AbortWithError(http.StatusExpectationFailed, ErrUploadPartsCombineWrongSha256) c.AbortWithError(http.StatusExpectationFailed, ErrUploadPartsCombineWrongSha256)
return return
} }
@ -234,6 +233,19 @@ func (s *Service) UploadComplete(c *gin.Context) {
return 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) c.Status(http.StatusNoContent)
} }

View File

@ -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
}