Go-TestAPI/controllers/userController.go

248 lines
6.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package controllers
import (
"golang-test/database"
"golang-test/libs"
"golang-test/types"
"golang-test/validators"
"log"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"golang.org/x/crypto/bcrypt"
)
type TokenStruct struct {
UserID uint
token string
}
func RegisterUser(c *gin.Context, register types.RegisterRequest) {
db := database.Connector()
validate := validators.Validate
var token database.Token
var user database.User
// Валидация входных данных
if err := validate.Struct(register); err != nil {
c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors)))
return
}
// Проверка, существует ли уже пользователь с таким email
if userExists(register.Email) {
c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: "User already exists"})
return
}
// Генерация хэшированного пароля
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(register.Password), 12)
if err != nil {
log.Println(err.Error())
c.JSON(http.StatusInternalServerError, types.ErrorResponse{Message: err.Error()})
return
}
// Создание нового пользователя
user = database.User{
Name: register.Name,
Email: register.Email,
Password: string(hashedPassword),
}
// Генерация токена для пользователя
token.Token = libs.GenerateToken()
token.UserID = user.ID
user.Tokens = append(user.Tokens, token)
// Сохранение пользователя в базе данных
if err := db.Create(&user).Error; err != nil {
c.JSON(http.StatusInternalServerError, types.ErrorResponse{Message: err.Error()})
return
}
// Отправка ответа с токеном
c.JSON(http.StatusCreated, types.TokenResponse{Token: token.Token})
}
// userExists проверяет, существует ли пользователь с данным email
func userExists(email string) bool {
db := database.Connector()
var user database.User
err := db.Where("email = ?", email).First(&user).Error
return err == nil
}
func LoginUser(c *gin.Context, login types.LoginRequest) {
var user database.User
db := database.Connector()
validate := validators.Validate
var token database.Token
if err := validate.Struct(login); err != nil {
c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors)))
return
}
if err := db.Where("email = ?", login.Email).First(&user).Error; err != nil {
c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: "Invalid email or password"})
return
}
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(login.Password)); err != nil {
c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: "Invalid email or password"})
return
}
token.Token = libs.GenerateToken()
token.UserID = user.ID
user.Tokens = append(user.Tokens, token)
db.Save(&user)
c.JSON(http.StatusOK, types.TokenResponse{Token: token.Token})
}
func GetUser(c *gin.Context) {
var products []types.ProductResponse
userFromMiddleware, ok := c.Get("user")
if !ok {
c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Authorization Error. Please login"})
return
}
user := userFromMiddleware.(database.User)
for _, product := range user.Products {
products = append(products, types.ProductResponse{
ID: product.ID,
Name: product.Name,
Price: product.Price,
ManufacturerID: product.ManufacturerID,
Manufacturer: types.ManufacturerResponse{
Name: product.Manufacturer.Name,
ID: product.Manufacturer.ID,
},
})
}
userResponse := types.UserResponse{
ID: user.ID,
Name: user.Name,
Email: user.Email,
Products: products,
Money: user.Money,
}
c.JSON(http.StatusOK, userResponse)
}
func EditUserName(c *gin.Context, userName types.EditUserNameRequest) {
db := database.Connector()
validate := validators.Validate
if err := validate.Struct(userName); err != nil {
c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors)))
return
}
userFromMiddleware, ok := c.Get("user")
if !ok {
c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Authorization Error. Please login"})
return
}
user := userFromMiddleware.(database.User)
user.Name = userName.Name
if err := db.Save(user).Error; err != nil {
c.JSON(http.StatusInternalServerError, types.ErrorResponse{Message: err.Error()})
return
}
c.JSON(http.StatusOK, types.MessageResponse{Message: "User name successfully updated"})
}
func AddMoneyToUser(c *gin.Context, moneyRequest types.AddMoneyRequest) {
db := database.Connector()
user, err := libs.GetUserFromHeaders(c)
if err != nil {
c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: err.Error()})
return
}
user.Money += moneyRequest.Money
if err := db.Save(&user).Error; err != nil {
c.JSON(http.StatusInternalServerError, types.ErrorResponse{Message: err.Error()})
}
c.JSON(http.StatusOK, types.MessageResponse{Message: "Money successfully added"})
}
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
}
userFromMiddleware, ok := c.Get("user")
if !ok {
c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Authorization Error. Please login"})
return
}
user := userFromMiddleware.(database.User)
if user.Money-product.Price < 0 {
c.JSON(http.StatusOK, types.MessageResponse{Message: "Not enough money"})
return
}
user.Money -= product.Price
user.Products = append(user.Products, product)
db.Save(&user)
c.JSON(http.StatusOK, types.MessageResponse{Message: "Product successful buyed"})
}
func GetBuyedProducts(c *gin.Context) {
var response []types.ProductResponse
user, err := libs.GetUserFromHeaders(c)
if err != nil {
c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: err.Error()})
return
}
for _, product := range user.Products {
manufacturer := types.ManufacturerResponse{
ID: product.ManufacturerID,
Name: product.Manufacturer.Name,
}
response = append(response, types.ProductResponse{
ID: product.ID,
Name: product.Manufacturer.Name,
Price: product.Price,
ManufacturerID: manufacturer.ID,
Manufacturer: manufacturer,
})
}
c.JSON(http.StatusOK, response)
}