Skip to content

Commit

Permalink
Update login handler
Browse files Browse the repository at this point in the history
  • Loading branch information
voltgizerz committed Jun 9, 2024
1 parent 0e6d628 commit e5439ae
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 12 deletions.
7 changes: 4 additions & 3 deletions internal/app/api/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"time"

"github.com/golang-jwt/jwt/v5"
"github.com/voltgizerz/POS-restaurant/internal/app/entity"
"github.com/voltgizerz/POS-restaurant/internal/app/ports"
)

Expand All @@ -18,11 +19,11 @@ func NewAuthJWT(secretKey string) ports.IAuth {
}
}

func (a *Auth) CreateToken(username string) (string, error) {
func (a *Auth) CreateToken(user *entity.User) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256,
jwt.MapClaims{
"username": username,
"exp": time.Now().Add(time.Hour * 24).Unix(),
"id": user.ID,
"expired_at": time.Now().Add(time.Hour * 24).Unix(),
})

tokenString, err := token.SignedString(a.SecretKey)
Expand Down
8 changes: 8 additions & 0 deletions internal/app/api/handler/request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package handler

type (
loginRequest struct {
Username string `json:"username"`
Password string `json:"password"`
}
)
37 changes: 37 additions & 0 deletions internal/app/api/handler/response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package handler

import "github.com/gofiber/fiber/v3"

type (
errorResponse struct {
Code int `json:"code"`
Message string `json:"message"`
}

successResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data"`
}
)

// sendErrorResponse generates and sends error response
func sendErrorResponse(c fiber.Ctx, statusCode int, errorMessage string) error {
response := errorResponse{
Code: statusCode,
Message: errorMessage,
}

return c.Status(statusCode).JSON(response)
}

// sendSuccessResponse generates and sends success response with dynamic data
func sendSuccessResponse(c fiber.Ctx, statusCode int, message string, data interface{}) error {
response := successResponse{
Code: statusCode,
Message: message,
Data: data,
}

return c.Status(statusCode).JSON(response)
}
38 changes: 33 additions & 5 deletions internal/app/api/handler/user_handler.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package handler

import (
"database/sql"

"github.com/gofiber/fiber/v3"
"github.com/opentracing/opentracing-go"
"github.com/voltgizerz/POS-restaurant/internal/app/interactor"
"github.com/voltgizerz/POS-restaurant/internal/app/ports"
)
Expand All @@ -19,17 +22,42 @@ func NewUserHandler(i interactor.UserHandler) *UserHandler {
}

func (h *UserHandler) Login(c fiber.Ctx) error {
// TODO
span, ctx := opentracing.StartSpanFromContext(c.Context(), "handler.UserHandler.Login")
defer span.Finish()

req := &loginRequest{}

// Hit db check user and password
err := c.Bind().Body(req)
if err != nil {
return sendErrorResponse(c, fiber.StatusBadRequest, "Invalid request body. Please provide both username and password.")
}

// success ?
// h.userService
// Check if the username and password are provided
if req.Username == "" || req.Password == "" {
return sendErrorResponse(c, fiber.StatusBadRequest, "Username and password are required.")
}

return nil
dataUser, err := h.userService.Login(ctx, req.Username, req.Password)
if err != nil {
if err == sql.ErrNoRows {
return sendErrorResponse(c, fiber.StatusUnauthorized, "Username not found.")
}

return sendErrorResponse(c, fiber.StatusUnauthorized, "Invalid username or password.")
}

token, err := h.authService.CreateToken(dataUser)
if err != nil {
return sendErrorResponse(c, fiber.StatusInternalServerError, "Failed create user token.")
}

return sendSuccessResponse(c, fiber.StatusOK, "Login successful.", token)
}

func (h *UserHandler) Register(c fiber.Ctx) error {
span, _ := opentracing.StartSpanFromContext(c.Context(), "handler.UserHandler.Register")
defer span.Finish()

// TODO
return nil
}
4 changes: 3 additions & 1 deletion internal/app/ports/auth_ports.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package ports

import "github.com/voltgizerz/POS-restaurant/internal/app/entity"

type IAuth interface {
CreateToken(username string) (string, error)
CreateToken(user *entity.User) (string, error)
VerifyToken(tokenString string) error
}
1 change: 1 addition & 0 deletions internal/app/ports/user_ports.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type IUserRepository interface {
}

type IUserService interface {
Login(ctx context.Context, username string, password string) (*entity.User, error)
}

type IUserHandler interface {
Expand Down
7 changes: 4 additions & 3 deletions internal/app/repository/user_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import (
)

const (
queryLogin = "SELECT * FROM users WHERE username=$1 and hash_password=$2"
queryGetUserByUsernameAndPassword = `SELECT id, name, username, email, password_hashed, is_active, created_at, updated_at
FROM users WHERE username=? AND password_hashed=?`
)

type UserRepository struct {
Expand All @@ -24,11 +25,11 @@ func NewUserRepository(opts RepositoryOpts) ports.IUserRepository {
}

func (r *UserRepository) GetUserByUsernameAndPassword(ctx context.Context, username string, hashPassword string) (*entity.UserORM, error) {
span, _ := opentracing.StartSpanFromContext(ctx, "repo.UserRepository.GetUserByUsernameAndPassword")
span, ctx := opentracing.StartSpanFromContext(ctx, "repo.UserRepository.GetUserByUsernameAndPassword")
defer span.Finish()

user := entity.UserORM{}
err := r.MasterDB.Get(&user, queryLogin, username, hashPassword)
err := r.MasterDB.GetContext(ctx, &user, queryGetUserByUsernameAndPassword, username, hashPassword)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit e5439ae

Please sign in to comment.