Browse Source

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.
pull/8147/head
Chris Lu 4 days ago
parent
commit
922b0c3171
  1. 10
      weed/s3api/s3tables/handler_bucket_create.go
  2. 19
      weed/s3api/s3tables/handler_bucket_get_list_delete.go

10
weed/s3api/s3tables/handler_bucket_create.go

@ -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 err := h.createDirectory(r.Context(), client, TablesPath); err != nil {
return fmt.Errorf("failed to ensure root tables directory: %w", err)
if !h.entryExists(r.Context(), client, TablesPath) {
if err := h.createDirectory(r.Context(), client, TablesPath); err != nil {
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)

19
weed/s3api/s3tables/handler_bucket_get_list_delete.go

@ -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) {
h.writeError(w, http.StatusInternalServerError, ErrCodeInternalError, fmt.Sprintf("failed to list bucket entries: %v", err))
if errors.Is(err, filer_pb.ErrNotFound) {
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 {

Loading…
Cancel
Save