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, }) }