This is an automated email from the ASF dual-hosted git repository. madhan pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push: new 433da0281 RANGER-4299: fixed security-zone validator to handle wildcard resources at different hierarchies 433da0281 is described below commit 433da02817877d8100171da0d2f5d6e1c910a469 Author: Madhan Neethiraj <mad...@apache.org> AuthorDate: Thu Jun 22 11:34:55 2023 -0700 RANGER-4299: fixed security-zone validator to handle wildcard resources at different hierarchies --- .../validation/RangerSecurityZoneValidator.java | 26 +++++---------- .../RangerSecurityZoneValidatorTest.java | 38 ++++++++++++++++++++++ 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidator.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidator.java index 1a2b3160b..970055511 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidator.java @@ -322,17 +322,16 @@ public class RangerSecurityZoneValidator extends RangerValidator { LOG.debug(String.format("==> RangerSecurityZoneValidator.validateZoneServiceInAllZones(%s, %s, %s, %s)", zones, serviceName, serviceDef, failures)); } - boolean ret = true; + boolean ret = true; + RangerServiceDefHelper serviceDefHelper = new RangerServiceDefHelper(serviceDef); + List<RangerZoneResourceMatcher> matchers = new ArrayList<>(); + Set<String> resourceNames = new HashSet<>(); // For each zone, get list-of-resources corresponding to serviceName. // For each list-of-resources: // get one resource (this is a map of <String, List<String>>); convert it into map of <String, RangerPolicyResource>. excludes is always false, recursive true only for HDFS // build a subclass of RangerPolicyResourceEvaluator with id of zone, zoneName as a member, and RangerDefaultResourceMatcher as matcher. // add this to list-of-evaluators - - Map<String, List<RangerZoneResourceMatcher>> matchersForResourceDef = new HashMap<>(); - RangerServiceDefHelper serviceDefHelper = new RangerServiceDefHelper(serviceDef); - for (RangerSecurityZone zone : zones) { Map<String, RangerSecurityZoneService> zoneServices = zone.getServices(); RangerSecurityZoneService zoneService = zoneServices != null ? zoneServices.get(serviceName) : null; @@ -352,17 +351,12 @@ public class RangerSecurityZoneValidator extends RangerValidator { RangerPolicyResource policyResource = new RangerPolicyResource(resourceValues, false, EmbeddedServiceDefsUtil.isRecursiveEnabled(serviceDef, resourceDefName)); policyResources.put(resourceDefName, policyResource); - - if (matchersForResourceDef.get(resourceDefName) == null) { - matchersForResourceDef.put(resourceDefName, new ArrayList<>()); - } } RangerZoneResourceMatcher matcher = new RangerZoneResourceMatcher(zone.getName(), policyResources, serviceDefHelper); - for (String resourceDefName : resource.keySet()) { - matchersForResourceDef.get(resourceDefName).add(matcher); - } + matchers.add(matcher); + resourceNames.addAll(policyResources.keySet()); } } @@ -370,12 +364,10 @@ public class RangerSecurityZoneValidator extends RangerValidator { Map<String, RangerResourceTrie<RangerZoneResourceMatcher>> trieMap = new HashMap<>(); - for (Map.Entry<String, List<RangerZoneResourceMatcher>> entry : matchersForResourceDef.entrySet()) { - String resourceDefName = entry.getKey(); - List<RangerZoneResourceMatcher> matchers = entry.getValue(); - RangerResourceDef resourceDef = ServiceDefUtil.getResourceDef(serviceDef, resourceDefName); + for (String resourceName : resourceNames) { + RangerResourceDef resourceDef = ServiceDefUtil.getResourceDef(serviceDef, resourceName); - trieMap.put(resourceDefName, new RangerResourceTrie<>(resourceDef, matchers)); + trieMap.put(resourceName, new RangerResourceTrie<>(resourceDef, matchers)); } // For each zone, get list-of-resources corresponding to serviceName diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidatorTest.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidatorTest.java index ef95c69aa..1a1c30517 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidatorTest.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidatorTest.java @@ -443,6 +443,44 @@ public class RangerSecurityZoneValidatorTest { } } + @Test + public void test2ValidateHiveResourceInMultipleSecurityZones() throws Exception { + List<HashMap<String, List<String>>> zone1Resources = new ArrayList<>(); + List<HashMap<String, List<String>>> zone2Resources = new ArrayList<>(); + + zone1Resources.add(new HashMap<String, List<String>>() {{ put("database", Arrays.asList("*")); }}); + zone2Resources.add(new HashMap<String, List<String>>() {{ put("database", Arrays.asList("db1")); put("table", Arrays.asList("tbl1")); }}); + + RangerServiceDef svcDef = getHiveServiceDef(); + RangerService svc = getHiveService(); + RangerSecurityZoneService zone1HiveSvc = new RangerSecurityZoneService(zone1Resources); + RangerSecurityZoneService zone2HiveSvc = new RangerSecurityZoneService(zone2Resources); + + RangerSecurityZone zone1 = new RangerSecurityZone("zone1", Collections.singletonMap(svc.getName(), zone1HiveSvc), null, Arrays.asList("admin"), null, Arrays.asList("auditor"), null, "Zone 1"); + RangerSecurityZone zone2 = new RangerSecurityZone("zone2", Collections.singletonMap(svc.getName(), zone2HiveSvc), null, Arrays.asList("admin"), null, Arrays.asList("auditor"), null, "Zone 1"); + + zone1.setId(1L); + zone2.setId(2L); + + List<RangerSecurityZone> zones = new ArrayList<RangerSecurityZone>() {{ add(zone1); }}; + + Mockito.when(_store.getServiceByName(svc.getName())).thenReturn(svc); + Mockito.when(_store.getServiceDefByName(svc.getType())).thenReturn(svcDef); + Mockito.when(_store.getSecurityZone(2L)).thenReturn(zone2); + Mockito.when(_securityZoneStore.getSecurityZones(Mockito.any())).thenReturn(zones); + + try { + rangerSecurityZoneValidator.validate(zone2, RangerValidator.Action.UPDATE); + + Assert.assertFalse("security-zone update should have failed in validation", true); + } catch (Exception excp) { + String failureMessage = excp.getMessage(); + boolean hasResourceConflictError = StringUtils.contains(failureMessage, ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_ZONE_RESOURCE_CONFLICT.getErrorCode() + ""); + + Assert.assertTrue("validation failure message didn't include expected error code " + ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_ZONE_RESOURCE_CONFLICT.getErrorCode() + ". Failure message: " + excp.getMessage(), hasResourceConflictError); + } + } + private RangerService getRangerService() { Map<String, String> configs = new HashMap<String, String>(); configs.put("username", "servicemgr");