yuqi1129 commented on code in PR #13481:
URL: https://github.com/apache/gravitino/pull/13481#discussion_r4094953098


##########
core/src/main/java/org/apache/gravitino/catalog/TableNormalizeDispatcher.java:
##########
@@ -62,7 +66,7 @@ public NameIdentifier[] listTables(Namespace namespace) 
throws NoSuchSchemaExcep
   public Table loadTable(NameIdentifier ident) throws NoSuchTableException {
     // The constraints of the name spec may be more strict than underlying 
catalog,
     // and for compatibility reasons, we only apply case-sensitive 
capabilities here.
-    return dispatcher.loadTable(normalizeCaseSensitive(ident));
+    return dispatcher.loadTable(resolvePhysicalName(ident, 
normalizeCaseSensitive(ident)));

Review Comment:
   Authorization for this request already ran in the REST layer against 
`normalizeCaseSensitive(ident)` (via `MetadataIdConverter.getID`), not against 
the identifier resolved here. When the two differ and the normalized name has 
an entity, the privilege check and the operation target different tables. The 
same applies to alter/drop/purge/exists below. See the review summary for two 
concrete timelines.



##########
core/src/main/java/org/apache/gravitino/connector/SupportsTableNameResolution.java:
##########
@@ -0,0 +1,78 @@
+/*
+ * 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.connector;
+
+import org.apache.gravitino.NameIdentifier;
+import org.apache.gravitino.annotation.Evolving;
+import org.apache.gravitino.rel.TableCatalog;
+
+/**
+ * A server-internal, connector-side capability that maps a table identifier 
to the identifier under
+ * which the table is physically stored by the underlying source, for backends 
whose name
+ * normalization is not reversible.
+ *
+ * <p>Most catalogs store a table under exactly the name Gravitino normalized 
it to, so they do not
+ * implement this. A catalog whose {@link 
org.apache.gravitino.connector.capability.Capability}
+ * folds an unquoted name to a fixed case while the source also keeps 
case-sensitive names created
+ * with a different case (so a name returned by {@link 
TableCatalog#listTables} may not equal the
+ * normalized name) may implement this so that a name returned by list 
round-trips through
+ * load/alter/drop.
+ *
+ * <p>This is a {@link CatalogOperations} mixin, not part of the user-facing 
{@link TableCatalog}
+ * API: it is only consulted by the server on the load/alter/drop path and is 
never exposed to
+ * clients. The server resolves the name before the operation runs, so the 
resolved identifier
+ * drives the downstream authorization hooks, the underlying catalog call and 
the Gravitino entity
+ * store key consistently.
+ *
+ * <p><b>Resolution contract.</b> Implementations receive both the identifier 
the caller requested
+ * and the identifier after Gravitino's case normalization, and must:
+ *
+ * <ul>
+ *   <li>prefer an object whose stored name equals {@code requestedIdent}'s 
name exactly, so a
+ *       case-sensitive name the caller supplied verbatim is honored even when 
a differently-cased
+ *       sibling exists;
+ *   <li>otherwise use an object whose stored name equals {@code 
normalizedIdent}'s name exactly;
+ *   <li>otherwise, if exactly one stored name matches {@code normalizedIdent} 
case-insensitively,

Review Comment:
   Even without the rule above, this fallback can diverge from the authorized 
name. The authorizer looks up the entity *store* by the normalized name, while 
this rule looks at the *source*. With a stale `ORDERS` registration in the 
store and only `orders` in the source, the request is authorized by the stale 
entity and then acts on `orders`. The resolved name has to be the one that gets 
authorized.



##########
core/src/main/java/org/apache/gravitino/connector/SupportsTableNameResolution.java:
##########
@@ -0,0 +1,78 @@
+/*
+ * 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.connector;
+
+import org.apache.gravitino.NameIdentifier;
+import org.apache.gravitino.annotation.Evolving;
+import org.apache.gravitino.rel.TableCatalog;
+
+/**
+ * A server-internal, connector-side capability that maps a table identifier 
to the identifier under
+ * which the table is physically stored by the underlying source, for backends 
whose name
+ * normalization is not reversible.
+ *
+ * <p>Most catalogs store a table under exactly the name Gravitino normalized 
it to, so they do not
+ * implement this. A catalog whose {@link 
org.apache.gravitino.connector.capability.Capability}
+ * folds an unquoted name to a fixed case while the source also keeps 
case-sensitive names created
+ * with a different case (so a name returned by {@link 
TableCatalog#listTables} may not equal the
+ * normalized name) may implement this so that a name returned by list 
round-trips through
+ * load/alter/drop.
+ *
+ * <p>This is a {@link CatalogOperations} mixin, not part of the user-facing 
{@link TableCatalog}
+ * API: it is only consulted by the server on the load/alter/drop path and is 
never exposed to
+ * clients. The server resolves the name before the operation runs, so the 
resolved identifier
+ * drives the downstream authorization hooks, the underlying catalog call and 
the Gravitino entity
+ * store key consistently.
+ *
+ * <p><b>Resolution contract.</b> Implementations receive both the identifier 
the caller requested
+ * and the identifier after Gravitino's case normalization, and must:
+ *
+ * <ul>
+ *   <li>prefer an object whose stored name equals {@code requestedIdent}'s 
name exactly, so a

Review Comment:
   This rule makes the authorization mismatch directly reachable. With `ORDERS` 
and a quoted `orders` both present, an unquoted request for `orders` is 
authorized as `ORDERS` but resolves to `orders`. It also contradicts a folding 
capability: unquoted `orders` means `ORDERS`. I'd drop this rule and the 
`requestedIdent` parameter, since quoted input is already preserved by the 
normalization.



##########
core/src/test/java/org/apache/gravitino/catalog/TestTableNormalizeDispatcher.java:
##########
@@ -295,4 +298,179 @@ private void assertTableCaseInsensitive(
     Assertions.assertEquals(
         expectedColumns[0].name().toLowerCase(), 
table.index()[0].fieldNames()[0][0].toLowerCase());
   }
+
+  @Test
+  public void testPhysicalNameResolutionDrivesDownstreamIdentifier() throws 
Exception {

Review Comment:
   These tests mock the resolver and the downstream dispatcher, so they can't 
catch the authorization mismatch. Please add a test showing that, for one 
request, the metadata id used for authorization and the identifier handed to 
the dispatcher come from the same resolved name (for example, 
`MetadataIdConverter.getID` with a resolving catalog).



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to