Skip to content

Commit

Permalink
Add delivery person login functionality
Browse files Browse the repository at this point in the history
Implemented login endpoint for delivery personnel. Added context-based validation and JWT generation for secure authentication. Updated delivery models and routes to support the new login feature.
  • Loading branch information
mukulmantosh committed Sep 12, 2024
1 parent ffe7840 commit 5b0e268
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 0 deletions.
10 changes: 10 additions & 0 deletions pkg/abstract/delivery/delivery.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,15 @@ import (

type DeliveryPerson interface {
AddDeliveryPerson(ctx context.Context, deliveryPerson *delivery.DeliveryPerson) (bool, error)
}

type Validation interface {
GenerateTOTP(_ context.Context, phone string) (string, string, error)
ValidateOTP(_ context.Context, secretKey string, otp string) bool
ValidateAccountDetails(ctx context.Context, phone string) (*delivery.DeliveryPerson, error)
Verify(ctx context.Context, phone string, otp string) bool
}

type DeliveryLogin interface {
GenerateJWT(ctx context.Context, userId int64, name string) (string, error)
}
5 changes: 5 additions & 0 deletions pkg/database/models/delivery/delivery.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,8 @@ type DeliveryPersonParams struct {
Phone string `json:"phone"`
VehicleDetails string `json:"vehicle_details"`
}

type DeliveryLoginParams struct {
Phone string `json:"phone"`
OTP string `json:"otp"`
}
41 changes: 41 additions & 0 deletions pkg/handler/delivery/login.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package delivery

import (
"Go_Food_Delivery/pkg/database/models/delivery"
"context"
"github.com/gin-gonic/gin"
"net/http"
"time"
)

func (s *DeliveryHandler) loginDelivery(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 5*time.Second)
defer cancel()
var token string
var deliverLoginPerson delivery.DeliveryLoginParams

if err := c.BindJSON(&deliverLoginPerson); err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
return
}

verify := s.service.Verify(ctx, deliverLoginPerson.Phone, deliverLoginPerson.OTP)
if !verify {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Either Phone or OTP is incorrect or user is inactive. Please contact administrator."})
return
} else {
deliveryLoginDetails, err := s.service.ValidateAccountDetails(ctx, deliverLoginPerson.Phone)
if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unable to fetch delivery person details. Please contact administrator."})
return
}
token, err = s.service.GenerateJWT(ctx, deliveryLoginDetails.DeliveryPersonID, deliveryLoginDetails.Name)
if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Unable to generate login information. Please contact administrator."})
return
}

}

c.JSON(http.StatusCreated, gin.H{"token": token})
}
1 change: 1 addition & 0 deletions pkg/handler/delivery/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ func (s *DeliveryHandler) registerGroup(middleware ...gin.HandlerFunc) gin.IRout

func (s *DeliveryHandler) routes() http.Handler {
s.router.POST("/add", s.addDeliveryPerson)
s.router.POST("/login", s.loginDelivery)

return s.serve.Gin
}
55 changes: 55 additions & 0 deletions pkg/service/delivery/validate_2fa.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package delivery

import (
"Go_Food_Delivery/cmd/api/middleware"
"Go_Food_Delivery/pkg/database/models/delivery"
"context"
"errors"
"fmt"
"github.com/golang-jwt/jwt/v5"
"github.com/pquerna/otp/totp"
"log/slog"
"os"
"time"
)

func (deliverSrv *DeliveryService) ValidateAccountDetails(ctx context.Context, phone string) (*delivery.DeliveryPerson, error) {
var deliveryAccountInfo delivery.DeliveryPerson
err := deliverSrv.db.Select(ctx, &deliveryAccountInfo, "phone", phone)
if err != nil {
return nil, err
}
if deliveryAccountInfo.Status != "AVAILABLE" {
return nil, errors.New("account is inactive or not available")
}
fmt.Printf("%+v", deliveryAccountInfo)
return &deliveryAccountInfo, nil
}

func (deliverSrv *DeliveryService) ValidateOTP(_ context.Context, secretKey string, otp string) bool {
return totp.Validate(otp, secretKey)
}

func (deliverSrv *DeliveryService) Verify(ctx context.Context, phone string, otp string) bool {
accDetail, err := deliverSrv.ValidateAccountDetails(ctx, phone)
if err != nil {
slog.Error("Error::validating account details", "err", err)
return false
}

valid := deliverSrv.ValidateOTP(ctx, accDetail.AuthKey, otp)
return valid
}

func (deliverSrv *DeliveryService) GenerateJWT(_ context.Context, userId int64, name string) (string, error) {

claims := middleware.UserClaims{UserID: userId, Name: name,
RegisteredClaims: jwt.RegisteredClaims{

ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * time.Duration(2))),
Issuer: "Go_Food_Delivery",
}}

token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(os.Getenv("JWT_SECRET_KEY")))
}

0 comments on commit 5b0e268

Please sign in to comment.