move errors
This commit is contained in:
parent
7557e74862
commit
7a266bafd8
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
data
|
data
|
||||||
|
.DS_Store
|
@ -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{
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
|
@ -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)
|
||||||
|
9
internal/photoserrors/accounts.go
Normal file
9
internal/photoserrors/accounts.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package photoserrors
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Account
|
||||||
|
ErrAccountExists = errors.New("account exists")
|
||||||
|
ErrAccountAuth = errors.New("login or password incorrect")
|
||||||
|
)
|
9
internal/photoserrors/albums.go
Normal file
9
internal/photoserrors/albums.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package photoserrors
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var (
|
||||||
|
|
||||||
|
// Album
|
||||||
|
ErrAlbumDontExists = errors.New("album doesn't exists")
|
||||||
|
)
|
9
internal/photoserrors/panic.go
Normal file
9
internal/photoserrors/panic.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package photoserrors
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var (
|
||||||
|
|
||||||
|
// Panic
|
||||||
|
ErrUnexpected = errors.New("an unexpected error occur")
|
||||||
|
)
|
9
internal/photoserrors/requests.go
Normal file
9
internal/photoserrors/requests.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package photoserrors
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Request
|
||||||
|
ErrReqMissingBody = errors.New("missing body")
|
||||||
|
ErrReqNotFound = errors.New("this route doesn't exists")
|
||||||
|
)
|
10
internal/photoserrors/session.go
Normal file
10
internal/photoserrors/session.go
Normal 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")
|
||||||
|
)
|
14
internal/photoserrors/store.go
Normal file
14
internal/photoserrors/store.go
Normal 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")
|
||||||
|
)
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user