Files
steve 2a86f87b50
Build image / build-and-push (push) Successful in 4s
Sharing backend: shares CRUD + ACL enforcement everywhere (#16)
Co-authored-by: Steve Dudenhoeffer <[email protected]>
2026-07-19 03:49:54 +00:00

89 lines
2.1 KiB
Go

package api
import (
"net/http"
"github.com/gin-gonic/gin"
)
// shareCreateRequest is the body for POST /gardens/:id/shares: the recipient's
// exact account email and the role to grant (viewer|editor).
type shareCreateRequest struct {
Email string `json:"email" binding:"required"`
Role string `json:"role" binding:"required"`
}
// shareUpdateRequest is the body for PATCH /gardens/:id/shares/:userId.
type shareUpdateRequest struct {
Role string `json:"role" binding:"required"`
}
func (h *handlers) listShares(c *gin.Context) {
gardenID, ok := parseIDParam(c, "id")
if !ok {
return
}
shares, err := h.svc.ListShares(c.Request.Context(), mustActor(c).ID, gardenID)
if err != nil {
writeServiceError(c, err)
return
}
c.JSON(http.StatusOK, shares)
}
func (h *handlers) addShare(c *gin.Context) {
gardenID, ok := parseIDParam(c, "id")
if !ok {
return
}
var req shareCreateRequest
if err := c.ShouldBindJSON(&req); err != nil {
writeAPIError(c, http.StatusBadRequest, "INVALID_INPUT", "an email and a role are required")
return
}
sh, err := h.svc.AddShare(c.Request.Context(), mustActor(c).ID, gardenID, req.Email, req.Role)
if err != nil {
writeServiceError(c, err)
return
}
c.JSON(http.StatusCreated, sh)
}
func (h *handlers) updateShare(c *gin.Context) {
gardenID, ok := parseIDParam(c, "id")
if !ok {
return
}
userID, ok := parseIDParam(c, "userId")
if !ok {
return
}
var req shareUpdateRequest
if err := c.ShouldBindJSON(&req); err != nil {
writeAPIError(c, http.StatusBadRequest, "INVALID_INPUT", "a role is required")
return
}
sh, err := h.svc.UpdateShareRole(c.Request.Context(), mustActor(c).ID, gardenID, userID, req.Role)
if err != nil {
writeServiceError(c, err)
return
}
c.JSON(http.StatusOK, sh)
}
func (h *handlers) removeShare(c *gin.Context) {
gardenID, ok := parseIDParam(c, "id")
if !ok {
return
}
userID, ok := parseIDParam(c, "userId")
if !ok {
return
}
if err := h.svc.RemoveShare(c.Request.Context(), mustActor(c).ID, gardenID, userID); err != nil {
writeServiceError(c, err)
return
}
c.Status(http.StatusNoContent)
}