90 lines
2.1 KiB
Go
90 lines
2.1 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/vaultdrop/backend/internal/auth"
|
|
"github.com/vaultdrop/backend/internal/service"
|
|
"github.com/vaultdrop/backend/pkg/api"
|
|
)
|
|
|
|
type ShareHandler struct {
|
|
rebac *service.RebacService
|
|
}
|
|
|
|
func (h *ShareHandler) Grant(c *gin.Context) {
|
|
userID := c.GetString(auth.UserIDKey)
|
|
resourceID := c.Param("id")
|
|
|
|
var body struct {
|
|
SubjectUserID string `json:"subject_user_id" binding:"required"`
|
|
Role string `json:"role" binding:"required"`
|
|
}
|
|
if err := c.ShouldBindJSON(&body); err != nil {
|
|
api.Error(c, http.StatusBadRequest, "INVALID_BODY", "subject_user_id and role are required")
|
|
return
|
|
}
|
|
|
|
if err := h.rebac.GrantRole(userID, resourceID, body.SubjectUserID, body.Role); err != nil {
|
|
api.Error(c, http.StatusForbidden, "FORBIDDEN", err.Error())
|
|
return
|
|
}
|
|
|
|
api.Success(c, gin.H{"granted": true})
|
|
}
|
|
|
|
func (h *ShareHandler) Revoke(c *gin.Context) {
|
|
userID := c.GetString(auth.UserIDKey)
|
|
resourceID := c.Param("id")
|
|
subjectID := c.Param("userId")
|
|
|
|
if err := h.rebac.RevokeRole(userID, resourceID, subjectID); err != nil {
|
|
api.Error(c, http.StatusForbidden, "FORBIDDEN", err.Error())
|
|
return
|
|
}
|
|
|
|
api.Success(c, gin.H{"revoked": true})
|
|
}
|
|
|
|
func (h *ShareHandler) List(c *gin.Context) {
|
|
resourceID := c.Param("id")
|
|
|
|
relations, err := h.rebac.ListShares(resourceID)
|
|
if err != nil {
|
|
api.Error(c, http.StatusInternalServerError, "DB_ERROR", "Failed to list shares")
|
|
return
|
|
}
|
|
|
|
type shareResponse struct {
|
|
UserID string `json:"user_id"`
|
|
Role string `json:"role"`
|
|
}
|
|
|
|
resp := make([]shareResponse, len(relations))
|
|
for i, r := range relations {
|
|
resp[i] = shareResponse{
|
|
UserID: r.SubjectUserID.String(),
|
|
Role: r.Role,
|
|
}
|
|
}
|
|
|
|
api.Success(c, resp)
|
|
}
|
|
|
|
func (h *ShareHandler) Check(c *gin.Context) {
|
|
userID := c.GetString(auth.UserIDKey)
|
|
resourceID := c.Param("id")
|
|
|
|
role, err := h.rebac.ResolveEffectiveRole(userID, resourceID)
|
|
if err != nil {
|
|
api.Error(c, http.StatusInternalServerError, "DB_ERROR", "Failed to resolve role")
|
|
return
|
|
}
|
|
|
|
api.Success(c, gin.H{
|
|
"role": role,
|
|
"access": role != "",
|
|
})
|
|
}
|