Code Refactoring and Added Buy Product

This commit is contained in:
Владимир Шалимов 2024-06-07 17:52:09 +05:00
parent 6790a0ba81
commit 6705d08a16
16 changed files with 314 additions and 387 deletions

View File

@ -5,120 +5,72 @@ import (
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"golang-test/database" "golang-test/database"
"golang-test/libs" "golang-test/libs"
"golang-test/message"
"golang-test/types" "golang-test/types"
"golang-test/validators" "golang-test/validators"
"log" "net/http"
) )
func CreateManufacturer(c *gin.Context, manufacturer database.Manufacturer) { func CreateManufacturer(c *gin.Context, manufacturer database.Manufacturer) {
db := database.Connector() db := database.Connector()
validate := validators.Validate validate := validators.Validate
response := message.Response{Status: 200}
if err := validate.Struct(manufacturer); err != nil { if err := validate.Struct(manufacturer); err != nil {
response.Error = libs.GetValidationErrors(err.(validator.ValidationErrors)) c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors)))
response.Status = 400
message.SendResponse(c, response)
return
} }
if err := db.Create(&manufacturer).Error; err != nil { if err := db.Create(&manufacturer).Error; err != nil {
log.Println(err.Error()) c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: err.Error()})
response.Error = gin.H{
"error": err.Error(),
} }
response.Status = 500 c.JSON(http.StatusCreated, types.MessageResponse{Message: "Manufacturer created successfully"})
message.SendResponse(c, response)
return
}
response.Message = gin.H{
"message": "Manufacturer created",
}
message.SendResponse(c, response)
} }
func DeleteManufacturer(c *gin.Context) { func DeleteManufacturer(c *gin.Context) {
db := database.Connector() db := database.Connector()
response := message.Response{Status: 200}
id := c.Param("id") id := c.Param("id")
var manufacturer database.Manufacturer var manufacturer database.Manufacturer
if db.First(&manufacturer, id).Error != nil { if db.First(&manufacturer, id).Error != nil {
response.Error = gin.H{ c.JSON(http.StatusNotFound, types.NotFoundError("Manufacturer", id))
"error": "Manufacturer with id '" + id + "' not found",
}
response.Status = 404
message.SendResponse(c, response)
return
} }
db.Delete(&manufacturer, id) if err := db.Delete(&manufacturer, id).Error; err != nil {
c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: err.Error()})
response.Message = gin.H{
"message": "Manufacturer deleted",
} }
message.SendResponse(c, response)
c.JSON(http.StatusOK, types.MessageResponse{Message: "Manufacturer deleted successfully"})
} }
func GetManufacturers(c *gin.Context) { func GetManufacturers(c *gin.Context) {
type ManufacturerResponse struct {
ID uint
Name string
}
db := database.Connector() db := database.Connector()
response := message.Response{Status: 200} var manufacturers []types.ManufacturerResponse
var manufacturers []ManufacturerResponse
db.Model(&database.Manufacturer{}).Select("ID", "Name").Scan(&manufacturers) if err := db.Model(&database.Manufacturer{}).Select("ID", "Name").Scan(&manufacturers).Error; err != nil {
c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: err.Error()})
response.Message = gin.H{
"manufacturers": manufacturers,
} }
message.SendResponse(c, response) c.JSON(http.StatusOK, manufacturers)
} }
func EditManufacture(c *gin.Context, editedManufacturer types.ManufacturerPatchRequest) { func EditManufacture(c *gin.Context, editedManufacturer types.ManufacturerPatchRequest) {
db := database.Connector() db := database.Connector()
response := message.Response{Status: 200}
id := c.Param("id") 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 var manufacturer database.Manufacturer
if db.First(&manufacturer, id).Error != nil { validate := validators.Validate
response.Error = gin.H{ if err := validate.Struct(editedManufacturer); err != nil {
"error": "Manufacturer with id '" + id + "' not found", c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors)))
} }
response.Status = 404
message.SendResponse(c, response) if db.First(&manufacturer, id).Error != nil {
return c.JSON(http.StatusNotFound, types.NotFoundError("Manufacturer", id))
} }
db.First(&manufacturer, id) db.First(&manufacturer, id)
manufacturer.Name = editedManufacturer.Name manufacturer.Name = editedManufacturer.Name
db.Save(&manufacturer) db.Save(&manufacturer)
response.Message = gin.H{ c.JSON(http.StatusOK, types.MessageResponse{Message: "Manufacturer edited successfully"})
"message": "Manufacturer edited",
}
message.SendResponse(c, response)
} }

