Skip to content

Commit

Permalink
Add jwt auth middleware and refactor code
Browse files Browse the repository at this point in the history
  • Loading branch information
voltgizerz committed Jun 23, 2024
1 parent 61709bb commit 30fec93
Show file tree
Hide file tree
Showing 23 changed files with 353 additions and 138 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
logs
./coverage.out
config.production.yml
app.exe
app.exe
tmp
main.exe
46 changes: 46 additions & 0 deletions air.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
args_bin = []
bin = "./main.exe"
cmd = "go build -o main.exe ./cmd"
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
post_cmd = []
pre_cmd = []
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_error = false

[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"

[log]
main_only = false
time = false

[misc]
clean_on_exit = false

[screen]
clear_on_rebuild = false
keep_scroll = true
16 changes: 10 additions & 6 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import (
"github.com/voltgizerz/POS-restaurant/config"
"github.com/voltgizerz/POS-restaurant/database"
"github.com/voltgizerz/POS-restaurant/internal/app/api"
"github.com/voltgizerz/POS-restaurant/internal/app/api/auth"
"github.com/voltgizerz/POS-restaurant/internal/app/api/handler"
"github.com/voltgizerz/POS-restaurant/internal/app/api/middleware"
"github.com/voltgizerz/POS-restaurant/internal/app/auth"
"github.com/voltgizerz/POS-restaurant/internal/app/interactor"
"github.com/voltgizerz/POS-restaurant/internal/app/repository"
"github.com/voltgizerz/POS-restaurant/internal/app/service"
Expand Down Expand Up @@ -39,6 +40,9 @@ func main() {
// Initialize Auth JWT
authJWT := auth.NewAuthJWT(cfg.API.JWTSecretKey)

// Initialize Middleware
jwtMiddleware := middleware.NewJWTAuthMiddleware(authJWT)

repoOpts := repository.RepositoryOpts{
Database: db,
}
Expand All @@ -53,17 +57,17 @@ func main() {
})

// Initialize Handlers
userHandler := handler.NewUserHandler(interactor.UserHandler{
authHandler := handler.NewAuthHandler(interactor.UserHandler{
UserService: userService,
})

interactoAPI := interactor.APInteractor{
CfgAPI: cfg.API,
UserHandler: userHandler,
AuthHandler: authHandler,
}

// Start API server
go startAPIServer(interactoAPI)
go startAPIServer(interactoAPI, jwtMiddleware)

// Wait for termination signal
waitForSignal()
Expand All @@ -84,8 +88,8 @@ func handlePanic() {
}
}

func startAPIServer(interactor interactor.APInteractor) {
httpServer := api.NewServer(interactor)
func startAPIServer(interactor interactor.APInteractor, jwtMiddleware middleware.JWTAuth) {
httpServer := api.NewServer(interactor, jwtMiddleware)
httpServer.Initialize()
}

Expand Down
2 changes: 1 addition & 1 deletion database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func InitDatabase(ctx context.Context, cfg config.Database) *DatabaseOpts {
span, ctx := opentracing.StartSpanFromContext(ctx, "database.InitDatabase")
defer span.Finish()

dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s", cfg.Username, cfg.Password, cfg.Host, cfg.Name)
dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?parseTime=true", cfg.Username, cfg.Password, cfg.Host, cfg.Name)

return &DatabaseOpts{
MasterDB: connectMySQL(ctx, dsn, cfg.MaxOpenConns, cfg.MaxIdleConns),
Expand Down
1 change: 1 addition & 0 deletions database/migrations/20240622125106_add_users_table.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ CREATE TABLE `users` (
`email` varchar(255) DEFAULT NULL,
`password_hashed` varchar(528) DEFAULT NULL,
`is_active` tinyint(1) NOT NULL,
`role_id` tinyint(1) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
Expand Down
65 changes: 0 additions & 65 deletions internal/app/api/auth/auth.go

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,59 +13,65 @@ import (
"github.com/voltgizerz/POS-restaurant/internal/app/ports"
)

type UserHandler struct {
authService ports.IAuth
type AuthHandler struct {
userService ports.IUserService
}

func NewUserHandler(i interactor.UserHandler) *UserHandler {
return &UserHandler{
func NewAuthHandler(i interactor.UserHandler) *AuthHandler {
return &AuthHandler{
userService: i.UserService,
}
}

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

req := &loginRequest{}

err := c.Bind().Body(req)
if err != nil {
return sendErrorResp(c, fiber.StatusBadRequest, constants.ErrMsgInvalidUsernameAndPassword)
return SendErrorResp(c, fiber.StatusBadRequest, constants.ErrMsgInvalidUsernameAndPassword)
}

err = validator.New().StructCtx(ctx, req)
if err != nil {
validationErrors := err.(validator.ValidationErrors)

return sendErrorResp(c, fiber.StatusBadRequest, validationErrors.Error())
return SendErrorResp(c, fiber.StatusBadRequest, validationErrors.Error())
}

userLoginData, err := h.userService.Login(ctx, req.Username, req.Password)
if err != nil {
if err == sql.ErrNoRows {
return sendErrorResp(c, fiber.StatusUnauthorized, constants.ErrMsgUsernameNotFound)
return SendErrorResp(c, fiber.StatusUnauthorized, constants.ErrMsgUsernameNotFound)
}

return sendErrorResp(c, fiber.StatusUnauthorized, constants.ErrMsgInvalidUsernameOrPassword)
return SendErrorResp(c, fiber.StatusUnauthorized, constants.ErrMsgInvalidUsernameOrPassword)
}

return sendSuccessResp(c, fiber.StatusOK, "Success", userLoginData)
return SendSuccessResp(c, fiber.StatusOK, "Success", userLoginData)
}

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

req := &registerRequest{}
err := c.Bind().Body(req)
if err != nil {
return sendErrorResp(c, fiber.StatusBadRequest, "Invalid request body.")
return SendErrorResp(c, fiber.StatusBadRequest, "Invalid request body.")
}

err = validator.New().StructCtx(ctx, req)
if err != nil {
validationErrors := err.(validator.ValidationErrors)

return SendErrorResp(c, fiber.StatusBadRequest, validationErrors.Error())
}

if req.Password != req.ConfirmPassword {
return sendErrorResp(c, fiber.StatusBadRequest, "Password mismatch")
return SendErrorResp(c, fiber.StatusBadRequest, "Password mismatch")
}

userData := &entity.User{
Expand All @@ -77,11 +83,11 @@ func (h *UserHandler) Register(c fiber.Ctx) error {

result, err := h.userService.Register(ctx, *userData)
if err != nil {
return sendErrorResp(c, fiber.StatusBadRequest, err.Error())
return SendErrorResp(c, fiber.StatusBadRequest, err.Error())
}
res := map[string]int64{
"user_id": result,
}

return sendSuccessResp(c, fiber.StatusCreated, "Account created succesfully.", res)
return SendSuccessResp(c, fiber.StatusCreated, "Account created succesfully.", res)
}
10 changes: 5 additions & 5 deletions internal/app/api/handler/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ type (
}

registerRequest struct {
Username string `json:"username"`
Password string `json:"password"`
Name string `json:"name"`
ConfirmPassword string `json:"confirm_password"`
Email string `json:"email"`
Name string `json:"name" validate:"required"`
Username string `json:"username" validate:"required"`
Email string `json:"email" validate:"required"`
Password string `json:"password" validate:"required"`
ConfirmPassword string `json:"confirm_password" validate:"required"`
}
)
8 changes: 4 additions & 4 deletions internal/app/api/handler/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ type (
}
)

// sendErrorResp generates and sends error response
func sendErrorResp(c fiber.Ctx, statusCode int, errorMessage string) error {
// SendErrorResp generates and sends error response
func SendErrorResp(c fiber.Ctx, statusCode int, errorMessage string) error {
response := errorResponse{
Code: statusCode,
Message: errorMessage,
Expand All @@ -25,8 +25,8 @@ func sendErrorResp(c fiber.Ctx, statusCode int, errorMessage string) error {
return c.Status(statusCode).JSON(response)
}

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

0 comments on commit 30fec93

Please sign in to comment.