255 lines
6.9 KiB
Go
255 lines
6.9 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
"go.uber.org/zap"
|
|
|
|
"veza-backend-api/internal/services"
|
|
)
|
|
|
|
// RBACHandlers handles RBAC-related API endpoints
|
|
type RBACHandlers struct {
|
|
rbacService *services.RBACService
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// NewRBACHandlers creates new RBAC handlers
|
|
func NewRBACHandlers(rbacService *services.RBACService, logger *zap.Logger) *RBACHandlers {
|
|
return &RBACHandlers{
|
|
rbacService: rbacService,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// InitRBACHandlers initializes RBAC handlers
|
|
func InitRBACHandlers(rbacService *services.RBACService, logger *zap.Logger) {
|
|
handlers := NewRBACHandlers(rbacService, logger)
|
|
|
|
// Store handlers globally for route registration
|
|
RBACHandlersInstance = handlers
|
|
}
|
|
|
|
// RBACHandlersInstance holds the global RBAC handlers instance
|
|
var RBACHandlersInstance *RBACHandlers
|
|
|
|
// CreateRole creates a new role
|
|
func (h *RBACHandlers) CreateRole(c *gin.Context) {
|
|
var req struct {
|
|
Name string `json:"name" binding:"required"`
|
|
Description string `json:"description"`
|
|
Permissions []uuid.UUID `json:"permissions"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
role, err := h.rbacService.CreateRole(c.Request.Context(), req.Name, req.Description, req.Permissions)
|
|
if err != nil {
|
|
h.logger.Error("Failed to create role", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create role"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusCreated, gin.H{
|
|
"success": true,
|
|
"role": role,
|
|
})
|
|
}
|
|
|
|
// GetRole gets a role by ID
|
|
func (h *RBACHandlers) GetRole(c *gin.Context) {
|
|
roleID, err := uuid.Parse(c.Param("id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid role ID"})
|
|
return
|
|
}
|
|
|
|
role, err := h.rbacService.GetRoleByID(c.Request.Context(), roleID)
|
|
if err != nil {
|
|
h.logger.Error("Failed to get role", zap.Error(err))
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Role not found"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"role": role,
|
|
})
|
|
}
|
|
|
|
// GetAllRoles gets all roles
|
|
func (h *RBACHandlers) GetAllRoles(c *gin.Context) {
|
|
roles, err := h.rbacService.GetAllRoles(c.Request.Context())
|
|
if err != nil {
|
|
h.logger.Error("Failed to get roles", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get roles"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"roles": roles,
|
|
})
|
|
}
|
|
|
|
// AssignRoleToUser assigns a role to a user
|
|
func (h *RBACHandlers) AssignRoleToUser(c *gin.Context) {
|
|
userID, err := uuid.Parse(c.Param("user_id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
|
|
return
|
|
}
|
|
|
|
var req struct {
|
|
RoleID uuid.UUID `json:"role_id" binding:"required"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
err = h.rbacService.AssignRoleToUser(c.Request.Context(), userID, req.RoleID)
|
|
if err != nil {
|
|
h.logger.Error("Failed to assign role to user", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to assign role to user"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"message": "Role assigned to user successfully",
|
|
})
|
|
}
|
|
|
|
// RemoveRoleFromUser removes a role from a user
|
|
func (h *RBACHandlers) RemoveRoleFromUser(c *gin.Context) {
|
|
userID, err := uuid.Parse(c.Param("user_id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
|
|
return
|
|
}
|
|
|
|
roleID, err := uuid.Parse(c.Param("role_id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid role ID"})
|
|
return
|
|
}
|
|
|
|
err = h.rbacService.RemoveRoleFromUser(c.Request.Context(), userID, roleID)
|
|
if err != nil {
|
|
h.logger.Error("Failed to remove role from user", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to remove role from user"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"message": "Role removed from user successfully",
|
|
})
|
|
}
|
|
|
|
// GetUserRoles gets all roles for a user
|
|
func (h *RBACHandlers) GetUserRoles(c *gin.Context) {
|
|
userID, err := uuid.Parse(c.Param("user_id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
|
|
return
|
|
}
|
|
|
|
roles, err := h.rbacService.GetUserRoles(c.Request.Context(), userID)
|
|
if err != nil {
|
|
h.logger.Error("Failed to get user roles", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get user roles"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"roles": roles,
|
|
})
|
|
}
|
|
|
|
// GetUserPermissions gets all permissions for a user
|
|
func (h *RBACHandlers) GetUserPermissions(c *gin.Context) {
|
|
userID, err := uuid.Parse(c.Param("user_id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
|
|
return
|
|
}
|
|
|
|
permissions, err := h.rbacService.GetUserPermissions(c.Request.Context(), userID)
|
|
if err != nil {
|
|
h.logger.Error("Failed to get user permissions", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get user permissions"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"permissions": permissions,
|
|
})
|
|
}
|
|
|
|
// CheckPermission checks if a user has a specific permission
|
|
func (h *RBACHandlers) CheckPermission(c *gin.Context) {
|
|
userID, err := uuid.Parse(c.Param("user_id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
|
|
return
|
|
}
|
|
|
|
resource := c.Query("resource")
|
|
action := c.Query("action")
|
|
|
|
if resource == "" || action == "" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Resource and action are required"})
|
|
return
|
|
}
|
|
|
|
hasPermission, err := h.rbacService.CheckPermission(c.Request.Context(), userID, resource, action)
|
|
if err != nil {
|
|
h.logger.Error("Failed to check permission", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to check permission"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"has_permission": hasPermission,
|
|
"resource": resource,
|
|
"action": action,
|
|
})
|
|
}
|
|
|
|
// CreatePermission creates a new permission
|
|
func (h *RBACHandlers) CreatePermission(c *gin.Context) {
|
|
var req struct {
|
|
Name string `json:"name" binding:"required"`
|
|
Description string `json:"description"`
|
|
Resource string `json:"resource" binding:"required"`
|
|
Action string `json:"action" binding:"required"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
permission, err := h.rbacService.CreatePermission(c.Request.Context(), req.Name, req.Description, req.Resource, req.Action)
|
|
if err != nil {
|
|
h.logger.Error("Failed to create permission", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create permission"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusCreated, gin.H{
|
|
"success": true,
|
|
"permission": permission,
|
|
})
|
|
}
|