NAM-APJATEL-BACKEND/middleware/rbac.go

189 lines
5.5 KiB
Go

package middleware
import (
"net/http"
"users_management/m/config"
"users_management/m/utils/common"
"github.com/gin-gonic/gin"
)
// ConditionalRequireRole middleware that respects auth config
func ConditionalRequireRole(cfg *config.Config, allowedRoles ...string) gin.HandlerFunc {
return func(c *gin.Context) {
// If auth is disabled, allow all requests
if !cfg.AuthConfig.UserAuthEnabled {
c.Next()
return
}
// If auth is enabled, check roles normally
RequireRole(allowedRoles...)(c)
}
}
// ConditionalRequireAnyRole middleware that respects auth config
func ConditionalRequireAnyRole(cfg *config.Config, roles ...string) gin.HandlerFunc {
return func(c *gin.Context) {
// If auth is disabled, allow all requests
if !cfg.AuthConfig.UserAuthEnabled {
c.Next()
return
}
// If auth is enabled, check roles normally
RequireAnyRole(roles...)(c)
}
}
// RequireRole middleware to check if user has required role
func RequireRole(allowedRoles ...string) gin.HandlerFunc {
return func(c *gin.Context) {
userRole, exists := c.Get("userRole")
if !exists {
common.ErrorResponses(c, http.StatusUnauthorized, "User role not found")
c.Abort()
return
}
role, ok := userRole.(string)
if !ok {
common.ErrorResponses(c, http.StatusUnauthorized, "Invalid user role")
c.Abort()
return
}
// Check if user role is in allowed roles
for _, allowedRole := range allowedRoles {
if role == allowedRole {
c.Next()
return
}
}
common.ErrorResponses(c, http.StatusForbidden, "Insufficient permissions")
c.Abort()
}
}
// RequireAnyRole middleware - user needs at least one of the specified roles
func RequireAnyRole(roles ...string) gin.HandlerFunc {
return RequireRole(roles...)
}
// RequireAdminRole middleware for admin-only access
func RequireAdminRole() gin.HandlerFunc {
return RequireRole("Admin", "Super Admin")
}
// RequireSuperAdminRole middleware for superadmin-only access
func RequireSuperAdminRole() gin.HandlerFunc {
return RequireRole("Super Admin")
}
// RequireTeknisiRole middleware for teknisi access
func RequireTeknisiRole() gin.HandlerFunc {
return RequireRole("Teknisi")
}
// RequireNonTeknisiRole middleware to block teknisi users
func RequireNonTeknisiRole() gin.HandlerFunc {
return func(c *gin.Context) {
userRole, exists := c.Get("userRole")
if !exists {
common.ErrorResponses(c, http.StatusUnauthorized, "User role not found")
c.Abort()
return
}
role, ok := userRole.(string)
if !ok {
common.ErrorResponses(c, http.StatusUnauthorized, "Invalid user role")
c.Abort()
return
}
if role == "Teknisi" {
common.ErrorResponses(c, http.StatusForbidden, "Teknisi users are not allowed to access this resource")
c.Abort()
return
}
c.Next()
}
}
// PermissionMiddleware for more granular permissions
func PermissionMiddleware(resource, action string) gin.HandlerFunc {
return func(c *gin.Context) {
userRole, exists := c.Get("userRole")
if !exists {
common.ErrorResponses(c, http.StatusUnauthorized, "User role not found")
c.Abort()
return
}
role, ok := userRole.(string)
if !ok {
common.ErrorResponses(c, http.StatusUnauthorized, "Invalid user role")
c.Abort()
return
}
if !hasPermission(role, resource, action) {
common.ErrorResponses(c, http.StatusForbidden, "Insufficient permissions for this action")
c.Abort()
return
}
c.Next()
}
}
// Permission checker function
func hasPermission(role, resource, action string) bool {
permissions := getPermissions()
rolePermissions, exists := permissions[role]
if !exists {
return false
}
resourcePermissions, exists := rolePermissions[resource]
if !exists {
return false
}
for _, allowedAction := range resourcePermissions {
if allowedAction == action || allowedAction == "*" {
return true
}
}
return false
}
// Define permissions for each role
func getPermissions() map[string]map[string][]string {
return map[string]map[string][]string{
"Superadmin": {
"*": {"*"}, // Full access to everything
},
"Admin": {
"backbone": {"CREATE", "READ", "UPDATE", "DELETE"},
"fishbone": {"CREATE", "READ", "UPDATE", "DELETE"},
"devices": {"CREATE", "READ", "UPDATE", "DELETE"},
"towers": {"CREATE", "READ", "UPDATE", "DELETE"},
"ports": {"CREATE", "READ", "UPDATE", "DELETE"},
"logs": {"READ"},
"users": {"READ"},
},
"Teknisi": {
"backbone": {"CREATE", "READ", "UPDATE"},
"fishbone": {"CREATE", "READ", "UPDATE"},
"devices": {"CREATE", "READ", "UPDATE"},
"towers": {"CREATE", "READ", "UPDATE"},
"ports": {"CREATE", "READ", "UPDATE"},
"logs": {"READ"}, // Only own logs
},
}
}