Spaces:
Runtime error
Runtime error
Commit ·
90e41cb
1
Parent(s): 539de26
Deploy files from GitHub repository
Browse files- controllers/authentication_controller.go +3 -3
- middleware/authentication_middleware.go +4 -2
- models/dto/jwt_dto.go +1 -1
- router/forgot_password_router.go +14 -0
- router/router.go +1 -0
- services/account_service.go +1 -1
- services/email_verification_service.go +1 -1
- services/external_auth_service.go +1 -2
- services/forgot_password_service.go +1 -1
- services/jwt_service.go +10 -4
- utils/util.go +20 -0
controllers/authentication_controller.go
CHANGED
|
@@ -3,8 +3,8 @@ package controllers
|
|
| 3 |
import (
|
| 4 |
"abdanhafidz.com/go-boilerplate/models/dto"
|
| 5 |
"abdanhafidz.com/go-boilerplate/services"
|
|
|
|
| 6 |
"github.com/gin-gonic/gin"
|
| 7 |
-
"github.com/google/uuid"
|
| 8 |
)
|
| 9 |
|
| 10 |
type AuthenticationController interface {
|
|
@@ -39,8 +39,8 @@ func (c *authenticationController) SignIn(ctx *gin.Context) {
|
|
| 39 |
|
| 40 |
func (c *authenticationController) ChangePassword(ctx *gin.Context) {
|
| 41 |
req := RequestJSON[dto.ChangePasswordRequest](ctx)
|
| 42 |
-
|
| 43 |
-
accountId,
|
| 44 |
res, err := c.accountService.ChangePassword(ctx.Request.Context(), accountId, req.OldPassword, req.NewPassword)
|
| 45 |
ResponseJSON(ctx, req, res, err)
|
| 46 |
}
|
|
|
|
| 3 |
import (
|
| 4 |
"abdanhafidz.com/go-boilerplate/models/dto"
|
| 5 |
"abdanhafidz.com/go-boilerplate/services"
|
| 6 |
+
"abdanhafidz.com/go-boilerplate/utils"
|
| 7 |
"github.com/gin-gonic/gin"
|
|
|
|
| 8 |
)
|
| 9 |
|
| 10 |
type AuthenticationController interface {
|
|
|
|
| 39 |
|
| 40 |
func (c *authenticationController) ChangePassword(ctx *gin.Context) {
|
| 41 |
req := RequestJSON[dto.ChangePasswordRequest](ctx)
|
| 42 |
+
gaccountId, _ := ctx.Get("account_id")
|
| 43 |
+
accountId, err := utils.ToUUID(gaccountId)
|
| 44 |
res, err := c.accountService.ChangePassword(ctx.Request.Context(), accountId, req.OldPassword, req.NewPassword)
|
| 45 |
ResponseJSON(ctx, req, res, err)
|
| 46 |
}
|
middleware/authentication_middleware.go
CHANGED
|
@@ -2,6 +2,8 @@ package middleware
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"errors"
|
|
|
|
|
|
|
| 5 |
|
| 6 |
http_error "abdanhafidz.com/go-boilerplate/models/error"
|
| 7 |
"abdanhafidz.com/go-boilerplate/services"
|
|
@@ -26,7 +28,7 @@ func (m *authenticationMiddleware) VerifyAccount(c *gin.Context) {
|
|
| 26 |
authorizationBearer := c.Request.Header["Authorization"]
|
| 27 |
|
| 28 |
if authorizationBearer != nil {
|
| 29 |
-
token := authorizationBearer[0]
|
| 30 |
claim, err := m.jwtService.ValidateToken(c.Request.Context(), token)
|
| 31 |
|
| 32 |
if err != nil && errors.Is(err, http_error.INVALID_TOKEN) {
|
|
@@ -34,7 +36,7 @@ func (m *authenticationMiddleware) VerifyAccount(c *gin.Context) {
|
|
| 34 |
c.Abort()
|
| 35 |
return
|
| 36 |
}
|
| 37 |
-
|
| 38 |
c.Set("account_id", claim.AccountId)
|
| 39 |
c.Next()
|
| 40 |
|
|
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"errors"
|
| 5 |
+
"fmt"
|
| 6 |
+
"strings"
|
| 7 |
|
| 8 |
http_error "abdanhafidz.com/go-boilerplate/models/error"
|
| 9 |
"abdanhafidz.com/go-boilerplate/services"
|
|
|
|
| 28 |
authorizationBearer := c.Request.Header["Authorization"]
|
| 29 |
|
| 30 |
if authorizationBearer != nil {
|
| 31 |
+
token := strings.Split(authorizationBearer[0], " ")[1]
|
| 32 |
claim, err := m.jwtService.ValidateToken(c.Request.Context(), token)
|
| 33 |
|
| 34 |
if err != nil && errors.Is(err, http_error.INVALID_TOKEN) {
|
|
|
|
| 36 |
c.Abort()
|
| 37 |
return
|
| 38 |
}
|
| 39 |
+
fmt.Println("Claims:", claim)
|
| 40 |
c.Set("account_id", claim.AccountId)
|
| 41 |
c.Next()
|
| 42 |
|
models/dto/jwt_dto.go
CHANGED
|
@@ -6,7 +6,7 @@ import (
|
|
| 6 |
)
|
| 7 |
|
| 8 |
type JWTCustomClaims struct {
|
| 9 |
-
AccountId
|
| 10 |
jwt.RegisteredClaims
|
| 11 |
}
|
| 12 |
|
|
|
|
| 6 |
)
|
| 7 |
|
| 8 |
type JWTCustomClaims struct {
|
| 9 |
+
AccountId string `json:"account_id" binding:"required"`
|
| 10 |
jwt.RegisteredClaims
|
| 11 |
}
|
| 12 |
|
router/forgot_password_router.go
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package router
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"abdanhafidz.com/go-boilerplate/provider"
|
| 5 |
+
"github.com/gin-gonic/gin"
|
| 6 |
+
)
|
| 7 |
+
|
| 8 |
+
func ForgotPasswordRouter(router *gin.Engine, controller provider.ControllerProvider) {
|
| 9 |
+
routerGroup := router.Group("/api/v1/forgot-password")
|
| 10 |
+
forgotPasswordController := controller.ProvideForgotPasswordController()
|
| 11 |
+
{
|
| 12 |
+
routerGroup.POST("/", forgotPasswordController.Request)
|
| 13 |
+
}
|
| 14 |
+
}
|
router/router.go
CHANGED
|
@@ -7,6 +7,7 @@ import (
|
|
| 7 |
func RunRouter(appProvider provider.AppProvider) {
|
| 8 |
router, controller, config, middleware := appProvider.ProvideRouter(), appProvider.ProvideControllers(), appProvider.ProvideConfig(), appProvider.ProvideMiddlewares()
|
| 9 |
AuthenticationRouter(router, middleware, controller)
|
|
|
|
| 10 |
AccountDetailRouter(router, middleware, controller)
|
| 11 |
EmailVerificationRouter(router, controller)
|
| 12 |
EventRouter(router, middleware, controller)
|
|
|
|
| 7 |
func RunRouter(appProvider provider.AppProvider) {
|
| 8 |
router, controller, config, middleware := appProvider.ProvideRouter(), appProvider.ProvideControllers(), appProvider.ProvideConfig(), appProvider.ProvideMiddlewares()
|
| 9 |
AuthenticationRouter(router, middleware, controller)
|
| 10 |
+
ForgotPasswordRouter(router, controller)
|
| 11 |
AccountDetailRouter(router, middleware, controller)
|
| 12 |
EmailVerificationRouter(router, controller)
|
| 13 |
EventRouter(router, middleware, controller)
|
services/account_service.go
CHANGED
|
@@ -93,7 +93,7 @@ func (s *accountService) Validate(ctx context.Context, emailorusername string, p
|
|
| 93 |
}
|
| 94 |
|
| 95 |
token, err := s.jwtService.GenerateToken(ctx, dto.JWTCustomClaims{
|
| 96 |
-
AccountId: acc.Id,
|
| 97 |
})
|
| 98 |
|
| 99 |
if err != nil {
|
|
|
|
| 93 |
}
|
| 94 |
|
| 95 |
token, err := s.jwtService.GenerateToken(ctx, dto.JWTCustomClaims{
|
| 96 |
+
AccountId: acc.Id.String(),
|
| 97 |
})
|
| 98 |
|
| 99 |
if err != nil {
|
services/email_verification_service.go
CHANGED
|
@@ -50,7 +50,7 @@ func (s *emailVerificationService) VerifyToken(ctx context.Context, email string
|
|
| 50 |
|
| 51 |
ev, err := s.emailVerificationRepo.GetByAccountAndToken(ctx, acc.Id, token)
|
| 52 |
if errors.Is(err, gorm.ErrRecordNotFound) {
|
| 53 |
-
return http_error.
|
| 54 |
}
|
| 55 |
if err != nil {
|
| 56 |
return err
|
|
|
|
| 50 |
|
| 51 |
ev, err := s.emailVerificationRepo.GetByAccountAndToken(ctx, acc.Id, token)
|
| 52 |
if errors.Is(err, gorm.ErrRecordNotFound) {
|
| 53 |
+
return http_error.INVALID_OTP
|
| 54 |
}
|
| 55 |
if err != nil {
|
| 56 |
return err
|
services/external_auth_service.go
CHANGED
|
@@ -83,9 +83,8 @@ func (s *externalAuthService) GoogleAuth(ctx context.Context, idToken string) (d
|
|
| 83 |
if errExtAuth != nil {
|
| 84 |
return dto.AuthenticatedUser{}, errExtAuth
|
| 85 |
}
|
| 86 |
-
|
| 87 |
token, _ := s.jwtService.GenerateToken(ctx, dto.JWTCustomClaims{
|
| 88 |
-
AccountId: acc.Id,
|
| 89 |
})
|
| 90 |
|
| 91 |
err = errors.Join(errAcc, errExtAuth)
|
|
|
|
| 83 |
if errExtAuth != nil {
|
| 84 |
return dto.AuthenticatedUser{}, errExtAuth
|
| 85 |
}
|
|
|
|
| 86 |
token, _ := s.jwtService.GenerateToken(ctx, dto.JWTCustomClaims{
|
| 87 |
+
AccountId: acc.Id.String(),
|
| 88 |
})
|
| 89 |
|
| 90 |
err = errors.Join(errAcc, errExtAuth)
|
services/forgot_password_service.go
CHANGED
|
@@ -50,7 +50,7 @@ func (s *forgotPasswordService) Reset(ctx context.Context, token uint, newPasswo
|
|
| 50 |
|
| 51 |
rec, err := s.forgotPasswordRepo.GetByToken(ctx, token)
|
| 52 |
if errors.Is(err, gorm.ErrRecordNotFound) {
|
| 53 |
-
return http_error.
|
| 54 |
}
|
| 55 |
|
| 56 |
if err != nil {
|
|
|
|
| 50 |
|
| 51 |
rec, err := s.forgotPasswordRepo.GetByToken(ctx, token)
|
| 52 |
if errors.Is(err, gorm.ErrRecordNotFound) {
|
| 53 |
+
return http_error.INVALID_OTP
|
| 54 |
}
|
| 55 |
|
| 56 |
if err != nil {
|
services/jwt_service.go
CHANGED
|
@@ -2,11 +2,11 @@ package services
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"context"
|
|
|
|
| 5 |
|
| 6 |
"abdanhafidz.com/go-boilerplate/models/dto"
|
| 7 |
http_error "abdanhafidz.com/go-boilerplate/models/error"
|
| 8 |
"github.com/golang-jwt/jwt/v4"
|
| 9 |
-
uuid "github.com/google/uuid"
|
| 10 |
"golang.org/x/crypto/bcrypt"
|
| 11 |
)
|
| 12 |
|
|
@@ -56,16 +56,22 @@ func (s *jwtService) ValidateToken(ctx context.Context, tokenStr string) (claim
|
|
| 56 |
return []byte(s.secretKey), nil
|
| 57 |
})
|
| 58 |
|
|
|
|
|
|
|
|
|
|
| 59 |
if err != nil || !token.Valid {
|
| 60 |
return nil, http_error.INVALID_TOKEN
|
| 61 |
}
|
| 62 |
|
| 63 |
claims, ok := token.Claims.(jwt.MapClaims)
|
| 64 |
if !ok {
|
| 65 |
-
return nil, http_error.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
}
|
| 67 |
-
|
| 68 |
return &dto.JWTCustomClaims{
|
| 69 |
-
AccountId:
|
| 70 |
}, nil
|
| 71 |
}
|
|
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
+
"fmt"
|
| 6 |
|
| 7 |
"abdanhafidz.com/go-boilerplate/models/dto"
|
| 8 |
http_error "abdanhafidz.com/go-boilerplate/models/error"
|
| 9 |
"github.com/golang-jwt/jwt/v4"
|
|
|
|
| 10 |
"golang.org/x/crypto/bcrypt"
|
| 11 |
)
|
| 12 |
|
|
|
|
| 56 |
return []byte(s.secretKey), nil
|
| 57 |
})
|
| 58 |
|
| 59 |
+
fmt.Println("Token", token)
|
| 60 |
+
fmt.Println("secretKey", s.secretKey)
|
| 61 |
+
|
| 62 |
if err != nil || !token.Valid {
|
| 63 |
return nil, http_error.INVALID_TOKEN
|
| 64 |
}
|
| 65 |
|
| 66 |
claims, ok := token.Claims.(jwt.MapClaims)
|
| 67 |
if !ok {
|
| 68 |
+
return nil, http_error.INTERNAL_SERVER_ERROR
|
| 69 |
+
}
|
| 70 |
+
account_id, ok := claims["account_id"].(string)
|
| 71 |
+
if !ok {
|
| 72 |
+
return nil, http_error.INTERNAL_SERVER_ERROR
|
| 73 |
}
|
|
|
|
| 74 |
return &dto.JWTCustomClaims{
|
| 75 |
+
AccountId: account_id,
|
| 76 |
}, nil
|
| 77 |
}
|
utils/util.go
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package utils
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
http_error "abdanhafidz.com/go-boilerplate/models/error"
|
| 5 |
+
"github.com/google/uuid"
|
| 6 |
+
)
|
| 7 |
+
|
| 8 |
+
func ToUUID(s any) (uuid.UUID, error) {
|
| 9 |
+
sStr, ok := s.(string)
|
| 10 |
+
if !ok {
|
| 11 |
+
return uuid.UUID{}, http_error.INTERNAL_SERVER_ERROR
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
res, err := uuid.Parse(sStr)
|
| 15 |
+
if err != nil {
|
| 16 |
+
return uuid.UUID{}, http_error.INTERNAL_SERVER_ERROR
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
return res, nil
|
| 20 |
+
}
|