kontenhumas-be/app/middleware/menu_action_access.middlewa...

170 lines
4.5 KiB
Go

package middleware
import (
"netidhub-saas-be/app/database"
"netidhub-saas-be/app/database/entity"
"github.com/gofiber/fiber/v2"
)
type MenuActionAccessMiddleware struct {
DB *database.Database
}
func NewMenuActionAccessMiddleware(db *database.Database) *MenuActionAccessMiddleware {
return &MenuActionAccessMiddleware{
DB: db,
}
}
// CheckMenuAccess middleware untuk validasi akses user_level ke menu tertentu
func (m *MenuActionAccessMiddleware) CheckMenuAccess(menuId uint) fiber.Handler {
return func(c *fiber.Ctx) error {
// Get user from context
userCtx := c.Locals("user")
if userCtx == nil {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"success": false,
"code": 401,
"messages": []string{"User tidak terautentikasi"},
})
}
user, ok := userCtx.(*entity.Users)
if !ok || user == nil {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"success": false,
"code": 401,
"messages": []string{"User tidak valid"},
})
}
// Get user role untuk mendapatkan user_level_id
var userRole entity.UserRoles
if err := m.DB.DB.Where("id = ?", user.UserRoleId).First(&userRole).Error; err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"code": 500,
"messages": []string{"Error mendapatkan user role"},
"error": err.Error(),
})
}
userLevelId := userRole.UserLevelId
// Check akses user_level ke menu
var access entity.UserLevelMenuAccesses
err := m.DB.DB.Where(
"user_level_id = ? AND menu_id = ? AND is_active = ? AND can_access = ?",
userLevelId,
menuId,
true,
true,
).First(&access).Error
if err != nil {
// Jika tidak ada record, berarti tidak ada akses
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
"success": false,
"code": 403,
"messages": []string{"Anda tidak memiliki akses ke menu ini"},
"user_level_id": userLevelId,
"menu_id": menuId,
})
}
// Set menu ke context
c.Locals("menu_id", menuId)
c.Locals("user_level_id", userLevelId)
return c.Next()
}
}
// CheckMenuActionAccess middleware untuk validasi akses user_level ke action tertentu di dalam menu
func (m *MenuActionAccessMiddleware) CheckMenuActionAccess(menuId uint, actionCode string) fiber.Handler {
return func(c *fiber.Ctx) error {
// Get user from context
userCtx := c.Locals("user")
if userCtx == nil {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"success": false,
"code": 401,
"messages": []string{"User tidak terautentikasi"},
})
}
user, ok := userCtx.(*entity.Users)
if !ok || user == nil {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"success": false,
"code": 401,
"messages": []string{"User tidak valid"},
})
}
// Get user role untuk mendapatkan user_level_id
var userRole entity.UserRoles
if err := m.DB.DB.Where("id = ?", user.UserRoleId).First(&userRole).Error; err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"code": 500,
"messages": []string{"Error mendapatkan user role"},
"error": err.Error(),
})
}
userLevelId := userRole.UserLevelId
// First, check if user has access to the menu
var menuAccess entity.UserLevelMenuAccesses
err := m.DB.DB.Where(
"user_level_id = ? AND menu_id = ? AND is_active = ? AND can_access = ?",
userLevelId,
menuId,
true,
true,
).First(&menuAccess).Error
if err != nil {
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
"success": false,
"code": 403,
"messages": []string{"Anda tidak memiliki akses ke menu ini"},
"user_level_id": userLevelId,
"menu_id": menuId,
})
}
// Then, check if user has access to the specific action
var actionAccess entity.UserLevelMenuActionAccesses
err = m.DB.DB.Where(
"user_level_id = ? AND menu_id = ? AND action_code = ? AND is_active = ? AND can_access = ?",
userLevelId,
menuId,
actionCode,
true,
true,
).First(&actionAccess).Error
if err != nil {
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
"success": false,
"code": 403,
"messages": []string{"Anda tidak memiliki akses untuk melakukan action ini"},
"user_level_id": userLevelId,
"menu_id": menuId,
"action_code": actionCode,
})
}
// Set to context
c.Locals("menu_id", menuId)
c.Locals("action_code", actionCode)
c.Locals("user_level_id", userLevelId)
return c.Next()
}
}