This is an automated email from the ASF dual-hosted git repository.

roryqi 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 300daf9055 [#9266] feat(authz): Support filter MetadataObject (#9290)
300daf9055 is described below

commit 300daf905531109aac5ae15338c4c89fc04e7371
Author: yangyang zhong <[email protected]>
AuthorDate: Wed Dec 3 10:12:27 2025 +0800

    [#9266] feat(authz): Support filter MetadataObject (#9290)
    
    ### What changes were proposed in this pull request?
    
    Support filter MetadataObject
    
    ### Why are the changes needed?
    
    Fix: #9266
    
    ### Does this PR introduce _any_ user-facing change?
    
    None
    
    ### How was this patch tested?
    
    Add new test cases.
---
 .../test/authorization/PolicyAuthorizationIT.java  |  49 ++++++++
 .../TagOperationsAuthorizationIT.java              |  86 +++++++++++++-
 .../authorization/AuthorizationRequestContext.java |   2 +-
 .../server/authorization/MetadataAuthzHelper.java  | 130 ++++++++++++++-------
 .../authorization/TestMetadataAuthzHelper.java     | 111 +++++++++++++-----
 .../authorization/CommonAuthorizerExecutor.java    |   2 +
 .../server/web/rest/PolicyOperations.java          |   4 +-
 .../gravitino/server/web/rest/TagOperations.java   |   5 +-
 8 files changed, 308 insertions(+), 81 deletions(-)

diff --git 
a/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/authorization/PolicyAuthorizationIT.java
 
b/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/authorization/PolicyAuthorizationIT.java
index 211137b493..5776ce1b9f 100644
--- 
a/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/authorization/PolicyAuthorizationIT.java
+++ 
b/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/authorization/PolicyAuthorizationIT.java
@@ -25,6 +25,7 @@ import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Maps;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -33,6 +34,7 @@ import org.apache.gravitino.Catalog;
 import org.apache.gravitino.MetadataObject;
 import org.apache.gravitino.MetadataObjects;
 import org.apache.gravitino.NameIdentifier;
+import org.apache.gravitino.authorization.Owner;
 import org.apache.gravitino.authorization.Privileges;
 import org.apache.gravitino.authorization.SecurableObject;
 import org.apache.gravitino.authorization.SecurableObjects;
@@ -372,6 +374,53 @@ public class PolicyAuthorizationIT extends 
BaseRestApiAuthorizationIT {
 
   @Test
   @Order(9)
+  public void testListObjForPolicy() {
+    GravitinoMetalake gravitinoMetalake = client.loadMetalake(METALAKE);
+    GravitinoMetalake gravitinoMetalakeLoadByNormalUser = 
normalUserClient.loadMetalake(METALAKE);
+    String[] tables =
+        Arrays.stream(
+                gravitinoMetalakeLoadByNormalUser
+                    .getPolicy("policy2")
+                    .associatedObjects()
+                    .objects())
+            .map(MetadataObject::name)
+            .toList()
+            .toArray(new String[0]);
+    Arrays.sort(tables);
+    Assertions.assertArrayEquals(new String[] {"table2", "table3"}, tables);
+    MetadataObject metadataObject =
+        MetadataObjects.of(ImmutableList.of(CATALOG, SCHEMA, "table2"), 
MetadataObject.Type.TABLE);
+    gravitinoMetalake.setOwner(metadataObject, USER, Owner.Type.USER);
+    gravitinoMetalake.grantPrivilegesToRole(
+        role, metadataObject, ImmutableSet.of(Privileges.SelectTable.deny()));
+    tables =
+        Arrays.stream(
+                gravitinoMetalakeLoadByNormalUser
+                    .getPolicy("policy2")
+                    .associatedObjects()
+                    .objects())
+            .map(MetadataObject::name)
+            .toList()
+            .toArray(new String[0]);
+    Arrays.sort(tables);
+    Assertions.assertArrayEquals(new String[] {"table3"}, tables);
+    assertThrows(
+        "Can not access metadata.",
+        ForbiddenException.class,
+        () -> {
+          
gravitinoMetalakeLoadByNormalUser.getPolicy("policy1").associatedObjects().objects();
+        });
+    tables =
+        
Arrays.stream(gravitinoMetalake.getPolicy("policy1").associatedObjects().objects())
+            .map(MetadataObject::name)
+            .toList()
+            .toArray(new String[0]);
+    Arrays.sort(tables);
+    Assertions.assertArrayEquals(new String[] {"table1"}, tables);
+  }
+
+  @Test
+  @Order(10)
   public void testDropPolicy() {
     GravitinoMetalake gravitinoMetalake = client.loadMetalake(METALAKE);
     GravitinoMetalake metalakeLoadByNormalUser = 
normalUserClient.loadMetalake(METALAKE);
diff --git 
a/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/authorization/TagOperationsAuthorizationIT.java
 
b/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/authorization/TagOperationsAuthorizationIT.java
index 74034a130f..01780d8bee 100644
--- 
a/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/authorization/TagOperationsAuthorizationIT.java
+++ 
b/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/authorization/TagOperationsAuthorizationIT.java
@@ -301,21 +301,80 @@ public class TagOperationsAuthorizationIT extends 
BaseRestApiAuthorizationIT {
 
   @Test
   @Order(9)
-  public void testDropTag() {
+  public void testListObjForTag() {
+    GravitinoMetalake gravitinoMetalake = client.loadMetalake(METALAKE);
     GravitinoMetalake gravitinoMetalakeLoadByNormalUser = 
normalUserClient.loadMetalake(METALAKE);
+    String[] objs =
+        
Arrays.stream(gravitinoMetalake.getTag("tag1").associatedObjects().objects())
+            .map(MetadataObject::name)
+            .toList()
+            .toArray(new String[0]);
+    Arrays.sort(objs);
+    Assertions.assertArrayEquals(new String[] {"catalog", "table1"}, objs);
+    objs =
+        
Arrays.stream(gravitinoMetalake.getTag("tag2").associatedObjects().objects())
+            .map(MetadataObject::name)
+            .toList()
+            .toArray(new String[0]);
+    Arrays.sort(objs);
+    Assertions.assertArrayEquals(new String[] {"table1"}, objs);
+    objs =
+        
Arrays.stream(gravitinoMetalake.getTag("tag3").associatedObjects().objects())
+            .map(MetadataObject::name)
+            .toList()
+            .toArray(new String[0]);
+    Arrays.sort(objs);
+    Assertions.assertArrayEquals(new String[] {"table1"}, objs);
     assertThrows(
         "Can not access metadata.",
         ForbiddenException.class,
         () -> {
-          gravitinoMetalakeLoadByNormalUser.deleteTag("tag1");
+          Arrays.stream(
+                  
gravitinoMetalakeLoadByNormalUser.getTag("tag1").associatedObjects().objects())
+              .map(MetadataObject::name)
+              .toList()
+              .toArray(new String[0]);
         });
-    gravitinoMetalakeLoadByNormalUser.deleteTag("tag2");
-    GravitinoMetalake gravitinoMetalake = client.loadMetalake(METALAKE);
-    gravitinoMetalake.deleteTag("tag1");
+    objs =
+        Arrays.stream(
+                
gravitinoMetalakeLoadByNormalUser.getTag("tag2").associatedObjects().objects())
+            .map(MetadataObject::name)
+            .toList()
+            .toArray(new String[0]);
+    Arrays.sort(objs);
+    Assertions.assertArrayEquals(new String[] {"table1"}, objs);
+    objs =
+        Arrays.stream(
+                
gravitinoMetalakeLoadByNormalUser.getTag("tag3").associatedObjects().objects())
+            .map(MetadataObject::name)
+            .toList()
+            .toArray(new String[0]);
+    Arrays.sort(objs);
+    Assertions.assertArrayEquals(new String[] {"table1"}, objs);
+
+    objs =
+        
Arrays.stream(gravitinoMetalake.getTag("tag3").associatedObjects().objects())
+            .map(MetadataObject::name)
+            .toList()
+            .toArray(new String[0]);
+    Arrays.sort(objs);
+    Assertions.assertArrayEquals(new String[] {"table1"}, objs);
+    gravitinoMetalake.revokePrivilegesFromRole(
+        role,
+        MetadataObjects.of(ImmutableList.of(CATALOG, SCHEMA), 
MetadataObject.Type.SCHEMA),
+        ImmutableSet.of(Privileges.SelectTable.allow(), 
Privileges.UseSchema.allow()));
+    objs =
+        Arrays.stream(
+                
gravitinoMetalakeLoadByNormalUser.getTag("tag3").associatedObjects().objects())
+            .map(MetadataObject::name)
+            .toList()
+            .toArray(new String[0]);
+    Arrays.sort(objs);
+    Assertions.assertArrayEquals(new String[] {}, objs);
   }
 
   @Test
-  @Order(9)
+  @Order(10)
   public void testTagOperationsWithNonExistentMetalake() throws Exception {
     // Test that all tag operations with @AuthorizationExpression return 403 
Forbidden
     // when the metalake doesn't exist, instead of inconsistent 404 responses
@@ -390,6 +449,21 @@ public class TagOperationsAuthorizationIT extends 
BaseRestApiAuthorizationIT {
                 .associateTags(new String[] {"testTag"}, null));
   }
 
+  @Test
+  @Order(11)
+  public void testDropTag() {
+    GravitinoMetalake gravitinoMetalakeLoadByNormalUser = 
normalUserClient.loadMetalake(METALAKE);
+    assertThrows(
+        "Can not access metadata.",
+        ForbiddenException.class,
+        () -> {
+          gravitinoMetalakeLoadByNormalUser.deleteTag("tag1");
+        });
+    gravitinoMetalakeLoadByNormalUser.deleteTag("tag2");
+    GravitinoMetalake gravitinoMetalake = client.loadMetalake(METALAKE);
+    gravitinoMetalake.deleteTag("tag1");
+  }
+
   private Column[] createColumns() {
     return new Column[] {Column.of("col1", Types.StringType.get())};
   }
diff --git 
a/core/src/main/java/org/apache/gravitino/authorization/AuthorizationRequestContext.java
 
b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationRequestContext.java
index 1e1b635f63..bc8964ccfa 100644
--- 
a/core/src/main/java/org/apache/gravitino/authorization/AuthorizationRequestContext.java
+++ 
b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationRequestContext.java
@@ -36,7 +36,7 @@ public class AuthorizationRequestContext {
   /** Used to determine whether the role has already been loaded. */
   private final AtomicBoolean hasLoadRole = new AtomicBoolean();
 
-  private String originalAuthorizationExpression;
+  private volatile String originalAuthorizationExpression;
 
   /**
    * check allow
diff --git 
a/server-common/src/main/java/org/apache/gravitino/server/authorization/MetadataAuthzHelper.java
 
b/server-common/src/main/java/org/apache/gravitino/server/authorization/MetadataAuthzHelper.java
index 35ebe9b860..ffa32bc294 100644
--- 
a/server-common/src/main/java/org/apache/gravitino/server/authorization/MetadataAuthzHelper.java
+++ 
b/server-common/src/main/java/org/apache/gravitino/server/authorization/MetadataAuthzHelper.java
@@ -20,11 +20,11 @@ package org.apache.gravitino.server.authorization;
 import java.lang.reflect.Array;
 import java.security.Principal;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
@@ -33,12 +33,15 @@ import org.apache.gravitino.Config;
 import org.apache.gravitino.Configs;
 import org.apache.gravitino.Entity;
 import org.apache.gravitino.GravitinoEnv;
+import org.apache.gravitino.MetadataObject;
 import org.apache.gravitino.Metalake;
 import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.authorization.AuthorizationRequestContext;
 import org.apache.gravitino.authorization.GravitinoAuthorizer;
-import org.apache.gravitino.authorization.Privilege;
+import org.apache.gravitino.dto.tag.MetadataObjectDTO;
+import 
org.apache.gravitino.server.authorization.expression.AuthorizationExpressionConstants;
 import 
org.apache.gravitino.server.authorization.expression.AuthorizationExpressionEvaluator;
+import org.apache.gravitino.utils.MetadataObjectUtil;
 import org.apache.gravitino.utils.NameIdentifierUtil;
 import org.apache.gravitino.utils.PrincipalUtils;
 import org.slf4j.Logger;
@@ -56,44 +59,7 @@ public class MetadataAuthzHelper {
 
   private MetadataAuthzHelper() {}
 
-  /**
-   * Call {@link GravitinoAuthorizer} to filter the metadata list
-   *
-   * @param entityType for example, CATALOG, SCHEMA,TABLE, etc.
-   * @param privilege for example, CREATE_CATALOG, CREATE_TABLE, etc.
-   * @param metadataList metadata list.
-   * @return metadata List that the user has permission to access.
-   */
-  public static NameIdentifier[] filterByPrivilege(
-      String metalake,
-      Entity.EntityType entityType,
-      String privilege,
-      NameIdentifier[] metadataList) {
-    if (!enableAuthorization()) {
-      return metadataList;
-    }
-    checkExecutor();
-    GravitinoAuthorizer gravitinoAuthorizer =
-        GravitinoAuthorizerProvider.getInstance().getGravitinoAuthorizer();
-    Principal currentPrincipal = PrincipalUtils.getCurrentPrincipal();
-    AuthorizationRequestContext authorizationRequestContext = new 
AuthorizationRequestContext();
-    return Arrays.stream(metadataList)
-        .filter(
-            metaDataName ->
-                gravitinoAuthorizer.authorize(
-                    currentPrincipal,
-                    metalake,
-                    NameIdentifierUtil.toMetadataObject(metaDataName, 
entityType),
-                    Privilege.Name.valueOf(privilege),
-                    authorizationRequestContext))
-        .toArray(NameIdentifier[]::new);
-  }
-
   public static Metalake[] filterMetalakes(Metalake[] metalakes, String 
expression) {
-    if (!enableAuthorization()) {
-      return metalakes;
-    }
-    checkExecutor();
     AuthorizationRequestContext authorizationRequestContext = new 
AuthorizationRequestContext();
     return doFilter(
         expression,
@@ -108,6 +74,51 @@ public class MetadataAuthzHelper {
               NameIdentifierUtil.ofMetalake(metalakeName));
         });
   }
+
+  /**
+   * Filters MetadataObjectDTO array based on access permissions.
+   *
+   * @param metalake The metalake name
+   * @param metadataObjects The array of metadata object DTOs to filter
+   * @return Filtered array of metadata object DTOs that the current user has 
access to
+   */
+  public static MetadataObjectDTO[] filterMetadataObject(
+      String metalake, MetadataObjectDTO[] metadataObjects) {
+    return doFilter(
+        AuthorizationExpressionConstants.CAN_ACCESS_METADATA,
+        metadataObjects,
+        GravitinoAuthorizerProvider.getInstance().getGravitinoAuthorizer(),
+        new AuthorizationRequestContext(),
+        metadataObject ->
+            splitMetadataNames(
+                metalake,
+                MetadataObjectUtil.toEntityType(metadataObject.type()),
+                MetadataObjectUtil.toEntityIdent(metalake, metadataObject)),
+        metadataObject -> 
MetadataObjectUtil.toEntityType(metadataObject.type()));
+  }
+
+  /**
+   * Filters MetadataObject array based on access permissions.
+   *
+   * @param metalake The metalake name
+   * @param metadataObjects The array of metadata objects to filter
+   * @return Filtered array of metadata objects that the current user has 
access to
+   */
+  public static MetadataObject[] filterMetadataObject(
+      String metalake, MetadataObject[] metadataObjects) {
+    return doFilter(
+        AuthorizationExpressionConstants.CAN_ACCESS_METADATA,
+        metadataObjects,
+        GravitinoAuthorizerProvider.getInstance().getGravitinoAuthorizer(),
+        new AuthorizationRequestContext(),
+        metadataObject ->
+            splitMetadataNames(
+                metalake,
+                MetadataObjectUtil.toEntityType(metadataObject.type()),
+                MetadataObjectUtil.toEntityIdent(metalake, metadataObject)),
+        metadataObject -> 
MetadataObjectUtil.toEntityType(metadataObject.type()));
+  }
+
   /**
    * Call {@link AuthorizationExpressionEvaluator} to filter the metadata list
    *
@@ -191,10 +202,6 @@ public class MetadataAuthzHelper {
       E[] entities,
       Function<E, NameIdentifier> toNameIdentifier,
       GravitinoAuthorizer authorizer) {
-    if (!enableAuthorization()) {
-      return entities;
-    }
-    checkExecutor();
     AuthorizationRequestContext authorizationRequestContext = new 
AuthorizationRequestContext();
     return doFilter(
         expression,
@@ -207,12 +214,43 @@ public class MetadataAuthzHelper {
         });
   }
 
+  /**
+   * Filters entities based on authorization expression evaluation.
+   *
+   * @param expression The authorization expression to evaluate
+   * @param entities The array of entities to filter
+   * @param authorizer The authorizer used to evaluate permissions
+   * @param authorizationRequestContext The context of the authorization 
request
+   * @param extractMetadataNamesMap Function to extract metadata names map 
from entity
+   * @param <E> The type of entity
+   * @return Filtered array of entities that passed authorization check
+   */
   private static <E> E[] doFilter(
       String expression,
       E[] entities,
       GravitinoAuthorizer authorizer,
       AuthorizationRequestContext authorizationRequestContext,
       Function<E, Map<Entity.EntityType, NameIdentifier>> 
extractMetadataNamesMap) {
+    return doFilter(
+        expression,
+        entities,
+        authorizer,
+        authorizationRequestContext,
+        extractMetadataNamesMap,
+        (unused) -> null);
+  }
+
+  private static <E> E[] doFilter(
+      String expression,
+      E[] entities,
+      GravitinoAuthorizer authorizer,
+      AuthorizationRequestContext authorizationRequestContext,
+      Function<E, Map<Entity.EntityType, NameIdentifier>> 
extractMetadataNamesMap,
+      Function<E, Entity.EntityType> extractEntityType) {
+    if (!enableAuthorization()) {
+      return entities;
+    }
+    checkExecutor();
     Principal currentPrincipal = PrincipalUtils.getCurrentPrincipal();
     authorizationRequestContext.setOriginalAuthorizationExpression(expression);
     List<CompletableFuture<E>> futures = new ArrayList<>();
@@ -227,7 +265,11 @@ public class MetadataAuthzHelper {
                         AuthorizationExpressionEvaluator 
authorizationExpressionEvaluator =
                             new AuthorizationExpressionEvaluator(expression, 
authorizer);
                         return authorizationExpressionEvaluator.evaluate(
-                                extractMetadataNamesMap.apply(entity), 
authorizationRequestContext)
+                                extractMetadataNamesMap.apply(entity),
+                                authorizationRequestContext,
+                                currentPrincipal,
+                                
Optional.ofNullable(extractEntityType.apply(entity))
+                                    .map(Entity.EntityType::name))
                             ? entity
                             : null;
                       });
diff --git 
a/server-common/src/test/java/org/apache/gravitino/server/authorization/TestMetadataAuthzHelper.java
 
b/server-common/src/test/java/org/apache/gravitino/server/authorization/TestMetadataAuthzHelper.java
index 26581b4a0b..81e7d858ca 100644
--- 
a/server-common/src/test/java/org/apache/gravitino/server/authorization/TestMetadataAuthzHelper.java
+++ 
b/server-common/src/test/java/org/apache/gravitino/server/authorization/TestMetadataAuthzHelper.java
@@ -29,9 +29,10 @@ import org.apache.gravitino.Config;
 import org.apache.gravitino.Configs;
 import org.apache.gravitino.Entity;
 import org.apache.gravitino.GravitinoEnv;
+import org.apache.gravitino.MetadataObject;
 import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.UserPrincipal;
-import org.apache.gravitino.authorization.Privilege;
+import org.apache.gravitino.dto.tag.MetadataObjectDTO;
 import org.apache.gravitino.utils.NameIdentifierUtil;
 import org.apache.gravitino.utils.PrincipalUtils;
 import org.junit.jupiter.api.AfterAll;
@@ -63,7 +64,7 @@ public class TestMetadataAuthzHelper {
   }
 
   @Test
-  public void testFilter() {
+  public void testFilterByExpression() {
     makeCompletableFutureUseCurrentThread();
     try (MockedStatic<PrincipalUtils> principalUtilsMocked = 
mockStatic(PrincipalUtils.class);
         MockedStatic<GravitinoAuthorizerProvider> mockStatic =
@@ -83,19 +84,24 @@ public class TestMetadataAuthzHelper {
       nameIdentifiers[2] =
           NameIdentifierUtil.ofSchema("testMetalake", "testCatalog2", 
"testSchema");
       NameIdentifier[] filtered =
-          MetadataAuthzHelper.filterByPrivilege(
+          MetadataAuthzHelper.filterByExpression(
               "testMetalake",
+              "CATALOG::USE_CATALOG && SCHEMA::USE_SCHEMA",
               Entity.EntityType.SCHEMA,
-              Privilege.Name.USE_SCHEMA.name(),
               nameIdentifiers);
-      Assertions.assertEquals(2, filtered.length);
+      Assertions.assertEquals(1, filtered.length);
       Assertions.assertEquals("testMetalake.testCatalog.testSchema", 
filtered[0].toString());
-      Assertions.assertEquals("testMetalake.testCatalog2.testSchema", 
filtered[1].toString());
+      NameIdentifier[] filtered2 =
+          MetadataAuthzHelper.filterByExpression(
+              "testMetalake", "CATALOG::USE_CATALOG", 
Entity.EntityType.SCHEMA, nameIdentifiers);
+      Assertions.assertEquals(2, filtered2.length);
+      Assertions.assertEquals("testMetalake.testCatalog.testSchema", 
filtered2[0].toString());
+      Assertions.assertEquals("testMetalake.testCatalog.testSchema2", 
filtered2[1].toString());
     }
   }
 
   @Test
-  public void testFilterByExpression() {
+  public void testFilterMetadataObject() {
     makeCompletableFutureUseCurrentThread();
     try (MockedStatic<PrincipalUtils> principalUtilsMocked = 
mockStatic(PrincipalUtils.class);
         MockedStatic<GravitinoAuthorizerProvider> mockStatic =
@@ -108,26 +114,79 @@ public class TestMetadataAuthzHelper {
       GravitinoAuthorizerProvider mockedProvider = 
mock(GravitinoAuthorizerProvider.class);
       
mockStatic.when(GravitinoAuthorizerProvider::getInstance).thenReturn(mockedProvider);
       when(mockedProvider.getGravitinoAuthorizer()).thenReturn(new 
MockGravitinoAuthorizer());
-      NameIdentifier[] nameIdentifiers = new NameIdentifier[3];
-      nameIdentifiers[0] = NameIdentifierUtil.ofSchema("testMetalake", 
"testCatalog", "testSchema");
-      nameIdentifiers[1] =
-          NameIdentifierUtil.ofSchema("testMetalake", "testCatalog", 
"testSchema2");
-      nameIdentifiers[2] =
-          NameIdentifierUtil.ofSchema("testMetalake", "testCatalog2", 
"testSchema");
-      NameIdentifier[] filtered =
-          MetadataAuthzHelper.filterByExpression(
-              "testMetalake",
-              "CATALOG::USE_CATALOG && SCHEMA::USE_SCHEMA",
-              Entity.EntityType.SCHEMA,
-              nameIdentifiers);
+
+      // Create test MetadataObjectDTO instances
+      MetadataObjectDTO[] metadataObjects = new MetadataObjectDTO[3];
+      metadataObjects[0] =
+          MetadataObjectDTO.builder()
+              .withName("testSchema")
+              .withParent("testCatalog")
+              .withType(MetadataObject.Type.SCHEMA)
+              .build();
+      metadataObjects[1] =
+          MetadataObjectDTO.builder()
+              .withName("testSchema2")
+              .withParent("testCatalog")
+              .withType(MetadataObject.Type.SCHEMA)
+              .build();
+      metadataObjects[2] =
+          MetadataObjectDTO.builder()
+              .withName("testSchema3")
+              .withParent("testCatalog2")
+              .withType(MetadataObject.Type.SCHEMA)
+              .build();
+
+      MetadataObjectDTO[] filtered =
+          MetadataAuthzHelper.filterMetadataObject("testMetalake", 
metadataObjects);
+
+      // Based on the MockGravitinoAuthorizer, 2 of the 3 schemas should be 
accessible
       Assertions.assertEquals(1, filtered.length);
-      Assertions.assertEquals("testMetalake.testCatalog.testSchema", 
filtered[0].toString());
-      NameIdentifier[] filtered2 =
-          MetadataAuthzHelper.filterByExpression(
-              "testMetalake", "CATALOG::USE_CATALOG", 
Entity.EntityType.SCHEMA, nameIdentifiers);
-      Assertions.assertEquals(2, filtered2.length);
-      Assertions.assertEquals("testMetalake.testCatalog.testSchema", 
filtered2[0].toString());
-      Assertions.assertEquals("testMetalake.testCatalog.testSchema2", 
filtered2[1].toString());
+      Assertions.assertEquals("testSchema", filtered[0].name());
+    }
+  }
+
+  @Test
+  public void testFilterMetadataObjectDTO() {
+    makeCompletableFutureUseCurrentThread();
+    try (MockedStatic<PrincipalUtils> principalUtilsMocked = 
mockStatic(PrincipalUtils.class);
+        MockedStatic<GravitinoAuthorizerProvider> mockStatic =
+            mockStatic(GravitinoAuthorizerProvider.class)) {
+      principalUtilsMocked
+          .when(PrincipalUtils::getCurrentPrincipal)
+          .thenReturn(new UserPrincipal("tester"));
+      principalUtilsMocked.when(() -> PrincipalUtils.doAs(any(), 
any())).thenCallRealMethod();
+
+      GravitinoAuthorizerProvider mockedProvider = 
mock(GravitinoAuthorizerProvider.class);
+      
mockStatic.when(GravitinoAuthorizerProvider::getInstance).thenReturn(mockedProvider);
+      when(mockedProvider.getGravitinoAuthorizer()).thenReturn(new 
MockGravitinoAuthorizer());
+
+      // Create test MetadataObjectDTO instances
+      MetadataObjectDTO[] metadataObjects = new MetadataObjectDTO[3];
+      metadataObjects[0] =
+          MetadataObjectDTO.builder()
+              .withName("testSchema")
+              .withParent("testCatalog")
+              .withType(MetadataObject.Type.SCHEMA)
+              .build();
+      metadataObjects[1] =
+          MetadataObjectDTO.builder()
+              .withName("testSchema2")
+              .withParent("testCatalog")
+              .withType(MetadataObject.Type.SCHEMA)
+              .build();
+      metadataObjects[2] =
+          MetadataObjectDTO.builder()
+              .withName("testSchema3")
+              .withParent("testCatalog")
+              .withType(MetadataObject.Type.SCHEMA)
+              .build();
+
+      MetadataObjectDTO[] filtered =
+          MetadataAuthzHelper.filterMetadataObject("testMetalake", 
metadataObjects);
+
+      // Based on the MockGravitinoAuthorizer, 2 of the 3 tables should be 
accessible
+      Assertions.assertEquals(1, filtered.length);
+      Assertions.assertEquals("testSchema", filtered[0].name());
     }
   }
 
diff --git 
a/server/src/main/java/org/apache/gravitino/server/web/filter/authorization/CommonAuthorizerExecutor.java
 
b/server/src/main/java/org/apache/gravitino/server/web/filter/authorization/CommonAuthorizerExecutor.java
index 9c15a1c52d..5b78ae28ad 100644
--- 
a/server/src/main/java/org/apache/gravitino/server/web/filter/authorization/CommonAuthorizerExecutor.java
+++ 
b/server/src/main/java/org/apache/gravitino/server/web/filter/authorization/CommonAuthorizerExecutor.java
@@ -47,6 +47,8 @@ public class CommonAuthorizerExecutor implements 
AuthorizationExecutor {
 
   @Override
   public boolean execute() throws Exception {
+    AuthorizationRequestContext authorizationRequestContext = new 
AuthorizationRequestContext();
+    authorizationRequestContext.setOriginalAuthorizationExpression(expression);
     return authorizationExpressionEvaluator.evaluate(
         metadataContext,
         pathParams,
diff --git 
a/server/src/main/java/org/apache/gravitino/server/web/rest/PolicyOperations.java
 
b/server/src/main/java/org/apache/gravitino/server/web/rest/PolicyOperations.java
index a263e6b471..946ede3e16 100644
--- 
a/server/src/main/java/org/apache/gravitino/server/web/rest/PolicyOperations.java
+++ 
b/server/src/main/java/org/apache/gravitino/server/web/rest/PolicyOperations.java
@@ -314,9 +314,8 @@ public class PolicyOperations {
           () -> {
             MetadataObject[] objects =
                 policyDispatcher.listMetadataObjectsForPolicy(metalake, 
policyName);
-            // TODO filter by can-access-metadata, MetadataFilterHelper can 
not support now
             objects = objects == null ? new MetadataObject[0] : objects;
-
+            objects = MetadataAuthzHelper.filterMetadataObject(metalake, 
objects);
             LOG.info(
                 "List {} objects for policy: {} under metalake: {}",
                 objects.length,
@@ -325,6 +324,7 @@ public class PolicyOperations {
 
             MetadataObjectDTO[] objectDTOs =
                 
Arrays.stream(objects).map(DTOConverters::toDTO).toArray(MetadataObjectDTO[]::new);
+
             return Utils.ok(new MetadataObjectListResponse(objectDTOs));
           });
 
diff --git 
a/server/src/main/java/org/apache/gravitino/server/web/rest/TagOperations.java 
b/server/src/main/java/org/apache/gravitino/server/web/rest/TagOperations.java
index 95a2973ddf..71c4e869dd 100644
--- 
a/server/src/main/java/org/apache/gravitino/server/web/rest/TagOperations.java
+++ 
b/server/src/main/java/org/apache/gravitino/server/web/rest/TagOperations.java
@@ -263,7 +263,8 @@ public class TagOperations {
   @Produces("application/vnd.gravitino.v1+json")
   @Timed(name = "list-objects-for-tag." + MetricNames.HTTP_PROCESS_DURATION, 
absolute = true)
   @ResponseMetered(name = "list-objects-for-tag", absolute = true)
-  @AuthorizationExpression(expression = "")
+  @AuthorizationExpression(
+      expression = 
AuthorizationExpressionConstants.loadTagAuthorizationExpression)
   public Response listMetadataObjectsForTag(
       @PathParam("metalake") @AuthorizationMetadata(type = 
Entity.EntityType.METALAKE)
           String metalake,
@@ -285,7 +286,7 @@ public class TagOperations {
 
             MetadataObjectDTO[] objectDTOs =
                 
Arrays.stream(objects).map(DTOConverters::toDTO).toArray(MetadataObjectDTO[]::new);
-            // TODO filter by can-access-metadata, MetadataFilterHelper can 
not support now
+            objectDTOs = MetadataAuthzHelper.filterMetadataObject(metalake, 
objectDTOs);
             return Utils.ok(new MetadataObjectListResponse(objectDTOs));
           });
 

Reply via email to