145 lines
2.5 KiB
Go
145 lines
2.5 KiB
Go
package controllers
|
|
|
|
import(
|
|
"os"
|
|
"time"
|
|
"net/http"
|
|
"golang.org/x/crypto/bcrypt"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
"github.com/gin-gonic/gin"
|
|
"gorm.io/gorm"
|
|
|
|
"example.com/gin/test/models"
|
|
)
|
|
|
|
|
|
type UserController struct {
|
|
DB *gorm.DB
|
|
}
|
|
|
|
func NewUserController(db *gorm.DB) UserController {
|
|
return UserController{
|
|
DB: db,
|
|
}
|
|
}
|
|
|
|
|
|
func (uc *UserController) Signup(c *gin.Context) {
|
|
//Get the email/passwd off req body
|
|
var body struct {
|
|
Email string
|
|
Password string
|
|
}
|
|
|
|
err := c.Bind(&body)
|
|
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"error": "Failed to read body",
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
//hash pw
|
|
hash, err := bcrypt.GenerateFromPassword([]byte(body.Password), 10)
|
|
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"error": "Failed to hash password",
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
//create user
|
|
user := models.User{Email: body.Email, Password: string(hash)}
|
|
result := uc.DB.Create(&user)
|
|
|
|
if result.Error != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"error": "Failed to create user",
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
|
|
//respond
|
|
c.JSON(http.StatusOK, gin.H{})
|
|
}
|
|
|
|
|
|
func (uc *UserController) Login(c *gin.Context) {
|
|
//Get the email/passwd off req body
|
|
var body struct {
|
|
Email string
|
|
Password string
|
|
}
|
|
|
|
err := c.Bind(&body)
|
|
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"error": "Failed to read body",
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
//lookup requested user
|
|
var user models.User
|
|
result := uc.DB.First(&user, "email = ?", body.Email)
|
|
|
|
if result.Error != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"error": "Invalid email or password",
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
// compare sent with saved pass
|
|
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(body.Password))
|
|
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"error": "Invalid email or password",
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
//generate jwt token
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
|
"sub": user.ID,
|
|
"exp": time.Now().Add(time.Hour * 24).Unix(),
|
|
})
|
|
|
|
// Sign and get the complete encoded token as a string using the secret
|
|
tokenString, err := token.SignedString([]byte(os.Getenv("SECRET")))
|
|
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"error": "Failed to create token",
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
// send it back
|
|
c.SetSameSite(http.SameSiteLaxMode)
|
|
c.SetCookie("Authorization", tokenString, 3600 * 24, "", "", false, true)
|
|
|
|
c.JSON(http.StatusOK, gin.H{})
|
|
}
|
|
|
|
func (uc *UserController) Validate(c *gin.Context) {
|
|
user, _ := c.Get("user")
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"message": user,
|
|
})
|
|
}
|