This is an automated email from the ASF dual-hosted git repository.
jerryshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new a274f7adba [#13222] fix(api): fail closed in TableCatalog.loadTable
default with required privileges (#13223)
a274f7adba is described below
commit a274f7adbabb31fa945435c6bbf860f3af1c6225
Author: YangJie <[email protected]>
AuthorDate: Sun Sep 20 07:29:53 2026 -0400
[#13222] fix(api): fail closed in TableCatalog.loadTable default with
required privileges (#13223)
### What changes were proposed in this pull request?
The default `loadTable(ident, requiredPrivilegeNames)` now throws
`UnsupportedOperationException` instead of delegating to
`loadTable(ident)`, matching the convention used for other unsupported
capability defaults.
### Why are the changes needed?
The default silently discarded the required privileges while the javadoc
promised privilege-aware loading, so a caller relying on it as an
access-control checkpoint got the table with no enforcement and no
signal.
Fix: #13222
### Does this PR introduce _any_ user-facing change?
Yes. The default `loadTable(ident, requiredPrivilegeNames)` now throws
`UnsupportedOperationException` instead of silently ignoring the
privileges. This is a behavior change for any out-of-tree catalog that
relied on the default; the only in-repo override, `RelationalCatalog`,
forwards the privileges to the server and is unaffected.
### How was this patch tested?
Added `TestTableCatalog`, which pins that the default `loadTable(ident,
requiredPrivilegeNames)` throws `UnsupportedOperationException`; it
fails on the pre-fix tree (the default returned the table and dropped
the privileges) and passes after the fix.
Co-authored-by: Jerry Shao <[email protected]>
---
.../org/apache/gravitino/rel/TableCatalog.java | 9 ++-
.../org/apache/gravitino/rel/TestTableCatalog.java | 88 ++++++++++++++++++++++
2 files changed, 96 insertions(+), 1 deletion(-)
diff --git a/api/src/main/java/org/apache/gravitino/rel/TableCatalog.java
b/api/src/main/java/org/apache/gravitino/rel/TableCatalog.java
index 888526ffd5..6f564760f3 100644
--- a/api/src/main/java/org/apache/gravitino/rel/TableCatalog.java
+++ b/api/src/main/java/org/apache/gravitino/rel/TableCatalog.java
@@ -65,14 +65,21 @@ public interface TableCatalog {
/**
* Load table metadata by {@link NameIdentifier} from the catalog with
required privileges.
*
+ * <p>The default implementation throws {@link
UnsupportedOperationException}: a catalog that
+ * cannot enforce the required privileges must fail closed instead of
silently returning the table
+ * metadata. Catalogs that support privilege-aware loading must override
this method.
+ *
* @param ident A table identifier.
* @param requiredPrivilegeNames The required privilege names to access the
table.
* @return The table metadata.
* @throws NoSuchTableException If the table does not exist.
+ * @throws UnsupportedOperationException If the catalog does not support
loading a table with
+ * required privileges.
*/
default Table loadTable(NameIdentifier ident, Set<Privilege.Name>
requiredPrivilegeNames)
throws NoSuchTableException {
- return loadTable(ident);
+ throw new UnsupportedOperationException(
+ "The catalog does not support loading a table with required
privileges");
}
/**
diff --git a/api/src/test/java/org/apache/gravitino/rel/TestTableCatalog.java
b/api/src/test/java/org/apache/gravitino/rel/TestTableCatalog.java
new file mode 100644
index 0000000000..50281dad13
--- /dev/null
+++ b/api/src/test/java/org/apache/gravitino/rel/TestTableCatalog.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.gravitino.rel;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.Map;
+import org.apache.gravitino.NameIdentifier;
+import org.apache.gravitino.Namespace;
+import org.apache.gravitino.authorization.Privilege;
+import org.apache.gravitino.exceptions.NoSuchSchemaException;
+import org.apache.gravitino.exceptions.NoSuchTableException;
+import org.apache.gravitino.rel.expressions.distributions.Distribution;
+import org.apache.gravitino.rel.expressions.sorts.SortOrder;
+import org.apache.gravitino.rel.expressions.transforms.Transform;
+import org.apache.gravitino.rel.indexes.Index;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class TestTableCatalog {
+
+ private static TableCatalog minimalCatalog() {
+ return new TableCatalog() {
+ @Override
+ public NameIdentifier[] listTables(Namespace namespace) throws
NoSuchSchemaException {
+ return new NameIdentifier[0];
+ }
+
+ @Override
+ public Table loadTable(NameIdentifier ident) throws NoSuchTableException
{
+ return null;
+ }
+
+ @Override
+ public Table createTable(
+ NameIdentifier ident,
+ Column[] columns,
+ String comment,
+ Map<String, String> properties,
+ Transform[] partitions,
+ Distribution distribution,
+ SortOrder[] sortOrders,
+ Index[] indexes) {
+ return null;
+ }
+
+ @Override
+ public Table alterTable(NameIdentifier ident, TableChange... changes)
+ throws NoSuchTableException {
+ return null;
+ }
+
+ @Override
+ public boolean dropTable(NameIdentifier ident) {
+ return false;
+ }
+ };
+ }
+
+ @Test
+ void testLoadTableWithRequiredPrivilegesFailsClosedByDefault() {
+ TableCatalog catalog = minimalCatalog();
+
+ // Before the fix, the default silently discarded the required privileges
and returned the
+ // table as if no privilege check was requested.
+ Assertions.assertThrows(
+ UnsupportedOperationException.class,
+ () ->
+ catalog.loadTable(
+ NameIdentifier.of("schema", "table"),
+ ImmutableSet.of(Privilege.Name.SELECT_TABLE)));
+ }
+}