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