You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2015/01/31 21:38:50 UTC
[7/8] incubator-ranger git commit: RANGER-203: moved
pluggable-service-model implementation from plugin-common to exiting project
ranger-plugin-common
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerMutableResource.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerMutableResource.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerMutableResource.java
new file mode 100644
index 0000000..f49bf8c
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerMutableResource.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.policyengine;
+
+
+public interface RangerMutableResource extends RangerResource {
+ void setOwnerUser(String ownerUser);
+
+ void setValue(String type, String value);
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
new file mode 100644
index 0000000..a66bc23
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
@@ -0,0 +1,54 @@
+/*
+ * 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.Collection;
+import java.util.List;
+
+import org.apache.ranger.plugin.audit.RangerAuditHandler;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+
+public interface RangerPolicyEngine {
+ public static final String GROUP_PUBLIC = "public";
+ public static final String ANY_ACCESS = "_any";
+ public static final String ADMIN_ACCESS = "_admin";
+ public static final long UNKNOWN_POLICY = -1;
+
+ String getServiceName();
+
+ RangerServiceDef getServiceDef();
+
+ void setPolicies(String serviceName, RangerServiceDef serviceDef, List<RangerPolicy> policies);
+
+ void setDefaultAuditHandler(RangerAuditHandler auditHandler);
+
+ RangerAuditHandler getDefaultAuditHandler();
+
+ RangerAccessResult createAccessResult(RangerAccessRequest request);
+
+ RangerAccessResult isAccessAllowed(RangerAccessRequest request);
+
+ Collection<RangerAccessResult> isAccessAllowed(Collection<RangerAccessRequest> requests);
+
+ RangerAccessResult isAccessAllowed(RangerAccessRequest request, RangerAuditHandler auditHandler);
+
+ Collection<RangerAccessResult> isAccessAllowed(Collection<RangerAccessRequest> requests, RangerAuditHandler auditHandler);
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/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
new file mode 100644
index 0000000..8f6231b
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
@@ -0,0 +1,254 @@
+/*
+ * 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.Collection;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.audit.RangerAuditHandler;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyevaluator.RangerDefaultPolicyEvaluator;
+import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
+
+
+public class RangerPolicyEngineImpl implements RangerPolicyEngine {
+ private static final Log LOG = LogFactory.getLog(RangerPolicyEngineImpl.class);
+
+ private String serviceName = null;
+ private RangerServiceDef serviceDef = null;
+ private List<RangerPolicyEvaluator> policyEvaluators = null;
+ private RangerAuditHandler defaultAuditHandler = null;
+
+
+ public RangerPolicyEngineImpl() {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerPolicyEngineImpl()");
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerPolicyEngineImpl()");
+ }
+ }
+
+ @Override
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ @Override
+ public RangerServiceDef getServiceDef() {
+ return serviceDef;
+ }
+
+ @Override
+ public void setPolicies(String serviceName, RangerServiceDef serviceDef, List<RangerPolicy> policies) {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerPolicyEngineImpl.setPolicies(" + serviceName + ", " + serviceDef + ", policies.count=" + (policies == null ? 0 : policies.size()) + ")");
+ }
+
+ if(serviceName != null && serviceDef != null && policies != null) {
+ List<RangerPolicyEvaluator> evaluators = new ArrayList<RangerPolicyEvaluator>();
+
+ for(RangerPolicy policy : policies) {
+ if(! policy.getIsEnabled()) {
+ continue;
+ }
+
+ RangerPolicyEvaluator evaluator = getPolicyEvaluator(policy, serviceDef);
+
+ if(evaluator != null) {
+ evaluators.add(evaluator);
+ }
+ }
+
+ /* TODO:
+ * sort evaluators list for faster completion of isAccessAllowed() method
+ * 1. Global policies: the policies that cover for any resource (for example: database=*; table=*; column=*)
+ * 2. Policies that cover all resources under level-1 (for example: every thing in one or more databases)
+ * 3. Policies that cover all resources under level-2 (for example: every thing in one or more tables)
+ * ...
+ * 4. Policies that cover all resources under level-n (for example: one or more columns)
+ *
+ */
+
+ this.serviceName = serviceName;
+ this.serviceDef = serviceDef;
+ this.policyEvaluators = evaluators;
+ } else {
+ LOG.error("RangerPolicyEngineImpl.setPolicies(): invalid arguments - null serviceDef/policies");
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerPolicyEngineImpl.setPolicies(" + serviceName + ", " + serviceDef + ", policies.count=" + (policies == null ? 0 : policies.size()) + ")");
+ }
+ }
+
+ @Override
+ public void setDefaultAuditHandler(RangerAuditHandler auditHandler) {
+ this.defaultAuditHandler = auditHandler;
+ }
+
+ @Override
+ public RangerAuditHandler getDefaultAuditHandler() {
+ return defaultAuditHandler;
+ }
+
+ @Override
+ public RangerAccessResult createAccessResult(RangerAccessRequest request) {
+ return new RangerAccessResult(serviceName, serviceDef, request);
+ }
+
+ @Override
+ public RangerAccessResult isAccessAllowed(RangerAccessRequest request) {
+ return isAccessAllowed(request, defaultAuditHandler);
+ }
+
+ @Override
+ public Collection<RangerAccessResult> isAccessAllowed(Collection<RangerAccessRequest> requests) {
+ return isAccessAllowed(requests, defaultAuditHandler);
+ }
+
+ @Override
+ public RangerAccessResult isAccessAllowed(RangerAccessRequest request, RangerAuditHandler auditHandler) {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerPolicyEngineImpl.isAccessAllowed(" + request + ")");
+ }
+
+ RangerAccessResult ret = isAccessAllowedNoAudit(request);
+
+ if(auditHandler != null) {
+ auditHandler.logAudit(ret);
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerPolicyEngineImpl.isAccessAllowed(" + request + "): " + ret);
+ }
+
+ return ret;
+ }
+
+ @Override
+ public Collection<RangerAccessResult> isAccessAllowed(Collection<RangerAccessRequest> requests, RangerAuditHandler auditHandler) {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerPolicyEngineImpl.isAccessAllowed(" + requests + ")");
+ }
+
+ Collection<RangerAccessResult> ret = new ArrayList<RangerAccessResult>();
+
+ if(requests != null) {
+ for(RangerAccessRequest request : requests) {
+ RangerAccessResult result = isAccessAllowedNoAudit(request);
+
+ ret.add(result);
+ }
+ }
+
+ if(auditHandler != null) {
+ auditHandler.logAudit(ret);
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerPolicyEngineImpl.isAccessAllowed(" + requests + "): " + ret);
+ }
+
+ return ret;
+ }
+
+ protected RangerAccessResult isAccessAllowedNoAudit(RangerAccessRequest request) {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerPolicyEngineImpl.isAccessAllowedNoAudit(" + request + ")");
+ }
+
+ RangerAccessResult ret = createAccessResult(request);
+
+ if(request != null) {
+ List<RangerPolicyEvaluator> evaluators = policyEvaluators;
+
+ if(evaluators != null) {
+ for(RangerPolicyEvaluator evaluator : evaluators) {
+ evaluator.evaluate(request, ret);
+
+ // stop once allowed=true && audited==true
+ if(ret.getIsAllowed() && ret.getIsAudited()) {
+ break;
+ }
+ }
+ }
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerPolicyEngineImpl.isAccessAllowedNoAudit(" + request + "): " + ret);
+ }
+
+ return ret;
+ }
+
+ private RangerPolicyEvaluator getPolicyEvaluator(RangerPolicy policy, RangerServiceDef serviceDef) {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerPolicyEngineImpl.getPolicyEvaluator(" + policy + "," + serviceDef + ")");
+ }
+
+ RangerPolicyEvaluator ret = null;
+
+ ret = new RangerDefaultPolicyEvaluator(); // TODO: configurable evaluator class?
+
+ ret.init(policy, serviceDef);
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerPolicyEngineImpl.getPolicyEvaluator(" + policy + "," + serviceDef + "): " + ret);
+ }
+
+ return ret;
+ }
+
+ @Override
+ public String toString( ) {
+ StringBuilder sb = new StringBuilder();
+
+ toString(sb);
+
+ return sb.toString();
+ }
+
+ public StringBuilder toString(StringBuilder sb) {
+ sb.append("RangerPolicyEngineImpl={");
+
+ sb.append("serviceName={").append(serviceName).append("} ");
+ sb.append("serviceDef={").append(serviceDef).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/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResource.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResource.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResource.java
new file mode 100644
index 0000000..6941bc3
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResource.java
@@ -0,0 +1,33 @@
+/*
+ * 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.Set;
+
+
+public interface RangerResource {
+ public abstract String getOwnerUser();
+
+ public abstract boolean exists(String name);
+
+ public abstract String getValue(String name);
+
+ public Set<String> getKeys();
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceImpl.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceImpl.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceImpl.java
new file mode 100644
index 0000000..86f7ea4
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceImpl.java
@@ -0,0 +1,107 @@
+/*
+ * 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.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+
+public class RangerResourceImpl implements RangerMutableResource {
+ private String ownerUser = null;
+ private Map<String, String> elements = null;
+
+
+ public RangerResourceImpl() {
+ }
+
+ @Override
+ public String getOwnerUser() {
+ return ownerUser;
+ }
+
+ @Override
+ public boolean exists(String name) {
+ return elements != null && elements.containsKey(name);
+ }
+
+ @Override
+ public String getValue(String name) {
+ String ret = null;
+
+ if(elements != null && elements.containsKey(name)) {
+ ret = elements.get(name);
+ }
+
+ return ret;
+ }
+
+ @Override
+ public Set<String> getKeys() {
+ Set<String> ret = null;
+
+ if(elements != null) {
+ ret = elements.keySet();
+ }
+
+ return ret;
+ }
+
+ @Override
+ public void setOwnerUser(String ownerUser) {
+ this.ownerUser = ownerUser;
+ }
+
+ @Override
+ public void setValue(String name, String value) {
+ if(elements == null) {
+ elements = new HashMap<String, String>();
+ }
+
+ elements.put(name, value);
+ }
+
+ @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, String> e : elements.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/217e1892/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
new file mode 100644
index 0000000..36273eb
--- /dev/null
+++ b/agents-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/217e1892/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
new file mode 100644
index 0000000..cc1ee1e
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
@@ -0,0 +1,446 @@
+/*
+ * 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.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+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.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.RangerAccessTypeDef;
+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.RangerPolicyEngine;
+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 Map<String, RangerResourceMatcher> matchers = null;
+
+ @Override
+ public void init(RangerPolicy policy, RangerServiceDef serviceDef) {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerDefaultPolicyEvaluator.init()");
+ }
+
+ preprocessPolicy(policy, serviceDef);
+
+ super.init(policy, serviceDef);
+
+ this.matchers = new HashMap<String, RangerResourceMatcher>();
+
+ if(policy != null && policy.getResources() != null && serviceDef != null) {
+ for(RangerResourceDef resourceDef : serviceDef.getResources()) {
+ String resourceName = resourceDef.getName();
+ RangerPolicyResource policyResource = policy.getResources().get(resourceName);
+
+ RangerResourceMatcher matcher = createResourceMatcher(resourceDef, policyResource);
+
+ if(matcher != null) {
+ matchers.put(resourceName, matcher);
+ } else {
+ LOG.error("failed to find matcher for resource " + resourceName);
+ }
+ }
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerDefaultPolicyEvaluator.init()");
+ }
+ }
+
+ @Override
+ public void evaluate(RangerAccessRequest request, RangerAccessResult result) {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerDefaultPolicyEvaluator.evaluate(" + request + ", " + result + ")");
+ }
+
+ RangerPolicy policy = getPolicy();
+
+ if(policy != null && request != null && result != null) {
+ boolean isResourceMatch = matchResource(request.getResource());
+ boolean isResourceHeadMatch = isResourceMatch || matchResourceHead(request.getResource());
+ String accessType = request.getAccessType();
+
+ if(StringUtils.isEmpty(accessType)) {
+ accessType = RangerPolicyEngine.ANY_ACCESS;
+ }
+
+ boolean isAnyAccess = StringUtils.equals(accessType, RangerPolicyEngine.ANY_ACCESS);
+
+ if(isResourceMatch || (isResourceHeadMatch && isAnyAccess)) {
+ if(policy.getIsAuditEnabled()) {
+ result.setIsAudited(true);
+ }
+
+ for(RangerPolicyItem policyItem : policy.getPolicyItems()) {
+ if(result.getIsAllowed()) {
+ break;
+ }
+
+ if(CollectionUtils.isEmpty(policyItem.getAccesses())) {
+ continue;
+ }
+
+ boolean isUserGroupMatch = matchUserGroup(policyItem, request.getUser(), request.getUserGroups());
+
+ if(! isUserGroupMatch) {
+ continue;
+ }
+
+ boolean isCustomConditionsMatch = matchCustomConditions(policyItem, request);
+
+ if(! isCustomConditionsMatch) {
+ continue;
+ }
+
+ if(isAnyAccess) {
+ for(RangerPolicyItemAccess access : policyItem.getAccesses()) {
+ if(access.getIsAllowed()) {
+ result.setIsAllowed(true);
+ result.setPolicyId(policy.getId());
+ break;
+ }
+ }
+ } else {
+ RangerPolicyItemAccess access = getAccess(policyItem, accessType);
+
+ if(access != null && access.getIsAllowed()) {
+ result.setIsAllowed(true);
+ result.setPolicyId(policy.getId());
+ }
+ }
+ }
+ }
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerDefaultPolicyEvaluator.evaluate(" + request + ", " + result + ")");
+ }
+ }
+
+ protected boolean matchResource(RangerResource resource) {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerDefaultPolicyEvaluator.matchResource(" + resource + ")");
+ }
+
+ boolean ret = false;
+
+ RangerServiceDef serviceDef = getServiceDef();
+
+ if(serviceDef != null && serviceDef.getResources() != null) {
+ Collection<String> resourceKeys = resource == null ? null : resource.getKeys();
+ Collection<String> policyKeys = matchers == null ? null : matchers.keySet();
+
+ boolean keysMatch = (resourceKeys == null) || (policyKeys != null && policyKeys.containsAll(resourceKeys));
+
+ if(keysMatch) {
+ for(RangerResourceDef resourceDef : serviceDef.getResources()) {
+ String resourceName = resourceDef.getName();
+ String resourceValue = resource == null ? null : resource.getValue(resourceName);
+ RangerResourceMatcher matcher = matchers == null ? null : matchers.get(resourceName);
+
+ // when no value exists for a resourceName, consider it a match only if (policy doesn't have a matcher OR matcher allows no-value resource)
+ if(StringUtils.isEmpty(resourceValue)) {
+ ret = matcher == null || matcher.isMatch(resourceValue);
+ } else {
+ ret = matcher != null && matcher.isMatch(resourceValue);
+ }
+
+ if(! ret) {
+ break;
+ }
+ }
+ }
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerDefaultPolicyEvaluator.matchResource(" + resource + "): " + ret);
+ }
+
+ return ret;
+ }
+
+ protected boolean matchResourceHead(RangerResource resource) {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerDefaultPolicyEvaluator.matchResourceHead(" + resource + ")");
+ }
+
+ boolean ret = false;
+
+ RangerServiceDef serviceDef = getServiceDef();
+
+ if(serviceDef != null && serviceDef.getResources() != null) {
+ int numMatched = 0;
+ int numUnmatched = 0;
+
+ for(RangerResourceDef resourceDef : serviceDef.getResources()) {
+ String resourceName = resourceDef.getName();
+ String resourceValue = resource == null ? null : resource.getValue(resourceName);
+ RangerResourceMatcher matcher = matchers == null ? null : matchers.get(resourceName);
+
+ if(numUnmatched > 0) { // no further values are expected in the resource
+ if(! StringUtils.isEmpty(resourceValue)) {
+ break;
+ }
+
+ numUnmatched++;
+ continue;
+ } else {
+ boolean isMatch = false;
+
+ // when no value exists for a resourceName, consider it a match only if (policy doesn't have a matcher OR matcher allows no-value resource)
+ if(StringUtils.isEmpty(resourceValue)) {
+ isMatch = matcher == null || matcher.isMatch(resourceValue);
+ } else {
+ isMatch = matcher != null && matcher.isMatch(resourceValue);
+ }
+
+ if(isMatch) {
+ numMatched++;
+ } else {
+ numUnmatched++;
+ }
+ }
+ }
+
+ ret = (numMatched > 0) && serviceDef.getResources().size() == (numMatched + numUnmatched);
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerDefaultPolicyEvaluator.matchResourceHead(" + 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) {
+ if(!ret && user != null && policyItem.getUsers() != null) {
+ ret = policyItem.getUsers().contains(user);
+ }
+
+ if(!ret && groups != null && policyItem.getGroups() != null) {
+ ret = policyItem.getGroups().contains(RangerPolicyEngine.GROUP_PUBLIC) ||
+ !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(StringUtils.equalsIgnoreCase(accessType, access.getType())) {
+ ret = access;
+
+ break;
+ }
+ }
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerDefaultPolicyEvaluator.getAccess(" + policyItem + ", " + accessType + "): " + 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(StringUtils.isEmpty(clsName)) {
+ 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(resourceDef, 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(RangerResourceMatcher matcher : matchers.values()) {
+ sb.append("{").append(matcher).append("} ");
+ }
+ }
+ sb.append("} ");
+
+ sb.append("}");
+
+ return sb;
+ }
+
+ private void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef) {
+ if(policy == null || CollectionUtils.isEmpty(policy.getPolicyItems()) || serviceDef == null) {
+ return;
+ }
+
+ Map<String, Collection<String>> impliedAccessGrants = getImpliedAccessGrants(serviceDef);
+
+ if(impliedAccessGrants == null || impliedAccessGrants.isEmpty()) {
+ return;
+ }
+
+ for(RangerPolicyItem policyItem : policy.getPolicyItems()) {
+ if(CollectionUtils.isEmpty(policyItem.getAccesses())) {
+ continue;
+ }
+
+ // Only one round of 'expansion' is done; multi-level impliedGrants (like shown below) are not handled for now
+ // multi-level impliedGrants: given admin=>write; write=>read: must imply admin=>read,write
+ for(Map.Entry<String, Collection<String>> e : impliedAccessGrants.entrySet()) {
+ String accessType = e.getKey();
+ Collection<String> impliedGrants = e.getValue();
+
+ RangerPolicyItemAccess access = getAccess(policyItem, accessType);
+
+ if(access == null) {
+ continue;
+ }
+
+ for(String impliedGrant : impliedGrants) {
+ RangerPolicyItemAccess impliedAccess = getAccess(policyItem, impliedGrant);
+
+ if(impliedAccess == null) {
+ impliedAccess = new RangerPolicyItemAccess(impliedGrant, access.getIsAllowed());
+
+ policyItem.getAccesses().add(impliedAccess);
+ } else {
+ if(! impliedAccess.getIsAllowed()) {
+ impliedAccess.setIsAllowed(access.getIsAllowed());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private Map<String, Collection<String>> getImpliedAccessGrants(RangerServiceDef serviceDef) {
+ Map<String, Collection<String>> ret = null;
+
+ if(serviceDef != null && !CollectionUtils.isEmpty(serviceDef.getAccessTypes())) {
+ for(RangerAccessTypeDef accessTypeDef : serviceDef.getAccessTypes()) {
+ if(!CollectionUtils.isEmpty(accessTypeDef.getImpliedGrants())) {
+ if(ret == null) {
+ ret = new HashMap<String, Collection<String>>();
+ }
+
+ Collection<String> impliedAccessGrants = ret.get(accessTypeDef.getName());
+
+ if(impliedAccessGrants == null) {
+ impliedAccessGrants = new HashSet<String>();
+
+ ret.put(accessTypeDef.getName(), impliedAccessGrants);
+ }
+
+ for(String impliedAccessGrant : accessTypeDef.getImpliedGrants()) {
+ impliedAccessGrants.add(impliedAccessGrant);
+ }
+ }
+ }
+ }
+
+ return ret;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/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
new file mode 100644
index 0000000..b6e0f10
--- /dev/null
+++ b/agents-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();
+
+ void evaluate(RangerAccessRequest request, RangerAccessResult result);
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
new file mode 100644
index 0000000..9fb248a
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
@@ -0,0 +1,226 @@
+/*
+ * 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.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+
+
+public abstract class RangerAbstractResourceMatcher implements RangerResourceMatcher {
+ private static final Log LOG = LogFactory.getLog(RangerAbstractResourceMatcher.class);
+
+ public final String WILDCARD_PATTERN = ".*";
+
+ 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 RangerResourceDef resourceDef = null;
+ private RangerPolicyResource policyResource = null;
+ private String optionsString = null;
+ private Map<String, String> options = null;
+
+ protected boolean optIgnoreCase = false;
+ protected boolean optWildCard = false;
+
+ protected List<String> policyValues = null;
+ protected boolean policyIsExcludes = false;
+ protected boolean isMatchAny = false;
+
+ @Override
+ public void init(RangerResourceDef resourceDef, RangerPolicyResource policyResource, String optionsString) {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerAbstractResourceMatcher.init(" + resourceDef + ", " + policyResource + ", " + optionsString + ")");
+ }
+
+ this.resourceDef = resourceDef;
+ this.policyResource = policyResource;
+ this.optionsString = optionsString;
+
+ options = new HashMap<String, String>();
+
+ if(optionsString != null) {
+ for(String optionString : optionsString.split(OPTIONS_SEP)) {
+ if(StringUtils.isEmpty(optionString)) {
+ continue;
+ }
+
+ 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(StringUtils.isEmpty(name)) {
+ continue;
+ }
+
+ options.put(name, value);
+ }
+ }
+
+ optIgnoreCase = getBooleanOption(OPTION_IGNORE_CASE, true);
+ optWildCard = getBooleanOption(OPTION_WILD_CARD, true);
+
+ policyValues = new ArrayList<String>();
+ policyIsExcludes = policyResource == null ? false : policyResource.getIsExcludes();
+
+ if(policyResource != null && policyResource.getValues() != null) {
+ for(String policyValue : policyResource.getValues()) {
+ if(StringUtils.isEmpty(policyValue)) {
+ continue;
+ }
+
+ if(optIgnoreCase) {
+ policyValue = policyValue.toLowerCase();
+ }
+
+ if(optWildCard) {
+ policyValue = getWildCardPattern(policyValue);
+ }
+
+ if(policyValue.equals(WILDCARD_PATTERN)) {
+ isMatchAny = true;
+ }
+
+ policyValues.add(policyValue);
+ }
+ }
+
+ if(policyValues.isEmpty()) {
+ isMatchAny = true;
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerAbstractResourceMatcher.init(" + resourceDef + ", " + policyResource + ", " + optionsString + ")");
+ }
+ }
+
+ @Override
+ public RangerResourceDef getResourceDef() {
+ return resourceDef;
+ }
+
+ @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(StringUtils.isEmpty(ret)) {
+ ret = defaultValue;
+ }
+
+ return ret;
+ }
+
+ public boolean getBooleanOption(String name) {
+ String val = getOption(name);
+
+ boolean ret = StringUtils.isEmpty(val) ? false : Boolean.parseBoolean(val);
+
+ return ret;
+ }
+
+ public boolean getBooleanOption(String name, boolean defaultValue) {
+ String strVal = getOption(name);
+
+ boolean ret = StringUtils.isEmpty(strVal) ? defaultValue : Boolean.parseBoolean(strVal);
+
+ return ret;
+ }
+
+ public String getWildCardPattern(String policyValue) {
+ if (policyValue != null) {
+ policyValue = policyValue.replaceAll("\\?", "\\.")
+ .replaceAll("\\*", ".*") ;
+ }
+
+ return policyValue ;
+ }
+
+ @Override
+ public String toString( ) {
+ StringBuilder sb = new StringBuilder();
+
+ toString(sb);
+
+ return sb.toString();
+ }
+
+ public StringBuilder toString(StringBuilder sb) {
+ sb.append("RangerAbstractResourceMatcher={");
+
+ sb.append("resourceDef={");
+ if(resourceDef != null) {
+ resourceDef.toString(sb);
+ }
+ sb.append("} ");
+ 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("policyValues={").append(StringUtils.join(policyValues, ",")).append("} ");
+ sb.append("policyIsExcludes={").append(policyIsExcludes).append("} ");
+ sb.append("isMatchAny={").append(isMatchAny).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/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
new file mode 100644
index 0000000..13500dc
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
@@ -0,0 +1,101 @@
+/*
+ * 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.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+
+
+public class RangerDefaultResourceMatcher extends RangerAbstractResourceMatcher {
+ private static final Log LOG = LogFactory.getLog(RangerDefaultResourceMatcher.class);
+
+
+ @Override
+ public void init(RangerResourceDef resourceDef, RangerPolicyResource policyResource, String optionsString) {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerDefaultResourceMatcher.init(" + resourceDef + ", " + policyResource + ", " + optionsString + ")");
+ }
+
+ super.init(resourceDef, policyResource, optionsString);
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerDefaultResourceMatcher.init(" + resourceDef + ", " + 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) : StringUtils.equals(resource, policyValue);
+
+ if(ret) {
+ break;
+ }
+ }
+ } else {
+ ret = isMatchAny;
+ }
+
+ 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/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java
new file mode 100644
index 0000000..2cf3a68
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java
@@ -0,0 +1,151 @@
+/*
+ * 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.commons.io.FilenameUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+
+
+public class RangerPathResourceMatcher extends RangerAbstractResourceMatcher {
+ private static final Log LOG = LogFactory.getLog(RangerPathResourceMatcher.class);
+
+ private boolean policyIsRecursive = false;
+
+ @Override
+ public void init(RangerResourceDef resourceDef, RangerPolicyResource policyResource, String optionsString) {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerPathResourceMatcher.init(" + resourceDef + ", " + policyResource + ", " + optionsString + ")");
+ }
+
+ super.init(resourceDef, policyResource, optionsString);
+
+ policyIsRecursive = policyResource == null ? false : policyResource.getIsRecursive();
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerPathResourceMatcher.init(" + resourceDef + ", " + 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 = StringUtils.startsWith(resource, policyValue);
+
+ if(! ret && optWildCard) {
+ ret = isRecursiveWildCardMatch(resource, policyValue) ;
+ }
+ } else {
+ ret = StringUtils.equals(resource, policyValue);
+
+ if(! ret && optWildCard) {
+ ret = FilenameUtils.wildcardMatch(resource, policyValue);
+ }
+ }
+
+ if(ret) {
+ break;
+ }
+ }
+ } else {
+ ret = isMatchAny;
+ }
+
+ 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/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
new file mode 100644
index 0000000..c750cd8
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.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.resourcematcher;
+
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+
+public interface RangerResourceMatcher {
+ void init(RangerResourceDef resourceDef, RangerPolicyResource policyResource, String optionsString);
+
+ RangerResourceDef getResourceDef();
+
+ RangerPolicyResource getPolicyResource();
+
+ String getOptionsString();
+
+ boolean isMatch(String resource);
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
new file mode 100644
index 0000000..8f1fa5f
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
@@ -0,0 +1,178 @@
+/*
+ * 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.service;
+
+import java.util.Collection;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
+import org.apache.ranger.plugin.audit.RangerAuditHandler;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngineImpl;
+import org.apache.ranger.plugin.store.ServiceStore;
+import org.apache.ranger.plugin.store.ServiceStoreFactory;
+import org.apache.ranger.plugin.util.PolicyRefresher;
+
+
+public class RangerBasePlugin {
+ private String serviceType = null;
+ private String serviceName = null;
+ private RangerPolicyEngine policyEngine = null;
+ private PolicyRefresher refresher = null;
+
+
+ public RangerBasePlugin(String serviceType) {
+ this.serviceType = serviceType;
+ }
+
+ public String getServiceType() {
+ return serviceType;
+ }
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ public RangerPolicyEngine getPolicyEngine() {
+ return policyEngine;
+ }
+
+ public void init() {
+ RangerPolicyEngine policyEngine = new RangerPolicyEngineImpl();
+
+ init(policyEngine);
+ }
+
+ public synchronized void init(RangerPolicyEngine policyEngine) {
+ cleanup();
+
+
+ String serviceName = RangerConfiguration.getInstance().get("ranger.plugin." + serviceType + ".service.name");
+ String serviceStoreClass = RangerConfiguration.getInstance().get("ranger.plugin." + serviceType + ".service.store.class", "org.apache.ranger.plugin.store.rest.ServiceRESTStore");
+ String cacheDir = RangerConfiguration.getInstance().get("ranger.plugin." + serviceType + ".service.store.cache.dir", "/tmp");
+ long pollingIntervalMs = RangerConfiguration.getInstance().getLong("ranger.plugin." + serviceType + ".service.store.pollIntervalMs", 30 * 1000);
+
+ if(StringUtils.isEmpty(serviceName)) {
+ // get the serviceName from download URL: http://ranger-admin-host:port/service/assets/policyList/serviceName
+ String policyDownloadUrl = RangerConfiguration.getInstance().get("xasecure." + serviceType + ".policymgr.url");
+
+ if(! StringUtils.isEmpty(policyDownloadUrl)) {
+ int idx = policyDownloadUrl.lastIndexOf('/');
+
+ if(idx != -1) {
+ serviceName = policyDownloadUrl.substring(idx + 1);
+ }
+ }
+ }
+
+ ServiceStore serviceStore = ServiceStoreFactory.instance().getServiceStore(serviceStoreClass);
+
+ refresher = new PolicyRefresher(policyEngine, serviceType, serviceName, serviceStore, pollingIntervalMs, cacheDir);
+ refresher.startRefresher();
+ this.policyEngine = policyEngine;
+ }
+
+ public synchronized void cleanup() {
+ PolicyRefresher refresher = this.refresher;
+
+ this.serviceName = null;
+ this.policyEngine = null;
+ this.refresher = null;
+
+ if(refresher != null) {
+ refresher.stopRefresher();
+ }
+ }
+
+ public void setDefaultAuditHandler(RangerAuditHandler auditHandler) {
+ RangerPolicyEngine policyEngine = this.policyEngine;
+
+ if(policyEngine != null) {
+ policyEngine.setDefaultAuditHandler(auditHandler);
+ }
+ }
+
+ public RangerAuditHandler getDefaultAuditHandler() {
+ RangerPolicyEngine policyEngine = this.policyEngine;
+
+ if(policyEngine != null) {
+ return policyEngine.getDefaultAuditHandler();
+ }
+
+ return null;
+ }
+
+
+ public RangerAccessResult createAccessResult(RangerAccessRequest request) {
+ RangerPolicyEngine policyEngine = this.policyEngine;
+
+ if(policyEngine != null) {
+ return policyEngine.createAccessResult(request);
+ }
+
+ return null;
+ }
+
+
+ public RangerAccessResult isAccessAllowed(RangerAccessRequest request) {
+ RangerPolicyEngine policyEngine = this.policyEngine;
+
+ if(policyEngine != null) {
+ return policyEngine.isAccessAllowed(request);
+ }
+
+ return null;
+ }
+
+
+ public Collection<RangerAccessResult> isAccessAllowed(Collection<RangerAccessRequest> requests) {
+ RangerPolicyEngine policyEngine = this.policyEngine;
+
+ if(policyEngine != null) {
+ return policyEngine.isAccessAllowed(requests);
+ }
+
+ return null;
+ }
+
+
+ public RangerAccessResult isAccessAllowed(RangerAccessRequest request, RangerAuditHandler auditHandler) {
+ RangerPolicyEngine policyEngine = this.policyEngine;
+
+ if(policyEngine != null) {
+ return policyEngine.isAccessAllowed(request, auditHandler);
+ }
+
+ return null;
+ }
+
+
+ public Collection<RangerAccessResult> isAccessAllowed(Collection<RangerAccessRequest> requests, RangerAuditHandler auditHandler) {
+ RangerPolicyEngine policyEngine = this.policyEngine;
+
+ if(policyEngine != null) {
+ return policyEngine.isAccessAllowed(requests, auditHandler);
+ }
+
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBaseService.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBaseService.java b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBaseService.java
new file mode 100644
index 0000000..8eeb439
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBaseService.java
@@ -0,0 +1,55 @@
+/*
+ * 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.service;
+
+import java.util.List;
+
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+
+
+public abstract class RangerBaseService {
+ private RangerServiceDef serviceDef;
+ private RangerService service;
+
+
+ public void init(RangerServiceDef serviceDef, RangerService service) {
+ this.serviceDef = serviceDef;
+ this.service = service;
+ }
+
+ /**
+ * @return the serviceDef
+ */
+ public RangerServiceDef getServiceDef() {
+ return serviceDef;
+ }
+
+ /**
+ * @return the service
+ */
+ public RangerService getService() {
+ return service;
+ }
+
+ public abstract void validateConfig() throws Exception;
+
+ public abstract List<String> lookupResource(ResourceLookupContext context) throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/service/ResourceLookupContext.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/service/ResourceLookupContext.java b/agents-common/src/main/java/org/apache/ranger/plugin/service/ResourceLookupContext.java
new file mode 100644
index 0000000..b5c3dda
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/service/ResourceLookupContext.java
@@ -0,0 +1,72 @@
+/*
+ * 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.service;
+
+import java.util.List;
+import java.util.Map;
+
+
+public class ResourceLookupContext {
+ private String userInput;
+ private String resourceName;
+ private Map<String, List<String>> resources;
+
+
+ public ResourceLookupContext() {
+
+ }
+
+ /**
+ * @return the userInput
+ */
+ public String getUserInput() {
+ return userInput;
+ }
+ /**
+ * @param userInput the userInput to set
+ */
+ public void setUserInput(String userInput) {
+ this.userInput = userInput;
+ }
+ /**
+ * @return the resourceName
+ */
+ public String getResourceName() {
+ return resourceName;
+ }
+ /**
+ * @param resourceName the resourceName to set
+ */
+ public void setResourceName(String resourceName) {
+ this.resourceName = resourceName;
+ }
+ /**
+ * @return the resources
+ */
+ public Map<String, List<String>> getResources() {
+ return resources;
+ }
+ /**
+ * @param resources the resources to set
+ */
+ public void setResources(Map<String, List<String>> resources) {
+ this.resources = resources;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/store/ServiceStore.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/ServiceStore.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/ServiceStore.java
new file mode 100644
index 0000000..e8d970c
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/ServiceStore.java
@@ -0,0 +1,74 @@
+/*
+ * 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.store;
+
+import java.util.List;
+
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.util.SearchFilter;
+import org.apache.ranger.plugin.util.ServicePolicies;
+
+public interface ServiceStore {
+ void init() throws Exception;
+
+ RangerServiceDef createServiceDef(RangerServiceDef serviceDef) throws Exception;
+
+ RangerServiceDef updateServiceDef(RangerServiceDef serviceDef) throws Exception;
+
+ void deleteServiceDef(Long id) throws Exception;
+
+ RangerServiceDef getServiceDef(Long id) throws Exception;
+
+ RangerServiceDef getServiceDefByName(String name) throws Exception;
+
+ List<RangerServiceDef> getServiceDefs(SearchFilter filter) throws Exception;
+
+
+ RangerService createService(RangerService service) throws Exception;
+
+ RangerService updateService(RangerService service) throws Exception;
+
+ void deleteService(Long id) throws Exception;
+
+ RangerService getService(Long id) throws Exception;
+
+ RangerService getServiceByName(String name) throws Exception;
+
+ List<RangerService> getServices(SearchFilter filter) throws Exception;
+
+
+ RangerPolicy createPolicy(RangerPolicy policy) throws Exception;
+
+ RangerPolicy updatePolicy(RangerPolicy policy) throws Exception;
+
+ void deletePolicy(Long id) throws Exception;
+
+ RangerPolicy getPolicy(Long id) throws Exception;
+
+ List<RangerPolicy> getPolicies(SearchFilter filter) throws Exception;
+
+ List<RangerPolicy> getServicePolicies(Long serviceId, SearchFilter filter) throws Exception;
+
+ List<RangerPolicy> getServicePolicies(String serviceName, SearchFilter filter) throws Exception;
+
+ ServicePolicies getServicePoliciesIfUpdated(String serviceName, Long lastKnownVersion) throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/store/ServiceStoreFactory.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/ServiceStoreFactory.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/ServiceStoreFactory.java
new file mode 100644
index 0000000..f9a2404
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/ServiceStoreFactory.java
@@ -0,0 +1,113 @@
+/*
+ * 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.store;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
+
+
+public class ServiceStoreFactory {
+ private static final Log LOG = LogFactory.getLog(ServiceStoreFactory.class);
+
+ private static ServiceStoreFactory sInstance = null;
+
+ private Map<String, ServiceStore> serviceStores = null;
+ private ServiceStore defaultServiceStore = null;
+
+
+ public static ServiceStoreFactory instance() {
+ if(sInstance == null) {
+ sInstance = new ServiceStoreFactory();
+ }
+
+ return sInstance;
+ }
+
+ public ServiceStore getServiceStore() {
+ ServiceStore ret = defaultServiceStore;
+
+ if(ret == null) { // if no service store has been created yet, create the default store. TODO: review the impact and update, if necessary
+ String defaultServiceStoreClass = RangerConfiguration.getInstance().get("ranger.default.service.store.class", "org.apache.ranger.plugin.store.file.ServiceFileStore");
+
+ ret = getServiceStore(defaultServiceStoreClass);
+ }
+
+ return ret;
+ }
+
+ public ServiceStore getServiceStore(String storeClassname) {
+ ServiceStore ret = serviceStores.get(storeClassname);
+
+ if(ret == null) {
+ synchronized(this) {
+ ret = serviceStores.get(storeClassname);
+
+ if(ret == null) {
+ try {
+ @SuppressWarnings("unchecked")
+ Class<ServiceStore> storeClass = (Class<ServiceStore>)Class.forName(storeClassname);
+
+ ret = storeClass.newInstance();
+
+ ret.init();
+
+ serviceStores.put(storeClassname, ret);
+
+ if(defaultServiceStore == null) {
+ defaultServiceStore = ret;
+ }
+ } catch(Exception excp) {
+ LOG.error("failed to instantiate service store of type " + storeClassname, excp);
+ }
+ }
+ }
+ }
+
+ return ret;
+ }
+
+ private ServiceStoreFactory() {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> ServiceStoreFactory.ServiceStoreFactory()");
+ }
+
+ init();
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== ServiceStoreFactory.ServiceStoreFactory()");
+ }
+ }
+
+ private void init() {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> ServiceStoreFactory.init()");
+ }
+
+ serviceStores = new HashMap<String, ServiceStore>();
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== ServiceStoreFactory.init()");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/217e1892/agents-common/src/main/java/org/apache/ranger/plugin/store/file/BaseFileStore.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/file/BaseFileStore.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/file/BaseFileStore.java
new file mode 100644
index 0000000..17b46f9
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/file/BaseFileStore.java
@@ -0,0 +1,390 @@
+/*
+ * 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.store.file;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataInputStream;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.PathFilter;
+import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
+import org.apache.ranger.plugin.model.RangerBaseModelObject;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class BaseFileStore {
+ private static final Log LOG = LogFactory.getLog(BaseFileStore.class);
+
+ private Gson gsonBuilder = null;
+ private String dataDir = null;
+
+ protected static String FILE_PREFIX_SERVICE_DEF = "ranger-servicedef-";
+ protected static String FILE_PREFIX_SERVICE = "ranger-service-";
+ protected static String FILE_PREFIX_POLICY = "ranger-policy-";
+ protected static String FILE_SUFFIX_JSON = ".json";
+
+
+ protected void initStore() {
+ dataDir = RangerConfiguration.getInstance().get("ranger.service.store.file.dir", "file:///etc/ranger/data");
+
+ try {
+ gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSS-Z").setPrettyPrinting().create();
+ } catch(Throwable excp) {
+ LOG.fatal("BaseFileStore.init(): failed to create GsonBuilder object", excp);
+ }
+ }
+
+ protected String getDataDir() {
+ return dataDir;
+ }
+
+ protected String getServiceDefFile(Long id) {
+ String filePath = dataDir + Path.SEPARATOR + FILE_PREFIX_SERVICE_DEF + id + FILE_SUFFIX_JSON;
+
+ return filePath;
+ }
+
+ protected String getServiceFile(Long id) {
+ String filePath = dataDir + Path.SEPARATOR + FILE_PREFIX_SERVICE + id + FILE_SUFFIX_JSON;
+
+ return filePath;
+ }
+
+ protected String getPolicyFile(Long serviceId, Long policyId) {
+ String filePath = dataDir + Path.SEPARATOR + FILE_PREFIX_POLICY + serviceId + "-" + policyId + FILE_SUFFIX_JSON;
+
+ return filePath;
+ }
+
+ protected <T> T loadFromResource(String resource, Class<T> cls) throws Exception {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> BaseFileStore.loadFromResource(" + resource + ")");
+ }
+
+ InputStream inStream = this.getClass().getResourceAsStream(resource);
+
+ T ret = loadFromStream(inStream, cls);
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== BaseFileStore.loadFromResource(" + resource + "): " + ret);
+ }
+
+ return ret;
+ }
+
+ protected <T> T loadFromStream(InputStream inStream, Class<T> cls) throws Exception {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> BaseFileStore.loadFromStream()");
+ }
+
+ InputStreamReader reader = new InputStreamReader(inStream);
+
+ T ret = gsonBuilder.fromJson(reader, cls);
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== BaseFileStore.loadFromStream(): " + ret);
+ }
+
+ return ret;
+ }
+
+ protected <T> T loadFromFile(Path filePath, Class<T> cls) throws Exception {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> BaseFileStore.loadFromFile(" + filePath + ")");
+ }
+
+ T ret = null;
+ InputStreamReader reader = null;
+
+ try {
+ FileSystem fileSystem = getFileSystem(filePath);
+ FSDataInputStream inStream = fileSystem.open(filePath);
+
+ ret = loadFromStream(inStream, cls);
+ } finally {
+ close(reader);
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== BaseFileStore.loadFromFile(" + filePath + "): " + ret);
+ }
+
+ return ret;
+ }
+
+ protected <T> List<T> loadFromDir(Path dirPath, final String filePrefix, Class<T> cls) throws Exception {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> BaseFileStore.loadFromDir()");
+ }
+
+ List<T> ret = new ArrayList<T>();
+
+ try {
+ FileSystem fileSystem = getFileSystem(dirPath);
+
+ if(fileSystem.exists(dirPath) && fileSystem.isDirectory(dirPath)) {
+ PathFilter filter = new PathFilter() {
+ @Override
+ public boolean accept(Path path) {
+ return path.getName().startsWith(filePrefix) &&
+ path.getName().endsWith(FILE_SUFFIX_JSON);
+ }
+ };
+
+ FileStatus[] sdFiles = fileSystem.listStatus(dirPath, filter);
+
+ if(sdFiles != null) {
+ for(FileStatus sdFile : sdFiles) {
+ T obj = loadFromFile(sdFile.getPath(), cls);
+
+ if(obj != null) {
+ ret.add(obj);
+ }
+ }
+ }
+ } else {
+ LOG.error(dirPath + ": does not exists or not a directory");
+ }
+ } catch(IOException excp) {
+ LOG.warn("error loading service-def in directory " + dirPath, excp);
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== BaseFileStore.loadFromDir(): count=" + (ret == null ? 0 : ret.size()));
+ }
+
+ return ret;
+ }
+
+ protected <T> T saveToFile(T obj, Path filePath, boolean overWrite) throws Exception {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> BaseFileStore.saveToFile(" + filePath + ")");
+ }
+
+ OutputStreamWriter writer = null;
+
+ try {
+ FileSystem fileSystem = getFileSystem(filePath);
+ FSDataOutputStream outStream = fileSystem.create(filePath, overWrite);
+
+ writer = new OutputStreamWriter(outStream);
+
+ gsonBuilder.toJson(obj, writer);
+ } finally {
+ close(writer);
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== BaseFileStore.saveToFile(" + filePath + "): " + obj);
+ }
+
+ return obj;
+ }
+
+ protected boolean deleteFile(Path filePath) throws Exception {
+ LOG.debug("==> BaseFileStore.deleteFile(" + filePath + ")");
+
+ FileSystem fileSystem = getFileSystem(filePath);
+
+ boolean ret = false;
+
+ if(fileSystem.exists(filePath)) {
+ ret = fileSystem.delete(filePath, false);
+ } else {
+ ret = true; // nothing to delete
+ }
+
+ LOG.debug("<== BaseFileStore.deleteFile(" + filePath + "): " + ret);
+
+ return ret;
+ }
+
+ protected boolean renamePath(Path oldPath, Path newPath) throws Exception {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> BaseFileStore.renamePath(" + oldPath + "," + newPath + ")");
+ }
+
+ FileSystem fileSystem = getFileSystem(oldPath);
+
+ boolean ret = false;
+
+ if(fileSystem.exists(oldPath)) {
+ if(! fileSystem.exists(newPath)) {
+ ret = fileSystem.rename(oldPath, newPath);
+ } else {
+ LOG.warn("target of rename '" + newPath + "' already exists");
+ }
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== BaseFileStore.renamePath(" + oldPath + "," + newPath + "): " + ret);
+ }
+
+ return ret;
+ }
+
+ protected RangerServiceDef saveToFile(RangerServiceDef serviceDef, boolean overWrite) throws Exception {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> BaseFileStore.saveToFile(" + serviceDef + "," + overWrite + ")");
+ }
+
+ Path filePath = new Path(getServiceDefFile(serviceDef.getId()));
+
+ RangerServiceDef ret = saveToFile(serviceDef, filePath, overWrite);
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== BaseFileStore.saveToFile(" + serviceDef + "," + overWrite + "): ");
+ }
+
+ return ret;
+ }
+
+ protected RangerService saveToFile(RangerService service, boolean overWrite) throws Exception {
+ Path filePath = new Path(getServiceFile(service.getId()));
+
+ RangerService ret = saveToFile(service, filePath, overWrite);
+
+ return ret;
+ }
+
+ protected RangerPolicy saveToFile(RangerPolicy policy, long serviceId, boolean overWrite) throws Exception {
+ Path filePath = new Path(getPolicyFile(serviceId, policy.getId()));
+
+ RangerPolicy ret = saveToFile(policy, filePath, overWrite);
+
+ return ret;
+ }
+
+ protected long getMaxId(List<? extends RangerBaseModelObject> objs) {
+ long ret = -1;
+
+ if(objs != null) {
+ for(RangerBaseModelObject obj : objs) {
+ if(obj.getId() > ret) {
+ ret = obj.getId();
+ }
+ }
+ }
+
+ return ret;
+ }
+ protected FileSystem getFileSystem(Path filePath) throws Exception {
+ Configuration conf = new Configuration();
+ FileSystem fileSystem = filePath.getFileSystem(conf);
+
+ return fileSystem;
+ }
+
+ protected void close(FileSystem fs) {
+ if(fs != null) {
+ try {
+ fs.close();
+ } catch(IOException excp) {
+ // ignore
+ }
+ }
+ }
+
+ protected void close(InputStreamReader reader) {
+ if(reader != null) {
+ try {
+ reader.close();
+ } catch(IOException excp) {
+ // ignore
+ }
+ }
+ }
+
+ protected void close(OutputStreamWriter writer) {
+ if(writer != null) {
+ try {
+ writer.close();
+ } catch(IOException excp) {
+ // ignore
+ }
+ }
+ }
+
+ protected void preCreate(RangerBaseModelObject obj) {
+ obj.setId(new Long(0));
+ obj.setGuid(UUID.randomUUID().toString());
+ obj.setCreateTime(new Date());
+ obj.setUpdateTime(obj.getCreateTime());
+ obj.setVersion(new Long(1));
+ }
+
+ protected void postCreate(RangerBaseModelObject obj) {
+ // TODO:
+ }
+
+ protected void preUpdate(RangerBaseModelObject obj) {
+ if(obj.getId() == null) {
+ obj.setId(new Long(0));
+ }
+
+ if(obj.getGuid() == null) {
+ obj.setGuid(UUID.randomUUID().toString());
+ }
+
+ if(obj.getCreateTime() == null) {
+ obj.setCreateTime(new Date());
+ }
+
+ Long version = obj.getVersion();
+
+ if(version == null) {
+ version = new Long(1);
+ } else {
+ version = new Long(version.longValue() + 1);
+ }
+
+ obj.setVersion(version);
+ obj.setUpdateTime(new Date());
+ }
+
+ protected void postUpdate(RangerBaseModelObject obj) {
+ // TODO:
+ }
+
+ protected void preDelete(RangerBaseModelObject obj) {
+ // TODO:
+ }
+
+ protected void postDelete(RangerBaseModelObject obj) {
+ // TODO:
+ }
+}