From 6705d08a16be3ffbc1e86f9f484928350d423376 Mon Sep 17 00:00:00 2001 From: ravonzz Date: Fri, 7 Jun 2024 17:52:09 +0500 Subject: [PATCH] Code Refactoring and Added Buy Product --- controllers/manufacturerController.go | 88 ++----- controllers/productController.go | 197 ++++++++------- controllers/userController.go | 225 +++++------------- database/models.go | 11 +- .../Manufacturer/Create Manufacturer.bru | 2 +- .../Manufacturer/Delete Manufacturer.bru | 2 +- golang-test/Manufacturer/EDIT Manufacture.bru | 4 +- golang-test/Product/Get Product Info.bru | 2 +- golang-test/Product/Get Products.bru | 10 +- golang-test/environments/golang-test.bru | 3 +- libs/libs.go | 29 ++- main.go | 28 ++- message/message.go | 19 -- types/requests.go | 20 ++ types/responses.go | 51 ++++ types/types.go | 10 - 16 files changed, 314 insertions(+), 387 deletions(-) delete mode 100644 message/message.go create mode 100644 types/requests.go create mode 100644 types/responses.go delete mode 100644 types/types.go diff --git a/controllers/manufacturerController.go b/controllers/manufacturerController.go index bab3308..2eb1daa 100644 --- a/controllers/manufacturerController.go +++ b/controllers/manufacturerController.go @@ -5,120 +5,72 @@ import ( "github.com/go-playground/validator/v10" "golang-test/database" "golang-test/libs" - "golang-test/message" "golang-test/types" "golang-test/validators" - "log" + "net/http" ) func CreateManufacturer(c *gin.Context, manufacturer database.Manufacturer) { db := database.Connector() validate := validators.Validate - response := message.Response{Status: 200} if err := validate.Struct(manufacturer); err != nil { - response.Error = libs.GetValidationErrors(err.(validator.ValidationErrors)) - response.Status = 400 - message.SendResponse(c, response) - return + c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors))) } if err := db.Create(&manufacturer).Error; err != nil { - log.Println(err.Error()) - response.Error = gin.H{ - "error": err.Error(), - } - - response.Status = 500 - message.SendResponse(c, response) - return + c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: err.Error()}) } - response.Message = gin.H{ - "message": "Manufacturer created", - } - - message.SendResponse(c, response) + c.JSON(http.StatusCreated, types.MessageResponse{Message: "Manufacturer created successfully"}) } func DeleteManufacturer(c *gin.Context) { db := database.Connector() - response := message.Response{Status: 200} id := c.Param("id") var manufacturer database.Manufacturer if db.First(&manufacturer, id).Error != nil { - response.Error = gin.H{ - "error": "Manufacturer with id '" + id + "' not found", - } - response.Status = 404 - message.SendResponse(c, response) - return + c.JSON(http.StatusNotFound, types.NotFoundError("Manufacturer", id)) } - db.Delete(&manufacturer, id) - - response.Message = gin.H{ - "message": "Manufacturer deleted", + if err := db.Delete(&manufacturer, id).Error; err != nil { + c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: err.Error()}) } - message.SendResponse(c, response) + + c.JSON(http.StatusOK, types.MessageResponse{Message: "Manufacturer deleted successfully"}) } func GetManufacturers(c *gin.Context) { - - type ManufacturerResponse struct { - ID uint - Name string - } - db := database.Connector() - response := message.Response{Status: 200} - var manufacturers []ManufacturerResponse + var manufacturers []types.ManufacturerResponse - db.Model(&database.Manufacturer{}).Select("ID", "Name").Scan(&manufacturers) - - response.Message = gin.H{ - "manufacturers": manufacturers, + if err := db.Model(&database.Manufacturer{}).Select("ID", "Name").Scan(&manufacturers).Error; err != nil { + c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: err.Error()}) } - message.SendResponse(c, response) + c.JSON(http.StatusOK, manufacturers) } func EditManufacture(c *gin.Context, editedManufacturer types.ManufacturerPatchRequest) { db := database.Connector() - response := message.Response{Status: 200} id := c.Param("id") - - validate := validators.Validate - err := validate.Struct(editedManufacturer) - - if err != nil { - response.Error = libs.GetValidationErrors(err.(validator.ValidationErrors)) - response.Status = 400 - message.SendResponse(c, response) - return - } - var manufacturer database.Manufacturer + validate := validators.Validate + if err := validate.Struct(editedManufacturer); err != nil { + c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors))) + } + if db.First(&manufacturer, id).Error != nil { - response.Error = gin.H{ - "error": "Manufacturer with id '" + id + "' not found", - } - response.Status = 404 - message.SendResponse(c, response) - return + c.JSON(http.StatusNotFound, types.NotFoundError("Manufacturer", id)) } db.First(&manufacturer, id) manufacturer.Name = editedManufacturer.Name db.Save(&manufacturer) - response.Message = gin.H{ - "message": "Manufacturer edited", - } - - message.SendResponse(c, response) + c.JSON(http.StatusOK, types.MessageResponse{Message: "Manufacturer edited successfully"}) } diff --git a/controllers/productController.go b/controllers/productController.go index 8570b29..b2fa07c 100644 --- a/controllers/productController.go +++ b/controllers/productController.go @@ -5,9 +5,10 @@ import ( "github.com/go-playground/validator/v10" "golang-test/database" "golang-test/libs" - "golang-test/message" + "golang-test/types" "golang-test/validators" "log" + "net/http" "strconv" //"golang-test/migrations" ) @@ -15,120 +16,154 @@ import ( func CreateProduct(c *gin.Context, product database.Product) { db := database.Connector() validate := validators.Validate - response := message.Response{Status: 200} + //response := types.MessageResponse{Message: "Product Created"} + var manufacturer *database.Manufacturer - err := validate.Struct(product) - - if err != nil { - response.Error = libs.GetValidationErrors(err.(validator.ValidationErrors)) - response.Status = 400 - message.SendResponse(c, response) + if err := validate.Struct(&product); err != nil { + c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors))) return } - if err := db.First(&database.Manufacturer{}, product.ManufacturerID).Error; err != nil { - response.Error = gin.H{ - "error": "Manufacturer with id '" + strconv.Itoa(int(product.ManufacturerID)) + "' not found", - } - } - - err = db.Create(&product).Error - - if err != nil { - log.Println(err.Error()) - response.Error = gin.H{ - "error": err.Error(), - } - - response.Status = 500 - message.SendResponse(c, response) + if err := db.First(&manufacturer, product.ManufacturerID).Error; err != nil { + c.JSON(http.StatusBadRequest, types.NotFoundError("Product", product.ManufacturerID)) return } - response.Message = gin.H{ - "message": "Product created", + product.Manufacturer = manufacturer + + log.Println(*product.Manufacturer) + + if err := db.Create(&product).Error; err != nil { + c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: err.Error()}) + return } - message.SendResponse(c, response) + c.JSON(http.StatusCreated, types.MessageResponse{Message: "Product created"}) } func DeleteProduct(c *gin.Context) { db := database.Connector() - response := message.Response{Status: 200} id := c.Param("id") var product database.Product + response := types.MessageResponse{ + Message: "Product deleted", + } + if db.First(&product, id).Error != nil { - response.Error = gin.H{ - "error": "Product with id '" + id + "' not found", - } - response.Status = 404 - message.SendResponse(c, response) + c.JSON(http.StatusNotFound, types.NotFoundError("Product", id)) return } db.Delete(&product, id) - response.Message = gin.H{ - "message": "Product deleted", - } - - message.SendResponse(c, response) + c.JSON(http.StatusOK, response) } -//func GetProducts(c *gin.Context) { -// -// db := database.Connector() -// response := message.Response{Status: 200} -// var product []database.Product -// -// resp := []interface{}{} -// -// db.Find(&product) -// -// for _, productItem := range product { -// resp = append(resp, gin.H{ -// "id": productItem.ID, -// "name": productItem.Name, -// "price": productItem.Price, -// "manufacturer_ID": productItem.Manufacturer.ID, -// "manufacturer_Name": productItem.Manufacturer.Name, -// }) -// log.Println(productItem.Manufacturer.Name) -// } -// -// response.Message = gin.H{ -// "products": resp, -// } -// -// message.SendResponse(c, response) -//} +func GetProducts(c *gin.Context) { + db := database.Connector() + var product []database.Product + var productResp []types.ProductResponse + + db.Find(&product).Scan(&productResp) + + for i, element := range productResp { + var manufacturer types.ManufacturerResponse + db.First(&database.Manufacturer{}, element.ManufacturerID).Scan(&manufacturer) + productResp[i].Manufacturer = manufacturer + } + + c.JSON(http.StatusOK, productResp) +} func GetProductInfo(c *gin.Context) { db := database.Connector() - response := message.Response{Status: 200} - id := c.Param("id") + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: err.Error()}) + } + + //var productResponse types.ProductResponse var product database.Product + var productResp types.ProductResponse + var manufacturer types.ManufacturerResponse - if err := db.First(&product, id).Error; err != nil { - response.Error = gin.H{ - "error": "Product with id '" + id + "' not found", - } - response.Status = 404 - message.SendResponse(c, response) + if err := db.First(&product, id).Select("ID", "Name", "Price", "ManufacturerID").Scan(&productResp).Error; err != nil { + c.JSON(http.StatusBadRequest, types.NotFoundError("Product", id)) return } - response.Message = gin.H{ - "product": gin.H{ - "id": product.ID, - "name": product.Name, - "price": product.Price, - "manufacturer_ID": product.ManufacturerID, - "manufacturer_Name": product.Manufacturer.Name, - }, + if err := db.First(&product.Manufacturer, product.ManufacturerID).Scan(&manufacturer).Error; err != nil { + c.JSON(http.StatusBadRequest, types.NotFoundError("Product", product.ManufacturerID)) + return } + productResp.Manufacturer = manufacturer + log.Println(product.Manufacturer) + + c.JSON(http.StatusOK, productResp) +} + +func BuyProduct(c *gin.Context) { + var product database.Product + + db := database.Connector() + id, err := strconv.Atoi(c.Param("id")) + + if err != nil { + c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: err.Error()}) + return + } + + if err := db.First(&product, id).Error; err != nil { + c.JSON(http.StatusBadRequest, types.NotFoundError("Product", id)) + return + } + + token, err := libs.GetTokenFromHeaders(c) + + if err != nil { + c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"}) + return + } + + u, err := GetUserByToken(token) + if err != nil { + c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"}) + return + } + + if u.Money-product.Price < 0 { + c.JSON(http.StatusOK, types.MessageResponse{Message: "Not enough money"}) + return + } + + u.Money -= product.Price + + u.Products = append(u.Products, product) + + db.Save(&u) + + c.JSON(http.StatusOK, types.MessageResponse{Message: "Product successful buyed"}) +} + +func GetBuyedProducts(c *gin.Context) { + db := database.Connector() + + token, err := libs.GetTokenFromHeaders(c) + + if err != nil { + c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"}) + return + } + + u, err := GetUserByToken(token) + if err != nil { + c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"}) + return + } + + db.Joins("Products").First(&u) } diff --git a/controllers/userController.go b/controllers/userController.go index dc750bc..222d786 100644 --- a/controllers/userController.go +++ b/controllers/userController.go @@ -1,7 +1,5 @@ package controllers -// Пример генератора токена - import ( "crypto/rand" "encoding/base64" @@ -9,93 +7,47 @@ import ( "github.com/go-playground/validator/v10" "golang-test/database" "golang-test/libs" - "golang-test/message" "golang-test/types" "golang-test/validators" "golang.org/x/crypto/bcrypt" - "strings" + "log" + "net/http" ) -//func tokenGenerator() string { -// b := make([]byte, 4) -// rand.Read(b) -// return fmt.Sprintf("%x", b) -//} - -// func main() { -// a := tokenGenerator() -// fmt.Println(a) -// } - type TokenStruct struct { UserID uint token string } -//func RegisterUser(c *gin.Context, user database.User) { -// db := database.Connector() -// validate := validators.Validate -// response := message.Response{Status: 200} -// if err := validate.Struct(user); err != nil { -// response.Error = libs.GetValidationErrors(err.(validator.ValidationErrors)) -// response.Status = 400 -// message.SendResponse(c, response) -// return -// } -// hash, err := bcrypt.GenerateFromPassword([]byte(user.Password), 12) -// if err != nil { -// return -// } -// user.Password = string(hash) -// if err := db.Create(user).Error; err != nil { -// return -// } -// return -//} - -func RegisterUser(c *gin.Context, register database.User) { - var user database.User +func RegisterUser(c *gin.Context, register types.RegisterRequest) { db := database.Connector() validate := validators.Validate - response := message.Response{Status: 201} - var token *database.Token + var token database.Token if err := validate.Struct(register); err != nil { - response.Error = libs.GetValidationErrors(err.(validator.ValidationErrors)) - response.Status = 400 - message.SendResponse(c, response) - return + c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors))) } - if err := db.Where("email =?", register.Email).First(&user).Error; err == nil { - response.Status = 400 - response.Error = gin.H{ - "error": "User already exists", - } - message.SendResponse(c, response) + if err := db.Where("email =?", register.Email).Error; err == nil { + c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: "User already exists"}) return } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(register.Password), 12) if err != nil { - response.Status = 500 - response.Error = gin.H{ - "error": "Internal Server Error", - } - message.SendResponse(c, response) + log.Println(err.Error()) + c.JSON(http.StatusInternalServerError, types.ErrorResponse{Message: err.Error()}) return } - user.Email = register.Email - user.Password = string(hashedPassword) - user.Name = register.Name + user := database.User{ + Name: register.Name, + Email: register.Email, + Password: string(hashedPassword), + } if err := db.Create(&user).Error; err != nil { - response.Status = 500 - response.Error = gin.H{ - "error": "Internal Server Error", - } - message.SendResponse(c, response) + c.JSON(http.StatusInternalServerError, types.ErrorResponse{Message: err.Error()}) return } @@ -103,53 +55,42 @@ func RegisterUser(c *gin.Context, register database.User) { token.UserID = user.ID user.Tokens = append(user.Tokens, token) - response.Message = gin.H{ - "message": "Registration Success", - } - - message.SendResponse(c, response) + c.JSON(http.StatusCreated, types.TokenResponse{Token: token.Token}) } func LoginUser(c *gin.Context, login types.LoginRequest) { var user database.User db := database.Connector() validate := validators.Validate - response := message.Response{Status: 200} - var token *database.Token + var token database.Token if err := validate.Struct(login); err != nil { - response.Error = libs.GetValidationErrors(err.(validator.ValidationErrors)) - response.Status = 400 - message.SendResponse(c, response) + c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors))) return } + if err := db.Where("email = ?", login.Email).First(&user).Error; err != nil { - response.Status = 404 - response.Error = gin.H{ - "error": "User not found", - } + c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: "Invalid email or password"}) + return } if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(login.Password)); err != nil { - response.Status = 404 - response.Error = gin.H{ - "error": "User not found", - } + c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: "Invalid email or password"}) + return } token.Token = generateToken() token.UserID = user.ID + user.Tokens = append(user.Tokens, token) - response.Message = gin.H{ - "message": "Login Success", - } + db.Save(&user) - message.SendResponse(c, response) + c.JSON(http.StatusOK, types.TokenResponse{Token: token.Token}) } func generateToken() string { - b := make([]byte, 4) + b := make([]byte, 25) if _, err := rand.Read(b); err != nil { return "" } @@ -157,7 +98,7 @@ func generateToken() string { } func GetUserByToken(token string) (database.User, error) { - var tokenObject TokenStruct + var tokenObject database.Token var err error var user database.User @@ -165,115 +106,55 @@ func GetUserByToken(token string) (database.User, error) { if err := db.Where("token = ?", token).First(&tokenObject).Error; err != nil { return user, err } + if err := db.First(&user, tokenObject.UserID).Error; err != nil { return user, err } return user, err } -func GetUser(c *gin.Context, user database.User) { - token := strings.Split(c.Request.Header["Bearer"][0], " ")[1] - validate := validators.Validate - response := message.Response{Status: 200} +func GetUser(c *gin.Context) { + token, err := libs.GetTokenFromHeaders(c) + + if err != nil { + c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"}) + } + u, err := GetUserByToken(token) if err != nil { - response.Status = 401 - response.Error = gin.H{ - "error": "Token is invalid, please login", - } - message.SendResponse(c, response) + c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"}) return } - if err := validate.Struct(user); err != nil { - response.Error = libs.GetValidationErrors(err.(validator.ValidationErrors)) - response.Status = 400 - message.SendResponse(c, response) - return - } - - response.Message = gin.H{ - "message": "User data successfully received", - "user": u, - } - message.SendResponse(c, response) + c.JSON(http.StatusOK, u) } -func EditUser(c *gin.Context, user database.User) { - token := strings.Split(c.Request.Header["Bearer"][0], " ")[1] +func EditUserName(c *gin.Context, userName types.EditUserNameRequest) { + token, err := libs.GetTokenFromHeaders(c) + if err != nil { + c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"}) + } db := database.Connector() validate := validators.Validate - response := message.Response{Status: 200} + + if err := validate.Struct(userName); err != nil { + c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors))) + return + } + u, err := GetUserByToken(token) if err != nil { - response.Status = 401 - response.Error = gin.H{ - "error": "Token is invalid, please login", - } - message.SendResponse(c, response) + c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"}) return } - if err := validate.Struct(user); err != nil { - response.Error = libs.GetValidationErrors(err.(validator.ValidationErrors)) - response.Status = 400 - message.SendResponse(c, response) - return - } - - hash, err := bcrypt.GenerateFromPassword([]byte(user.Password), 12) - if err != nil { - response.Status = 500 - response.Error = gin.H{ - "error": err, - } - message.SendResponse(c, response) - return - } - - u.Password = string(hash) + u.Name = userName.Name if err := db.Save(u).Error; err != nil { - response.Status = 500 - response.Error = gin.H{ - "error": err, - } - message.SendResponse(c, response) + c.JSON(http.StatusInternalServerError, types.ErrorResponse{Message: err.Error()}) return } - response.Message = gin.H{ - "message": "User successfully updated", - } - message.SendResponse(c, response) -} - -func DeleteUser(c *gin.Context) { - token := strings.Split(c.Request.Header["Bearer"][0], " ")[1] - db := database.Connector() - u, err := GetUserByToken(token) - response := message.Response{Status: 200} - if err != nil { - response.Status = 401 - response.Error = gin.H{ - "error": "Token is invalid, please login", - } - message.SendResponse(c, response) - return - } - - if err := db.Delete(u).Error; err != nil { - response.Status = 500 - response.Error = gin.H{ - "error": err, - } - message.SendResponse(c, response) - return - } - - response.Message = gin.H{ - "message": "User successfully deleted", - } - message.SendResponse(c, response) + c.JSON(http.StatusOK, types.MessageResponse{Message: "User name successfully updated"}) } diff --git a/database/models.go b/database/models.go index d20d354..2292076 100644 --- a/database/models.go +++ b/database/models.go @@ -24,9 +24,10 @@ type Token struct { type User struct { gorm.Model - Name string `validate:"required"` - Email string `validate:"required"` - Password string `validate:"required"` - Products []*Product `gorm:"many2many:user_products;"` - Tokens []*Token `gorm:"many2many:user_token;"` + Name string `validate:"required"` + Email string `validate:"required"` + Password string `validate:"required"` + Products []Product `gorm:"many2many:user_products;"` + Tokens []Token `gorm:"many2many:user_token;"` + Money uint `gorm:"default:0"` } diff --git a/golang-test/Manufacturer/Create Manufacturer.bru b/golang-test/Manufacturer/Create Manufacturer.bru index 531eaa0..43733a2 100644 --- a/golang-test/Manufacturer/Create Manufacturer.bru +++ b/golang-test/Manufacturer/Create Manufacturer.bru @@ -12,6 +12,6 @@ post { body:json { { - "name": "Тест 1" + "name": "Тест 123" } } diff --git a/golang-test/Manufacturer/Delete Manufacturer.bru b/golang-test/Manufacturer/Delete Manufacturer.bru index 824300e..0a46b85 100644 --- a/golang-test/Manufacturer/Delete Manufacturer.bru +++ b/golang-test/Manufacturer/Delete Manufacturer.bru @@ -5,7 +5,7 @@ meta { } delete { - url: {{host}}/manufacturer/{{manufacturerID}} + url: {{host}}/manufacturer/6 body: none auth: none } diff --git a/golang-test/Manufacturer/EDIT Manufacture.bru b/golang-test/Manufacturer/EDIT Manufacture.bru index 0b12460..7bf53ae 100644 --- a/golang-test/Manufacturer/EDIT Manufacture.bru +++ b/golang-test/Manufacturer/EDIT Manufacture.bru @@ -5,13 +5,13 @@ meta { } patch { - url: {{host}}/manufacturer/{{manufacturerID}} + url: {{host}}/manufacturer/5 body: json auth: none } body:json { { - "name": "Test3" + "name": "Sdsad" } } diff --git a/golang-test/Product/Get Product Info.bru b/golang-test/Product/Get Product Info.bru index 283d39e..fa4db10 100644 --- a/golang-test/Product/Get Product Info.bru +++ b/golang-test/Product/Get Product Info.bru @@ -5,7 +5,7 @@ meta { } get { - url: + url: {{host}}/product/19 body: none auth: none } diff --git a/golang-test/Product/Get Products.bru b/golang-test/Product/Get Products.bru index b85a317..fd9937f 100644 --- a/golang-test/Product/Get Products.bru +++ b/golang-test/Product/Get Products.bru @@ -4,20 +4,12 @@ meta { seq: 3 } -post { +get { url: {{host}}/product body: json auth: none } -body:json { - { - "name": "Яблоко", - "price": 5, - "manufacturerID": 1 - } -} - body:multipart-form { name: Яблоко price: 5 diff --git a/golang-test/environments/golang-test.bru b/golang-test/environments/golang-test.bru index 578588d..b29ff36 100644 --- a/golang-test/environments/golang-test.bru +++ b/golang-test/environments/golang-test.bru @@ -1,5 +1,6 @@ vars { host: http://localhost:8080 manufacturerID: 1 - productID: 2 + productID: 6 + token: TPqB2mHBjRkvLpH3M6kWSWVMj7O75t665g== } diff --git a/libs/libs.go b/libs/libs.go index 43152db..09f55b8 100644 --- a/libs/libs.go +++ b/libs/libs.go @@ -1,20 +1,25 @@ package libs import ( + "errors" "github.com/gin-gonic/gin" "github.com/go-playground/validator/v10" + "golang-test/types" + "net/http" "strings" ) -func GetValidationErrors(errs validator.ValidationErrors) gin.H { - errors := make(map[string]any) +type ValidationErrorsType struct { + Errors map[string]string `json:"errors"` +} + +func GetValidationErrors(errs validator.ValidationErrors) ValidationErrorsType { + errors := make(map[string]string) for _, err := range errs { errors[err.Field()] = err.Error() } - return gin.H{ - "error": errors, - } + return ValidationErrorsType{Errors: errors} } func ToSnakeCase(str string) string { @@ -27,3 +32,17 @@ func ToSnakeCase(str string) string { } return strings.ToLower(string(result)) } + +func GetTokenFromHeaders(c *gin.Context) (string, error) { + if c.Request.Header["Authorization"] == nil { + return "", errors.New("Authorization required") + } + + if len(strings.Split(c.Request.Header["Authorization"][0], " ")) < 2 { + c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"}) + return "", errors.New("Authorization required") + } + token := strings.Split(c.Request.Header["Authorization"][0], " ")[1] + + return token, nil +} diff --git a/main.go b/main.go index c4a483e..2b37539 100644 --- a/main.go +++ b/main.go @@ -72,9 +72,10 @@ func main() { //View для создания пользователя r.POST("/registration", func(c *gin.Context) { - var form database.User + var form types.RegisterRequest if err := c.ShouldBind(&form); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return } controllers.RegisterUser(c, form) @@ -85,6 +86,7 @@ func main() { var register types.LoginRequest if err := c.ShouldBind(®ister); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return } controllers.LoginUser(c, register) }) @@ -93,26 +95,28 @@ func main() { var user database.User if err := c.ShouldBind(&user); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return } - controllers.LoginUser(c, user) + controllers.GetUser(c) }) //View для редактированя пользователя - r.PATCH("/user/edit", func(c *gin.Context) { - var user database.User + r.PATCH("/user", func(c *gin.Context) { + var user types.EditUserNameRequest if err := c.ShouldBind(&user); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) } - controllers.EditUser(c, user) + controllers.EditUserName(c, user) }) - //View для удаления пользователя - r.DELETE("/user/delete", func(c *gin.Context) { - var form types.LoginRequest - if err := c.ShouldBind(&form); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - } - controllers.DeleteUser(c) + //View для покупки товара + r.GET("/product/:id/buy", func(c *gin.Context) { + controllers.BuyProduct(c) + }) + + //View для просмотра купленных товаров + r.GET("/user/products", func(c *gin.Context) { + controllers.GetBuyedProducts(c) }) err := r.Run() diff --git a/message/message.go b/message/message.go deleted file mode 100644 index 0498f91..0000000 --- a/message/message.go +++ /dev/null @@ -1,19 +0,0 @@ -package message - -import ( - "github.com/gin-gonic/gin" -) - -type Response struct { - Status int - Message gin.H - Error gin.H -} - -func SendResponse(c *gin.Context, response Response) { - if len(response.Message) > 0 { - c.JSON(response.Status, response.Message) - } else if len(response.Error) > 0 { - c.JSON(response.Status, response.Error) - } -} diff --git a/types/requests.go b/types/requests.go new file mode 100644 index 0000000..15f091a --- /dev/null +++ b/types/requests.go @@ -0,0 +1,20 @@ +package types + +type ManufacturerPatchRequest struct { + Name string `validate:"required"` +} + +type LoginRequest struct { + Email string `validate:"required,email"` + Password string `validate:"required"` +} + +type RegisterRequest struct { + Name string `validate:"required"` + Email string `validate:"required,email"` + Password string `validate:"required"` +} + +type EditUserNameRequest struct { + Name string `validate:"required"` +} diff --git a/types/responses.go b/types/responses.go new file mode 100644 index 0000000..c0f6e5a --- /dev/null +++ b/types/responses.go @@ -0,0 +1,51 @@ +package types + +import ( + "github.com/go-playground/validator/v10" + "reflect" + "strconv" +) + +type ManufacturerResponse struct { + ID string + Name string +} + +type ProductResponse struct { + ID uint + Name string + Price uint + ManufacturerID uint + Manufacturer ManufacturerResponse +} + +type TokenResponse struct { + Token string +} + +type ErrorResponse struct { + Message string `json:"error"` +} + +type ValidationErrorResponse struct { + Errors validator.ValidationErrors `json:"error"` +} + +func NotFoundError(obj string, id interface{}) ErrorResponse { + var idStr string + switch reflect.TypeOf(id).Kind() { + case reflect.String: + idStr = id.(string) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + idStr = strconv.FormatInt(reflect.ValueOf(id).Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + idStr = strconv.FormatUint(reflect.ValueOf(id).Uint(), 10) + default: + idStr = "" + } + return ErrorResponse{Message: obj + " with id " + idStr + " not found"} +} + +type MessageResponse struct { + Message string `json:"message"` +} diff --git a/types/types.go b/types/types.go deleted file mode 100644 index eabbbdb..0000000 --- a/types/types.go +++ /dev/null @@ -1,10 +0,0 @@ -package types - -type ManufacturerPatchRequest struct { - Name string `validate:"required"` -} - -type LoginRequest struct { - Email string `validate:"required,email"` - Password string `validate:"required"` -}