s3tables: update bucket handlers for multi-account support
Ensured bucket ownership is correctly attributed to the authenticated account ID and updated ARNs to use the request-derived account ID. Added standard S3 existence checks for bucket deletion.
This commit is contained in:
@@ -78,7 +78,7 @@ func (h *S3TablesHandler) handleCreateTableBucket(w http.ResponseWriter, r *http
|
|||||||
metadata := &tableBucketMetadata{
|
metadata := &tableBucketMetadata{
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
OwnerID: h.accountID,
|
OwnerID: h.getAccountID(r),
|
||||||
}
|
}
|
||||||
|
|
||||||
metadataBytes, err := json.Marshal(metadata)
|
metadataBytes, err := json.Marshal(metadata)
|
||||||
@@ -90,8 +90,10 @@ func (h *S3TablesHandler) handleCreateTableBucket(w http.ResponseWriter, r *http
|
|||||||
|
|
||||||
err = filerClient.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
|
err = filerClient.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
|
||||||
// Ensure root tables directory exists
|
// Ensure root tables directory exists
|
||||||
|
if !h.entryExists(r.Context(), client, TablesPath) {
|
||||||
if err := h.createDirectory(r.Context(), client, TablesPath); err != nil {
|
if err := h.createDirectory(r.Context(), client, TablesPath); err != nil {
|
||||||
return fmt.Errorf("failed to ensure root tables directory: %w", err)
|
return fmt.Errorf("failed to create root tables directory: %w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create bucket directory
|
// Create bucket directory
|
||||||
@@ -125,7 +127,7 @@ func (h *S3TablesHandler) handleCreateTableBucket(w http.ResponseWriter, r *http
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp := &CreateTableBucketResponse{
|
resp := &CreateTableBucketResponse{
|
||||||
ARN: h.generateTableBucketARN(req.Name),
|
ARN: h.generateTableBucketARN(r, req.Name),
|
||||||
}
|
}
|
||||||
|
|
||||||
h.writeJSON(w, http.StatusOK, resp)
|
h.writeJSON(w, http.StatusOK, resp)
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import (
|
|||||||
func (h *S3TablesHandler) handleGetTableBucket(w http.ResponseWriter, r *http.Request, filerClient FilerClient) error {
|
func (h *S3TablesHandler) handleGetTableBucket(w http.ResponseWriter, r *http.Request, filerClient FilerClient) error {
|
||||||
// Check permission
|
// Check permission
|
||||||
principal := h.getPrincipalFromRequest(r)
|
principal := h.getPrincipalFromRequest(r)
|
||||||
if !CanGetTableBucket(principal, h.accountID) {
|
accountID := h.getAccountID(r)
|
||||||
|
if !CanGetTableBucket(principal, accountID) {
|
||||||
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to get table bucket details")
|
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to get table bucket details")
|
||||||
return NewAuthError("GetTableBucket", principal, "not authorized to get table bucket details")
|
return NewAuthError("GetTableBucket", principal, "not authorized to get table bucket details")
|
||||||
}
|
}
|
||||||
@@ -58,7 +59,7 @@ func (h *S3TablesHandler) handleGetTableBucket(w http.ResponseWriter, r *http.Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp := &GetTableBucketResponse{
|
resp := &GetTableBucketResponse{
|
||||||
ARN: h.generateTableBucketARN(bucketName),
|
ARN: h.generateTableBucketARN(r, bucketName),
|
||||||
Name: metadata.Name,
|
Name: metadata.Name,
|
||||||
OwnerAccountID: metadata.OwnerID,
|
OwnerAccountID: metadata.OwnerID,
|
||||||
CreatedAt: metadata.CreatedAt,
|
CreatedAt: metadata.CreatedAt,
|
||||||
@@ -78,7 +79,8 @@ func (h *S3TablesHandler) handleListTableBuckets(w http.ResponseWriter, r *http.
|
|||||||
|
|
||||||
// Check permission
|
// Check permission
|
||||||
principal := h.getPrincipalFromRequest(r)
|
principal := h.getPrincipalFromRequest(r)
|
||||||
if !CanListTableBuckets(principal, h.accountID) {
|
accountID := h.getAccountID(r)
|
||||||
|
if !CanListTableBuckets(principal, accountID) {
|
||||||
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to list table buckets")
|
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to list table buckets")
|
||||||
return NewAuthError("ListTableBuckets", principal, "not authorized to list table buckets")
|
return NewAuthError("ListTableBuckets", principal, "not authorized to list table buckets")
|
||||||
}
|
}
|
||||||
@@ -150,7 +152,7 @@ func (h *S3TablesHandler) handleListTableBuckets(w http.ResponseWriter, r *http.
|
|||||||
}
|
}
|
||||||
|
|
||||||
buckets = append(buckets, TableBucketSummary{
|
buckets = append(buckets, TableBucketSummary{
|
||||||
ARN: h.generateTableBucketARN(entry.Entry.Name),
|
ARN: h.generateTableBucketARN(r, entry.Entry.Name),
|
||||||
Name: entry.Entry.Name,
|
Name: entry.Entry.Name,
|
||||||
CreatedAt: metadata.CreatedAt,
|
CreatedAt: metadata.CreatedAt,
|
||||||
})
|
})
|
||||||
@@ -197,7 +199,8 @@ func (h *S3TablesHandler) handleListTableBuckets(w http.ResponseWriter, r *http.
|
|||||||
func (h *S3TablesHandler) handleDeleteTableBucket(w http.ResponseWriter, r *http.Request, filerClient FilerClient) error {
|
func (h *S3TablesHandler) handleDeleteTableBucket(w http.ResponseWriter, r *http.Request, filerClient FilerClient) error {
|
||||||
// Check permission
|
// Check permission
|
||||||
principal := h.getPrincipalFromRequest(r)
|
principal := h.getPrincipalFromRequest(r)
|
||||||
if !CanDeleteTableBucket(principal, h.accountID) {
|
accountID := h.getAccountID(r)
|
||||||
|
if !CanDeleteTableBucket(principal, accountID) {
|
||||||
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to delete table buckets")
|
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to delete table buckets")
|
||||||
return NewAuthError("DeleteTableBucket", principal, "not authorized to delete table buckets")
|
return NewAuthError("DeleteTableBucket", principal, "not authorized to delete table buckets")
|
||||||
}
|
}
|
||||||
@@ -250,10 +253,12 @@ func (h *S3TablesHandler) handleDeleteTableBucket(w http.ResponseWriter, r *http
|
|||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(err, filer_pb.ErrNotFound) {
|
if errors.Is(err, filer_pb.ErrNotFound) {
|
||||||
h.writeError(w, http.StatusInternalServerError, ErrCodeInternalError, fmt.Sprintf("failed to list bucket entries: %v", err))
|
h.writeError(w, http.StatusNotFound, ErrCodeNoSuchBucket, fmt.Sprintf("table bucket %s not found", bucketName))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
h.writeError(w, http.StatusInternalServerError, ErrCodeInternalError, fmt.Sprintf("failed to list bucket entries: %v", err))
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasChildren {
|
if hasChildren {
|
||||||
|
|||||||
Reference in New Issue
Block a user