This is an automated email from the ASF dual-hosted git repository.
liuxun 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 f94fcdc94c [#7795] fix(authz): Support check deny privilege (#7800)
f94fcdc94c is described below
commit f94fcdc94c75a9acd7b8dd869b44b955df6622c1
Author: yangyang zhong <[email protected]>
AuthorDate: Wed Jul 30 16:44:37 2025 +0800
[#7795] fix(authz): Support check deny privilege (#7800)
### What changes were proposed in this pull request?
Support check deny privilege
### Why are the changes needed?
Fix: #7795
### Does this PR introduce _any_ user-facing change?
None
### How was this patch tested?
Existing metadata authentication for IT and UT
---
.../test/authorization/TableAuthorizationIT.java | 12 +-
.../org/apache/gravitino/auth/AuthConstants.java | 7 ++
.../authorization/GravitinoAuthorizer.java | 6 +
.../authorization/PassThroughAuthorizer.java | 9 ++
.../AuthorizationExpressionConverter.java | 79 +++++++++---
.../authorization/jcasbin/JcasbinAuthorizer.java | 134 +++++++++++++--------
.../authorization/MockGravitinoAuthorizer.java | 9 ++
.../server/web/rest/FilesetOperations.java | 2 +-
.../filter/TestGravitinoInterceptionService.java | 9 ++
.../TestCatalogAuthorizationExpression.java | 12 ++
.../TestFilesetAuthorizationExpression.java | 64 ++++++++++
.../TestModelAuthorizationExpression.java | 83 +++++++++++++
.../TestSchemaAuthorizationExpression.java | 30 +++++
.../TestTableAuthorizationExpression.java | 52 ++++++++
.../TestTopicAuthorizationExpression.java | 56 +++++++++
15 files changed, 499 insertions(+), 65 deletions(-)
diff --git
a/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/authorization/TableAuthorizationIT.java
b/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/authorization/TableAuthorizationIT.java
index 6042c0c33a..6c9f260594 100644
---
a/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/authorization/TableAuthorizationIT.java
+++
b/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/authorization/TableAuthorizationIT.java
@@ -186,9 +186,19 @@ public class TableAuthorizationIT extends
BaseRestApiAuthorizationIT {
GravitinoMetalake gravitinoMetalake = client.loadMetalake(METALAKE);
gravitinoMetalake.grantPrivilegesToRole(
role,
- MetadataObjects.of(ImmutableList.of(CATALOG, SCHEMA, "table1"),
MetadataObject.Type.TABLE),
+ MetadataObjects.of(ImmutableList.of(CATALOG, SCHEMA),
MetadataObject.Type.SCHEMA),
ImmutableList.of(Privileges.SelectTable.allow()));
tableCatalogNormalUser.loadTable(NameIdentifier.of(SCHEMA, "table1"));
+ gravitinoMetalake.grantPrivilegesToRole(
+ role,
+ MetadataObjects.of(ImmutableList.of(CATALOG, SCHEMA, "table1"),
MetadataObject.Type.TABLE),
+ ImmutableList.of(Privileges.SelectTable.deny()));
+ assertThrows(
+ String.format("Can not access metadata {%s.%s.%s}.", CATALOG, SCHEMA,
"table1"),
+ RuntimeException.class,
+ () -> {
+ tableCatalogNormalUser.loadTable(NameIdentifier.of(SCHEMA,
"table1"));
+ });
}
@Test
diff --git a/common/src/main/java/org/apache/gravitino/auth/AuthConstants.java
b/common/src/main/java/org/apache/gravitino/auth/AuthConstants.java
index 46b4e5964f..8750c4c942 100644
--- a/common/src/main/java/org/apache/gravitino/auth/AuthConstants.java
+++ b/common/src/main/java/org/apache/gravitino/auth/AuthConstants.java
@@ -21,6 +21,7 @@ package org.apache.gravitino.auth;
/** Constants used for authentication. */
public final class AuthConstants {
+
private AuthConstants() {}
/** The HTTP header used to pass the authentication token. */
@@ -50,6 +51,12 @@ public final class AuthConstants {
/** SELF authorization expression. */
public static final String SELF = "SELF";
+ /** deny. */
+ public static final String DENY = "deny";
+
+ /** allow. */
+ public static final String ALLOW = "allow";
+
/**
* The default name of the attribute that stores the authenticated principal
in the request.
*
diff --git
a/core/src/main/java/org/apache/gravitino/authorization/GravitinoAuthorizer.java
b/core/src/main/java/org/apache/gravitino/authorization/GravitinoAuthorizer.java
index 1887ffea08..08bcaa251d 100644
---
a/core/src/main/java/org/apache/gravitino/authorization/GravitinoAuthorizer.java
+++
b/core/src/main/java/org/apache/gravitino/authorization/GravitinoAuthorizer.java
@@ -50,6 +50,12 @@ public interface GravitinoAuthorizer extends Closeable {
MetadataObject metadataObject,
Privilege.Name privilege);
+ boolean deny(
+ Principal principal,
+ String metalake,
+ MetadataObject metadataObject,
+ Privilege.Name privilege);
+
/**
* Determine whether the user is the Owner of a certain metadata object.
*
diff --git
a/server-common/src/main/java/org/apache/gravitino/server/authorization/PassThroughAuthorizer.java
b/server-common/src/main/java/org/apache/gravitino/server/authorization/PassThroughAuthorizer.java
index f28e402128..3288f92b3b 100644
---
a/server-common/src/main/java/org/apache/gravitino/server/authorization/PassThroughAuthorizer.java
+++
b/server-common/src/main/java/org/apache/gravitino/server/authorization/PassThroughAuthorizer.java
@@ -43,6 +43,15 @@ public class PassThroughAuthorizer implements
GravitinoAuthorizer {
return true;
}
+ @Override
+ public boolean deny(
+ Principal principal,
+ String metalake,
+ MetadataObject metadataObject,
+ Privilege.Name privilege) {
+ return false;
+ }
+
@Override
public boolean isOwner(Principal principal, String metalake, MetadataObject
metadataObject) {
return true;
diff --git
a/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionConverter.java
b/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionConverter.java
index b72d904761..a090edbb77 100644
---
a/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionConverter.java
+++
b/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionConverter.java
@@ -49,6 +49,8 @@ public class AuthorizationExpressionConverter {
*/
public static final String CAN_SET_OWNER = "CAN_SET_OWNER";
+ private static final String DENY_PREFIX = "DENY_";
+
/**
* The EXPRESSION_CACHE caches the result of converting authorization
expressions into an OGNL
* expression.
@@ -82,6 +84,13 @@ public class AuthorizationExpressionConverter {
String replacement;
if (AuthConstants.OWNER.equals(privilegeOrExpression)) {
replacement =
String.format("authorizer.isOwner(principal,METALAKE_NAME,%s)", type);
+ } else if (privilegeOrExpression.startsWith(DENY_PREFIX)) {
+ String privilege = privilegeOrExpression.substring(5);
+ replacement =
+ String.format(
+ "authorizer.deny(principal,METALAKE_NAME,%s,"
+ +
"@org.apache.gravitino.authorization.Privilege\\$Name@%s)",
+ type, privilege);
} else if (AuthConstants.SELF.equals(privilegeOrExpression)) {
replacement =
String.format(
@@ -94,6 +103,7 @@ public class AuthorizationExpressionConverter {
+
"@org.apache.gravitino.authorization.Privilege\\$Name@%s)",
type, privilegeOrExpression);
}
+
matcher.appendReplacement(result, replacement);
}
matcher.appendTail(result);
@@ -147,48 +157,87 @@ public class AuthorizationExpressionConverter {
public static String replaceAnyPrivilege(String expression) {
expression = expression.replaceAll("SERVICE_ADMIN",
"authorizer.isServiceAdmin()");
expression = expression.replaceAll("METALAKE_USER",
"authorizer.isMetalakeUser(METALAKE_NAME)");
- expression = expression.replaceAll("ANY_USE_CATALOG", "(ANY(USE_CATALOG,
METALAKE, CATALOG))");
expression =
- expression.replaceAll("ANY_USE_SCHEMA", "(ANY(USE_SCHEMA, METALAKE,
CATALOG, SCHEMA))");
+ expression.replaceAll(
+ "ANY_USE_CATALOG",
+ "((ANY(USE_CATALOG, METALAKE, CATALOG)) && "
+ + "!(ANY(DENY_USE_CATALOG, METALAKE, CATALOG)))");
+ expression =
+ expression.replaceAll(
+ "ANY_USE_SCHEMA",
+ "((ANY(USE_SCHEMA, METALAKE, CATALOG, SCHEMA)) "
+ + "&& !(ANY(DENY_USE_SCHEMA, METALAKE, CATALOG, SCHEMA)))");
+ expression =
+ expression.replaceAll(
+ "ANY_CREATE_SCHEMA",
+ "((ANY(CREATE_SCHEMA, METALAKE, CATALOG)) "
+ + "&& !(ANY(DENY_CREATE_SCHEMA, METALAKE, CATALOG)))");
expression =
- expression.replaceAll("ANY_CREATE_SCHEMA", "(ANY(CREATE_SCHEMA,
METALAKE, CATALOG))");
+ expression.replaceAll(
+ "ANY_SELECT_TABLE",
+ "((ANY(SELECT_TABLE, METALAKE, CATALOG, SCHEMA, TABLE)) "
+ + "&& !(ANY(DENY_SELECT_TABLE, METALAKE, CATALOG, SCHEMA,
TABLE)) )");
expression =
expression.replaceAll(
- "ANY_SELECT_TABLE", "(ANY(SELECT_TABLE, METALAKE, CATALOG, SCHEMA,
TABLE))");
+ "ANY_MODIFY_TABLE",
+ "((ANY(MODIFY_TABLE, METALAKE, CATALOG, SCHEMA, TABLE)) "
+ + "&& !(ANY(DENY_MODIFY_TABLE, METALAKE, CATALOG, SCHEMA,
TABLE)))");
expression =
expression.replaceAll(
- "ANY_MODIFY_TABLE", "(ANY(MODIFY_TABLE, METALAKE, CATALOG, SCHEMA,
TABLE))");
+ "ANY_CREATE_TABLE",
+ "((ANY(CREATE_TABLE, METALAKE, CATALOG, SCHEMA, TABLE)) "
+ + "&& !(ANY(DENY_CREATE_TABLE, METALAKE, CATALOG, SCHEMA,
TABLE)))");
expression =
expression.replaceAll(
- "ANY_CREATE_TABLE", "(ANY(CREATE_TABLE, METALAKE, CATALOG, SCHEMA,
TABLE))");
+ "ANY_CREATE_FILESET",
+ "((ANY(CREATE_FILESET, METALAKE, CATALOG, SCHEMA, TABLE)) "
+ + "&& !(ANY(DENY_CREATE_FILESET, METALAKE, CATALOG, SCHEMA,
TABLE)))");
expression =
expression.replaceAll(
"SCHEMA_OWNER_WITH_USE_CATALOG",
- "SCHEMA::OWNER && (ANY(USE_CATALOG, METALAKE, CATALOG))");
+ "SCHEMA::OWNER && "
+ + "((ANY(USE_CATALOG, METALAKE, CATALOG)) && "
+ + "!(ANY(DENY_USE_CATALOG, METALAKE, CATALOG)))");
expression =
expression.replaceAll(
- "ANY_USE_MODEL", "(ANY(USE_MODEL, METALAKE, CATALOG, SCHEMA,
MODEL))");
+ "ANY_USE_MODEL",
+ "((ANY(USE_MODEL, METALAKE, CATALOG, SCHEMA, MODEL)) && "
+ + "!(ANY(DENY_USE_MODEL, METALAKE, CATALOG, SCHEMA, MODEL)))");
expression =
expression.replaceAll(
"ANY_CREATE_MODEL_VERSION",
- "(ANY(CREATE_MODEL_VERSION, METALAKE, CATALOG, SCHEMA, MODEL))");
+ "((ANY(CREATE_MODEL_VERSION, METALAKE, CATALOG, SCHEMA, MODEL)) "
+ + "&& !(ANY(DENY_CREATE_MODEL_VERSION, METALAKE, CATALOG,
SCHEMA, MODEL)))");
expression =
- expression.replaceAll("ANY_CREATE_MODEL", "(ANY(CREATE_MODEL,
METALAKE, CATALOG, SCHEMA))");
+ expression.replaceAll(
+ "ANY_CREATE_MODEL",
+ "((ANY(CREATE_MODEL, METALAKE, CATALOG, SCHEMA)) "
+ + "&& !(ANY(DENY_CREATE_MODEL, METALAKE, CATALOG, SCHEMA)))");
expression =
expression.replaceAll(
- "ANY_CREATE_TOPIC", "(ANY(CREATE_TOPIC, METALAKE, CATALOG, SCHEMA,
TOPIC))");
+ "ANY_CREATE_TOPIC",
+ "((ANY(CREATE_TOPIC, METALAKE, CATALOG, SCHEMA, TOPIC)) "
+ + "&& !(ANY(DENY_CREATE_TOPIC, METALAKE, CATALOG, SCHEMA,
TOPIC)))");
expression =
expression.replaceAll(
- "ANY_PRODUCE_TOPIC", "(ANY(PRODUCE_TOPIC, METALAKE, CATALOG,
SCHEMA, TOPIC))");
+ "ANY_PRODUCE_TOPIC",
+ "((ANY(PRODUCE_TOPIC, METALAKE, CATALOG, SCHEMA, TOPIC))"
+ + "&& !(ANY(DENY_PRODUCE_TOPIC, METALAKE, CATALOG, SCHEMA,
TOPIC)))");
expression =
expression.replaceAll(
- "ANY_CONSUME_TOPIC", "(ANY(CONSUME_TOPIC, METALAKE, CATALOG,
SCHEMA, TOPIC))");
+ "ANY_CONSUME_TOPIC",
+ "((ANY(CONSUME_TOPIC, METALAKE, CATALOG, SCHEMA, TOPIC))"
+ + "&& !(ANY(DENY_CONSUME_TOPIC, METALAKE, CATALOG, SCHEMA,
TOPIC)))");
expression =
expression.replaceAll(
- "ANY_READ_FILESET", "(ANY(READ_FILESET, METALAKE, CATALOG, SCHEMA,
FILESET))");
+ "ANY_READ_FILESET",
+ "((ANY(READ_FILESET, METALAKE, CATALOG, SCHEMA, FILESET))"
+ + "&& !(ANY(DENY_READ_FILESET, METALAKE, CATALOG, SCHEMA,
FILESET)))");
expression =
expression.replaceAll(
- "ANY_WRITE_FILESET", "(ANY(WRITE_FILESET, METALAKE, CATALOG,
SCHEMA, FILESET))");
+ "ANY_WRITE_FILESET",
+ "((ANY(WRITE_FILESET, METALAKE, CATALOG, SCHEMA, FILESET))"
+ + "&& !(ANY(DENY_WRITE_FILESET, METALAKE, CATALOG, SCHEMA,
FILESET)))");
expression =
expression.replaceAll(
CAN_SET_OWNER,
diff --git
a/server-common/src/main/java/org/apache/gravitino/server/authorization/jcasbin/JcasbinAuthorizer.java
b/server-common/src/main/java/org/apache/gravitino/server/authorization/jcasbin/JcasbinAuthorizer.java
index d8f260a638..86a36b9897 100644
---
a/server-common/src/main/java/org/apache/gravitino/server/authorization/jcasbin/JcasbinAuthorizer.java
+++
b/server-common/src/main/java/org/apache/gravitino/server/authorization/jcasbin/JcasbinAuthorizer.java
@@ -30,8 +30,6 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
-import org.apache.gravitino.Config;
-import org.apache.gravitino.Configs;
import org.apache.gravitino.Entity;
import org.apache.gravitino.EntityStore;
import org.apache.gravitino.GravitinoEnv;
@@ -61,9 +59,16 @@ public class JcasbinAuthorizer implements
GravitinoAuthorizer {
private static final Logger LOG =
LoggerFactory.getLogger(JcasbinAuthorizer.class);
/** Jcasbin enforcer is used for metadata authorization. */
- private Enforcer enforcer;
+ private Enforcer allowEnforcer;
- private final Set<String> serviceAdmins = ConcurrentHashMap.newKeySet();
+ /** Jcasbin deny enforcer is used for metadata authorization. */
+ private Enforcer denyEnforcer;
+
+ /** allow internal authorizer */
+ private InternalAuthorizer allowInternalAuthorizer;
+
+ /** deny internal authorizer */
+ private InternalAuthorizer denyInternalAuthorizer;
/**
* loadedRoles is used to cache roles that have loaded permissions. When the
permissions of a role
@@ -73,20 +78,22 @@ public class JcasbinAuthorizer implements
GravitinoAuthorizer {
@Override
public void initialize() {
- try (InputStream modelStream =
- JcasbinAuthorizer.class.getResourceAsStream("/jcasbin_model.conf")) {
+ allowEnforcer = new SyncedEnforcer(getModel("/jcasbin_model.conf"), new
GravitinoAdapter());
+ allowInternalAuthorizer = new InternalAuthorizer(allowEnforcer);
+ denyEnforcer = new SyncedEnforcer(getModel("/jcasbin_model.conf"), new
GravitinoAdapter());
+ denyInternalAuthorizer = new InternalAuthorizer(denyEnforcer);
+ }
+
+ private Model getModel(String modelFilePath) {
+ Model model = new Model();
+ try (InputStream modelStream =
JcasbinAuthorizer.class.getResourceAsStream(modelFilePath)) {
Preconditions.checkNotNull(modelStream, "Jcasbin model file can not
found.");
String modelData = IOUtils.toString(modelStream, StandardCharsets.UTF_8);
- Model model = new Model();
model.loadModelFromText(modelData);
- enforcer = new SyncedEnforcer(model, new GravitinoAdapter());
- Config config = GravitinoEnv.getInstance().config();
- if (config != null) {
- serviceAdmins.addAll(config.get(Configs.SERVICE_ADMINS));
- }
} catch (IOException e) {
throw new RuntimeException(e);
}
+ return model;
}
@Override
@@ -95,12 +102,24 @@ public class JcasbinAuthorizer implements
GravitinoAuthorizer {
String metalake,
MetadataObject metadataObject,
Privilege.Name privilege) {
- return authorizeInternal(principal, metalake, metadataObject,
privilege.name());
+ return allowInternalAuthorizer.authorizeInternal(
+ principal, metalake, metadataObject, privilege.name());
+ }
+
+ @Override
+ public boolean deny(
+ Principal principal,
+ String metalake,
+ MetadataObject metadataObject,
+ Privilege.Name privilege) {
+ return denyInternalAuthorizer.authorizeInternal(
+ principal, metalake, metadataObject, privilege.name());
}
@Override
public boolean isOwner(Principal principal, String metalake, MetadataObject
metadataObject) {
- return authorizeInternal(principal, metalake, metadataObject,
AuthConstants.OWNER);
+ return allowInternalAuthorizer.authorizeInternal(
+ principal, metalake, metadataObject, AuthConstants.OWNER);
}
@Override
@@ -146,7 +165,7 @@ public class JcasbinAuthorizer implements
GravitinoAuthorizer {
UserEntity userEntity = getUserEntity(currentUserName, metalake);
Long userId = userEntity.id();
loadRolePrivilege(metalake, currentUserName, userId);
- return enforcer.hasRoleForUser(String.valueOf(userId),
String.valueOf(roleId));
+ return allowEnforcer.hasRoleForUser(String.valueOf(userId),
String.valueOf(roleId));
} catch (Exception e) {
LOG.warn("can not get user id or role id.", e);
return false;
@@ -220,7 +239,8 @@ public class JcasbinAuthorizer implements
GravitinoAuthorizer {
@Override
public void handleRolePrivilegeChange(Long roleId) {
loadedRoles.remove(roleId);
- enforcer.deleteRole(String.valueOf(roleId));
+ allowEnforcer.deleteRole(String.valueOf(roleId));
+ denyEnforcer.deleteRole(String.valueOf(roleId));
}
@Override
@@ -234,42 +254,51 @@ public class JcasbinAuthorizer implements
GravitinoAuthorizer {
String.valueOf(metadataObject.type()),
String.valueOf(metadataId),
AuthConstants.OWNER,
- "allow");
- enforcer.removePolicy(policy);
+ AuthConstants.ALLOW);
+ allowEnforcer.removePolicy(policy);
}
@Override
public void close() throws IOException {}
- private boolean authorizeInternal(
- Principal principal, String metalake, MetadataObject metadataObject,
String privilege) {
- String username = principal.getName();
- return loadPrivilegeAndAuthorize(username, metalake, metadataObject,
privilege);
- }
+ private class InternalAuthorizer {
- private boolean authorizeByJcasbin(
- Long userId, MetadataObject metadataObject, Long metadataId, String
privilege) {
- return enforcer.enforce(
- String.valueOf(userId),
- String.valueOf(metadataObject.type()),
- String.valueOf(metadataId),
- privilege);
- }
+ Enforcer enforcer;
- private boolean loadPrivilegeAndAuthorize(
- String username, String metalake, MetadataObject metadataObject, String
privilege) {
- Long metadataId;
- Long userId;
- try {
- UserEntity userEntity = getUserEntity(username, metalake);
- userId = userEntity.id();
- metadataId = MetadataIdConverter.getID(metadataObject, metalake);
- } catch (Exception e) {
- LOG.debug("Can not get entity id", e);
- return false;
+ public InternalAuthorizer(Enforcer enforcer) {
+ this.enforcer = enforcer;
+ }
+
+ private boolean authorizeInternal(
+ Principal principal, String metalake, MetadataObject metadataObject,
String privilege) {
+ String username = principal.getName();
+ return loadPrivilegeAndAuthorize(username, metalake, metadataObject,
privilege);
+ }
+
+ private boolean loadPrivilegeAndAuthorize(
+ String username, String metalake, MetadataObject metadataObject,
String privilege) {
+ Long metadataId;
+ Long userId;
+ try {
+ UserEntity userEntity = getUserEntity(username, metalake);
+ userId = userEntity.id();
+ metadataId = MetadataIdConverter.getID(metadataObject, metalake);
+ } catch (Exception e) {
+ LOG.debug("Can not get entity id", e);
+ return false;
+ }
+ loadPrivilege(metalake, username, userId, metadataObject, metadataId);
+ return authorizeByJcasbin(userId, metadataObject, metadataId, privilege);
+ }
+
+ private boolean authorizeByJcasbin(
+ Long userId, MetadataObject metadataObject, Long metadataId, String
privilege) {
+ return enforcer.enforce(
+ String.valueOf(userId),
+ String.valueOf(metadataObject.type()),
+ String.valueOf(metadataId),
+ privilege);
}
- loadPrivilege(metalake, username, userId, metadataObject, metadataId);
- return authorizeByJcasbin(userId, metadataObject, metadataId, privilege);
}
private static UserEntity getUserEntity(String username, String metalake)
throws IOException {
@@ -317,7 +346,8 @@ public class JcasbinAuthorizer implements
GravitinoAuthorizer {
if (loadedRoles.contains(roleId)) {
continue;
}
- enforcer.addRoleForUser(String.valueOf(userId), String.valueOf(roleId));
+ allowEnforcer.addRoleForUser(String.valueOf(userId),
String.valueOf(roleId));
+ denyEnforcer.addRoleForUser(String.valueOf(userId),
String.valueOf(roleId));
loadPolicyByRoleEntity(role);
loadedRoles.add(roleId);
}
@@ -343,8 +373,8 @@ public class JcasbinAuthorizer implements
GravitinoAuthorizer {
String.valueOf(metadataObject.type()),
String.valueOf(metadataId),
AuthConstants.OWNER,
- "allow");
- enforcer.addPolicy(policy);
+ AuthConstants.ALLOW);
+ allowEnforcer.addPolicy(policy);
}
}
} catch (IOException e) {
@@ -359,7 +389,15 @@ public class JcasbinAuthorizer implements
GravitinoAuthorizer {
for (SecurableObject securableObject : securableObjects) {
for (Privilege privilege : securableObject.privileges()) {
Privilege.Condition condition = privilege.condition();
- enforcer.addPolicy(
+ if (AuthConstants.DENY.equalsIgnoreCase(condition.name())) {
+ denyEnforcer.addPolicy(
+ String.valueOf(roleEntity.id()),
+ securableObject.type().name(),
+ String.valueOf(MetadataIdConverter.getID(securableObject,
metalake)),
+ privilege.name().name().toUpperCase(),
+ AuthConstants.ALLOW);
+ }
+ allowEnforcer.addPolicy(
String.valueOf(roleEntity.id()),
securableObject.type().name(),
String.valueOf(MetadataIdConverter.getID(securableObject,
metalake)),
diff --git
a/server-common/src/test/java/org/apache/gravitino/server/authorization/MockGravitinoAuthorizer.java
b/server-common/src/test/java/org/apache/gravitino/server/authorization/MockGravitinoAuthorizer.java
index dfe021b6d9..82ca4e3651 100644
---
a/server-common/src/test/java/org/apache/gravitino/server/authorization/MockGravitinoAuthorizer.java
+++
b/server-common/src/test/java/org/apache/gravitino/server/authorization/MockGravitinoAuthorizer.java
@@ -57,6 +57,15 @@ public class MockGravitinoAuthorizer implements
GravitinoAuthorizer {
&& privilege == Privilege.Name.SELECT_TABLE;
}
+ @Override
+ public boolean deny(
+ Principal principal,
+ String metalake,
+ MetadataObject metadataObject,
+ Privilege.Name privilege) {
+ return false;
+ }
+
@Override
public boolean isOwner(Principal principal, String metalake, MetadataObject
metadataObject) {
if (!("tester".equals(principal.getName()) &&
"metalakeWithOwner".equals(metalake))) {
diff --git
a/server/src/main/java/org/apache/gravitino/server/web/rest/FilesetOperations.java
b/server/src/main/java/org/apache/gravitino/server/web/rest/FilesetOperations.java
index 1d06e82ea2..68f8ef35ce 100644
---
a/server/src/main/java/org/apache/gravitino/server/web/rest/FilesetOperations.java
+++
b/server/src/main/java/org/apache/gravitino/server/web/rest/FilesetOperations.java
@@ -139,7 +139,7 @@ public class FilesetOperations {
expression =
"ANY(OWNER, METALAKE, CATALOG) || "
+ "SCHEMA_OWNER_WITH_USE_CATALOG || "
- + "ANY_USE_CATALOG && ANY_USE_SCHEMA && SCHEMA::CREATE_FILESET",
+ + "ANY_USE_CATALOG && ANY_USE_SCHEMA && ANY_CREATE_FILESET",
accessMetadataType = MetadataObject.Type.FILESET)
public Response createFileset(
@PathParam("metalake") @AuthorizationMetadata(type =
Entity.EntityType.METALAKE)
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 02c2cc0477..ba09e09f1d 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
@@ -154,6 +154,15 @@ public class TestGravitinoInterceptionService {
&& privilege == Privilege.Name.USE_CATALOG;
}
+ @Override
+ public boolean deny(
+ Principal principal,
+ String metalake,
+ MetadataObject metadataObject,
+ Privilege.Name privilege) {
+ return false;
+ }
+
@Override
public boolean isOwner(Principal principal, String metalake,
MetadataObject metadataObject) {
return false;
diff --git
a/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestCatalogAuthorizationExpression.java
b/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestCatalogAuthorizationExpression.java
index 2cc3851255..6728fea8ee 100644
---
a/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestCatalogAuthorizationExpression.java
+++
b/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestCatalogAuthorizationExpression.java
@@ -63,6 +63,12 @@ public class TestCatalogAuthorizationExpression {
assertTrue(mockEvaluator.getResult(ImmutableSet.of("CATALOG::OWNER")));
assertFalse(mockEvaluator.getResult(ImmutableSet.of("METALAKE::CREATE_CATALOG")));
assertTrue(mockEvaluator.getResult(ImmutableSet.of("CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of("METALAKE::USE_CATALOG",
"CATALOG::DENY_USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of("METALAKE::DENY_USE_CATALOG",
"CATALOG::USE_CATALOG")));
}
@Test
@@ -80,6 +86,12 @@ public class TestCatalogAuthorizationExpression {
assertTrue(mockEvaluator.getResult(ImmutableSet.of("CATALOG::OWNER")));
assertFalse(mockEvaluator.getResult(ImmutableSet.of("METALAKE::CREATE_CATALOG")));
assertTrue(mockEvaluator.getResult(ImmutableSet.of("CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of("METALAKE::USE_CATALOG",
"CATALOG::DENY_USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of("METALAKE::DENY_USE_CATALOG",
"CATALOG::USE_CATALOG")));
}
@Test
diff --git
a/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestFilesetAuthorizationExpression.java
b/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestFilesetAuthorizationExpression.java
index 74f8fd45e5..806a7d0036 100644
---
a/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestFilesetAuthorizationExpression.java
+++
b/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestFilesetAuthorizationExpression.java
@@ -57,6 +57,24 @@ public class TestFilesetAuthorizationExpression {
mockEvaluator.getResult(
ImmutableSet.of(
"SCHEMA::CREATE_FILESET", "SCHEMA::USE_SCHEMA",
"CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::DENY_CREATE_FILESET", "SCHEMA::USE_SCHEMA",
"CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::DENY_CREATE_FILESET",
+ "CATALOG::CREATE_FILESET",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::CREATE_FILESET",
+ "CATALOG::DENY_CREATE_FILESET",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::USE_CATALOG")));
}
@Test
@@ -87,6 +105,20 @@ public class TestFilesetAuthorizationExpression {
mockEvaluator.getResult(
ImmutableSet.of(
"SCHEMA::WRITE_FILESET", "SCHEMA::USE_SCHEMA",
"CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::WRITE_FILESET",
+ "CATALOG::DENY_WRITE_FILESET",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::DENY_WRITE_FILESET",
+ "CATALOG::WRITE_FILESET",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::USE_CATALOG")));
assertFalse(mockEvaluator.getResult(ImmutableSet.of("METALAKE::READ_FILESET")));
assertFalse(mockEvaluator.getResult(ImmutableSet.of("CATALOG::READ_FILESET")));
@@ -96,6 +128,20 @@ public class TestFilesetAuthorizationExpression {
assertTrue(
mockEvaluator.getResult(
ImmutableSet.of("SCHEMA::READ_FILESET", "SCHEMA::USE_SCHEMA",
"CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::READ_FILESET",
+ "CATALOG::DENY_READ_FILESET",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::DENY_READ_FILESET",
+ "CATALOG::READ_FILESET",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::USE_CATALOG")));
assertFalse(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER")));
assertTrue(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER",
"CATALOG::USE_CATALOG")));
@@ -138,6 +184,20 @@ public class TestFilesetAuthorizationExpression {
mockEvaluator.getResult(
ImmutableSet.of(
"SCHEMA::WRITE_FILESET", "SCHEMA::USE_SCHEMA",
"CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::WRITE_FILESET",
+ "CATALOG::DENY_WRITE_FILESET",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::DENY_WRITE_FILESET",
+ "CATALOG::WRITE_FILESET",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::USE_CATALOG")));
assertFalse(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER")));
assertTrue(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER",
"CATALOG::USE_CATALOG")));
@@ -179,6 +239,10 @@ public class TestFilesetAuthorizationExpression {
assertFalse(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER")));
assertTrue(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER",
"CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::OWNER", "CATALOG::USE_CATALOG",
"METALAKE::DENY_USE_CATALOG")));
assertTrue(
mockEvaluator.getResult(
ImmutableSet.of("SCHEMA::OWNER", "SCHEMA::USE_SCHEMA",
"CATALOG::USE_CATALOG")));
diff --git
a/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestModelAuthorizationExpression.java
b/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestModelAuthorizationExpression.java
index 53b1e91536..b000eebf8e 100644
---
a/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestModelAuthorizationExpression.java
+++
b/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestModelAuthorizationExpression.java
@@ -64,6 +64,20 @@ public class TestModelAuthorizationExpression {
mockEvaluator.getResult(
ImmutableSet.of(
"METALAKE::CREATE_MODEL", "METALAKE::USE_SCHEMA",
"METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "METALAKE::CREATE_MODEL",
+ "CATALOG::DENY_CREATE_MODEL",
+ "METALAKE::USE_SCHEMA",
+ "METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "METALAKE::DENY_CREATE_MODEL",
+ "CATALOG::CREATE_MODEL",
+ "METALAKE::USE_SCHEMA",
+ "METALAKE::USE_CATALOG")));
}
@Test
@@ -99,6 +113,27 @@ public class TestModelAuthorizationExpression {
mockEvaluator.getResult(
ImmutableSet.of(
"METALAKE::USE_MODEL", "METALAKE::USE_SCHEMA",
"METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "METALAKE::USE_MODEL",
+ "CATALOG::DENY_USE_MODEL",
+ "METALAKE::USE_SCHEMA",
+ "METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "METALAKE::USE_MODEL",
+ "CATALOG::DENY_USE_SCHEMA",
+ "METALAKE::USE_SCHEMA",
+ "METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "METALAKE::DENY_USE_MODEL",
+ "CATALOG::USE_MODEL",
+ "METALAKE::USE_SCHEMA",
+ "METALAKE::USE_CATALOG")));
}
@Test
@@ -141,6 +176,14 @@ public class TestModelAuthorizationExpression {
mockEvaluator.getResult(
ImmutableSet.of(
"MODEL::OWNER", "MODEL::USE_MODEL", "SCHEMA::USE_SCHEMA",
"CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "MODEL::OWNER",
+ "MODEL::USE_MODEL",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::DENY_USE_SCHEMA",
+ "CATALOG::USE_CATALOG")));
}
@Test
@@ -178,6 +221,14 @@ public class TestModelAuthorizationExpression {
mockEvaluator.getResult(
ImmutableSet.of(
"MODEL::OWNER", "MODEL::USE_MODEL", "SCHEMA::USE_SCHEMA",
"CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "MODEL::OWNER",
+ "MODEL::USE_MODEL",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::DENY_USE_SCHEMA",
+ "CATALOG::USE_CATALOG")));
}
@Test
@@ -238,6 +289,22 @@ public class TestModelAuthorizationExpression {
"MODEL::USE_MODEL",
"METALAKE::USE_SCHEMA",
"METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "METALAKE::CREATE_MODEL_VERSION",
+ "CATALOG::DENY_CREATE_MODEL_VERSION",
+ "MODEL::USE_MODEL",
+ "METALAKE::USE_SCHEMA",
+ "METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "METALAKE::DENY_CREATE_MODEL_VERSION",
+ "CATALOG::CREATE_MODEL_VERSION",
+ "MODEL::USE_MODEL",
+ "METALAKE::USE_SCHEMA",
+ "METALAKE::USE_CATALOG")));
assertFalse(mockEvaluator.getResult(ImmutableSet.of("MODEL::OWNER",
"CATALOG::USE_CATALOG")));
assertFalse(mockEvaluator.getResult(ImmutableSet.of("MODEL::OWNER",
"SCHEMA::USE_SCHEMA")));
assertTrue(
@@ -285,6 +352,10 @@ public class TestModelAuthorizationExpression {
assertFalse(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER")));
assertTrue(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER",
"CATALOG::USE_CATALOG")));
assertTrue(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER",
"METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::OWNER", "METALAKE::USE_CATALOG",
"CATALOG::DENY_USE_CATALOG")));
assertFalse(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::CREATE_MODEL")));
assertFalse(
mockEvaluator.getResult(ImmutableSet.of("SCHEMA::CREATE_MODEL",
"SCHEMA::USE_SCHEMA")));
@@ -328,6 +399,10 @@ public class TestModelAuthorizationExpression {
assertFalse(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER")));
assertTrue(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER",
"CATALOG::USE_CATALOG")));
assertTrue(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER",
"METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::OWNER", "METALAKE::USE_CATALOG",
"CATALOG::DENY_USE_CATALOG")));
assertFalse(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::CREATE_MODEL")));
assertFalse(
mockEvaluator.getResult(ImmutableSet.of("SCHEMA::CREATE_MODEL",
"SCHEMA::USE_SCHEMA")));
@@ -370,6 +445,10 @@ public class TestModelAuthorizationExpression {
assertFalse(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER")));
assertTrue(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER",
"CATALOG::USE_CATALOG")));
assertTrue(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER",
"METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::OWNER", "METALAKE::USE_CATALOG",
"CATALOG::DENY_USE_CATALOG")));
assertFalse(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::CREATE_MODEL")));
assertFalse(
mockEvaluator.getResult(ImmutableSet.of("SCHEMA::CREATE_MODEL",
"SCHEMA::USE_SCHEMA")));
@@ -412,6 +491,10 @@ public class TestModelAuthorizationExpression {
assertFalse(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER")));
assertTrue(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER",
"CATALOG::USE_CATALOG")));
assertTrue(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER",
"METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::OWNER", "METALAKE::USE_CATALOG",
"CATALOG::DENY_USE_CATALOG")));
assertFalse(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::CREATE_MODEL")));
assertFalse(
mockEvaluator.getResult(ImmutableSet.of("SCHEMA::CREATE_MODEL",
"SCHEMA::USE_SCHEMA")));
diff --git
a/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestSchemaAuthorizationExpression.java
b/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestSchemaAuthorizationExpression.java
index fe1a85fc9b..b2ddc646d3 100644
---
a/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestSchemaAuthorizationExpression.java
+++
b/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestSchemaAuthorizationExpression.java
@@ -50,6 +50,16 @@ public class TestSchemaAuthorizationExpression {
assertTrue(
mockEvaluator.getResult(
ImmutableSet.of("METALAKE::CREATE_SCHEMA",
"METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "METALAKE::CREATE_SCHEMA",
+ "CATALOG::DENY_CREATE_SCHEMA",
+ "METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "METALAKE::CREATE_SCHEMA", "METALAKE::USE_CATALOG",
"CATALOG::DENY_USE_CATALOG")));
}
@Test
@@ -70,6 +80,14 @@ public class TestSchemaAuthorizationExpression {
assertFalse(mockEvaluator.getResult(ImmutableSet.of("CATALOG::USE_CATALOG")));
assertTrue(
mockEvaluator.getResult(ImmutableSet.of("CATALOG::USE_CATALOG",
"METALAKE::USE_SCHEMA")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "CATALOG::USE_CATALOG", "METALAKE::USE_SCHEMA",
"SCHEMA::DENY_USE_SCHEMA")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "CATALOG::USE_CATALOG", "METALAKE::DENY_USE_SCHEMA",
"SCHEMA::USE_SCHEMA")));
}
@Test
@@ -89,6 +107,10 @@ public class TestSchemaAuthorizationExpression {
assertFalse(mockEvaluator.getResult(ImmutableSet.of("METALAKE::USE_SCHEMA")));
assertTrue(
mockEvaluator.getResult(ImmutableSet.of("CATALOG::USE_CATALOG",
"METALAKE::USE_SCHEMA")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "CATALOG::USE_CATALOG", "METALAKE::DENY_USE_SCHEMA",
"CATALOG::USE_SCHEMA")));
}
@Test
@@ -112,6 +134,10 @@ public class TestSchemaAuthorizationExpression {
mockEvaluator.getResult(ImmutableSet.of("CATALOG::USE_CATALOG",
"METALAKE::USE_SCHEMA")));
assertFalse(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER")));
assertTrue(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER",
"CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::OWNER", "CATALOG::USE_CATALOG",
"METALAKE::DENY_USE_CATALOG")));
}
@Test
@@ -133,5 +159,9 @@ public class TestSchemaAuthorizationExpression {
assertFalse(mockEvaluator.getResult(ImmutableSet.of("CATALOG::USE_CATALOG")));
assertFalse(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER")));
assertTrue(mockEvaluator.getResult(ImmutableSet.of("SCHEMA::OWNER",
"CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::OWNER", "CATALOG::USE_CATALOG",
"METALAKE::DENY_USE_CATALOG")));
}
}
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 2ab74c08b2..5190327aa8 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
@@ -62,6 +62,20 @@ public class TestTableAuthorizationExpression {
mockEvaluator.getResult(
ImmutableSet.of(
"METALAKE::CREATE_TABLE", "METALAKE::USE_SCHEMA",
"METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "METALAKE::CREATE_TABLE",
+ "CATALOG::DENY_CREATE_TABLE",
+ "METALAKE::USE_SCHEMA",
+ "METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "METALAKE::DENY_CREATE_TABLE",
+ "CATALOG::CREATE_TABLE",
+ "METALAKE::USE_SCHEMA",
+ "METALAKE::USE_CATALOG")));
}
@Test
@@ -98,6 +112,13 @@ public class TestTableAuthorizationExpression {
mockEvaluator.getResult(
ImmutableSet.of(
"METALAKE::SELECT_TABLE", "METALAKE::USE_SCHEMA",
"METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "METALAKE::SELECT_TABLE",
+ "CATALOG::DENY_SELECT_TABLE",
+ "METALAKE::USE_SCHEMA",
+ "METALAKE::USE_CATALOG")));
}
@Test
@@ -136,6 +157,13 @@ public class TestTableAuthorizationExpression {
mockEvaluator.getResult(
ImmutableSet.of(
"METALAKE::SELECT_TABLE", "METALAKE::USE_SCHEMA",
"METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "METALAKE::SELECT_TABLE",
+ "CATALOG::DENY_SELECT_TABLE",
+ "METALAKE::USE_SCHEMA",
+ "METALAKE::USE_CATALOG")));
}
@Test
@@ -192,6 +220,16 @@ public class TestTableAuthorizationExpression {
mockEvaluator.getResult(
ImmutableSet.of(
"METALAKE::MODIFY_TABLE", "METALAKE::USE_SCHEMA",
"METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "METALAKE::MODIFY_TABLE", "CATALOG::DENY_MODIFY_TABLE",
+ "METALAKE::USE_SCHEMA", "METALAKE::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "METALAKE::DENY_MODIFY_TABLE", "CATALOG::MODIFY_TABLE",
+ "METALAKE::USE_SCHEMA", "METALAKE::USE_CATALOG")));
}
@Test
@@ -248,5 +286,19 @@ public class TestTableAuthorizationExpression {
assertTrue(
mockEvaluator.getResult(
ImmutableSet.of("TABLE::OWNER", "SCHEMA::USE_SCHEMA",
"CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "TABLE::OWNER",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::DENY_USE_SCHEMA",
+ "CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "TABLE::OWNER",
+ "SCHEMA::DENY_USE_SCHEMA",
+ "CATALOG::USE_SCHEMA",
+ "CATALOG::USE_CATALOG")));
}
}
diff --git
a/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestTopicAuthorizationExpression.java
b/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestTopicAuthorizationExpression.java
index 8e4b88aeb6..e9f5a32fc1 100644
---
a/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestTopicAuthorizationExpression.java
+++
b/server/src/test/java/org/apache/gravitino/server/web/rest/authorization/TestTopicAuthorizationExpression.java
@@ -56,6 +56,20 @@ public class TestTopicAuthorizationExpression {
assertTrue(
mockEvaluator.getResult(
ImmutableSet.of("SCHEMA::CREATE_TOPIC", "SCHEMA::USE_SCHEMA",
"CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::CREATE_TOPIC",
+ "METALAKE::DENY_CREATE_TOPIC",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::DENY_CREATE_TOPIC",
+ "METALAKE::CREATE_TOPIC",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::USE_CATALOG")));
}
@Test
@@ -102,6 +116,20 @@ public class TestTopicAuthorizationExpression {
assertTrue(
mockEvaluator.getResult(
ImmutableSet.of("SCHEMA::OWNER", "SCHEMA::USE_SCHEMA",
"CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::OWNER",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::USE_CATALOG",
+ "METALAKE::DENY_USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::OWNER",
+ "SCHEMA::DENY_USE_SCHEMA",
+ "CATALOG::DENY_USE_CATALOG",
+ "METALAKE::USE_CATALOG")));
}
@Test
@@ -144,6 +172,20 @@ public class TestTopicAuthorizationExpression {
assertTrue(
mockEvaluator.getResult(
ImmutableSet.of("SCHEMA::OWNER", "SCHEMA::USE_SCHEMA",
"CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::OWNER",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::USE_CATALOG",
+ "METALAKE::DENY_USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::OWNER",
+ "SCHEMA::DENY_USE_SCHEMA",
+ "CATALOG::DENY_USE_CATALOG",
+ "METALAKE::USE_CATALOG")));
}
@Test
@@ -182,5 +224,19 @@ public class TestTopicAuthorizationExpression {
assertTrue(
mockEvaluator.getResult(
ImmutableSet.of("SCHEMA::OWNER", "SCHEMA::USE_SCHEMA",
"CATALOG::USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::OWNER",
+ "SCHEMA::USE_SCHEMA",
+ "CATALOG::USE_CATALOG",
+ "METALAKE::DENY_USE_CATALOG")));
+ assertFalse(
+ mockEvaluator.getResult(
+ ImmutableSet.of(
+ "SCHEMA::OWNER",
+ "SCHEMA::DENY_USE_SCHEMA",
+ "CATALOG::DENY_USE_CATALOG",
+ "METALAKE::USE_CATALOG")));
}
}