You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ab...@apache.org on 2018/03/05 06:27:12 UTC
[3/4] ranger git commit: RANGER-2000: Policy effective dates to
support time-bound and temporary authorization
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
----------------------------------------------------------------------
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 f8241c5..29ecfa8 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
@@ -39,6 +39,7 @@ import org.apache.ranger.plugin.util.ServicePolicies;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -656,7 +657,8 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
List<RangerPolicy> ret = new ArrayList<>();
- // TODO: run through evaluator in tagPolicyRepository as well
+
+ // TODO: run through evaluator in tagPolicyRepository as well
for (RangerPolicyEvaluator evaluator : policyRepository.getPolicyEvaluators()) {
RangerPolicy policy = evaluator.getPolicy();
@@ -680,42 +682,56 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
}
RangerAccessResult ret = createAccessResult(request, policyType);
+ Date accessTime = request.getAccessTime();
- if (ret != null && request != null) {
-
- if (hasTagPolicies()) {
+ if (ret != null && request != null) {
- evaluateTagPolicies(request, policyType, ret);
+ evaluateTagPolicies(request, policyType, ret);
- if (LOG.isDebugEnabled()) {
- if (ret.getIsAccessDetermined() && ret.getIsAuditedDetermined()) {
- LOG.debug("RangerPolicyEngineImpl.evaluatePoliciesNoAudit() - access and audit determined by tag policy. request=" + request + ", result=" + ret);
+ if (LOG.isDebugEnabled()) {
+ if (ret.getIsAccessDetermined() && ret.getIsAuditedDetermined()) {
+ if (!ret.getIsAllowed()) {
+ LOG.debug("RangerPolicyEngineImpl.evaluatePoliciesNoAudit() - audit determined and access denied by a tag policy. Higher priority resource policies will be evaluated to check for allow, request=" + request + ", result=" + ret);
+ } else {
+ LOG.debug("RangerPolicyEngineImpl.evaluatePoliciesNoAudit() - audit determined and access allowed by a tag policy. Same or higher priority resource policies will be evaluated to check for deny, request=" + request + ", result=" + ret);
}
}
}
boolean isAllowedByTags = ret.getIsAccessDetermined() && ret.getIsAllowed();
boolean isDeniedByTags = ret.getIsAccessDetermined() && !ret.getIsAllowed();
- boolean evaluateResourcePolicies = hasResourcePolicies() && (!isDeniedByTags || !ret.getIsAuditedDetermined());
+ boolean evaluateResourcePolicies = hasResourcePolicies();
if (evaluateResourcePolicies) {
-
boolean findAuditByResource = !ret.getIsAuditedDetermined();
boolean foundInCache = findAuditByResource && policyRepository.setAuditEnabledFromCache(request, ret);
- if(isAllowedByTags) {
- ret.setIsAccessDetermined(false); // discard allowed result by tag-policies, to evaluate resource policies for possible deny
- }
+ ret.setIsAccessDetermined(false); // discard result by tag-policies, to evaluate resource policies for possible override
List<RangerPolicyEvaluator> evaluators = policyRepository.getLikelyMatchPolicyEvaluators(request.getResource(), policyType);
for (RangerPolicyEvaluator evaluator : evaluators) {
+ if (!evaluator.isApplicable(accessTime)) {
+ continue;
+ }
+
+ if (isDeniedByTags) {
+ if (ret.getPolicyPriority() >= evaluator.getPolicyPriority()) {
+ ret.setIsAccessDetermined(true);
+ }
+ } else if (isAllowedByTags) {
+ if (ret.getPolicyPriority() > evaluator.getPolicyPriority()) {
+ ret.setIsAccessDetermined(true);
+ }
+ }
ret.incrementEvaluatedPoliciesCount();
evaluator.evaluate(request, ret);
- if (ret.getIsAllowed() && !evaluator.hasDeny()) { // all policies having deny have been evaluated
- ret.setIsAccessDetermined(true);
+ if (ret.getIsAllowed()) {
+ if (!evaluator.hasDeny()) { // No more deny policies left
+ ret.setIsAccessDetermined(true);
+ }
}
if (ret.getIsAuditedDetermined() && ret.getIsAccessDetermined()) {
@@ -724,6 +740,14 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
}
+ if (!ret.getIsAccessDetermined()) {
+ if (isDeniedByTags) {
+ ret.setIsAllowed(false);
+ } else if (isAllowedByTags) {
+ ret.setIsAllowed(true);
+ }
+ }
+
if(ret.getIsAllowed()) {
ret.setIsAccessDetermined(true);
}
@@ -746,15 +770,16 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
LOG.debug("==> RangerPolicyEngineImpl.evaluateTagPolicies(" + request + ", policyType =" + policyType + ", " + result + ")");
}
+ Date accessTime = request.getAccessTime();
+
Set<RangerTagForEval> tags = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
- List<PolicyEvaluatorForTag> policyEvaluators = tagPolicyRepository.getLikelyMatchPolicyEvaluators(tags, policyType);
+ List<PolicyEvaluatorForTag> policyEvaluators = tagPolicyRepository == null ? null : tagPolicyRepository.getLikelyMatchPolicyEvaluators(tags, policyType, accessTime);
if (CollectionUtils.isNotEmpty(policyEvaluators)) {
-
for (PolicyEvaluatorForTag policyEvaluator : policyEvaluators) {
-
RangerPolicyEvaluator evaluator = policyEvaluator.getEvaluator();
+
RangerTagForEval tag = policyEvaluator.getTag();
RangerAccessRequest tagEvalRequest = new RangerTagAccessRequest(tag, tagPolicyRepository.getServiceDef(), request);
@@ -771,8 +796,10 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
evaluator.evaluate(tagEvalRequest, tagEvalResult);
- if (tagEvalResult.getIsAllowed() && !evaluator.hasDeny()) { // all policies having deny have been evaluated
- tagEvalResult.setIsAccessDetermined(true);
+ if (tagEvalResult.getIsAllowed()) {
+ if (!evaluator.hasDeny()) { // No Deny policies left now
+ tagEvalResult.setIsAccessDetermined(true);
+ }
}
if (tagEvalResult.getIsAudited()) {
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
----------------------------------------------------------------------
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 23d1efa..088b729 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
@@ -43,6 +43,7 @@ import org.apache.ranger.plugin.util.ServicePolicies;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -286,10 +287,10 @@ class RangerPolicyRepository {
}
List<RangerPolicyEvaluator> getRowFilterPolicyEvaluators() {
- return rowFilterPolicyEvaluators;
+ return rowFilterPolicyEvaluators;
}
- List<PolicyEvaluatorForTag> getLikelyMatchPolicyEvaluators(Set<RangerTagForEval> tags, int policyType) {
+ List<PolicyEvaluatorForTag> getLikelyMatchPolicyEvaluators(Set<RangerTagForEval> tags, int policyType, Date accessTime) {
List<PolicyEvaluatorForTag> ret = Collections.EMPTY_LIST;
if (CollectionUtils.isNotEmpty(tags) && getServiceDef() != null) {
@@ -297,26 +298,34 @@ class RangerPolicyRepository {
ret = new ArrayList<PolicyEvaluatorForTag>();
for (RangerTagForEval tag : tags) {
- RangerAccessResource resource = new RangerTagResource(tag.getType(), getServiceDef());
- List<RangerPolicyEvaluator> evaluators = getLikelyMatchPolicyEvaluators(resource, policyType);
-
- if (CollectionUtils.isNotEmpty(evaluators)) {
- for (RangerPolicyEvaluator evaluator : evaluators) {
- ret.add(new PolicyEvaluatorForTag(evaluator, tag));
- }
- }
+ if (tag.isApplicable(accessTime)) {
+ RangerAccessResource resource = new RangerTagResource(tag.getType(), getServiceDef());
+ List<RangerPolicyEvaluator> evaluators = getLikelyMatchPolicyEvaluators(resource, policyType);
+
+ if (CollectionUtils.isNotEmpty(evaluators)) {
+ for (RangerPolicyEvaluator evaluator : evaluators) {
+ if (evaluator.isApplicable(accessTime)) {
+ ret.add(new PolicyEvaluatorForTag(evaluator, tag));
+ }
+ }
+ }
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Tag:[" + tag.getType() + "] is not applicable at accessTime:[" + accessTime +"]");
+ }
+ }
}
if (CollectionUtils.isNotEmpty(ret)) {
switch(policyType) {
case RangerPolicy.POLICY_TYPE_ACCESS:
- Collections.sort(ret, new PolicyEvaluatorForTag.PolicyEvalOrderComparator());
+ Collections.sort(ret, PolicyEvaluatorForTag.EVAL_ORDER_COMPARATOR);
break;
case RangerPolicy.POLICY_TYPE_DATAMASK:
- Collections.sort(ret, new PolicyEvaluatorForTag.PolicyNameComparator());
+ Collections.sort(ret, PolicyEvaluatorForTag.NAME_COMPARATOR);
break;
case RangerPolicy.POLICY_TYPE_ROWFILTER:
- Collections.sort(ret, new PolicyEvaluatorForTag.PolicyNameComparator());
+ Collections.sort(ret, PolicyEvaluatorForTag.NAME_COMPARATOR);
break;
default:
LOG.warn("Unknown policy-type:[" + policyType + "]. Ignoring..");
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
index d218c73..4e6ca2f 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
@@ -74,6 +74,11 @@ public abstract class RangerAbstractPolicyEvaluator implements RangerPolicyEvalu
}
@Override
+ public int getPolicyPriority() {
+ return policy != null && policy.getPolicyPriority() != null ? policy.getPolicyPriority() : RangerPolicy.POLICY_PRIORITY_NORMAL;
+ }
+
+ @Override
public RangerServiceDef getServiceDef() {
return serviceDef;
}
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java
index 349ab36..bfdf581 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java
@@ -18,8 +18,6 @@
*/
package org.apache.ranger.plugin.policyevaluator;
-
-
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
@@ -44,7 +42,7 @@ public class RangerDefaultDataMaskPolicyItemEvaluator extends RangerDefaultPolic
}
@Override
- public void updateAccessResult(RangerAccessResult result, RangerPolicyResourceMatcher.MatchType matchType, Long policyId) {
+ public void updateAccessResult(RangerAccessResult result, RangerPolicyResourceMatcher.MatchType matchType, RangerPolicy policy) {
RangerPolicyItemDataMaskInfo dataMaskInfo = getDataMaskInfo();
if (dataMaskInfo != null) {
@@ -54,6 +52,7 @@ public class RangerDefaultDataMaskPolicyItemEvaluator extends RangerDefaultPolic
result.setMaskType(dataMaskInfo.getDataMaskType());
result.setMaskCondition(dataMaskInfo.getConditionExpr());
result.setMaskedValue(dataMaskInfo.getValueExpr());
+ result.setPolicyPriority(policy.getPolicyPriority());
result.setPolicyId(policyId);
}
}
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
index 2b66c70..ffeea26 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
@@ -22,6 +22,7 @@ package org.apache.ranger.plugin.policyevaluator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -40,6 +41,7 @@ import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
+import org.apache.ranger.plugin.model.RangerValiditySchedule;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
import org.apache.ranger.plugin.policyengine.RangerAccessResource;
import org.apache.ranger.plugin.policyengine.RangerAccessResult;
@@ -61,6 +63,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
private static final Log PERF_POLICY_REQUEST_LOG = RangerPerfTracer.getPerfLogger("policy.request");
private RangerPolicyResourceMatcher resourceMatcher;
+ private List<RangerValidityScheduleEvaluator> validityScheduleEvaluators;
private List<RangerPolicyItemEvaluator> allowEvaluators;
private List<RangerPolicyItemEvaluator> denyEvaluators;
private List<RangerPolicyItemEvaluator> allowExceptionEvaluators;
@@ -117,6 +120,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
resourceMatcher.init();
if(policy != null) {
+ validityScheduleEvaluators = createValidityScheduleEvaluators(policy);
allowEvaluators = createPolicyItemEvaluators(policy, serviceDef, options, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW);
denyEvaluators = createPolicyItemEvaluators(policy, serviceDef, options, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY);
allowExceptionEvaluators = createPolicyItemEvaluators(policy, serviceDef, options, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS);
@@ -124,6 +128,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
dataMaskEvaluators = createDataMaskPolicyItemEvaluators(policy, serviceDef, options, policy.getDataMaskPolicyItems());
rowFilterEvaluators = createRowFilterPolicyItemEvaluators(policy, serviceDef, options, policy.getRowFilterPolicyItems());
} else {
+ validityScheduleEvaluators = Collections.<RangerValidityScheduleEvaluator>emptyList();
allowEvaluators = Collections.<RangerPolicyItemEvaluator>emptyList();
denyEvaluators = Collections.<RangerPolicyItemEvaluator>emptyList();
allowExceptionEvaluators = Collections.<RangerPolicyItemEvaluator>emptyList();
@@ -150,6 +155,32 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
}
}
+ @Override
+ public boolean isApplicable(Date accessTime) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerDefaultPolicyEvaluator.isApplicable(" + accessTime + ")");
+ }
+
+ boolean ret = false;
+
+ if (accessTime != null && CollectionUtils.isNotEmpty(validityScheduleEvaluators)) {
+ for (RangerValidityScheduleEvaluator evaluator : validityScheduleEvaluators) {
+ if (evaluator.isApplicable(accessTime.getTime())) {
+ ret = true;
+ break;
+ }
+ }
+ } else {
+ ret = true;
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerDefaultPolicyEvaluator.isApplicable(" + accessTime + ") : " + ret);
+ }
+
+ return ret;
+ }
+
@Override
public void evaluate(RangerAccessRequest request, RangerAccessResult result) {
if (LOG.isDebugEnabled()) {
@@ -373,7 +404,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
RangerPolicyItemEvaluator matchedPolicyItem = getMatchingPolicyItem(request, result);
if(matchedPolicyItem != null) {
- matchedPolicyItem.updateAccessResult(result, matchType, getPolicy().getId());
+ matchedPolicyItem.updateAccessResult(result, matchType, getPolicy());
}
if(LOG.isDebugEnabled()) {
@@ -583,6 +614,22 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
return ret;
}
+ private List<RangerValidityScheduleEvaluator> createValidityScheduleEvaluators(RangerPolicy policy) {
+ List<RangerValidityScheduleEvaluator> ret = null;
+
+ if (CollectionUtils.isNotEmpty(policy.getValiditySchedules())) {
+ ret = new ArrayList<>();
+
+ for (RangerValiditySchedule schedule : policy.getValiditySchedules()) {
+ ret.add(new RangerValidityScheduleEvaluator(schedule));
+ }
+ } else {
+ ret = Collections.<RangerValidityScheduleEvaluator>emptyList();
+ }
+
+ return ret;
+ }
+
private List<RangerPolicyItemEvaluator> createPolicyItemEvaluators(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options, int policyItemType) {
List<RangerPolicyItemEvaluator> ret = null;
List<RangerPolicyItem> policyItems = null;
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
index 9564565..312deef 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
@@ -350,16 +350,18 @@ public class RangerDefaultPolicyItemEvaluator extends RangerAbstractPolicyItemEv
}
@Override
- public void updateAccessResult(RangerAccessResult result, RangerPolicyResourceMatcher.MatchType matchType, Long policyId) {
+ public void updateAccessResult(RangerAccessResult result, RangerPolicyResourceMatcher.MatchType matchType, RangerPolicy policy) {
if(getPolicyItemType() == RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY) {
if(matchType != RangerPolicyResourceMatcher.MatchType.DESCENDANT) {
result.setIsAllowed(false);
+ result.setPolicyPriority(policy.getPolicyPriority());
result.setPolicyId(policyId);
result.setReason(getComments());
}
} else {
if(! result.getIsAllowed()) { // if access is not yet allowed by another policy
result.setIsAllowed(true);
+ result.setPolicyPriority(policy.getPolicyPriority());
result.setPolicyId(policyId);
result.setReason(getComments());
}
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java
index cacae5a..a6cea95 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java
@@ -18,7 +18,6 @@
*/
package org.apache.ranger.plugin.policyevaluator;
-
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemRowFilterInfo;
import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem;
@@ -43,7 +42,7 @@ public class RangerDefaultRowFilterPolicyItemEvaluator extends RangerDefaultPoli
}
@Override
- public void updateAccessResult(RangerAccessResult result, RangerPolicyResourceMatcher.MatchType matchType, Long policyId) {
+ public void updateAccessResult(RangerAccessResult result, RangerPolicyResourceMatcher.MatchType matchType, RangerPolicy policy) {
RangerPolicyItemRowFilterInfo rowFilterInfo = getRowFilterInfo();
if (rowFilterInfo != null) {
@@ -51,6 +50,7 @@ public class RangerDefaultRowFilterPolicyItemEvaluator extends RangerDefaultPoli
result.setIsAccessDetermined(true);
result.setFilterExpr(rowFilterInfo.getFilterExpr());
+ result.setPolicyPriority(policy.getPolicyPriority());
result.setPolicyId(policyId);
}
}
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
index 7a890b8..60b350e 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
@@ -22,6 +22,7 @@ package org.apache.ranger.plugin.policyevaluator;
import java.io.Serializable;
import java.util.Comparator;
+import java.util.Date;
import java.util.Map;
import java.util.Set;
@@ -38,6 +39,7 @@ import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceEvalua
public interface RangerPolicyEvaluator extends RangerPolicyResourceEvaluator {
Comparator<RangerPolicyEvaluator> EVAL_ORDER_COMPARATOR = new RangerPolicyEvaluator.PolicyEvalOrderComparator();
+ Comparator<RangerPolicyEvaluator> NAME_COMPARATOR = new RangerPolicyEvaluator.PolicyNameComparator();
String EVALUATOR_TYPE_AUTO = "auto";
String EVALUATOR_TYPE_OPTIMIZED = "optimized";
@@ -53,6 +55,10 @@ public interface RangerPolicyEvaluator extends RangerPolicyResourceEvaluator {
boolean hasDeny();
+ int getPolicyPriority();
+
+ boolean isApplicable(Date accessTime);
+
int getEvalOrder();
long getUsageCount();
@@ -84,6 +90,12 @@ public interface RangerPolicyEvaluator extends RangerPolicyResourceEvaluator {
class PolicyEvalOrderComparator implements Comparator<RangerPolicyEvaluator>, Serializable {
@Override
public int compare(RangerPolicyEvaluator me, RangerPolicyEvaluator other) {
+ int result = Integer.compare(other.getPolicyPriority(), me.getPolicyPriority());
+
+ return result == 0 ? compareNormal(me, other) : result;
+ }
+
+ private int compareNormal(RangerPolicyEvaluator me, RangerPolicyEvaluator other) {
int result;
if (me.hasDeny() && !other.hasDeny()) {
@@ -102,4 +114,27 @@ public interface RangerPolicyEvaluator extends RangerPolicyResourceEvaluator {
}
}
+ class PolicyNameComparator implements Comparator<RangerPolicyEvaluator>, Serializable {
+ @Override
+ public int compare(RangerPolicyEvaluator me, RangerPolicyEvaluator other) {
+ int result = Integer.compare(other.getPolicyPriority(), me.getPolicyPriority());
+
+ return result == 0 ? compareNormal(me, other) : result;
+ }
+
+ private int compareNormal(RangerPolicyEvaluator me, RangerPolicyEvaluator other) {
+ final int result;
+
+ if (me.hasDeny() && !other.hasDeny()) {
+ result = -1;
+ } else if (!me.hasDeny() && other.hasDeny()) {
+ result = 1;
+ } else {
+ result = me.getPolicy().getName().compareTo(other.getPolicy().getName());
+ }
+
+ return result;
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
index e486403..bd61cfd 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Set;
import org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator;
+import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
import org.apache.ranger.plugin.policyengine.RangerAccessResult;
@@ -65,6 +66,6 @@ public interface RangerPolicyItemEvaluator {
return Integer.compare(me.getEvalOrder(), other.getEvalOrder());
}
}
- void updateAccessResult(RangerAccessResult result, RangerPolicyResourceMatcher.MatchType matchType, Long policyId);
+ void updateAccessResult(RangerAccessResult result, RangerPolicyResourceMatcher.MatchType matchType, RangerPolicy policy);
}
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerValidityScheduleEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerValidityScheduleEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerValidityScheduleEvaluator.java
new file mode 100644
index 0000000..8f996d1
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerValidityScheduleEvaluator.java
@@ -0,0 +1,588 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.plugin.policyevaluator;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.model.RangerValidityRecurrence;
+import org.apache.ranger.plugin.model.RangerValiditySchedule;
+import org.apache.ranger.plugin.resourcematcher.ScheduledTimeAlwaysMatcher;
+import org.apache.ranger.plugin.resourcematcher.ScheduledTimeExactMatcher;
+import org.apache.ranger.plugin.resourcematcher.ScheduledTimeMatcher;
+import org.apache.ranger.plugin.resourcematcher.ScheduledTimeRangeMatcher;
+import org.apache.ranger.plugin.util.RangerPerfTracer;
+
+import javax.annotation.Nonnull;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.TimeZone;
+
+public class RangerValidityScheduleEvaluator {
+ private static final Log LOG = LogFactory.getLog(RangerValidityScheduleEvaluator.class);
+ private static final Log PERF_LOG = LogFactory.getLog("test.perf.RangerValidityScheduleEvaluator");
+
+ private final static TimeZone defaultTZ = TimeZone.getDefault();
+
+ private static final ThreadLocal<DateFormat> DATE_FORMATTER = new ThreadLocal<DateFormat>() {
+ @Override
+ protected DateFormat initialValue() {
+ return new SimpleDateFormat(RangerValiditySchedule.VALIDITY_SCHEDULE_DATE_STRING_SPECIFICATION);
+ }
+ };
+
+ private final Date startTime;
+ private final Date endTime;
+ private final String timeZone;
+ private final List<RangerRecurrenceEvaluator> recurrenceEvaluators = new ArrayList<>();
+
+ public RangerValidityScheduleEvaluator(@Nonnull RangerValiditySchedule validitySchedule) {
+ this(validitySchedule.getStartTime(), validitySchedule.getEndTime(), validitySchedule.getTimeZone(), validitySchedule.getRecurrences());
+ }
+
+ public RangerValidityScheduleEvaluator(String startTimeStr, String endTimeStr, String timeZone, List<RangerValidityRecurrence> recurrences) {
+ Date startTime = null;
+ Date endTime = null;
+
+ if (startTimeStr != null) {
+ try {
+ startTime = DATE_FORMATTER.get().parse(startTimeStr);
+ } catch (ParseException exception) {
+ LOG.error("Error parsing startTime:[" + startTimeStr + "]", exception);
+ }
+ }
+
+ if (endTimeStr != null) {
+ try {
+ endTime = DATE_FORMATTER.get().parse(endTimeStr);
+ } catch (ParseException exception) {
+ LOG.error("Error parsing endTime:[" + endTimeStr + "]", exception);
+ }
+ }
+
+ this.startTime = startTime;
+ this.endTime = endTime;
+ this.timeZone = timeZone;
+
+ if (CollectionUtils.isNotEmpty(recurrences)) {
+ for (RangerValidityRecurrence recurrence : recurrences) {
+ recurrenceEvaluators.add(new RangerRecurrenceEvaluator(recurrence));
+ }
+ }
+ }
+
+ public boolean isApplicable(long accessTime) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("===> isApplicable(accessTime=" + accessTime + ")");
+ }
+
+ boolean ret = false;
+ RangerPerfTracer perf = null;
+
+ if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+ perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "RangerValidityScheduleEvaluator.isApplicable(accessTime=" + accessTime + ")");
+ }
+
+ long startTimeInMSs = startTime == null ? 0 : startTime.getTime();
+ long endTimeInMSs = endTime == null ? 0 : endTime.getTime();
+
+ if (StringUtils.isNotBlank(timeZone)) {
+ TimeZone targetTZ = TimeZone.getTimeZone(timeZone);
+
+ if (startTimeInMSs > 0) {
+ startTimeInMSs = getAdjustedTime(startTimeInMSs, targetTZ);
+ }
+
+ if (endTimeInMSs > 0) {
+ endTimeInMSs = getAdjustedTime(endTimeInMSs, targetTZ);
+ }
+ }
+
+ if ((startTimeInMSs == 0 || accessTime >= startTimeInMSs) && (endTimeInMSs == 0 || accessTime <= endTimeInMSs)) {
+ if (CollectionUtils.isEmpty(recurrenceEvaluators)) {
+ ret = true;
+ } else {
+ Calendar now = new GregorianCalendar();
+ now.setTime(new Date(accessTime));
+
+ for (RangerRecurrenceEvaluator recurrenceEvaluator : recurrenceEvaluators) {
+ ret = recurrenceEvaluator.isApplicable(now);
+
+ if (ret) {
+ break;
+ }
+ }
+ }
+ }
+
+ RangerPerfTracer.log(perf);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<=== isApplicable(accessTime=" + accessTime + ") :" + ret);
+ }
+ return ret;
+ }
+
+ public static long getAdjustedTime(long localTime, TimeZone timeZone) {
+ long ret = localTime;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Input:[" + new Date(localTime) + ", target-timezone" + timeZone + "], default-timezone:[" + defaultTZ + "]");
+ }
+
+ if (!defaultTZ.equals(timeZone)) {
+ int targetOffset = timeZone.getOffset(localTime);
+ int defaultOffset = defaultTZ.getOffset(localTime);
+ int diff = defaultOffset - targetOffset;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Offset of target-timezone from UTC :[" + targetOffset + "]");
+ LOG.debug("Offset of default-timezone from UTC :[" + defaultOffset + "]");
+ LOG.debug("Difference between default-timezone and target-timezone :[" + diff + "]");
+ }
+
+ ret += diff;
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Output:[" + new Date(ret) + "]");
+ }
+
+ return ret;
+ }
+
+ static class RangerRecurrenceEvaluator {
+ private final List<ScheduledTimeMatcher> minutes = new ArrayList<>();
+ private final List<ScheduledTimeMatcher> hours = new ArrayList<>();
+ private final List<ScheduledTimeMatcher> daysOfMonth = new ArrayList<>();
+ private final List<ScheduledTimeMatcher> daysOfWeek = new ArrayList<>();
+ private final List<ScheduledTimeMatcher> months = new ArrayList<>();
+ private final List<ScheduledTimeMatcher> years = new ArrayList<>();
+ private final RangerValidityRecurrence recurrence;
+ private int intervalInMinutes = 0;
+
+
+ public RangerRecurrenceEvaluator(RangerValidityRecurrence recurrence) {
+ this.recurrence = recurrence;
+
+ if (recurrence != null) {
+ intervalInMinutes = RangerValidityRecurrence.ValidityInterval.getValidityIntervalInMinutes(recurrence.getInterval());
+
+ if (intervalInMinutes > 0) {
+ addScheduledTime(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.minute, minutes);
+ addScheduledTime(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.hour, hours);
+ addScheduledTime(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.dayOfMonth, daysOfMonth);
+ addScheduledTime(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.dayOfWeek, daysOfWeek);
+ addScheduledTime(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.month, months);
+ addScheduledTime(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.year, years);
+ }
+ }
+ }
+
+ public boolean isApplicable(Calendar now) {
+ boolean ret = false;
+
+ RangerPerfTracer perf = null;
+
+ if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+ perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "RangerRecurrenceEvaluator.isApplicable(accessTime=" + now.getTime().getTime() + ")");
+ }
+
+ if (recurrence != null && intervalInMinutes > 0) { // recurring schedule
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Access-Time:[" + now.getTime() + "]");
+ }
+
+ Calendar startOfInterval = getClosestPastEpoch(now);
+
+ if (startOfInterval != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Start-of-Interval:[" + startOfInterval.getTime() + "]");
+ }
+
+ Calendar endOfInterval = (Calendar) startOfInterval.clone();
+ endOfInterval.add(Calendar.MINUTE, recurrence.getInterval().getMinutes());
+ endOfInterval.add(Calendar.HOUR, recurrence.getInterval().getHours());
+ endOfInterval.add(Calendar.DAY_OF_MONTH, recurrence.getInterval().getDays());
+
+ endOfInterval.getTime(); // for recomputation
+ now.getTime();
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("End-of-Interval:[" + endOfInterval.getTime() + "]");
+ }
+
+ ret = startOfInterval.compareTo(now) <= 0 && endOfInterval.compareTo(now) >= 0;
+ }
+
+ } else {
+ ret = true;
+ }
+
+ RangerPerfTracer.log(perf);
+ return ret;
+ }
+
+ private void addScheduledTime(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec fieldSpec, List<ScheduledTimeMatcher> list) {
+ final String str = recurrence.getSchedule().getFieldValue(fieldSpec);
+ final boolean isMonth = fieldSpec == RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.month;
+
+ if (StringUtils.isNotBlank(str)) {
+ String[] specs = str.split(",");
+
+ for (String spec : specs) {
+ String[] range = spec.split("-");
+
+ if (range.length == 1) {
+ if (StringUtils.equals(range[0], RangerValidityRecurrence.RecurrenceSchedule.WILDCARD)) {
+ list.clear();
+ list.add(new ScheduledTimeAlwaysMatcher());
+
+ break;
+ } else {
+ list.add(new ScheduledTimeExactMatcher(Integer.valueOf(range[0]) - (isMonth ? 1 : 0)));
+ }
+ } else {
+ if (StringUtils.equals(range[0], RangerValidityRecurrence.RecurrenceSchedule.WILDCARD) || StringUtils.equals(range[1], RangerValidityRecurrence.RecurrenceSchedule.WILDCARD)) {
+ list.clear();
+ list.add(new ScheduledTimeAlwaysMatcher());
+
+ break;
+ } else {
+ list.add(new ScheduledTimeRangeMatcher(Integer.valueOf(range[0]) - (isMonth ? 1 : 0), Integer.valueOf(range[1]) - (isMonth ? 1 : 0)));
+ }
+ }
+ }
+
+ Collections.reverse(list);
+ }
+
+ }
+
+ /*
+ Given a Calendar object, get the closest, earlier Calendar object based on configured validity schedules.
+ Returns - a valid Calendar object. Throws exception if any errors during processing or no suitable Calendar object is found.
+ Description - Typically, a caller will call this with Calendar constructed with current time, and use returned object
+ along with specified interval to ensure that next schedule time is after the input Calendar.
+ Algorithm - This involves doing a Calendar arithmetic (subtraction) with borrow. The tricky parts are ensuring that
+ Calendar arithmetic yields a valid Calendar object.
+ - Start with minutes, and then hours.
+ - Must make sure that the later of the two Calendars - one computed with dayOfMonth, another computed with
+ dayOfWeek - is picked
+ - For dayOfMonth calculation, consider that months have different number of days
+ */
+
+ private class ValueWithBorrow {
+ int value;
+ boolean borrow;
+
+ ValueWithBorrow() {
+ }
+
+ ValueWithBorrow(int value) {
+ this(value, false);
+ }
+
+ ValueWithBorrow(int value, boolean borrow) {
+ this.value = value;
+ this.borrow = borrow;
+ }
+
+ void setValue(int value) {
+ this.value = value;
+ }
+
+ void setBorrow(boolean borrow) {
+ this.borrow = borrow;
+ }
+
+ int getValue() {
+ return value;
+ }
+
+ boolean getBorrow() {
+ return borrow;
+ }
+
+ @Override
+ public String toString() {
+ return "value=" + value + ", borrow=" + borrow;
+ }
+ }
+
+ private Calendar getClosestPastEpoch(Calendar current) {
+ Calendar ret = null;
+
+ try {
+ ValueWithBorrow input = new ValueWithBorrow();
+
+ input.setValue(current.get(Calendar.MINUTE));
+ input.setBorrow(false);
+ ValueWithBorrow closestMinute = getPastFieldValueWithBorrow(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.minute, minutes, input);
+
+ input.setValue(current.get(Calendar.HOUR_OF_DAY));
+ input.setBorrow(closestMinute.borrow);
+ ValueWithBorrow closestHour = getPastFieldValueWithBorrow(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.hour, hours, input);
+
+ Calendar dayOfMonthCalendar = getClosestDayOfMonth(current, closestMinute, closestHour);
+
+ Calendar dayOfWeekCalendar = getClosestDayOfWeek(current, closestMinute, closestHour);
+
+ ret = getEarlierCalendar(dayOfMonthCalendar, dayOfWeekCalendar);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("ClosestPastEpoch:[" + (ret != null ? ret.getTime() : null) + "]");
+ }
+
+ } catch (Exception e) {
+ LOG.error("Could not find ClosestPastEpoch, Exception=", e);
+ }
+ return ret;
+ }
+
+ private Calendar getClosestDayOfMonth(Calendar current, ValueWithBorrow closestMinute, ValueWithBorrow closestHour) throws Exception {
+ Calendar ret = null;
+ if (StringUtils.isNotBlank(recurrence.getSchedule().getDayOfMonth())) {
+ int initialDayOfMonth = current.get(Calendar.DAY_OF_MONTH);
+
+ int currentDayOfMonth = initialDayOfMonth, currentMonth = current.get(Calendar.MONTH), currentYear = current.get(Calendar.YEAR);
+ int maximumDaysInPreviousMonth = getMaximumValForPreviousMonth(current);
+
+ if (closestHour.borrow) {
+ initialDayOfMonth--;
+ Calendar dayOfMonthCalc = (GregorianCalendar) current.clone();
+ dayOfMonthCalc.add(Calendar.DAY_OF_MONTH, -1);
+ dayOfMonthCalc.getTime();
+ int previousDayOfMonth = dayOfMonthCalc.get(Calendar.DAY_OF_MONTH);
+ if (initialDayOfMonth < previousDayOfMonth) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Need to borrow from previous month, initialDayOfMonth:[" + initialDayOfMonth + "], previousDayOfMonth:[" + previousDayOfMonth + "], dayOfMonthCalc:[" + dayOfMonthCalc.getTime() + "]");
+ }
+ currentDayOfMonth = previousDayOfMonth;
+ currentMonth = dayOfMonthCalc.get(Calendar.MONTH);
+ currentYear = dayOfMonthCalc.get(Calendar.YEAR);
+ maximumDaysInPreviousMonth = getMaximumValForPreviousMonth(dayOfMonthCalc);
+ } else if (initialDayOfMonth == previousDayOfMonth) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("No need to borrow from previous month, initialDayOfMonth:[" + initialDayOfMonth + "], previousDayOfMonth:[" + previousDayOfMonth + "]");
+ }
+ } else {
+ LOG.error("Should not get here, initialDayOfMonth:[" + initialDayOfMonth + "], previousDayOfMonth:[" + previousDayOfMonth + "]");
+ throw new Exception("Should not get here, initialDayOfMonth:[" + initialDayOfMonth + "], previousDayOfMonth:[" + previousDayOfMonth + "]");
+ }
+ }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("currentDayOfMonth:[" + currentDayOfMonth + "], maximumDaysInPreviourMonth:[" + maximumDaysInPreviousMonth + "]");
+ }
+ ValueWithBorrow input = new ValueWithBorrow();
+ input.setValue(currentDayOfMonth);
+ input.setBorrow(false);
+ ValueWithBorrow closestDayOfMonth = null;
+ do {
+ int i = 0;
+ try {
+ closestDayOfMonth = getPastFieldValueWithBorrow(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.dayOfMonth, daysOfMonth, input, maximumDaysInPreviousMonth);
+ } catch (Exception e) {
+ i++;
+ Calendar c = (GregorianCalendar) current.clone();
+ c.set(Calendar.YEAR, currentYear);
+ c.set(Calendar.MONTH, currentMonth);
+ c.set(Calendar.DAY_OF_MONTH, currentDayOfMonth);
+ c.add(Calendar.MONTH, -i);
+ c.getTime();
+ currentMonth = c.get(Calendar.MONTH);
+ currentYear = c.get(Calendar.YEAR);
+ currentDayOfMonth = c.get(Calendar.DAY_OF_MONTH);
+ maximumDaysInPreviousMonth = getMaximumValForPreviousMonth(c);
+ input.setValue(currentDayOfMonth);
+ input.setBorrow(false);
+ }
+ } while (closestDayOfMonth == null);
+
+ // Build calendar for dayOfMonth
+ ret = new GregorianCalendar();
+ ret.set(Calendar.DAY_OF_MONTH, closestDayOfMonth.value);
+ ret.set(Calendar.HOUR_OF_DAY, closestHour.value);
+ ret.set(Calendar.MINUTE, closestMinute.value);
+ ret.set(Calendar.SECOND, 0);
+ ret.set(Calendar.MILLISECOND, 0);
+
+ ret.set(Calendar.YEAR, currentYear);
+
+ if (closestDayOfMonth.borrow) {
+ ret.set(Calendar.MONTH, currentMonth - 1);
+ } else {
+ ret.set(Calendar.MONTH, currentMonth);
+ }
+ ret.getTime(); // For recomputation
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Best guess using DAY_OF_MONTH:[" + ret.getTime() + "]");
+ }
+ }
+ return ret;
+ }
+
+ private Calendar getClosestDayOfWeek(Calendar current, ValueWithBorrow closestMinute, ValueWithBorrow closestHour) throws Exception {
+ Calendar ret = null;
+ if (StringUtils.isNotBlank(recurrence.getSchedule().getDayOfWeek())) {
+ ValueWithBorrow input = new ValueWithBorrow();
+
+ input.setValue(current.get(Calendar.DAY_OF_WEEK));
+ input.setBorrow(closestHour.borrow);
+
+
+ ValueWithBorrow closestDayOfWeek = getPastFieldValueWithBorrow(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.dayOfWeek, daysOfWeek, input);
+
+ int daysToGoback = closestHour.borrow ? 1 : 0;
+ int range = RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.dayOfWeek.maximum - RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.dayOfWeek.minimum + 1;
+
+ if (closestDayOfWeek.borrow) {
+ if (input.value - closestDayOfWeek.value != daysToGoback) {
+ daysToGoback = range + input.value - closestDayOfWeek.value;
+ }
+ } else {
+ daysToGoback = input.value - closestDayOfWeek.value;
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Need to go back [" + daysToGoback + "] days to match dayOfWeek");
+ }
+
+ ret = (GregorianCalendar) current.clone();
+ ret.set(Calendar.MINUTE, closestMinute.value);
+ ret.set(Calendar.HOUR_OF_DAY, closestHour.value);
+ ret.add(Calendar.DAY_OF_MONTH, (0 - daysToGoback));
+ ret.set(Calendar.SECOND, 0);
+ ret.set(Calendar.MILLISECOND, 0);
+
+ ret.getTime();
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Best guess using DAY_OF_WEEK:[" + ret.getTime() + "]");
+ }
+ }
+ return ret;
+
+ }
+
+ private int getMaximumValForPreviousMonth(Calendar current) {
+ Calendar cal = (Calendar) current.clone();
+ cal.add(Calendar.MONTH, -1);
+ cal.getTime(); // For recomputation
+
+ return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
+ }
+
+ private Calendar getEarlierCalendar(Calendar dayOfMonthCalendar, Calendar dayOfWeekCalendar) throws Exception {
+
+ Calendar withDayOfMonth = fillOutCalendar(dayOfMonthCalendar);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("dayOfMonthCalendar:[" + (withDayOfMonth != null ? withDayOfMonth.getTime() : null) + "]");
+ }
+
+ Calendar withDayOfWeek = fillOutCalendar(dayOfWeekCalendar);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("dayOfWeekCalendar:[" + (withDayOfWeek != null ? withDayOfWeek.getTime() : null) + "]");
+ }
+
+ if (withDayOfMonth != null && withDayOfWeek != null) {
+ return withDayOfMonth.after(withDayOfWeek) ? withDayOfMonth : withDayOfWeek;
+ } else if (withDayOfMonth == null) {
+ return withDayOfWeek;
+ } else {
+ return withDayOfMonth;
+ }
+ }
+
+ private Calendar fillOutCalendar(Calendar calendar) throws Exception {
+ Calendar ret = null;
+
+ if (calendar != null) {
+ ValueWithBorrow input = new ValueWithBorrow(calendar.get(Calendar.MONTH));
+ ValueWithBorrow closestMonth = getPastFieldValueWithBorrow(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.month, months, input);
+
+ input.setValue(calendar.get(Calendar.YEAR));
+ input.setBorrow(closestMonth.borrow);
+ ValueWithBorrow closestYear = getPastFieldValueWithBorrow(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec.year, years, input);
+
+ // Build calendar
+ ret = (Calendar) calendar.clone();
+ ret.set(Calendar.YEAR, closestYear.value);
+ ret.set(Calendar.MONTH, closestMonth.value);
+ ret.set(Calendar.SECOND, 0);
+
+ ret.getTime(); // for recomputation
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Filled-out-Calendar:[" + ret.getTime() + "]");
+ }
+ }
+ return ret;
+ }
+
+ private ValueWithBorrow getPastFieldValueWithBorrow(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec fieldSpec, List<ScheduledTimeMatcher> searchList, ValueWithBorrow input) throws Exception {
+ return getPastFieldValueWithBorrow(fieldSpec, searchList, input, fieldSpec.maximum);
+ }
+
+ private ValueWithBorrow getPastFieldValueWithBorrow(RangerValidityRecurrence.RecurrenceSchedule.ScheduleFieldSpec fieldSpec, List<ScheduledTimeMatcher> searchList, ValueWithBorrow input, int maximum) throws Exception {
+
+ ValueWithBorrow ret;
+ boolean borrow = false;
+
+ int value = input.value - (input.borrow ? 1 : 0);
+
+ if (CollectionUtils.isNotEmpty(searchList)) {
+ int range = fieldSpec.maximum - fieldSpec.minimum + 1;
+
+ for (int i = 0; i < range; i++, value--) {
+ if (value < fieldSpec.minimum) {
+ value = maximum;
+ borrow = true;
+ }
+ for (ScheduledTimeMatcher time : searchList) {
+ if (time.isMatch(value)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Found match in field:[" + fieldSpec + "], value:[" + value + "], borrow:[" + borrow + "], maximum:[" + maximum + "]");
+ }
+ return new ValueWithBorrow(value, borrow);
+ }
+ }
+ }
+ // Not found
+ throw new Exception("No match found in field:[" + fieldSpec + "] for [input=" + input + "]");
+ } else {
+ if (value < fieldSpec.minimum) {
+ value = maximum;
+ }
+ ret = new ValueWithBorrow(value, false);
+ }
+ return ret;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeAlwaysMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeAlwaysMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeAlwaysMatcher.java
new file mode 100644
index 0000000..414efcf
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeAlwaysMatcher.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.plugin.resourcematcher;
+
+public class ScheduledTimeAlwaysMatcher implements ScheduledTimeMatcher {
+ @Override
+ public boolean isMatch(int currentTime) {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeExactMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeExactMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeExactMatcher.java
new file mode 100644
index 0000000..da71040
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeExactMatcher.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.plugin.resourcematcher;
+
+public class ScheduledTimeExactMatcher implements ScheduledTimeMatcher {
+ private int scheduledTime;
+
+ public ScheduledTimeExactMatcher(int scheduledTime) {
+ this.scheduledTime = scheduledTime;
+ }
+ @Override
+ public boolean isMatch(int currentTime) {
+ return currentTime == scheduledTime;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeMatcher.java
new file mode 100644
index 0000000..3c388ca
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeMatcher.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.plugin.resourcematcher;
+
+public interface ScheduledTimeMatcher {
+ boolean isMatch(int targetTime);
+}
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeRangeMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeRangeMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeRangeMatcher.java
new file mode 100644
index 0000000..8c0bcd5
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ScheduledTimeRangeMatcher.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.plugin.resourcematcher;
+
+public class ScheduledTimeRangeMatcher implements ScheduledTimeMatcher {
+ private int lowerBound;
+ private int upperBound;
+
+ public ScheduledTimeRangeMatcher(int lowerBound, int upperBound) {
+ this.lowerBound = lowerBound;
+ this.upperBound = upperBound;
+ }
+ @Override
+ public boolean isMatch(int currentTime) {
+ return currentTime >= lowerBound && currentTime <= upperBound;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
index 1e3f145..4d2bc62 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
@@ -96,7 +96,8 @@ public class AbstractPredicateUtil {
addPredicateForPartialPolicyName(filter.getParam(SearchFilter.POLICY_NAME_PARTIAL), predicates);
addPredicateForResourceSignature(filter.getParam(SearchFilter.RESOURCE_SIGNATURE), predicates);
addPredicateForPolicyType(filter.getParam(SearchFilter.POLICY_TYPE), predicates);
- addPredicateForPartialPolicyLabels(filter.getParam(SearchFilter.POLICY_LABELS_PARTIAL), predicates);
+ addPredicateForPolicyPriority(filter.getParam(SearchFilter.POLICY_PRIORITY), predicates);
+ addPredicateForPartialPolicyLabels(filter.getParam(SearchFilter.POLICY_LABELS_PARTIAL), predicates);
}
public Comparator<RangerBaseModelObject> getSorter(SearchFilter filter) {
@@ -825,45 +826,86 @@ public class AbstractPredicateUtil {
return ret;
}
- private Predicate addPredicateForPartialPolicyLabels(final String policyLabels, List<Predicate> predicates) {
- if (StringUtils.isEmpty(policyLabels)) {
- return null;
- }
-
- Predicate ret = new Predicate() {
- @Override
- public boolean evaluate(Object object) {
- if (object == null) {
- return false;
- }
- boolean ret = false;
-
- if (object instanceof RangerPolicy) {
- RangerPolicy policy = (RangerPolicy) object;
- // exact match
+ private Predicate addPredicateForPartialPolicyLabels(final String policyLabels, List<Predicate> predicates) {
+ if (StringUtils.isEmpty(policyLabels)) {
+ return null;
+ }
+
+ Predicate ret = new Predicate() {
+ @Override
+ public boolean evaluate(Object object) {
+ if (object == null) {
+ return false;
+ }
+ boolean ret = false;
+
+ if (object instanceof RangerPolicy) {
+ RangerPolicy policy = (RangerPolicy) object;
+ // exact match
/*if (policy.getPolicyLabels().contains(policyLabels)) {
ret = true;
}*/
- /*partial match*/
- for (String label :policy.getPolicyLabels()){
- ret = StringUtils.containsIgnoreCase(label, policyLabels);
- if(ret){
- return ret;
- }
- }
-
- } else {
- ret = true;
- }
- return ret;
- }
- };
- if (predicates != null) {
- predicates.add(ret);
- }
-
- return ret;
- }
+ /*partial match*/
+ for (String label :policy.getPolicyLabels()){
+ ret = StringUtils.containsIgnoreCase(label, policyLabels);
+ if(ret){
+ return ret;
+ }
+ }
+
+ } else {
+ ret = true;
+ }
+ return ret;
+ }
+ };
+ if (predicates != null) {
+ predicates.add(ret);
+ }
+
+ return ret;
+ }
+
+ private Predicate addPredicateForPolicyPriority(final String policyPriority, List<Predicate> predicates) {
+ if(StringUtils.isEmpty(policyPriority)) {
+ return null;
+ }
+
+ Predicate ret = new Predicate() {
+ @Override
+ public boolean evaluate(Object object) {
+ if (object == null) {
+ return false;
+ }
+
+ boolean ret = true;
+
+ if (object instanceof RangerPolicy) {
+ RangerPolicy policy = (RangerPolicy) object;
+
+ Integer priority = policy.getPolicyPriority() != null ? policy.getPolicyPriority() : RangerPolicy.POLICY_PRIORITY_NORMAL;
+
+ if (priority == RangerPolicy.POLICY_PRIORITY_NORMAL) {
+ ret = StringUtils.equalsIgnoreCase(policyPriority, policy.POLICY_PRIORITY_NAME_NORMAL)
+ || StringUtils.equalsIgnoreCase(policyPriority, priority.toString());
+ } else if (priority == RangerPolicy.POLICY_PRIORITY_OVERRIDE) {
+ ret = StringUtils.equalsIgnoreCase(policyPriority, policy.POLICY_PRIORITY_NAME_OVERRIDE)
+ || StringUtils.equalsIgnoreCase(policyPriority, priority.toString());
+ } else {
+ ret = false;
+ }
+ }
+ return ret;
+ }
+
+ };
+
+ if(predicates != null) {
+ predicates.add(ret);
+ }
+
+ return ret;
+ }
public Predicate createPredicateForResourceSignature(final String policySignature) {
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
index 4a8f139..33f82dd 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
@@ -51,6 +51,7 @@ public class SearchFilter {
public static final String SORT_BY = "sortBy";
public static final String RESOURCE_SIGNATURE = "resourceSignature:"; // search
public static final String POLICY_TYPE = "policyType"; // search
+ public static final String POLICY_PRIORITY = "policyPriority"; // search
public static final String GUID = "guid"; //search
public static final String POLICY_LABEL = "policyLabel"; // search
public static final String POLICY_LABELS_PARTIAL = "policyLabelsPartial"; // search
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
----------------------------------------------------------------------
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
index f8c692b..97ae8a2 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
@@ -27,6 +27,7 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.ranger.audit.provider.AuditHandler;
import org.apache.ranger.audit.provider.AuditProviderFactory;
@@ -35,7 +36,11 @@ import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler;
import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerValiditySchedule;
+import org.apache.ranger.plugin.model.validation.RangerValidityScheduleValidator;
+import org.apache.ranger.plugin.model.validation.ValidationFailureDetails;
import org.apache.ranger.plugin.policyengine.TestPolicyEngine.PolicyEngineTestCase.TestData;
+import org.apache.ranger.plugin.policyevaluator.RangerValidityScheduleEvaluator;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
import org.apache.ranger.plugin.util.RangerRequestedResources;
import org.apache.ranger.plugin.util.ServicePolicies;
@@ -50,6 +55,8 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@@ -62,7 +69,7 @@ public class TestPolicyEngine {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
- gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSS-Z")
+ gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSSZ")
.setPrettyPrinting()
.registerTypeAdapter(RangerAccessRequest.class, new RangerAccessRequestDeserializer())
.registerTypeAdapter(RangerAccessResource.class, new RangerResourceDeserializer())
@@ -301,6 +308,12 @@ public class TestPolicyEngine {
runTestsFromResourceFiles(resourceFiles);
}
+ @Test
+ public void testPolicyEngine_temporary() {
+ String[] resourceFiles = {"/policyengine/test_policyengine_temporary.json"};
+
+ runTestsFromResourceFiles(resourceFiles);
+ }
@Test
public void testPolicyEngine_atlas() {
@@ -505,8 +518,88 @@ public class TestPolicyEngine {
public List<RangerPolicy> tagPolicies;
}
}
-
- static class RangerAccessRequestDeserializer implements JsonDeserializer<RangerAccessRequest> {
+
+ static class ValiditySchedulerTestResult {
+ boolean isValid;
+ int validationFailureCount;
+ boolean isApplicable;
+ }
+
+ static class ValiditySchedulerTestCase {
+ String name;
+ List<RangerValiditySchedule> validitySchedules;
+ Date accessTime;
+ ValiditySchedulerTestResult result;
+ }
+
+ @Test
+ public void testValiditySchedularInvalid() {
+ String resourceName = "/policyengine/validityscheduler/test-validity-schedules-invalid.json";
+
+ runValiditySchedulerTests(resourceName);
+ }
+
+ @Test
+ public void testValiditySchedularValid() {
+ String resourceName = "/policyengine/validityscheduler/test-validity-schedules-valid.json";
+
+ runValiditySchedulerTests(resourceName);
+ }
+
+ @Test
+ public void testValiditySchedularApplicable() {
+ String resourceName = "/policyengine/validityscheduler/test-validity-schedules-valid-and-applicable.json";
+
+ runValiditySchedulerTests(resourceName);
+ }
+
+ private void runValiditySchedulerTests(String resourceName) {
+ List<ValiditySchedulerTestCase> testCases = null;
+ InputStream inStream = this.getClass().getResourceAsStream(resourceName);
+ InputStreamReader reader = new InputStreamReader(inStream);
+ try {
+ Type listType = new TypeToken<List<ValiditySchedulerTestCase>>() {}.getType();
+ testCases = gsonBuilder.fromJson(reader, listType);
+ } catch (Exception e) {
+ assertFalse("Exception in reading validity-scheduler test cases.", true);
+ }
+
+ assertNotNull("TestCases are null!", testCases);
+
+
+ if (CollectionUtils.isNotEmpty(testCases)) {
+ for (ValiditySchedulerTestCase testCase : testCases) {
+ boolean isValid = true;
+ List<ValidationFailureDetails> validationFailures = new ArrayList<>();
+ boolean isApplicable = false;
+
+ List<RangerValiditySchedule> validatedSchedules = new ArrayList<>();
+
+ for (RangerValiditySchedule validitySchedule : testCase.validitySchedules) {
+ RangerValidityScheduleValidator validator = new RangerValidityScheduleValidator(validitySchedule);
+ RangerValiditySchedule validatedSchedule = validator.validate(validationFailures);
+ isValid = isValid && validatedSchedule != null;
+ if (isValid) {
+ validatedSchedules.add(validatedSchedule);
+ }
+ }
+ if (isValid) {
+ for (RangerValiditySchedule validSchedule : validatedSchedules) {
+ isApplicable = new RangerValidityScheduleEvaluator(validSchedule).isApplicable(testCase.accessTime.getTime());
+ if (isApplicable) {
+ break;
+ }
+ }
+ }
+
+ assertTrue(testCase.name, isValid == testCase.result.isValid);
+ assertTrue(testCase.name, isApplicable == testCase.result.isApplicable);
+ assertTrue(testCase.name + ", [" + validationFailures +"]", validationFailures.size() == testCase.result.validationFailureCount);
+ }
+ }
+ }
+
+ static class RangerAccessRequestDeserializer implements JsonDeserializer<RangerAccessRequest> {
@Override
public RangerAccessRequest deserialize(JsonElement jsonObj, Type type,
JsonDeserializationContext context) throws JsonParseException {
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/test/resources/log4j.xml
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/log4j.xml b/agents-common/src/test/resources/log4j.xml
index 558e27b..ddf57b9 100644
--- a/agents-common/src/test/resources/log4j.xml
+++ b/agents-common/src/test/resources/log4j.xml
@@ -78,12 +78,12 @@
-->
<logger name="org.apache.ranger.perf.policyresourcematcher" additivity="false">
- <level value="debug" />
+ <level value="warn" />
<appender-ref ref="ranger_perf_appender" />
</logger>
<root>
- <level value="warn" />
+ <level value="debug" />
<appender-ref ref="console" />
</root>
http://git-wip-us.apache.org/repos/asf/ranger/blob/844315cd/agents-common/src/test/resources/policyengine/test_policyengine_temporary.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_temporary.json b/agents-common/src/test/resources/policyengine/test_policyengine_temporary.json
new file mode 100644
index 0000000..17cf322
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_temporary.json
@@ -0,0 +1,347 @@
+{
+ "serviceName":"hdfsdev",
+ "serviceDef":{
+ "name":"hdfs",
+ "id":1,
+ "resources":[
+ {"name":"path","type":"path","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Resource Path","description":"HDFS file or directory path"}
+ ],
+ "options": {
+ "enableDenyAndExceptionsInPolicies":"true"
+ },
+ "accessTypes":[
+ {"name":"read","label":"Read"},
+ {"name":"write","label":"Write"},
+ {"name":"execute","label":"Execute"}
+ ]
+ },
+ "policies":[
+ {
+ "id": 99,
+ "name": "/resource: allow: groups=public",
+ "isEnabled": true,
+ "isAuditEnabled": true,
+ "resources": {
+ "path": { "values": [ "/resource" ], "isRecursive": true }
+ },
+ "policyItems": [
+ {
+ "accesses":[
+ {"type":"read"},
+ {"type": "execute" },
+ {"type":"write"}
+ ],
+ "groups" : ["public"]
+ }
+ ]
+ },
+ {
+ "id": 1,
+ "name": "/resource: allow: users=super; deny: user=user",
+ "isEnabled": true,
+ "isAuditEnabled": true,
+ "resources": {
+ "path": { "values": [ "/resource" ], "isRecursive": true }
+ },
+ "policyPriority":1,
+ "validitySchedules": [
+ {
+ "startTime": "2018/01/12 14:32:00",
+ "endTime": "2020/02/13 12:16:00",
+ "recurrences": [
+ {
+ "schedule": {
+ "minute": "0,10,20,30,40,50",
+ "hour": "*",
+ "dayOfMonth": "*",
+ "dayOfWeek": "5,7",
+ "month": "*",
+ "year": "2018"
+ },
+ "interval": {
+ "minutes": 4
+ }
+ }
+ ]
+ }
+ ],
+ "policyItems": [
+ {
+ "accesses":[
+ {"type":"read"},
+ {"type":"write"}
+ ],
+ "users":["super"]
+ }
+ ],
+ "allowExceptions":[ ],
+ "denyPolicyItems": [
+ {
+ "accesses": [
+ { "type": "read" },
+ { "type": "execute" },
+ { "type": "write" }
+ ],
+ "users": [ "user"]
+ }
+ ],
+ "denyExceptions":[ ]
+ },
+ {
+ "id": 2,
+ "name": "/unaudited-resource: allow: users=super deny: user=user",
+ "isEnabled": true,
+ "isAuditEnabled": false,
+ "resources": {
+ "path": { "values": [ "/unaudited-resource" ], "isRecursive": true }
+ },
+ "validitySchedules": [],
+ "policyItems": [
+ {
+ "accesses":[
+ {"type":"read" },
+ {"type":"write" }
+ ],
+ "users":["super"]
+ }
+ ],
+ "allowExceptions":[ ],
+ "denyPolicyItems": [
+ {
+ "accesses": [
+ { "type": "read" },
+ { "type": "execute" },
+ { "type": "write" }
+ ],
+ "users": [ "user" ]
+ }
+ ],
+ "denyExceptions":[ ]
+ }
+ ],
+
+ "tagPolicyInfo": {
+ "serviceName":"tagdev",
+ "serviceDef": {
+ "name": "tag",
+ "id": 100,
+ "resources": [
+ { "name": "tag", "type": "string", "level": 1, "mandatory": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": false, "ignoreCase": false }, "label": "TAG", "description": "TAG" }
+ ],
+ "accessTypes": [
+ { "name": "hdfs:read", "label": "hdfs:Read" },
+ { "name": "hdfs:write", "label": "hdfs:Write" },
+ { "name": "hdfs:execute", "label": "hdfs:Execute" }
+ ],
+ "contextEnrichers": [ ],
+ "policyConditions": [ ]
+ },
+ "tagPolicies":[
+ {
+ "id":101,
+ "name":"PII",
+ "isEnabled":true,
+ "isAuditEnabled":true,
+ "resources":{"tag":{"values":["PII"],"isRecursive":false}},
+ "policyItems":[
+ {
+ "accesses":[
+ {"type":"hdfs:read", "isAllowed":true},
+ {"type":"hdfs:write", "isAllowed":true}
+ ],
+ "users":["super"]
+ }
+ ],
+ "allowExceptions":[ ],
+ "denyPolicyItems":[
+ {
+ "accesses":[
+ {"type":"hdfs:read" },
+ {"type":"hdfs:write" }
+ ],
+ "users":["user"]
+ }
+ ],
+ "denyExceptions":[ ],
+ "policyPriority":1,
+ "validitySchedules": [
+ {
+ "startTime": "2018/01/12 14:32:00",
+ "endTime": "2020/02/13 12:16:00",
+ "recurrences": [
+ {
+ "schedule": {
+ "minute": "0,10,20,30,40,50",
+ "hour": "*",
+ "dayOfMonth": "*",
+ "dayOfWeek": "5,7",
+ "month": "*",
+ "year": "2018"
+ },
+ "interval": {
+ "minutes": 5
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id":102,
+ "name":"Unaudited-TAG",
+ "isEnabled":true,
+ "isAuditEnabled":false,
+ "resources":{"tag":{"values":["Unaudited-TAG"],"isRecursive":false}},
+ "validitySchedules": [],
+ "policyItems":[
+ {
+ "accesses":[
+ {"type":"hdfs:read" },
+ {"type":"hdfs:write" }
+ ],
+ "users":["super"]
+ }
+ ],
+ "allowExceptions":[ ],
+ "denyPolicyItems":[
+ {
+ "accesses":[
+ {"type":"hdfs:read" },
+ {"type":"hdfs:write" }
+ ],
+ "users":["user"]
+ }
+ ],
+ "denyExceptions":[ ]
+ }
+ ]
+ },
+ "tests":[
+ {
+ "name": "ALLOW 'read /resource' for u=user no tag temporarily",
+ "request": {
+ "resource": {
+ "elements": {
+ "path": "/resource"
+ }
+ },
+ "accessType": "read",
+ "user": "user",
+ "userGroups": [],
+ "requestData": "read /resource for u=user no tag temporarily",
+ "context": {
+ "TAGS": "[{\"type\":\"PII\",\"options\":{\"TAG_VALIDITY_PERIODS\":\"[{\\\"startTime\\\":\\\"2018/01/12 14:32:00\\\",\\\"endTime\\\":\\\"2020/02/13 12:16:00\\\",\\\"recurrences\\\":[{\\\"schedule\\\":{\\\"minute\\\":\\\"0,10,20,30,40,50\\\",\\\"hour\\\":\\\"*\\\",\\\"dayOfMonth\\\":\\\"*\\\",\\\"dayOfWeek\\\":\\\"5,7\\\",\\\"month\\\":\\\"*\\\",\\\"year\\\":\\\"2018\\\"},\\\"interval\\\":{\\\"days\\\":0,\\\"hours\\\":0,\\\"minutes\\\":4}}]}]\"}}]"
+ },
+ "accessTime": "20180127-10:06:00.000-0800"
+ },
+ "result": {"isAudited": true, "isAllowed": true, "policyId": 99}
+ },
+ {
+ "name": "DENY 'read /resource' for u=user tag temporarily",
+ "request": {
+ "resource": {
+ "elements": {
+ "path": "/resource"
+ }
+ },
+ "accessType": "read",
+ "user": "user",
+ "userGroups": [],
+ "requestData": "read /resource for u=user tag temporarily",
+ "context": {
+ "TAGS": "[{\"type\":\"PII\",\"options\":{\"TAG_VALIDITY_PERIODS\":\"[{\\\"startTime\\\":\\\"2018/01/12 14:32:00\\\",\\\"endTime\\\":\\\"2020/02/13 12:16:00\\\",\\\"recurrences\\\":[{\\\"schedule\\\":{\\\"minute\\\":\\\"0,10,20,30,40,50\\\",\\\"hour\\\":\\\"*\\\",\\\"dayOfMonth\\\":\\\"*\\\",\\\"dayOfWeek\\\":\\\"5,7\\\",\\\"month\\\":\\\"*\\\",\\\"year\\\":\\\"2018\\\"},\\\"interval\\\":{\\\"days\\\":0,\\\"hours\\\":0,\\\"minutes\\\":7}}]}]\"}}]"
+ },
+ "accessTime": "20180127-10:05:00.000-0800"
+ },
+ "result": {"isAudited": true, "isAllowed": false, "policyId": 101}
+ },
+ {
+ "name": "ALLOW 'read /resource' for u=user temporarily",
+ "request": {
+ "resource": {
+ "elements": {
+ "path": "/resource"
+ }
+ },
+ "accessType": "read",
+ "user": "user",
+ "userGroups": [],
+ "requestData": "read /resource temporarily",
+ "accessTime": "20180127-10:06:00.000-0800"
+ },
+ "result": {"isAudited": true, "isAllowed": true, "policyId": 99}
+ },
+ {
+ "name": "DENY 'read /resource' for u=user temporarily",
+ "request": {
+ "resource": {
+ "elements": {
+ "path": "/resource"
+ }
+ },
+ "accessType": "read",
+ "user": "user",
+ "userGroups": [],
+ "requestData": "read /resource temporarily",
+ "accessTime": "20180127-10:03:00.000-0800"
+ },
+ "result": {"isAudited": true, "isAllowed": false, "policyId": 1}
+ },
+ {
+ "name": "DENY 'read /resource' for u=user",
+ "request": {
+ "resource": { "elements": { "path": "/resource" } },
+ "accessType": "read",
+ "user": "user",
+ "userGroups": [ ],
+ "requestData": "read /resource for u=user",
+ "accessTime": "20180127-10:03:00.000-0800",
+ "context": {
+ "TAGS": "[{\"type\":\"PII\"}]"
+ }
+ },
+ "result": { "isAudited": true, "isAllowed": false, "policyId": 101 }
+ },
+ {
+ "name": "ALLOW 'read /resource' for u=super",
+ "request": {
+ "resource": { "elements": { "path": "/resource" } },
+ "accessType": "read",
+ "user": "super",
+ "userGroups": [ ],
+ "requestData": "read /resource for u=super",
+ "accessTime": "20180127-10:03:00.000-0800",
+ "context": {
+ "TAGS": "[{\"type\":\"PII\"}]"
+ }
+ },
+ "result": { "isAudited": true, "isAllowed": true, "policyId": 101 }
+ }
+ ,
+ {
+ "name": "ALLOW 'read /resource' for u=super",
+ "request": {
+ "resource": { "elements": { "path": "/resource" } },
+ "accessType": "read",
+ "user": "super",
+ "userGroups": [ ],
+ "requestData": "read /resource for u=super",
+ "accessTime": "20180127-10:03:00.000-0800"
+
+ },
+ "result": { "isAudited": true, "isAllowed": true, "policyId": 1 }
+ },
+ {
+ "name": "ALLOW 'read /resource' for u=any",
+ "request": {
+ "resource": { "elements": { "path": "/resource" } },
+ "accessType": "read",
+ "user": "any",
+ "userGroups": [ ],
+ "requestData": "read /resource for u=any"
+ },
+ "result": { "isAudited": true, "isAllowed": true, "policyId": 99 }
+ }
+
+ ]
+}