Repository: incubator-ranger Updated Branches: refs/heads/stack 565351c4c -> d4a79f50c
RANGER-203: initial implementation of the policy engine Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/580f2c7f Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/580f2c7f Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/580f2c7f Branch: refs/heads/stack Commit: 580f2c7fe7ff697833449886d6ada170bf70829f Parents: 565351c Author: Madhan Neethiraj <[email protected]> Authored: Wed Dec 31 01:27:46 2014 -0800 Committer: Madhan Neethiraj <[email protected]> Committed: Wed Dec 31 01:27:46 2014 -0800 ---------------------------------------------------------------------- .../ranger/plugin/model/RangerPolicy.java | 37 +- .../policyengine/RangerAccessRequest.java | 12 +- .../policyengine/RangerAccessRequestImpl.java | 134 ++++++-- .../plugin/policyengine/RangerAccessResult.java | 92 ++++- .../RangerDefaultResourceMatcher.java | 113 ------ .../policyengine/RangerPathResourceMatcher.java | 137 -------- .../policyengine/RangerPolicyEngineImpl.java | 112 +++++- .../plugin/policyengine/RangerResource.java | 4 + .../plugin/policyengine/RangerResourceImpl.java | 44 +++ .../policyengine/RangerResourceMatcher.java | 32 -- .../RangerAbstractPolicyEvaluator.java | 79 +++++ .../RangerDefaultPolicyEvaluator.java | 343 +++++++++++++++++++ .../policyevaluator/RangerPolicyEvaluator.java | 35 ++ .../RangerAbstractResourceMatcher.java | 166 +++++++++ .../RangerDefaultResourceMatcher.java | 123 +++++++ .../RangerPathResourceMatcher.java | 165 +++++++++ .../resourcematcher/RangerResourceMatcher.java | 32 ++ .../plugin/manager/TestServiceManager.java | 8 +- .../org/apache/ranger/common/ServiceUtil.java | 2 +- 19 files changed, 1323 insertions(+), 347 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java b/plugin-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java index 57b52cc..bab79a1 100644 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java @@ -518,14 +518,20 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria private String type = null; private Boolean isAllowed = null; + private Boolean isAudited = null; public RangerPolicyItemAccess() { - this(null, null); + this(null, null, null); + } + + public RangerPolicyItemAccess(String type) { + this(type, null, null); } - public RangerPolicyItemAccess(String type, Boolean value) { + public RangerPolicyItemAccess(String type, Boolean isAllowed, Boolean isAudited) { setType(type); - setValue(value); + setIsAllowed(isAllowed); + setIsAudited(isAudited); } /** @@ -543,17 +549,31 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria } /** - * @return the value + * @return the isAllowed */ - public Boolean getValue() { + public Boolean getIsAllowed() { return isAllowed; } /** - * @param value the value to set + * @param isAllowed the isAllowed to set + */ + public void setIsAllowed(Boolean isAllowed) { + this.isAllowed = isAllowed == null ? Boolean.TRUE : isAllowed; + } + + /** + * @return the isAudited + */ + public Boolean getIsAudited() { + return isAudited; + } + + /** + * @param isAudited the isAudited to set */ - public void setValue(Boolean isAllowed) { - this.isAllowed = isAllowed == null ? Boolean.FALSE : isAllowed; + public void setIsAudited(Boolean isAudited) { + this.isAudited = isAudited == null ? Boolean.TRUE : isAudited; } @Override @@ -569,6 +589,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria sb.append("RangerPolicyItemAccess={"); sb.append("type={").append(type).append("} "); sb.append("isAllowed={").append(isAllowed).append("} "); + sb.append("isAudited={").append(isAudited).append("} "); sb.append("}"); return sb; http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java index 1abc3f2..5082947 100644 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java @@ -20,15 +20,19 @@ package org.apache.ranger.plugin.policyengine; import java.util.Collection; +import java.util.Date; +import java.util.Map; public interface RangerAccessRequest { RangerResource getResource(); - Collection<String> getAccessTypes(); + String getAccessType(); - String getRequestUser(); + String getUser(); - Collection<String> getRequestUserGroups(); + Collection<String> getUserGroups(); + + Date getAccessTime(); String getClientIPAddress(); @@ -39,4 +43,6 @@ public interface RangerAccessRequest { String getRequestData(); String getSessionId(); + + Map<String, Object> getContext(); } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java index 5867e67..8e215da 100644 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java @@ -1,18 +1,48 @@ package org.apache.ranger.plugin.policyengine; import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; public class RangerAccessRequestImpl implements RangerAccessRequest { - private RangerResource resource = null; - private Collection<String> accessTypes = null; - private String requestUser = null; - private Collection<String> requestUserGroups = null; - private String clientIPAddress = null; - private String clientType = null; - private String action = null; - private String requestData = null; - private String sessionId = null; + private RangerResource resource = null; + private String accessType = null; + private String user = null; + private Collection<String> userGroups = null; + private Date accessTime = null; + private String clientIPAddress = null; + private String clientType = null; + private String action = null; + private String requestData = null; + private String sessionId = null; + private Map<String, Object> context = null; + + + public RangerAccessRequestImpl() { + this(null, null, null, null); + } + + public RangerAccessRequestImpl(RangerResource resource, String accessType, String user, Collection<String> userGroups) { + setResource(resource); + setAccessType(accessType); + setUser(user); + setUserGroups(userGroups); + + // set remaining fields to default value + setAccessTime(null); + setClientIPAddress(null); + setClientType(null); + setAction(null); + setRequestData(null); + setSessionId(null); + setContext(null); + } @Override public RangerResource getResource() { @@ -20,18 +50,23 @@ public class RangerAccessRequestImpl implements RangerAccessRequest { } @Override - public Collection<String> getAccessTypes() { - return accessTypes; + public String getAccessType() { + return accessType; } @Override - public String getRequestUser() { - return requestUser; + public String getUser() { + return user; } @Override - public Collection<String> getRequestUserGroups() { - return requestUserGroups; + public Collection<String> getUserGroups() { + return userGroups; + } + + @Override + public Date getAccessTime() { + return accessTime; } @Override @@ -59,21 +94,30 @@ public class RangerAccessRequestImpl implements RangerAccessRequest { return sessionId; } + @Override + public Map<String, Object> getContext() { + return context; + } + public void setResource(RangerResource resource) { this.resource = resource; } - public void setAccessTypes(Collection<String> accessTypes) { - this.accessTypes = accessTypes; + public void setAccessType(String accessType) { + this.accessType = accessType; + } + + public void setUser(String user) { + this.user = user; } - public void setRequestUser(String requestUser) { - this.requestUser = requestUser; + public void setUserGroups(Collection<String> userGroups) { + this.userGroups = (userGroups == null) ? new HashSet<String>() : userGroups; } - public void setRequestUserGroups(Collection<String> requestUserGroups) { - this.requestUserGroups = requestUserGroups; + public void setAccessTime(Date accessTime) { + this.accessTime = (accessTime == null) ? new Date() : accessTime; } public void setClientIPAddress(String clientIPAddress) { @@ -95,4 +139,52 @@ public class RangerAccessRequestImpl implements RangerAccessRequest { public void setSessionId(String sessionId) { this.sessionId = sessionId; } + + public void setContext(Map<String, Object> context) { + this.context = (context == null) ? new HashMap<String, Object>() : context; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerAccessRequestImpl={"); + + sb.append("resource={").append(resource).append("} "); + sb.append("accessType={").append(accessType).append("} "); + sb.append("user={").append(user).append("} "); + + sb.append("userGroups={"); + if(userGroups != null) { + for(String userGroup : userGroups) { + sb.append(userGroup).append(" "); + } + } + + sb.append("accessTime={").append(accessTime).append("} "); + sb.append("clientIPAddress={").append(clientIPAddress).append("} "); + sb.append("clientType={").append(clientType).append("} "); + sb.append("action={").append(action).append("} "); + sb.append("requestData={").append(requestData).append("} "); + sb.append("sessionId={").append(sessionId).append("} "); + + + sb.append("context={"); + if(context != null) { + for(Map.Entry<String, Object> e : context.entrySet()) { + sb.append(e.getKey()).append("={").append(e.getValue()).append("} "); + } + } + sb.append("} "); + + sb.append("}"); + + return sb; + } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java index bf17e86..0735bd2 100644 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java @@ -23,40 +23,110 @@ package org.apache.ranger.plugin.policyengine; public class RangerAccessResult { private RangerAccessRequest request; private boolean isAllowed; - private boolean auditAccess; + private boolean isAudited; private long policyId; private String reason; - public RangerAccessResult(RangerAccessRequest request, boolean isAllowed, boolean auditAccess) { - this(request, isAllowed, auditAccess, -1, null); + public RangerAccessResult(RangerAccessRequest request) { + this(request, false, false, -1, null); } - public RangerAccessResult(RangerAccessRequest request, boolean isAllowed, boolean auditAccess, long policyId, String reason) { - this.request = request; - this.isAllowed = isAllowed; - this.auditAccess = auditAccess; - this.policyId = policyId; - this.reason = reason; + public RangerAccessResult(RangerAccessRequest request, boolean isAllowed, boolean isAudited) { + this(request, isAllowed, isAudited, -1, null); } + public RangerAccessResult(RangerAccessRequest request, boolean isAllowed, boolean isAudited, long policyId, String reason) { + this.request = request; + this.isAllowed = isAllowed; + this.isAudited = isAudited; + this.policyId = policyId; + this.reason = reason; + } + + /** + * @return the request + */ public RangerAccessRequest getRequest() { return request; } + /** + * @return the isAllowed + */ public boolean isAllowed() { return isAllowed; } - public boolean auditAccess() { - return auditAccess; + /** + * @param isAllowed the isAllowed to set + */ + public void setAllowed(boolean isAllowed) { + this.isAllowed = isAllowed; + } + + /** + * @return the auditAccess + */ + public boolean isAudited() { + return isAudited; + } + + /** + * @param auditAccess the auditAccess to set + */ + public void setAudited(boolean isAudited) { + this.isAudited = isAudited; } + /** + * @return the policyId + */ public long getPolicyId() { return policyId; } + /** + * @param policyId the policyId to set + */ + public void setPolicyId(long policyId) { + this.policyId = policyId; + } + + /** + * @return the reason + */ public String getReason() { return reason; } + + /** + * @param reason the reason to set + */ + public void setReason(String reason) { + this.reason = reason; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerAccessResult={"); + + sb.append("request={").append(request).append("} "); + sb.append("isAllowed={").append(isAllowed).append("} "); + sb.append("isAudited={").append(isAudited).append("} "); + sb.append("policyId={").append(policyId).append("} "); + sb.append("reason={").append(reason).append("} "); + + sb.append("}"); + + return sb; + } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerDefaultResourceMatcher.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerDefaultResourceMatcher.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerDefaultResourceMatcher.java deleted file mode 100644 index 735b5b9..0000000 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerDefaultResourceMatcher.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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.policyengine; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; - -public class RangerDefaultResourceMatcher implements RangerResourceMatcher { - private List<String> policyValues = null; - private boolean policyIsExcludes = false; - private boolean optIgnoreCase = false; - private boolean optWildCard = false; - - @Override - public void init(RangerPolicyResource policyResource, String options) { - this.policyValues = new ArrayList<String>(); - this.policyIsExcludes = false; - this.optIgnoreCase = false; - this.optWildCard = false; - - if(options != null) { - for(String optionStr : options.split(OPTIONS_SEP)) { - if(optionStr == null) { - continue; - } - optionStr = optionStr.trim(); - - if(!optionStr.isEmpty()) { - String[] optionArr = optionStr.split("="); - - String optionName = optionArr.length > 0 ? optionArr[0].trim() : null; - String optionValue = optionArr.length > 1 ? optionArr[1].trim() : null; - - if(optionName == null) { - continue; - } - - if(optionName.equals(OPTION_IGNORE_CASE)) { - optIgnoreCase = (optionValue == null || optionValue.isEmpty()) ? true : Boolean.parseBoolean(optionValue); - } else if(optionName.equals(OPTION_WILD_CARD)) { - optWildCard = (optionValue == null || optionValue.isEmpty()) ? true : Boolean.parseBoolean(optionValue); - } else { - // log warning: unrecognized option.. - } - } - } - } - - - if(policyResource != null) { - policyIsExcludes = policyResource.getIsExcludes(); - - if(policyResource.getValues() != null && !policyResource.getValues().isEmpty()) { - for(String policyValue : policyResource.getValues()) { - if(policyValue == null) { - continue; - } - - if(optIgnoreCase) { - policyValue = policyValue.toLowerCase(); - } - - policyValues.add(policyValue); - } - } - } - } - - @Override - public boolean isMatch(String value) { - boolean ret = false; - - if(value != null) { - if(optIgnoreCase) { - value = value.toLowerCase(); - } - - for(String policyValue : policyValues) { - ret = optWildCard ? value.matches(policyValue) : value.equals(policyValue); - - if(ret) { - break; - } - } - } - - if(policyIsExcludes) { - ret = !ret; - } - - return ret; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPathResourceMatcher.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPathResourceMatcher.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPathResourceMatcher.java deleted file mode 100644 index 67e1887..0000000 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPathResourceMatcher.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 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.policyengine; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.io.FilenameUtils; -import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; - -public class RangerPathResourceMatcher implements RangerResourceMatcher { - private List<String> policyValues = null; - private boolean policyIsExcludes = false; - private boolean policyIsRecursive = false; - private boolean optIgnoreCase = false; - private boolean optWildCard = false; - - @Override - public void init(RangerPolicyResource policyResource, String options) { - this.policyValues = new ArrayList<String>(); - this.policyIsExcludes = false; - this.policyIsRecursive = false; - this.optIgnoreCase = false; - this.optWildCard = false; - - if(options != null) { - for(String optionStr : options.split(OPTIONS_SEP)) { - if(optionStr == null) { - continue; - } - optionStr = optionStr.trim(); - - if(!optionStr.isEmpty()) { - String[] optionArr = optionStr.split("="); - - String optionName = optionArr.length > 0 ? optionArr[0].trim() : null; - String optionValue = optionArr.length > 1 ? optionArr[1].trim() : null; - - if(optionName == null) { - continue; - } - - if(optionName.equals(OPTION_IGNORE_CASE)) { - optIgnoreCase = (optionValue == null || optionValue.isEmpty()) ? true : Boolean.parseBoolean(optionValue); - } else if(optionName.equals(OPTION_WILD_CARD)) { - optWildCard = (optionValue == null || optionValue.isEmpty()) ? true : Boolean.parseBoolean(optionValue); - } else { - // log warning: unrecognized option.. - } - } - } - } - - if(policyResource != null) { - policyIsExcludes = policyResource.getIsExcludes(); - policyIsRecursive = policyResource.getIsRecursive(); - - if(policyResource.getValues() != null && !policyResource.getValues().isEmpty()) { - for(String policyValue : policyResource.getValues()) { - if(policyValue == null) { - continue; - } - - if(optIgnoreCase) { - policyValue = policyValue.toLowerCase(); - } - - policyValues.add(policyValue); - } - } - } - } - - @Override - public boolean isMatch(String value) { - boolean ret = false; - - if(value != null) { - if(optIgnoreCase) { - value = value.toLowerCase(); - } - - for(String policyValue : policyValues) { - if(policyIsRecursive) { - ret = optWildCard ? isRecursiveWildCardMatch(value, policyValue) : value.startsWith(policyValue); - } else { - ret = optWildCard ? FilenameUtils.wildcardMatch(value, policyValue) : value.equals(policyValue); - } - - if(ret) { - break; - } - } - } - - if(policyIsExcludes) { - ret = !ret; - } - - return ret; - } - - private static boolean isRecursiveWildCardMatch(String pathToCheck, String wildcardPath) { - if (pathToCheck != null) { - StringBuilder sb = new StringBuilder() ; - for(String p : pathToCheck.split(File.separator) ) { - sb.append(p) ; - boolean matchFound = FilenameUtils.wildcardMatch(sb.toString(), wildcardPath) ; - if (matchFound) { - return true ; - } - sb.append(File.separator) ; - } - sb = null; - } - return false; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java index 49cf364..b2324c5 100644 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java @@ -19,35 +19,36 @@ package org.apache.ranger.plugin.policyengine; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.ranger.plugin.manager.ServiceDefManager; import org.apache.ranger.plugin.manager.ServiceManager; import org.apache.ranger.plugin.model.RangerPolicy; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; import org.apache.ranger.plugin.model.RangerService; import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; +import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator; public class RangerPolicyEngineImpl implements RangerPolicyEngine { private static final Log LOG = LogFactory.getLog(RangerPolicyEngineImpl.class); - private String svcName = null; - private ServiceDefManager sdMgr = null; - private ServiceManager svcMgr = null; - private RangerService service = null; - private RangerServiceDef serviceDef = null; - private List<RangerPolicy> policies = null; + private String svcName = null; + private List<RangerPolicyEvaluator> policyEvaluators = null; + public RangerPolicyEngineImpl() { if(LOG.isDebugEnabled()) { LOG.debug("==> RangerPolicyEngine()"); } - sdMgr = new ServiceDefManager(); - svcMgr = new ServiceManager(); - if(LOG.isDebugEnabled()) { LOG.debug("<== RangerPolicyEngine()"); } @@ -58,13 +59,18 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine { LOG.debug("==> RangerPolicyEngine.init(" + serviceName + ")"); } - svcName = serviceName; - service = svcMgr.getByName(svcName); + svcName = serviceName; + policyEvaluators = new ArrayList<RangerPolicyEvaluator>(); + + ServiceManager svcMgr = new ServiceManager(); + RangerService service = svcMgr.getByName(svcName); if(service == null) { LOG.error(svcName + ": service not found"); } else { - serviceDef = sdMgr.getByName(service.getType()); + ServiceDefManager sdMgr = new ServiceDefManager(); + + RangerServiceDef serviceDef = sdMgr.getByName(service.getType()); if(serviceDef == null) { String msg = service.getType() + ": service-def not found"; @@ -74,10 +80,20 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine { throw new Exception(msg); } - policies = svcMgr.getPolicies(service.getId()); + List<RangerPolicy> policies = svcMgr.getPolicies(service.getId()); + + if(policies != null) { + for(RangerPolicy policy : policies) { + RangerPolicyEvaluator evaluator = getPolicyEvaluator(policy, serviceDef); + + if(evaluator != null) { + policyEvaluators.add(evaluator); + } + } + } if(LOG.isDebugEnabled()) { - LOG.debug("found " + (policies == null ? 0 : policies.size()) + " policies in service '" + svcName + "'"); + LOG.debug("found " + (policyEvaluators == null ? 0 : policyEvaluators.size()) + " policies in service '" + svcName + "'"); } } @@ -86,15 +102,48 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine { } } + private RangerPolicyEvaluator getPolicyEvaluator(RangerPolicy policy, RangerServiceDef serviceDef) { + RangerPolicyEvaluator ret = null; + + // TODO: instantiate policy-matcher + + return ret; + } + @Override public RangerAccessResult isAccessAllowed(RangerAccessRequest request) { - // TODO Auto-generated method stub - return null; + RangerAccessResult ret = null; + + for(RangerPolicyEvaluator evaluator : policyEvaluators) { + ret = evaluator.evaluate(request); + + if(ret != null) { + break; + } + } + + if(ret == null) { + ret = new RangerAccessResult(request); + + ret.setAllowed(Boolean.FALSE); + ret.setAudited(Boolean.FALSE); + } + + return ret; } @Override public void isAccessAllowed(List<RangerAccessRequest> requests, List<RangerAccessResult> results) { - // TODO Auto-generated method stub + if(requests != null && results != null) { + results.clear(); + + for(int i = 0; i < requests.size(); i++) { + RangerAccessRequest request = requests.get(i); + RangerAccessResult result = isAccessAllowed(request); + + results.add(result); + } + } } @Override @@ -108,4 +157,33 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine { // TODO Auto-generated method stub } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerPolicyEngineImpl={"); + + sb.append("svcName={").append(svcName).append("} "); + + sb.append("policyEvaluators={"); + if(policyEvaluators != null) { + for(RangerPolicyEvaluator policyEvaluator : policyEvaluators) { + if(policyEvaluator != null) { + sb.append(policyEvaluator).append(" "); + } + } + } + sb.append("} "); + + sb.append("}"); + + return sb; + } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResource.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResource.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResource.java index b07f42a..9e10e40 100644 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResource.java +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResource.java @@ -24,6 +24,10 @@ import java.util.List; public interface RangerResource { public abstract String getOwnerUser(); + public abstract boolean elementExists(String type); + + public abstract boolean elementIsSingleValued(String type); + public abstract String getElementValue(String type); public abstract List<String> getElementValues(String type); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceImpl.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceImpl.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceImpl.java index 5d5a81d..da5010b 100644 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceImpl.java +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceImpl.java @@ -24,6 +24,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; + public class RangerResourceImpl implements RangerResource { private String ownerUser = null; @@ -39,6 +42,18 @@ public class RangerResourceImpl implements RangerResource { } @Override + public boolean elementExists(String type) { + return elements != null && elements.containsKey(type); + } + + @Override + public boolean elementIsSingleValued(String type) { + Object val = (elements != null && elements.containsKey(type)) ? elements.get(type) : null; + + return val == null || (val instanceof String) || (((List<?>)val).size() <= 1); + } + + @Override public String getElementValue(String type) { String ret = null; @@ -134,4 +149,33 @@ public class RangerResourceImpl implements RangerResource { } } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerResourceImpl={"); + + sb.append("ownerUser={").append(ownerUser).append("} "); + + sb.append("elements={"); + if(elements != null) { + for(Map.Entry<String, Object> e : elements.entrySet()) { + sb.append(e.getKey()).append("={"); + sb.append(e.getValue()); + sb.append("} "); + } + } + sb.append("} "); + + sb.append("}"); + + return sb; + } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceMatcher.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceMatcher.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceMatcher.java deleted file mode 100644 index bfe3605..0000000 --- a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceMatcher.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.policyengine; - -import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; - -public interface RangerResourceMatcher { - public final String OPTIONS_SEP = ";"; - public final String OPTION_IGNORE_CASE = "ignoreCase"; - public final String OPTION_WILD_CARD = "wildCard"; - - void init(RangerPolicyResource policyResource, String options); - - boolean isMatch(String value); -} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java new file mode 100644 index 0000000..36273eb --- /dev/null +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java @@ -0,0 +1,79 @@ +/* + * 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.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ranger.plugin.model.RangerPolicy; +import org.apache.ranger.plugin.model.RangerServiceDef; + + +public abstract class RangerAbstractPolicyEvaluator implements RangerPolicyEvaluator { + private static final Log LOG = LogFactory.getLog(RangerAbstractPolicyEvaluator.class); + + private RangerPolicy policy = null; + private RangerServiceDef serviceDef = null; + + + @Override + public void init(RangerPolicy policy, RangerServiceDef serviceDef) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerAbstractPolicyEvaluator.init(" + policy + ", " + serviceDef + ")"); + } + + this.policy = policy; + this.serviceDef = serviceDef; + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerAbstractPolicyEvaluator.init(" + policy + ", " + serviceDef + ")"); + } + } + + @Override + public RangerPolicy getPolicy() { + return policy; + } + + @Override + public RangerServiceDef getServiceDef() { + return serviceDef; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerAbstractPolicyEvaluator={"); + + sb.append("policy={").append(policy).append("} "); + sb.append("serviceDef={").append(serviceDef).append("} "); + + sb.append("}"); + + return sb; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java new file mode 100644 index 0000000..2e7d691 --- /dev/null +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java @@ -0,0 +1,343 @@ +/* + * 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 java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ranger.plugin.model.RangerPolicy; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; +import org.apache.ranger.plugin.policyengine.RangerAccessRequest; +import org.apache.ranger.plugin.policyengine.RangerAccessResult; +import org.apache.ranger.plugin.policyengine.RangerResource; +import org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher; +import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher; + + +public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator { + private static final Log LOG = LogFactory.getLog(RangerDefaultPolicyEvaluator.class); + + private List<ResourceDefMatcher> matchers = null; + + @Override + public void init(RangerPolicy policy, RangerServiceDef serviceDef) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.init()"); + } + + super.init(policy, serviceDef); + + this.matchers = new ArrayList<ResourceDefMatcher>(); + + if(policy != null && policy.getResources() != null) { + for(Map.Entry<String, RangerPolicyResource> e : policy.getResources().entrySet()) { + String resourceType = e.getKey(); + RangerPolicyResource policyResource = e.getValue(); + RangerResourceDef resourceDef = getResourceDef(resourceType); + + RangerResourceMatcher matcher = createResourceMatcher(resourceDef, policyResource); + + if(matcher != null) { + matchers.add(new ResourceDefMatcher(resourceDef, matcher)); + } else { + // TODO: ERROR: no matcher found for resourceType + } + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyEvaluator.init()"); + } + } + + @Override + public RangerAccessResult evaluate(RangerAccessRequest request) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.evaluate(" + request + ")"); + } + + RangerAccessResult ret = null; + RangerPolicy policy = getPolicy(); + + if(request != null && policy != null && matchResource(request.getResource())) { + for(RangerPolicyItem policyItem : policy.getPolicyItems()) { + RangerPolicyItemAccess access = getAccess(policyItem, request.getAccessType()); + + if(access != null && access.getIsAllowed()) { + if(matchUserGroup(policyItem, request.getUser(), request.getUserGroups())) { + if(matchCustomConditions(policyItem, request)) { + ret = new RangerAccessResult(request); + + ret.setPolicyId(policy.getId()); + ret.setAllowed(access.getIsAllowed()); + ret.setAudited(access.getIsAudited()); + + break; + } + } + } + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyEvaluator.evaluate(" + request + "): " + ret); + } + + return ret; + } + + protected boolean matchResource(RangerResource resource) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.matchResource(" + resource + ")"); + } + + boolean ret = false; + + if(matchers != null && !matchers.isEmpty()) { + ret = true; + + for(ResourceDefMatcher matcher : matchers) { + String resourceType = matcher.getResourceType(); + + if(resource.elementIsSingleValued(resourceType)) { + String resourceValue = resource.getElementValue(resourceType); + + ret = matcher.isMatch(resourceValue); + } else { + List<String> resourceValues = resource.getElementValues(resourceType); + + ret = matcher.isMatch(resourceValues); + } + + if(! ret) { + break; + } + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyEvaluator.matchResource(" + resource + "): " + ret); + } + + return ret; + } + + protected boolean matchUserGroup(RangerPolicyItem policyItem, String user, Collection<String> groups) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.matchUserGroup(" + policyItem + ", " + user + ", " + groups + ")"); + } + + boolean ret = false; + + if(policyItem != null && user != null && policyItem.getUsers() != null) { + ret = policyItem.getUsers().contains(user); + } + + if(!ret && policyItem != null && groups != null && policyItem.getGroups() != null) { + ret = !Collections.disjoint(policyItem.getGroups(), groups); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyEvaluator.matchUserGroup(" + policyItem + ", " + user + ", " + groups + "): " + ret); + } + + return ret; + } + + protected boolean matchCustomConditions(RangerPolicyItem policyItem, RangerAccessRequest request) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.matchCustomConditions(" + policyItem + ", " + request + ")"); + } + + boolean ret = false; + + // TODO: + ret = true; + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyEvaluator.matchCustomConditions(" + policyItem + ", " + request + "): " + ret); + } + + return ret; + } + + protected RangerPolicyItemAccess getAccess(RangerPolicyItem policyItem, String accessType) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.getAccess(" + policyItem + ", " + accessType + ")"); + } + + RangerPolicyItemAccess ret = null; + + if(policyItem != null && accessType != null && policyItem.getAccesses() != null) { + for(RangerPolicyItemAccess access : policyItem.getAccesses()) { + if(accessType.equalsIgnoreCase(access.getType())) { + ret = access; + + break; + } + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyEvaluator.getAccess(" + policyItem + ", " + accessType + "): " + ret); + } + + return ret; + } + + protected RangerResourceDef getResourceDef(String resourceType) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.getResourceDef(" + resourceType + ")"); + } + + RangerResourceDef ret = null; + + RangerServiceDef serviceDef = getServiceDef(); + + if(serviceDef != null && resourceType != null) { + for(RangerResourceDef resourceDef : serviceDef.getResources()) { + if(resourceType.equalsIgnoreCase(resourceDef.getName())) { + ret = resourceDef; + + break; + } + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyEvaluator.getResourceDef(" + resourceType + "): " + ret); + } + + return ret; + } + + protected RangerResourceMatcher createResourceMatcher(RangerResourceDef resourceDef, RangerPolicyResource resource) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.createResourceMatcher(" + resourceDef + ", " + resource + ")"); + } + + RangerResourceMatcher ret = null; + + String clsName = resourceDef != null ? resourceDef.getMatcher() : null; + String options = resourceDef != null ? resourceDef.getMatcherOptions() : null; + + if(clsName == null || clsName.isEmpty()) { + ret = new RangerDefaultResourceMatcher(); + } else { + try { + @SuppressWarnings("unchecked") + Class<RangerResourceMatcher> matcherClass = (Class<RangerResourceMatcher>)Class.forName(clsName); + + ret = matcherClass.newInstance(); + } catch(ClassNotFoundException excp) { + // TODO: ERROR + excp.printStackTrace(); + } catch (InstantiationException excp) { + // TODO: ERROR + excp.printStackTrace(); + } catch (IllegalAccessException excp) { + // TODO: ERROR + excp.printStackTrace(); + } + } + + if(ret != null) { + ret.init(resource, options); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.createResourceMatcher(" + resourceDef + ", " + resource + "): " + ret); + } + + return ret; + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerDefaultPolicyEvaluator={"); + + super.toString(sb); + + sb.append("matchers={"); + if(matchers != null) { + for(ResourceDefMatcher matcher : matchers) { + sb.append("{"); + matcher.toString(sb); + sb.append("} "); + } + } + sb.append("} "); + + sb.append("}"); + + return sb; + } + + class ResourceDefMatcher { + RangerResourceDef resourceDef = null; + RangerResourceMatcher resourceMatcher = null; + + ResourceDefMatcher(RangerResourceDef resourceDef, RangerResourceMatcher resourceMatcher) { + this.resourceDef = resourceDef; + this.resourceMatcher = resourceMatcher; + } + + String getResourceType() { + return resourceDef.getName(); + } + + boolean isMatch(String value) { + return resourceMatcher.isMatch(value); + } + + boolean isMatch(Collection<String> values) { + boolean ret = false; + + if(values == null || values.isEmpty()) { + ret = resourceMatcher.isMatch(null); + } else { + for(String value : values) { + ret = resourceMatcher.isMatch(value); + + if(! ret) { + break; + } + } + } + + return ret; + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("resourceDef={").append(resourceDef).append("} "); + sb.append("resourceMatcher={").append(resourceMatcher).append("} "); + + return sb; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java new file mode 100644 index 0000000..333275e --- /dev/null +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java @@ -0,0 +1,35 @@ +/* + * 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.ranger.plugin.model.RangerPolicy; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.policyengine.RangerAccessRequest; +import org.apache.ranger.plugin.policyengine.RangerAccessResult; + +public interface RangerPolicyEvaluator { + void init(RangerPolicy policy, RangerServiceDef serviceDef); + + RangerPolicy getPolicy(); + + RangerServiceDef getServiceDef(); + + RangerAccessResult evaluate(RangerAccessRequest request); +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java b/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java new file mode 100644 index 0000000..6ddebd1 --- /dev/null +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java @@ -0,0 +1,166 @@ +/* + * 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; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; + + +public abstract class RangerAbstractResourceMatcher implements RangerResourceMatcher { + private static final Log LOG = LogFactory.getLog(RangerAbstractResourceMatcher.class); + + public final String OPTIONS_SEP = ";"; + public final String OPTION_NV_SEP = "="; + public final String OPTION_IGNORE_CASE = "ignoreCase"; + public final String OPTION_WILD_CARD = "wildCard"; + + private RangerPolicyResource policyResource = null; + private String optionsString = null; + private Map<String, String> options = null; + + protected boolean optIgnoreCase = false; + protected boolean optWildCard = false; + + @Override + public void init(RangerPolicyResource policyResource, String optionsString) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerAbstractResourceMatcher.init(" + policyResource + ", " + optionsString + ")"); + } + + this.policyResource = policyResource; + this.optionsString = optionsString; + + options = new HashMap<String, String>(); + + if(optionsString != null) { + for(String optionString : optionsString.split(OPTIONS_SEP)) { + if(optionString == null) { + continue; + } + optionString = optionString.trim(); + + if(!optionString.isEmpty()) { + String[] nvArr = optionString.split(OPTION_NV_SEP); + + String name = (nvArr != null && nvArr.length > 0) ? nvArr[0].trim() : null; + String value = (nvArr != null && nvArr.length > 1) ? nvArr[1].trim() : null; + + if(name == null || name.isEmpty()) { + continue; + } + + options.put(name, value); + } + } + } + + optIgnoreCase = getBooleanOption(OPTION_IGNORE_CASE, true); + optWildCard = getBooleanOption(OPTION_WILD_CARD, true); + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerAbstractResourceMatcher.init(" + policyResource + ", " + optionsString + ")"); + } + } + + @Override + public RangerPolicyResource getPolicyResource() { + return policyResource; + } + + @Override + public String getOptionsString() { + return optionsString; + } + + + public String getOption(String name) { + String ret = null; + + if(options != null && name != null) { + ret = options.get(name); + } + + return ret; + } + + public String getOption(String name, String defaultValue) { + String ret = getOption(name); + + if(ret == null) { + ret = defaultValue; + } + + return ret; + } + + public boolean getBooleanOption(String name) { + String val = getOption(name); + + boolean ret = (val == null) ? false : Boolean.parseBoolean(val); + + return ret; + } + + public boolean getBooleanOption(String name, boolean defaultValue) { + String strVal = getOption(name); + + boolean ret = (strVal == null) ? defaultValue : Boolean.parseBoolean(strVal); + + return ret; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerAbstractResourceMatcher={"); + + sb.append("policyResource={"); + if(policyResource != null) { + policyResource.toString(sb); + } + sb.append("} "); + sb.append("optionsString={").append(optionsString).append("} "); + sb.append("optIgnoreCase={").append(optIgnoreCase).append("} "); + sb.append("optWildCard={").append(optWildCard).append("} "); + + sb.append("options={"); + if(options != null) { + for(Map.Entry<String, String> e : options.entrySet()) { + sb.append(e.getKey()).append("=").append(e.getValue()).append(OPTIONS_SEP); + } + } + sb.append("} "); + + sb.append("}"); + + return sb; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java b/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java new file mode 100644 index 0000000..9aa882b --- /dev/null +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java @@ -0,0 +1,123 @@ +/* + * 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; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; + + +public class RangerDefaultResourceMatcher extends RangerAbstractResourceMatcher { + private static final Log LOG = LogFactory.getLog(RangerDefaultResourceMatcher.class); + + private List<String> policyValues = null; + private boolean policyIsExcludes = false; + + @Override + public void init(RangerPolicyResource policyResource, String optionsString) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultResourceMatcher.init(" + policyResource + ", " + optionsString + ")"); + } + + super.init(policyResource, optionsString); + + policyValues = new ArrayList<String>(); + policyIsExcludes = false; + + if(policyResource != null) { + policyIsExcludes = policyResource.getIsExcludes(); + + if(policyResource.getValues() != null) { + for(String policyValue : policyResource.getValues()) { + if(policyValue == null) { + continue; + } + + if(optIgnoreCase) { + policyValue = policyValue.toLowerCase(); + } + + policyValues.add(policyValue); + } + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultResourceMatcher.init(" + policyResource + ", " + optionsString + ")"); + } + } + + @Override + public boolean isMatch(String resource) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultResourceMatcher.isMatch(" + resource + ")"); + } + + boolean ret = false; + + if(resource != null) { + if(optIgnoreCase) { + resource = resource.toLowerCase(); + } + + for(String policyValue : policyValues) { + ret = optWildCard ? resource.matches(policyValue) : resource.equals(policyValue); + + if(ret) { + break; + } + } + } + + if(policyIsExcludes) { + ret = !ret; + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultResourceMatcher.isMatch(" + resource + "): " + ret); + } + + return ret; + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerDefaultResourceMatcher={"); + + super.toString(sb); + + sb.append("policyValues={"); + if(policyValues != null) { + for(String value : policyValues) { + sb.append(value).append(","); + } + } + sb.append("} "); + + sb.append("policyIsExcludes={").append(policyIsExcludes).append("} "); + + sb.append("}"); + + return sb; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java b/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java new file mode 100644 index 0000000..fea3610 --- /dev/null +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java @@ -0,0 +1,165 @@ +/* + * 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; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; + + +public class RangerPathResourceMatcher extends RangerAbstractResourceMatcher { + private static final Log LOG = LogFactory.getLog(RangerPathResourceMatcher.class); + + private List<String> policyValues = null; + private boolean policyIsExcludes = false; + private boolean policyIsRecursive = false; + + @Override + public void init(RangerPolicyResource policyResource, String optionsString) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerPathResourceMatcher.init(" + policyResource + ", " + optionsString + ")"); + } + + super.init(policyResource, optionsString); + + policyValues = new ArrayList<String>(); + policyIsExcludes = false; + policyIsRecursive = false; + + if(policyResource != null) { + policyIsExcludes = policyResource.getIsExcludes(); + policyIsRecursive = policyResource.getIsRecursive(); + + if(policyResource.getValues() != null) { + for(String policyValue : policyResource.getValues()) { + if(policyValue == null) { + continue; + } + + if(optIgnoreCase) { + policyValue = policyValue.toLowerCase(); + } + + policyValues.add(policyValue); + } + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerPathResourceMatcher.init(" + policyResource + ", " + optionsString + ")"); + } + } + + @Override + public boolean isMatch(String resource) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerPathResourceMatcher.isMatch(" + resource + ")"); + } + + boolean ret = false; + + if(resource != null) { + if(optIgnoreCase) { + resource = resource.toLowerCase(); + } + + for(String policyValue : policyValues) { + if(policyIsRecursive) { + ret = optWildCard ? isRecursiveWildCardMatch(resource, policyValue) : resource.startsWith(policyValue); + } else { + ret = optWildCard ? FilenameUtils.wildcardMatch(resource, policyValue) : resource.equals(policyValue); + } + + if(ret) { + break; + } + } + } + + if(policyIsExcludes) { + ret = !ret; + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerPathResourceMatcher.isMatch(" + resource + "): " + ret); + } + + return ret; + } + + private static boolean isRecursiveWildCardMatch(String pathToCheck, String wildcardPath) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerPathResourceMatcher.isRecursiveWildCardMatch(" + pathToCheck + ", " + wildcardPath + ")"); + } + + boolean ret = false; + + if (pathToCheck != null) { + StringBuilder sb = new StringBuilder() ; + + for(String p : pathToCheck.split(org.apache.hadoop.fs.Path.SEPARATOR) ) { + sb.append(p); + + boolean matchFound = FilenameUtils.wildcardMatch(sb.toString(), wildcardPath) ; + + if (matchFound) { + ret = true ; + + break; + } + + sb.append(org.apache.hadoop.fs.Path.SEPARATOR) ; + } + + sb = null; + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerPathResourceMatcher.isRecursiveWildCardMatch(" + pathToCheck + ", " + wildcardPath + "): " + ret); + } + + return ret; + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerPathResourceMatcher={"); + + super.toString(sb); + + sb.append("policyValues={"); + if(policyValues != null) { + for(String value : policyValues) { + sb.append(value).append(","); + } + } + sb.append("} "); + + sb.append("policyIsExcludes={").append(policyIsExcludes).append("} "); + sb.append("policyIsRecursive={").append(policyIsRecursive).append("} "); + + sb.append("}"); + + return sb; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java b/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java new file mode 100644 index 0000000..3c9b687 --- /dev/null +++ b/plugin-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.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; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; + +public interface RangerResourceMatcher { + void init(RangerPolicyResource policyResource, String optionsString); + + RangerPolicyResource getPolicyResource(); + + String getOptionsString(); + + boolean isMatch(String resource); +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/plugin-common/src/test/java/org/apache/ranger/plugin/manager/TestServiceManager.java ---------------------------------------------------------------------- diff --git a/plugin-common/src/test/java/org/apache/ranger/plugin/manager/TestServiceManager.java b/plugin-common/src/test/java/org/apache/ranger/plugin/manager/TestServiceManager.java index 4263f59..7b4a039 100644 --- a/plugin-common/src/test/java/org/apache/ranger/plugin/manager/TestServiceManager.java +++ b/plugin-common/src/test/java/org/apache/ranger/plugin/manager/TestServiceManager.java @@ -120,14 +120,14 @@ public class TestServiceManager { policy.getResources().put("path", new RangerPolicyResource("/demo/test/finance", Boolean.FALSE, Boolean.TRUE)); RangerPolicyItem item1 = new RangerPolicyItem(); - item1.getAccesses().add(new RangerPolicyItemAccess("read", Boolean.TRUE)); - item1.getAccesses().add(new RangerPolicyItemAccess("write", Boolean.TRUE)); - item1.getAccesses().add(new RangerPolicyItemAccess("execute", Boolean.TRUE)); + item1.getAccesses().add(new RangerPolicyItemAccess("read")); + item1.getAccesses().add(new RangerPolicyItemAccess("write")); + item1.getAccesses().add(new RangerPolicyItemAccess("execute")); item1.getUsers().add("admin"); item1.getGroups().add("finance"); RangerPolicyItem item2 = new RangerPolicyItem(); - item2.getAccesses().add(new RangerPolicyItemAccess("read", Boolean.TRUE)); + item2.getAccesses().add(new RangerPolicyItemAccess("read")); item2.getGroups().add("public"); policy.getPolicyItems().add(item1); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/580f2c7f/security-admin/src/main/java/org/apache/ranger/common/ServiceUtil.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/common/ServiceUtil.java b/security-admin/src/main/java/org/apache/ranger/common/ServiceUtil.java index 62a65c3..748deb6 100644 --- a/security-admin/src/main/java/org/apache/ranger/common/ServiceUtil.java +++ b/security-admin/src/main/java/org/apache/ranger/common/ServiceUtil.java @@ -181,7 +181,7 @@ public class ServiceUtil { } } - accessList.add(new RangerPolicyItemAccess(toAccessType(permMap.getPermType()), Boolean.TRUE)); + accessList.add(new RangerPolicyItemAccess(toAccessType(permMap.getPermType()))); ipAddress = permMap.getIpAddress(); }
