s3tables: implement granular authorization and refine error responses
- Remove mandatory ACTION_ADMIN at the router level - Enforce granular permissions in bucket and namespace handlers - Prioritize AccountID in ExtractPrincipalFromContext for ARN matching - Distinguish between 404 (NoSuchBucket) and 500 (InternalError) in metadata lookups - Clean up unused imports in s3api_tables.go
This commit is contained in:
@@ -19,6 +19,13 @@ func (h *S3TablesHandler) handleCreateNamespace(w http.ResponseWriter, r *http.R
|
||||
return err
|
||||
}
|
||||
|
||||
// Check permission
|
||||
principal := h.getPrincipalFromRequest(r)
|
||||
if !CanCreateNamespace(principal, h.accountID) {
|
||||
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to create namespace")
|
||||
return NewAuthError("CreateNamespace", principal, "not authorized to create namespace")
|
||||
}
|
||||
|
||||
if req.TableBucketARN == "" {
|
||||
h.writeError(w, http.StatusBadRequest, ErrCodeInvalidRequest, "tableBucketARN is required")
|
||||
return fmt.Errorf("tableBucketARN is required")
|
||||
@@ -120,6 +127,13 @@ func (h *S3TablesHandler) handleGetNamespace(w http.ResponseWriter, r *http.Requ
|
||||
return err
|
||||
}
|
||||
|
||||
// Check permission
|
||||
principal := h.getPrincipalFromRequest(r)
|
||||
if !CanGetNamespace(principal, h.accountID) {
|
||||
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to get namespace details")
|
||||
return NewAuthError("GetNamespace", principal, "not authorized to get namespace details")
|
||||
}
|
||||
|
||||
if req.TableBucketARN == "" {
|
||||
h.writeError(w, http.StatusBadRequest, ErrCodeInvalidRequest, "tableBucketARN is required")
|
||||
return fmt.Errorf("tableBucketARN is required")
|
||||
@@ -172,6 +186,13 @@ func (h *S3TablesHandler) handleListNamespaces(w http.ResponseWriter, r *http.Re
|
||||
return err
|
||||
}
|
||||
|
||||
// Check permission
|
||||
principal := h.getPrincipalFromRequest(r)
|
||||
if !CanListNamespaces(principal, h.accountID) {
|
||||
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to list namespaces")
|
||||
return NewAuthError("ListNamespaces", principal, "not authorized to list namespaces")
|
||||
}
|
||||
|
||||
if req.TableBucketARN == "" {
|
||||
h.writeError(w, http.StatusBadRequest, ErrCodeInvalidRequest, "tableBucketARN is required")
|
||||
return fmt.Errorf("tableBucketARN is required")
|
||||
@@ -276,6 +297,13 @@ func (h *S3TablesHandler) handleDeleteNamespace(w http.ResponseWriter, r *http.R
|
||||
return err
|
||||
}
|
||||
|
||||
// Check permission
|
||||
principal := h.getPrincipalFromRequest(r)
|
||||
if !CanDeleteNamespace(principal, h.accountID) {
|
||||
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to delete namespace")
|
||||
return NewAuthError("DeleteNamespace", principal, "not authorized to delete namespace")
|
||||
}
|
||||
|
||||
if req.TableBucketARN == "" {
|
||||
h.writeError(w, http.StatusBadRequest, ErrCodeInvalidRequest, "tableBucketARN is required")
|
||||
return fmt.Errorf("tableBucketARN is required")
|
||||
|
||||
Reference in New Issue
Block a user