This is an automated email from the ASF dual-hosted git repository.
abhay 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 d4d4f65 RANGER-2379: Support for associating a tag service with
security zone and relevant authorization logic
d4d4f65 is described below
commit d4d4f655d76e902cc8ad611e5b56d66d4487218e
Author: Abhay Kulkarni <>
AuthorDate: Mon Apr 1 09:18:41 2019 -0700
RANGER-2379: Support for associating a tag service with security zone and
relevant authorization logic
---
.../ranger/plugin/errors/ValidationErrorCode.java | 1 +
.../validation/RangerSecurityZoneValidator.java | 89 +++++++++++++---------
.../policyengine/RangerPolicyEngineImpl.java | 14 ++++
.../policyengine/RangerPolicyRepository.java | 13 ++++
.../apache/ranger/plugin/util/ServicePolicies.java | 8 +-
.../RangerSecurityZoneValidatorTest.java | 6 ++
.../policyengine/test_policyengine_hdfs_zones.json | 3 +-
.../org/apache/ranger/db/XXSecurityZoneDao.java | 13 ++++
.../java/org/apache/ranger/rest/ServiceREST.java | 19 ++++-
.../main/resources/META-INF/jpa_named_queries.xml | 6 ++
10 files changed, 131 insertions(+), 41 deletions(-)
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
b/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
index 5a8fb5e..3111037 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
@@ -113,6 +113,7 @@ public enum ValidationErrorCode {
SECURITY_ZONE_VALIDATION_ERR_MISSING_SERVICES(3044, "No services specified
for security-zone:[{0}]"),
SECURITY_ZONE_VALIDATION_ERR_INTERNAL_ERROR(3045, "Internal Error:[{0}]"),
SECURITY_ZONE_VALIDATION_ERR_ZONE_RESOURCE_CONFLICT(3046, "Multiple
zones:[{0}] match resource:[{1}]"),
+ SECURITY_ZONE_VALIDATION_ERR_UNEXPECTED_RESOURCES(3047, "Tag service
[{0}], with non-empty resources, is associated with security zone"),
;
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 0e3b8f4..35e3ebb 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
@@ -33,7 +33,6 @@ import
org.apache.ranger.plugin.model.RangerSecurityZone.RangerSecurityZoneServi
import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
import
org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
import
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
-import org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.store.SecurityZoneStore;
import org.apache.ranger.plugin.store.ServiceStore;
@@ -523,60 +522,70 @@ public class RangerSecurityZoneValidator extends
RangerValidator {
boolean ret = true;
- if (CollectionUtils.isEmpty(securityZoneService.getResources())) {
- ValidationErrorCode error =
ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_MISSING_RESOURCES;
+ // Verify service with serviceName exists - get the service-type
+ RangerService service = getService(serviceName);
- failures.add(new ValidationFailureDetailsBuilder().field("security
zone
resources").isMissing().becauseOf(error.getMessage(serviceName)).errorCode(error.getErrorCode()).build());
+ if (service == null) {
+ ValidationErrorCode error =
ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_INVALID_SERVICE_NAME;
+
+ failures.add(new ValidationFailureDetailsBuilder().field("security
zone resource
service-name").becauseOf(error.getMessage(serviceName)).errorCode(error.getErrorCode()).build());
ret = false;
} else {
- // Verify service with serviceName exists - get the service-type
- RangerService service = getService(serviceName);
-
- if (service == null) {
- ValidationErrorCode error =
ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_INVALID_SERVICE_NAME;
+ RangerServiceDef serviceDef = getServiceDef(service.getType());
- failures.add(new
ValidationFailureDetailsBuilder().field("security zone resource
service-name").becauseOf(error.getMessage(serviceName)).errorCode(error.getErrorCode()).build());
+ if (serviceDef == null) {
+ ValidationErrorCode error =
ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_INVALID_SERVICE_TYPE;
+ failures.add(new
ValidationFailureDetailsBuilder().field("security zone resource
service-type").becauseOf(error.getMessage(service.getType())).errorCode(error.getErrorCode()).build());
ret = false;
} else {
- RangerServiceDef serviceDef = getServiceDef(service.getType());
+ String serviceType = serviceDef.getName();
- if (serviceDef == null ||
serviceDef.getName().equals(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME))
{
- ValidationErrorCode error =
ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_INVALID_SERVICE_TYPE;
-
- failures.add(new
ValidationFailureDetailsBuilder().field("security zone resource
service-type").becauseOf(error.getMessage(service.getType())).errorCode(error.getErrorCode()).build());
- ret = false;
+ if (StringUtils.equals(serviceType,
EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME)) {
+ if
(CollectionUtils.isNotEmpty(securityZoneService.getResources())) {
+ ValidationErrorCode error =
ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_UNEXPECTED_RESOURCES;
+ failures.add(new
ValidationFailureDetailsBuilder().field("security zone
resources").becauseOf(error.getMessage(serviceName)).errorCode(error.getErrorCode()).build());
+ ret = false;
+ }
} else {
- // For each resource-spec, verify that it forms valid
hierarchy for some policy-type
- for (Map<String, List<String>> resource :
securityZoneService.getResources()) {
- Set<String> resourceDefNames =
resource.keySet();
- RangerServiceDefHelper serviceDefHelper = new
RangerServiceDefHelper(serviceDef);
- boolean isValidHierarchy = false;
+ if
(CollectionUtils.isEmpty(securityZoneService.getResources())) {
+ ValidationErrorCode error =
ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_MISSING_RESOURCES;
+ failures.add(new
ValidationFailureDetailsBuilder().field("security zone
resources").isMissing().becauseOf(error.getMessage(serviceName)).errorCode(error.getErrorCode()).build());
+ ret = false;
+ } else {
+ // For each resource-spec, verify that it forms valid
hierarchy for some policy-type
+ for (Map<String, List<String>> resource :
securityZoneService.getResources()) {
+ Set<String> resourceDefNames = resource.keySet();
+ RangerServiceDefHelper serviceDefHelper = new
RangerServiceDefHelper(serviceDef);
+ boolean isValidHierarchy = false;
- for (int policyType : RangerPolicy.POLICY_TYPES) {
- Set<List<RangerServiceDef.RangerResourceDef>>
resourceHierarchies = serviceDefHelper.getResourceHierarchies(policyType,
resourceDefNames);
+ for (int policyType : RangerPolicy.POLICY_TYPES) {
+ Set<List<RangerServiceDef.RangerResourceDef>>
resourceHierarchies = serviceDefHelper.getResourceHierarchies(policyType,
resourceDefNames);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Size of resourceHierarchies for
resourceDefNames:[" + resourceDefNames +", policyType=" + policyType + "] = " +
resourceHierarchies.size());
- }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Size of resourceHierarchies for
resourceDefNames:[" + resourceDefNames + ", policyType=" + policyType + "] = "
+ resourceHierarchies.size());
+ }
- for (List<RangerServiceDef.RangerResourceDef>
resourceHierarchy : resourceHierarchies) {
+ for (List<RangerServiceDef.RangerResourceDef>
resourceHierarchy : resourceHierarchies) {
- if
(RangerDefaultPolicyResourceMatcher.isHierarchyValidForResources(resourceHierarchy,
resource)) {
- isValidHierarchy = true;
- break;
- } else {
- LOG.info("gaps found in resource, skipping
hierarchy:[" + resourceHierarchies + "]");
+ if
(RangerDefaultPolicyResourceMatcher.isHierarchyValidForResources(resourceHierarchy,
resource)) {
+ isValidHierarchy = true;
+ break;
+ } else {
+ LOG.info("gaps found in resource,
skipping hierarchy:[" + resourceHierarchies + "]");
+ }
}
}
- }
- if (!isValidHierarchy) {
- ValidationErrorCode error =
ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_INVALID_RESOURCE_HIERARCHY;
+ if (!isValidHierarchy) {
+ ValidationErrorCode error =
ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_INVALID_RESOURCE_HIERARCHY;
- failures.add(new
ValidationFailureDetailsBuilder().field("security zone resource
hierarchy").becauseOf(error.getMessage(serviceName,
resourceDefNames)).errorCode(error.getErrorCode()).build());
- ret = false;
- }
+ failures.add(new
ValidationFailureDetailsBuilder().field("security zone resource
hierarchy").becauseOf(error.getMessage(serviceName,
resourceDefNames)).errorCode(error.getErrorCode()).build());
+ ret = false;
+ }
+ /*
+ * Ignore this check. It should be possible to have
all wildcard resource in a zone if zone-admin so desires
+ *
boolean isValidResourceSpec =
isAnyNonWildcardResource(resource, failures);
if (!isValidResourceSpec) {
@@ -586,7 +595,9 @@ public class RangerSecurityZoneValidator extends
RangerValidator {
ret = false;
LOG.warn("RangerPolicyValidator.validateSecurityZoneService() : All wildcard
resource-values specified for service :[" + serviceName + "]");
}
+ */
+ }
}
}
}
@@ -599,6 +610,7 @@ public class RangerSecurityZoneValidator extends
RangerValidator {
return ret;
}
+ /*
private boolean isAnyNonWildcardResource(Map<String, List<String>>
resource, List<ValidationFailureDetails> failures) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("==>
RangerPolicyValidator.isAnyNonWildcardResource(%s, %s)", resource, failures));
@@ -628,4 +640,5 @@ public class RangerSecurityZoneValidator extends
RangerValidator {
}
return ret;
}
+ */
}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
index 9fe0531..5e10e0d 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
@@ -83,6 +83,7 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
private Map<String, RangerPolicyRepository> policyRepositories = new
HashMap<>();
private Map<String, RangerResourceTrie> trieMap;
+ private Map<String, String> zoneTagServiceMap;
public RangerPolicyEngineImpl(final RangerPolicyEngineImpl other,
ServicePolicies servicePolicies) {
@@ -1352,6 +1353,13 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
LOG.debug("==>
RangerPolicyEngineImpl.evaluateTagPolicies(" + request + ", policyType =" +
policyType + ", zoneName=" + zoneName + ", " + result + ")");
}
+ if (StringUtils.isNotEmpty(zoneName) && tagPolicyRepository !=
null && (zoneTagServiceMap == null || zoneTagServiceMap.get(zoneName) == null))
{
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Accessed resource is in a zone:[" +
zoneName + "] which is not associated with the tag-service:[" +
tagPolicyRepository.getServiceName() + "]. Evaluating unzoned tag policies of
this service");
+ }
+ zoneName = null;
+ }
+
Date accessTime = request.getAccessTime() != null ?
request.getAccessTime() : new Date();
Set<RangerTagForEval> tags =
RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
@@ -1527,6 +1535,8 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
RangerServiceDef serviceDef =
servicePolicies.getServiceDef();
List<RangerZoneResourceMatcher> matchers = new
ArrayList<>();
+ zoneTagServiceMap = new HashMap<>();
+
for (Map.Entry<String,
ServicePolicies.SecurityZoneInfo> securityZone : securityZones.entrySet()) {
String zoneName =
securityZone.getKey();
ServicePolicies.SecurityZoneInfo zoneDetails =
securityZone.getValue();
@@ -1565,6 +1575,10 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
if (LOG.isDebugEnabled()) {
LOG.debug("Built all matchers for zone:[" + zoneName +"]");
}
+
+ if (zoneDetails.getContainsAssociatedTagService()) {
+ zoneTagServiceMap.put(zoneName, zoneName);
+ }
}
if (LOG.isDebugEnabled()) {
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
index ff2a4b2..3a954f3 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
@@ -489,6 +489,19 @@ class RangerPolicyRepository {
List<RangerContextEnricher> getContextEnrichers() { return
contextEnrichers; }
+ List<RangerPolicyEvaluator> getPolicyEvaluators(int policyType) {
+ switch(policyType) {
+ case RangerPolicy.POLICY_TYPE_ACCESS:
+ return getPolicyEvaluators();
+ case RangerPolicy.POLICY_TYPE_DATAMASK:
+ return getDataMaskPolicyEvaluators();
+ case RangerPolicy.POLICY_TYPE_ROWFILTER:
+ return getRowFilterPolicyEvaluators();
+ default:
+ return getPolicyEvaluators();
+ }
+ }
+
List<RangerPolicyEvaluator> getPolicyEvaluators() {
return policyEvaluators;
}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java
b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java
index 2a80b25..3ce9212 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java
@@ -297,6 +297,7 @@ public class ServicePolicies implements
java.io.Serializable {
private List<HashMap<String, List<String>>> resources;
private List<RangerPolicy> policies;
private List<RangerPolicyDelta> policyDeltas;
+ private Boolean
containsAssociatedTagService;
public String getZoneName() {
return zoneName;
@@ -312,6 +313,8 @@ public class ServicePolicies implements
java.io.Serializable {
public List<RangerPolicyDelta> getPolicyDeltas() { return
policyDeltas; }
+ public Boolean getContainsAssociatedTagService() { return
containsAssociatedTagService; }
+
public void setZoneName(String zoneName) {
this.zoneName = zoneName;
}
@@ -326,12 +329,15 @@ public class ServicePolicies implements
java.io.Serializable {
public void setPolicyDeltas(List<RangerPolicyDelta>
policyDeltas) { this.policyDeltas = policyDeltas; }
+ public void setContainsAssociatedTagService(Boolean
containsAssociatedTagService) { this.containsAssociatedTagService =
containsAssociatedTagService; }
+
@Override
public String toString() {
return "zoneName=" + zoneName + ", "
+ "resources=" + resources + ", "
+ "policies=" + policies + ", "
- + "policyDeltas=" + policyDeltas
+ + "policyDeltas=" + policyDeltas + ", "
+ + "containsAssociatedTagService=" +
containsAssociatedTagService
;
}
}
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 fa167a7..8bc7767 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
@@ -170,12 +170,18 @@ public class RangerSecurityZoneValidatorTest {
@Test
public void
testValidateSecurityZoneWitoutResourcesForCreateThrowsError() throws Exception{
RangerSecurityZoneService rangerSecurityZoneService = new
RangerSecurityZoneService();
+ RangerService rangerSvc = getRangerService();
+ RangerServiceDef rangerSvcDef = rangerServiceDef();
+
Mockito.when(_store.getServiceDefByName("1")).thenReturn(rangerSvcDef);
+
Map<String, RangerSecurityZone.RangerSecurityZoneService> map =
new HashMap<String, RangerSecurityZone.RangerSecurityZoneService>();
map.put("hdfsSvc", rangerSecurityZoneService);
RangerSecurityZone suppliedSecurityZone =
getRangerSecurityZone();
suppliedSecurityZone.setServices(map);
Mockito.when(_store.getSecurityZone("MyZone")).thenReturn(null);
+
Mockito.when(_store.getServiceByName("hdfsSvc")).thenReturn(rangerSvc);
+
try {
rangerSecurityZoneValidator.validate(suppliedSecurityZone,
RangerValidator.Action.CREATE);
diff --git
a/agents-common/src/test/resources/policyengine/test_policyengine_hdfs_zones.json
b/agents-common/src/test/resources/policyengine/test_policyengine_hdfs_zones.json
index 6fcb66e..87ec493 100644
---
a/agents-common/src/test/resources/policyengine/test_policyengine_hdfs_zones.json
+++
b/agents-common/src/test/resources/policyengine/test_policyengine_hdfs_zones.json
@@ -461,7 +461,8 @@
]
}
],
- "zoneName": "finance"
+ "zoneName": "finance",
+ "containsAssociatedTagService": false
}
},
"tests":[
diff --git
a/security-admin/src/main/java/org/apache/ranger/db/XXSecurityZoneDao.java
b/security-admin/src/main/java/org/apache/ranger/db/XXSecurityZoneDao.java
index 9916496..c0f0666 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXSecurityZoneDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXSecurityZoneDao.java
@@ -23,6 +23,8 @@ import org.apache.ranger.entity.XXSecurityZone;
import org.springframework.stereotype.Service;
import javax.persistence.NoResultException;
+import java.util.Collections;
+import java.util.List;
@Service
public class XXSecurityZoneDao extends BaseDao<XXSecurityZone> {
@@ -60,4 +62,15 @@ public class XXSecurityZoneDao extends
BaseDao<XXSecurityZone> {
return null;
}
}
+ public List<String> findZonesByServiceName(String serviceName) {
+ if (serviceName == null) {
+ return Collections.emptyList();
+ }
+ try {
+ return
getEntityManager().createNamedQuery("XXSecurityZone.findByServiceName",
String.class)
+ .setParameter("serviceName", serviceName).getResultList();
+ } catch (NoResultException e) {
+ return Collections.emptyList();
+ }
+ }
}
diff --git
a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
index a60d4e0..6ddb359 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
@@ -3689,7 +3689,7 @@ public class ServiceREST {
}
}
}
- private static ServicePolicies
getUpdatedServicePoliciesForZones(ServicePolicies servicePolicies, Map<String,
RangerSecurityZone.RangerSecurityZoneService> securityZones) {
+ private ServicePolicies
getUpdatedServicePoliciesForZones(ServicePolicies servicePolicies, Map<String,
RangerSecurityZone.RangerSecurityZoneService> securityZones) {
final ServicePolicies ret;
@@ -3702,6 +3702,21 @@ public class ServiceREST {
ret.setPolicyVersion(servicePolicies.getPolicyVersion());
ret.setPolicyUpdateTime(servicePolicies.getPolicyUpdateTime());
+ // Get list of zones that associated
tag-service (if any) is associated with
+ List<String> zonesInAssociatedTagService = new
ArrayList<>();
+
+ String tagServiceName =
servicePolicies.getTagPolicies() != null ?
servicePolicies.getTagPolicies().getServiceName() : null;
+ if (StringUtils.isNotEmpty(tagServiceName)) {
+ try {
+ RangerService tagService =
svcStore.getServiceByName(tagServiceName);
+ if (tagService != null &&
tagService.getIsEnabled()) {
+
zonesInAssociatedTagService =
daoManager.getXXSecurityZoneDao().findZonesByServiceName(tagServiceName);
+ }
+ } catch (Exception exception) {
+ LOG.warn("Could not get service
associated with [" + tagServiceName + "]", exception);
+ }
+ }
+
Map<String, ServicePolicies.SecurityZoneInfo>
securityZonesInfo = new HashMap<>();
if
(CollectionUtils.isEmpty(servicePolicies.getPolicyDeltas())) {
@@ -3721,6 +3736,8 @@ public class ServiceREST {
securityZoneInfo.setPolicies(zonePolicies);
securityZoneInfo.setResources(entry.getValue().getResources());
+
securityZoneInfo.setContainsAssociatedTagService(zonesInAssociatedTagService.contains(entry.getKey()));
+
securityZonesInfo.put(entry.getKey(), securityZoneInfo);
}
diff --git a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
index eaa4e08..7e702c1 100644
--- a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
+++ b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
@@ -1309,6 +1309,12 @@
</query>
</named-query>
+ <named-query name="XXSecurityZone.findByServiceName">
+ <query>
+ select obj.name from XXSecurityZone obj where obj.id in
(select ref.zoneId from XXSecurityZoneRefService ref where ref.serviceName =
:serviceName)
+ </query>
+ </named-query>
+
<named-query name="XXSecurityZoneRefGroup.findByZoneId">
<query>
select obj from XXSecurityZoneRefGroup obj where obj.zoneId =
:zoneId