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