2023-10-25 20:17:27 +05:30
package controllers
import (
"context"
"fmt"
"log"
2023-10-26 14:52:42 +05:30
2023-10-25 20:17:27 +05:30
"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"
2023-10-26 14:52:42 +05:30
2023-10-25 20:17:27 +05:30
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"golang.org/x/crypto/bcrypt"
)
2023-10-26 14:52:42 +05:30
var userCollection * mongo . Collection = database . OpenCollection ( database . Client , "user" )
2023-10-25 20:17:27 +05:30
var validate = validator . New ( )
2023-10-26 14:52:42 +05:30
// 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 {
2023-10-25 20:17:27 +05:30
bytes , err := bcrypt . GenerateFromPassword ( [ ] byte ( password ) , 14 )
if err != nil {
2023-10-26 14:52:42 +05:30
log . Panic ( err )
2023-10-25 20:17:27 +05:30
}
2023-10-26 14:52:42 +05:30
2023-10-25 20:17:27 +05:30
return string ( bytes )
}
2023-10-26 14:52:42 +05:30
// VerifyPassword checks the input password while verifying it with the passward in the DB.
2023-10-25 20:17:27 +05:30
func VerifyPassword ( userPassword string , providedPassword string ) ( bool , string ) {
err := bcrypt . CompareHashAndPassword ( [ ] byte ( providedPassword ) , [ ] byte ( userPassword ) )
check := true
msg := ""
2023-10-26 14:52:42 +05:30
2023-10-25 20:17:27 +05:30
if err != nil {
2023-10-26 14:52:42 +05:30
msg = fmt . Sprintf ( "login or passowrd is incorrect" )
2023-10-25 20:17:27 +05:30
check = false
}
2023-10-26 14:52:42 +05:30
2023-10-25 20:17:27 +05:30
return check , msg
}
2023-10-26 14:52:42 +05:30
// 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
2023-10-25 20:17:27 +05:30
func SignUp ( ) gin . HandlerFunc {
return func ( c * gin . Context ) {
var ctx , cancel = context . WithTimeout ( context . Background ( ) , 100 * time . Second )
var user models . User
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 )
2023-10-26 14:52:42 +05:30
c . JSON ( http . StatusInternalServerError , gin . H { "error" : "error occured while checking for the email" } )
2023-10-25 20:17:27 +05:30
return
}
2023-10-26 14:52:42 +05:30
password := HashPassword ( * user . Password )
2023-10-25 20:17:27 +05:30
user . Password = & password
2023-10-26 14:52:42 +05:30
count , err = userCollection . CountDocuments ( ctx , bson . M { "phone" : user . Phone } )
2023-10-25 20:17:27 +05:30
defer cancel ( )
if err != nil {
log . Panic ( err )
2023-10-26 14:52:42 +05:30
c . JSON ( http . StatusInternalServerError , gin . H { "error" : "error occured while checking for the phone number" } )
2023-10-25 20:17:27 +05:30
return
}
2023-10-26 14:52:42 +05:30
2023-10-25 20:17:27 +05:30
if count > 0 {
c . JSON ( http . StatusInternalServerError , gin . H { "error" : "this email or phone number already exists" } )
return
}
2023-10-26 14:52:42 +05:30
2023-10-25 20:17:27 +05:30
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 )
2023-10-26 14:52:42 +05:30
2023-10-25 20:17:27 +05:30
user . Token = & token
user . Refresh_token = & refreshToken
resultInsertionNumber , insertErr := userCollection . InsertOne ( ctx , user )
2023-10-26 14:52:42 +05:30
log . Printf ( "resultInsertionNumber %d" , resultInsertionNumber )
2023-10-25 20:17:27 +05:30
if insertErr != nil {
msg := fmt . Sprintf ( "User item was not created" )
c . JSON ( http . StatusInternalServerError , gin . H { "error" : msg } )
return
}
defer cancel ( )
2023-10-26 14:52:42 +05:30
2023-10-25 20:17:27 +05:30
c . JSON ( http . StatusOK , resultInsertionNumber )
2023-10-26 14:52:42 +05:30
2023-10-25 20:17:27 +05:30
}
}
2023-10-26 14:52:42 +05:30
// Login is the api used to tget a single user
2023-10-25 20:17:27 +05:30
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
if err := c . BindJSON ( & user ) ; err != nil {
c . JSON ( http . StatusBadRequest , gin . H { "error" : err . Error ( ) } )
return
}
2023-10-26 14:52:42 +05:30
err := userCollection . FindOne ( ctx , bson . M { "email" : user . Email } ) . Decode ( & foundUser )
2023-10-25 20:17:27 +05:30
defer cancel ( )
if err != nil {
2023-10-26 14:52:42 +05:30
c . JSON ( http . StatusInternalServerError , gin . H { "error" : "login or passowrd is incorrect" } )
2023-10-25 20:17:27 +05:30
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 )
2023-10-26 14:52:42 +05:30
2023-10-25 20:17:27 +05:30
helpers . UpdateAllToken ( token , refreshToken , foundUser . User_id )
2023-10-26 14:52:42 +05:30
2023-10-25 20:17:27 +05:30
c . JSON ( http . StatusOK , foundUser )
2023-10-26 14:52:42 +05:30
2023-10-25 20:17:27 +05:30
}
}