move errors

This commit is contained in:
celogeek 2022-03-02 16:30:34 +01:00
parent 7557e74862
commit 7a266bafd8
Signed by: celogeek
GPG Key ID: E6B7BDCFC446233A
15 changed files with 95 additions and 48 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
data data
.DS_Store

View File

@ -6,6 +6,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gitlab.celogeek.com/photos/api/internal/photos/models" "gitlab.celogeek.com/photos/api/internal/photos/models"
"gitlab.celogeek.com/photos/api/internal/photoserrors"
"gopkg.in/validator.v2" "gopkg.in/validator.v2"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -33,7 +34,7 @@ func (s *Service) Signup(c *gin.Context) {
return return
} }
if accountExists > 0 { if accountExists > 0 {
s.Error(c, http.StatusConflict, ErrAccountExists) s.Error(c, http.StatusConflict, photoserrors.ErrAccountExists)
return return
} }
if err := s.DB.Create(models.NewAccount(account.Login, account.Password)).Error; err != nil { if err := s.DB.Create(models.NewAccount(account.Login, account.Password)).Error; err != nil {
@ -57,7 +58,7 @@ func (s *Service) Login(c *gin.Context) {
session, err := models.NewSession(s.DB, account.Login, account.Password) session, err := models.NewSession(s.DB, account.Login, account.Password)
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
s.Error(c, http.StatusNotFound, ErrAccountAuth) s.Error(c, http.StatusNotFound, photoserrors.ErrAccountAuth)
} else { } else {
s.Error(c, http.StatusInternalServerError, err) s.Error(c, http.StatusInternalServerError, err)
} }
@ -77,7 +78,7 @@ func (s *Service) Logout(c *gin.Context) {
return return
} }
if res.RowsAffected == 0 { if res.RowsAffected == 0 {
s.Error(c, http.StatusNotFound, ErrSessionNotFound) s.Error(c, http.StatusNotFound, photoserrors.ErrSessionNotFound)
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{

View File

@ -4,11 +4,12 @@ import (
"net/http" "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gitlab.celogeek.com/photos/api/internal/photoserrors"
) )
func (s *Service) RequireBody(c *gin.Context) { func (s *Service) RequireBody(c *gin.Context) {
if c.Request.Method == "POST" && c.Request.ContentLength == 0 { if c.Request.Method == "POST" && c.Request.ContentLength == 0 {
s.Error(c, http.StatusBadRequest, ErrReqMissingBody) s.Error(c, http.StatusBadRequest, photoserrors.ErrReqMissingBody)
return return
} }
} }

View File

@ -1,39 +1,9 @@
package api package api
import ( import (
"errors"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
var (
// Session
ErrSessionNotFound = errors.New("session not found")
ErrSessionInvalid = errors.New("session invalid")
ErrTokenMissing = errors.New("token missing")
// Request
ErrReqMissingBody = errors.New("missing body")
ErrReqNotFound = errors.New("this route doesn't exists")
// Account
ErrAccountExists = errors.New("account exists")
ErrAccountAuth = errors.New("login or password incorrect")
// Panic
ErrUnexpected = errors.New("an unexpected error occur")
// Album
ErrAlbumDontExists = errors.New("album doesn't exists")
// Store
ErrStorePathNotADirectory = errors.New("store path is not a directory")
ErrStoreBadChecksum = errors.New("checksum should be sha1 in hex format")
ErrStoreBadChunkSize = errors.New("part file size should be 1MB max")
ErrStoreMissingChunks = errors.New("part checksum missing")
ErrStoreMismatchChecksum = errors.New("part files doesn't match the original checksum")
)
func (s *Service) Error(c *gin.Context, code int, err error) { func (s *Service) Error(c *gin.Context, code int, err error) {
c.AbortWithStatusJSON(code, gin.H{ c.AbortWithStatusJSON(code, gin.H{
"status": "failed", "status": "failed",

View File

@ -5,8 +5,10 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"path/filepath"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gitlab.celogeek.com/photos/api/internal/photoserrors"
) )
var CHUNK_SIZE int64 = 1 << 20 var CHUNK_SIZE int64 = 1 << 20
@ -24,17 +26,17 @@ func (s *Service) FileCreate(c *gin.Context) {
} }
if len(file.Sum) != 40 { if len(file.Sum) != 40 {
s.Error(c, http.StatusBadRequest, ErrStoreBadChecksum) s.Error(c, http.StatusBadRequest, photoserrors.ErrStoreBadChecksum)
return return
} }
if len(file.Chunks) == 0 { if len(file.Chunks) == 0 {
s.Error(c, http.StatusBadRequest, ErrStoreMissingChunks) s.Error(c, http.StatusBadRequest, photoserrors.ErrStoreMissingChunks)
return return
} }
for _, chunk := range file.Chunks { for _, chunk := range file.Chunks {
if len(chunk) != 40 { if len(chunk) != 40 {
s.Error(c, http.StatusBadRequest, ErrStoreBadChecksum) s.Error(c, http.StatusBadRequest, photoserrors.ErrStoreBadChecksum)
return return
} }
} }
@ -47,7 +49,7 @@ func (s *Service) FileCreate(c *gin.Context) {
if r != file.Sum { if r != file.Sum {
fmt.Printf("R=%s, O=%s\n", r, file.Sum) fmt.Printf("R=%s, O=%s\n", r, file.Sum)
s.Error(c, http.StatusExpectationFailed, ErrStoreMismatchChecksum) s.Error(c, http.StatusExpectationFailed, photoserrors.ErrStoreMismatchChecksum)
return return
} }
@ -70,12 +72,19 @@ func (s *Service) FileCreateTemp(c *gin.Context) {
sumb = c.Param("sum") sumb = c.Param("sum")
) )
if len(origsum) != 40 || len(sumb) != 40 { if len(origsum) != 40 || len(sumb) != 40 {
s.Error(c, http.StatusBadRequest, ErrStoreBadChecksum) s.Error(c, http.StatusBadRequest, photoserrors.ErrStoreBadChecksum)
return
}
originaldir := s.Store.Dir("original", origsum)
originalname := filepath.Join(originaldir, origsum)
if s.Store.FileExists(originalname) {
s.Error(c, http.StatusBadRequest, photoserrors.ErrStoreAlreadyExists)
return return
} }
if c.Request.ContentLength > CHUNK_SIZE { if c.Request.ContentLength > CHUNK_SIZE {
s.Error(c, http.StatusBadRequest, ErrStoreBadChunkSize) s.Error(c, http.StatusBadRequest, photoserrors.ErrStoreBadChunkSize)
return return
} }

View File

@ -10,6 +10,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/go-sql-driver/mysql" "github.com/go-sql-driver/mysql"
"gitlab.celogeek.com/photos/api/internal/photoserrors"
"gitlab.celogeek.com/photos/api/internal/store" "gitlab.celogeek.com/photos/api/internal/store"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -62,7 +63,7 @@ func (s *Service) SetupRoutes() {
album.POST("/tmp/:origsum/:sum", s.FileCreateTemp) album.POST("/tmp/:origsum/:sum", s.FileCreateTemp)
s.Gin.NoRoute(func(c *gin.Context) { s.Gin.NoRoute(func(c *gin.Context) {
s.Error(c, http.StatusNotFound, ErrReqNotFound) s.Error(c, http.StatusNotFound, photoserrors.ErrReqNotFound)
}) })
} }
@ -72,7 +73,7 @@ func (s *Service) PrepareStore() {
s.LogErr.Fatal("Store", err) s.LogErr.Fatal("Store", err)
} }
if !d.IsDir() { if !d.IsDir() {
s.LogErr.Fatal("Store", ErrStorePathNotADirectory) s.LogErr.Fatal("Store", photoserrors.ErrStorePathNotADirectory)
} }
if err := s.Store.MkDirs([]string{"tmp", "original"}); err != nil { if err := s.Store.MkDirs([]string{"tmp", "original"}); err != nil {
s.LogErr.Fatal("Store", err) s.LogErr.Fatal("Store", err)

View File

@ -4,13 +4,14 @@ import (
"net/http" "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gitlab.celogeek.com/photos/api/internal/photoserrors"
) )
func (s *Service) Recovery(c *gin.Context) { func (s *Service) Recovery(c *gin.Context) {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
s.LogErr.Print("PANIC", err) s.LogErr.Print("PANIC", err)
s.Error(c, http.StatusInternalServerError, ErrUnexpected) s.Error(c, http.StatusInternalServerError, photoserrors.ErrUnexpected)
} }
}() }()
c.Next() c.Next()

View File

@ -8,13 +8,14 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gitlab.celogeek.com/photos/api/internal/photos/models" "gitlab.celogeek.com/photos/api/internal/photos/models"
"gitlab.celogeek.com/photos/api/internal/photoserrors"
"gorm.io/gorm" "gorm.io/gorm"
) )
func (s *Service) RequireAuthToken(c *gin.Context) { func (s *Service) RequireAuthToken(c *gin.Context) {
token := c.GetHeader("Authorization") token := c.GetHeader("Authorization")
if !strings.HasPrefix(token, "Private ") { if !strings.HasPrefix(token, "Private ") {
s.Error(c, http.StatusForbidden, ErrTokenMissing) s.Error(c, http.StatusForbidden, photoserrors.ErrTokenMissing)
return return
} }
token = token[8:] token = token[8:]
@ -30,14 +31,14 @@ func (s *Service) RequireSession(c *gin.Context) {
sess := &models.Session{} sess := &models.Session{}
if err := s.DB.Preload("Account").Where("token = ?", c.GetString("token")).First(sess).Error; err != nil { if err := s.DB.Preload("Account").Where("token = ?", c.GetString("token")).First(sess).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
s.Error(c, http.StatusForbidden, ErrSessionNotFound) s.Error(c, http.StatusForbidden, photoserrors.ErrSessionNotFound)
} else { } else {
s.Error(c, http.StatusForbidden, err) s.Error(c, http.StatusForbidden, err)
} }
return return
} }
if sess.Account == nil { if sess.Account == nil {
s.Error(c, http.StatusInternalServerError, ErrSessionInvalid) s.Error(c, http.StatusInternalServerError, photoserrors.ErrSessionInvalid)
return return
} }
s.DB.Select("updated_at").Save(sess) s.DB.Select("updated_at").Save(sess)

View File

@ -0,0 +1,9 @@
package photoserrors
import "errors"
var (
// Account
ErrAccountExists = errors.New("account exists")
ErrAccountAuth = errors.New("login or password incorrect")
)

View File

@ -0,0 +1,9 @@
package photoserrors
import "errors"
var (
// Album
ErrAlbumDontExists = errors.New("album doesn't exists")
)

View File

@ -0,0 +1,9 @@
package photoserrors
import "errors"
var (
// Panic
ErrUnexpected = errors.New("an unexpected error occur")
)

View File

@ -0,0 +1,9 @@
package photoserrors
import "errors"
var (
// Request
ErrReqMissingBody = errors.New("missing body")
ErrReqNotFound = errors.New("this route doesn't exists")
)

View File

@ -0,0 +1,10 @@
package photoserrors
import "errors"
var (
// Session
ErrSessionNotFound = errors.New("session not found")
ErrSessionInvalid = errors.New("session invalid")
ErrTokenMissing = errors.New("token missing")
)

View File

@ -0,0 +1,14 @@
package photoserrors
import "errors"
var (
// Store
ErrStorePathNotADirectory = errors.New("store path is not a directory")
ErrStoreBadChecksum = errors.New("checksum should be sha1 in hex format")
ErrStoreBadChunkSize = errors.New("part file size should be 1MB max")
ErrStoreMissingChunks = errors.New("part checksum missing")
ErrStoreWrongChecksum = errors.New("wrong checksum")
ErrStoreMismatchChecksum = errors.New("part files doesn't match the original checksum")
ErrStoreAlreadyExists = errors.New("original file already exists")
)

View File

@ -7,6 +7,8 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"gitlab.celogeek.com/photos/api/internal/photoserrors"
) )
type Store struct { type Store struct {
@ -40,7 +42,7 @@ func (s *Store) SaveTemp(path string, sumb string, b []byte) error {
sumString := hex.EncodeToString(sum.Sum(nil)) sumString := hex.EncodeToString(sum.Sum(nil))
if sumb != sumString { if sumb != sumString {
return errors.New("wrong checksum") return photoserrors.ErrStoreWrongChecksum
} }
dir := s.Dir(path, sumString) dir := s.Dir(path, sumString)
@ -89,7 +91,7 @@ func (s *Store) CommitTemp(path string, sumb []string) error {
originalname := filepath.Join(originaldir, path) originalname := filepath.Join(originaldir, path)
if s.FileExists(originalname) { if s.FileExists(originalname) {
return fmt.Errorf("original file already exists") return photoserrors.ErrStoreAlreadyExists
} }
os.MkdirAll(originaldir, 0755) os.MkdirAll(originaldir, 0755)