Files
calypso/backend/internal/shares/handler.go
2026-01-04 12:54:25 +07:00

148 lines
4.0 KiB
Go

package shares
import (
"net/http"
"github.com/atlasos/calypso/internal/common/database"
"github.com/atlasos/calypso/internal/common/logger"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
)
// Handler handles Shares-related API requests
type Handler struct {
service *Service
logger *logger.Logger
}
// NewHandler creates a new Shares handler
func NewHandler(db *database.DB, log *logger.Logger) *Handler {
return &Handler{
service: NewService(db, log),
logger: log,
}
}
// ListShares lists all shares
func (h *Handler) ListShares(c *gin.Context) {
shares, err := h.service.ListShares(c.Request.Context())
if err != nil {
h.logger.Error("Failed to list shares", "error", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list shares"})
return
}
// Ensure we return an empty array instead of null
if shares == nil {
shares = []*Share{}
}
c.JSON(http.StatusOK, gin.H{"shares": shares})
}
// GetShare retrieves a share by ID
func (h *Handler) GetShare(c *gin.Context) {
shareID := c.Param("id")
share, err := h.service.GetShare(c.Request.Context(), shareID)
if err != nil {
if err.Error() == "share not found" {
c.JSON(http.StatusNotFound, gin.H{"error": "share not found"})
return
}
h.logger.Error("Failed to get share", "error", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get share"})
return
}
c.JSON(http.StatusOK, share)
}
// CreateShare creates a new share
func (h *Handler) CreateShare(c *gin.Context) {
var req CreateShareRequest
if err := c.ShouldBindJSON(&req); err != nil {
h.logger.Error("Invalid create share request", "error", err)
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request: " + err.Error()})
return
}
// Validate request
validate := validator.New()
if err := validate.Struct(req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "validation failed: " + err.Error()})
return
}
// Get user ID from context (set by auth middleware)
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
return
}
share, err := h.service.CreateShare(c.Request.Context(), &req, userID.(string))
if err != nil {
if err.Error() == "dataset not found" {
c.JSON(http.StatusNotFound, gin.H{"error": "dataset not found"})
return
}
if err.Error() == "only filesystem datasets can be shared (not volumes)" {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err.Error() == "at least one protocol (NFS or SMB) must be enabled" {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
h.logger.Error("Failed to create share", "error", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, share)
}
// UpdateShare updates an existing share
func (h *Handler) UpdateShare(c *gin.Context) {
shareID := c.Param("id")
var req UpdateShareRequest
if err := c.ShouldBindJSON(&req); err != nil {
h.logger.Error("Invalid update share request", "error", err)
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request: " + err.Error()})
return
}
share, err := h.service.UpdateShare(c.Request.Context(), shareID, &req)
if err != nil {
if err.Error() == "share not found" {
c.JSON(http.StatusNotFound, gin.H{"error": "share not found"})
return
}
h.logger.Error("Failed to update share", "error", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, share)
}
// DeleteShare deletes a share
func (h *Handler) DeleteShare(c *gin.Context) {
shareID := c.Param("id")
err := h.service.DeleteShare(c.Request.Context(), shareID)
if err != nil {
if err.Error() == "share not found" {
c.JSON(http.StatusNotFound, gin.H{"error": "share not found"})
return
}
h.logger.Error("Failed to delete share", "error", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "share deleted successfully"})
}