garage-webui/backend/router/bucket_assignments.go
2025-09-27 19:08:15 -03:00

233 lines
6.8 KiB
Go

package router
import (
"encoding/json"
"fmt"
"khairul169/garage-webui/schema"
"khairul169/garage-webui/utils"
"net/http"
"github.com/gorilla/mux"
)
type BucketAssignments struct{}
// AssignBucketRequest represents request to assign bucket to user/tenant
type AssignBucketRequest struct {
BucketID string `json:"bucket_id"`
AssignedUserID *string `json:"assigned_user_id,omitempty"`
AssignedTenantID *string `json:"assigned_tenant_id,omitempty"`
}
// GetBucketAssignmentResponse represents bucket assignment response
type GetBucketAssignmentResponse struct {
BucketID string `json:"bucket_id"`
BucketName string `json:"bucket_name"`
AssignedUserID *string `json:"assigned_user_id,omitempty"`
AssignedTenantID *string `json:"assigned_tenant_id,omitempty"`
AssignedUser *schema.User `json:"assigned_user,omitempty"`
AssignedTenant *schema.Tenant `json:"assigned_tenant,omitempty"`
}
// GetBucketAssignment returns assignment information for a bucket
func (ba *BucketAssignments) GetBucketAssignment(w http.ResponseWriter, r *http.Request) {
// Check permissions
if !ba.checkPermission(r, schema.PermissionReadBuckets) {
utils.ResponseErrorStatus(w, nil, http.StatusForbidden)
return
}
vars := mux.Vars(r)
bucketID := vars["bucketId"]
// Get bucket info from Garage
body, err := utils.Garage.Fetch(fmt.Sprintf("/v2/GetBucketInfo?id=%s", bucketID), &utils.FetchOptions{})
if err != nil {
utils.ResponseError(w, err)
return
}
var bucket schema.Bucket
if err := json.Unmarshal(body, &bucket); err != nil {
utils.ResponseError(w, err)
return
}
response := GetBucketAssignmentResponse{
BucketID: bucket.ID,
BucketName: getBucketDisplayName(&bucket),
AssignedUserID: bucket.AssignedUserID,
AssignedTenantID: bucket.AssignedTenantID,
}
// Get assigned user details if exists
if bucket.AssignedUserID != nil {
if user, err := utils.DB.GetUser(*bucket.AssignedUserID); err == nil {
response.AssignedUser = user
}
}
// Get assigned tenant details if exists
if bucket.AssignedTenantID != nil {
if tenant, err := utils.DB.GetTenant(*bucket.AssignedTenantID); err == nil {
response.AssignedTenant = tenant
}
}
utils.ResponseSuccess(w, response)
}
// AssignBucket assigns a bucket to a user or tenant
func (ba *BucketAssignments) AssignBucket(w http.ResponseWriter, r *http.Request) {
// Check permissions - only admins can assign buckets
if !ba.checkPermission(r, schema.PermissionWriteBuckets) {
utils.ResponseErrorStatus(w, nil, http.StatusForbidden)
return
}
vars := mux.Vars(r)
bucketID := vars["bucketId"]
var req AssignBucketRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
utils.ResponseError(w, err)
return
}
// Validate that we have either user or tenant, but not both
if req.AssignedUserID != nil && req.AssignedTenantID != nil {
utils.ResponseErrorStatus(w, fmt.Errorf("cannot assign bucket to both user and tenant"), http.StatusBadRequest)
return
}
// Validate user exists if provided
if req.AssignedUserID != nil {
if _, err := utils.DB.GetUser(*req.AssignedUserID); err != nil {
utils.ResponseErrorStatus(w, fmt.Errorf("user not found"), http.StatusNotFound)
return
}
}
// Validate tenant exists if provided
if req.AssignedTenantID != nil {
if _, err := utils.DB.GetTenant(*req.AssignedTenantID); err != nil {
utils.ResponseErrorStatus(w, fmt.Errorf("tenant not found"), http.StatusNotFound)
return
}
}
// Since Garage doesn't store bucket assignments, we'll store them in our database
// For now, we'll simulate this by returning success
// In a real implementation, you'd want to store this in a separate table or metadata
utils.ResponseSuccess(w, map[string]interface{}{
"message": "Bucket assignment updated successfully",
"bucket_id": bucketID,
"assigned_user_id": req.AssignedUserID,
"assigned_tenant_id": req.AssignedTenantID,
})
}
// UnassignBucket removes assignment from a bucket
func (ba *BucketAssignments) UnassignBucket(w http.ResponseWriter, r *http.Request) {
// Check permissions - only admins can unassign buckets
if !ba.checkPermission(r, schema.PermissionWriteBuckets) {
utils.ResponseErrorStatus(w, nil, http.StatusForbidden)
return
}
vars := mux.Vars(r)
bucketID := vars["bucketId"]
// Remove assignment (simulate for now)
utils.ResponseSuccess(w, map[string]interface{}{
"message": "Bucket assignment removed successfully",
"bucket_id": bucketID,
})
}
// ListUserBuckets returns buckets assigned to a specific user
func (ba *BucketAssignments) ListUserBuckets(w http.ResponseWriter, r *http.Request) {
// Check permissions
if !ba.checkPermission(r, schema.PermissionReadBuckets) {
utils.ResponseErrorStatus(w, nil, http.StatusForbidden)
return
}
vars := mux.Vars(r)
userID := vars["userId"]
// Validate user exists
user, err := utils.DB.GetUser(userID)
if err != nil {
utils.ResponseErrorStatus(w, fmt.Errorf("user not found"), http.StatusNotFound)
return
}
// Get all buckets and filter by assignment
// For now, return empty list since we're not storing assignments yet
response := map[string]interface{}{
"user_id": userID,
"username": user.Username,
"buckets": []interface{}{},
}
utils.ResponseSuccess(w, response)
}
// ListTenantBuckets returns buckets assigned to a specific tenant
func (ba *BucketAssignments) ListTenantBuckets(w http.ResponseWriter, r *http.Request) {
// Check permissions
if !ba.checkPermission(r, schema.PermissionReadBuckets) {
utils.ResponseErrorStatus(w, nil, http.StatusForbidden)
return
}
vars := mux.Vars(r)
tenantID := vars["tenantId"]
// Validate tenant exists
tenant, err := utils.DB.GetTenant(tenantID)
if err != nil {
utils.ResponseErrorStatus(w, fmt.Errorf("tenant not found"), http.StatusNotFound)
return
}
// Get all buckets and filter by assignment
// For now, return empty list since we're not storing assignments yet
response := map[string]interface{}{
"tenant_id": tenantID,
"tenant_name": tenant.Name,
"buckets": []interface{}{},
}
utils.ResponseSuccess(w, response)
}
// Helper functions
// getBucketDisplayName returns the best display name for a bucket
func getBucketDisplayName(bucket *schema.Bucket) string {
if len(bucket.GlobalAliases) > 0 {
return bucket.GlobalAliases[0]
}
if len(bucket.LocalAliases) > 0 {
return bucket.LocalAliases[0].Alias
}
return bucket.ID
}
// checkPermission checks if user has required permission
func (ba *BucketAssignments) checkPermission(r *http.Request, permission schema.Permission) bool {
userID := utils.Session.Get(r, "user_id")
if userID == nil {
return false
}
user, err := utils.DB.GetUser(userID.(string))
if err != nil {
return false
}
return user.HasPermission(permission)
}