Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,42 @@ public static <E> E[] filterByExpression(
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;
}
checkExecutor();
AuthorizationRequestContext authorizationRequestContext = new AuthorizationRequestContext();
List<CompletableFuture<E>> futures = new ArrayList<>();
for (E entity : entities) {
Principal currentPrincipal = PrincipalUtils.getCurrentPrincipal();
futures.add(
CompletableFuture.supplyAsync(
() -> {
Expand All @@ -172,7 +200,7 @@ public static <E> E[] filterByExpression(
currentPrincipal,
() -> {
AuthorizationExpressionEvaluator authorizationExpressionEvaluator =
new AuthorizationExpressionEvaluator(expression);
new AuthorizationExpressionEvaluator(expression, authorizer);
NameIdentifier nameIdentifier = toNameIdentifier.apply(entity);
Map<Entity.EntityType, NameIdentifier> nameIdentifierMap =
spiltMetadataNames(metalake, entityType, nameIdentifier);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
public class AuthorizationExpressionEvaluator {

private final String ognlAuthorizationExpression;
private final GravitinoAuthorizer authorizer;

/**
* Use {@link AuthorizationExpressionConverter} to convert the authorization expression into an
Expand All @@ -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;
}

/**
Expand All @@ -61,7 +73,24 @@ public AuthorizationExpressionEvaluator(String expression) {
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);
}

/**
Expand All @@ -77,11 +106,27 @@ public boolean evaluate(
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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand All @@ -53,6 +51,9 @@ public void testEvaluator() {
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(
Expand All @@ -79,17 +80,19 @@ public void testEvaluator() {
@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"));
Expand Down