veza/veza-backend-api/internal/api/handlers/rbac_handlers.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,
})
}