Go-TestAPI/controllers/userController.go

161 lines
4.0 KiB
Go
Raw Normal View History

package controllers
import (
"crypto/rand"
2024-06-06 15:03:22 +00:00
"encoding/base64"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"golang-test/database"
"golang-test/libs"
2024-06-06 16:02:59 +00:00
"golang-test/types"
2024-06-06 15:03:22 +00:00
"golang-test/validators"
"golang.org/x/crypto/bcrypt"
2024-06-07 12:52:09 +00:00
"log"
"net/http"
)
2024-06-06 15:21:25 +00:00
type TokenStruct struct {
2024-06-06 15:03:22 +00:00
UserID uint
token string
}
2024-06-07 12:52:09 +00:00
func RegisterUser(c *gin.Context, register types.RegisterRequest) {
2024-06-06 15:03:22 +00:00
db := database.Connector()
validate := validators.Validate
2024-06-07 12:52:09 +00:00
var token database.Token
if err := validate.Struct(register); err != nil {
2024-06-07 12:52:09 +00:00
c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors)))
2024-06-06 15:03:22 +00:00
}
2024-06-07 12:52:09 +00:00
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)
2024-06-06 15:03:22 +00:00
if err != nil {
2024-06-07 12:52:09 +00:00
log.Println(err.Error())
c.JSON(http.StatusInternalServerError, types.ErrorResponse{Message: err.Error()})
2024-06-06 15:03:22 +00:00
return
}
2024-06-07 12:52:09 +00:00
user := database.User{
Name: register.Name,
Email: register.Email,
Password: string(hashedPassword),
}
if err := db.Create(&user).Error; err != nil {
2024-06-07 12:52:09 +00:00
c.JSON(http.StatusInternalServerError, types.ErrorResponse{Message: err.Error()})
2024-06-06 15:03:22 +00:00
return
}
token.Token = generateToken()
token.UserID = user.ID
user.Tokens = append(user.Tokens, token)
2024-06-07 12:52:09 +00:00
c.JSON(http.StatusCreated, types.TokenResponse{Token: token.Token})
2024-06-06 15:03:22 +00:00
}
2024-06-06 16:02:59 +00:00
func LoginUser(c *gin.Context, login types.LoginRequest) {
2024-06-06 15:03:22 +00:00
var user database.User
db := database.Connector()
validate := validators.Validate
2024-06-07 12:52:09 +00:00
var token database.Token
2024-06-06 16:02:59 +00:00
if err := validate.Struct(login); err != nil {
2024-06-07 12:52:09 +00:00
c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors)))
2024-06-06 16:02:59 +00:00
return
2024-06-06 15:03:22 +00:00
}
2024-06-07 12:52:09 +00:00
2024-06-06 16:02:59 +00:00
if err := db.Where("email = ?", login.Email).First(&user).Error; err != nil {
2024-06-07 12:52:09 +00:00
c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: "Invalid email or password"})
return
2024-06-06 15:03:22 +00:00
}
2024-06-06 16:02:59 +00:00
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(login.Password)); err != nil {
2024-06-07 12:52:09 +00:00
c.JSON(http.StatusBadRequest, types.ErrorResponse{Message: "Invalid email or password"})
return
2024-06-06 15:03:22 +00:00
}
2024-06-06 16:02:59 +00:00
token.Token = generateToken()
token.UserID = user.ID
2024-06-07 12:52:09 +00:00
2024-06-06 16:02:59 +00:00
user.Tokens = append(user.Tokens, token)
2024-06-07 12:52:09 +00:00
db.Save(&user)
2024-06-06 16:02:59 +00:00
2024-06-07 12:52:09 +00:00
c.JSON(http.StatusOK, types.TokenResponse{Token: token.Token})
2024-06-06 15:03:22 +00:00
}
func generateToken() string {
2024-06-07 12:52:09 +00:00
b := make([]byte, 25)
2024-06-06 15:03:22 +00:00
if _, err := rand.Read(b); err != nil {
return ""
}
return base64.StdEncoding.EncodeToString(b)
}
2024-06-06 15:41:41 +00:00
func GetUserByToken(token string) (database.User, error) {
2024-06-07 12:52:09 +00:00
var tokenObject database.Token
2024-06-06 15:21:25 +00:00
var err error
var user database.User
2024-06-06 15:03:22 +00:00
db := database.Connector()
2024-06-06 15:21:25 +00:00
if err := db.Where("token = ?", token).First(&tokenObject).Error; err != nil {
return user, err
2024-06-06 15:03:22 +00:00
}
2024-06-07 12:52:09 +00:00
2024-06-06 15:21:25 +00:00
if err := db.First(&user, tokenObject.UserID).Error; err != nil {
return user, err
2024-06-06 15:03:22 +00:00
}
2024-06-06 15:21:25 +00:00
return user, err
2024-06-06 15:03:22 +00:00
}
2024-06-07 12:52:09 +00:00
func GetUser(c *gin.Context) {
token, err := libs.GetTokenFromHeaders(c)
2024-06-07 12:52:09 +00:00
if err != nil {
c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"})
}
2024-06-06 15:41:41 +00:00
u, err := GetUserByToken(token)
2024-06-06 15:36:14 +00:00
if err != nil {
2024-06-07 12:52:09 +00:00
c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"})
2024-06-06 15:03:22 +00:00
return
}
2024-06-06 15:36:14 +00:00
2024-06-07 12:52:09 +00:00
c.JSON(http.StatusOK, u)
}
2024-06-06 15:36:14 +00:00
2024-06-07 12:52:09 +00:00
func EditUserName(c *gin.Context, userName types.EditUserNameRequest) {
token, err := libs.GetTokenFromHeaders(c)
2024-06-06 15:36:14 +00:00
if err != nil {
2024-06-07 12:52:09 +00:00
c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"})
2024-06-06 15:03:22 +00:00
}
2024-06-06 15:36:14 +00:00
2024-06-07 12:52:09 +00:00
db := database.Connector()
validate := validators.Validate
2024-06-06 15:36:14 +00:00
2024-06-07 12:52:09 +00:00
if err := validate.Struct(userName); err != nil {
c.JSON(http.StatusBadRequest, libs.GetValidationErrors(err.(validator.ValidationErrors)))
2024-06-06 15:03:22 +00:00
return
}
2024-06-06 15:41:41 +00:00
u, err := GetUserByToken(token)
2024-06-06 15:03:22 +00:00
if err != nil {
2024-06-07 12:52:09 +00:00
c.JSON(http.StatusUnauthorized, types.ErrorResponse{Message: "Invalid token. Please login"})
2024-06-06 15:03:22 +00:00
return
}
2024-06-06 15:41:41 +00:00
2024-06-07 12:52:09 +00:00
u.Name = userName.Name
if err := db.Save(u).Error; err != nil {
c.JSON(http.StatusInternalServerError, types.ErrorResponse{Message: err.Error()})
2024-06-06 15:03:22 +00:00
return
}
2024-06-06 15:41:41 +00:00
2024-06-07 12:52:09 +00:00
c.JSON(http.StatusOK, types.MessageResponse{Message: "User name successfully updated"})
}