SENTRY-641: Add binding for lily hbase indexer (Mano Kovacs, reviewed by Sergio Pena)
Project: http://git-wip-us.apache.org/repos/asf/sentry/repo Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/6b644c97 Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/6b644c97 Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/6b644c97 Branch: refs/heads/master Commit: 6b644c97a5ddb39b0848abd954017a8585430723 Parents: 4dc0171 Author: Sergio Pena <[email protected]> Authored: Thu Jan 11 11:04:44 2018 -0600 Committer: Sergio Pena <[email protected]> Committed: Thu Jan 11 11:04:44 2018 -0600 ---------------------------------------------------------------------- pom.xml | 10 +- sentry-binding/pom.xml | 1 + .../sentry-binding-hbase-indexer/pom.xml | 60 ++++ .../authz/HBaseIndexerAuthzBinding.java | 219 +++++++++++++ .../conf/HBaseIndexerAuthzConf.java | 84 +++++ .../TestHBaseIndexerAuthzBinding.java | 309 +++++++++++++++++++ .../src/test/resources/log4j.properties | 31 ++ .../src/test/resources/sentry-site-service.xml | 29 ++ .../src/test/resources/sentry-site.xml | 29 ++ .../src/test/resources/test-authz-provider.ini | 37 +++ sentry-dist/pom.xml | 8 +- sentry-dist/src/license/THIRD-PARTY.properties | 9 +- sentry-policy/pom.xml | 1 - sentry-policy/sentry-policy-indexer/pom.xml | 91 ------ .../indexer/IndexerWildcardPrivilege.java | 159 ---------- .../indexer/SimpleIndexerPolicyEngine.java | 110 ------- .../AbstractTestIndexerPolicyEngine.java | 129 -------- .../policy/indexer/IndexPolicyTestUtil.java | 44 --- .../indexer/TestCommonPrivilegeForIndexer.java | 221 ------------- ...ndexerAuthorizationProviderGeneralCases.java | 179 ----------- ...ndexerAuthorizationProviderSpecialCases.java | 84 ----- .../indexer/TestIndexerModelAuthorizables.java | 54 ---- .../indexer/TestIndexerPolicyEngineDFS.java | 74 ----- .../indexer/TestIndexerPolicyEngineLocalFS.java | 43 --- .../indexer/TestIndexerPolicyNegative.java | 101 ------ .../indexer/TestIndexerRequiredInRole.java | 64 ---- .../src/test/resources/log4j.properties | 31 -- .../src/test/resources/test-authz-provider.ini | 31 -- .../provider/common/AuthorizationComponent.java | 1 + 29 files changed, 813 insertions(+), 1430 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index c797181..6f9856e 100644 --- a/pom.xml +++ b/pom.xml @@ -510,6 +510,11 @@ limitations under the License. </dependency> <dependency> <groupId>org.apache.sentry</groupId> + <artifactId>sentry-binding-hbase-indexer</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.sentry</groupId> <artifactId>sentry-binding-solr</artifactId> <version>${project.version}</version> </dependency> @@ -587,11 +592,6 @@ limitations under the License. </dependency> <dependency> <groupId>org.apache.sentry</groupId> - <artifactId>sentry-policy-indexer</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.apache.sentry</groupId> <artifactId>sentry-tools</artifactId> <version>${project.version}</version> </dependency> http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-binding/pom.xml ---------------------------------------------------------------------- diff --git a/sentry-binding/pom.xml b/sentry-binding/pom.xml index b12683c..17b0f1a 100644 --- a/sentry-binding/pom.xml +++ b/sentry-binding/pom.xml @@ -34,6 +34,7 @@ limitations under the License. <module>sentry-binding-hive-common</module> <module>sentry-binding-solr</module> <module>sentry-binding-sqoop</module> + <module>sentry-binding-hbase-indexer</module> <module>sentry-binding-hive-conf</module> <module>sentry-binding-hive-follower</module> </modules> http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-binding/sentry-binding-hbase-indexer/pom.xml ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hbase-indexer/pom.xml b/sentry-binding/sentry-binding-hbase-indexer/pom.xml new file mode 100644 index 0000000..d50acfe --- /dev/null +++ b/sentry-binding/sentry-binding-hbase-indexer/pom.xml @@ -0,0 +1,60 @@ +<?xml version="1.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. +--> +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.sentry</groupId> + <artifactId>sentry-binding</artifactId> + <version>2.1.0-SNAPSHOT</version> + </parent> + + <artifactId>sentry-binding-hbase-indexer</artifactId> + <name>Sentry Binding for HBase Indexer</name> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.sentry</groupId> + <artifactId>sentry-core-common</artifactId> + </dependency> + <dependency> + <groupId>org.apache.sentry</groupId> + <artifactId>sentry-core-model-indexer</artifactId> + </dependency> + <dependency> + <groupId>org.apache.sentry</groupId> + <artifactId>sentry-provider-common</artifactId> + </dependency> + <dependency> + <groupId>org.apache.sentry</groupId> + <artifactId>sentry-provider-db</artifactId> + </dependency> + <dependency> + <groupId>org.apache.hadoop</groupId> + <artifactId>hadoop-common</artifactId> + <scope>provided</scope> + </dependency> + </dependencies> + +</project> http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-binding/sentry-binding-hbase-indexer/src/main/java/org/apache/sentry/binding/hbaseindexer/authz/HBaseIndexerAuthzBinding.java ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hbase-indexer/src/main/java/org/apache/sentry/binding/hbaseindexer/authz/HBaseIndexerAuthzBinding.java b/sentry-binding/sentry-binding-hbase-indexer/src/main/java/org/apache/sentry/binding/hbaseindexer/authz/HBaseIndexerAuthzBinding.java new file mode 100644 index 0000000..d919fe7 --- /dev/null +++ b/sentry-binding/sentry-binding-hbase-indexer/src/main/java/org/apache/sentry/binding/hbaseindexer/authz/HBaseIndexerAuthzBinding.java @@ -0,0 +1,219 @@ +/* + * 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.sentry.binding.hbaseindexer.authz; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.security.SecurityUtil; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.sentry.binding.hbaseindexer.conf.HBaseIndexerAuthzConf; +import org.apache.sentry.binding.hbaseindexer.conf.HBaseIndexerAuthzConf.AuthzConfVars; +import org.apache.sentry.core.common.ActiveRoleSet; +import org.apache.sentry.core.common.Model; +import org.apache.sentry.core.common.Subject; +import org.apache.sentry.core.common.exception.SentryAccessDeniedException; +import org.apache.sentry.core.model.indexer.Indexer; +import org.apache.sentry.core.model.indexer.IndexerModelAction; +import org.apache.sentry.core.model.indexer.IndexerPrivilegeModel; +import org.apache.sentry.policy.common.PolicyEngine; +import org.apache.sentry.provider.common.AuthorizationProvider; +import org.apache.sentry.provider.common.ProviderBackend; +import org.apache.sentry.provider.common.ProviderBackendContext; +import org.apache.sentry.service.thrift.ServiceConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumSet; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.apache.hadoop.fs.CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION; +import static org.apache.sentry.provider.common.AuthorizationComponent.HBASE_INDEXER; + +/** + * This class provides functionality to initialize the Sentry as + * well as query the permissions for a given user over indexers for HBase-Indexer. + */ +public class HBaseIndexerAuthzBinding { + private static final Logger LOG = LoggerFactory + .getLogger(HBaseIndexerAuthzBinding.class); + private static final String[] HADOOP_HBASE_CONF_FILES = {"core-site.xml", + "hdfs-site.xml", "mapred-site.xml", "yarn-site.xml", "hadoop-site.xml", "hbase-site.xml"}; + public static final String HBASE_REGIONSERVER_KEYTAB_FILE = "hbase.regionserver.keytab.file"; + public static final String HBASE_REGIONSERVER_KERBEROS_PRINCIPAL = "hbase.regionserver.kerberos.principal"; + private static final AtomicBoolean kerberosInit = new AtomicBoolean(false); + + private final HBaseIndexerAuthzConf authzConf; + private final AuthorizationProvider authProvider; + private ProviderBackend providerBackend; + + public HBaseIndexerAuthzBinding (HBaseIndexerAuthzConf authzConf) throws Exception { + this.authzConf = addHdfsPropsToConf(authzConf); + this.authProvider = getAuthProvider(); + } + + // Instantiate the configured authz provider + private AuthorizationProvider getAuthProvider() throws Exception { + // get the provider class and resources from the authz config + String authProviderName = authzConf.get(AuthzConfVars.AUTHZ_PROVIDER.getVar()); + String resourceName = + authzConf.get(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar()); + String providerBackendName = + authzConf.get(AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getVar()); + String policyEngineName = + authzConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar()); + + LOG.debug("Using HBase indexer authorization provider " + authProviderName + + " with resource " + resourceName + ", policy engine " + + policyEngineName + ", provider backend " + providerBackendName); + // load the provider backend class + Constructor<?> providerBackendConstructor = + Class.forName(providerBackendName).getDeclaredConstructor(Configuration.class, String.class); + providerBackendConstructor.setAccessible(true); + + if ("kerberos".equals(authzConf.get(HADOOP_SECURITY_AUTHENTICATION))) { + // let's just reuse the hadoop/hbase properties since the HBase Indexer is + // essentially running as an HBase RegionServer + String keytabProp = authzConf.get(HBASE_REGIONSERVER_KEYTAB_FILE); + String principalProp = authzConf.get(HBASE_REGIONSERVER_KERBEROS_PRINCIPAL); + if (keytabProp != null && principalProp != null) { + // if necessary, translate _HOST in principal specification + String actualHost = authzConf.get(AuthzConfVars.PRINCIPAL_HOSTNAME.getVar()); + if (actualHost != null) { + principalProp = SecurityUtil.getServerPrincipal(principalProp, actualHost); + } + initKerberos(keytabProp, principalProp); + } + } + + // For SentryGenericProviderBackend + authzConf.set(ServiceConstants.ClientConfig.COMPONENT_TYPE, HBASE_INDEXER); + + providerBackend = + (ProviderBackend) providerBackendConstructor.newInstance(new Object[] {authzConf, resourceName}); + + // create backendContext + ProviderBackendContext context = new ProviderBackendContext(); + context.setAllowPerDatabase(true); + context.setValidators(IndexerPrivilegeModel.getInstance().getPrivilegeValidators()); + // initialize the backend with the context + providerBackend.initialize(context); + + // load the policy engine class + Constructor<?> policyConstructor = + Class.forName(policyEngineName).getDeclaredConstructor(ProviderBackend.class); + policyConstructor.setAccessible(true); + PolicyEngine policyEngine = + (PolicyEngine) policyConstructor.newInstance(new Object[] {providerBackend}); + + // load the authz provider class + Constructor<?> constrctor = + Class.forName(authProviderName).getDeclaredConstructor(String.class, PolicyEngine.class, Model.class); + constrctor.setAccessible(true); + return (AuthorizationProvider) constrctor.newInstance(new Object[] {resourceName, policyEngine, + IndexerPrivilegeModel.getInstance()}); + } + + public void authorize(Subject subject, Indexer indexer, Set<IndexerModelAction> actions) + throws SentryAccessDeniedException { + if (!authProvider.hasAccess(subject, Arrays.asList(new Indexer[] {indexer}), actions, + ActiveRoleSet.ALL)) { + throw new SentryAccessDeniedException(String.format("User '%s' does not have privileges for indexer '%s'", + (subject != null?subject.getName():""), + (indexer != null?indexer.getName():"") + )); + } + } + + public Collection<Indexer> filterIndexers(Subject subject, + Collection<Indexer> indexers) { + ArrayList<Indexer> filteredIndexers = new ArrayList<Indexer>(); + Set<IndexerModelAction> actions = EnumSet.of(IndexerModelAction.READ); + for (Indexer def : indexers) { + if (authProvider.hasAccess(subject, Arrays.asList(new Indexer[] {new Indexer(def.getName())}), actions, + ActiveRoleSet.ALL)) { + filteredIndexers.add(def); + } + } + return filteredIndexers; + } + + private HBaseIndexerAuthzConf addHdfsPropsToConf(HBaseIndexerAuthzConf conf) throws IOException { + final String hdfsConfdirKey = "hbaseindxer.hdfs.confdir"; + String confDir = System.getProperty(hdfsConfdirKey, "."); + if (confDir != null && confDir.length() > 0) { + File confDirFile = new File(confDir); + if (!confDirFile.exists()) { + throw new IOException(String.format("The HBase indexer resource '%s' does not exist. Use the '%s' configuration variable to specify an existing resource directory.", + confDirFile.getAbsolutePath(), hdfsConfdirKey)); + } + if (!confDirFile.isDirectory()) { + throw new IOException(String.format("The HBase indexer resource '%s' is not a directory. Use the '%s' configuration variable to specify an existing resource directory.", + confDirFile.getAbsolutePath(), hdfsConfdirKey)); + } + if (!confDirFile.canRead()) { + throw new IOException(String.format("The HBase indexer resource '%s' does not have read permissions. Change the directory\n" + + "permissions to allow the HBase indexer process to read or use the %s' configuration variable to specify an existing resource directory with read permissions.", + confDirFile.getAbsolutePath(), hdfsConfdirKey)); + } + for (String file : HADOOP_HBASE_CONF_FILES) { + if (new File(confDirFile, file).exists()) { + conf.addResource(new Path(confDir, file)); + } + } + } + return conf; + } + + /** + * Initialize kerberos via UserGroupInformation. Will only attempt to login + * during the first request, subsequent calls will have no effect. + * @param keytabFile path to keytab file + * @param principal principal used for authentication + * @throws IllegalArgumentException + */ + private void initKerberos(String keytabFile, String principal) { + if (keytabFile == null || keytabFile.length() == 0) { + throw new IllegalArgumentException(String.format("Setting keytab file path required when kerberos is enabled. Use %s configuration entry to define keytab file.", HBASE_REGIONSERVER_KEYTAB_FILE)); + } + if (principal == null || principal.length() == 0) { + throw new IllegalArgumentException(String.format("Setting kerberos principal is required when kerberos is enabled. Use %s configuration entry to define principal.", HBASE_REGIONSERVER_KERBEROS_PRINCIPAL)); + } + if(kerberosInit.compareAndSet(false, true)) { // init kerberos if kerberosInit is false, then set it to true + // let's avoid modifying the supplied configuration, just to be conservative + final Configuration ugiConf = new Configuration(authzConf); + UserGroupInformation.setConfiguration(ugiConf); + LOG.info( + "Attempting to acquire kerberos ticket for HBase Indexer binding with keytab: {}, principal: {} ", + keytabFile, principal); + try { + UserGroupInformation.loginUserFromKeytab(principal, keytabFile); + } catch (IOException ioe) { + kerberosInit.set(false); + throw new RuntimeException(ioe); + } + LOG.info("Got Kerberos ticket for HBase Indexer binding"); + } + + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-binding/sentry-binding-hbase-indexer/src/main/java/org/apache/sentry/binding/hbaseindexer/conf/HBaseIndexerAuthzConf.java ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hbase-indexer/src/main/java/org/apache/sentry/binding/hbaseindexer/conf/HBaseIndexerAuthzConf.java b/sentry-binding/sentry-binding-hbase-indexer/src/main/java/org/apache/sentry/binding/hbaseindexer/conf/HBaseIndexerAuthzConf.java new file mode 100644 index 0000000..cfbd37b --- /dev/null +++ b/sentry-binding/sentry-binding-hbase-indexer/src/main/java/org/apache/sentry/binding/hbaseindexer/conf/HBaseIndexerAuthzConf.java @@ -0,0 +1,84 @@ +/* + * 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.sentry.binding.hbaseindexer.conf; + +import java.net.URL; + +import org.apache.hadoop.conf.Configuration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Contains configuration entries for HBase Indexer Binding + */ +public class HBaseIndexerAuthzConf extends Configuration { + + /** + * Config setting definitions + */ + public static enum AuthzConfVars { + AUTHZ_PROVIDER("sentry.provider", + "org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider"), + AUTHZ_PROVIDER_RESOURCE("sentry.hbaseindexer.provider.resource", ""), + AUTHZ_PROVIDER_BACKEND("sentry.hbaseindexer.provider.backend", "org.apache.sentry.provider.file.SimpleFileProviderBackend"), + AUTHZ_POLICY_ENGINE("sentry.hbaseindexer.policy.engine", "org.apache.sentry.policy.engine.common.CommonPolicyEngine"), + AUTHZ_SERVICE_NAME("sentry.hbaseindexer.service", "KS_INDEXER-1"), + // binding uses hbase regionserver specification to login, but hbase regionservers + // support putting _HOST instead of fqdn and doing the translation at runtime. + // Setting this property tells sentry how to do the translation. + PRINCIPAL_HOSTNAME("sentry.hbaseindexer.principal.hostname", null); + + private final String varName; + private final String defaultVal; + + AuthzConfVars(String varName, String defaultVal) { + this.varName = varName; + this.defaultVal = defaultVal; + } + + public String getVar() { + return varName; + } + + public String getDefault() { + return defaultVal; + } + + public static String getDefault(String varName) { + for (AuthzConfVars oneVar : AuthzConfVars.values()) { + if(oneVar.getVar().equalsIgnoreCase(varName)) { + return oneVar.getDefault(); + } + } + return null; + } + } + + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory + .getLogger(HBaseIndexerAuthzConf.class); + + public HBaseIndexerAuthzConf(URL hbaseIndexerAuthzSiteURL) { + super(true); + addResource(hbaseIndexerAuthzSiteURL); + } + + @Override + public String get(String varName) { + return get(varName, AuthzConfVars.getDefault(varName)); + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-binding/sentry-binding-hbase-indexer/src/test/java/org/apache/sentry/binding/hbaseindexer/TestHBaseIndexerAuthzBinding.java ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hbase-indexer/src/test/java/org/apache/sentry/binding/hbaseindexer/TestHBaseIndexerAuthzBinding.java b/sentry-binding/sentry-binding-hbase-indexer/src/test/java/org/apache/sentry/binding/hbaseindexer/TestHBaseIndexerAuthzBinding.java new file mode 100644 index 0000000..a2675bf --- /dev/null +++ b/sentry-binding/sentry-binding-hbase-indexer/src/test/java/org/apache/sentry/binding/hbaseindexer/TestHBaseIndexerAuthzBinding.java @@ -0,0 +1,309 @@ +/* + * 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.sentry.binding.hbaseindexer; + +import com.google.common.io.Files; +import com.google.common.io.Resources; +import junit.framework.Assert; +import org.apache.commons.io.FileUtils; +import org.apache.sentry.binding.hbaseindexer.authz.HBaseIndexerAuthzBinding; +import org.apache.sentry.binding.hbaseindexer.conf.HBaseIndexerAuthzConf; +import org.apache.sentry.binding.hbaseindexer.conf.HBaseIndexerAuthzConf.AuthzConfVars; +import org.apache.sentry.core.common.Subject; +import org.apache.sentry.core.common.exception.SentryAccessDeniedException; +import org.apache.sentry.core.common.utils.PolicyFiles; +import org.apache.sentry.core.model.indexer.Indexer; +import org.apache.sentry.core.model.indexer.IndexerModelAction; +import org.apache.sentry.provider.db.generic.SentryGenericProviderBackend; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.io.FileNotFoundException; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.util.Collection; +import java.util.EnumSet; +import java.util.LinkedList; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; +import static org.apache.sentry.provider.common.AuthorizationComponent.HBASE_INDEXER; + + +/** + * Test for hbaseindexer authz binding + */ +public class TestHBaseIndexerAuthzBinding { + private static final String RESOURCE_PATH = "test-authz-provider.ini"; + private HBaseIndexerAuthzConf authzConf = new HBaseIndexerAuthzConf(Resources.getResource("sentry-site.xml")); + private File baseDir; + + private Indexer infoIndexer = new Indexer("info"); + private Indexer generalInfoIndexer = new Indexer("generalInfo"); + + private Subject corporal1 = new Subject("corporal1"); + private Subject sergeant1 = new Subject("sergeant1"); + private Subject general1 = new Subject("general1"); + + private EnumSet<IndexerModelAction> readSet = EnumSet.of(IndexerModelAction.READ); + private EnumSet<IndexerModelAction> writeSet = EnumSet.of(IndexerModelAction.WRITE); + private EnumSet<IndexerModelAction> allSet = EnumSet.of(IndexerModelAction.ALL); + private EnumSet<IndexerModelAction> allOfSet = EnumSet.allOf(IndexerModelAction.class); + private EnumSet<IndexerModelAction> emptySet = EnumSet.noneOf(IndexerModelAction.class); + + @Before + public void setUp() throws Exception { + baseDir = Files.createTempDir(); + PolicyFiles.copyToDir(baseDir, RESOURCE_PATH); + authzConf.set(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar(), new File(baseDir, RESOURCE_PATH).getPath()); + } + + @After + public void teardown() { + if (baseDir != null) { + FileUtils.deleteQuietly(baseDir); + } + } + + private void setUsableAuthzConf(HBaseIndexerAuthzConf conf) { + conf.set(AuthzConfVars.AUTHZ_PROVIDER.getVar(), "org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider"); + conf.set(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar(), new File(baseDir, RESOURCE_PATH).getPath()); + conf.set(AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getVar(), AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getDefault()); + conf.set(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar(), AuthzConfVars.AUTHZ_POLICY_ENGINE.getDefault()); + } + + /** + * Test that incorrect specification of classes for + * AUTHZ_PROVIDER, AUTHZ_PROVIDER_BACKEND, and AUTHZ_POLICY_ENGINE + * correctly throw ClassNotFoundExceptions + */ + @Test + public void testClassNotFound() throws Exception { + HBaseIndexerAuthzConf indexerAuthzConf = + new HBaseIndexerAuthzConf(Resources.getResource("sentry-site.xml")); + setUsableAuthzConf(indexerAuthzConf); + // verify it is usable + new HBaseIndexerAuthzBinding(indexerAuthzConf); + + // give a bogus provider + indexerAuthzConf.set(AuthzConfVars.AUTHZ_PROVIDER.getVar(), "org.apache.sentry.provider.BogusProvider"); + try { + new HBaseIndexerAuthzBinding(indexerAuthzConf); + Assert.fail("Expected ClassNotFoundException"); + } catch (ClassNotFoundException e) { + } + + setUsableAuthzConf(indexerAuthzConf); + // give a bogus provider backend + indexerAuthzConf.set(AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getVar(), "org.apache.sentry.provider.file.BogusProviderBackend"); + try { + new HBaseIndexerAuthzBinding(indexerAuthzConf); + Assert.fail("Expected ClassNotFoundException"); + } catch (ClassNotFoundException e) { + } + + setUsableAuthzConf(indexerAuthzConf); + // give a bogus policy enine + indexerAuthzConf.set(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar(), "org.apache.sentry.provider.hbaseindexer.BogusPolicyEngine"); + try { + new HBaseIndexerAuthzBinding(indexerAuthzConf); + Assert.fail("Expected ClassNotFoundException"); + } catch (ClassNotFoundException e) { + } + } + + /** + * Test that incorrect specification of the provider resource + * throws an exception + */ + @Test + public void testResourceNotFound() throws Exception { + HBaseIndexerAuthzConf indexerAuthzConf = + new HBaseIndexerAuthzConf(Resources.getResource("sentry-site.xml")); + setUsableAuthzConf(indexerAuthzConf); + + // bogus specification + indexerAuthzConf.set(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar(), new File(baseDir, "test-authz-bogus-provider.ini").getPath()); + try { + new HBaseIndexerAuthzBinding(indexerAuthzConf); + Assert.fail("Expected InvocationTargetException"); + } catch (InvocationTargetException e) { + assertTrue(e.getTargetException() instanceof FileNotFoundException); + } + + // missing specification + indexerAuthzConf.unset(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar()); + try { + new HBaseIndexerAuthzBinding(indexerAuthzConf); + Assert.fail("Expected InvocationTargetException"); + } catch (InvocationTargetException e) { + assertTrue(e.getTargetException() instanceof IllegalArgumentException); + } + } + + /** + * Verify that an definition of only the AuthorizationProvider + * (not ProviderBackend or PolicyEngine) works. + */ + @Test + public void testAuthProviderOnlyHBaseIndexerAuthzConfs() throws Exception { + new HBaseIndexerAuthzBinding(authzConf); + } + + /** + * Test that a full sentry-site definition works. + */ + @Test + public void testHBaseIndexerAuthzConfs() throws Exception { + HBaseIndexerAuthzConf indexerAuthzConf = + new HBaseIndexerAuthzConf(Resources.getResource("sentry-site.xml")); + setUsableAuthzConf(indexerAuthzConf); + new HBaseIndexerAuthzBinding(indexerAuthzConf); + } + + private void expectAuthException(HBaseIndexerAuthzBinding binding, Subject subject, + Indexer indexer, EnumSet<IndexerModelAction> action) throws Exception { + try { + binding.authorize(subject, indexer, action); + Assert.fail("Expected SentryHBaseIndexerAuthorizationException"); + } catch (SentryAccessDeniedException e) { + } + } + + /** + * Test that a user that doesn't exist throws an exception + * when trying to authorize + */ + @Test + public void testNoUser() throws Exception { + HBaseIndexerAuthzConf indexerAuthzConf = + new HBaseIndexerAuthzConf(Resources.getResource("sentry-site.xml")); + setUsableAuthzConf(indexerAuthzConf); + HBaseIndexerAuthzBinding binding = new HBaseIndexerAuthzBinding(indexerAuthzConf); + expectAuthException(binding, new Subject("bogus"), infoIndexer, readSet); + } + + /** + * Test that a bogus indexer name throws an exception + */ + @Test + public void testNoIndexer() throws Exception { + HBaseIndexerAuthzConf indexerAuthzConf = + new HBaseIndexerAuthzConf(Resources.getResource("sentry-site.xml")); + setUsableAuthzConf(indexerAuthzConf); + HBaseIndexerAuthzBinding binding = new HBaseIndexerAuthzBinding(indexerAuthzConf); + expectAuthException(binding, corporal1, new Indexer("bogus"), readSet); + } + + /** + * Test if no action is attempted an exception is thrown + */ + @Test + public void testNoAction() throws Exception { + HBaseIndexerAuthzConf indexerAuthzConf = + new HBaseIndexerAuthzConf(Resources.getResource("sentry-site.xml")); + setUsableAuthzConf(indexerAuthzConf); + HBaseIndexerAuthzBinding binding = new HBaseIndexerAuthzBinding(indexerAuthzConf); + try { + binding.authorize(corporal1, infoIndexer, emptySet); + Assert.fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + } + } + + /** + * Test that standard unauthorized attempts fail + */ + @Test + public void testAuthException() throws Exception { + HBaseIndexerAuthzConf indexerAuthzConf = + new HBaseIndexerAuthzConf(Resources.getResource("sentry-site.xml")); + setUsableAuthzConf(indexerAuthzConf); + HBaseIndexerAuthzBinding binding = new HBaseIndexerAuthzBinding(indexerAuthzConf); + expectAuthException(binding, corporal1, infoIndexer, writeSet); + expectAuthException(binding, corporal1, infoIndexer, allSet); + expectAuthException(binding, corporal1, generalInfoIndexer, readSet); + expectAuthException(binding, corporal1, generalInfoIndexer, writeSet); + expectAuthException(binding, corporal1, generalInfoIndexer, allSet); + expectAuthException(binding, sergeant1, infoIndexer, allSet); + expectAuthException(binding, sergeant1, generalInfoIndexer, readSet); + expectAuthException(binding, sergeant1, generalInfoIndexer, writeSet); + expectAuthException(binding, sergeant1, generalInfoIndexer, allSet); + } + + /** + * Test that standard authorized attempts succeed + */ + @Test + public void testAuthAllowed() throws Exception { + HBaseIndexerAuthzConf indexerAuthzConf = + new HBaseIndexerAuthzConf(Resources.getResource("sentry-site.xml")); + setUsableAuthzConf(indexerAuthzConf); + HBaseIndexerAuthzBinding binding = new HBaseIndexerAuthzBinding(indexerAuthzConf); + binding.authorize(corporal1, infoIndexer, readSet); + binding.authorize(sergeant1, infoIndexer, readSet); + binding.authorize(sergeant1, infoIndexer, writeSet); + binding.authorize(general1, infoIndexer, readSet); + binding.authorize(general1, infoIndexer, writeSet); + binding.authorize(general1, infoIndexer, allSet); + binding.authorize(general1, infoIndexer, allOfSet); + binding.authorize(general1, generalInfoIndexer, readSet); + binding.authorize(general1, generalInfoIndexer, writeSet); + binding.authorize(general1, generalInfoIndexer, allSet); + binding.authorize(general1, generalInfoIndexer, allOfSet); + } + + @Test + public void testFilterIndexers() throws Exception { + HBaseIndexerAuthzConf indexerAuthzConf = + new HBaseIndexerAuthzConf(Resources.getResource("sentry-site.xml")); + setUsableAuthzConf(indexerAuthzConf); + HBaseIndexerAuthzBinding binding = new HBaseIndexerAuthzBinding(indexerAuthzConf); + LinkedList<Indexer> list = new LinkedList<Indexer>(); + list.add(infoIndexer); + list.add(generalInfoIndexer); + + Collection<Indexer> corpFilter = binding.filterIndexers(corporal1, list); + assertEquals(1, corpFilter.size()); + assertTrue(corpFilter.contains(infoIndexer)); + + Collection<Indexer> sergFilter = binding.filterIndexers(sergeant1, list); + assertEquals(1, sergFilter.size()); + assertTrue(corpFilter.contains(infoIndexer)); + + Collection<Indexer> genFilter = binding.filterIndexers(general1, list); + assertEquals(2, genFilter.size()); + assertTrue(genFilter.contains(infoIndexer)); + assertTrue(genFilter.contains(generalInfoIndexer)); + } + + @Test + public void testSentryGenericProviderBackendConfig() throws Exception { + HBaseIndexerAuthzConf indexerAuthzConf = + new HBaseIndexerAuthzConf(Resources.getResource("sentry-site-service.xml")); + + HBaseIndexerAuthzBinding binding = new HBaseIndexerAuthzBinding(indexerAuthzConf); + Field f = binding.getClass().getDeclaredField("providerBackend"); //NoSuchFieldException + f.setAccessible(true); + SentryGenericProviderBackend providerBackend = (SentryGenericProviderBackend) f.get(binding); + assertEquals(HBASE_INDEXER, providerBackend.getComponentType()); + assertEquals("MyService", providerBackend.getServiceName()); + } + +} http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/log4j.properties ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/log4j.properties b/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/log4j.properties new file mode 100644 index 0000000..c41373c --- /dev/null +++ b/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/log4j.properties @@ -0,0 +1,31 @@ +# +# 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. +# + +# Define some default values that can be overridden by system properties. +# +# For testing, it may also be convenient to specify + +log4j.rootLogger=DEBUG,console + +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.target=System.err +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%d (%t) [%p - %l] %m%n + +log4j.logger.org.apache.hadoop.conf.Configuration=INFO http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/sentry-site-service.xml ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/sentry-site-service.xml b/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/sentry-site-service.xml new file mode 100644 index 0000000..3189f3f --- /dev/null +++ b/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/sentry-site-service.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> +<!-- + 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. +--> + +<configuration> + <property> + <name>sentry.hbaseindexer.provider.backend</name> + <value>org.apache.sentry.provider.db.generic.SentryGenericProviderBackend</value> + </property> + <property> + <name>sentry.provider.backend.generic.service-name</name> + <value>MyService</value> + </property> +</configuration> http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/sentry-site.xml ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/sentry-site.xml b/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/sentry-site.xml new file mode 100644 index 0000000..488a3e4 --- /dev/null +++ b/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/sentry-site.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> +<!-- + 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. +--> + +<configuration> + <property> + <name>sentry.provider</name> + <value>org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider</value> + </property> + <property> + <name>sentry.hbaseindexer.provider.resource</name> + <value>classpath:test-authz-provider.ini</value> + </property> +</configuration> http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/test-authz-provider.ini ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/test-authz-provider.ini b/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/test-authz-provider.ini new file mode 100644 index 0000000..b326f8a --- /dev/null +++ b/sentry-binding/sentry-binding-hbase-indexer/src/test/resources/test-authz-provider.ini @@ -0,0 +1,37 @@ +# 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. + +[groups] +corporal = corporal_role +sergeant = corporal_role, sergeant_role +general = corporal_role, sergeant_role, general_role +undefinedRoleGroup = undefinedRole + +[roles] +#test that specification of a bogus action doesn't affect further specifications +corporal_role = indexer=info->action=FOOBAR, \ + indexer=info->action=read +sergeant_role = indexer=info->action=write +general_role = indexer=*->action=* + +[users] +corporal1=corporal +sergeant1=sergeant +general1=general, othergeneralgroup +undefinedGroupUser=undefinedGroup +undefinedRoleUser=undefinedRoleGroup +overlappingUser=general, sergeant, corporal http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-dist/pom.xml ---------------------------------------------------------------------- diff --git a/sentry-dist/pom.xml b/sentry-dist/pom.xml index 63eb81c..8cc4eca 100644 --- a/sentry-dist/pom.xml +++ b/sentry-dist/pom.xml @@ -52,6 +52,10 @@ limitations under the License. </dependency> <dependency> <groupId>org.apache.sentry</groupId> + <artifactId>sentry-binding-hbase-indexer</artifactId> + </dependency> + <dependency> + <groupId>org.apache.sentry</groupId> <artifactId>sentry-binding-solr</artifactId> </dependency> <dependency> @@ -84,10 +88,6 @@ limitations under the License. </dependency> <dependency> <groupId>org.apache.sentry</groupId> - <artifactId>sentry-policy-indexer</artifactId> - </dependency> - <dependency> - <groupId>org.apache.sentry</groupId> <artifactId>solr-sentry-handlers</artifactId> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-dist/src/license/THIRD-PARTY.properties ---------------------------------------------------------------------- diff --git a/sentry-dist/src/license/THIRD-PARTY.properties b/sentry-dist/src/license/THIRD-PARTY.properties index 22429fc..7226acd 100644 --- a/sentry-dist/src/license/THIRD-PARTY.properties +++ b/sentry-dist/src/license/THIRD-PARTY.properties @@ -1,7 +1,6 @@ # Generated by org.codehaus.mojo.license.AddThirdPartyMojo #------------------------------------------------------------------------------- # Already used licenses in project : -# - Apache 2.0 license # - BSD 2-clause # - BSD License # - BSD style @@ -13,12 +12,10 @@ # - Common Public License Version 1.0 # - Eclipse Public License - Version 1.0 # - Eclipse Public License-1 -# - GNU General Public Library # - GNU Lesser General Public License (LGPL), Version 2.1 +# - GPL # - GPL2 w/ CPE # - LGPL 2.1 -# - LGPL 2.1 license -# - LGPL 3.0 license # - MIT License # - Mozilla Public License Version 1.1 # - Public Domain @@ -30,7 +27,7 @@ # Please fill the missing licenses for dependencies : # # -#Fri Dec 01 07:51:25 CST 2017 +#Fri Jan 05 17:47:47 CET 2018 ant--ant--1.5=The Apache Software License, Version 2.0 asm--asm--3.1=BSD dom4j--dom4j--1.6.1=BSD @@ -41,4 +38,6 @@ javax.transaction--transaction-api--1.1=CDDL 2 org.apache.zookeeper--zookeeper--3.4.5=The Apache Software License, Version 2.0 org.apache.zookeeper--zookeeper--3.4.6=The Apache Software License, Version 2.0 org.codehaus.jettison--jettison--1.1=Apache 2.0 +org.restlet.jee--org.restlet--2.3.0= +org.restlet.jee--org.restlet.ext.servlet--2.3.0= oro--oro--2.0.8=Apache http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-policy/pom.xml ---------------------------------------------------------------------- diff --git a/sentry-policy/pom.xml b/sentry-policy/pom.xml index b082aa6..1124829 100644 --- a/sentry-policy/pom.xml +++ b/sentry-policy/pom.xml @@ -32,7 +32,6 @@ limitations under the License. <modules> <module>sentry-policy-common</module> <module>sentry-policy-engine</module> - <module>sentry-policy-indexer</module> </modules> </project> http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-policy/sentry-policy-indexer/pom.xml ---------------------------------------------------------------------- diff --git a/sentry-policy/sentry-policy-indexer/pom.xml b/sentry-policy/sentry-policy-indexer/pom.xml deleted file mode 100644 index 0696b1d..0000000 --- a/sentry-policy/sentry-policy-indexer/pom.xml +++ /dev/null @@ -1,91 +0,0 @@ -<?xml version="1.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. ---> -<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>org.apache.sentry</groupId> - <artifactId>sentry-policy</artifactId> - <version>2.1.0-SNAPSHOT</version> - </parent> - - <artifactId>sentry-policy-indexer</artifactId> - <name>Sentry Policy for Indexer</name> - - <dependencies> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.hadoop</groupId> - <artifactId>hadoop-common</artifactId> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.apache.hadoop</groupId> - <artifactId>hadoop-minicluster</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>log4j</groupId> - <artifactId>log4j</artifactId> - </dependency> - <dependency> - <groupId>org.apache.shiro</groupId> - <artifactId>shiro-core</artifactId> - </dependency> - <dependency> - <groupId>com.google.guava</groupId> - <artifactId>guava</artifactId> - </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> - </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - </dependency> - <dependency> - <groupId>org.apache.sentry</groupId> - <artifactId>sentry-core-model-indexer</artifactId> - </dependency> - <dependency> - <groupId>org.apache.sentry</groupId> - <artifactId>sentry-provider-common</artifactId> - </dependency> - <dependency> - <groupId>org.apache.sentry</groupId> - <artifactId>sentry-policy-engine</artifactId> - </dependency> - <dependency> - <groupId>org.apache.sentry</groupId> - <artifactId>sentry-provider-file</artifactId> - </dependency> - <dependency> - <groupId>org.apache.sentry</groupId> - <artifactId>sentry-provider-common</artifactId> - <scope>test</scope> - <type>test-jar</type> - <version>${project.version}</version> - </dependency> - </dependencies> - -</project> http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerWildcardPrivilege.java ---------------------------------------------------------------------- diff --git a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerWildcardPrivilege.java b/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerWildcardPrivilege.java deleted file mode 100644 index 9e9a0d2..0000000 --- a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerWildcardPrivilege.java +++ /dev/null @@ -1,159 +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. - */ - -// copied from apache shiro - -package org.apache.sentry.policy.indexer; - -import java.util.LinkedList; -import java.util.List; - -import org.apache.sentry.core.common.Model; -import org.apache.sentry.core.common.utils.SentryConstants; -import org.apache.sentry.core.model.indexer.IndexerConstants; -import org.apache.sentry.policy.common.Privilege; -import org.apache.sentry.policy.common.PrivilegeFactory; -import org.apache.sentry.core.common.utils.KeyValue; - -import com.google.common.base.Preconditions; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; - -public class IndexerWildcardPrivilege implements Privilege { - - private final ImmutableList<KeyValue> parts; - - public IndexerWildcardPrivilege(String wildcardString) { - wildcardString = Strings.nullToEmpty(wildcardString).trim(); - if (wildcardString.isEmpty()) { - throw new IllegalArgumentException("Wildcard string cannot be null or empty."); - } - List<KeyValue>parts = Lists.newArrayList(); - for (String authorizable : SentryConstants.AUTHORIZABLE_SPLITTER.trimResults().split( - wildcardString)) { - if (authorizable.isEmpty()) { - throw new IllegalArgumentException("Privilege '" + wildcardString + "' has an empty section"); - } - parts.add(new KeyValue(authorizable)); - } - if (parts.isEmpty()) { - throw new AssertionError("Should never occur: " + wildcardString); - } - this.parts = ImmutableList.copyOf(parts); - } - - - @Override - public boolean implies(Privilege p, Model model) { - // By default only supports comparisons with other IndexerWildcardPermissions - if (!(p instanceof IndexerWildcardPrivilege)) { - return false; - } - - IndexerWildcardPrivilege wp = (IndexerWildcardPrivilege) p; - - List<KeyValue> otherParts = wp.parts; - if(equals(wp)) { - return true; - } - int index = 0; - for (KeyValue otherPart : otherParts) { - // If this privilege has less parts than the other privilege, everything - // after the number of parts contained - // in this privilege is automatically implied, so return true - if (parts.size() - 1 < index) { - return true; - } else { - KeyValue part = parts.get(index); - // are the keys even equal - if(!part.getKey().equalsIgnoreCase(otherPart.getKey())) { - return false; - } - if (!impliesKeyValue(part, otherPart)) { - return false; - } - index++; - } - } - // If this privilege has more parts than - // the other parts, only imply it if - // all of the other parts are wildcards - for (; index < parts.size(); index++) { - KeyValue part = parts.get(index); - if (!part.getValue().equals(IndexerConstants.ALL)) { - return false; - } - } - - return true; - } - - @Override - public List<KeyValue> getAuthorizable() { - List<KeyValue> authorizable = new LinkedList<>(); - - for (KeyValue part : parts) { - if (!SentryConstants.PRIVILEGE_NAME.equalsIgnoreCase(part.getKey())) { - authorizable.add(part); - } - } - - return authorizable; - } - - private boolean impliesKeyValue(KeyValue policyPart, KeyValue requestPart) { - Preconditions.checkState(policyPart.getKey().equalsIgnoreCase(requestPart.getKey()), - "Please report, this method should not be called with two different keys"); - if(policyPart.getValue().equals(IndexerConstants.ALL) || policyPart.equals(requestPart)) { - return true; - } else if (!SentryConstants.PRIVILEGE_NAME.equalsIgnoreCase(policyPart.getKey()) - && IndexerConstants.ALL.equalsIgnoreCase(requestPart.getValue())) { - /* privilege request is to match with any object of given type */ - return true; - } - return false; - } - - @Override - public String toString() { - return SentryConstants.AUTHORIZABLE_JOINER.join(parts); - } - - @Override - public boolean equals(Object o) { - if (o instanceof IndexerWildcardPrivilege) { - IndexerWildcardPrivilege wp = (IndexerWildcardPrivilege) o; - return parts.equals(wp.parts); - } - return false; - } - - @Override - public int hashCode() { - return parts.hashCode(); - } - - public static class IndexerWildcardPrivilegeFactory implements PrivilegeFactory { - @Override - public Privilege createPrivilege(String privilege) { - return new IndexerWildcardPrivilege(privilege); - } - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/SimpleIndexerPolicyEngine.java ---------------------------------------------------------------------- diff --git a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/SimpleIndexerPolicyEngine.java b/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/SimpleIndexerPolicyEngine.java deleted file mode 100644 index 932690c..0000000 --- a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/SimpleIndexerPolicyEngine.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sentry.policy.indexer; - -import java.util.Set; - -import org.apache.sentry.core.common.ActiveRoleSet; -import org.apache.sentry.core.common.Authorizable; -import org.apache.sentry.core.common.exception.SentryConfigurationException; -import org.apache.sentry.policy.common.PrivilegeFactory; -import org.apache.sentry.policy.common.PolicyEngine; -import org.apache.sentry.provider.common.ProviderBackend; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.ImmutableSet; - -/** - * A PolicyEngine for an indexer service. - */ -public class SimpleIndexerPolicyEngine implements PolicyEngine { - - private static final Logger LOGGER = LoggerFactory - .getLogger(SimpleIndexerPolicyEngine.class); - - private final ProviderBackend providerBackend; - - public SimpleIndexerPolicyEngine(ProviderBackend providerBackend) { - this.providerBackend = providerBackend; - } - - /** - * {@inheritDoc} - */ - @Override - public PrivilegeFactory getPrivilegeFactory() { - return new IndexerWildcardPrivilege.IndexerWildcardPrivilegeFactory(); - } - - /** - * {@inheritDoc} - */ - @Override - public ImmutableSet<String> getAllPrivileges(Set<String> groups, - ActiveRoleSet roleSet) throws SentryConfigurationException { - return getPrivileges(groups, roleSet); - } - - @Override - public ImmutableSet<String> getAllPrivileges(Set<String> groups, Set<String> users, - ActiveRoleSet roleSet) throws SentryConfigurationException { - return getPrivileges(groups, users, roleSet); - } - - /** - * {@inheritDoc} - */ - @Override - public ImmutableSet<String> getPrivileges(Set<String> groups, ActiveRoleSet roleSet, Authorizable... authorizationHierarchy ) { - if(LOGGER.isDebugEnabled()) { - LOGGER.debug("Getting permissions for {}", groups); - } - ImmutableSet<String> result = providerBackend.getPrivileges(groups, roleSet); - if(LOGGER.isDebugEnabled()) { - LOGGER.debug("result = " + result); - } - return result; - } - - @Override - public ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> users, - ActiveRoleSet roleSet, Authorizable... authorizationHierarchy) { - if(LOGGER.isDebugEnabled()) { - LOGGER.debug("Getting permissions for groups: {}, users: {}", groups, users); - } - ImmutableSet<String> result = providerBackend.getPrivileges(groups, users, roleSet); - if(LOGGER.isDebugEnabled()) { - LOGGER.debug("result = " + result); - } - return result; - } - - @Override - public void validatePolicy(boolean strictValidation) - throws SentryConfigurationException { - throw new SentryConfigurationException("Not implemented yet"); - } - - @Override - public void close() { - if (providerBackend != null) { - providerBackend.close(); - } - } - -} http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/AbstractTestIndexerPolicyEngine.java ---------------------------------------------------------------------- diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/AbstractTestIndexerPolicyEngine.java b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/AbstractTestIndexerPolicyEngine.java deleted file mode 100644 index 66455e8..0000000 --- a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/AbstractTestIndexerPolicyEngine.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sentry.policy.indexer; - -import java.io.File; -import java.io.IOException; -import java.util.Set; -import java.util.TreeSet; - -import org.junit.Assert; - -import org.apache.commons.io.FileUtils; -import org.apache.sentry.core.common.ActiveRoleSet; -import org.apache.sentry.policy.common.PolicyEngine; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.google.common.collect.Sets; -import com.google.common.io.Files; - -public abstract class AbstractTestIndexerPolicyEngine { - private static final String ANALYST_PURCHASES_WRITE = "indexer=purchases->action=write"; - private static final String ANALYST_ANALYST1_ALL = "indexer=analyst1"; - private static final String ANALYST_JRANALYST1_ACTION_ALL = "indexer=jranalyst1->action=*"; - private static final String ANALYST_TMPINDEXER_WRITE = "indexer=tmpindexer->action=write"; - private static final String ANALYST_TMPINDEXER_READ = "indexer=tmpindexer->action=read"; - private static final String JRANALYST_JRANALYST1_ALL = "indexer=jranalyst1"; - private static final String JRANALYST_PURCHASES_PARTIAL_READ = "indexer=purchases_partial->action=read"; - private static final String ADMIN_INDEXER_ALL = "indexer=*"; - - private PolicyEngine policy; - private static File baseDir; - - @BeforeClass - public static void setupClazz() throws IOException { - baseDir = Files.createTempDir(); - } - - @AfterClass - public static void teardownClazz() throws IOException { - if(baseDir != null) { - FileUtils.deleteQuietly(baseDir); - } - } - - protected void setPolicy(PolicyEngine policy) { - this.policy = policy; - } - protected static File getBaseDir() { - return baseDir; - } - @Before - public void setup() throws IOException { - afterSetup(); - } - @After - public void teardown() throws IOException { - beforeTeardown(); - } - protected void afterSetup() throws IOException { - - } - - protected void beforeTeardown() throws IOException { - - } - - @Test - public void testManager() throws Exception { - Set<String> expected = Sets.newTreeSet(Sets.newHashSet( - ANALYST_PURCHASES_WRITE, ANALYST_ANALYST1_ALL, - ANALYST_JRANALYST1_ACTION_ALL, ANALYST_TMPINDEXER_WRITE, - ANALYST_TMPINDEXER_READ, JRANALYST_JRANALYST1_ALL, - JRANALYST_PURCHASES_PARTIAL_READ)); - Assert.assertEquals(expected.toString(), - new TreeSet<String>(policy.getPrivileges(set("manager"), ActiveRoleSet.ALL)) - .toString()); - } - - @Test - public void testAnalyst() throws Exception { - Set<String> expected = Sets.newTreeSet(Sets.newHashSet( - ANALYST_PURCHASES_WRITE, ANALYST_ANALYST1_ALL, - ANALYST_JRANALYST1_ACTION_ALL, ANALYST_TMPINDEXER_WRITE, - ANALYST_TMPINDEXER_READ)); - Assert.assertEquals(expected.toString(), - new TreeSet<String>(policy.getPrivileges(set("analyst"), ActiveRoleSet.ALL)) - .toString()); - } - - @Test - public void testJuniorAnalyst() throws Exception { - Set<String> expected = Sets.newTreeSet(Sets - .newHashSet(JRANALYST_JRANALYST1_ALL, - JRANALYST_PURCHASES_PARTIAL_READ)); - Assert.assertEquals(expected.toString(), - new TreeSet<String>(policy.getPrivileges(set("jranalyst"), ActiveRoleSet.ALL)) - .toString()); - } - - @Test - public void testAdmin() throws Exception { - Set<String> expected = Sets.newTreeSet(Sets.newHashSet(ADMIN_INDEXER_ALL)); - Assert.assertEquals(expected.toString(), - new TreeSet<String>(policy.getPrivileges(set("admin"), ActiveRoleSet.ALL)) - .toString()); - } - - private static Set<String> set(String... values) { - return Sets.newHashSet(values); - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/IndexPolicyTestUtil.java ---------------------------------------------------------------------- diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/IndexPolicyTestUtil.java b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/IndexPolicyTestUtil.java deleted file mode 100644 index 45f100e..0000000 --- a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/IndexPolicyTestUtil.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sentry.policy.indexer; - -import org.apache.hadoop.conf.Configuration; -import org.apache.sentry.core.model.indexer.IndexerPrivilegeModel; -import org.apache.sentry.policy.common.PolicyEngine; -import org.apache.sentry.policy.engine.common.CommonPolicyEngine; -import org.apache.sentry.provider.common.ProviderBackend; -import org.apache.sentry.provider.common.ProviderBackendContext; -import org.apache.sentry.provider.file.SimpleFileProviderBackend; - -import java.io.IOException; - -public class IndexPolicyTestUtil { - - public static PolicyEngine createPolicyEngineForTest(String resource) throws IOException { - - ProviderBackend providerBackend = new SimpleFileProviderBackend(new Configuration(), resource); - - // create backendContext - ProviderBackendContext context = new ProviderBackendContext(); - context.setAllowPerDatabase(false); - context.setValidators(IndexerPrivilegeModel.getInstance().getPrivilegeValidators()); - // initialize the backend with the context - providerBackend.initialize(context); - - return new CommonPolicyEngine(providerBackend); - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestCommonPrivilegeForIndexer.java ---------------------------------------------------------------------- diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestCommonPrivilegeForIndexer.java b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestCommonPrivilegeForIndexer.java deleted file mode 100644 index aa8aa5f..0000000 --- a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestCommonPrivilegeForIndexer.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sentry.policy.indexer; - -import org.apache.sentry.core.common.Model; -import org.apache.sentry.core.common.utils.KeyValue; -import org.apache.sentry.core.common.utils.SentryConstants; -import org.apache.sentry.core.model.indexer.IndexerConstants; -import org.apache.sentry.core.model.indexer.IndexerPrivilegeModel; -import org.apache.sentry.policy.common.CommonPrivilege; -import org.apache.sentry.policy.common.Privilege; -import org.junit.Before; -import org.junit.Test; - -import java.util.List; - -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; - -public class TestCommonPrivilegeForIndexer { - - private Model indexerPrivilegeModel; - - private static final String ALL = IndexerConstants.ALL; - - @Before - public void prepareData() { - indexerPrivilegeModel = IndexerPrivilegeModel.getInstance(); - } - - @Test - public void testSimpleNoAction() throws Exception { - CommonPrivilege indexer1 = create(new KeyValue("indexer", "ind1")); - CommonPrivilege indexer2 = create(new KeyValue("indexer", "ind2")); - CommonPrivilege indexer1Case = create(new KeyValue("indeXeR", "inD1")); - - assertTrue(indexer1.implies(indexer1, indexerPrivilegeModel)); - assertTrue(indexer2.implies(indexer2, indexerPrivilegeModel)); - assertTrue(indexer1.implies(indexer1Case, indexerPrivilegeModel)); - assertTrue(indexer1Case.implies(indexer1, indexerPrivilegeModel)); - - assertFalse(indexer1.implies(indexer2, indexerPrivilegeModel)); - assertFalse(indexer1Case.implies(indexer2, indexerPrivilegeModel)); - assertFalse(indexer2.implies(indexer1, indexerPrivilegeModel)); - assertFalse(indexer2.implies(indexer1Case, indexerPrivilegeModel)); - } - - @Test - public void testSimpleAction() throws Exception { - CommonPrivilege read = - create(new KeyValue("indexer", "ind1"), new KeyValue("action", "read")); - CommonPrivilege write = - create(new KeyValue("indexer", "ind1"), new KeyValue("action", "write")); - CommonPrivilege readCase = - create(new KeyValue("indeXeR", "iNd1"), new KeyValue("AcTiOn", "ReAd")); - - assertTrue(read.implies(read, indexerPrivilegeModel)); - assertTrue(write.implies(write, indexerPrivilegeModel)); - assertTrue(read.implies(readCase, indexerPrivilegeModel)); - assertTrue(readCase.implies(read, indexerPrivilegeModel)); - - assertFalse(read.implies(write, indexerPrivilegeModel)); - assertFalse(readCase.implies(write, indexerPrivilegeModel)); - assertFalse(write.implies(read, indexerPrivilegeModel)); - assertFalse(write.implies(readCase, indexerPrivilegeModel)); - } - - @Test - public void testRoleShorterThanRequest() throws Exception { - CommonPrivilege indexer1 = create(new KeyValue("indexer", "ind1")); - CommonPrivilege read = - create(new KeyValue("indexer", "ind1"), new KeyValue("action", "read")); - CommonPrivilege write = - create(new KeyValue("indexer", "ind1"), new KeyValue("action", "write")); - CommonPrivilege all = - create(new KeyValue("indexer", "ind1"), new KeyValue("action", ALL)); - - assertTrue(indexer1.implies(read, indexerPrivilegeModel)); - assertTrue(indexer1.implies(write, indexerPrivilegeModel)); - assertTrue(indexer1.implies(all, indexerPrivilegeModel)); - - assertFalse(read.implies(indexer1, indexerPrivilegeModel)); - assertFalse(write.implies(indexer1, indexerPrivilegeModel)); - assertTrue(all.implies(indexer1, indexerPrivilegeModel)); - } - - @Test - public void testIndexerAll() throws Exception { - CommonPrivilege indexerAll = create(new KeyValue("indexer", ALL)); - CommonPrivilege indexer1 = create(new KeyValue("indexer", "ind1")); - assertTrue(indexerAll.implies(indexer1, indexerPrivilegeModel)); - assertTrue(indexer1.implies(indexerAll, indexerPrivilegeModel)); - - CommonPrivilege allWrite = - create(new KeyValue("indexer", ALL), new KeyValue("action", "write")); - CommonPrivilege allRead = - create(new KeyValue("indexer", ALL), new KeyValue("action", "read")); - CommonPrivilege ind1Write = - create(new KeyValue("indexer", "ind1"), new KeyValue("action", "write")); - CommonPrivilege ind1Read = - create(new KeyValue("indexer", "ind1"), new KeyValue("action", "read")); - assertTrue(allWrite.implies(ind1Write, indexerPrivilegeModel)); - assertTrue(allRead.implies(ind1Read, indexerPrivilegeModel)); - assertTrue(ind1Write.implies(allWrite, indexerPrivilegeModel)); - assertTrue(ind1Read.implies(allRead, indexerPrivilegeModel)); - assertFalse(allWrite.implies(ind1Read, indexerPrivilegeModel)); - assertFalse(ind1Write.implies(ind1Read, indexerPrivilegeModel)); - assertFalse(allRead.implies(ind1Write, indexerPrivilegeModel)); - assertFalse(ind1Read.implies(allWrite, indexerPrivilegeModel)); - assertFalse(allWrite.implies(allRead, indexerPrivilegeModel)); - assertFalse(allRead.implies(allWrite, indexerPrivilegeModel)); - assertFalse(ind1Write.implies(ind1Read, indexerPrivilegeModel)); - assertFalse(ind1Read.implies(ind1Write, indexerPrivilegeModel)); - - // test different length paths - assertTrue(indexerAll.implies(allWrite, indexerPrivilegeModel)); - assertTrue(indexerAll.implies(allRead, indexerPrivilegeModel)); - assertTrue(indexerAll.implies(ind1Write, indexerPrivilegeModel)); - assertTrue(indexerAll.implies(ind1Read, indexerPrivilegeModel)); - assertFalse(allWrite.implies(indexerAll, indexerPrivilegeModel)); - assertFalse(allRead.implies(indexerAll, indexerPrivilegeModel)); - assertFalse(ind1Write.implies(indexerAll, indexerPrivilegeModel)); - assertFalse(ind1Read.implies(indexerAll, indexerPrivilegeModel)); - } - - @Test - public void testActionAll() throws Exception { - CommonPrivilege ind1All = - create(new KeyValue("indexer", "index1"), new KeyValue("action", ALL)); - CommonPrivilege ind1Write = - create(new KeyValue("indexer", "index1"), new KeyValue("action", "write")); - CommonPrivilege ind1Read = - create(new KeyValue("indexer", "index1"), new KeyValue("action", "read")); - assertTrue(ind1All.implies(ind1All, indexerPrivilegeModel)); - assertTrue(ind1All.implies(ind1Write, indexerPrivilegeModel)); - assertTrue(ind1All.implies(ind1Read, indexerPrivilegeModel)); - assertFalse(ind1Write.implies(ind1All, indexerPrivilegeModel)); - assertFalse(ind1Read.implies(ind1All, indexerPrivilegeModel)); - - // test different lengths - CommonPrivilege ind1 = - create(new KeyValue("indexer", "index1")); - assertTrue(ind1All.implies(ind1, indexerPrivilegeModel)); - assertTrue(ind1.implies(ind1All, indexerPrivilegeModel)); - } - - @Test - public void testUnexpected() throws Exception { - Privilege p = new Privilege() { - @Override - public boolean implies(Privilege p, Model model) { - return false; - } - - @Override - public List<KeyValue> getAuthorizable() { - return null; - } - }; - CommonPrivilege indexer1 = create(new KeyValue("indexer", "index1")); - assertFalse(indexer1.implies(null, indexerPrivilegeModel)); - assertFalse(indexer1.implies(p, indexerPrivilegeModel)); - assertFalse(indexer1.equals(null)); - assertFalse(indexer1.equals(p)); - } - - @Test(expected=IllegalArgumentException.class) - public void testNullString() throws Exception { - System.out.println(create((String)null)); - } - - @Test(expected=IllegalArgumentException.class) - public void testEmptyString() throws Exception { - System.out.println(create("")); - } - - @Test(expected=IllegalArgumentException.class) - public void testEmptyKey() throws Exception { - System.out.println(create(SentryConstants.KV_JOINER.join("indexer", ""))); - } - - @Test(expected=IllegalArgumentException.class) - public void testEmptyValue() throws Exception { - System.out.println(create(SentryConstants.KV_JOINER.join("", "index1"))); - } - - @Test(expected=IllegalArgumentException.class) - public void testEmptyPart() throws Exception { - System.out.println(create(SentryConstants.AUTHORIZABLE_JOINER. - join(SentryConstants.KV_JOINER.join("indexer11", "index1"), ""))); - } - - @Test(expected=IllegalArgumentException.class) - public void testOnlySeperators() throws Exception { - System.out.println(create(SentryConstants.AUTHORIZABLE_JOINER. - join(SentryConstants.KV_SEPARATOR, SentryConstants.KV_SEPARATOR, - SentryConstants.KV_SEPARATOR))); - } - - static CommonPrivilege create(KeyValue... keyValues) { - return create(SentryConstants.AUTHORIZABLE_JOINER.join(keyValues)); - } - - static CommonPrivilege create(String s) { - return new CommonPrivilege(s); - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/6b644c97/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerAuthorizationProviderGeneralCases.java ---------------------------------------------------------------------- diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerAuthorizationProviderGeneralCases.java b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerAuthorizationProviderGeneralCases.java deleted file mode 100644 index 29b377e..0000000 --- a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerAuthorizationProviderGeneralCases.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sentry.policy.indexer; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.List; -import java.util.Set; - -import org.junit.Assert; - -import org.apache.commons.io.FileUtils; -import org.apache.sentry.core.common.Action; -import org.apache.sentry.core.common.ActiveRoleSet; -import org.apache.sentry.core.common.Authorizable; -import org.apache.sentry.core.common.Subject; -import org.apache.sentry.core.model.indexer.Indexer; -import org.apache.sentry.core.model.indexer.IndexerModelAction; -import org.apache.sentry.core.model.indexer.IndexerPrivilegeModel; -import org.apache.sentry.provider.common.MockGroupMappingServiceProvider; -import org.apache.sentry.provider.common.ResourceAuthorizationProvider; -import org.apache.sentry.provider.file.HadoopGroupResourceAuthorizationProvider; -import org.apache.sentry.core.common.utils.PolicyFiles; -import org.junit.After; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Objects; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; -import com.google.common.io.Files; - - -public class TestIndexerAuthorizationProviderGeneralCases { - - private static final Logger LOGGER = LoggerFactory - .getLogger(TestIndexerAuthorizationProviderGeneralCases.class); - - private static final Multimap<String, String> USER_TO_GROUP_MAP = HashMultimap - .create(); - - private static final Subject SUB_ADMIN = new Subject("admin1"); - private static final Subject SUB_MANAGER = new Subject("manager1"); - private static final Subject SUB_ANALYST = new Subject("analyst1"); - private static final Subject SUB_JUNIOR_ANALYST = new Subject("jranalyst1"); - - private static final Indexer IND_PURCHASES = new Indexer("purchases"); - private static final Indexer IND_ANALYST1 = new Indexer("analyst1"); - private static final Indexer IND_JRANALYST1 = new Indexer("jranalyst1"); - private static final Indexer IND_TMP = new Indexer("tmpindexer"); - private static final Indexer IND_PURCHASES_PARTIAL = new Indexer("purchases_partial"); - - private static final IndexerModelAction READ = IndexerModelAction.READ; - private static final IndexerModelAction WRITE = IndexerModelAction.WRITE; - - static { - USER_TO_GROUP_MAP.putAll(SUB_ADMIN.getName(), Arrays.asList("admin")); - USER_TO_GROUP_MAP.putAll(SUB_MANAGER.getName(), Arrays.asList("manager")); - USER_TO_GROUP_MAP.putAll(SUB_ANALYST.getName(), Arrays.asList("analyst")); - USER_TO_GROUP_MAP.putAll(SUB_JUNIOR_ANALYST.getName(), - Arrays.asList("jranalyst")); - } - - private final ResourceAuthorizationProvider authzProvider; - private File baseDir; - - public TestIndexerAuthorizationProviderGeneralCases() throws IOException { - baseDir = Files.createTempDir(); - PolicyFiles.copyToDir(baseDir, "test-authz-provider.ini"); - authzProvider = new HadoopGroupResourceAuthorizationProvider( - IndexPolicyTestUtil.createPolicyEngineForTest(new File(baseDir, "test-authz-provider.ini").getPath()), - new MockGroupMappingServiceProvider(USER_TO_GROUP_MAP), IndexerPrivilegeModel.getInstance()); - - } - - @After - public void teardown() { - if(baseDir != null) { - FileUtils.deleteQuietly(baseDir); - } - } - - private void doTestAuthProviderOnIndexer(Subject subject, - Indexer indexer, Set<? extends Action> expectedPass) throws Exception { - Set<IndexerModelAction> allActions = EnumSet.of(IndexerModelAction.ALL, IndexerModelAction.READ, IndexerModelAction.WRITE); - for(IndexerModelAction action : allActions) { - doTestResourceAuthorizationProvider(subject, indexer, - EnumSet.of(action), expectedPass.contains(action)); - } - } - - private void doTestResourceAuthorizationProvider(Subject subject, - Indexer indexer, - Set<? extends Action> privileges, boolean expected) throws Exception { - List<Authorizable> authzHierarchy = Arrays.asList(new Authorizable[] { - indexer - }); - Objects.ToStringHelper helper = Objects.toStringHelper("TestParameters"); - helper.add("Subject", subject).add("Indexer", indexer) - .add("Privileges", privileges).add("authzHierarchy", authzHierarchy); - LOGGER.info("Running with " + helper.toString()); - Assert.assertEquals(helper.toString(), expected, - authzProvider.hasAccess(subject, authzHierarchy, privileges, ActiveRoleSet.ALL)); - LOGGER.info("Passed " + helper.toString()); - } - - @Test - public void testAdmin() throws Exception { - Set<IndexerModelAction> allActions = EnumSet.allOf(IndexerModelAction.class); - doTestAuthProviderOnIndexer(SUB_ADMIN, IND_PURCHASES, allActions); - doTestAuthProviderOnIndexer(SUB_ADMIN, IND_ANALYST1, allActions); - doTestAuthProviderOnIndexer(SUB_ADMIN, IND_JRANALYST1, allActions); - doTestAuthProviderOnIndexer(SUB_ADMIN, IND_TMP, allActions); - doTestAuthProviderOnIndexer(SUB_ADMIN, IND_PURCHASES_PARTIAL, allActions); - } - - @Test - public void testManager() throws Exception { - Set<IndexerModelAction> writeOnly = EnumSet.of(IndexerModelAction.WRITE); - doTestAuthProviderOnIndexer(SUB_MANAGER, IND_PURCHASES, writeOnly); - - Set<IndexerModelAction> allActions = EnumSet.allOf(IndexerModelAction.class); - doTestAuthProviderOnIndexer(SUB_MANAGER, IND_ANALYST1, allActions); - doTestAuthProviderOnIndexer(SUB_MANAGER, IND_JRANALYST1, allActions); - - Set<IndexerModelAction> readWriteOnly = EnumSet.of(READ, WRITE); - doTestAuthProviderOnIndexer(SUB_MANAGER, IND_TMP, readWriteOnly); - - Set<IndexerModelAction> readOnly = EnumSet.of(IndexerModelAction.READ); - doTestAuthProviderOnIndexer(SUB_MANAGER, IND_PURCHASES_PARTIAL, readOnly); - } - - @Test - public void testAnalyst() throws Exception { - Set<IndexerModelAction> writeOnly = EnumSet.of(IndexerModelAction.WRITE); - doTestAuthProviderOnIndexer(SUB_ANALYST, IND_PURCHASES, writeOnly); - - Set<IndexerModelAction> allActions = EnumSet.allOf(IndexerModelAction.class); - doTestAuthProviderOnIndexer(SUB_ANALYST, IND_ANALYST1, allActions); - doTestAuthProviderOnIndexer(SUB_ANALYST, IND_JRANALYST1, allActions); - - Set<IndexerModelAction> readWriteOnly = EnumSet.of(READ, WRITE); - doTestAuthProviderOnIndexer(SUB_ANALYST, IND_TMP, readWriteOnly); - - Set<IndexerModelAction> noActions = EnumSet.noneOf(IndexerModelAction.class); - doTestAuthProviderOnIndexer(SUB_ANALYST, IND_PURCHASES_PARTIAL, noActions); - } - - @Test - public void testJuniorAnalyst() throws Exception { - Set<IndexerModelAction> allActions = EnumSet.allOf(IndexerModelAction.class); - doTestAuthProviderOnIndexer(SUB_JUNIOR_ANALYST, IND_JRANALYST1, allActions); - - Set<IndexerModelAction> readOnly = EnumSet.of(IndexerModelAction.READ); - doTestAuthProviderOnIndexer(SUB_JUNIOR_ANALYST, IND_PURCHASES_PARTIAL, readOnly); - - Set<IndexerModelAction> noActions = EnumSet.noneOf(IndexerModelAction.class); - doTestAuthProviderOnIndexer(SUB_JUNIOR_ANALYST, IND_PURCHASES, noActions); - doTestAuthProviderOnIndexer(SUB_JUNIOR_ANALYST, IND_ANALYST1, noActions); - doTestAuthProviderOnIndexer(SUB_JUNIOR_ANALYST, IND_TMP, noActions); - } -}
