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 2014/12/12 02:30:22 UTC
[39/51] [partial] incubator-ranger git commit: RANGER-194: Rename
packages from xasecure to apache ranger
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-impl/src/main/java/org/apache/ranger/pdp/knox/URLBasedAuthDB.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/knox/URLBasedAuthDB.java b/agents-impl/src/main/java/org/apache/ranger/pdp/knox/URLBasedAuthDB.java
new file mode 100644
index 0000000..d5aa16e
--- /dev/null
+++ b/agents-impl/src/main/java/org/apache/ranger/pdp/knox/URLBasedAuthDB.java
@@ -0,0 +1,452 @@
+/**
+ * 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.pdp.knox;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
+import org.apache.ranger.pdp.config.Jersey2PolicyRefresher;
+import org.apache.ranger.pdp.config.PolicyChangeListener;
+import org.apache.ranger.pdp.constants.RangerConstants;
+import org.apache.ranger.pdp.model.Policy;
+import org.apache.ranger.pdp.model.PolicyContainer;
+import org.apache.ranger.pdp.model.RolePermission;
+
+public class URLBasedAuthDB implements PolicyChangeListener {
+
+ private static final Log LOG = LogFactory.getLog(URLBasedAuthDB.class) ;
+
+ private static URLBasedAuthDB me = null;
+
+ private Jersey2PolicyRefresher refresher = null ;
+
+ private PolicyContainer policyContainer = null;
+
+ private HashMap<String,Boolean> cachedAuditFlag = new HashMap<String,Boolean>() ; // needs to be cleaned when ruleList changes
+
+ public static URLBasedAuthDB getInstance() {
+ if (me == null) {
+ synchronized (URLBasedAuthDB.class) {
+ URLBasedAuthDB temp = me;
+ if (temp == null) {
+ me = new URLBasedAuthDB();
+ me.init() ;
+ }
+ }
+ }
+ return me;
+ }
+
+ public static URLBasedAuthDB getInstanceWithBackEndMocked() {
+ return new URLBasedAuthDB("instanceWithBackednMocked");
+ }
+
+ private URLBasedAuthDB() {
+ String url = RangerConfiguration.getInstance().get(RangerConstants.RANGER_KNOX_POLICYMGR_URL_PROP);
+ long refreshInMilli = RangerConfiguration.getInstance().getLong(
+ RangerConstants.RANGER_KNOX_POLICYMGR_URL_RELOAD_INTERVAL_IN_MILLIS_PROP ,
+ RangerConstants.RANGER_KNOX_POLICYMGR_URL_RELOAD_INTERVAL_IN_MILLIS_DEFAULT);
+ String sslConfigFileName = RangerConfiguration.getInstance().get(RangerConstants.RANGER_KNOX_POLICYMGR_SSL_CONFIG_FILE_PROP) ;
+
+ String lastStoredFileName = RangerConfiguration.getInstance().get(RangerConstants.RANGER_KNOX_LAST_SAVED_POLICY_FILE_PROP) ;
+
+ refresher = new Jersey2PolicyRefresher(url, refreshInMilli,sslConfigFileName,lastStoredFileName) ;
+
+ String saveAsFileName = RangerConfiguration.getInstance().get(RangerConstants.RANGER_KNOX_POLICYMGR_URL_SAVE_FILE_PROP) ;
+ if (saveAsFileName != null) {
+ refresher.setSaveAsFileName(saveAsFileName) ;
+ }
+
+ if (lastStoredFileName != null) {
+ refresher.setLastStoredFileName(lastStoredFileName);
+ }
+ }
+
+ private URLBasedAuthDB(String mockName) {
+ }
+
+ private void init() {
+ refresher.setPolicyChangeListener(this);
+ }
+
+
+ @Override
+ public void OnPolicyChange(PolicyContainer aPolicyContainer) {
+ setPolicyContainer(aPolicyContainer);
+ }
+
+
+ public boolean isAccessGranted(String topology, String service, String access, String userName, Set<String> groups,
+ String requestIp) {
+
+ boolean accessGranted = false;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Evaluating access for topology: " + topology +
+ ", service: " + service +
+ ", access: " + access +
+ ", requestingIp: " +requestIp +
+ ", requestingUser: " + userName +
+ ", requestingUserGroups: " + groups);
+ }
+ PolicyContainer policyContainer = getPolicyContainer() ;
+
+ if (policyContainer == null) {
+ LOG.warn("Denying access: policyContainer is null") ;
+ return false ;
+ }
+
+ for(Policy policy : policyContainer.getAcl()) {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Evaluating policy: " + policy.toString() ) ;
+ }
+
+ if (!policy.isEnabled()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Skipping policy: " + policy + ", policy disabled") ;
+ }
+ continue; // jump to next policy
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Evaluating topology match for policyTopologyList: " + policy.getTopologyList() +
+ ", requestTopology: " + topology) ;
+ }
+
+ boolean topologyMatched = false;
+
+ List<String> topologyList = policy.getTopologyList();
+ if (topologyList == null || topologyList.isEmpty()) {
+ LOG.debug("Denying access: policy topologyList is empty") ;
+ continue; // jump to next policy
+ }
+
+ if (topologyList.contains("*") || topologyList.contains(topology)) {
+ topologyMatched = true;
+ LOG.debug("Policy topologyList matches requested topology");
+ }
+
+ if (!topologyMatched) {
+ for (String policyTopology : topologyList) {
+ if (FilenameUtils.wildcardMatch(topology, policyTopology)) {
+ topologyMatched = true;
+ LOG.debug("Policy topologyList matches requested topology");
+ break; // break out of topologyList
+ }
+ }
+ }
+ if (!topologyMatched) {
+ LOG.debug("Denying access: policy topologyList does not match requested topology") ;
+ continue; // jump to next policy
+ } else {
+ LOG.debug("policy topologyList matches requested topology");
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Evaluating service match for policyServiceList: " + policy.getServiceList() +
+ ", requestService: " + service) ;
+ }
+
+ boolean serviceMatched = false;
+
+ List<String> serviceList = policy.getServiceList();
+ if (serviceList == null || serviceList.isEmpty()) {
+ LOG.debug("Denying access: policy serviceList is empty") ;
+ continue; // jump to next policy
+ }
+
+ if (serviceList.contains("*") || serviceList.contains(service)) {
+ serviceMatched = true;
+ LOG.debug("Policy serviceList matches requested service");
+ }
+
+ if (!serviceMatched) {
+ for (String policyService : serviceList) {
+ if (FilenameUtils.wildcardMatch(service, policyService)) {
+ serviceMatched = true;
+ LOG.debug("Policy serviceList matches requested service");
+ break; // break out of serviceList
+ }
+ }
+ }
+ if (!serviceMatched) {
+ LOG.debug("Denying access: policy serviceList does not match requested service") ;
+ continue; // jump to next policy
+ } else {
+ LOG.debug("Policy serviceList matches requested service");
+ }
+
+ LOG.debug("Checking accessType, IP, User, Group based permission");
+ if ( policy.getPermissions() == null
+ || policy.getPermissions().isEmpty()) {
+ LOG.debug("Policy not applicable, no user or group based permission");
+ }
+
+ for (RolePermission rp : policy.getPermissions()) {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Evaluating RolePermission: " + rp);
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Checking accessTypeMatch for rolePermissionAccesType: "
+ + rp.getAccess() + ", requestAccessType: " + access);
+ }
+
+ if (rp.getAccess().contains(access)) {
+
+ LOG.debug("RolePermission accessType matches request accessType");
+
+ boolean ipMatched = false;
+ List<String> ipList = rp.getIpAddress();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Checking ipMatch for rolePermissionIpList: " + ipList +
+ ", requestIP: " + requestIp);
+ }
+
+ if (ipList == null || ipList.isEmpty()) {
+ LOG.debug("RolePermission does not require IP Matching");
+ ipMatched = true;
+ } else if ( ipList.contains("*") ) {
+ LOG.debug("RolePermission allows any IP: *");
+ ipMatched = true;
+ } else {
+ for (String ip : ipList) {
+ if (ipMatches(ip, requestIp)) {
+ LOG.debug("RolePermission IP matches request IP");
+ ipMatched = true;
+ break;// break out of ipList
+ }
+ }
+ }
+
+ if (!ipMatched) {
+ // ip not matched, jump to next RolePermission check
+ LOG.debug("Request IP does not match RolePermission");
+ continue; // jump to next rolePermission
+ } else {
+ LOG.debug("Request IP matches RolePermission");
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Checking userMatch for rolePermissionUsers: "
+ + rp.getUsers() + ", requestUser: " + userName);
+ }
+
+ if ( rp.getUsers() != null && rp.getUsers().contains(userName) ) {
+ LOG.debug("Request user matches RolePermission");
+ return true ;
+ }
+ LOG.debug("RolePermission does not permit request by request user, would check by groups");
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Checking groupMatch for rolePermissionGroups: "
+ + rp.getGroups() + ", requestGroups: " + groups);
+ }
+
+ for(String ug : groups) {
+ if ( rp.getGroups() != null && rp.getGroups().contains(ug)) {
+ LOG.debug("Request userGroups matches RolePermission");
+ return true ;
+ }
+ }
+ LOG.debug("RolePermission does not permit request by request user groups");
+
+ if (rp.getGroups().contains(RangerConstants.PUBLIC_ACCESS_ROLE)) {
+ LOG.debug("RolePermission applies to public group");
+ return true ;
+ }
+
+ LOG.debug("RolePermission does not permit by users, groups or public group");
+ } else {
+ LOG.debug("rolePermissionAccessType does not match requestAccessType");
+ }
+ }
+ }
+ LOG.debug("No matching policy permission found, denying access");
+ return accessGranted;
+ }
+
+ public boolean isAuditEnabled(String topology, String service) {
+
+ boolean auditEnabled = false;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Checcking whether audit is enabled for topology: " + topology +
+ ", service: " + service );
+ }
+
+ PolicyContainer policyContainer = getPolicyContainer() ;
+ if (policyContainer == null) {
+ LOG.warn("PolicyContainer is null") ;
+ return false ;
+ }
+
+ for(Policy policy : policyContainer.getAcl()) {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Evaluating policy: " + policy) ;
+ }
+
+ if (!policy.isEnabled()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Skipping policy: " + policy + ", policy disabled") ;
+ }
+ continue; // jump to next policy
+ }
+
+ if (policy.getAuditInd() == 0) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Skipping policy: " + policy + ", policy audit disabled") ;
+ }
+ continue; // jump to next policy
+ }
+
+ boolean topologyMatched = false;
+
+ List<String> topologyList = policy.getTopologyList();
+ if (topologyList == null || topologyList.isEmpty()) {
+ LOG.debug("Policy not applicable: policy topologyList is empty") ;
+ continue; // jump to next policy
+ }
+
+ if (topologyList.contains("*") || topologyList.contains(topology)) {
+ topologyMatched = true;
+ LOG.debug("Policy topologyList matches requested topology");
+ }
+
+ if (!topologyMatched) {
+ for (String policyTopology : topologyList) {
+ if (FilenameUtils.wildcardMatch(topology, policyTopology)) {
+ topologyMatched = true;
+ LOG.debug("Policy topologyList matches requested topology");
+ break; // break out of topologyList check
+ }
+ }
+ }
+ if (!topologyMatched) {
+ LOG.debug("Policy not applicable: polocy topologyList does not match requested topology") ;
+ continue; // jump to next policy
+ } else {
+ LOG.debug("Policy topologyList matches requested topology");
+ }
+
+ boolean serviceMatched = false;
+
+ List<String> serviceList = policy.getServiceList();
+ if (serviceList == null || serviceList.isEmpty()) {
+ LOG.debug("Policy not applicable: serviceList is empty") ;
+ continue; // jump to next policy
+ }
+
+ if (serviceList.contains("*") || serviceList.contains(service)) {
+ serviceMatched = true;
+ LOG.debug("Policy serviceList matches requested service");
+ }
+
+ if (!serviceMatched) {
+ for (String policyService : serviceList) {
+ if (FilenameUtils.wildcardMatch(service, policyService)) {
+ serviceMatched = true;
+ LOG.debug("Policy serviceList matches requested service");
+ break; // break out of serviceList check
+ }
+ }
+ }
+ if (!serviceMatched) {
+ LOG.debug("Policy not applicable: policy serviceList does not match requested service") ;
+ continue; // jump to next policy
+ } else {
+ LOG.debug("Policy serviceList matches requested service");
+ }
+ auditEnabled = true;;
+ break; // break out of policyList check
+ }
+ return auditEnabled;
+ }
+
+ public PolicyContainer getPolicyContainer() {
+ return policyContainer;
+ }
+
+
+ synchronized void setPolicyContainer(PolicyContainer aPolicyContainer) {
+
+ for(Policy p : aPolicyContainer.getAcl()) {
+ for(RolePermission rp : p.getPermissions()) {
+ // lowercase accesType value stings
+ List<String> rpaccess = rp.getAccess() ;
+ if (rpaccess != null && rpaccess.size() > 0) {
+ List<String> temp = new ArrayList<String>() ;
+ for(String s : rpaccess) {
+ temp.add(s.toLowerCase()) ;
+ }
+ rp.setAccess(temp);
+ }
+ }
+ }
+
+ this.policyContainer = aPolicyContainer ;
+ this.cachedAuditFlag.clear();
+ }
+
+
+ private boolean ipMatches(String policyIp, String requestIp) {
+ if (policyIp == null) {
+ return false;
+ }
+ policyIp = policyIp.trim();
+ if (policyIp.isEmpty()) {
+ return false;
+ }
+ boolean ipMatched = false;
+ boolean wildEnd = false;
+ if (policyIp.contains(".")) {
+ while (policyIp.endsWith(".*")) {
+ wildEnd = true;
+ policyIp = policyIp.substring(0, policyIp.lastIndexOf(".*"));
+ }
+ if (wildEnd) {
+ policyIp = policyIp + ".";
+ }
+ } else if (policyIp.contains(":")) {
+ while (policyIp.endsWith(":*")) {
+ wildEnd = true;
+ policyIp = policyIp.substring(0, policyIp.lastIndexOf(":*"));
+ }
+ if (wildEnd) {
+ policyIp = policyIp + ":";
+ }
+ }
+ if (wildEnd && requestIp.toLowerCase().startsWith(policyIp.toLowerCase())) {
+ ipMatched = true;
+ } else if (policyIp.equalsIgnoreCase(requestIp)) {
+ ipMatched = true;
+ }
+ return ipMatched;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-impl/src/main/java/org/apache/ranger/pdp/knox/deploy/RangerPDPKnoxDeploymentContributor.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/knox/deploy/RangerPDPKnoxDeploymentContributor.java b/agents-impl/src/main/java/org/apache/ranger/pdp/knox/deploy/RangerPDPKnoxDeploymentContributor.java
new file mode 100644
index 0000000..a70224f
--- /dev/null
+++ b/agents-impl/src/main/java/org/apache/ranger/pdp/knox/deploy/RangerPDPKnoxDeploymentContributor.java
@@ -0,0 +1,73 @@
+/**
+ * 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.pdp.knox.deploy;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.hadoop.gateway.deploy.DeploymentContext;
+import org.apache.hadoop.gateway.deploy.ProviderDeploymentContributorBase;
+import org.apache.hadoop.gateway.descriptor.FilterParamDescriptor;
+import org.apache.hadoop.gateway.descriptor.ResourceDescriptor;
+import org.apache.hadoop.gateway.topology.Provider;
+import org.apache.hadoop.gateway.topology.Service;
+
+public class RangerPDPKnoxDeploymentContributor extends ProviderDeploymentContributorBase {
+
+ private static final String FILTER_CLASSNAME = "org.apache.ranger.pdp.knox.filter.RangerPDPKnoxFilter";
+
+ @Override
+ public String getRole() {
+ return "authorization";
+ }
+
+ @Override
+ public String getName() {
+ return "XASecurePDPKnox";
+ }
+
+ @Override
+ public void initializeContribution(DeploymentContext context) {
+ super.initializeContribution(context);
+ }
+
+ @Override
+ public void contributeProvider( DeploymentContext context, Provider provider ) {
+ }
+
+ @Override
+ public void contributeFilter( DeploymentContext context, Provider provider, Service service,
+ ResourceDescriptor resource, List<FilterParamDescriptor> params ) {
+ if (params == null) {
+ params = new ArrayList<FilterParamDescriptor>();
+ }
+ // add resource role to params so that we can determine the acls to enforce at runtime
+ params.add( resource.createFilterParam().name( "resource.role" ).value(resource.role() ) );
+
+ // blindly add all the provider params as filter init params
+ // this will include any {resource.role}-ACLS parameters to be enforced - such as NAMENODE-ACLS
+ Map<String, String> providerParams = provider.getParams();
+ for(Entry<String, String> entry : providerParams.entrySet()) {
+ params.add( resource.createFilterParam().name( entry.getKey().toLowerCase() ).value( entry.getValue() ) );
+ }
+
+ resource.addFilter().name( getName() ).role( getRole() ).impl( FILTER_CLASSNAME ).params( params );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-impl/src/main/java/org/apache/ranger/pdp/knox/filter/RangerPDPKnoxFilter.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/knox/filter/RangerPDPKnoxFilter.java b/agents-impl/src/main/java/org/apache/ranger/pdp/knox/filter/RangerPDPKnoxFilter.java
new file mode 100644
index 0000000..7eb498e
--- /dev/null
+++ b/agents-impl/src/main/java/org/apache/ranger/pdp/knox/filter/RangerPDPKnoxFilter.java
@@ -0,0 +1,214 @@
+/**
+ * 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.pdp.knox.filter;
+
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.Principal;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.gateway.filter.AbstractGatewayFilter;
+import org.apache.hadoop.gateway.security.GroupPrincipal;
+import org.apache.hadoop.gateway.security.ImpersonatedPrincipal;
+import org.apache.hadoop.gateway.security.PrimaryPrincipal;
+import org.apache.ranger.audit.model.EnumRepositoryType;
+import org.apache.ranger.audit.model.KnoxAuditEvent;
+import org.apache.ranger.audit.provider.AuditProvider;
+import org.apache.ranger.audit.provider.AuditProviderFactory;
+import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
+import org.apache.ranger.authorization.hadoop.constants.RangerHadoopConstants;
+import org.apache.ranger.authorization.knox.KnoxAccessVerifier;
+import org.apache.ranger.authorization.knox.KnoxAccessVerifierFactory;
+import org.apache.ranger.authorization.utils.StringUtil;
+
+public class RangerPDPKnoxFilter implements Filter {
+
+ private static final Log LOG = LogFactory.getLog(RangerPDPKnoxFilter.class);
+ private static final String ACL_ENFORCER = "xasecure-acl";
+ private static final String PERM_ALLOW = "allow";
+ private String resourceRole = null;
+ private KnoxAccessVerifier knoxAccessVerifier;
+
+
+ AuditProvider auditProvider = AuditProviderFactory.getAuditProvider();
+ private final String REPOSITORY_NAME = RangerConfiguration.getInstance().get(RangerHadoopConstants.AUDITLOG_REPOSITORY_NAME_PROP);
+
+ static {
+ RangerConfiguration.getInstance().initAudit(AuditProviderFactory.ApplicationType.Knox);
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ resourceRole = getInitParameter(filterConfig, "resource.role");
+ knoxAccessVerifier = KnoxAccessVerifierFactory.getInstance();
+ }
+
+ private String getInitParameter(FilterConfig filterConfig, String paramName) {
+ return filterConfig.getInitParameter(paramName.toLowerCase());
+ }
+
+ public void destroy() {
+ }
+
+ public void doFilter(ServletRequest request, ServletResponse response,
+ FilterChain chain) throws IOException, ServletException {
+
+ String sourceUrl = (String) request
+ .getAttribute(AbstractGatewayFilter.SOURCE_REQUEST_CONTEXT_URL_ATTRIBUTE_NAME);
+ String topologyName = getTopologyName(sourceUrl);
+ String serviceName = getServiceName();
+
+ Subject subject = Subject.getSubject(AccessController.getContext());
+
+ Principal primaryPrincipal = (Principal) subject.getPrincipals(
+ PrimaryPrincipal.class).toArray()[0];
+ String primaryUser = primaryPrincipal.getName();
+
+ String impersonatedUser = null;
+ Object[] impersonations = subject.getPrincipals(
+ ImpersonatedPrincipal.class).toArray();
+ if (impersonations != null && impersonations.length > 0) {
+ impersonatedUser = ((Principal) impersonations[0]).getName();
+ }
+
+ String user = (impersonatedUser != null) ? impersonatedUser
+ : primaryUser;
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Checking access primaryUser: " + primaryUser + ", impersonatedUser: "
+ + impersonatedUser + ", effectiveUser: " + user);
+ }
+
+ Object[] groupObjects = subject.getPrincipals(GroupPrincipal.class)
+ .toArray();
+ Set<String> groups = new HashSet<String>();
+ for (Object obj : groupObjects) {
+ groups.add(((Principal) obj).getName());
+ }
+
+ String clientIp = request.getRemoteAddr();
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Checking access primaryUser: " + primaryUser + ", impersonatedUser: "
+ + impersonatedUser + ", effectiveUser: " + user +
+ ", groups: " + groups + ", clientIp: " + clientIp);
+ }
+ boolean accessAllowed = knoxAccessVerifier.isAccessAllowed(
+ topologyName, serviceName, PERM_ALLOW, user, groups, clientIp);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Access allowed: " + accessAllowed);
+ }
+ if (accessAllowed) {
+ chain.doFilter(request, response);
+ if (knoxAccessVerifier.isAuditEnabled(topologyName, serviceName)) {
+ LOG.debug("Audit is enabled");
+ logAuditEvent(user, clientIp, topologyName, serviceName,
+ "allow", true);
+ } else {
+ LOG.debug("Audit is not enabled");
+ }
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Access is denied");
+ }
+ if (knoxAccessVerifier.isAuditEnabled(topologyName, serviceName)) {
+ LOG.debug("Audit is enabled");
+ logAuditEvent(user, clientIp, topologyName, serviceName,
+ "allow", false);
+ } else {
+ LOG.debug("Audit is not enabled");
+ }
+ sendForbidden((HttpServletResponse) response);
+ }
+ }
+
+ private void sendForbidden(HttpServletResponse res) {
+ sendErrorCode(res, 403);
+ }
+
+ private void sendErrorCode(HttpServletResponse res, int code) {
+ try {
+ res.sendError(code);
+ } catch (IOException e) {
+ LOG.error("Error while redireting:", e);
+ }
+ }
+
+ private String getTopologyName(String requestUrl) {
+ if (requestUrl == null) {
+ return null;
+ }
+ String url = requestUrl.trim();
+ String[] tokens = url.split("/");
+ if (tokens.length > 2) {
+ return tokens[2];
+ } else {
+ return null;
+ }
+ }
+
+ private String getServiceName() {
+ return resourceRole;
+ }
+
+ private void logAuditEvent(String userName, String clientIp,
+ String topology, String service,
+ String accessType, boolean accessGranted) {
+
+ KnoxAuditEvent auditEvent = new KnoxAuditEvent();
+
+ auditEvent.setUser(userName == null ?
+ RangerHadoopConstants.AUDITLOG_EMPTY_STRING : userName);
+ auditEvent.setResourcePath("/" + topology + "/" + service);
+ auditEvent.setResourceType("service");
+ auditEvent.setAccessType(accessType);
+ auditEvent.setClientIP(clientIp);
+ auditEvent.setEventTime(StringUtil.getUTCDate());
+ auditEvent.setAccessResult((short) (accessGranted ? 1 : 0));
+ auditEvent.setResultReason(null);
+ auditEvent.setRepositoryType(EnumRepositoryType.KNOX);
+ auditEvent.setRepositoryName(REPOSITORY_NAME);
+ auditEvent.setAclEnforcer(ACL_ENFORCER);
+
+ try {
+ LOG.debug("logEvent [" + auditEvent + "] - START");
+
+ AuditProvider ap = AuditProviderFactory.getAuditProvider();
+ ap.log(auditEvent);
+
+ LOG.debug("logEvent [" + auditEvent + "] - END");
+ } catch (Throwable t) {
+ LOG.error("ERROR logEvent [" + auditEvent + "]", t);
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-impl/src/main/java/org/apache/ranger/pdp/model/Policy.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/model/Policy.java b/agents-impl/src/main/java/org/apache/ranger/pdp/model/Policy.java
new file mode 100644
index 0000000..46ca26b
--- /dev/null
+++ b/agents-impl/src/main/java/org/apache/ranger/pdp/model/Policy.java
@@ -0,0 +1,326 @@
+/*
+ * 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.pdp.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.ranger.pdp.config.gson.ExcludeSerialization;
+
+import com.google.gson.annotations.SerializedName;
+
+public class Policy {
+
+ public static final String RESOURCE_SPLITER = "," ;
+ public static final String POLICY_ENABLED_STATUS = "Enabled" ;
+ public static final String SELECTION_TYPE_INCLUSIVE = "Inclusion" ;
+ public static final String SELECTION_TYPE_EXCLUSIVE = "Exclusion" ;
+
+ //
+ // Only for HDFS policies
+ //
+ private String resource ;
+ @SerializedName("isRecursive")
+ private int recursiveInd;
+
+ // Only for Knox Policies
+ //
+
+ @SerializedName("topology_name")
+ private String topologies ;
+
+ @SerializedName("service_name")
+ private String services ;
+
+
+ //
+ // Only for Hive Policies
+ //
+
+ @SerializedName("database_name")
+ private String databases ;
+
+ @SerializedName("table_name")
+ private String tables ;
+
+ @SerializedName("udf_name")
+ private String udfs ;
+
+ @SerializedName("column_name")
+ private String columns ;
+
+ @SerializedName("column_families")
+ private String columnfamilies ;
+
+ //
+ // Neede for all Policies
+ //
+ @SerializedName("permission")
+ private List<RolePermission> permissions ;
+
+ @SerializedName("audit")
+ private int auditInd ;
+
+ @SerializedName("encrypt")
+ private int encryptInd ;
+
+ @SerializedName("policyStatus")
+ private String policyStatus;
+
+ @SerializedName("tablePolicyType")
+ private String tableSelectionType ;
+
+ @SerializedName("columnPolicyType")
+ private String columnSelectionType ;
+
+ // Derived fields for PolicyAnalysis
+ @ExcludeSerialization
+ private List<ResourcePath> resourceList ;
+ @ExcludeSerialization
+ private List<String> databaseList ;
+ @ExcludeSerialization
+ private List<String> tableList ;
+ @ExcludeSerialization
+ private List<String> udfList ;
+ @ExcludeSerialization
+ private List<String> columnList ;
+ @ExcludeSerialization
+ private List<String> columnFamilyList ;
+ @ExcludeSerialization
+ private List<String> topologyList ;
+ @ExcludeSerialization
+ private List<String> serviceList ;
+
+ public Policy() {
+ permissions = new ArrayList<RolePermission>() ;
+ }
+
+
+ public String getResource() {
+ return resource;
+ }
+
+ public void setResource(String resource) {
+ this.resource = resource;
+ }
+
+ public String getDatabases() {
+ return databases;
+ }
+
+ public void setDatabases(String databases) {
+ this.databases = databases;
+ }
+
+ public String getTables() {
+ return tables;
+ }
+
+ public void setTables(String tables) {
+ this.tables = tables;
+ }
+
+ public String gettopologies() {
+ return topologies;
+ }
+
+ public void setTopologies(String topologies) {
+ this.topologies = topologies;
+ }
+
+ public String getServices() {
+ return services;
+ }
+
+ public void setServices(String services) {
+ this.services = services;
+ }
+ public String getUdfs() {
+ return udfs;
+ }
+
+ public void setUdfs(String udfs) {
+ this.udfs = udfs;
+ }
+
+
+ public String getColumns() {
+ return columns;
+ }
+ public void setColumns(String columns) {
+ this.columns = columns;
+ }
+ public String getColumnfamilies() {
+ return columnfamilies;
+ }
+ public void setColumnfamilies(String columnfamilies) {
+ this.columnfamilies = columnfamilies;
+ }
+
+ public List<RolePermission> getPermissions() {
+ return permissions;
+ }
+ public void setPermissions(List<RolePermission> permissions) {
+ this.permissions = permissions;
+ }
+
+ public int getRecursiveInd() {
+ return recursiveInd;
+ }
+ public void setRecursiveInd(int recursiveInd) {
+ this.recursiveInd = recursiveInd;
+ }
+
+ public int getAuditInd() {
+ return auditInd;
+ }
+
+
+ public void setAuditInd(int auditInd) {
+ this.auditInd = auditInd;
+ }
+
+
+ public int getEncryptInd() {
+ return encryptInd;
+ }
+
+
+ public void setEncryptInd(int encryptInd) {
+ this.encryptInd = encryptInd;
+ }
+
+ public String getPolicyStatus() {
+ return policyStatus;
+ }
+
+
+ public void setPolicyStatus(String policyStatus) {
+ this.policyStatus = policyStatus;
+ }
+
+ public String getTableSelectionType() {
+ return tableSelectionType;
+ }
+
+
+ public void setTableSelectionType(String tableSelectionType) {
+ this.tableSelectionType = tableSelectionType;
+ }
+
+
+ public String getColumnSelectionType() {
+ return columnSelectionType;
+ }
+
+
+ public void setColumnSelectionType(String columnSelectionType) {
+ this.columnSelectionType = columnSelectionType;
+ }
+
+ public boolean isTableSelectionExcluded() {
+ return (this.tableSelectionType != null && SELECTION_TYPE_EXCLUSIVE.equalsIgnoreCase(this.tableSelectionType)) ;
+ }
+
+ public boolean isColumnSelectionExcluded() {
+ return (this.columnSelectionType != null && SELECTION_TYPE_EXCLUSIVE.equalsIgnoreCase(this.columnSelectionType)) ;
+ }
+
+
+ // An older version of policy manager would show policyStatus as NULL (considered that as Enabled)
+ public boolean isEnabled() {
+ return (this.policyStatus == null || POLICY_ENABLED_STATUS.equalsIgnoreCase(this.policyStatus)) ;
+ }
+
+ public List<ResourcePath> getResourceList() {
+ if (this.resourceList == null) {
+ this.resourceList = getResourceList(resource) ;
+ }
+ return this.resourceList;
+ }
+ public List<String> getDatabaseList() {
+ if (this.databaseList == null) {
+ this.databaseList = getList(this.databases) ;
+ }
+ return this.databaseList;
+ }
+ public List<String> getTableList() {
+ if (this.tableList == null) {
+ this.tableList = getList(this.tables) ;
+ }
+ return this.tableList;
+ }
+ public List<String> getColumnList() {
+ if (this.columnList == null) {
+ this.columnList = getList(this.columns) ;
+ }
+ return this.columnList;
+ }
+ public List<String> getColumnFamilyList() {
+ if (this.columnFamilyList == null) {
+ this.columnFamilyList = getList(this.columnfamilies) ;
+ }
+ return this.columnFamilyList;
+ }
+ public List<String> getUDFList() {
+ if (this.udfList == null && this.udfList != null) {
+ this.udfList = getList(this.udfs) ;
+ }
+ return this.udfList;
+ }
+
+ public List<String> getTopologyList() {
+ if (this.topologyList == null) {
+ this.topologyList = getList(this.topologies) ;
+ }
+ return this.topologyList;
+ }
+
+ public List<String> getServiceList() {
+ if (this.serviceList == null) {
+ this.serviceList = getList(this.services) ;
+ }
+ return this.serviceList;
+ }
+
+
+ private List<String> getList(String resource) {
+ List<String> ret = new ArrayList<String>() ;
+ if (resource == null || resource.trim().isEmpty()) {
+ resource = "*" ;
+ }
+ for(String r : resource.split(RESOURCE_SPLITER)) {
+ ret.add(r) ;
+ }
+
+ return ret;
+ }
+
+ private List<ResourcePath> getResourceList(String resource) {
+ List<ResourcePath> ret = new ArrayList<ResourcePath>() ;
+ if (resource != null && ! resource.isEmpty()) {
+ for(String path : resource.split(RESOURCE_SPLITER)) {
+ ret.add(new ResourcePath(path)) ;
+ }
+ }
+ return ret ;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-impl/src/main/java/org/apache/ranger/pdp/model/PolicyContainer.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/model/PolicyContainer.java b/agents-impl/src/main/java/org/apache/ranger/pdp/model/PolicyContainer.java
new file mode 100644
index 0000000..3674102
--- /dev/null
+++ b/agents-impl/src/main/java/org/apache/ranger/pdp/model/PolicyContainer.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.pdp.model;
+
+import java.util.List;
+
+import com.google.gson.annotations.SerializedName;
+
+public class PolicyContainer {
+
+ @SerializedName("repository_name")
+ private String repositoryName ;
+
+ @SerializedName("last_updated")
+ private long lastUpdatedTimeInEpoc ;
+
+ @SerializedName("acl")
+ private List<Policy> acl;
+
+ public String getRepositoryName() {
+ return repositoryName;
+ }
+ public void setRepositoryName(String repositoryName) {
+ this.repositoryName = repositoryName;
+ }
+ public long getLastUpdatedTimeInEpoc() {
+ return lastUpdatedTimeInEpoc;
+ }
+ public void setLastUpdatedTimeInEpoc(long lastUpdatedTimeInEpoc) {
+ this.lastUpdatedTimeInEpoc = lastUpdatedTimeInEpoc;
+ }
+ public List<Policy> getAcl() {
+ return acl;
+ }
+ public void setAcl(List<Policy> acl) {
+ this.acl = acl;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-impl/src/main/java/org/apache/ranger/pdp/model/ResourcePath.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/model/ResourcePath.java b/agents-impl/src/main/java/org/apache/ranger/pdp/model/ResourcePath.java
new file mode 100644
index 0000000..fa32ed8
--- /dev/null
+++ b/agents-impl/src/main/java/org/apache/ranger/pdp/model/ResourcePath.java
@@ -0,0 +1,43 @@
+/*
+ * 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.pdp.model;
+
+public class ResourcePath {
+
+ String path ;
+ boolean wildcardPath ;
+
+ public ResourcePath(String path) {
+ this.path = path ;
+ if (this.path.contains("*") || this.path.contains("?")) {
+ this.wildcardPath = true ;
+ }
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public boolean isWildcardPath() {
+ return wildcardPath;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-impl/src/main/java/org/apache/ranger/pdp/model/RolePermission.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/model/RolePermission.java b/agents-impl/src/main/java/org/apache/ranger/pdp/model/RolePermission.java
new file mode 100644
index 0000000..accee6c
--- /dev/null
+++ b/agents-impl/src/main/java/org/apache/ranger/pdp/model/RolePermission.java
@@ -0,0 +1,71 @@
+/*
+ * 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.pdp.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RolePermission {
+
+ private List<String> users ;
+ private List<String> groups ;
+ private List<String> access ;
+ private List<String> ipAddress ;
+
+ public RolePermission() {
+ users = new ArrayList<String>() ;
+ groups = new ArrayList<String>() ;
+ access = new ArrayList<String>() ;
+ }
+
+
+ public List<String> getUsers() {
+ return users;
+ }
+
+ public void setUsers(List<String> users) {
+ this.users = users;
+ }
+
+ public List<String> getGroups() {
+ return groups;
+ }
+
+ public void setGroups(List<String> groups) {
+ this.groups = groups;
+ }
+
+ public List<String> getAccess() {
+ return this.access;
+ }
+
+ public List<String> getIpAddress() {
+ return this.ipAddress;
+ }
+
+ public void setIpAddress(List<String> ipAddress) {
+ this.ipAddress = ipAddress ;
+ }
+
+ public void setAccess(List<String> access) {
+ this.access = access ;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-impl/src/main/java/org/apache/ranger/pdp/storm/RangerAuthorizer.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/storm/RangerAuthorizer.java b/agents-impl/src/main/java/org/apache/ranger/pdp/storm/RangerAuthorizer.java
new file mode 100644
index 0000000..f7d3b0f
--- /dev/null
+++ b/agents-impl/src/main/java/org/apache/ranger/pdp/storm/RangerAuthorizer.java
@@ -0,0 +1,61 @@
+/*
+ * 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.pdp.storm;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.authorization.storm.RangerStormAccessVerifier;
+
+public class RangerAuthorizer implements RangerStormAccessVerifier {
+
+ private static final Log LOG = LogFactory.getLog(RangerAuthorizer.class) ;
+
+ private static URLBasedAuthDB authDB = URLBasedAuthDB.getInstance() ;
+
+
+ @Override
+ public boolean isAccessAllowed(String aUserName, String[] aGroupName, String aOperationName, String aTopologyName) {
+ boolean ret = false ;
+
+ if (authDB != null) {
+ ret = authDB.isAccessAllowed(aUserName, aGroupName, aOperationName, aTopologyName) ;
+ }
+ else {
+ LOG.error("Unable to find a URLBasedAuthDB for authorization - Found null");
+ }
+
+ return ret ;
+ }
+
+ @Override
+ public boolean isAudited(String aTopologyName) {
+ boolean ret = false ;
+
+ if (authDB != null) {
+ ret = authDB.isAudited(aTopologyName) ;
+ }
+ else {
+ LOG.error("Unable to find a URLBasedAuthDB for authorization - Found null");
+ }
+
+ return ret ;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-impl/src/main/java/org/apache/ranger/pdp/storm/StormAuthRule.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/storm/StormAuthRule.java b/agents-impl/src/main/java/org/apache/ranger/pdp/storm/StormAuthRule.java
new file mode 100644
index 0000000..f655839
--- /dev/null
+++ b/agents-impl/src/main/java/org/apache/ranger/pdp/storm/StormAuthRule.java
@@ -0,0 +1,136 @@
+/*
+ * 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.pdp.storm;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.ranger.authorization.utils.StringUtil;
+
+public class StormAuthRule {
+ private String topologyName ;
+ private List<String> accessTypeList ;
+ private List<String> groupList ;
+ private List<String> userList;
+ private boolean auditEnabled ;
+
+
+ public StormAuthRule(String topologyName, List<String> accessTypeList,
+ List<String> userList, List<String> groupList, boolean auditEnabled) {
+ super();
+ this.topologyName = topologyName;
+ this.accessTypeList = accessTypeList;
+ if (this.accessTypeList == null) {
+ this.accessTypeList = new ArrayList<String>();
+ }
+ this.userList = userList;
+ if (this.userList == null) {
+ this.userList = new ArrayList<String>();
+ }
+
+ this.groupList = groupList;
+ if (this.groupList == null) {
+ this.groupList = new ArrayList<String>();
+ }
+
+ this.auditEnabled = auditEnabled ;
+ }
+
+ public String getTopologyName() {
+ return topologyName;
+ }
+ public void setTopologyName(String topologyName) {
+ this.topologyName = topologyName;
+ }
+ public List<String> getAccessTypeList() {
+ return accessTypeList;
+ }
+ public void setAccessTypeList(List<String> accessTypeList) {
+ this.accessTypeList = accessTypeList;
+ }
+ public List<String> getGroupList() {
+ return groupList;
+ }
+ public void setGroupList(List<String> groupList) {
+ this.groupList = groupList;
+ }
+ public List<String> getUserList() {
+ return userList;
+ }
+ public void setUserList(List<String> userList) {
+ this.userList = userList;
+ }
+
+ public boolean isMatchedTopology(String aTopologyName) {
+
+ boolean ret = false ;
+
+ if (aTopologyName == null || aTopologyName.length() == 0) {
+ ret = "*".equals(this.topologyName) ;
+ }
+ else {
+ ret = (aTopologyName.equals(this.topologyName) || FilenameUtils.wildcardMatch(aTopologyName,this.topologyName)) ;
+ }
+ return ret ;
+ }
+
+ public boolean isOperationAllowed(String aOperationName) {
+ return this.accessTypeList.contains(aOperationName);
+ }
+
+ private static final String PUBLIC_GROUP_NAME = "public" ;
+
+ public boolean isUserAllowed(String aUserName, String[] aGroupList) {
+
+ boolean accessAllowed = false ;
+
+ if ( this.userList.contains(aUserName) ) {
+ accessAllowed = true ;
+ }
+ else if (this.groupList.contains(PUBLIC_GROUP_NAME)) {
+ accessAllowed = true ;
+ }
+ else if (aGroupList != null ) {
+ for(String userGroup : aGroupList ) {
+ if (this.groupList.contains(userGroup) ) {
+ accessAllowed = true ;
+ break ;
+ }
+ }
+ }
+
+ return accessAllowed ;
+ }
+
+ public boolean getAuditEnabled() {
+ return this.auditEnabled ;
+ }
+
+ @Override
+ public String toString() {
+ return "StormAuthRule: { topologyName: [" + topologyName + "]," +
+ "userList: [" + StringUtil.toString(userList) + "]" +
+ "groupList: [" + StringUtil.toString(groupList) + "]" +
+ "accessTypeList: [" + StringUtil.toString(accessTypeList) + "]" +
+ "auditEnabled: [" + auditEnabled + "] }";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-impl/src/main/java/org/apache/ranger/pdp/storm/URLBasedAuthDB.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/storm/URLBasedAuthDB.java b/agents-impl/src/main/java/org/apache/ranger/pdp/storm/URLBasedAuthDB.java
new file mode 100644
index 0000000..1977fb2
--- /dev/null
+++ b/agents-impl/src/main/java/org/apache/ranger/pdp/storm/URLBasedAuthDB.java
@@ -0,0 +1,176 @@
+/*
+ * 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.pdp.storm;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
+import org.apache.ranger.authorization.storm.RangerStormAccessVerifier;
+import org.apache.ranger.pdp.config.PolicyChangeListener;
+import org.apache.ranger.pdp.config.PolicyRefresher;
+import org.apache.ranger.pdp.constants.RangerConstants;
+import org.apache.ranger.pdp.model.Policy;
+import org.apache.ranger.pdp.model.PolicyContainer;
+import org.apache.ranger.pdp.model.RolePermission;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class URLBasedAuthDB implements PolicyChangeListener, RangerStormAccessVerifier {
+
+ private static final Logger LOG = LoggerFactory.getLogger(URLBasedAuthDB.class) ;
+
+ private static URLBasedAuthDB me = null;
+
+ private PolicyRefresher refresher = null ;
+
+ private PolicyContainer policyContainer = null;
+
+ private List<StormAuthRule> stormAuthDB = null ;
+
+ public static URLBasedAuthDB getInstance() {
+ if (me == null) {
+ synchronized (URLBasedAuthDB.class) {
+ URLBasedAuthDB temp = me;
+ if (temp == null) {
+ me = new URLBasedAuthDB();
+ me.init() ;
+ }
+ }
+ }
+ return me;
+ }
+
+ private URLBasedAuthDB() {
+
+ String url = RangerConfiguration.getInstance().get(RangerConstants.RANGER_STORM_POLICYMGR_URL_PROP);
+
+ long refreshInMilli = RangerConfiguration.getInstance().getLong(
+ RangerConstants.RANGER_STORM_POLICYMGR_URL_RELOAD_INTERVAL_IN_MILLIS_PROP ,
+ RangerConstants.RANGER_STORM_POLICYMGR_URL_RELOAD_INTERVAL_IN_MILLIS_DEFAULT);
+
+ String lastStoredFileName = RangerConfiguration.getInstance().get(RangerConstants.RANGER_STORM_LAST_SAVED_POLICY_FILE_PROP) ;
+
+ String sslConfigFileName = RangerConfiguration.getInstance().get(RangerConstants.RANGER_STORM_POLICYMGR_SSL_CONFIG_FILE_PROP) ;
+
+ refresher = new PolicyRefresher(url, refreshInMilli,sslConfigFileName,lastStoredFileName) ;
+
+ String saveAsFileName = RangerConfiguration.getInstance().get(RangerConstants.RANGER_STORM_POLICYMGR_URL_SAVE_FILE_PROP) ;
+ if (saveAsFileName != null) {
+ refresher.setSaveAsFileName(saveAsFileName) ;
+ }
+
+ if (lastStoredFileName != null) {
+ refresher.setLastStoredFileName(lastStoredFileName);
+ }
+ }
+
+
+ private void init() {
+ refresher.setPolicyChangeListener(this);
+ }
+
+
+ @Override
+ public void OnPolicyChange(PolicyContainer aPolicyContainer) {
+ setPolicyContainer(aPolicyContainer);
+ }
+
+
+ public PolicyContainer getPolicyContainer() {
+ return policyContainer;
+ }
+
+
+
+ public synchronized void setPolicyContainer(PolicyContainer aPolicyContainer) {
+
+ if (aPolicyContainer != null) {
+
+ List<StormAuthRule> tempStormAuthDB = new ArrayList<StormAuthRule>() ;
+
+ for(Policy p : aPolicyContainer.getAcl()) {
+
+ if (! p.isEnabled()) {
+ continue;
+ }
+
+ for (String topologyName : p.getTopologyList()) {
+
+ List<RolePermission> rpList = p.getPermissions() ;
+
+ for(RolePermission rp : rpList) {
+ StormAuthRule rule = new StormAuthRule(topologyName, rp.getAccess() , rp.getUsers(), rp.getGroups(), (p.getAuditInd() == 1)) ;
+ tempStormAuthDB.add(rule) ;
+ }
+ }
+ }
+
+ this.stormAuthDB = tempStormAuthDB ;
+
+ this.policyContainer = aPolicyContainer ;
+ }
+ }
+
+ @Override
+ public boolean isAccessAllowed(String aUserName, String[] aGroupName, String aOperationName, String aTopologyName) {
+
+ boolean accessAllowed = false ;
+
+ List<StormAuthRule> tempStormAuthDB = this.stormAuthDB ;
+
+ if (tempStormAuthDB != null) {
+ for(StormAuthRule rule : tempStormAuthDB) {
+ if (rule.isMatchedTopology(aTopologyName)) {
+ if (rule.isOperationAllowed(aOperationName)) {
+ if (rule.isUserAllowed(aUserName, aGroupName)) {
+ accessAllowed = true ;
+ break ;
+ }
+ }
+ }
+ }
+ }
+
+ return accessAllowed ;
+ }
+
+ @Override
+ public boolean isAudited(String aTopologyName) {
+ boolean auditEnabled = false ;
+
+ List<StormAuthRule> tempStormAuthDB = stormAuthDB ;
+
+ if (tempStormAuthDB != null) {
+ for(StormAuthRule rule : tempStormAuthDB) {
+ if (rule.isMatchedTopology(aTopologyName)) {
+ auditEnabled = rule.getAuditEnabled() ;
+ if (auditEnabled) {
+ break ;
+ }
+ }
+ }
+ }
+
+ return auditEnabled ;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-impl/src/main/java/org/apache/ranger/pdp/utils/RangerUtils.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/utils/RangerUtils.java b/agents-impl/src/main/java/org/apache/ranger/pdp/utils/RangerUtils.java
new file mode 100644
index 0000000..27e7dee
--- /dev/null
+++ b/agents-impl/src/main/java/org/apache/ranger/pdp/utils/RangerUtils.java
@@ -0,0 +1,49 @@
+/*
+ * 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.pdp.utils;
+
+import java.io.File;
+import java.net.URL;
+
+public class RangerUtils {
+
+ public static String getFilePathFromClassPath(String aFileName) {
+ String pathName = null;
+
+ File lf = new File(aFileName) ;
+
+ if (lf.exists()) {
+ pathName = lf.getAbsolutePath();
+ }
+ else {
+ URL lurl = RangerUtils.class.getResource(aFileName);
+ if (lurl == null) {
+ if (!aFileName.startsWith("/")) {
+ lurl = RangerUtils.class.getResource("/" + aFileName);
+ }
+ }
+ if (lurl != null) {
+ pathName = lurl.getFile();
+ }
+ }
+ return pathName;
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-impl/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor b/agents-impl/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
index 44483f0..6db0bdc 100644
--- a/agents-impl/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
+++ b/agents-impl/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
@@ -15,4 +15,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##########################################################################
-com.xasecure.pdp.knox.deploy.XASecurePDPKnoxDeploymentContributor
+org.apache.ranger.pdp.knox.deploy.RangerPDPKnoxDeploymentContributor
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-impl/src/test/java/com/xasecure/pdp/hdfs/PolicyCacheStoreTest.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/test/java/com/xasecure/pdp/hdfs/PolicyCacheStoreTest.java b/agents-impl/src/test/java/com/xasecure/pdp/hdfs/PolicyCacheStoreTest.java
deleted file mode 100644
index 2b1b508..0000000
--- a/agents-impl/src/test/java/com/xasecure/pdp/hdfs/PolicyCacheStoreTest.java
+++ /dev/null
@@ -1,169 +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 com.xasecure.pdp.hdfs;
-
-import java.io.BufferedReader;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.junit.Before;
-import org.junit.After;
-import org.junit.Test;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.xasecure.pdp.config.ConfigWatcher;
-import com.xasecure.pdp.config.PolicyRefresher;
-import com.xasecure.pdp.model.Policy;
-import com.xasecure.pdp.model.PolicyContainer;
-import com.xasecure.pdp.model.RolePermission;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-
-public class PolicyCacheStoreTest {
- URLBasedAuthDB authDB = null;
- ConfigWatcher watcherDaemon = null;
- PolicyRefresher pr = null;
- PolicyContainer policyContainer=null;
- String url=null;
- String sslConfigFileName=null;
- String lastStoredFileName=null;
- Long refreshInterval =0L;
- private static final Log LOG = LogFactory.getLog(PolicyCacheStoreTest.class);
- @Before
- public void setup(){
- authDB = URLBasedAuthDB.getInstance();
-
- }
-
- @After
- public void teardown(){
- authDB = null;
- PolicyRefresher pr = null;
- }
-
- @Test
- public void testHdfsPolicyCacheStore(){
- //Check if the policy cache gets created when agent get created;
- url="dummyurl";
- refreshInterval=10L;
- sslConfigFileName = "dummyConfigFileName.xml";
- lastStoredFileName = System.getProperty("user.home") +"/"+ "haooopPolicyCache.json";
- policyContainer = buildPolicyContainer(
- "/demo/data",
- 1,
- asList("allow"),
- asList("guest"),
- asList("sales"),
- null, // ipAddress
- true, // policyEnabled
- true); // auditEnabled
- authDB.OnPolicyChange(policyContainer);
- pr = spy(new PolicyRefresher(url,refreshInterval,sslConfigFileName,lastStoredFileName));
- pr.setPolicyContainer(policyContainer);
- pr.setPolicyChangeListener(authDB);
- PolicyContainer newPr = readPolicyCache(lastStoredFileName);
- assertEquals(policyToString(policyContainer),policyToString(newPr));
- }
-
- private static PolicyContainer buildPolicyContainer(String resource,
- int recursiveInd, List<String> accessTypes, List<String> users,
- List<String> groups, List<String> ipAddresses,
- boolean policyEnabled, boolean auditEnabled) {
-
- PolicyContainer policyContainer = new PolicyContainer();
- policyContainer.setRepositoryName("hadoopdev");
-
- List<Policy> policies = new ArrayList<Policy>();
-
- Policy policy = new Policy();
- policy.setResource(resource);
- policy.setRecursiveInd(recursiveInd);
- policy.setPolicyStatus(policyEnabled ? "Enabled" : "NotEnabled");
- policy.setAuditInd(auditEnabled ? 1 : 0);
-
- List<RolePermission> rolePermissions = new ArrayList<RolePermission>();
-
- RolePermission rolePermission = new RolePermission();
-
- rolePermissions.add(rolePermission);
- rolePermission.setAccess(accessTypes);
- rolePermission.setUsers(users);
- rolePermission.setGroups(groups);
- rolePermission.setIpAddress(ipAddresses);
-
- policy.setPermissions(rolePermissions);
-
- policies.add(policy);
-
- policyContainer.setAcl(policies);
-
- return policyContainer;
- }
-
- private static Set<String> asSet(String... a) {
- Set<String> vals = new HashSet<String>();
- for (String s : a) {
- vals.add(s);
- }
- return vals;
- }
-
- private static List<String> asList(String... a) {
- List<String> vals = new ArrayList<String>();
- for (String s : a) {
- vals.add(s);
- }
- return vals;
- }
-
-
- private PolicyContainer readPolicyCache(String lastStoreFileName) {
- BufferedReader jsonString = null;
- try {
- jsonString = new BufferedReader(new FileReader(lastStoredFileName));
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- Gson gson = new GsonBuilder().create();
- PolicyContainer newPolicyContainer = gson.fromJson(jsonString, PolicyContainer.class);
- return newPolicyContainer;
- }
-
- private String policyToString(PolicyContainer pc) {
- Gson gson = new GsonBuilder().create() ;
- String policyAsJson = gson.toJson(policyContainer) ;
- return policyAsJson;
- }
-
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-impl/src/test/java/com/xasecure/pdp/hdfs/URLBasedAuthDBTest.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/test/java/com/xasecure/pdp/hdfs/URLBasedAuthDBTest.java b/agents-impl/src/test/java/com/xasecure/pdp/hdfs/URLBasedAuthDBTest.java
deleted file mode 100644
index 4a19d98..0000000
--- a/agents-impl/src/test/java/com/xasecure/pdp/hdfs/URLBasedAuthDBTest.java
+++ /dev/null
@@ -1,66 +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 com.xasecure.pdp.hdfs;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.junit.Test;
-
-import com.xasecure.pdp.model.Policy;
-import com.xasecure.pdp.model.PolicyContainer;
-import com.xasecure.pdp.model.ResourcePath;
-
-public class URLBasedAuthDBTest {
-
- @Test
- public void testIsAuditLogEnabledByACL_emptyPolicyContainer() {
-
- // audit can't be enabled if authdb isn't initialized
- assertFalse(mAuthDB.isAuditLogEnabledByACL("blah"));
-
- // or if the policy container in is null!
- URLBasedAuthDB spy = spy(mAuthDB);
- when(spy.getPolicyContainer()).thenReturn(null);
- assertFalse(mAuthDB.isAuditLogEnabledByACL("blah"));
-
- // of if policy container is empty, i.e. has no policies!
- List<Policy> policies = new ArrayList<Policy>();
- PolicyContainer policyContainer = mock(PolicyContainer.class);
- when(policyContainer.getAcl()).thenReturn(policies);
- when(spy.getPolicyContainer()).thenReturn(policyContainer);
- assertFalse(mAuthDB.isAuditLogEnabledByACL("blah"));
-
- // or if all policies are empty, i.e. no acls!
- Policy aPolicy = mock(Policy.class);
- when(aPolicy.getResourceList()).thenReturn(new ArrayList<ResourcePath>());
- policies.add(aPolicy);
- when(policyContainer.getAcl()).thenReturn(policies);
- when(spy.getPolicyContainer()).thenReturn(policyContainer);
- assertFalse(spy.isAuditLogEnabledByACL("blah"));
- }
-
- private final URLBasedAuthDB mAuthDB = URLBasedAuthDB.getInstance();
-}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-impl/src/test/java/com/xasecure/pdp/hdfs/URLBasedAuthDB_IsAuditLogEnabledByACL_PTest.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/test/java/com/xasecure/pdp/hdfs/URLBasedAuthDB_IsAuditLogEnabledByACL_PTest.java b/agents-impl/src/test/java/com/xasecure/pdp/hdfs/URLBasedAuthDB_IsAuditLogEnabledByACL_PTest.java
deleted file mode 100644
index 02c81f5..0000000
--- a/agents-impl/src/test/java/com/xasecure/pdp/hdfs/URLBasedAuthDB_IsAuditLogEnabledByACL_PTest.java
+++ /dev/null
@@ -1,340 +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 com.xasecure.pdp.hdfs;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-import com.xasecure.pdp.model.Policy;
-import com.xasecure.pdp.model.PolicyContainer;
-import com.xasecure.pdp.model.ResourcePath;
-
-@RunWith(Parameterized.class)
-public class URLBasedAuthDB_IsAuditLogEnabledByACL_PTest {
-
- static class PolicyIs {
- static final boolean wildcard = true;
- static final boolean audited = true;
- static final boolean recursive = true;
-
- static final boolean notWildcard = false;
- static final boolean notAudited = false;
- static final boolean notRecursive = false;
- }
-
- static final class PolicyPath {
- static final String path1 = "aPath";
- static final String path1Child1 = PolicyPath.path1 + "/" + "child1";
- static final String path1Child2 = PolicyPath.path1 + "/" + "child2";
-
- static final String path2 = "anotherPath";
- }
- static final class TestPath {
- static final String path1 = PolicyPath.path1;
- static final String beginsWithPath1 = PolicyPath.path1 + "_";
- static final String path1Child1 = PolicyPath.path1Child1;
- static final String path1Child2 = PolicyPath.path1Child2;
- static final String path1GrandChild1 = String.format("%s/%s/%s", path1, path1Child1, "grandChild1");
- static final String path1GrandChild2 = String.format("%s/%s/%s", path1, path1Child1, "grandChild2");
-
- static final String path2 = PolicyPath.path2;
- static final String beginsWithPath2 = PolicyPath.path2 + "_";
- static final String path2Child1 = PolicyPath.path2 + "/" + "child1";
- static final String path2Child2 = PolicyPath.path2 + "/" + "child2";
- }
-
- static class ExpectedResult {
- static final class AuditEnabled {
- static final boolean yes = true;
- static final boolean no = false;
- }
- }
-
- static class TestDataIndex {
- static final int ExpectedResult = 6;
- static final int Audited = 3;
- public static final int TestName = 0;
- public static final int wildCard = 2;
- }
-
-
- /**
- * ASSUMPTION: set of tests passed as such that they require wildcard flag to be set for them to return audit enabled.
- * So turn wildcard flag of them off to assert that they no-longer work. Of course, those that don't work even with wildcard
- * should also continue to not work when wildcard is turned off!
- */
- private static List<Object[]> turnWildcardOffForTestsThatRequireWildcard(List<Object[]> tests) {
-
- // in the worse case we would generate one test for each existing test
- List<Object[]> newTests = new ArrayList<Object[]>(tests.size());
- for (Object[] aTest: tests) {
- boolean isPolicyWildcard = (Boolean) aTest[TestDataIndex.wildCard];
- if (isPolicyWildcard == PolicyIs.wildcard) {
- Object[] newTest = Arrays.copyOf(aTest, aTest.length);
- // Change the policy of this test so that Audit is disabled at policy level and accordingly change the expected result
- newTest[TestDataIndex.wildCard] = PolicyIs.notWildcard;
- newTest[TestDataIndex.ExpectedResult] = ExpectedResult.AuditEnabled.no;
- // for debugging purposes alter the test description, too
- String testName = (String) newTest[TestDataIndex.TestName];
- newTest[TestDataIndex.TestName] = "[Wildcard-ed base test with wildcard flag turned off] " + testName;
- newTests.add(newTest);
- }
- }
- return newTests;
- }
-
- /**
- * wildcard - policy flag says wildcard by the policy path itself does not have any wildcards worth expanding.
- * This should work exactly the same as if wildcard was turned off!
- */
- private static List<Object[]> turnWildcardOnForNonWildcardTests(List<Object[]> tests) {
-
- // in the worse case we would generate one test for each existing test
- List<Object[]> newTests = new ArrayList<Object[]>(tests.size());
- /*
- * If a test currently does not have wildcard set on it, then expectation is changing wildcard flag
- * true shouldn't change the result. ASSUMPTION here, of course, is that "base tests" don't use any
- * wild-card characters in their resource paths that would make an otherwise disabled audit to return enabled.
- */
- for (Object[] aTest: tests) {
- boolean isPolicyWildcard = (Boolean) aTest[TestDataIndex.wildCard];
- if (isPolicyWildcard == PolicyIs.notWildcard) {
- Object[] newTest = Arrays.copyOf(aTest, aTest.length);
- // Change the policy of this test so that Audit is disabled at policy level and accordingly change the expected result
- newTest[TestDataIndex.wildCard] = PolicyIs.wildcard;
- // for debugging purposes alter the test description, too
- String testName = (String) newTest[TestDataIndex.TestName];
- newTest[TestDataIndex.TestName] = "[Base test with wildcard enabled] " + testName;
- newTests.add(newTest);
- }
- }
- return newTests;
- }
-
- /**
- * Disabled audit on every test that expects result to be yes to ensure that no matter what answer should be false if policy says that audit is disabled!
- */
- private static List<Object[]> disableAuditForBaseTests(List<Object[]> tests) {
-
- List<Object[]> newTests = new ArrayList<Object[]>(tests.size());
-
- for (Object[] aTest : tests) {
- boolean expectedResult = (Boolean) aTest[TestDataIndex.ExpectedResult];
- boolean isPolicyAuditEnabled = (Boolean) aTest[TestDataIndex.Audited];
-
- if (expectedResult == ExpectedResult.AuditEnabled.yes
- && isPolicyAuditEnabled == PolicyIs.audited) {
- Object[] newTest = Arrays.copyOf(aTest, aTest.length);
- // Change the policy of this test so that Audit is disabled at policy level and accordingly change the expected result
- newTest[TestDataIndex.Audited] = PolicyIs.notAudited;
- newTest[TestDataIndex.ExpectedResult] = ExpectedResult.AuditEnabled.no;
- // for debugging purposes alter the test description, too
- String testName = (String) newTest[TestDataIndex.TestName];
- newTest[TestDataIndex.TestName] = "[Base tests with audit disabled] " + testName;
- newTests.add(newTest);
- }
- }
-
- return newTests;
- }
-
- @Parameters
- public static Collection<Object[]> data() {
- Object[][] baseTestData = new Object[][] {
-
- // no-recursive paths - return true if paths match
- {"policypath(path1) == testpath(path1) => yes",
- PolicyPath.path1, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.notRecursive, TestPath.path1, ExpectedResult.AuditEnabled.yes},
- {"policypath(path2) == testpath(path2) => yes",
- PolicyPath.path2, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.notRecursive, TestPath.path2, ExpectedResult.AuditEnabled.yes},
-
- // no-recursive paths - return false if paths don't match!
- {"policypath(path1) != testPath(path2) => no",
- PolicyPath.path1, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.notRecursive, TestPath.path2, ExpectedResult.AuditEnabled.no},
- {"policypath(path2) != testPath(path1) => no",
- PolicyPath.path2, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.notRecursive, TestPath.path1, ExpectedResult.AuditEnabled.no},
-
- // recursive path policy - should work at least as well as non-recursive, i.e. match when same and not otherwise!
- {"recursive, policypath(path1) == testpath(path1)",
- PolicyPath.path1, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.recursive, TestPath.path1, ExpectedResult.AuditEnabled.yes},
- {"recursive, policypath(path2) == testpath(path2)",
- PolicyPath.path2, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.recursive, TestPath.path2, ExpectedResult.AuditEnabled.yes},
- {"recursive, policypath(path1) == testpath(path2)",
- PolicyPath.path1, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.recursive, TestPath.path2, ExpectedResult.AuditEnabled.no},
- {"recursive, policypath(path1) == testpath(path2)",
- PolicyPath.path2, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.recursive, TestPath.path1, ExpectedResult.AuditEnabled.no},
-
- // recursive path policy - should match children
- {"recursive, policypath(path1) == testpath(path1/child1)",
- PolicyPath.path1, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.recursive, TestPath.path1Child1, ExpectedResult.AuditEnabled.yes},
- {"recursive, policypath(path1) == testpath(path1/child2)",
- PolicyPath.path1, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.recursive, TestPath.path1Child2, ExpectedResult.AuditEnabled.yes},
- {"recursive, policypath(path1) == testpath(path1/child1)",
- PolicyPath.path2, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.recursive, TestPath.path2Child1, ExpectedResult.AuditEnabled.yes},
- {"recursive, policypath(path1) == testpath(path1/child2)",
- PolicyPath.path2, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.recursive, TestPath.path2Child2, ExpectedResult.AuditEnabled.yes},
-
- // recursive path policy - should match grand children, too!
- {"recursive, policypath(path1) == testpath(path1/child1/grandChild1)",
- PolicyPath.path1, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.recursive, TestPath.path1GrandChild1, ExpectedResult.AuditEnabled.yes},
- {"recursive, policypath(path1) == testpath(path1/child1/grandChild2)",
- PolicyPath.path1, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.recursive, TestPath.path1GrandChild2, ExpectedResult.AuditEnabled.yes},
-
- // recursive path policy - shouldn't match child in some other directory
- {"recursive, policypath(path1) == testpath(path1/child1)",
- PolicyPath.path1, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.recursive, TestPath.path2Child1, ExpectedResult.AuditEnabled.no},
- {"recursive, policypath(path1) == testpath(path1/child2)",
- PolicyPath.path1, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.recursive, TestPath.path2Child2, ExpectedResult.AuditEnabled.no},
- {"recursive, policypath(path1) == testpath(path1/child1)",
- PolicyPath.path2, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.recursive, TestPath.path1Child1, ExpectedResult.AuditEnabled.no},
- {"recursive, policypath(path1) == testpath(path1/child2)",
- PolicyPath.path2, PolicyIs.notWildcard, PolicyIs.audited, PolicyIs.recursive, TestPath.path1Child2, ExpectedResult.AuditEnabled.no},
-
- };
-
- Object[][] wildCardTestData = new Object[][] {
- // Pattern contains exact substring
- {"Wildcard, Pattern contains substring of tested path - 1",
- "aPath*", PolicyIs.wildcard, PolicyIs.audited, PolicyIs.recursive, "aPath", ExpectedResult.AuditEnabled.yes},
- {"Wildcard, Pattern contains substring of tested path - 2",
- "*aPath", PolicyIs.wildcard, PolicyIs.audited, PolicyIs.recursive, "aPath", ExpectedResult.AuditEnabled.yes},
- {"Wildcard, Pattern contains substring of tested path - 3",
- "aPa*th", PolicyIs.wildcard, PolicyIs.audited, PolicyIs.recursive, "aPath", ExpectedResult.AuditEnabled.yes},
- {"Wildcard, Pattern contains substring of tested path - 4",
- "aP*at*h", PolicyIs.wildcard, PolicyIs.audited, PolicyIs.recursive, "aPath", ExpectedResult.AuditEnabled.yes},
-
- // Pattern should match
- {"Wildcard, Pattern should match - 1",
- "aPath*", PolicyIs.wildcard, PolicyIs.audited, PolicyIs.recursive, "aPath_", ExpectedResult.AuditEnabled.yes},
- {"Wildcard, Pattern should match - 2",
- "aPath*", PolicyIs.wildcard, PolicyIs.audited, PolicyIs.recursive, "aPath_longSuffix", ExpectedResult.AuditEnabled.yes},
- {"Wildcard, Pattern should match - 3",
- "*aPath", PolicyIs.wildcard, PolicyIs.audited, PolicyIs.recursive, "_aPath", ExpectedResult.AuditEnabled.yes},
- {"Wildcard, Pattern should match - 4",
- "*aPath", PolicyIs.wildcard, PolicyIs.audited, PolicyIs.recursive, "longPrefix_aPath", ExpectedResult.AuditEnabled.yes},
- {"Wildcard, Pattern should match - 5",
- "*aPath", PolicyIs.wildcard, PolicyIs.audited, PolicyIs.recursive, "_aPath", ExpectedResult.AuditEnabled.yes},
- {"Wildcard, Pattern should match - 6",
- "*aPath", PolicyIs.wildcard, PolicyIs.audited, PolicyIs.recursive, "longPrefix_aPath", ExpectedResult.AuditEnabled.yes},
- {"Wildcard, Pattern should match - 5",
- "a*Path", PolicyIs.wildcard, PolicyIs.audited, PolicyIs.recursive, "a___Path", ExpectedResult.AuditEnabled.yes},
- {"Wildcard, Pattern should match - 6",
- "a*Path", PolicyIs.wildcard, PolicyIs.audited, PolicyIs.recursive, "aMiddlePath", ExpectedResult.AuditEnabled.yes},
- };
-
- // in the worst case all tests have a corresponding audit disabled test
- List<Object[]> baseTests = Arrays.asList(baseTestData);
- List<Object[]> result = new ArrayList<Object[]>(baseTests);
-
- // answer is false no matter what if policy is set to not audit
- List<Object[]> additionalTests = disableAuditForBaseTests(baseTests);
- result.addAll(additionalTests);
-
- // turning wildcard flag on when policy path itself does not have wildcard characters in it shouldn't change the result!
- additionalTests = turnWildcardOnForNonWildcardTests(baseTests);
- result.addAll(additionalTests);
-
- List<Object[]> wildcardBaseTests = Arrays.asList(wildCardTestData);
- result.addAll(wildcardBaseTests);
-
- additionalTests = turnWildcardOffForTestsThatRequireWildcard(wildcardBaseTests);
- result.addAll(additionalTests);
- return result;
- }
-
- public URLBasedAuthDB_IsAuditLogEnabledByACL_PTest(String testName, String policyPath, boolean wildCard, boolean audited, boolean recursive, String testPath, boolean expectedResult) {
- _testName = testName;
- _policyPath = policyPath;
- _policyPathWildcard = wildCard;
- _policyAudited = audited;
- _policyRecursive = recursive;
- _testPath = testPath;
- _expectedResult = expectedResult;
- }
-
- private final String _testName;
- private final String _policyPath;
- private final boolean _policyPathWildcard;
- private final boolean _policyAudited;
- private final boolean _policyRecursive;
- private final String _testPath;
- private final boolean _expectedResult;
-
- @Test
- public void testIsAuditLogEnabledByACL() {
-
- if (LOG.isDebugEnabled()) {
- LOG.debug(String.format("Test: %sPolicy Path: %s, isWildcard: %b, isAudited: %b, isRecursive: %b, TestPath: %s",
- _testName, _policyPath, _policyPathWildcard, _policyAudited, _policyRecursive, _testPath));
- }
-
- // A policy can have several paths, so let's first stuff our path into a collection
- ResourcePath path = mock(ResourcePath.class);
- when(path.getPath()).thenReturn(_policyPath);
- when(path.isWildcardPath()).thenReturn(_policyPathWildcard);
- List<ResourcePath> resourcePaths = new ArrayList<ResourcePath>();
- resourcePaths.add(path);
-
- // wire it into the policy and set other aspects of the policy
- Policy aPolicy = mock(Policy.class);
- when(aPolicy.getResourceList()).thenReturn(resourcePaths);
-
- int recursiveIndicator = _policyRecursive ? 1 : 0;
- when(aPolicy.getRecursiveInd()).thenReturn(recursiveIndicator);
-
- int auditedIndicator = _policyAudited ? 1 : 0;
- when(aPolicy.getAuditInd()).thenReturn(auditedIndicator);
-
- // a container can have several policies to first we stuff our policy into a container
- List<Policy> policies = new ArrayList<Policy>();
- policies.add(aPolicy);
- // now wire the policy into the container
- PolicyContainer policyContainer = mock(PolicyContainer.class);
- when(policyContainer.getAcl()).thenReturn(policies);
-
- // finally wire the policy container into the authdb
- URLBasedAuthDB spy = spy(mAuthDB);
- when(spy.getPolicyContainer()).thenReturn(policyContainer);
-
- // assert the result
- boolean result = spy.isAuditLogEnabledByACL(_testPath);
- assertThat(_testName, result, is(_expectedResult));
- if (LOG.isDebugEnabled()) {
- LOG.debug(String.format(", Expected Result (Audit enabled?): %b Result: %b\n", _expectedResult, result));
- }
- }
-
- private final URLBasedAuthDB mAuthDB = URLBasedAuthDB.getInstance();
- private static final Log LOG = LogFactory.getLog(URLBasedAuthDB_IsAuditLogEnabledByACL_PTest.class) ;
-}