feat: add feature secure role access endpoint
This commit is contained in:
parent
885c0495f8
commit
7f4bc872c6
|
@ -4,6 +4,7 @@ import (
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/pahmiudahgede/senggoldong/internal/controllers"
|
"github.com/pahmiudahgede/senggoldong/internal/controllers"
|
||||||
"github.com/pahmiudahgede/senggoldong/internal/middleware"
|
"github.com/pahmiudahgede/senggoldong/internal/middleware"
|
||||||
|
"github.com/pahmiudahgede/senggoldong/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func AppRouter(app *fiber.App) {
|
func AppRouter(app *fiber.App) {
|
||||||
|
@ -35,8 +36,8 @@ func AppRouter(app *fiber.App) {
|
||||||
api.Delete("/coverage-areas-subdistrict/:id", controllers.DeleteCoverageSubdistrict)
|
api.Delete("/coverage-areas-subdistrict/:id", controllers.DeleteCoverageSubdistrict)
|
||||||
|
|
||||||
// # role #
|
// # role #
|
||||||
api.Get("/roles", controllers.GetAllUserRoles)
|
api.Get("/roles", middleware.RoleRequired(utils.RoleAdministrator), controllers.GetAllUserRoles)
|
||||||
api.Get("/role/:id", controllers.GetUserRoleByID)
|
api.Get("/role/:id", middleware.RoleRequired(utils.RoleAdministrator), controllers.GetUserRoleByID)
|
||||||
|
|
||||||
// # authentication #
|
// # authentication #
|
||||||
api.Post("/register", controllers.Register)
|
api.Post("/register", controllers.Register)
|
||||||
|
|
|
@ -70,7 +70,6 @@ func Login(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.BodyParser(&credentials); err != nil {
|
if err := c.BodyParser(&credentials); err != nil {
|
||||||
|
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||||
fiber.StatusBadRequest,
|
fiber.StatusBadRequest,
|
||||||
"Invalid input data",
|
"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)
|
token, err := services.LoginUser(credentials.EmailOrUsername, credentials.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusUnauthorized).JSON(utils.FormatResponse(
|
||||||
fiber.StatusUnauthorized,
|
fiber.StatusUnauthorized,
|
||||||
err.Error(),
|
err.Error(),
|
||||||
|
@ -91,7 +98,10 @@ func Login(c *fiber.Ctx) error {
|
||||||
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||||
fiber.StatusOK,
|
fiber.StatusOK,
|
||||||
"Login successful",
|
"Login successful",
|
||||||
map[string]string{"token": token},
|
map[string]interface{}{
|
||||||
|
"token": token,
|
||||||
|
"role": user.RoleID,
|
||||||
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,68 @@
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"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 {
|
func AuthMiddleware(c *fiber.Ctx) error {
|
||||||
tokenString := c.Get("Authorization")
|
tokenString := c.Get("Authorization")
|
||||||
tokenString = strings.TrimPrefix(tokenString, "Bearer ")
|
tokenString = strings.TrimPrefix(tokenString, "Bearer ")
|
||||||
|
|
|
@ -54,15 +54,15 @@ func LoginUser(emailOrUsername, password string) (string, error) {
|
||||||
return "", errors.New("invalid email/username or password")
|
return "", errors.New("invalid email/username or password")
|
||||||
}
|
}
|
||||||
|
|
||||||
token := generateJWT(user.ID)
|
token := generateJWT(user.ID, user.RoleID)
|
||||||
|
|
||||||
return token, nil
|
return token, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateJWT(userID string) string {
|
func generateJWT(userID, role string) string {
|
||||||
claims := jwt.MapClaims{
|
claims := jwt.MapClaims{
|
||||||
"sub": userID,
|
"sub": userID,
|
||||||
"exp": time.Now().Add(time.Hour * 24).Unix(),
|
"role": role,
|
||||||
|
"exp": time.Now().Add(time.Hour * 24 * 7).Unix(),
|
||||||
}
|
}
|
||||||
|
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
|
|
|
@ -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"
|
||||||
|
)
|
Loading…
Reference in New Issue