mirror of
https://github.com/Uttkarsh-raj/Plannerly.git
synced 2025-11-23 21:54:39 +02:00
150 lines
4.6 KiB
Go
150 lines
4.6 KiB
Go
package controllers
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/Uttkarsh-raj/To_Do_App/database"
|
|
"github.com/Uttkarsh-raj/To_Do_App/helpers"
|
|
"github.com/Uttkarsh-raj/To_Do_App/models"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/go-playground/validator/v10"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
var userCollection *mongo.Collection = database.OpenCollection(database.Client, "user")
|
|
var validate = validator.New()
|
|
|
|
// Now implement password hashing and verification in your controllers/userController.go file with the following code.
|
|
// HashPassword is used to encrypt the password before it is stored in the DB
|
|
func HashPassword(password string) string {
|
|
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
|
|
if err != nil {
|
|
log.Panic(err)
|
|
}
|
|
|
|
return string(bytes)
|
|
}
|
|
|
|
// VerifyPassword checks the input password while verifying it with the passward in the DB.
|
|
func VerifyPassword(userPassword string, providedPassword string) (bool, string) {
|
|
err := bcrypt.CompareHashAndPassword([]byte(providedPassword), []byte(userPassword))
|
|
check := true
|
|
msg := ""
|
|
|
|
if err != nil {
|
|
msg = fmt.Sprintf("login or passowrd is incorrect")
|
|
check = false
|
|
}
|
|
|
|
return check, msg
|
|
}
|
|
|
|
// Now let's move on to implementing the signup and login service in your controllers/userController.go file with the following code. Kindly note that some functions such as helper.GenerateAllTokens and helper.UpdateAllTokens will not be available since you haven't written them yet. keep calm 😁😁
|
|
// CreateUser is the api used to tget a single user
|
|
func SignUp() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
var ctx, cancel = context.WithTimeout(context.Background(), 100*time.Second)
|
|
var user models.User
|
|
defer cancel()
|
|
if err := c.BindJSON(&user); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
validationErr := validate.Struct(user)
|
|
if validationErr != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": validationErr.Error()})
|
|
return
|
|
}
|
|
|
|
count, err := userCollection.CountDocuments(ctx, bson.M{"email": user.Email})
|
|
defer cancel()
|
|
if err != nil {
|
|
log.Panic(err)
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "error occured while checking for the email"})
|
|
return
|
|
}
|
|
|
|
password := HashPassword(*user.Password)
|
|
user.Password = &password
|
|
|
|
count, err = userCollection.CountDocuments(ctx, bson.M{"phone": user.Phone})
|
|
defer cancel()
|
|
if err != nil {
|
|
log.Panic(err)
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "error occured while checking for the phone number"})
|
|
return
|
|
}
|
|
|
|
if count > 0 {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "this email or phone number already exists"})
|
|
return
|
|
}
|
|
|
|
user.Created_at, _ = time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
|
|
user.Updated_at, _ = time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
|
|
user.ID = primitive.NewObjectID()
|
|
user.User_id = user.ID.Hex()
|
|
token, refreshToken, _ := helpers.GenerateAllTokens(*user.Email, *user.First_name, *user.Last_name, user.User_id)
|
|
|
|
user.Token = &token
|
|
user.Refresh_token = &refreshToken
|
|
|
|
resultInsertionNumber, insertErr := userCollection.InsertOne(ctx, user)
|
|
log.Printf("resultInsertionNumber %d", resultInsertionNumber)
|
|
if insertErr != nil {
|
|
msg := fmt.Sprintf("User item was not created")
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": msg})
|
|
return
|
|
}
|
|
defer cancel()
|
|
|
|
c.JSON(http.StatusOK, resultInsertionNumber)
|
|
|
|
}
|
|
}
|
|
|
|
// Login is the api used to tget a single user
|
|
func Login() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
var ctx, cancel = context.WithTimeout(context.Background(), 100*time.Second)
|
|
var user models.User
|
|
var foundUser models.User
|
|
defer cancel()
|
|
if err := c.BindJSON(&user); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
err := userCollection.FindOne(ctx, bson.M{"email": user.Email}).Decode(&foundUser)
|
|
defer cancel()
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "login or passowrd is incorrect"})
|
|
return
|
|
}
|
|
|
|
passwordIsValid, msg := VerifyPassword(*user.Password, *foundUser.Password)
|
|
defer cancel()
|
|
if passwordIsValid != true {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": msg})
|
|
return
|
|
}
|
|
|
|
token, refreshToken, _ := helpers.GenerateAllTokens(*foundUser.Email, *foundUser.First_name, *foundUser.Last_name, foundUser.User_id)
|
|
|
|
helpers.UpdateAllToken(token, refreshToken, foundUser.User_id)
|
|
|
|
c.JSON(http.StatusOK, foundUser)
|
|
|
|
}
|
|
}
|