View File

@ -5,9 +5,10 @@ import (
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"golang-test/database" "golang-test/database"
"golang-test/libs" "golang-test/libs"
"golang-test/message" "golang-test/types"
"golang-test/validators" "golang-test/validators"
"log" "log"
"net/http"
"strconv" "strconv"
//"golang-test/migrations" //"golang-test/migrations"
) )
@ -15,120 +16,154 @@ import (
func CreateProduct(c *gin.Context, product database.Product) { func CreateProduct(c *gin.Context, product database.Product) {
db := database.Connector() db := database.Connector()
validate := validators.Validate validate := validators.Validate
response := message.Response{Status: 200} //response := types.MessageResponse{Message: "Product Created"}
var manufacturer *database.Manufacturer
err := validate.Struct(product) if err := validate.Struct(&product); err != nil {
c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors)))
if err != nil {
response.Error = libs.GetValidationErrors(err.(validator.ValidationErrors))
response.Status = 400
message.SendResponse(c, response)
return return
} }
if err := db.First(&database.Manufacturer{}, product.ManufacturerID).Error; err != nil { if err := db.First(&manufacturer, product.ManufacturerID).Error; err != nil {
response.Error = gin.H{ c.JSON(http.StatusBadRequest, types.NotFoundError("Product", product.ManufacturerID))
"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)
return return
} }
response.Message = gin.H{ product.Manufacturer = manufacturer
"message": "Product created",
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) { func DeleteProduct(c *gin.Context) {
db := database.Connector() db := database.Connector()
response := message.Response{Status: 200}
id := c.Param("id") id := c.Param("id")
var product database.Product var product database.Product
if db.First(&product, id).Error != nil { response := types.MessageResponse{
response.Error = gin.H{ Message: "Product deleted",
"error": "Product with id '" + id + "' not found",
} }
response.Status = 404
message.SendResponse(c, response) if db.First(&product, id).Error != nil {
c.JSON(http.StatusNotFound, types.NotFoundError("Product", id))
return return
} }
db.Delete(&product, id) db.Delete(&product, id)
response.Message = gin.H{ c.JSON(http.StatusOK, response)
"message": "Product deleted",
}
message.SendResponse(c, response)
} }
//func GetProducts(c *gin.Context) { func GetProducts(c *gin.Context) {
// db := database.Connector()
// db := database.Connector() var product []database.Product
// response := message.Response{Status: 200} var productResp []types.ProductResponse
// var product []database.Product
// db.Find(&product).Scan(&productResp)
// resp := []interface{}{}
// for i, element := range productResp {
// db.Find(&product) var manufacturer types.ManufacturerResponse
// db.First(&database.Manufacturer{}, element.ManufacturerID).Scan(&manufacturer)
// for _, productItem := range product { productResp[i].Manufacturer = manufacturer
// resp = append(resp, gin.H{ }
// "id": productItem.ID,
// "name": productItem.Name, c.JSON(http.StatusOK, productResp)
// "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 GetProductInfo(c *gin.Context) { func GetProductInfo(c *gin.Context) {
db := database.Connector() db := database.Connector()
response := message.Response{Status: 200} id, err := strconv.Atoi(c.Param("id"))
id := c.Param("id")
var product database.Product if err != nil {
c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: err.Error()})
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) //var productResponse types.ProductResponse
var product database.Product
var productResp types.ProductResponse
var manufacturer types.ManufacturerResponse
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 return
} }
response.Message = gin.H{ if err := db.First(&product.Manufacturer, product.ManufacturerID).Scan(&manufacturer).Error; err != nil {
"product": gin.H{ c.JSON(http.StatusBadRequest, types.NotFoundError("Product", product.ManufacturerID))
"id": product.ID, return
"name": product.Name,
"price": product.Price,
"manufacturer_ID": product.ManufacturerID,
"manufacturer_Name": product.Manufacturer.Name,
},
} }
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)
} }

View File

@ -1,7 +1,5 @@
package controllers package controllers
// Пример генератора токена
import ( import (
"crypto/rand" "crypto/rand"
"encoding/base64" "encoding/base64"
@ -9,93 +7,47 @@ import (
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"golang-test/database" "golang-test/database"
"golang-test/libs" "golang-test/libs"
"golang-test/message"
"golang-test/types" "golang-test/types"
"golang-test/validators" "golang-test/validators"
"golang.org/x/crypto/bcrypt" "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 { type TokenStruct struct {
UserID uint UserID uint
token string token string
} }
//func RegisterUser(c *gin.Context, user database.User) { func RegisterUser(c *gin.Context, register types.RegisterRequest) {
// 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
db := database.Connector() db := database.Connector()
validate := validators.Validate validate := validators.Validate
response := message.Response{Status: 201} var token database.Token
var token *database.Token
if err := validate.Struct(register); err != nil { if err := validate.Struct(register); err != nil {
response.Error = libs.GetValidationErrors(err.(validator.ValidationErrors)) c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors)))
response.Status = 400
message.SendResponse(c, response)
return
} }
if err := db.Where("email =?", register.Email).First(&user).Error; err == nil { if err := db.Where("email =?", register.Email).Error; err == nil {
response.Status = 400 c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: "User already exists"})
response.Error = gin.H{
"error": "User already exists",
}
message.SendResponse(c, response)
return return
} }
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(register.Password), 12) hashedPassword, err := bcrypt.GenerateFromPassword([]byte(register.Password), 12)
if err != nil { if err != nil {
response.Status = 500 log.Println(err.Error())
response.Error = gin.H{ c.JSON(http.StatusInternalServerError, types.ErrorResponse{Message: err.Error()})
"error": "Internal Server Error",
}
message.SendResponse(c, response)
return return
} }
user.Email = register.Email user := database.User{
user.Password = string(hashedPassword) Name: register.Name,
user.Name = register.Name Email: register.Email,
Password: string(hashedPassword),
}
if err := db.Create(&user).Error; err != nil { if err := db.Create(&user).Error; err != nil {
response.Status = 500 c.JSON(http.StatusInternalServerError, types.ErrorResponse{Message: err.Error()})
response.Error = gin.H{
"error": "Internal Server Error",
}
message.SendResponse(c, response)
return return
} }
@ -103,53 +55,42 @@ func RegisterUser(c *gin.Context, register database.User) {
token.UserID = user.ID token.UserID = user.ID
user.Tokens = append(user.Tokens, token) user.Tokens = append(user.Tokens, token)
response.Message = gin.H{ c.JSON(http.StatusCreated, types.TokenResponse{Token: token.Token})
"message": "Registration Success",
}
message.SendResponse(c, response)
} }
func LoginUser(c *gin.Context, login types.LoginRequest) { func LoginUser(c *gin.Context, login types.LoginRequest) {
var user database.User var user database.User
db := database.Connector() db := database.Connector()
validate := validators.Validate validate := validators.Validate
response := message.Response{Status: 200} var token database.Token
var token *database.Token
if err := validate.Struct(login); err != nil { if err := validate.Struct(login); err != nil {
response.Error = libs.GetValidationErrors(err.(validator.ValidationErrors)) c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors)))
response.Status = 400
message.SendResponse(c, response)
return return
} }
if err := db.Where("email = ?", login.Email).First(&user).Error; err != nil { if err := db.Where("email = ?", login.Email).First(&user).Error; err != nil {
response.Status = 404 c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: "Invalid email or password"})
response.Error = gin.H{ return
"error": "User not found",
}
} }
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(login.Password)); err != nil { if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(login.Password)); err != nil {
response.Status = 404 c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: "Invalid email or password"})
response.Error = gin.H{ return
"error": "User not found",
}
} }
token.Token = generateToken() token.Token = generateToken()
token.UserID = user.ID token.UserID = user.ID
user.Tokens = append(user.Tokens, token) user.Tokens = append(user.Tokens, token)
response.Message = gin.H{ db.Save(&user)
"message": "Login Success",
}
message.SendResponse(c, response) c.JSON(http.StatusOK, types.TokenResponse{Token: token.Token})
} }
func generateToken() string { func generateToken() string {
b := make([]byte, 4) b := make([]byte, 25)
if _, err := rand.Read(b); err != nil { if _, err := rand.Read(b); err != nil {
return "" return ""
} }
@ -157,7 +98,7 @@ func generateToken() string {
} }
func GetUserByToken(token string) (database.User, error) { func GetUserByToken(token string) (database.User, error) {
var tokenObject TokenStruct var tokenObject database.Token
var err error var err error
var user database.User 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 { if err := db.Where("token = ?", token).First(&tokenObject).Error; err != nil {
return user, err return user, err
} }
if err := db.First(&user, tokenObject.UserID).Error; err != nil { if err := db.First(&user, tokenObject.UserID).Error; err != nil {
return user, err return user, err
} }
return user, err return user, err
} }
func GetUser(c *gin.Context, user database.User) { func GetUser(c *gin.Context) {
token := strings.Split(c.Request.Header["Bearer"][0], " ")[1] token, err := libs.GetTokenFromHeaders(c)
validate := validators.Validate
response := message.Response{Status: 200} if err != nil {
c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"})
}
u, err := GetUserByToken(token) u, err := GetUserByToken(token)
if err != nil { if err != nil {
response.Status = 401 c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"})
response.Error = gin.H{
"error": "Token is invalid, please login",
}
message.SendResponse(c, response)
return return
} }
if err := validate.Struct(user); err != nil { c.JSON(http.StatusOK, u)
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)
} }
func EditUser(c *gin.Context, user database.User) { func EditUserName(c *gin.Context, userName types.EditUserNameRequest) {
token := strings.Split(c.Request.Header["Bearer"][0], " ")[1] token, err := libs.GetTokenFromHeaders(c)
if err != nil {
c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"})
}
db := database.Connector() db := database.Connector()
validate := validators.Validate 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) u, err := GetUserByToken(token)
if err != nil { if err != nil {
response.Status = 401 c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"})
response.Error = gin.H{
"error": "Token is invalid, please login",
}
message.SendResponse(c, response)
return return
} }
if err := validate.Struct(user); err != nil { u.Name = userName.Name
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)
if err := db.Save(u).Error; err != nil { if err := db.Save(u).Error; err != nil {
response.Status = 500 c.JSON(http.StatusInternalServerError, types.ErrorResponse{Message: err.Error()})
response.Error = gin.H{
"error": err,
}
message.SendResponse(c, response)
return return
} }
response.Message = gin.H{ c.JSON(http.StatusOK, types.MessageResponse{Message: "User name successfully updated"})
"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)
} }

View File

@ -27,6 +27,7 @@ type User struct {
Name string `validate:"required"` Name string `validate:"required"`
Email string `validate:"required"` Email string `validate:"required"`
Password string `validate:"required"` Password string `validate:"required"`
Products []*Product `gorm:"many2many:user_products;"` Products []Product `gorm:"many2many:user_products;"`
Tokens []*Token `gorm:"many2many:user_token;"` Tokens []Token `gorm:"many2many:user_token;"`
Money uint `gorm:"default:0"`
} }

