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());
+  }
 }

Reply via email to