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

jshao 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 3bd3bfb736 [MINOR] polish(authz): polish authz codes for easier reuse 
(#8840)
3bd3bfb736 is described below

commit 3bd3bfb7369a17b6cff205435ccffeff66fd9b85
Author: mchades <[email protected]>
AuthorDate: Mon Oct 20 10:41:51 2025 +0800

    [MINOR] polish(authz): polish authz codes for easier reuse (#8840)
    
    ### What changes were proposed in this pull request?
    
    can specify a principal and authorizer to do authz
    
    ### Why are the changes needed?
    
    polish authz codes for easier reuse
    
    ### Does this PR introduce _any_ user-facing change?
    
    no
    
    ### How was this patch tested?
    
    tests updated
---
 .../server/authorization/MetadataFilterHelper.java | 32 ++++++++++++-
 .../AuthorizationExpressionEvaluator.java          | 53 ++++++++++++++++++++--
 .../TestAuthorizationExpressionEvaluator.java      | 17 ++++---
 3 files changed, 89 insertions(+), 13 deletions(-)

diff --git 
a/server-common/src/main/java/org/apache/gravitino/server/authorization/MetadataFilterHelper.java
 
b/server-common/src/main/java/org/apache/gravitino/server/authorization/MetadataFilterHelper.java
index e435bac4a1..874424feb2 100644
--- 
a/server-common/src/main/java/org/apache/gravitino/server/authorization/MetadataFilterHelper.java
+++ 
b/server-common/src/main/java/org/apache/gravitino/server/authorization/MetadataFilterHelper.java
@@ -156,6 +156,35 @@ public class MetadataFilterHelper {
       Entity.EntityType entityType,
       E[] entities,
       Function<E, NameIdentifier> toNameIdentifier) {
+    GravitinoAuthorizer authorizer =
+        GravitinoAuthorizerProvider.getInstance().getGravitinoAuthorizer();
+    Principal currentPrincipal = PrincipalUtils.getCurrentPrincipal();
+    return filterByExpression(
+        metalake, expression, entityType, entities, toNameIdentifier, 
currentPrincipal, authorizer);
+  }
+
+  /**
+   * Call {@link AuthorizationExpressionEvaluator} and use specified Principal 
and
+   * GravitinoAuthorizer to filter the metadata list
+   *
+   * @param metalake metalake name
+   * @param expression authorization expression
+   * @param entityType entity type
+   * @param entities metadata entities
+   * @param toNameIdentifier function to convert entity to NameIdentifier
+   * @param currentPrincipal current principal
+   * @param authorizer authorizer to filter metadata
+   * @return Filtered Metadata Entity
+   * @param <E> Entity class
+   */
+  public static <E> E[] filterByExpression(
+      String metalake,
+      String expression,
+      Entity.EntityType entityType,
+      E[] entities,
+      Function<E, NameIdentifier> toNameIdentifier,
+      Principal currentPrincipal,
+      GravitinoAuthorizer authorizer) {
     if (!enableAuthorization()) {
       return entities;
     }
@@ -163,7 +192,6 @@ public class MetadataFilterHelper {
     AuthorizationRequestContext authorizationRequestContext = new 
AuthorizationRequestContext();
     List<CompletableFuture<E>> futures = new ArrayList<>();
     for (E entity : entities) {
-      Principal currentPrincipal = PrincipalUtils.getCurrentPrincipal();
       futures.add(
           CompletableFuture.supplyAsync(
               () -> {
@@ -172,7 +200,7 @@ public class MetadataFilterHelper {
                       currentPrincipal,
                       () -> {
                         AuthorizationExpressionEvaluator 
authorizationExpressionEvaluator =
-                            new AuthorizationExpressionEvaluator(expression);
+                            new AuthorizationExpressionEvaluator(expression, 
authorizer);
                         NameIdentifier nameIdentifier = 
toNameIdentifier.apply(entity);
                         Map<Entity.EntityType, NameIdentifier> 
nameIdentifierMap =
                             spiltMetadataNames(metalake, entityType, 
nameIdentifier);
diff --git 
a/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionEvaluator.java
 
b/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionEvaluator.java
index 78ddf58d44..02c455e887 100644
--- 
a/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionEvaluator.java
+++ 
b/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionEvaluator.java
@@ -39,6 +39,7 @@ import org.apache.gravitino.utils.PrincipalUtils;
 public class AuthorizationExpressionEvaluator {
 
   private final String ognlAuthorizationExpression;
+  private final GravitinoAuthorizer authorizer;
 
   /**
    * Use {@link AuthorizationExpressionConverter} to convert the authorization 
expression into an
@@ -47,8 +48,19 @@ public class AuthorizationExpressionEvaluator {
    * @param expression authorization expression
    */
   public AuthorizationExpressionEvaluator(String expression) {
+    this(expression, 
GravitinoAuthorizerProvider.getInstance().getGravitinoAuthorizer());
+  }
+
+  /**
+   * Constructor of AuthorizationExpressionEvaluator
+   *
+   * @param expression authorization expression
+   * @param authorizer GravitinoAuthorizer instance
+   */
+  public AuthorizationExpressionEvaluator(String expression, 
GravitinoAuthorizer authorizer) {
     this.ognlAuthorizationExpression =
         AuthorizationExpressionConverter.convertToOgnlExpression(expression);
+    this.authorizer = authorizer;
   }
 
   /**
@@ -61,7 +73,24 @@ public class AuthorizationExpressionEvaluator {
   public boolean evaluate(
       Map<Entity.EntityType, NameIdentifier> metadataNames,
       AuthorizationRequestContext requestContext) {
-    return evaluate(metadataNames, new HashMap<>(), requestContext);
+    Principal currentPrincipal = PrincipalUtils.getCurrentPrincipal();
+    return evaluate(metadataNames, new HashMap<>(), requestContext, 
currentPrincipal);
+  }
+
+  /**
+   * Use OGNL expressions to invoke GravitinoAuthorizer for authorizing 
multiple types of metadata
+   * IDs.
+   *
+   * @param metadataNames key-metadata type, value-metadata NameIdentifier
+   * @param requestContext authorization request context
+   * @param principal current principal
+   * @return authorization result
+   */
+  public boolean evaluate(
+      Map<Entity.EntityType, NameIdentifier> metadataNames,
+      AuthorizationRequestContext requestContext,
+      Principal principal) {
+    return evaluate(metadataNames, new HashMap<>(), requestContext, principal);
   }
 
   /**
@@ -77,11 +106,27 @@ public class AuthorizationExpressionEvaluator {
       Map<String, Object> pathParams,
       AuthorizationRequestContext requestContext) {
     Principal currentPrincipal = PrincipalUtils.getCurrentPrincipal();
-    GravitinoAuthorizer gravitinoAuthorizer =
-        GravitinoAuthorizerProvider.getInstance().getGravitinoAuthorizer();
+    return evaluate(metadataNames, pathParams, requestContext, 
currentPrincipal);
+  }
+
+  /**
+   * Use OGNL expressions to invoke GravitinoAuthorizer for authorizing 
multiple types of metadata
+   * IDs.
+   *
+   * @param metadataNames key-metadata type, value-metadata NameIdentifier
+   * @param pathParams params from request path
+   * @param requestContext authorization request context
+   * @param currentPrincipal current principal
+   * @return authorization result
+   */
+  private boolean evaluate(
+      Map<Entity.EntityType, NameIdentifier> metadataNames,
+      Map<String, Object> pathParams,
+      AuthorizationRequestContext requestContext,
+      Principal currentPrincipal) {
     OgnlContext ognlContext = Ognl.createDefaultContext(null);
     ognlContext.put("principal", currentPrincipal);
-    ognlContext.put("authorizer", gravitinoAuthorizer);
+    ognlContext.put("authorizer", authorizer);
     ognlContext.put("authorizationContext", requestContext);
     ognlContext.putAll(pathParams);
     metadataNames.forEach(
diff --git 
a/server-common/src/test/java/org/apache/gravitino/server/authorization/expression/TestAuthorizationExpressionEvaluator.java
 
b/server-common/src/test/java/org/apache/gravitino/server/authorization/expression/TestAuthorizationExpressionEvaluator.java
index 59def1e536..ed3f291dc8 100644
--- 
a/server-common/src/test/java/org/apache/gravitino/server/authorization/expression/TestAuthorizationExpressionEvaluator.java
+++ 
b/server-common/src/test/java/org/apache/gravitino/server/authorization/expression/TestAuthorizationExpressionEvaluator.java
@@ -42,8 +42,6 @@ public class TestAuthorizationExpressionEvaluator {
   public void testEvaluator() {
     String expression =
         "CATALOG::USE_CATALOG && SCHEMA::USE_SCHEMA && (TABLE::SELECT_TABLE || 
TABLE::MODIFY_TABLE)";
-    AuthorizationExpressionEvaluator authorizationExpressionEvaluator =
-        new AuthorizationExpressionEvaluator(expression);
     try (MockedStatic<PrincipalUtils> principalUtilsMocked = 
mockStatic(PrincipalUtils.class);
         MockedStatic<GravitinoAuthorizerProvider> mockStatic =
             mockStatic(GravitinoAuthorizerProvider.class)) {
@@ -53,6 +51,9 @@ public class TestAuthorizationExpressionEvaluator {
       GravitinoAuthorizerProvider mockedProvider = 
mock(GravitinoAuthorizerProvider.class);
       
mockStatic.when(GravitinoAuthorizerProvider::getInstance).thenReturn(mockedProvider);
       when(mockedProvider.getGravitinoAuthorizer()).thenReturn(new 
MockGravitinoAuthorizer());
+      AuthorizationExpressionEvaluator authorizationExpressionEvaluator =
+          new AuthorizationExpressionEvaluator(expression);
+
       Map<Entity.EntityType, NameIdentifier> metadataNames = new HashMap<>();
       metadataNames.put(Entity.EntityType.METALAKE, 
NameIdentifierUtil.ofMetalake("testMetalake"));
       metadataNames.put(
@@ -79,17 +80,19 @@ public class TestAuthorizationExpressionEvaluator {
   @Test
   public void testEvaluatorWithOwner() {
     String expression = "METALAKE::OWNER || CATALOG::CREATE_CATALOG";
-    AuthorizationExpressionEvaluator authorizationExpressionEvaluator =
-        new AuthorizationExpressionEvaluator(expression);
     try (MockedStatic<PrincipalUtils> principalUtilsMocked = 
mockStatic(PrincipalUtils.class);
         MockedStatic<GravitinoAuthorizerProvider> mockStatic =
             mockStatic(GravitinoAuthorizerProvider.class)) {
-      principalUtilsMocked
-          .when(PrincipalUtils::getCurrentPrincipal)
-          .thenReturn(new UserPrincipal("tester"));
       GravitinoAuthorizerProvider mockedProvider = 
mock(GravitinoAuthorizerProvider.class);
       
mockStatic.when(GravitinoAuthorizerProvider::getInstance).thenReturn(mockedProvider);
       when(mockedProvider.getGravitinoAuthorizer()).thenReturn(new 
MockGravitinoAuthorizer());
+
+      AuthorizationExpressionEvaluator authorizationExpressionEvaluator =
+          new AuthorizationExpressionEvaluator(expression);
+      principalUtilsMocked
+          .when(PrincipalUtils::getCurrentPrincipal)
+          .thenReturn(new UserPrincipal("tester"));
+
       Map<Entity.EntityType, NameIdentifier> metadataNames = new HashMap<>();
       metadataNames.put(
           Entity.EntityType.METALAKE, 
NameIdentifierUtil.ofMetalake("metalakeWithOutOwner"));

Reply via email to