diff --git a/go.mod b/go.mod index e86cb2f..dce34b7 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module food-app -go 1.13 +go 1.17 require ( - github.com/aws/aws-sdk-go v1.29.30 github.com/badoux/checkmail v0.0.0-20181210160741-9661bd69e9ad github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/gin-gonic/gin v1.5.0 github.com/go-redis/redis/v7 v7.0.0-beta.6 + github.com/go-sql-driver/mysql v1.5.0 // indirect github.com/jinzhu/gorm v1.9.12 github.com/joho/godotenv v1.3.0 github.com/minio/minio-go/v6 v6.0.50 @@ -15,5 +15,6 @@ require ( github.com/stretchr/testify v1.4.0 github.com/twinj/uuid v1.0.0 golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd + golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect gopkg.in/stretchr/testify.v1 v1.2.2 // indirect ) diff --git a/go.sum b/go.sum index d6988bf..baabbac 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -github.com/aws/aws-sdk-go v1.29.30 h1:HEEb7p5H850+hKVLRif2fWpaoJe5ZkZ5WUJwJ+CKWV4= -github.com/aws/aws-sdk-go v1.29.30/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg= github.com/badoux/checkmail v0.0.0-20181210160741-9661bd69e9ad h1:kXfVkP8xPSJXzicomzjECcw6tv1Wl9h1lNenWBfNKdg= github.com/badoux/checkmail v0.0.0-20181210160741-9661bd69e9ad/go.mod h1:r5ZalvRl3tXevRNJkwIB6DC4DD3DMjIlY9NEU1XGoaQ= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -24,7 +22,6 @@ github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rm github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= github.com/go-redis/redis/v7 v7.0.0-beta.6 h1:ApjPvZNUF+/oVHwrTBQsVOwex5v/WapUUR4bOL2kMFA= github.com/go-redis/redis/v7 v7.0.0-beta.6/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg= -github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -44,8 +41,6 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M= github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= @@ -83,7 +78,6 @@ github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -113,7 +107,6 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -122,7 +115,6 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -131,9 +123,7 @@ golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -150,7 +140,6 @@ gopkg.in/stretchr/testify.v1 v1.2.2/go.mod h1:QI5V/q6UbPmuhtm10CaFZxED9NreB8PnFY gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/infrastructure/persistence/food_repository.go b/infrastructure/persistence/food_repository.go index ee190e6..31eaaa4 100644 --- a/infrastructure/persistence/food_repository.go +++ b/infrastructure/persistence/food_repository.go @@ -1,90 +1,91 @@ package persistence import ( - "errors" - "food-app/domain/entity" - "food-app/domain/repository" - "github.com/jinzhu/gorm" - "os" - "strings" -) + "errors" + "os" + "strings" + + "github.com/jinzhu/gorm" + "food-app/domain/entity" + "food-app/domain/repository" +) type FoodRepo struct { - db *gorm.DB + db *gorm.DB } func NewFoodRepository(db *gorm.DB) *FoodRepo { - return &FoodRepo{db} + return &FoodRepo{db} } -//FoodRepo implements the repository.FoodRepository interface +// FoodRepo implements the repository.FoodRepository interface var _ repository.FoodRepository = &FoodRepo{} func (r *FoodRepo) SaveFood(food *entity.Food) (*entity.Food, map[string]string) { - dbErr := map[string]string{} - //The images are uploaded to digital ocean spaces. So we need to prepend the url. This might not be your use case, if you are not uploading image to Digital Ocean. - food.FoodImage = os.Getenv("DO_SPACES_URL") + food.FoodImage + dbErr := map[string]string{} + // The images are uploaded to digital ocean spaces. So we need to prepend the url. This might not be your use case, if you are not uploading image to Digital Ocean. + food.FoodImage = os.Getenv("DO_SPACES_URL") + food.FoodImage - err := r.db.Debug().Create(&food).Error - if err != nil { - //since our title is unique - if strings.Contains(err.Error(), "duplicate") || strings.Contains(err.Error(), "Duplicate") { - dbErr["unique_title"] = "food title already taken" - return nil, dbErr - } - //any other db error - dbErr["db_error"] = "database error" - return nil, dbErr - } - return food, nil + err := r.db.Debug().Create(&food).Error + if err != nil { + // since our title is unique + if strings.Contains(err.Error(), "duplicate") || strings.Contains(err.Error(), "Duplicate") { + dbErr["unique_title"] = "food title already taken" + return nil, dbErr + } + // any other db error + dbErr["db_error"] = "database error" + return nil, dbErr + } + return food, nil } func (r *FoodRepo) GetFood(id uint64) (*entity.Food, error) { - var food entity.Food - err := r.db.Debug().Where("id = ?", id).Take(&food).Error - if err != nil { - return nil, errors.New("database error, please try again") - } - if gorm.IsRecordNotFoundError(err) { - return nil, errors.New("food not found") - } - return &food, nil + var food entity.Food + err := r.db.Debug().Where("id = ?", id).Take(&food).Error + if gorm.IsRecordNotFoundError(err) { + return nil, errors.New("food not found") + } + if err != nil { + return nil, errors.New("database error, please try again") + } + return &food, nil } func (r *FoodRepo) GetAllFood() ([]entity.Food, error) { - var foods []entity.Food - err := r.db.Debug().Limit(100).Order("created_at desc").Find(&foods).Error - if err != nil { - return nil, err - } - if gorm.IsRecordNotFoundError(err) { - return nil, errors.New("user not found") - } - return foods, nil + var foods []entity.Food + err := r.db.Debug().Limit(100).Order("created_at desc").Find(&foods).Error + if gorm.IsRecordNotFoundError(err) { + return nil, errors.New("user not found") + } + if err != nil { + return nil, err + } + return foods, nil } func (r *FoodRepo) UpdateFood(food *entity.Food) (*entity.Food, map[string]string) { - dbErr := map[string]string{} - err := r.db.Debug().Save(&food).Error - if err != nil { - //since our title is unique - if strings.Contains(err.Error(), "duplicate") || strings.Contains(err.Error(), "Duplicate") { - dbErr["unique_title"] = "title already taken" - return nil, dbErr - } - //any other db error - dbErr["db_error"] = "database error" - return nil, dbErr - } - return food, nil + dbErr := map[string]string{} + err := r.db.Debug().Save(&food).Error + if err != nil { + // since our title is unique + if strings.Contains(err.Error(), "duplicate") || strings.Contains(err.Error(), "Duplicate") { + dbErr["unique_title"] = "title already taken" + return nil, dbErr + } + // any other db error + dbErr["db_error"] = "database error" + return nil, dbErr + } + return food, nil } func (r *FoodRepo) DeleteFood(id uint64) error { - var food entity.Food - err := r.db.Debug().Where("id = ?", id).Delete(&food).Error - if err != nil { - return errors.New("database error, please try again") - } - return nil + var food entity.Food + err := r.db.Debug().Where("id = ?", id).Delete(&food).Error + if err != nil { + return errors.New("database error, please try again") + } + return nil } diff --git a/infrastructure/persistence/user_repository.go b/infrastructure/persistence/user_repository.go index 81b4343..9ee2a58 100644 --- a/infrastructure/persistence/user_repository.go +++ b/infrastructure/persistence/user_repository.go @@ -1,82 +1,85 @@ package persistence import ( - "errors" - "food-app/domain/entity" - "food-app/domain/repository" - "food-app/infrastructure/security" - "github.com/jinzhu/gorm" - "golang.org/x/crypto/bcrypt" - "strings" + "errors" + "strings" + + "github.com/jinzhu/gorm" + "golang.org/x/crypto/bcrypt" + + "food-app/domain/entity" + "food-app/domain/repository" + "food-app/infrastructure/security" ) type UserRepo struct { - db *gorm.DB + db *gorm.DB } func NewUserRepository(db *gorm.DB) *UserRepo { - return &UserRepo{db} + return &UserRepo{db} } -//UserRepo implements the repository.UserRepository interface + +// UserRepo implements the repository.UserRepository interface var _ repository.UserRepository = &UserRepo{} func (r *UserRepo) SaveUser(user *entity.User) (*entity.User, map[string]string) { - dbErr := map[string]string{} - err := r.db.Debug().Create(&user).Error - if err != nil { - //If the email is already taken - if strings.Contains(err.Error(), "duplicate") || strings.Contains(err.Error(), "Duplicate") { - dbErr["email_taken"] = "email already taken" - return nil, dbErr - } - //any other db error - dbErr["db_error"] = "database error" - return nil, dbErr - } - return user, nil + dbErr := map[string]string{} + err := r.db.Debug().Create(&user).Error + if err != nil { + // If the email is already taken + if strings.Contains(err.Error(), "duplicate") || strings.Contains(err.Error(), "Duplicate") { + dbErr["email_taken"] = "email already taken" + return nil, dbErr + } + // any other db error + dbErr["db_error"] = "database error" + return nil, dbErr + } + return user, nil } func (r *UserRepo) GetUser(id uint64) (*entity.User, error) { - var user entity.User - err := r.db.Debug().Where("id = ?", id).Take(&user).Error - if err != nil { - return nil, err - } - if gorm.IsRecordNotFoundError(err) { - return nil, errors.New("user not found") - } - return &user, nil + var user entity.User + err := r.db.Debug().Where("id = ?", id).Take(&user).Error + if gorm.IsRecordNotFoundError(err) { + return nil, errors.New("user not found") + } + if err != nil { + return nil, err + } + return &user, nil } func (r *UserRepo) GetUsers() ([]entity.User, error) { - var users []entity.User - err := r.db.Debug().Find(&users).Error - if err != nil { - return nil, err - } - if gorm.IsRecordNotFoundError(err) { - return nil, errors.New("user not found") - } - return users, nil + var users []entity.User + err := r.db.Debug().Find(&users).Error + if gorm.IsRecordNotFoundError(err) { + return nil, errors.New("user not found") + } + if err != nil { + return nil, err + } + return users, nil } func (r *UserRepo) GetUserByEmailAndPassword(u *entity.User) (*entity.User, map[string]string) { - var user entity.User - dbErr := map[string]string{} - err := r.db.Debug().Where("email = ?", u.Email).Take(&user).Error - if gorm.IsRecordNotFoundError(err) { - dbErr["no_user"] = "user not found" - return nil, dbErr - } - if err != nil { - dbErr["db_error"] = "database error" - return nil, dbErr - } - //Verify the password - err = security.VerifyPassword(user.Password, u.Password) - if err != nil && err == bcrypt.ErrMismatchedHashAndPassword { - dbErr["incorrect_password"] = "incorrect password" - return nil, dbErr - } - return &user, nil + var user entity.User + dbErr := map[string]string{} + err := r.db.Debug().Where("email = ?", u.Email).Take(&user).Error + if gorm.IsRecordNotFoundError(err) { + dbErr["no_user"] = "user not found" + return nil, dbErr + } + if err != nil { + dbErr["db_error"] = "database error" + return nil, dbErr + } + // Verify the password + err = security.VerifyPassword(user.Password, u.Password) + if err != nil && err == bcrypt.ErrMismatchedHashAndPassword { + dbErr["incorrect_password"] = "incorrect password" + return nil, dbErr + } + return &user, nil }