This is an automated email from the ASF dual-hosted git repository.
jerryshao pushed a commit to branch branch-1.3
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/branch-1.3 by this push:
new 9736cb1173 [Cherry-pick to branch-1.3] [#13326] fix(server): Check
object before listing roles (#13327) (#13328)
9736cb1173 is described below
commit 9736cb117309fc264b7cc71950a5dbac1417b9e4
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Fri Sep 18 22:19:28 2026 +0800
[Cherry-pick to branch-1.3] [#13326] fix(server): Check object before
listing roles (#13327) (#13328)
**Cherry-pick Information:**
- Original commit: 744a7591d2f62d680fec2bd1584ab7d36e2b5115
- Target branch: `branch-1.3`
- Status: ✅ Clean cherry-pick (no conflicts)
Co-authored-by: roryqi <[email protected]>
---
.../web/rest/MetadataObjectRoleOperations.java | 2 +
.../web/rest/TestMetadataObjectRoleOperations.java | 47 ++++++++++++++++++++++
2 files changed, 49 insertions(+)
diff --git
a/server/src/main/java/org/apache/gravitino/server/web/rest/MetadataObjectRoleOperations.java
b/server/src/main/java/org/apache/gravitino/server/web/rest/MetadataObjectRoleOperations.java
index 225a2e5e6b..fc6eebcdac 100644
---
a/server/src/main/java/org/apache/gravitino/server/web/rest/MetadataObjectRoleOperations.java
+++
b/server/src/main/java/org/apache/gravitino/server/web/rest/MetadataObjectRoleOperations.java
@@ -39,6 +39,7 @@ import org.apache.gravitino.metrics.MetricNames;
import org.apache.gravitino.server.authorization.MetadataAuthzHelper;
import org.apache.gravitino.server.authorization.NameBindings;
import org.apache.gravitino.server.web.Utils;
+import org.apache.gravitino.utils.MetadataObjectUtil;
import org.apache.gravitino.utils.NameIdentifierUtil;
@NameBindings.AccessControlInterfaces
@@ -76,6 +77,7 @@ public class MetadataObjectRoleOperations {
httpRequest,
() -> {
MetalakeManager.checkMetalakeInUse(metalake);
+ MetadataObjectUtil.checkMetadataObject(metalake, object);
String[] names =
accessControlDispatcher.listRoleNamesByObject(metalake, object);
names =
MetadataAuthzHelper.filterByExpression(
diff --git
a/server/src/test/java/org/apache/gravitino/server/web/rest/TestMetadataObjectRoleOperations.java
b/server/src/test/java/org/apache/gravitino/server/web/rest/TestMetadataObjectRoleOperations.java
index 339953434a..17d33f3807 100644
---
a/server/src/test/java/org/apache/gravitino/server/web/rest/TestMetadataObjectRoleOperations.java
+++
b/server/src/test/java/org/apache/gravitino/server/web/rest/TestMetadataObjectRoleOperations.java
@@ -35,7 +35,9 @@ import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.gravitino.Config;
import org.apache.gravitino.EntityStore;
import org.apache.gravitino.GravitinoEnv;
+import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.authorization.AccessControlManager;
+import org.apache.gravitino.catalog.TableDispatcher;
import org.apache.gravitino.connector.PropertiesMetadata;
import org.apache.gravitino.dto.responses.ErrorConstants;
import org.apache.gravitino.dto.responses.ErrorResponse;
@@ -44,6 +46,7 @@ import org.apache.gravitino.exceptions.NoSuchEntityException;
import org.apache.gravitino.exceptions.NoSuchMetalakeException;
import org.apache.gravitino.lock.LockManager;
import org.apache.gravitino.meta.BaseMetalake;
+import org.apache.gravitino.metalake.MetalakeDispatcher;
import org.apache.gravitino.rest.RESTUtils;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;
@@ -51,6 +54,7 @@ import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.TestProperties;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
@@ -58,6 +62,8 @@ public class TestMetadataObjectRoleOperations extends
JerseyTest {
private static final AccessControlManager manager =
mock(AccessControlManager.class);
private static final EntityStore entityStore = mock(EntityStore.class);
+ private static final MetalakeDispatcher metalakeDispatcher =
mock(MetalakeDispatcher.class);
+ private static final TableDispatcher tableDispatcher =
mock(TableDispatcher.class);
private static class MockServletRequestFactory extends
ServletRequestFactoryBase {
@Override
@@ -77,6 +83,26 @@ public class TestMetadataObjectRoleOperations extends
JerseyTest {
FieldUtils.writeField(GravitinoEnv.getInstance(), "lockManager", new
LockManager(config), true);
FieldUtils.writeField(GravitinoEnv.getInstance(),
"accessControlDispatcher", manager, true);
FieldUtils.writeField(GravitinoEnv.getInstance(), "entityStore",
entityStore, true);
+ FieldUtils.writeField(
+ GravitinoEnv.getInstance(), "internalMetalakeDispatcher",
metalakeDispatcher, true);
+ FieldUtils.writeField(
+ GravitinoEnv.getInstance(), "internalTableDispatcher",
tableDispatcher, true);
+ }
+
+ @BeforeEach
+ public void resetMocks() throws IOException {
+ Mockito.reset(manager, entityStore, metalakeDispatcher, tableDispatcher);
+ when(metalakeDispatcher.metalakeExists(any())).thenReturn(true);
+ when(tableDispatcher.tableExists(any())).thenReturn(true);
+ mockInUseMetalake();
+ }
+
+ private static void mockInUseMetalake() throws IOException {
+ BaseMetalake metalake = mock(BaseMetalake.class);
+ PropertiesMetadata propertiesMetadata = mock(PropertiesMetadata.class);
+ when(propertiesMetadata.getOrDefault(any(), any())).thenReturn(true);
+ when(metalake.propertiesMetadata()).thenReturn(propertiesMetadata);
+ when(entityStore.get(any(), any(), any())).thenReturn(metalake);
}
@Override
@@ -160,4 +186,25 @@ public class TestMetadataObjectRoleOperations extends
JerseyTest {
Assertions.assertEquals(ErrorConstants.INTERNAL_ERROR_CODE,
errorResponse2.getCode());
Assertions.assertEquals(RuntimeException.class.getSimpleName(),
errorResponse2.getType());
}
+
+ @Test
+ public void testListRoleNamesChecksTableObjectBeforeListing() throws
IOException {
+ when(manager.listRoleNamesByObject(any(), any())).thenReturn(new
String[0]);
+
+ Response resp =
+
target("/metalakes/metalake1/objects/table/catalog1.schema1.table1/roles")
+ .request(MediaType.APPLICATION_JSON_TYPE)
+ .accept("application/vnd.gravitino.v1+json")
+ .get();
+
+ Assertions.assertEquals(Response.Status.OK.getStatusCode(),
resp.getStatus());
+
+ NameListResponse listResponse = resp.readEntity(NameListResponse.class);
+ Assertions.assertEquals(0, listResponse.getCode());
+ Assertions.assertEquals(0, listResponse.getNames().length);
+
+ Mockito.verify(tableDispatcher)
+ .tableExists(NameIdentifier.of("metalake1", "catalog1", "schema1",
"table1"));
+ Mockito.verify(manager).listRoleNamesByObject(any(), any());
+ }
}