Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package controllers
- import (
- "fibber/models"
- "fibber/utils"
- "log"
- "net/http"
- "os"
- "time"
- "github.com/gin-gonic/gin"
- "github.com/go-playground/validator/v10"
- "gorm.io/gorm"
- )
- type AuthController interface {
- Login(c *gin.Context)
- Register(c *gin.Context)
- Me(c *gin.Context)
- Logout(c *gin.Context)
- }
- type AuthControllerImpl struct{}
- func NewAuthController() *AuthControllerImpl {
- return &AuthControllerImpl{}
- }
- type loginInput struct {
- Email string `validate:"required,email" json:"email"`
- Password string `validate:"required" json:"password"`
- }
- type registerInput struct {
- Name string `validate:"required,min=3,max=100" json:"name"`
- Email string `validate:"required,email" json:"email"`
- Password string `validate:"required,min=6,max=100" json:"password"`
- LoginDirectly bool `json:"login_directly"`
- }
- func (a *AuthControllerImpl) Login(c *gin.Context) {
- var body loginInput
- if err := c.ShouldBindJSON(&body); err != nil {
- c.JSON(http.StatusInternalServerError, gin.H{
- "message": "Cannot bind request body",
- })
- return
- }
- validate := validator.New()
- if err := validate.Struct(body); err != nil {
- log.Println("Validation error:", err)
- c.JSON(http.StatusBadRequest, gin.H{
- "message": "Invalid input data",
- "errors": err.Error(),
- })
- return
- }
- db := c.MustGet("db").(*gorm.DB)
- var user models.User
- result := db.Where("email = ?", body.Email).First(&user)
- /* Checks if user exists */
- if result.Error != nil {
- log.Println("User not found:", body.Email)
- c.JSON(http.StatusUnauthorized, gin.H{
- "message": "User does not exist",
- })
- return
- }
- /* Checks for password */
- if !utils.VerifyPassword(body.Password, user.Password) {
- log.Println("Invalid password for user:", body.Email)
- c.JSON(http.StatusUnauthorized, gin.H{
- "message": "Invalid credentials",
- })
- return
- }
- tokenString, err := utils.CreateToken(user.ID, os.Getenv("JWT_SECRET"))
- if err != nil {
- log.Println("Error creating token:", err)
- c.JSON(http.StatusInternalServerError, gin.H{
- "message": "Internal server error",
- })
- return
- }
- exp := time.Now().Add(time.Hour * 24).Unix()
- /* INFO: name of the cookie is "auth_gin" */
- c.SetCookie("auth_gin", tokenString, int(exp), "/", "localhost", false, true)
- c.JSON(200, gin.H{
- "message": "Login successful",
- })
- }
- func (a *AuthControllerImpl) Me(c *gin.Context) {
- cookie, err := c.Cookie("auth_gin")
- if err != nil {
- c.JSON(http.StatusUnauthorized, gin.H{
- "message": "Unauthorized",
- })
- return
- }
- userId, err := utils.VerifyToken(cookie, os.Getenv("JWT_SECRET"))
- if err != nil {
- log.Println("Error verifying token:", err)
- c.JSON(http.StatusUnauthorized, gin.H{
- "message": "Unauthorized",
- })
- return
- }
- db := c.MustGet("db").(*gorm.DB)
- var user models.User
- result := db.Model(&models.User{}).Where("id = ?", userId).First(&user)
- if result.Error != nil {
- if result.Error == gorm.ErrRecordNotFound {
- log.Default().Println("User not found:", userId)
- c.JSON(http.StatusNotFound, gin.H{
- "message": "User not found",
- })
- return
- }
- c.JSON(http.StatusInternalServerError, gin.H{
- "message": "Internal server error",
- })
- return
- }
- c.JSON(http.StatusOK, gin.H{
- "user_name": user.Name,
- "created_at": user.CreatedAt,
- })
- return
- }
- func (a *AuthControllerImpl) Register(c *gin.Context) {
- var body registerInput
- if err := c.ShouldBindJSON(&body); err != nil {
- c.JSON(http.StatusInternalServerError, gin.H{
- "message": "Cannot bind request body",
- })
- return
- }
- validate := validator.New()
- if err := validate.Struct(body); err != nil {
- log.Println("Validation error:", err)
- c.JSON(http.StatusBadRequest, gin.H{
- "message": "Invalid input data",
- "errors": err.Error(),
- })
- return
- }
- db := c.MustGet("db").(*gorm.DB)
- hashedPassword, err := utils.HashPassword(body.Password)
- if err != nil {
- log.Println("Error hashing password:", err)
- c.JSON(http.StatusInternalServerError, gin.H{
- "message": "Cannot hash password",
- "errors": err.Error(),
- })
- return
- }
- newUser := models.User{
- Name: body.Name,
- Email: body.Email,
- Password: hashedPassword,
- }
- result := db.Create(&newUser)
- if result.Error != nil {
- log.Println("Error inserting into database:", result.Error)
- c.JSON(http.StatusConflict, gin.H{
- "message": "User with this email already exists",
- "errors": result.Error.Error(),
- })
- return
- }
- if body.LoginDirectly {
- tokenString, err := utils.CreateToken(newUser.ID, os.Getenv("JWT_SECRET"))
- if err != nil {
- log.Println("Error creating token:", err)
- c.JSON(http.StatusInternalServerError, gin.H{
- "message": "Internal server error",
- })
- return
- }
- exp := time.Now().Add(time.Hour * 24).Unix()
- /* INFO: name of the cookie is "auth_gin" */
- c.SetCookie("auth_gin", tokenString, int(exp), "/", "localhost", false, true)
- c.JSON(http.StatusCreated, gin.H{
- "message": "User created and logged in",
- "data": map[string]any{
- "user_name": newUser.Name,
- "created_at": newUser.CreatedAt,
- },
- })
- return
- }
- c.JSON(http.StatusCreated, gin.H{
- "message": "User created",
- "data": map[string]any{
- "user_name": newUser.Name,
- "created_at": newUser.CreatedAt,
- },
- })
- return
- }
- func (a *AuthControllerImpl) Logout(c *gin.Context) {
- cookie, err := c.Cookie("auth_gin")
- if err != nil {
- c.JSON(http.StatusUnauthorized, gin.H{
- "message": "Unauthorized",
- })
- return
- }
- if _, err := utils.VerifyToken(cookie, os.Getenv("JWT_SECRET")); err != nil {
- log.Println("Error verifying token:", err)
- c.JSON(http.StatusUnauthorized, gin.H{
- "message": "Unauthorized",
- })
- return
- }
- /* INFO: name of the cookie is "auth_gin" */
- c.SetCookie("auth_gin", "", -1, "/", "localhost", false, true) // set cookie to expire immediately
- c.JSON(http.StatusOK, gin.H{
- "message": "Logged out successfully!",
- })
- return
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement