This is an automated email from the ASF dual-hosted git repository. liuxun pushed a commit to branch branch-0.7 in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/branch-0.7 by this push: new fa7bb6389 [#4614] feat(auth-ranger): Support deny privilege in the RangerAuthorizationPlugin (#5371) fa7bb6389 is described below commit fa7bb6389eee7a15ea6da0aa929748eb53dfcf15 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> AuthorDate: Wed Oct 30 17:57:49 2024 +0800 [#4614] feat(auth-ranger): Support deny privilege in the RangerAuthorizationPlugin (#5371) ### What changes were proposed in this pull request? Currently, RangerAuthorizationPlugin only supports allow privilege. So we need support to deny privilege. ### Why are the changes needed? Fix: #4614 ### Does this PR introduce _any_ user-facing change? N/A ### How was this patch tested? Added some ITs Co-authored-by: Xun <x...@datastrato.com> --- .../ranger/RangerAuthorizationPlugin.java | 87 ++++-- .../authorization/ranger/RangerHelper.java | 69 ++--- .../ranger/integration/test/RangerHiveIT.java | 318 ++++++++++++++------- .../ranger/integration/test/RangerITEnv.java | 54 ++-- 4 files changed, 345 insertions(+), 183 deletions(-) diff --git a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationPlugin.java b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationPlugin.java index 03376cb07..965c7df31 100644 --- a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationPlugin.java +++ b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationPlugin.java @@ -27,13 +27,13 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; import org.apache.gravitino.MetadataObject; import org.apache.gravitino.authorization.Group; import org.apache.gravitino.authorization.Owner; +import org.apache.gravitino.authorization.Privilege; import org.apache.gravitino.authorization.Role; import org.apache.gravitino.authorization.RoleChange; import org.apache.gravitino.authorization.SecurableObject; @@ -562,6 +562,15 @@ public abstract class RangerAuthorizationPlugin if (policy != null) { // Check the policy item's accesses and roles equal the Ranger securable object's privilege + List<RangerPrivilege> allowPrivilies = + securableObject.privileges().stream() + .filter(privilege -> privilege.condition() == Privilege.Condition.ALLOW) + .collect(Collectors.toList()); + List<RangerPrivilege> denyPrivilies = + securableObject.privileges().stream() + .filter(privilege -> privilege.condition() == Privilege.Condition.DENY) + .collect(Collectors.toList()); + Set<RangerPrivilege> policyPrivileges = policy.getPolicyItems().stream() .filter(policyItem -> policyItem.getRoles().contains(roleName)) @@ -569,7 +578,17 @@ public abstract class RangerAuthorizationPlugin .map(RangerPolicy.RangerPolicyItemAccess::getType) .map(RangerPrivileges::valueOf) .collect(Collectors.toSet()); - if (policyPrivileges.containsAll(securableObject.privileges())) { + + Set<RangerPrivilege> policyDenyPrivileges = + policy.getDenyPolicyItems().stream() + .filter(policyItem -> policyItem.getRoles().contains(roleName)) + .flatMap(policyItem -> policyItem.getAccesses().stream()) + .map(RangerPolicy.RangerPolicyItemAccess::getType) + .map(RangerPrivileges::valueOf) + .collect(Collectors.toSet()); + + if (policyPrivileges.containsAll(allowPrivilies) + && policyDenyPrivileges.containsAll(denyPrivilies)) { LOG.info( "The privilege({}) already added to Ranger policy({})!", policy.getName(), @@ -614,24 +633,25 @@ public abstract class RangerAuthorizationPlugin return true; } - policy - .getPolicyItems() + rangerSecurableObject.privileges().stream() .forEach( - policyItem -> { - boolean match = - policyItem.getAccesses().stream() - .allMatch( - // Find the policy item that matches access and role - access -> { - // Use Gravitino privilege to search the Ranger policy item's access - boolean matchPrivilege = - rangerSecurableObject.privileges().stream() - .filter(Objects::nonNull) - .anyMatch(privilege -> privilege.equalsTo(access.getType())); - return matchPrivilege; - }); - if (match) { - policyItem.getRoles().removeIf(roleName::equals); + rangerPrivilege -> { + if (rangerPrivilege.condition() == Privilege.Condition.ALLOW) { + policy + .getPolicyItems() + .forEach( + policyItem -> { + removePolicyItemIfEqualRoleName( + policyItem, rangerSecurableObject, roleName); + }); + } else { + policy + .getDenyPolicyItems() + .forEach( + policyItem -> { + removePolicyItemIfEqualRoleName( + policyItem, rangerSecurableObject, roleName); + }); } }); @@ -643,9 +663,16 @@ public abstract class RangerAuthorizationPlugin policyItem.getRoles().isEmpty() && policyItem.getUsers().isEmpty() && policyItem.getGroups().isEmpty()); + policy + .getDenyPolicyItems() + .removeIf( + policyItem -> + policyItem.getRoles().isEmpty() + && policyItem.getUsers().isEmpty() + && policyItem.getGroups().isEmpty()); try { - if (policy.getPolicyItems().isEmpty()) { + if (policy.getPolicyItems().isEmpty() && policy.getDenyPolicyItems().isEmpty()) { rangerClient.deletePolicy(policy.getId()); } else { rangerClient.updatePolicy(policy.getId(), policy); @@ -657,6 +684,26 @@ public abstract class RangerAuthorizationPlugin return true; } + private void removePolicyItemIfEqualRoleName( + RangerPolicy.RangerPolicyItem policyItem, + RangerSecurableObject rangerSecurableObject, + String roleName) { + boolean match = + policyItem.getAccesses().stream() + .allMatch( + // Find the policy item that matches access and role + access -> { + // Use Gravitino privilege to search the Ranger policy item's access + boolean matchPrivilege = + rangerSecurableObject.privileges().stream() + .anyMatch(privilege -> privilege.equalsTo(access.getType())); + return matchPrivilege; + }); + if (match) { + policyItem.getRoles().removeIf(roleName::equals); + } + } + @Override public void close() throws IOException {} diff --git a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerHelper.java b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerHelper.java index dde7b7328..51a61560f 100644 --- a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerHelper.java +++ b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerHelper.java @@ -112,15 +112,28 @@ public class RangerHelper { .forEach( rangerPrivilege -> { // Find the policy item that matches Gravitino privilege - List<RangerPolicy.RangerPolicyItem> matchPolicyItems = - policy.getPolicyItems().stream() - .filter( - policyItem -> { - return policyItem.getAccesses().stream() - .anyMatch( - access -> access.getType().equals(rangerPrivilege.getName())); - }) - .collect(Collectors.toList()); + List<RangerPolicy.RangerPolicyItem> matchPolicyItems; + if (rangerPrivilege.condition() == Privilege.Condition.ALLOW) { + matchPolicyItems = + policy.getPolicyItems().stream() + .filter( + policyItem -> { + return policyItem.getAccesses().stream() + .anyMatch( + access -> access.getType().equals(rangerPrivilege.getName())); + }) + .collect(Collectors.toList()); + } else { + matchPolicyItems = + policy.getDenyPolicyItems().stream() + .filter( + policyItem -> { + return policyItem.getAccesses().stream() + .anyMatch( + access -> access.getType().equals(rangerPrivilege.getName())); + }) + .collect(Collectors.toList()); + } if (matchPolicyItems.isEmpty()) { // If the policy item does not exist, then create a new policy item @@ -149,44 +162,6 @@ public class RangerHelper { }); } - /** - * Remove policy item base the securable object's privileges and role name. <br> - * We cannot directly clean the policy items because one Ranger policy maybe contains multiple - * Gravitino privilege objects. <br> - */ - void removePolicyItem( - RangerPolicy policy, String roleName, RangerSecurableObject securableObject) { - // Delete the policy role base the securable object's privileges - policy.getPolicyItems().stream() - .forEach( - policyItem -> { - policyItem - .getAccesses() - .forEach( - access -> { - boolean matchPrivilege = - securableObject.privileges().stream() - .anyMatch( - privilege -> { - return access.getType().equals(privilege.getName()); - }); - if (matchPrivilege) { - policyItem.getRoles().removeIf(roleName::equals); - } - }); - }); - - // Delete the policy items if the roles are empty and not ownership policy item - policy - .getPolicyItems() - .removeIf( - policyItem -> { - return policyItem.getRoles().isEmpty() - && policyItem.getUsers().isEmpty() - && policyItem.getGroups().isEmpty(); - }); - } - /** * Find the managed policy for the ranger securable object. * diff --git a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerHiveIT.java b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerHiveIT.java index c105d42fd..85aa2f5b2 100644 --- a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerHiveIT.java +++ b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerHiveIT.java @@ -31,6 +31,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; import org.apache.gravitino.MetadataObject; import org.apache.gravitino.MetadataObjects; import org.apache.gravitino.authorization.Owner; @@ -152,6 +153,72 @@ public class RangerHiveIT { verifyRoleInRanger(rangerAuthHivePlugin, role); } + @Test + public void testOnDenyRoleCreated() { + String schemaName = currentFunName(); + SecurableObject securableObject1 = + SecurableObjects.parse( + String.format("catalog.%s", schemaName), // use unique db name to avoid conflict + MetadataObject.Type.SCHEMA, + Lists.newArrayList(Privileges.CreateTable.deny())); + + SecurableObject securableObject2 = + SecurableObjects.parse( + String.format("catalog.%s.tab2", schemaName), + SecurableObject.Type.TABLE, + Lists.newArrayList(Privileges.SelectTable.deny())); + + SecurableObject securableObject3 = + SecurableObjects.parse( + String.format("catalog.%s.tab3", schemaName), + SecurableObject.Type.TABLE, + Lists.newArrayList(Privileges.ModifyTable.deny())); + + RoleEntity role = + RoleEntity.builder() + .withId(1L) + .withName(schemaName) + .withAuditInfo(auditInfo) + .withSecurableObjects( + Lists.newArrayList(securableObject1, securableObject2, securableObject3)) + .build(); + Assertions.assertTrue(rangerAuthHivePlugin.onRoleCreated(role)); + verifyRoleInRanger(rangerAuthHivePlugin, role); + } + + @Test + public void testOnMixRoleCreated() { + String schemaName = currentFunName(); + SecurableObject securableObject1 = + SecurableObjects.parse( + String.format("catalog.%s", schemaName), // use unique db name to avoid conflict + MetadataObject.Type.SCHEMA, + Lists.newArrayList(Privileges.SelectTable.allow(), Privileges.CreateTable.deny())); + + SecurableObject securableObject2 = + SecurableObjects.parse( + String.format("catalog.%s.tab2", schemaName), + SecurableObject.Type.TABLE, + Lists.newArrayList(Privileges.SelectTable.allow(), Privileges.ModifyTable.deny())); + + SecurableObject securableObject3 = + SecurableObjects.parse( + String.format("catalog.%s.tab3", schemaName), + SecurableObject.Type.TABLE, + Lists.newArrayList(Privileges.SelectTable.deny(), Privileges.ModifyTable.allow())); + + RoleEntity role = + RoleEntity.builder() + .withId(1L) + .withName(schemaName) + .withAuditInfo(auditInfo) + .withSecurableObjects( + Lists.newArrayList(securableObject1, securableObject2, securableObject3)) + .build(); + Assertions.assertTrue(rangerAuthHivePlugin.onRoleCreated(role)); + verifyRoleInRanger(rangerAuthHivePlugin, role); + } + @Test public void testOnRoleCreatedCatalog() { Role mockCatalogRole = mockCatalogRole(currentFunName()); @@ -162,6 +229,45 @@ public class RangerHiveIT { assertFindManagedPolicy(mockCatalogRole, false); } + @Test + public void testOnDenyRoleCreatedCatalog() { + String roleName = currentFunName(); + SecurableObject securableObject1 = + SecurableObjects.parse( + currentFunName(), + SecurableObject.Type.CATALOG, + Lists.newArrayList(Privileges.CreateSchema.deny())); + RoleEntity mockCatalogRole = + RoleEntity.builder() + .withId(1L) + .withName(roleName) + .withAuditInfo(auditInfo) + .withSecurableObjects(Lists.newArrayList(securableObject1)) + .build(); + + Assertions.assertTrue(rangerAuthHivePlugin.onRoleCreated(mockCatalogRole)); + // Check if exist this policy + assertFindManagedPolicy(mockCatalogRole, true); + mockCatalogRole.securableObjects().stream() + .forEach( + securableObject -> { + rangerAuthHivePlugin.translatePrivilege(securableObject).stream() + .forEach( + rangerSecurableObject -> { + verifyRangerSecurableObjectInRanger( + rangerSecurableObject, + null, + null, + null, + null, + Lists.newArrayList(roleName)); + }); + }); + + Assertions.assertTrue(rangerAuthHivePlugin.onRoleDeleted(mockCatalogRole)); + assertFindManagedPolicy(mockCatalogRole, false); + } + @Test public void testOnRoleDeleted() { // prepare to create a role @@ -517,7 +623,8 @@ public class RangerHiveIT { rangerAuthHivePlugin.translateOwner(oldMetadataObject).stream() .forEach( rangerSecurableObject -> { - verifyOwnerInRanger(rangerSecurableObject, Lists.newArrayList(userName)); + verifyRangerSecurableObjectInRanger( + rangerSecurableObject, Lists.newArrayList(userName)); }); SecurableObject oldSecurableObject = @@ -558,7 +665,8 @@ public class RangerHiveIT { rangerAuthHivePlugin.translateOwner(oldMetadataObject).stream() .forEach( rangerSecurableObject -> { - verifyOwnerInRanger(rangerSecurableObject, Lists.newArrayList(userName)); + verifyRangerSecurableObjectInRanger( + rangerSecurableObject, Lists.newArrayList(userName)); }); // Delete the role @@ -568,7 +676,8 @@ public class RangerHiveIT { rangerAuthHivePlugin.translateOwner(oldMetadataObject).stream() .forEach( rangerSecurableObject -> { - verifyOwnerInRanger(rangerSecurableObject, Lists.newArrayList(userName)); + verifyRangerSecurableObjectInRanger( + rangerSecurableObject, Lists.newArrayList(userName)); }); } @@ -768,7 +877,8 @@ public class RangerHiveIT { rangerAuthHivePlugin.translateOwner(schema).stream() .forEach( rangerSecurableObject -> { - verifyOwnerInRanger(rangerSecurableObject, Lists.newArrayList(userName1)); + verifyRangerSecurableObjectInRanger( + rangerSecurableObject, Lists.newArrayList(userName1)); }); MetadataObject table = @@ -780,7 +890,8 @@ public class RangerHiveIT { rangerAuthHivePlugin.translateOwner(table).stream() .forEach( rangerSecurableObject -> { - verifyOwnerInRanger(rangerSecurableObject, Lists.newArrayList(userName2)); + verifyRangerSecurableObjectInRanger( + rangerSecurableObject, Lists.newArrayList(userName2)); }); String userName3 = "user3"; @@ -789,7 +900,7 @@ public class RangerHiveIT { rangerAuthHivePlugin.translateOwner(table).stream() .forEach( rangerSecurableObject -> { - verifyOwnerInRanger( + verifyRangerSecurableObjectInRanger( rangerSecurableObject, Lists.newArrayList(userName3), Lists.newArrayList(userName2)); @@ -801,7 +912,7 @@ public class RangerHiveIT { rangerAuthHivePlugin.translateOwner(table).stream() .forEach( rangerSecurableObject -> { - verifyOwnerInRanger( + verifyRangerSecurableObjectInRanger( rangerSecurableObject, null, Lists.newArrayList(userName1, userName2), @@ -814,7 +925,7 @@ public class RangerHiveIT { rangerAuthHivePlugin.translateOwner(table).stream() .forEach( rangerSecurableObject -> { - verifyOwnerInRanger( + verifyRangerSecurableObjectInRanger( rangerSecurableObject, null, Lists.newArrayList(userName1, userName2), @@ -834,7 +945,7 @@ public class RangerHiveIT { rangerAuthHivePlugin.translateOwner(metalake).stream() .forEach( rangerSecurableObject -> { - verifyOwnerInRanger( + verifyRangerSecurableObjectInRanger( rangerSecurableObject, null, null, @@ -852,7 +963,7 @@ public class RangerHiveIT { rangerAuthHivePlugin.translateOwner(catalog).stream() .forEach( rangerSecurableObject -> { - verifyOwnerInRanger( + verifyRangerSecurableObjectInRanger( rangerSecurableObject, null, null, @@ -913,7 +1024,7 @@ public class RangerHiveIT { rangerAuthHivePlugin.translateOwner(securableObject1).stream() .forEach( rangerSecurableObject -> { - verifyOwnerInRanger( + verifyRangerSecurableObjectInRanger( rangerSecurableObject, Lists.newArrayList(ownerName), null, null, null); }); @@ -1296,10 +1407,10 @@ public class RangerHiveIT { /** * Verify the Gravitino role in Ranger service * - * <p>metadataObject: the Gravitino securable object to be verified + * @param rangerSecurableObject: the Ranger securable object to be verified */ - private void verifyOwnerInRanger( - RangerMetadataObject metadataObject, + private void verifyRangerSecurableObjectInRanger( + RangerSecurableObject rangerSecurableObject, List<String> includeUsers, List<String> excludeUsers, List<String> includeGroups, @@ -1307,7 +1418,7 @@ public class RangerHiveIT { List<String> includeRoles, List<String> excludeRoles) { // Find policy by each metadata Object - String policyName = metadataObject.fullName(); + String policyName = rangerSecurableObject.fullName(); RangerPolicy policy; try { policy = RangerITEnv.rangerClient.getPolicy(RangerITEnv.RANGER_HIVE_REPO_NAME, policyName); @@ -1321,7 +1432,7 @@ public class RangerHiveIT { Assertions.assertTrue(policy.getPolicyLabels().contains(RangerHelper.MANAGED_BY_GRAVITINO)); // verify namespace - List<String> metaObjNamespaces = metadataObject.names(); + List<String> metaObjNamespaces = rangerSecurableObject.names(); List<String> rolePolicies = new ArrayList<>(); for (int i = 0; i < metaObjNamespaces.size(); i++) { rolePolicies.add( @@ -1336,113 +1447,126 @@ public class RangerHiveIT { } Assertions.assertEquals(metaObjNamespaces, rolePolicies); - policy.getPolicyItems().stream() - .filter( - policyItem -> { - // Filter Ranger policy item by Gravitino privilege - return policyItem.getAccesses().stream() - .anyMatch( - access -> { - return rangerAuthHivePlugin - .ownerMappingRule() - .contains(RangerPrivileges.valueOf(access.getType())); - }); - }) - .anyMatch( - policyItem -> { - if (includeUsers != null && !includeUsers.isEmpty()) { - if (!policyItem.getUsers().containsAll(includeUsers)) { - return false; - } - } - if (excludeUsers != null && !excludeUsers.isEmpty()) { - boolean containExcludeUser = - policyItem.getUsers().stream() - .anyMatch( - user -> { - return excludeUsers.contains(user); - }); - if (containExcludeUser) { - return false; - } - } - if (includeGroups != null && !includeGroups.isEmpty()) { - if (!policyItem.getGroups().containsAll(includeGroups)) { - return false; - } - } - if (excludeGroups != null && !excludeGroups.isEmpty()) { - boolean containExcludeGroup = - policyItem.getGroups().stream() - .anyMatch( - user -> { - return excludeGroups.contains(user); - }); - if (containExcludeGroup) { - return false; - } - } - if (includeRoles != null && !includeRoles.isEmpty()) { - if (!policyItem.getRoles().containsAll(includeRoles)) { - return false; - } - } - if (excludeRoles != null && !excludeRoles.isEmpty()) { - boolean containExcludeRole = - policyItem.getRoles().stream() - .anyMatch( - role -> { - return excludeRoles.contains(role); - }); - if (containExcludeRole) { - return false; - } + AtomicReference<List<RangerPolicy.RangerPolicyItem>> policyItems = new AtomicReference<>(); + rangerSecurableObject.privileges().stream() + .forEach( + privilege -> { + if (privilege.condition() == Privilege.Condition.ALLOW) { + policyItems.set(policy.getPolicyItems()); + } else { + policyItems.set(policy.getDenyPolicyItems()); } - return true; + policyItems.get().stream() + .filter( + policyItem -> { + // Filter Ranger policy item by Gravitino privilege + return policyItem.getAccesses().stream() + .anyMatch( + access -> { + return rangerAuthHivePlugin + .ownerMappingRule() + .contains(RangerPrivileges.valueOf(access.getType())); + }); + }) + .allMatch( + policyItem -> { + if (includeUsers != null && !includeUsers.isEmpty()) { + if (!policyItem.getUsers().containsAll(includeUsers)) { + return false; + } + } + if (excludeUsers != null && !excludeUsers.isEmpty()) { + boolean containExcludeUser = + policyItem.getUsers().stream() + .anyMatch( + user -> { + return excludeUsers.contains(user); + }); + if (containExcludeUser) { + return false; + } + } + if (includeGroups != null && !includeGroups.isEmpty()) { + if (!policyItem.getGroups().containsAll(includeGroups)) { + return false; + } + } + if (excludeGroups != null && !excludeGroups.isEmpty()) { + boolean containExcludeGroup = + policyItem.getGroups().stream() + .anyMatch( + user -> { + return excludeGroups.contains(user); + }); + if (containExcludeGroup) { + return false; + } + } + if (includeRoles != null && !includeRoles.isEmpty()) { + if (!policyItem.getRoles().containsAll(includeRoles)) { + return false; + } + } + if (excludeRoles != null && !excludeRoles.isEmpty()) { + boolean containExcludeRole = + policyItem.getRoles().stream() + .anyMatch( + role -> { + return excludeRoles.contains(role); + }); + if (containExcludeRole) { + return false; + } + } + return true; + }); }); } - private void verifyOwnerInRanger(RangerMetadataObject metadataObject) { - verifyOwnerInRanger(metadataObject, null, null, null, null, null, null); + private void verifyRangerSecurableObjectInRanger(RangerSecurableObject securableObject) { + verifyRangerSecurableObjectInRanger(securableObject, null, null, null, null, null, null); } - private void verifyOwnerInRanger(RangerMetadataObject metadataObject, List<String> includeUsers) { - verifyOwnerInRanger(metadataObject, includeUsers, null, null, null, null, null); + private void verifyRangerSecurableObjectInRanger( + RangerSecurableObject securableObject, List<String> includeUsers) { + verifyRangerSecurableObjectInRanger( + securableObject, includeUsers, null, null, null, null, null); } - private void verifyOwnerInRanger( - RangerMetadataObject metadataObject, List<String> includeUsers, List<String> excludeUsers) { - verifyOwnerInRanger(metadataObject, includeUsers, excludeUsers, null, null, null, null); + private void verifyRangerSecurableObjectInRanger( + RangerSecurableObject securableObject, List<String> includeUsers, List<String> excludeUsers) { + verifyRangerSecurableObjectInRanger( + securableObject, includeUsers, excludeUsers, null, null, null, null); } - private void verifyOwnerInRanger( - RangerMetadataObject metadataObject, + private void verifyRangerSecurableObjectInRanger( + RangerSecurableObject securableObject, List<String> includeUsers, List<String> excludeUsers, List<String> includeGroups) { - verifyOwnerInRanger( - metadataObject, includeUsers, excludeUsers, includeGroups, null, null, null); + verifyRangerSecurableObjectInRanger( + securableObject, includeUsers, excludeUsers, includeGroups, null, null, null); } - private void verifyOwnerInRanger( - RangerMetadataObject metadataObject, + private void verifyRangerSecurableObjectInRanger( + RangerSecurableObject securableObject, List<String> includeUsers, List<String> excludeUsers, List<String> includeGroups, List<String> excludeGroups) { - verifyOwnerInRanger( - metadataObject, includeUsers, excludeUsers, includeGroups, excludeGroups, null, null); + verifyRangerSecurableObjectInRanger( + securableObject, includeUsers, excludeUsers, includeGroups, excludeGroups, null, null); } - private void verifyOwnerInRanger( - RangerMetadataObject metadataObject, + private void verifyRangerSecurableObjectInRanger( + RangerSecurableObject securableObject, List<String> includeUsers, List<String> excludeUsers, List<String> includeGroups, List<String> excludeGroups, List<String> includeRoles) { - verifyOwnerInRanger( - metadataObject, + verifyRangerSecurableObjectInRanger( + securableObject, includeUsers, excludeUsers, includeGroups, diff --git a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerITEnv.java b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerITEnv.java index 1a5218b08..653d17202 100644 --- a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerITEnv.java +++ b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerITEnv.java @@ -25,7 +25,9 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; +import org.apache.gravitino.authorization.Privilege; import org.apache.gravitino.authorization.Role; import org.apache.gravitino.authorization.ranger.RangerAuthorizationHivePlugin; import org.apache.gravitino.authorization.ranger.RangerAuthorizationPlugin; @@ -443,26 +445,40 @@ public class RangerITEnv { LOG.error("Failed to get policy: " + securableObject.fullName()); throw new RuntimeException(e); } - boolean match = - policy.getPolicyItems().stream() - .filter( - policyItem -> { - // Filter Ranger policy item by Gravitino privilege - return policyItem.getAccesses().stream() - .anyMatch( - access -> { - return rangerSecurableObject - .privileges() - .contains( - RangerPrivileges.valueOf(access.getType())); + + AtomicReference<List<RangerPolicy.RangerPolicyItem>> policyItems = + new AtomicReference<>(); + rangerSecurableObject.privileges().stream() + .forEach( + privilege -> { + if (privilege.condition() == Privilege.Condition.ALLOW) { + policyItems.set(policy.getPolicyItems()); + } else { + policyItems.set(policy.getDenyPolicyItems()); + } + + boolean match = + policyItems.get().stream() + .filter( + policyItem -> { + // Filter Ranger policy item by Gravitino privilege + return policyItem.getAccesses().stream() + .allMatch( + access -> { + return rangerSecurableObject + .privileges() + .contains( + RangerPrivileges.valueOf( + access.getType())); + }); + }) + .allMatch( + policyItem -> { + // Verify role name in Ranger policy item + return policyItem.getRoles().contains(role.name()); }); - }) - .allMatch( - policyItem -> { - // Verify role name in Ranger policy item - return policyItem.getRoles().contains(role.name()); - }); - Assertions.assertTrue(match); + Assertions.assertTrue(match); + }); }); }); }