This is an automated email from the ASF dual-hosted git repository.
diqiu50 pushed a commit to branch branch-1.3
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/branch-1.3 by this push:
new c03d7ceb23 [Cherry-pick to branch-1.3] [#12480] improvement(server):
Allow table existence probe on loadTable (#12482) (#13806)
c03d7ceb23 is described below
commit c03d7ceb232c0471de2e5eb04157a17616f02714
Author: Yuhui <[email protected]>
AuthorDate: Tue Oct 13 14:43:25 2026 +0800
[Cherry-pick to branch-1.3] [#12480] improvement(server): Allow table
existence probe on loadTable (#12482) (#13806)
**Cherry-pick Information:**
- Original commit: 8a7348963b3b031791220c121cbe440c58cabf5d
- Target branch: `branch-1.3`
- Status: ⚠️ Partial cherry-pick (conflicts resolved)
Only the load-table existence probe is included, so a user with
`CREATE_TABLE` can create tables
through an engine. The `PROBE_TABLE_LIKE` privilege, the list-table
filter change and the Flink
connector changes are left out to avoid an API change in a patch
release.
---
.../AuthorizationExpressionConstants.java | 6 +
.../web/filter/GravitinoInterceptionService.java | 3 +-
.../authorization/AuthorizeExecutorFactory.java | 6 +-
.../LoadTableAuthorizationExecutor.java | 28 +++-
.../gravitino/server/web/rest/TableOperations.java | 2 +
.../filter/TestGravitinoInterceptionService.java | 167 +++++++++++++++++++++
...CatalogConnectionTestAuthorizationExecutor.java | 3 +-
.../TestLineageAuthorizationExecutor.java | 3 +-
.../TestLoadTableAuthorizationExecutor.java | 3 +-
.../TestTableAuthorizationExpression.java | 24 +++
10 files changed, 238 insertions(+), 7 deletions(-)
diff --git
a/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionConstants.java
b/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionConstants.java
index deadf7c96a..10f360d643 100644
---
a/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionConstants.java
+++
b/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionConstants.java
@@ -49,6 +49,12 @@ public class AuthorizationExpressionConstants {
ANY_USE_CATALOG && ANY_USE_SCHEMA && (TABLE::OWNER ||
ANY_SELECT_TABLE || ANY_MODIFY_TABLE)
""";
+ public static final String PROBE_TABLE_LIKE_AUTHORIZATION_EXPRESSION =
+ """
+ ANY_USE_CATALOG && ANY_USE_SCHEMA &&
+ (ANY_SELECT_TABLE || ANY_MODIFY_TABLE || ANY_CREATE_TABLE ||
ANY_CREATE_VIEW)
+ """;
+
// Adding ANY_CREATE_TABLE here as Spark calls tableExists before creating
a table.
public static final String ICEBERG_LOAD_TABLE_AUTHORIZATION_EXPRESSION =
"""
diff --git
a/server/src/main/java/org/apache/gravitino/server/web/filter/GravitinoInterceptionService.java
b/server/src/main/java/org/apache/gravitino/server/web/filter/GravitinoInterceptionService.java
index 215073d6e3..a21fd32e01 100644
---
a/server/src/main/java/org/apache/gravitino/server/web/filter/GravitinoInterceptionService.java
+++
b/server/src/main/java/org/apache/gravitino/server/web/filter/GravitinoInterceptionService.java
@@ -195,7 +195,8 @@ public class GravitinoInterceptionService implements
InterceptionService {
parameters,
args,
secondaryExpression,
- secondaryExpressionCondition);
+ secondaryExpressionCondition,
+ expressionAnnotation.allowCheckExistence());
Optional<String> dynamicMetalake;
try {
dynamicMetalake = executor.getAuthorizationMetalake();
diff --git
a/server/src/main/java/org/apache/gravitino/server/web/filter/authorization/AuthorizeExecutorFactory.java
b/server/src/main/java/org/apache/gravitino/server/web/filter/authorization/AuthorizeExecutorFactory.java
index 229655256c..12a526cb2b 100644
---
a/server/src/main/java/org/apache/gravitino/server/web/filter/authorization/AuthorizeExecutorFactory.java
+++
b/server/src/main/java/org/apache/gravitino/server/web/filter/authorization/AuthorizeExecutorFactory.java
@@ -36,7 +36,8 @@ public class AuthorizeExecutorFactory {
Parameter[] parameters,
Object[] args,
String secondaryExpression,
- ExpressionCondition secondaryExpressionCondition) {
+ ExpressionCondition secondaryExpressionCondition,
+ String allowCheckExistenceExpression) {
return switch (requestType) {
case COMMON -> new CommonAuthorizerExecutor(
expression, metadataContext, pathParams, entityType);
@@ -55,7 +56,8 @@ public class AuthorizeExecutorFactory {
pathParams,
entityType,
secondaryExpression,
- secondaryExpressionCondition);
+ secondaryExpressionCondition,
+ allowCheckExistenceExpression);
case CREATE_SCHEMA -> new CreateSchemaAuthorizationExecutor(
parameters, args, expression, metadataContext, pathParams,
entityType);
case TEST_CATALOG_CONNECTION -> new
CatalogConnectionTestAuthorizationExecutor(
diff --git
a/server/src/main/java/org/apache/gravitino/server/web/filter/authorization/LoadTableAuthorizationExecutor.java
b/server/src/main/java/org/apache/gravitino/server/web/filter/authorization/LoadTableAuthorizationExecutor.java
index 5b87979518..a0a99b94e4 100644
---
a/server/src/main/java/org/apache/gravitino/server/web/filter/authorization/LoadTableAuthorizationExecutor.java
+++
b/server/src/main/java/org/apache/gravitino/server/web/filter/authorization/LoadTableAuthorizationExecutor.java
@@ -22,7 +22,9 @@ import java.util.Map;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.apache.gravitino.Entity;
+import org.apache.gravitino.GravitinoEnv;
import org.apache.gravitino.NameIdentifier;
+import org.apache.gravitino.authorization.AuthorizationRequestContext;
import org.apache.gravitino.authorization.Privilege;
import
org.apache.gravitino.server.authorization.annotations.ExpressionCondition;
import
org.apache.gravitino.server.authorization.expression.AuthorizationExpressionEvaluator;
@@ -42,6 +44,8 @@ import org.apache.gravitino.server.web.filter.ParameterUtil;
* Legacy clients without the `privileges` parameter will use default
authorization.
*/
public class LoadTableAuthorizationExecutor extends CommonAuthorizerExecutor {
+ private final AuthorizationExpressionEvaluator allowCheckExistenceEvaluator;
+
public LoadTableAuthorizationExecutor(
Parameter[] parameters,
Object[] args,
@@ -50,8 +54,13 @@ public class LoadTableAuthorizationExecutor extends
CommonAuthorizerExecutor {
Map<String, Object> pathParams,
Optional<String> entityType,
String secondaryExpression,
- ExpressionCondition secondaryExpressionCondition) {
+ ExpressionCondition secondaryExpressionCondition,
+ String allowCheckExistenceExpression) {
super(expression, metadataContext, pathParams, entityType);
+ this.allowCheckExistenceEvaluator =
+ StringUtils.isBlank(allowCheckExistenceExpression)
+ ? null
+ : new
AuthorizationExpressionEvaluator(allowCheckExistenceExpression);
if (!shouldCheckModifyTablePrivilege(secondaryExpression,
secondaryExpressionCondition)) {
return;
@@ -65,6 +74,23 @@ public class LoadTableAuthorizationExecutor extends
CommonAuthorizerExecutor {
}
}
+ @Override
+ public boolean execute(AuthorizationRequestContext
authorizationRequestContext) throws Exception {
+ if (super.execute(authorizationRequestContext)) {
+ return true;
+ }
+
+ if (allowCheckExistenceEvaluator == null
+ || !allowCheckExistenceEvaluator.evaluate(
+ metadataContext, pathParams, authorizationRequestContext,
entityType)) {
+ return false;
+ }
+
+ NameIdentifier tableIdentifier =
metadataContext.get(Entity.EntityType.TABLE);
+ return tableIdentifier != null
+ &&
!GravitinoEnv.getInstance().tableDispatcher().tableExists(tableIdentifier);
+ }
+
private static boolean shouldCheckModifyTablePrivilege(
String secondaryExpression, ExpressionCondition
secondaryExpressionCondition) {
return StringUtils.isNotBlank(secondaryExpression)
diff --git
a/server/src/main/java/org/apache/gravitino/server/web/rest/TableOperations.java
b/server/src/main/java/org/apache/gravitino/server/web/rest/TableOperations.java
index b8acafb7be..5e7d062cc6 100644
---
a/server/src/main/java/org/apache/gravitino/server/web/rest/TableOperations.java
+++
b/server/src/main/java/org/apache/gravitino/server/web/rest/TableOperations.java
@@ -176,6 +176,8 @@ public class TableOperations {
@ResponseMetered(name = "load-table", absolute = true)
@AuthorizationExpression(
expression =
AuthorizationExpressionConstants.LOAD_TABLE_AUTHORIZATION_EXPRESSION,
+ allowCheckExistence =
+
AuthorizationExpressionConstants.PROBE_TABLE_LIKE_AUTHORIZATION_EXPRESSION,
secondaryExpression =
AuthorizationExpressionConstants.MODIFY_TABLE_AUTHORIZATION_EXPRESSION,
secondaryExpressionCondition =
ExpressionCondition.REQUIRED_MODIFY_PRIVILEGES,
accessMetadataType = MetadataObject.Type.TABLE)
diff --git
a/server/src/test/java/org/apache/gravitino/server/web/filter/TestGravitinoInterceptionService.java
b/server/src/test/java/org/apache/gravitino/server/web/filter/TestGravitinoInterceptionService.java
index 92d4617bfd..d29ade70ca 100644
---
a/server/src/test/java/org/apache/gravitino/server/web/filter/TestGravitinoInterceptionService.java
+++
b/server/src/test/java/org/apache/gravitino/server/web/filter/TestGravitinoInterceptionService.java
@@ -18,6 +18,8 @@
package org.apache.gravitino.server.web.filter;
import static
org.apache.gravitino.server.authorization.expression.AuthorizationExpressionConstants.CAN_ACCESS_METADATA_AND_TAG;
+import static
org.apache.gravitino.server.authorization.expression.AuthorizationExpressionConstants.LOAD_TABLE_AUTHORIZATION_EXPRESSION;
+import static
org.apache.gravitino.server.authorization.expression.AuthorizationExpressionConstants.PROBE_TABLE_LIKE_AUTHORIZATION_EXPRESSION;
import static
org.apache.gravitino.server.authorization.expression.AuthorizationExpressionConstants.TEST_CATALOG_CONNECTION_WITH_CHANGES_AUTHORIZATION_EXPRESSION;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
@@ -49,6 +51,7 @@ import
org.apache.gravitino.authorization.AuthorizationRequestContext;
import org.apache.gravitino.authorization.AuthorizationUtils;
import org.apache.gravitino.authorization.GravitinoAuthorizer;
import org.apache.gravitino.authorization.Privilege;
+import org.apache.gravitino.catalog.TableDispatcher;
import org.apache.gravitino.catalog.ViewDispatcher;
import org.apache.gravitino.dto.requests.CatalogUpdateRequest;
import org.apache.gravitino.dto.requests.CatalogUpdatesRequest;
@@ -629,6 +632,99 @@ public class TestGravitinoInterceptionService {
}
}
+ @Test
+ public void
testLoadTableAuthorizationProceedsWhenProbeAllowedTableDoesNotExist()
+ throws Throwable {
+ try (MockedStatic<PrincipalUtils> principalUtilsMocked =
mockStatic(PrincipalUtils.class);
+ MockedStatic<GravitinoAuthorizerProvider> authorizerMocked =
+ mockStatic(GravitinoAuthorizerProvider.class);
+ MockedStatic<AuthorizationUtils> authUtilsMocked =
mockStatic(AuthorizationUtils.class);
+ MockedStatic<GravitinoEnv> envMocked = mockStatic(GravitinoEnv.class))
{
+ principalUtilsMocked
+ .when(PrincipalUtils::getCurrentPrincipal)
+ .thenReturn(new UserPrincipal("tester"));
+
principalUtilsMocked.when(PrincipalUtils::getCurrentUserName).thenReturn("tester");
+
+ authUtilsMocked
+ .when(
+ () ->
+ AuthorizationUtils.checkCurrentUser(
+ ArgumentMatchers.any(), ArgumentMatchers.any(),
ArgumentMatchers.any()))
+ .thenAnswer(invocation -> null);
+
+ GravitinoAuthorizerProvider mockedProvider =
mock(GravitinoAuthorizerProvider.class);
+ GravitinoAuthorizer authorizer = tableProbeAuthorizer();
+
authorizerMocked.when(GravitinoAuthorizerProvider::getInstance).thenReturn(mockedProvider);
+ when(mockedProvider.getGravitinoAuthorizer()).thenReturn(authorizer);
+
+ GravitinoEnv mockEnv = mock(GravitinoEnv.class);
+ TableDispatcher tableDispatcher = mock(TableDispatcher.class);
+ EventBus mockEventBus = mock(EventBus.class);
+ envMocked.when(GravitinoEnv::getInstance).thenReturn(mockEnv);
+ when(mockEnv.tableDispatcher()).thenReturn(tableDispatcher);
+ when(mockEnv.eventBus()).thenReturn(mockEventBus);
+
when(tableDispatcher.tableExists(ArgumentMatchers.any())).thenReturn(false);
+
+ MethodInterceptor interceptor = tableLoadInterceptor();
+ MethodInvocation invocation = tableLoadInvocation();
+ Response notFound = Utils.notFound("NoSuchTableException", "Table does
not exist");
+ when(invocation.proceed()).thenReturn(notFound);
+
+ Response response = (Response) interceptor.invoke(invocation);
+
+ assertEquals(Response.Status.NOT_FOUND.getStatusCode(),
response.getStatus());
+ verify(invocation).proceed();
+ verify(tableDispatcher).tableExists(ArgumentMatchers.any());
+ verify(mockEventBus, never()).dispatchEvent(ArgumentMatchers.any());
+ }
+ }
+
+ @Test
+ public void
testLoadTableAuthorizationReturnsForbiddenWhenProbeAllowedTableExists()
+ throws Throwable {
+ try (MockedStatic<PrincipalUtils> principalUtilsMocked =
mockStatic(PrincipalUtils.class);
+ MockedStatic<GravitinoAuthorizerProvider> authorizerMocked =
+ mockStatic(GravitinoAuthorizerProvider.class);
+ MockedStatic<AuthorizationUtils> authUtilsMocked =
mockStatic(AuthorizationUtils.class);
+ MockedStatic<GravitinoEnv> envMocked = mockStatic(GravitinoEnv.class))
{
+ principalUtilsMocked
+ .when(PrincipalUtils::getCurrentPrincipal)
+ .thenReturn(new UserPrincipal("tester"));
+
principalUtilsMocked.when(PrincipalUtils::getCurrentUserName).thenReturn("tester");
+
+ authUtilsMocked
+ .when(
+ () ->
+ AuthorizationUtils.checkCurrentUser(
+ ArgumentMatchers.any(), ArgumentMatchers.any(),
ArgumentMatchers.any()))
+ .thenAnswer(invocation -> null);
+
+ GravitinoAuthorizerProvider mockedProvider =
mock(GravitinoAuthorizerProvider.class);
+ GravitinoAuthorizer authorizer = tableProbeAuthorizer();
+
authorizerMocked.when(GravitinoAuthorizerProvider::getInstance).thenReturn(mockedProvider);
+ when(mockedProvider.getGravitinoAuthorizer()).thenReturn(authorizer);
+
+ GravitinoEnv mockEnv = mock(GravitinoEnv.class);
+ TableDispatcher tableDispatcher = mock(TableDispatcher.class);
+ EventBus mockEventBus = spy(new EventBus(Collections.emptyList()));
+ envMocked.when(GravitinoEnv::getInstance).thenReturn(mockEnv);
+ when(mockEnv.tableDispatcher()).thenReturn(tableDispatcher);
+ when(mockEnv.eventBus()).thenReturn(mockEventBus);
+
when(tableDispatcher.tableExists(ArgumentMatchers.any())).thenReturn(true);
+
+ MethodInterceptor interceptor = tableLoadInterceptor();
+ MethodInvocation invocation = tableLoadInvocation();
+
+ Response response = (Response) interceptor.invoke(invocation);
+
+ assertEquals(Response.Status.FORBIDDEN.getStatusCode(),
response.getStatus());
+ verify(invocation, never()).proceed();
+ verify(tableDispatcher).tableExists(ArgumentMatchers.any());
+ verify(mockEventBus)
+
.dispatchEvent(ArgumentMatchers.any(AuthorizationDenialFailureEvent.class));
+ }
+ }
+
/**
* When {@code checkCurrentUser} throws {@link NoSuchMetalakeException}, the
403 is a
* resource-not-found masquerading as forbidden — no {@link
AuthorizationDenialFailureEvent} is
@@ -748,6 +844,23 @@ public class TestGravitinoInterceptionService {
}
}
+ public static class TestTableLoadOperations {
+
+ @AuthorizationExpression(
+ expression = LOAD_TABLE_AUTHORIZATION_EXPRESSION,
+ allowCheckExistence = PROBE_TABLE_LIKE_AUTHORIZATION_EXPRESSION,
+ accessMetadataType = MetadataObject.Type.TABLE)
+ public Response loadTable(
+ @AuthorizationMetadata(type = Entity.EntityType.METALAKE) String
metalake,
+ @AuthorizationMetadata(type = Entity.EntityType.CATALOG) String
catalog,
+ @AuthorizationMetadata(type = Entity.EntityType.SCHEMA) String schema,
+ @AuthorizationMetadata(type = Entity.EntityType.TABLE) String table,
+ @AuthorizationRequest(type =
AuthorizationRequest.RequestType.LOAD_TABLE)
+ String requiredPrivileges) {
+ return Utils.ok("unused");
+ }
+ }
+
public static class TestOperations {
@AuthorizationExpression(
@@ -845,6 +958,60 @@ public class TestGravitinoInterceptionService {
return authorizer;
}
+ private MethodInterceptor tableLoadInterceptor() throws
NoSuchMethodException {
+ Method method =
+ TestTableLoadOperations.class.getMethod(
+ "loadTable", String.class, String.class, String.class,
String.class, String.class);
+ return new
GravitinoInterceptionService().getMethodInterceptors(method).get(0);
+ }
+
+ private MethodInvocation tableLoadInvocation() throws NoSuchMethodException {
+ Method method =
+ TestTableLoadOperations.class.getMethod(
+ "loadTable", String.class, String.class, String.class,
String.class, String.class);
+ MethodInvocation invocation = mock(MethodInvocation.class);
+ when(invocation.getMethod()).thenReturn(method);
+ when(invocation.getArguments())
+ .thenReturn(
+ new Object[] {"testMetalake", "testCatalog", "testSchema",
"missingTable", null});
+ return invocation;
+ }
+
+ private GravitinoAuthorizer tableProbeAuthorizer() {
+ GravitinoAuthorizer authorizer = mock(GravitinoAuthorizer.class);
+ when(authorizer.authorize(
+ ArgumentMatchers.any(),
+ ArgumentMatchers.eq("testMetalake"),
+ ArgumentMatchers.argThat(
+ metadataObject ->
+ metadataObject.type() == MetadataObject.Type.CATALOG
+ && "testCatalog".equals(metadataObject.name())),
+ ArgumentMatchers.eq(Privilege.Name.USE_CATALOG),
+ ArgumentMatchers.any()))
+ .thenReturn(true);
+ when(authorizer.authorize(
+ ArgumentMatchers.any(),
+ ArgumentMatchers.eq("testMetalake"),
+ ArgumentMatchers.argThat(
+ metadataObject ->
+ metadataObject.type() == MetadataObject.Type.SCHEMA
+ && "testSchema".equals(metadataObject.name())),
+ ArgumentMatchers.eq(Privilege.Name.USE_SCHEMA),
+ ArgumentMatchers.any()))
+ .thenReturn(true);
+ when(authorizer.authorize(
+ ArgumentMatchers.any(),
+ ArgumentMatchers.eq("testMetalake"),
+ ArgumentMatchers.argThat(
+ metadataObject ->
+ metadataObject.type() == MetadataObject.Type.METALAKE
+ && "testMetalake".equals(metadataObject.name())),
+ ArgumentMatchers.eq(Privilege.Name.CREATE_TABLE),
+ ArgumentMatchers.any()))
+ .thenReturn(true);
+ return authorizer;
+ }
+
private static class MockGravitinoAuthorizer implements GravitinoAuthorizer {
@Override
diff --git
a/server/src/test/java/org/apache/gravitino/server/web/filter/authorization/TestCatalogConnectionTestAuthorizationExecutor.java
b/server/src/test/java/org/apache/gravitino/server/web/filter/authorization/TestCatalogConnectionTestAuthorizationExecutor.java
index 12f8a9ce8b..26cd29987b 100644
---
a/server/src/test/java/org/apache/gravitino/server/web/filter/authorization/TestCatalogConnectionTestAuthorizationExecutor.java
+++
b/server/src/test/java/org/apache/gravitino/server/web/filter/authorization/TestCatalogConnectionTestAuthorizationExecutor.java
@@ -97,7 +97,8 @@ public class TestCatalogConnectionTestAuthorizationExecutor {
method.getParameters(),
new Object[] {proposedChanges()},
SECONDARY_EXPRESSION,
- ExpressionCondition.HAS_PROPOSED_CHANGES);
+ ExpressionCondition.HAS_PROPOSED_CHANGES,
+ "");
assertTrue(executor instanceof CatalogConnectionTestAuthorizationExecutor);
assertEquals(
diff --git
a/server/src/test/java/org/apache/gravitino/server/web/filter/authorization/TestLineageAuthorizationExecutor.java
b/server/src/test/java/org/apache/gravitino/server/web/filter/authorization/TestLineageAuthorizationExecutor.java
index 518e09d6d1..cff07fd57c 100644
---
a/server/src/test/java/org/apache/gravitino/server/web/filter/authorization/TestLineageAuthorizationExecutor.java
+++
b/server/src/test/java/org/apache/gravitino/server/web/filter/authorization/TestLineageAuthorizationExecutor.java
@@ -403,7 +403,8 @@ class TestLineageAuthorizationExecutor {
lineageMethod().getParameters(),
new Object[] {event},
"",
- ExpressionCondition.NEVER);
+ ExpressionCondition.NEVER,
+ "");
}
private static Method lineageMethod() throws NoSuchMethodException {
diff --git
a/server/src/test/java/org/apache/gravitino/server/web/filter/authorization/TestLoadTableAuthorizationExecutor.java
b/server/src/test/java/org/apache/gravitino/server/web/filter/authorization/TestLoadTableAuthorizationExecutor.java
index fcd0f273e7..15bc76ce8f 100644
---
a/server/src/test/java/org/apache/gravitino/server/web/filter/authorization/TestLoadTableAuthorizationExecutor.java
+++
b/server/src/test/java/org/apache/gravitino/server/web/filter/authorization/TestLoadTableAuthorizationExecutor.java
@@ -74,7 +74,8 @@ public class TestLoadTableAuthorizationExecutor {
Collections.emptyMap(),
Optional.empty(),
SECONDARY_EXPRESSION,
- condition);
+ condition,
+ "");
}
private static String expression(LoadTableAuthorizationExecutor executor)
throws Exception {
diff --git
a/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestTableAuthorizationExpression.java
b/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestTableAuthorizationExpression.java
index f115695416..f21f372c00 100644
---
a/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestTableAuthorizationExpression.java
+++
b/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestTableAuthorizationExpression.java
@@ -170,6 +170,30 @@ public class TestTableAuthorizationExpression {
"METALAKE::USE_CATALOG")));
}
+ @Test
+ public void testLoadTableExistenceProbe() throws NoSuchMethodException,
OgnlException {
+ Method method =
+ TableOperations.class.getMethod(
+ "loadTable", String.class, String.class, String.class,
String.class, String.class);
+ AuthorizationExpression authorizationExpressionAnnotation =
+ method.getAnnotation(AuthorizationExpression.class);
+ String expression =
authorizationExpressionAnnotation.allowCheckExistence();
+ MockAuthorizationExpressionEvaluator mockEvaluator =
+ new MockAuthorizationExpressionEvaluator(expression);
+ assertFalse(mockEvaluator.getResult(ImmutableSet.of()));
+ assertFalse(mockEvaluator.getResult(ImmutableSet.of("METALAKE::OWNER")));
+
assertFalse(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::CREATE_TABLE")));
+ assertTrue(
+ mockEvaluator.getResult(
+ ImmutableSet.of("SCHEMA::CREATE_TABLE", "CATALOG::USE_CATALOG",
"SCHEMA::USE_SCHEMA")));
+ assertTrue(
+ mockEvaluator.getResult(
+ ImmutableSet.of("SCHEMA::SELECT_TABLE", "CATALOG::USE_CATALOG",
"SCHEMA::USE_SCHEMA")));
+ assertTrue(
+ mockEvaluator.getResult(
+ ImmutableSet.of("SCHEMA::MODIFY_TABLE", "CATALOG::USE_CATALOG",
"SCHEMA::USE_SCHEMA")));
+ }
+
@Test
public void testAlterTable() throws NoSuchMethodException, OgnlException {
Method method =