View File

@ -12,6 +12,6 @@ post {
body:json { body:json {
{ {
"name": "Тест 1" "name": "Тест 123"
} }
} }

View File

@ -5,7 +5,7 @@ meta {
} }
delete { delete {
url: {{host}}/manufacturer/{{manufacturerID}} url: {{host}}/manufacturer/6
body: none body: none
auth: none auth: none
} }

View File

@ -5,13 +5,13 @@ meta {
} }
patch { patch {
url: {{host}}/manufacturer/{{manufacturerID}} url: {{host}}/manufacturer/5
body: json body: json
auth: none auth: none
} }
body:json { body:json {
{ {
"name": "Test3" "name": "Sdsad"
} }
} }

View File

@ -5,7 +5,7 @@ meta {
} }
get { get {
url: url: {{host}}/product/19
body: none body: none
auth: none auth: none
} }

View File

@ -4,20 +4,12 @@ meta {
seq: 3 seq: 3
} }
post { get {
url: {{host}}/product url: {{host}}/product
body: json body: json
auth: none auth: none
} }
body:json {
{
"name": "Яблоко",
"price": 5,
"manufacturerID": 1
}
}
body:multipart-form { body:multipart-form {
name: Яблоко name: Яблоко
price: 5 price: 5

View File

@ -1,5 +1,6 @@
vars { vars {
host: http://localhost:8080 host: http://localhost:8080
manufacturerID: 1 manufacturerID: 1
productID: 2 productID: 6
token: TPqB2mHBjRkvLpH3M6kWSWVMj7O75t665g==
} }

View File

@ -1,20 +1,25 @@
package libs package libs
import ( import (
"errors"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"golang-test/types"
"net/http"
"strings" "strings"
) )
func GetValidationErrors(errs validator.ValidationErrors) gin.H { type ValidationErrorsType struct {
errors := make(map[string]any) Errors map[string]string `json:"errors"`
}
func GetValidationErrors(errs validator.ValidationErrors) ValidationErrorsType {
errors := make(map[string]string)
for _, err := range errs { for _, err := range errs {
errors[err.Field()] = err.Error() errors[err.Field()] = err.Error()
} }
return gin.H{ return ValidationErrorsType{Errors: errors}
"error": errors,
}
} }
func ToSnakeCase(str string) string { func ToSnakeCase(str string) string {
@ -27,3 +32,17 @@ func ToSnakeCase(str string) string {
} }
return strings.ToLower(string(result)) 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
}

28
main.go
View File

@ -72,9 +72,10 @@ func main() {
//View для создания пользователя //View для создания пользователя
r.POST("/registration", func(c *gin.Context) { r.POST("/registration", func(c *gin.Context) {
var form database.User var form types.RegisterRequest
if err := c.ShouldBind(&form); err != nil { if err := c.ShouldBind(&form); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
} }
controllers.RegisterUser(c, form) controllers.RegisterUser(c, form)
@ -85,6 +86,7 @@ func main() {
var register types.LoginRequest var register types.LoginRequest
if err := c.ShouldBind(&register); err != nil { if err := c.ShouldBind(&register); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
} }
controllers.LoginUser(c, register) controllers.LoginUser(c, register)
}) })
@ -93,26 +95,28 @@ func main() {
var user database.User var user database.User
if err := c.ShouldBind(&user); err != nil { if err := c.ShouldBind(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
} }
controllers.LoginUser(c, user) controllers.GetUser(c)
}) })
//View для редактированя пользователя //View для редактированя пользователя
r.PATCH("/user/edit", func(c *gin.Context) { r.PATCH("/user", func(c *gin.Context) {
var user database.User var user types.EditUserNameRequest
if err := c.ShouldBind(&user); err != nil { if err := c.ShouldBind(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
} }
controllers.EditUser(c, user) controllers.EditUserName(c, user)
}) })
//View для удаления пользователя //View для покупки товара
r.DELETE("/user/delete", func(c *gin.Context) { r.GET("/product/:id/buy", func(c *gin.Context) {
var form types.LoginRequest controllers.BuyProduct(c)
if err := c.ShouldBind(&form); err != nil { })
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
} //View для просмотра купленных товаров
controllers.DeleteUser(c) r.GET("/user/products", func(c *gin.Context) {
controllers.GetBuyedProducts(c)
}) })
err := r.Run() err := r.Run()

View File

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

20
types/requests.go Normal file
View File

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

51
types/responses.go Normal file
View File

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

View File

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