feat: add feature secure role access endpoint

This commit is contained in:
pahmiudahgede 2025-01-13 23:29:25 +07:00
parent 885c0495f8
commit 7f4bc872c6
5 changed files with 84 additions and 10 deletions

View File

@ -4,6 +4,7 @@ import (
"github.com/gofiber/fiber/v2"
"github.com/pahmiudahgede/senggoldong/internal/controllers"
"github.com/pahmiudahgede/senggoldong/internal/middleware"
"github.com/pahmiudahgede/senggoldong/utils"
)
func AppRouter(app *fiber.App) {
@ -35,8 +36,8 @@ func AppRouter(app *fiber.App) {
api.Delete("/coverage-areas-subdistrict/:id", controllers.DeleteCoverageSubdistrict)
// # role #
api.Get("/roles", controllers.GetAllUserRoles)
api.Get("/role/:id", controllers.GetUserRoleByID)
api.Get("/roles", middleware.RoleRequired(utils.RoleAdministrator), controllers.GetAllUserRoles)
api.Get("/role/:id", middleware.RoleRequired(utils.RoleAdministrator), controllers.GetUserRoleByID)
// # authentication #
api.Post("/register", controllers.Register)

View File

@ -70,7 +70,6 @@ func Login(c *fiber.Ctx) error {
}
if err := c.BodyParser(&credentials); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
fiber.StatusBadRequest,
"Invalid input data",
@ -78,9 +77,17 @@ func Login(c *fiber.Ctx) error {
))
}
user, err := repositories.GetUserByEmailOrUsername(credentials.EmailOrUsername)
if err != nil {
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
fiber.StatusUnauthorized,
err.Error(),
nil,
))
}
token, err := services.LoginUser(credentials.EmailOrUsername, credentials.Password)
if err != nil {
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
fiber.StatusUnauthorized,
err.Error(),
@ -91,7 +98,10 @@ func Login(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
fiber.StatusOK,
"Login successful",
map[string]string{"token": token},
map[string]interface{}{
"token": token,
"role": user.RoleID,
},
))
}

View File

@ -1,13 +1,68 @@
package middleware
import (
"errors"
"os"
"strings"
"github.com/gofiber/fiber/v2"
"github.com/golang-jwt/jwt/v5"
"github.com/pahmiudahgede/senggoldong/utils"
)
func RoleRequired(roles ...string) fiber.Handler {
return func(c *fiber.Ctx) error {
tokenString := c.Get("Authorization")
if tokenString == "" {
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
fiber.StatusUnauthorized,
"Token is required",
nil,
))
}
tokenString = strings.TrimPrefix(tokenString, "Bearer ")
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, errors.New("unexpected signing method")
}
return []byte(os.Getenv("API_KEY")), nil
})
if err != nil || !token.Valid {
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
fiber.StatusUnauthorized,
"Invalid or expired token",
nil,
))
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
fiber.StatusUnauthorized,
"Invalid token claims",
nil,
))
}
role := claims["role"].(string)
for _, r := range roles {
if r == role {
return c.Next()
}
}
return c.Status(fiber.StatusForbidden).JSON(utils.FormatResponse(
fiber.StatusForbidden,
"You do not have permission to access this resource",
nil,
))
}
}
func AuthMiddleware(c *fiber.Ctx) error {
tokenString := c.Get("Authorization")
tokenString = strings.TrimPrefix(tokenString, "Bearer ")

View File

@ -54,15 +54,15 @@ func LoginUser(emailOrUsername, password string) (string, error) {
return "", errors.New("invalid email/username or password")
}
token := generateJWT(user.ID)
token := generateJWT(user.ID, user.RoleID)
return token, nil
}
func generateJWT(userID string) string {
func generateJWT(userID, role string) string {
claims := jwt.MapClaims{
"sub": userID,
"exp": time.Now().Add(time.Hour * 24).Unix(),
"sub": userID,
"role": role,
"exp": time.Now().Add(time.Hour * 24 * 7).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

8
utils/role_permission.go Normal file
View File

@ -0,0 +1,8 @@
package utils
const (
RoleMasyarakat = "3e8cd1f0-205c-488d-9bab-bb53b99a6f49"
RolePengepul = "88a756fd-e9ab-4257-83a6-c36a0fb944b1"
RolePengelola = "cb328d60-5d40-4404-bfe1-25224d1bd126"
RoleAdministrator = "229395a8-f26d-445b-ae53-c67e5b25ea03"
)