You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by sp...@apache.org on 2018/05/31 03:32:28 UTC
[50/86] sentry git commit: SENTRY-2208: Refactor out Sentry service
into own module from sentry-provider-db (Anthony Young-Garner,
reviewed by Sergio Pena, Steve Moist, Na Li)
http://git-wip-us.apache.org/repos/asf/sentry/blob/7db84b2f/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/SentryStoreIntegrationBase.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/SentryStoreIntegrationBase.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/SentryStoreIntegrationBase.java
new file mode 100644
index 0000000..3fe5b6a
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/SentryStoreIntegrationBase.java
@@ -0,0 +1,91 @@
+/**
+ * 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.provider.db.generic.service.persistent;
+
+import java.io.File;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.apache.sentry.service.common.ServiceConstants.ServerConfig;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+import com.google.common.io.Files;
+
+public abstract class SentryStoreIntegrationBase {
+ protected final static String[] adminGroups = { "adminGroup" };
+ private static File dataDir;
+ private static File policyFilePath;
+ protected static Configuration conf;
+ protected static DelegateSentryStore sentryStore;
+ protected static PolicyFile policyFile;
+
+ @BeforeClass
+ public static void setup() throws Exception {
+ conf = new Configuration(false);
+ setup(conf);
+ sentryStore = new DelegateSentryStore(conf);
+ }
+
+ private static void setup(Configuration conf) throws Exception {
+ dataDir = new File(Files.createTempDir(), "sentry_policy_db");
+ conf.set(ServerConfig.SENTRY_VERIFY_SCHEM_VERSION, "false");
+ conf.set(ServerConfig.SENTRY_STORE_JDBC_URL,
+ "jdbc:derby:;databaseName=" + dataDir.getPath() + ";create=true");
+ conf.set(ServerConfig.SENTRY_STORE_JDBC_PASS, "dummy");
+ conf.setStrings(ServerConfig.ADMIN_GROUPS, adminGroups);
+ conf.set(ServerConfig.SENTRY_STORE_GROUP_MAPPING,
+ ServerConfig.SENTRY_STORE_LOCAL_GROUP_MAPPING);
+
+ policyFilePath = new File(Files.createTempDir(), "local_policy_file.ini");
+ conf.set(ServerConfig.SENTRY_STORE_GROUP_MAPPING_RESOURCE,
+ policyFilePath.getPath());
+ }
+
+ @After
+ public void clearData() throws Exception{
+ sentryStore.clearAllTables();
+ }
+
+ @AfterClass
+ public static void teardown() {
+ if (sentryStore != null) {
+ sentryStore.close();
+ }
+ if (dataDir != null) {
+ FileUtils.deleteQuietly(dataDir);
+ }
+ if (policyFilePath != null) {
+ FileUtils.deleteQuietly(policyFilePath);
+ }
+ }
+
+ public static void addGroupsToUser(String user, String... groupNames) {
+ policyFile.addGroupsToUser(user, groupNames);
+ }
+
+ public static void writePolicyFile() throws Exception {
+ policyFile.write(policyFilePath);
+ }
+
+ public String[] getAdminGroups() {
+ return adminGroups;
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/7db84b2f/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestDelegateSentryStore.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestDelegateSentryStore.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestDelegateSentryStore.java
new file mode 100644
index 0000000..69d1623
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestDelegateSentryStore.java
@@ -0,0 +1,182 @@
+/**
+ * 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.provider.db.generic.service.persistent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.Set;
+
+import org.apache.sentry.core.common.exception.SentryAlreadyExistsException;
+import org.apache.sentry.core.common.exception.SentryNoSuchObjectException;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.Sets;
+
+public class TestDelegateSentryStore extends SentryStoreIntegrationBase{
+ private static final String SEARCH = "solr";
+
+ @Before
+ public void configure() throws Exception {
+ /**
+ * add the admin user to admin groups
+ */
+ policyFile = new PolicyFile();
+ addGroupsToUser("admin", getAdminGroups());
+ writePolicyFile();
+ }
+
+ @Test
+ public void testCreateDropRole() throws Exception {
+ String roleName = "test-drop-role";
+ String grantor = "grantor";
+ sentryStore.createRole(SEARCH, roleName, grantor);
+ sentryStore.dropRole(SEARCH, roleName, grantor);
+ }
+
+ @Test
+ public void testCaseInsensitiveCreateDropRole() throws Exception {
+ String roleName1 = "test";
+ String roleName2 = "TeSt";
+ String grantor = "grantor";
+ sentryStore.createRole(SEARCH, roleName1, grantor);
+ try {
+ sentryStore.createRole(SEARCH, roleName2, grantor);
+ fail("Fail to throw Exception");
+ } catch (SentryAlreadyExistsException e) {
+ //ignore the exception
+ }
+
+ try {
+ sentryStore.dropRole(SEARCH, roleName2, grantor);
+ } catch (SentryNoSuchObjectException e) {
+ fail("Shouldn't throw SentryNoSuchObjectException");
+ }
+ }
+
+ @Test(expected=Exception.class)
+ public void testCreateDuplicateRole() throws Exception {
+ String roleName = "test-dup-role";
+ String grantor = "grantor";
+ sentryStore.createRole(SEARCH, roleName, grantor);
+ sentryStore.createRole(SEARCH, roleName, grantor);
+ }
+
+ @Test(expected=SentryNoSuchObjectException.class)
+ public void testDropNotExistRole() throws Exception {
+ String roleName = "not-exist";
+ String grantor = "grantor";
+ sentryStore.dropRole(SEARCH, roleName, grantor);
+ }
+
+ @Test(expected = SentryNoSuchObjectException.class)
+ public void testAddGroupsNonExistantRole()
+ throws Exception {
+ String roleName = "non-existant-role";
+ String grantor = "grantor";
+ sentryStore.alterRoleAddGroups(SEARCH, roleName, Sets.newHashSet("g1"), grantor);
+ }
+
+ @Test(expected = SentryNoSuchObjectException.class)
+ public void testDeleteGroupsNonExistantRole()
+ throws Exception {
+ String roleName = "non-existant-role";
+ String grantor = "grantor";
+ sentryStore.alterRoleDeleteGroups(SEARCH, roleName, Sets.newHashSet("g1"), grantor);
+ }
+
+ @Test
+ public void testAddDeleteRoleToGroups() throws Exception {
+ String role1 = "r1", role2 = "r2";
+ Set<String> twoGroups = Sets.newHashSet("g1", "g2");
+ Set<String> oneGroup = Sets.newHashSet("g3");
+ String grantor = "grantor";
+
+ sentryStore.createRole(SEARCH, role1, grantor);
+ sentryStore.createRole(SEARCH, role2, grantor);
+
+ sentryStore.alterRoleAddGroups(SEARCH, role1, twoGroups, grantor);
+ assertEquals(twoGroups, sentryStore.getGroupsByRoles(SEARCH,Sets.newHashSet(role1)));
+
+ assertEquals(Sets.newHashSet(role1), sentryStore.getRolesByGroups(SEARCH, twoGroups));
+
+ sentryStore.alterRoleAddGroups(SEARCH, role2, oneGroup, grantor);
+ assertEquals(oneGroup, sentryStore.getGroupsByRoles(SEARCH, Sets.newHashSet(role2)));
+
+ sentryStore.alterRoleDeleteGroups(SEARCH, role1, Sets.newHashSet("g1"), grantor);
+ assertEquals(Sets.newHashSet("g2"), sentryStore.getGroupsByRoles(SEARCH, Sets.newHashSet(role1)));
+
+ sentryStore.alterRoleDeleteGroups(SEARCH, role2, oneGroup, grantor);
+ assertEquals(Sets.newHashSet(), sentryStore.getGroupsByRoles(SEARCH, Sets.newHashSet(role2)));
+ }
+
+ @Test
+ public void testGetRolesByGroupNames() throws Exception {
+ String role1 = "r1", role2 = "r2";
+ Set<String> twoGroups = Sets.newHashSet("g1", "g2");
+ String grantor = "grantor";
+
+ sentryStore.createRole(SEARCH, role1, grantor);
+ sentryStore.createRole(SEARCH, role2, grantor);
+
+ sentryStore.alterRoleAddGroups(SEARCH, role1, twoGroups, grantor);
+ sentryStore.alterRoleAddGroups(SEARCH, role2, twoGroups, grantor);
+
+ assertEquals(Sets.newHashSet(role1,role2), sentryStore.getRolesByGroups(SEARCH, twoGroups));
+ }
+
+ @Test
+ public void testGetGroupsByRoleNames() throws Exception {
+ String role1 = "r1", role2 = "r2";
+ Set<String> twoGroups = Sets.newHashSet("g1", "g2");
+ String grantor = "grantor";
+
+ sentryStore.createRole(SEARCH, role1, grantor);
+ sentryStore.createRole(SEARCH, role2, grantor);
+
+ sentryStore.alterRoleAddGroups(SEARCH, role1, twoGroups, grantor);
+ sentryStore.alterRoleAddGroups(SEARCH, role2, twoGroups, grantor);
+
+ assertEquals(twoGroups, sentryStore.getGroupsByRoles(SEARCH, Sets.newHashSet(role1)));
+ assertEquals(twoGroups, sentryStore.getGroupsByRoles(SEARCH, Sets.newHashSet(role2)));
+ assertEquals(twoGroups, sentryStore.getGroupsByRoles(SEARCH, Sets.newHashSet(role1,role2)));
+ }
+
+ @Test
+ public void testGetAllRoles() throws Exception {
+ String role1 = "r1", role2 = "r2";
+ Set<String> twoGroups = Sets.newHashSet("g1", "g2");
+ String grantor = "grantor";
+
+ sentryStore.createRole(SEARCH, role1, grantor);
+ sentryStore.createRole(SEARCH, role2, grantor);
+
+ sentryStore.alterRoleAddGroups(SEARCH, role1, twoGroups, grantor);
+ sentryStore.alterRoleAddGroups(SEARCH, role2, twoGroups, grantor);
+
+ //test get all roles by groupName=null
+ String groupName = null;
+ Set<String> groups = Sets.newHashSet(groupName);
+ assertEquals(Sets.newHashSet(role1,role2), sentryStore.getRolesByGroups(SEARCH, groups));
+
+ groups.clear();
+ assertEquals(0, sentryStore.getRolesByGroups(SEARCH, groups).size());
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/7db84b2f/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestPrivilegeOperatePersistence.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestPrivilegeOperatePersistence.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestPrivilegeOperatePersistence.java
new file mode 100644
index 0000000..246b2be
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestPrivilegeOperatePersistence.java
@@ -0,0 +1,1138 @@
+/**
+ * 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.provider.db.generic.service.persistent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import com.google.common.collect.Lists;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.BitFieldAction;
+import org.apache.sentry.core.common.BitFieldActionFactory;
+import org.apache.sentry.core.model.solr.Collection;
+import org.apache.sentry.core.model.solr.Field;
+import org.apache.sentry.core.model.solr.SolrConstants;
+import org.apache.sentry.core.model.sqoop.SqoopActionConstant;
+import org.apache.sentry.core.common.exception.SentryGrantDeniedException;
+import org.apache.sentry.provider.db.generic.service.persistent.PrivilegeObject.Builder;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.apache.sentry.service.common.ServiceConstants;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.Sets;
+
+/**
+ * The test cases are used for search component The authorizables are COLLECTION and Field
+ * The actions of search privilege are ALL,QUERY and UPDATE
+ */
+public class TestPrivilegeOperatePersistence extends SentryStoreIntegrationBase {
+ private static final String SEARCH = "solr";
+ private static final String ADMIN_USER = "solr";
+ private static final String GRANT_OPTION_USER = "user_grant_option";
+ private static final String[] GRANT_OPTION_GROUP = { "group_grant_option" };
+ private static final String NO_GRANT_OPTION_USER = "user_no_grant_option";
+ private static final String[] NO_GRANT_OPTION_GROUP = { "group_no_grant_option" };
+
+ private static final String SERVICE = "service";
+ private static final String COLLECTION_NAME = "collection1";
+ private static final String NOT_COLLECTION_NAME = "not_collection1";
+ private static final String FIELD_NAME = "field1";
+ private static final String NOT_FIELD_NAME = "not_field1";
+
+ @Before
+ public void configure() throws Exception {
+ /**
+ * add the solr user to admin groups
+ */
+ policyFile = new PolicyFile();
+ addGroupsToUser(ADMIN_USER, getAdminGroups());
+ writePolicyFile();
+ }
+
+ /**
+ * Grant query privilege to role r1
+ */
+ @Test
+ public void testGrantPrivilege() throws Exception {
+ testGrantPrivilege(sentryStore, SEARCH);
+ }
+
+ @Test
+ public void testGrantPrivilegeTwice() throws Exception {
+ String roleName = "r1";
+ /**
+ * grantor is admin, there is no need to check grant option
+ */
+ String grantor = ADMIN_USER;
+ sentryStore.createRole(SEARCH, roleName, grantor);
+
+ PrivilegeObject queryPrivilegeWithOption = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .withGrantOption(true)
+ .build();
+
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, queryPrivilegeWithOption, grantor);
+ assertEquals(1,sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)).size());
+ //grant again
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, queryPrivilegeWithOption, grantor);
+ assertEquals(1,sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)).size());
+
+ PrivilegeObject queryPrivilegeWithNoOption = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .withGrantOption(false)
+ .build();
+
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, queryPrivilegeWithNoOption, grantor);
+ assertEquals(2,sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)).size());
+ //grant again
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, queryPrivilegeWithNoOption, grantor);
+ assertEquals(2,sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)).size());
+
+ PrivilegeObject queryPrivilegeWithNullGrant = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .withGrantOption(null)
+ .build();
+
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, queryPrivilegeWithNullGrant, grantor);
+
+ assertEquals(3,sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)).size());
+ //grant again
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, queryPrivilegeWithNullGrant, grantor);
+ assertEquals(3,sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)).size());
+
+ }
+
+ /**
+ * Grant query privilege to role r1 and there is ALL privilege related this
+ * collection existed
+ */
+ @Test
+ public void testGrantPrivilegeWithAllPrivilegeExist() throws Exception {
+ String roleName = "r1";
+ /**
+ * grantor is admin, there is no need to check grant option
+ */
+ String grantor = ADMIN_USER;
+ PrivilegeObject allPrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.ALL)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .build();
+
+ sentryStore.createRole(SEARCH, roleName, grantor);
+ /**
+ * grant all privilege to role r1
+ */
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, allPrivilege, grantor);
+ /**
+ * check role r1 truly has the privilege been granted
+ */
+ assertEquals(Sets.newHashSet(allPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+
+ PrivilegeObject queryPrivilege = new Builder(allPrivilege)
+ .setAction(SolrConstants.QUERY)
+ .build();
+
+ /**
+ * grant query privilege to role r1
+ */
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, queryPrivilege, grantor);
+ /**
+ * all privilege has been existed, the query privilege will not persistent
+ */
+ assertEquals(Sets.newHashSet(allPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+ }
+
+ /**
+ * Grant query privilege to role r1 and there are query and update privileges
+ * related this collection existed
+ */
+ @Test
+ public void testGrantALLPrivilegeWithOtherPrivilegesExist() throws Exception {
+ String roleName1 = "r1";
+ String roleName2 = "r2";
+ /**
+ * grantor is admin, there is no need to check grant option
+ */
+ String grantor = ADMIN_USER;
+
+ PrivilegeObject queryPrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .build();
+
+ PrivilegeObject updatePrivilege = new Builder(queryPrivilege)
+ .setAction(SolrConstants.UPDATE)
+ .build();
+
+ sentryStore.createRole(SEARCH, roleName1, grantor);
+ sentryStore.createRole(SEARCH, roleName2, grantor);
+ /**
+ * grant query and update privilege to role r1 and role r2
+ */
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, queryPrivilege, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, updatePrivilege,grantor);
+ assertEquals(Sets.newHashSet(queryPrivilege, updatePrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName1)));
+
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName2, queryPrivilege, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName2, updatePrivilege,grantor);
+ assertEquals(Sets.newHashSet(queryPrivilege, updatePrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName2)));
+
+ PrivilegeObject allPrivilege = new Builder(queryPrivilege)
+ .setAction(SolrConstants.ALL)
+ .build();
+
+ /**
+ * grant all privilege to role r1
+ */
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, allPrivilege, grantor);
+
+ /**
+ * check the query and update privileges of roleName1 will be removed because of ALl privilege
+ * granted
+ */
+ assertEquals(Sets.newHashSet(allPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName1)));
+
+ /**
+ * check the query and update privileges of roleName2 will not affected and exist
+ */
+ assertEquals(Sets.newHashSet(queryPrivilege, updatePrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName2)));
+ }
+
+ @Test
+ public void testGrantRevokeCheckWithGrantOption() throws Exception {
+
+ addGroupsToUser(GRANT_OPTION_USER, GRANT_OPTION_GROUP);
+ addGroupsToUser(NO_GRANT_OPTION_USER, NO_GRANT_OPTION_GROUP);
+ writePolicyFile();
+
+ String roleName1 = "r1";
+ String roleName2 = "r2";
+ String grantor = "g1";
+ sentryStore.createRole(SEARCH, roleName1, grantor);
+ sentryStore.createRole(SEARCH, roleName2, grantor);
+ /**
+ * grant query privilege to role r1 with grant option
+ */
+ PrivilegeObject queryPrivilege1 = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .withGrantOption(true)
+ .build();
+
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, queryPrivilege1,
+ ADMIN_USER);
+ assertEquals(Sets.newHashSet(queryPrivilege1),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName1)));
+ /**
+ * grant query privilege to role r2 no grant option
+ */
+ PrivilegeObject queryPrivilege2 = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .withGrantOption(false).build();
+
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName2, queryPrivilege2,
+ ADMIN_USER);
+ assertEquals(Sets.newHashSet(queryPrivilege2),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName2)));
+
+ sentryStore.alterRoleAddGroups(SEARCH, roleName1,
+ Sets.newHashSet(GRANT_OPTION_GROUP), grantor);
+ sentryStore.alterRoleAddGroups(SEARCH, roleName2,
+ Sets.newHashSet(NO_GRANT_OPTION_GROUP), grantor);
+
+ String roleName3 = "r3";
+ sentryStore.createRole(SEARCH, roleName3, grantor);
+ /**
+ * the user with grant option grant query privilege to rolr r3
+ */
+ try{
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName3, queryPrivilege1,
+ GRANT_OPTION_USER);
+ } catch (SentryGrantDeniedException e) {
+ fail("SentryGrantDeniedException shouldn't have been thrown");
+ }
+
+ /**
+ * the user with grant option revoke query privilege to rolr r3
+ */
+ try{
+ sentryStore.alterRoleRevokePrivilege(SEARCH, roleName3, queryPrivilege1,
+ GRANT_OPTION_USER);
+ } catch (SentryGrantDeniedException e) {
+ fail("SentryGrantDeniedException shouldn't have been thrown");
+ }
+
+ /**
+ * the user with no grant option grant query privilege to rolr r3, it will
+ * throw SentryGrantDeniedException
+ */
+ try {
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName3, queryPrivilege2,
+ NO_GRANT_OPTION_USER);
+ fail("SentryGrantDeniedException should have been thrown");
+ } catch (SentryGrantDeniedException e) {
+ //ignore the exception
+ }
+
+ /**
+ * the user with no grant option revoke query privilege to rolr r3, it will
+ * throw SentryGrantDeniedException
+ */
+ try {
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName3, queryPrivilege2,
+ NO_GRANT_OPTION_USER);
+ fail("SentryGrantDeniedException should have been thrown");
+ } catch (SentryGrantDeniedException e) {
+ //ignore the exception
+ }
+ }
+
+ @Test
+ public void testGrantWithGrantOption() throws Exception {
+
+ addGroupsToUser(GRANT_OPTION_USER, GRANT_OPTION_GROUP);
+ addGroupsToUser(NO_GRANT_OPTION_USER, NO_GRANT_OPTION_GROUP);
+ writePolicyFile();
+
+ String roleName1 = "r1";
+ String grantor = "g1";
+ sentryStore.createRole(SEARCH, roleName1, grantor);
+ /**
+ * grant query privilege to role r1 with grant option
+ */
+ PrivilegeObject queryPrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .withGrantOption(true)
+ .build();
+
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, queryPrivilege,ADMIN_USER);
+ sentryStore.alterRoleAddGroups(SEARCH, roleName1,
+ Sets.newHashSet(GRANT_OPTION_GROUP), grantor);
+
+ /**
+ * the user with grant option grant query privilege to rolr r2
+ */
+ String roleName2 = "r2";
+ sentryStore.createRole(SEARCH, roleName2, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName2, queryPrivilege, GRANT_OPTION_USER);
+
+ assertEquals(Sets.newHashSet(queryPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName2)));
+
+ }
+
+
+ /**
+ * Grant query and update privileges to role r1 and revoke query privilege
+ * there is left update privilege related to role r1
+ */
+ @Test
+ public void testRevokePrivilege() throws Exception {
+ String roleName = "r1";
+ /**
+ * grantor is admin, there is no need to check grant option
+ */
+ String grantor = ADMIN_USER;
+ PrivilegeObject queryPrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME)))
+ .build();
+
+ PrivilegeObject updatePrivilege = new Builder(queryPrivilege)
+ .setAction(SolrConstants.UPDATE)
+ .build();
+
+ sentryStore.createRole(SEARCH, roleName, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, queryPrivilege, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, updatePrivilege, grantor);
+
+ assertEquals(Sets.newHashSet(queryPrivilege,updatePrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+ /**
+ * revoke query privilege
+ */
+ sentryStore.alterRoleRevokePrivilege(SEARCH, roleName, queryPrivilege, grantor);
+ assertEquals(Sets.newHashSet(updatePrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+ }
+
+ /**
+ * Grant query and update privileges to role r1 and revoke all privilege,
+ * there is no privilege related to role r1
+ */
+ @Test
+ public void testRevokeAllPrivilege() throws Exception {
+ String roleName = "r1";
+ /**
+ * grantor is admin, there is no need to check grant option
+ */
+ String grantor = ADMIN_USER;
+ PrivilegeObject queryPrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME),new Field(FIELD_NAME)))
+ .build();
+
+ PrivilegeObject updatePrivilege = new Builder(queryPrivilege)
+ .setAction(SolrConstants.UPDATE)
+ .build();
+
+ sentryStore.createRole(SEARCH, roleName, grantor);
+
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, queryPrivilege, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, updatePrivilege, grantor);
+
+ assertEquals(Sets.newHashSet(queryPrivilege,updatePrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+ /**
+ * revoke all privilege
+ */
+ PrivilegeObject allPrivilege = new Builder(queryPrivilege)
+ .setAction(SolrConstants.ALL)
+ .build();
+
+ sentryStore.alterRoleRevokePrivilege(SEARCH, roleName, allPrivilege, grantor);
+
+ assertEquals(Sets.newHashSet(),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+ }
+
+ /**
+ * Grant all privilege to role r1 and revoke query privilege
+ * there is update privilege related to role r1
+ */
+ @Test
+ public void testRevokePrivilegeWithAllPrivilegeExist() throws Exception {
+ String roleName = "r1";
+ /**
+ * grantor is admin, there is no need to check grant option
+ */
+ String grantor = ADMIN_USER;
+ PrivilegeObject allPrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.ALL)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME)))
+ .build();
+
+ sentryStore.createRole(SEARCH, roleName, grantor);
+
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, allPrivilege, grantor);
+
+ assertEquals(Sets.newHashSet(allPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+ /**
+ * revoke update privilege
+ */
+ PrivilegeObject updatePrivilege = new Builder(allPrivilege)
+ .setAction(SolrConstants.UPDATE)
+ .build();
+
+ PrivilegeObject queryPrivilege = new Builder(allPrivilege)
+ .setAction(SolrConstants.QUERY)
+ .build();
+
+ sentryStore.alterRoleRevokePrivilege(SEARCH, roleName, updatePrivilege, grantor);
+
+ assertEquals(Sets.newHashSet(queryPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+ }
+
+ /**
+ * Grant update, query and all privilege to role r1
+ * Revoke query privilege from role r1
+ * there is update privilege related to role r1
+ */
+ @Test
+ public void testRevokePrivilegeWithAllPrivilegesGranted() throws Exception {
+ String roleName = "r1";
+ /**
+ * grantor is admin, there is no need to check grant option
+ */
+ String grantor = ADMIN_USER;
+ PrivilegeObject allPrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.ALL)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME)))
+ .build();
+
+ PrivilegeObject updatePrivilege = new Builder(allPrivilege)
+ .setAction(SolrConstants.UPDATE)
+ .build();
+
+ PrivilegeObject queryPrivilege = new Builder(allPrivilege)
+ .setAction(SolrConstants.QUERY)
+ .build();
+
+ sentryStore.createRole(SEARCH, roleName, grantor);
+ //grant query to role r1
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, queryPrivilege, grantor);
+ assertEquals(Sets.newHashSet(queryPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+
+ //grant update to role r1
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, updatePrivilege, grantor);
+ assertEquals(Sets.newHashSet(queryPrivilege, updatePrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+ /**
+ * grant all action privilege to role r1, because all action includes query and update action,
+ * The role r1 only has the action all privilege
+ */
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, allPrivilege, grantor);
+ assertEquals(Sets.newHashSet(allPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+ /**
+ * revoke update privilege from role r1, the query privilege has been left
+ */
+ sentryStore.alterRoleRevokePrivilege(SEARCH, roleName, updatePrivilege, grantor);
+ assertEquals(Sets.newHashSet(queryPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+ }
+
+ @Test
+ public void testRevokeParentPrivilegeWithChildsExist() throws Exception {
+ String roleName = "r1";
+ /**
+ * grantor is admin, there is no need to check grant option
+ */
+ String grantor = ADMIN_USER;
+ PrivilegeObject updatePrivilege1 = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.UPDATE)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME)))
+ .build();
+
+ PrivilegeObject queryPrivilege1 = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME),new Field(FIELD_NAME)))
+ .build();
+
+ PrivilegeObject queryPrivilege2 = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(NOT_COLLECTION_NAME)))
+ .build();
+
+ sentryStore.createRole(SEARCH, roleName, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, updatePrivilege1, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, queryPrivilege1, grantor);
+
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, queryPrivilege2, grantor);
+
+ /**
+ * revoke all privilege with collection[COLLECTION_NAME=collection1] and its child privileges
+ */
+ PrivilegeObject allPrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.ALL)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .build();
+
+ sentryStore.alterRoleRevokePrivilege(SEARCH, roleName, allPrivilege, grantor);
+ assertEquals(Sets.newHashSet(queryPrivilege2),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+ }
+
+ @Test
+ public void testRevokeWithGrantOption() throws Exception {
+
+ addGroupsToUser(GRANT_OPTION_USER, GRANT_OPTION_GROUP);
+ addGroupsToUser(NO_GRANT_OPTION_USER, NO_GRANT_OPTION_GROUP);
+ writePolicyFile();
+
+ String roleName1 = "r1";
+ String grantor = "g1";
+ sentryStore.createRole(SEARCH, roleName1, grantor);
+ /**
+ * grant query privilege to role r1 with grant option
+ */
+ PrivilegeObject queryPrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .withGrantOption(true)
+ .build();
+
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, queryPrivilege,
+ ADMIN_USER);
+ assertEquals(Sets.newHashSet(queryPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName1)));
+
+ sentryStore.alterRoleAddGroups(SEARCH, roleName1,
+ Sets.newHashSet(GRANT_OPTION_GROUP), grantor);
+
+ String roleName2 = "r2";
+ sentryStore.createRole(SEARCH, roleName2, grantor);
+ /**
+ * the user with grant option grant query privilege to rolr r2
+ */
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName2, queryPrivilege,
+ GRANT_OPTION_USER);
+ assertEquals(Sets.newHashSet(queryPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName2)));
+
+ /**
+ * the user with grant option revoke query privilege to rolr r3
+ */
+ sentryStore.alterRoleRevokePrivilege(SEARCH, roleName2, queryPrivilege, GRANT_OPTION_USER);
+ assertEquals(Sets.newHashSet(),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName2)));
+ }
+
+ @Test
+ public void testDropPrivilege() throws Exception{
+ String roleName1 = "r1";
+ String roleName2 = "r2";
+ String grantor = ADMIN_USER;
+
+ PrivilegeObject queryPrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME)))
+ .build();
+
+ PrivilegeObject updatePrivilege = new Builder(queryPrivilege)
+ .setAction(SolrConstants.UPDATE)
+ .build();
+
+ /**
+ * grant query and update privilege to role r1 and r2
+ */
+ sentryStore.createRole(SEARCH, roleName1, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, queryPrivilege, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, updatePrivilege, grantor);
+
+ sentryStore.createRole(SEARCH, roleName2, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName2, queryPrivilege, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName2, updatePrivilege, grantor);
+
+ assertEquals(Sets.newHashSet(queryPrivilege,updatePrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName1)));
+
+ assertEquals(Sets.newHashSet(queryPrivilege,updatePrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName2)));
+ /**
+ * drop query privilege
+ */
+ sentryStore.dropPrivilege(SEARCH, queryPrivilege, grantor);
+
+ assertEquals(Sets.newHashSet(updatePrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName1)));
+
+ assertEquals(Sets.newHashSet(updatePrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName2)));
+
+ /**
+ * drop ALL privilege
+ */
+ PrivilegeObject allPrivilege = new Builder(queryPrivilege)
+ .setAction(SolrConstants.ALL)
+ .build();
+
+ sentryStore.dropPrivilege(SEARCH, allPrivilege, grantor);
+
+ assertEquals(Sets.newHashSet(),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName1)));
+
+ assertEquals(Sets.newHashSet(),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName2)));
+
+ /**
+ * grant query and update field scope[collection1,field1] privilege to role r1
+ * drop collection scope[collection1] privilege
+ * there is no privilege
+ */
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, queryPrivilege, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, updatePrivilege, grantor);
+
+ PrivilegeObject parentPrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.ALL)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .build();
+
+ sentryStore.dropPrivilege(SEARCH, parentPrivilege, grantor);
+ assertEquals(Sets.newHashSet(),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName1)));
+ }
+
+ @Test
+ public void testRenamePrivilege() throws Exception{
+ String roleName1 = "r1";
+ String roleName2 = "r2";
+ String grantor = ADMIN_USER;
+
+ List<? extends Authorizable> oldAuthoriables = Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME));
+ List<? extends Authorizable> newAuthoriables = Arrays.asList(new Collection(COLLECTION_NAME), new Field(NOT_FIELD_NAME));
+
+ PrivilegeObject oldQueryPrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(oldAuthoriables)
+ .build();
+
+ PrivilegeObject oldUpdatePrivilege = new Builder(oldQueryPrivilege)
+ .setAction(SolrConstants.UPDATE)
+ .build();
+
+ PrivilegeObject oldALLPrivilege = new Builder(oldQueryPrivilege)
+ .setAction(SolrConstants.ALL)
+ .build();
+
+
+ PrivilegeObject newQueryPrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(newAuthoriables)
+ .build();
+
+ PrivilegeObject newUpdatePrivilege = new Builder(newQueryPrivilege)
+ .setAction(SolrConstants.UPDATE)
+ .build();
+
+ PrivilegeObject newALLPrivilege = new Builder(newQueryPrivilege)
+ .setAction(SolrConstants.ALL)
+ .build();
+
+
+ /**
+ * grant query and update privilege to role r1
+ * grant all privilege to role r2
+ */
+ sentryStore.createRole(SEARCH, roleName1, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, oldQueryPrivilege, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, oldUpdatePrivilege, grantor);
+
+ sentryStore.createRole(SEARCH, roleName2, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName2, oldALLPrivilege, grantor);
+
+ assertEquals(Sets.newHashSet(oldQueryPrivilege,oldUpdatePrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName1)));
+
+ assertEquals(Sets.newHashSet(oldALLPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName2)));
+ /**
+ * rename old query privilege to new query privilege
+ */
+ sentryStore.renamePrivilege(SEARCH, SERVICE,
+ oldAuthoriables,
+ newAuthoriables,
+ grantor);
+
+ assertEquals(Sets.newHashSet(newQueryPrivilege,newUpdatePrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName1)));
+
+ assertEquals(Sets.newHashSet(newALLPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName2)));
+ /**
+ * rename collection scope[collection=collection1] privilege to [collection=not_collection1]
+ * These privileges belong to collection scope[collection=collection1] will change to
+ * [collection=not_collection1]
+ */
+
+ List<? extends Authorizable> newAuthoriables1 = Arrays.asList(new Collection(NOT_COLLECTION_NAME),new Field(NOT_FIELD_NAME));
+
+ PrivilegeObject newQueryPrivilege1 = new Builder(newQueryPrivilege)
+ .setAuthorizables(newAuthoriables1)
+ .build();
+
+ PrivilegeObject newUpdatePrivilege1 = new Builder(newUpdatePrivilege)
+ .setAuthorizables(newAuthoriables1)
+ .build();
+
+ PrivilegeObject newALLPrivilege1 = new Builder(newALLPrivilege)
+ .setAuthorizables(newAuthoriables1)
+ .build();
+
+ sentryStore.renamePrivilege(SEARCH, SERVICE,
+ Arrays.asList(new Collection(COLLECTION_NAME)),
+ Arrays.asList(new Collection(NOT_COLLECTION_NAME)),
+ grantor);
+
+ assertEquals(Sets.newHashSet(newQueryPrivilege1,newUpdatePrivilege1),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName1)));
+
+ assertEquals(Sets.newHashSet(newALLPrivilege1),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName2)));
+ }
+
+ @Test
+ public void testGetPrivilegesByRoleName() throws Exception {
+ String roleName1 = "r1";
+ String roleName2 = "r2";
+ String grantor = "g1";
+
+ PrivilegeObject queryPrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .build();
+
+ sentryStore.createRole(SEARCH, roleName1, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, queryPrivilege,
+ ADMIN_USER);
+
+ PrivilegeObject updatePrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .build();
+
+ sentryStore.createRole(SEARCH, roleName2, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName2, updatePrivilege,
+ ADMIN_USER);
+
+ assertEquals(Sets.newHashSet(queryPrivilege,updatePrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName1,roleName2)));
+
+ }
+
+ @Test
+ public void testGetPrivilegesByProvider() throws Exception {
+ String roleName1 = "r1";
+ String roleName2 = "r2";
+ String roleName3 = "r3";
+ String group = "g3";
+ String grantor = ADMIN_USER;
+
+ String service1 = "service1";
+
+ PrivilegeObject queryPrivilege1 = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(service1)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .build();
+
+ PrivilegeObject updatePrivilege1 = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.UPDATE)
+ .setService(service1)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME)))
+ .build();
+
+ PrivilegeObject queryPrivilege2 = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(service1)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .build();
+
+ PrivilegeObject updatePrivilege2 = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.UPDATE)
+ .setService(service1)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME)))
+ .build();
+
+ sentryStore.createRole(SEARCH, roleName1, grantor);
+ sentryStore.createRole(SEARCH, roleName2, grantor);
+ sentryStore.createRole(SEARCH, roleName3, grantor);
+
+ sentryStore.alterRoleAddGroups(SEARCH, roleName3, Sets.newHashSet(group), grantor);
+
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, queryPrivilege1, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, updatePrivilege1, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName2, queryPrivilege2, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName3, updatePrivilege2, grantor);
+
+ assertEquals(Sets.newHashSet(updatePrivilege1, queryPrivilege1),
+ sentryStore.getPrivilegesByProvider(SEARCH, service1, Sets.newHashSet(roleName1), null, null));
+
+ assertEquals(Sets.newHashSet(updatePrivilege1, queryPrivilege1, queryPrivilege2),
+ sentryStore.getPrivilegesByProvider(SEARCH, service1, Sets.newHashSet(roleName1,roleName2),
+ null, null));
+
+ assertEquals(Sets.newHashSet(updatePrivilege1, queryPrivilege1, queryPrivilege2, updatePrivilege2),
+ sentryStore.getPrivilegesByProvider(SEARCH, service1, Sets.newHashSet(roleName1,roleName2),
+ Sets.newHashSet(group), null));
+
+ List<? extends Authorizable> authorizables = Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME));
+ assertEquals(Sets.newHashSet(updatePrivilege1, updatePrivilege2),
+ sentryStore.getPrivilegesByProvider(SEARCH, service1, Sets.newHashSet(roleName1,roleName2),
+ Sets.newHashSet(group), authorizables));
+ }
+
+ @Test
+ public void testGetPrivilegesByAuthorizable() throws Exception {
+ String roleName1 = "r1";
+ String roleName2 = "r2";
+ String roleName3 = "r3";
+ String grantor = ADMIN_USER;
+
+ String service1 = "service1";
+
+ PrivilegeObject queryPrivilege1 = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(service1)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .build();
+
+ PrivilegeObject updatePrivilege1 = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.UPDATE)
+ .setService(service1)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME)))
+ .build();
+
+ PrivilegeObject queryPrivilege2 = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.QUERY)
+ .setService(service1)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
+ .build();
+
+ PrivilegeObject updatePrivilege2 = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SolrConstants.UPDATE)
+ .setService(service1)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME)))
+ .build();
+
+ sentryStore.createRole(SEARCH, roleName1, grantor);
+ sentryStore.createRole(SEARCH, roleName2, grantor);
+ sentryStore.createRole(SEARCH, roleName3, grantor);
+
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, queryPrivilege1, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, updatePrivilege1, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName2, queryPrivilege2, grantor);
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName3, updatePrivilege2, grantor);
+
+ assertEquals(0, sentryStore.getPrivilegesByAuthorizable(SEARCH, service1, null,
+ Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME))).size());
+ assertEquals(1, sentryStore.getPrivilegesByAuthorizable(SEARCH, service1, Sets.newHashSet(roleName1),
+ Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME))).size());
+ assertEquals(2, sentryStore.getPrivilegesByAuthorizable(SEARCH, service1,
+ Sets.newHashSet(roleName1), null).size());
+ assertEquals(2, sentryStore.getPrivilegesByAuthorizable(SEARCH, service1,
+ Sets.newHashSet(roleName1,roleName2), null).size());
+ assertEquals(2, sentryStore.getPrivilegesByAuthorizable(SEARCH, service1,
+ Sets.newHashSet(roleName1,roleName2, roleName3), null).size());
+ }
+
+ @Test(expected = Exception.class)
+ public void testGrantPrivilegeExternalComponentMissingConf() throws Exception {
+ testGrantPrivilege(sentryStore, "externalComponent");
+ }
+
+ @Test(expected = Exception.class)
+ public void testGrantPrivilegeExternalComponentInvalidConf() throws Exception {
+ String externalComponent = "mycomponent";
+ Configuration confCopy = new Configuration(conf);
+ confCopy.set(String.format(ServiceConstants.ServerConfig.SENTRY_COMPONENT_ACTION_FACTORY_FORMAT, externalComponent),
+ InvalidActionFactory.class.getName());
+ SentryStoreLayer store = new DelegateSentryStore(confCopy);
+ testGrantPrivilege(store, externalComponent);
+ }
+
+ @Test
+ public void testGrantPrivilegeExternalComponent() throws Exception {
+ String externalComponent = "mycomponent";
+ Configuration confCopy = new Configuration(conf);
+ confCopy.set(String.format(ServiceConstants.ServerConfig.SENTRY_COMPONENT_ACTION_FACTORY_FORMAT, externalComponent),
+ MyComponentActionFactory.class.getName());
+ SentryStoreLayer store = new DelegateSentryStore(confCopy);
+ testGrantPrivilege(store, externalComponent);
+ }
+
+ @Test
+ public void testGrantPrivilegeExternalComponentCaseInsensitivity() throws Exception {
+ String externalComponent = "MyCoMpOnEnT";
+ Configuration confCopy = new Configuration(conf);
+ confCopy.set(String.format(ServiceConstants.ServerConfig.SENTRY_COMPONENT_ACTION_FACTORY_FORMAT, "mycomponent"),
+ MyComponentActionFactory.class.getName());
+ SentryStoreLayer store = new DelegateSentryStore(confCopy);
+ testGrantPrivilege(store, externalComponent);
+ }
+
+ private void testGrantPrivilege(SentryStoreLayer sentryStore, String component) throws Exception {
+ String roleName = "r1";
+ /**
+ * grantor is admin, there is no need to check grant option
+ */
+ String grantor = ADMIN_USER;
+ PrivilegeObject queryPrivilege = new Builder()
+ .setComponent(component)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Collections.singletonList(new Collection(COLLECTION_NAME)))
+ .withGrantOption(null)
+ .build();
+
+ sentryStore.createRole(component, roleName, grantor);
+ sentryStore.alterRoleGrantPrivilege(component, roleName, queryPrivilege, grantor);
+
+ assertEquals(Sets.newHashSet(queryPrivilege),
+ sentryStore.getPrivilegesByRole(component, Sets.newHashSet(roleName)));
+
+ PrivilegeObject queryPrivilegeWithOption = new Builder()
+ .setComponent(component)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Collections.singletonList(new Collection(COLLECTION_NAME)))
+ .withGrantOption(true)
+ .build();
+
+ sentryStore.alterRoleGrantPrivilege(component, roleName, queryPrivilegeWithOption, grantor);
+
+ assertEquals(Sets.newHashSet(queryPrivilege, queryPrivilegeWithOption),
+ sentryStore.getPrivilegesByRole(component, Sets.newHashSet(roleName)));
+
+ PrivilegeObject queryPrivilegeWithNoOption = new Builder()
+ .setComponent(component)
+ .setAction(SolrConstants.QUERY)
+ .setService(SERVICE)
+ .setAuthorizables(Collections.singletonList(new Collection(COLLECTION_NAME)))
+ .withGrantOption(false)
+ .build();
+
+ sentryStore.alterRoleGrantPrivilege(component, roleName, queryPrivilegeWithNoOption, grantor);
+
+ assertEquals(Sets.newHashSet(queryPrivilege, queryPrivilegeWithOption, queryPrivilegeWithNoOption),
+ sentryStore.getPrivilegesByRole(component, Sets.newHashSet(roleName)));
+ }
+
+ public static final class InvalidActionFactory {
+
+ }
+
+ public static final class MyComponentActionFactory extends BitFieldActionFactory {
+
+ public enum MyComponentActionType {
+ FOO("foo", 1),
+ BAR("bar", 2),
+ QUERY(SolrConstants.QUERY, 4),
+ ALL("*", FOO.getCode() | BAR.getCode() | QUERY.getCode());
+
+ private String name;
+ private int code;
+ MyComponentActionType(String name, int code) {
+ this.name = name;
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ static MyComponentActionType getActionByName(String name) {
+ for (MyComponentActionType action : MyComponentActionType.values()) {
+ if (action.name.equalsIgnoreCase(name)) {
+ return action;
+ }
+ }
+ throw new RuntimeException("can't get MyComponentActionType by name:" + name);
+ }
+
+ static List<MyComponentActionType> getActionByCode(int code) {
+ List<MyComponentActionType> actions = Lists.newArrayList();
+ for (MyComponentActionType action : MyComponentActionType.values()) {
+ if ((action.code & code) == action.code && action != MyComponentActionType.ALL) {
+ //MyComponentActionType.ALL action should not return in the list
+ actions.add(action);
+ }
+ }
+ if (actions.isEmpty()) {
+ throw new RuntimeException("can't get sqoopActionType by code:" + code);
+ }
+ return actions;
+ }
+ }
+
+ public static class MyComponentAction extends BitFieldAction {
+ public MyComponentAction(String name) {
+ this(MyComponentActionType.getActionByName(name));
+ }
+ public MyComponentAction(MyComponentActionType myComponentActionType) {
+ super(myComponentActionType.name, myComponentActionType.code);
+ }
+ }
+
+ @Override
+ public List<? extends BitFieldAction> getActionsByCode(int actionCode) {
+ List<MyComponentAction> actions = Lists.newArrayList();
+ for (MyComponentActionType action : MyComponentActionType.getActionByCode(actionCode)) {
+ actions.add(new MyComponentAction(action));
+ }
+ return actions;
+ }
+
+ @Override
+ public BitFieldAction getActionByName(String name) {
+ // Check the name is All
+ if (SqoopActionConstant.ALL_NAME.equalsIgnoreCase(name)) {
+ return new MyComponentAction(MyComponentActionType.ALL);
+ }
+ return new MyComponentAction(name);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/7db84b2f/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestSentryGMPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestSentryGMPrivilege.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestSentryGMPrivilege.java
new file mode 100644
index 0000000..03abb4e
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestSentryGMPrivilege.java
@@ -0,0 +1,207 @@
+/**
+ * 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.provider.db.generic.service.persistent;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+import java.util.Arrays;
+
+import org.apache.sentry.core.model.db.AccessConstants;
+import org.apache.sentry.core.model.solr.Collection;
+import org.apache.sentry.core.model.solr.Field;
+import org.apache.sentry.core.model.solr.SolrConstants;
+import org.apache.sentry.provider.db.service.model.MSentryGMPrivilege;
+import org.junit.Test;
+
+public class TestSentryGMPrivilege {
+
+ @Test
+ public void testValidateAuthorizables() throws Exception {
+ try {
+ new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(new Collection("c1"), new Field("f1")),SolrConstants.QUERY, false);
+ } catch (IllegalStateException e) {
+ fail("unexpect happend: it is a validated privilege");
+ }
+
+ try {
+ new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(new Collection(""), new Field("f1")),SolrConstants.QUERY, false);
+ fail("unexpect happend: it is not a validated privilege, The empty name of authorizable can't be empty");
+ } catch (IllegalStateException e) {
+ }
+
+ try {
+ new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(null, new Field("f1")),SolrConstants.QUERY, false);
+ fail("unexpect happend: it is not a validated privilege, The authorizable can't be null");
+ } catch (IllegalStateException e) {
+ }
+ }
+
+ @Test
+ public void testImpliesWithServerScope() throws Exception {
+ //The persistent privilege is server scope
+ MSentryGMPrivilege serverPrivilege = new MSentryGMPrivilege("solr",
+ "service1", null,SolrConstants.QUERY, false);
+
+ MSentryGMPrivilege collectionPrivilege = new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(new Collection("c1")),
+ SolrConstants.QUERY, false);
+ assertTrue(serverPrivilege.implies(collectionPrivilege));
+
+ MSentryGMPrivilege fieldPrivilege = new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(new Collection("c1"), new Field("f1")),
+ SolrConstants.QUERY, false);
+ assertTrue(serverPrivilege.implies(fieldPrivilege));
+ assertTrue(collectionPrivilege.implies(fieldPrivilege));
+
+ serverPrivilege.setAction(SolrConstants.UPDATE);
+ assertFalse(serverPrivilege.implies(collectionPrivilege));
+ assertFalse(serverPrivilege.implies(fieldPrivilege));
+
+ serverPrivilege.setAction(SolrConstants.ALL);
+ assertTrue(serverPrivilege.implies(collectionPrivilege));
+ assertTrue(serverPrivilege.implies(fieldPrivilege));
+ }
+ /**
+ * The requested privilege has the different authorizable size with the persistent privilege
+ * @throws Exception
+ */
+ @Test
+ public void testImpliesDifferentAuthorizable() throws Exception {
+ /**
+ * Test the scope of persistent privilege is the larger than the requested privilege
+ */
+ MSentryGMPrivilege serverPrivilege = new MSentryGMPrivilege("solr",
+ "service1", null, SolrConstants.QUERY, false);
+
+ MSentryGMPrivilege collectionPrivilege = new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(new Collection("c1")),
+ SolrConstants.QUERY, false);
+
+ MSentryGMPrivilege fieldPrivilege = new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(new Collection("c1"), new Field("f1")),
+ SolrConstants.QUERY, false);
+ assertTrue(serverPrivilege.implies(collectionPrivilege));
+ assertTrue(serverPrivilege.implies(fieldPrivilege));
+ assertTrue(collectionPrivilege.implies(fieldPrivilege));
+ /**
+ * Test the scope of persistent privilege is less than the request privilege
+ */
+ assertFalse(fieldPrivilege.implies(collectionPrivilege));
+ assertFalse(fieldPrivilege.implies(serverPrivilege));
+ assertFalse(collectionPrivilege.implies(serverPrivilege));
+
+ /**
+ * Test the scope of persistent privilege is less than the request privilege,
+ * but the name of left authorizable is ALL
+ */
+ MSentryGMPrivilege fieldAllPrivilege = new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(new Collection("c1"), new Field(AccessConstants.ALL)),
+ SolrConstants.QUERY, false);
+
+ assertTrue(fieldAllPrivilege.implies(collectionPrivilege));
+
+ /**
+ * Test the scope of persistent privilege has the same scope as request privilege
+ */
+ MSentryGMPrivilege fieldPrivilege1 = new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(new Collection("c1"), new Field("f1")),
+ SolrConstants.QUERY, false);
+
+ MSentryGMPrivilege fieldPrivilege2 = new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(new Collection("c2"), new Field("f2")),
+ SolrConstants.QUERY, false);
+ assertFalse(fieldPrivilege1.implies(fieldPrivilege2));
+ }
+
+ /**
+ * The requested privilege has the same authorizable size as with the persistent privilege
+ * @throws Exception
+ */
+ @Test
+ public void testSearchImpliesEqualAuthorizable() throws Exception {
+
+ MSentryGMPrivilege serverPrivilege1 = new MSentryGMPrivilege("solr",
+ "service1", null,SolrConstants.QUERY, false);
+
+ MSentryGMPrivilege serverPrivilege2 = new MSentryGMPrivilege("solr",
+ "service2", null,SolrConstants.QUERY, false);
+
+ assertFalse(serverPrivilege1.implies(serverPrivilege2));
+
+ MSentryGMPrivilege collectionPrivilege1 = new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(new Collection("c1")),
+ SolrConstants.QUERY, false);
+
+ MSentryGMPrivilege collectionPrivilege2 = new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(new Collection("c2")),
+ SolrConstants.QUERY, false);
+
+ assertFalse(collectionPrivilege1.implies(collectionPrivilege2));
+
+ MSentryGMPrivilege fieldPrivilege1 = new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(new Collection("c1"), new Field("f1")),
+ SolrConstants.QUERY, false);
+
+ MSentryGMPrivilege fieldPrivilege2 = new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(new Collection("c1"), new Field("f2")),
+ SolrConstants.QUERY, false);
+
+ assertFalse(fieldPrivilege1.implies(fieldPrivilege2));
+
+ /**
+ * The authorizables aren't equal,but the persistent privilege has the ALL name
+ */
+ collectionPrivilege2.setAuthorizables(Arrays.asList(new Collection(AccessConstants.ALL)));
+ collectionPrivilege2.implies(collectionPrivilege1);
+
+ fieldPrivilege2.setAuthorizables(Arrays.asList(new Collection("c1"), new Field(AccessConstants.ALL)));
+ fieldPrivilege2.implies(fieldPrivilege1);
+ }
+
+ @Test
+ public void testSearchImpliesAction() throws Exception {
+ /**
+ * action is equal
+ */
+ MSentryGMPrivilege fieldPrivilege1 = new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(new Collection("c1"), new Field("f2")),
+ SolrConstants.QUERY, false);
+
+ MSentryGMPrivilege fieldPrivilege2 = new MSentryGMPrivilege("solr",
+ "service1", Arrays.asList(new Collection("c1"), new Field("f2")),
+ SolrConstants.QUERY, false);
+
+ assertTrue(fieldPrivilege1.implies(fieldPrivilege2));
+
+ /**
+ * action isn't equal
+ */
+ fieldPrivilege2.setAction(SolrConstants.UPDATE);
+ assertFalse(fieldPrivilege1.implies(fieldPrivilege2));
+ /**
+ * action isn't equal,but the persistent privilege has the ALL action
+ */
+ fieldPrivilege1.setAction(SolrConstants.ALL);
+ assertTrue(fieldPrivilege1.implies(fieldPrivilege2));
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/7db84b2f/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestSentryRole.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestSentryRole.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestSentryRole.java
new file mode 100644
index 0000000..65d26c0
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestSentryRole.java
@@ -0,0 +1,542 @@
+/**
+ * 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.provider.db.generic.service.persistent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.List;
+
+import javax.jdo.JDOHelper;
+import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+import javax.jdo.Query;
+import javax.jdo.Transaction;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.model.solr.Collection;
+import org.apache.sentry.provider.db.service.model.MSentryGMPrivilege;
+import org.apache.sentry.provider.db.service.model.MSentryPrivilege;
+import org.apache.sentry.provider.db.service.model.MSentryRole;
+import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.service.common.ServiceConstants.ServerConfig;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.base.Preconditions;
+import com.google.common.io.Files;
+/**
+ * The class tests that the new feature SENTRY-398 generic model adds the new field in the MSentryRole
+ * will not affect the functionality of the origin hive/impala authorization model
+ * Some Tests below make sure that privileges are removed from sentry storage the moment they are not associated to any role.
+ * This avoid the need for PrivCleaner to perform periodic cleanup.
+ */
+public class TestSentryRole {
+ private static PersistenceManagerFactory pmf;
+ private static File dataDir;
+
+ @Before
+ public void setup() throws Exception {
+ dataDir = new File(Files.createTempDir(), "sentry_policy_db");
+ Properties prop = new Properties();
+ prop.setProperty(ServerConfig.JAVAX_JDO_URL, "jdbc:derby:;databaseName=" + dataDir.getPath() + ";create=true");
+ prop.setProperty(ServerConfig.JAVAX_JDO_USER, "Sentry");
+ prop.setProperty(ServerConfig.JAVAX_JDO_PASS, "Sentry");
+ prop.setProperty(ServerConfig.JAVAX_JDO_DRIVER_NAME, "org.apache.derby.jdbc.EmbeddedDriver");
+ prop.setProperty("datanucleus.schema.autoCreateAll", "true");
+ prop.setProperty("datanucleus.NontransactionalRead", "false");
+ prop.setProperty("datanucleus.NontransactionalWrite", "false");
+ pmf = JDOHelper.getPersistenceManagerFactory(prop);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ pmf.close();
+ FileUtils.deleteQuietly(dataDir);
+ }
+
+ @Test
+ public void grantMixedPrivilegeTest() throws Exception {
+ String roleName = "r1";
+ //hive/impala privilege
+ MSentryPrivilege hivePrivilege = new MSentryPrivilege();
+ hivePrivilege.setServerName("hive.server1");
+ hivePrivilege.setDbName("db1");
+ hivePrivilege.setTableName("tb1");
+ hivePrivilege.setPrivilegeScope("table");
+ hivePrivilege.setAction("select");
+ hivePrivilege.setGrantOption(true);
+ //solr privilege
+ MSentryGMPrivilege solrPrivilege = new MSentryGMPrivilege();
+ solrPrivilege.setComponentName("solr");
+ solrPrivilege.setServiceName("solr.server1");
+ solrPrivilege.setAuthorizables(Arrays.asList(new Collection("c1")));
+ solrPrivilege.setAction("query");
+ solrPrivilege.setGrantOption(true);
+
+ PersistenceManager pm = null;
+ //create role
+ pm = openTransaction();
+ pm.makePersistent(new MSentryRole(roleName, System.currentTimeMillis()));
+ commitTransaction(pm);
+ //add hivePrivilege to role
+ pm = openTransaction();
+ MSentryRole role = getMSentryRole(pm, roleName);
+ hivePrivilege.appendRole(role);
+ pm.makePersistent(hivePrivilege);
+ commitTransaction(pm);
+ //check hivePrivlege and solrPrivilege
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ pm.retrieve(role);
+ assertEquals(1, role.getPrivileges().size());
+ assertEquals(0, role.getGmPrivileges().size());
+ commitTransaction(pm);
+ //add solrPrivilege to role
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ pm.retrieve(role);
+ solrPrivilege.appendRole(role);
+ pm.makePersistent(solrPrivilege);
+ commitTransaction(pm);
+ //check hivePrivlege and solrPrivilege
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ pm.retrieve(role);
+ assertEquals(1, role.getPrivileges().size());
+ assertEquals(1, role.getGmPrivileges().size());
+ commitTransaction(pm);
+ }
+
+ @Test
+ public void testWantGrantPrivilegeTwice() throws Exception {
+ String roleName = "r1";
+ //hive/impala privilege
+ MSentryPrivilege hivePrivilege = new MSentryPrivilege();
+ hivePrivilege.setServerName("hive.server1");
+ hivePrivilege.setDbName("db1");
+ hivePrivilege.setTableName("tb1");
+ hivePrivilege.setPrivilegeScope("table");
+ hivePrivilege.setAction("select");
+ hivePrivilege.setURI(SentryStore.NULL_COL);
+ hivePrivilege.setColumnName(SentryStore.NULL_COL);
+ hivePrivilege.setGrantOption(true);
+ //The same hivePrivilege
+ MSentryPrivilege hivePrivilege2 = new MSentryPrivilege(hivePrivilege);
+ //solr privilege
+ MSentryGMPrivilege solrPrivilege = new MSentryGMPrivilege();
+ solrPrivilege.setComponentName("solr");
+ solrPrivilege.setServiceName("solr.server1");
+ solrPrivilege.setAuthorizables(Arrays.asList(new Collection("c1")));
+ solrPrivilege.setAction("query");
+ solrPrivilege.setGrantOption(true);
+ //The same solrPrivilege
+ MSentryGMPrivilege solrPrivilege2 = new MSentryGMPrivilege(solrPrivilege);
+
+ PersistenceManager pm = null;
+ //create role
+ pm = openTransaction();
+ pm.makePersistent(new MSentryRole(roleName, System.currentTimeMillis()));
+ commitTransaction(pm);
+
+ //grant hivePrivilege and solrPrivilege to role
+ pm = openTransaction();
+ MSentryRole role = getMSentryRole(pm, roleName);
+ solrPrivilege.appendRole(role);
+ hivePrivilege.appendRole(role);
+ pm.makePersistent(solrPrivilege);
+ pm.makePersistent(hivePrivilege);
+ commitTransaction(pm);
+ //check
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ pm.retrieve(role);
+ assertEquals(1, role.getPrivileges().size());
+ assertEquals(1, role.getGmPrivileges().size());
+ commitTransaction(pm);
+
+ //want to grant the same hivePrivilege and solrPrivilege to role again
+ //hivePrivilege2 is equal to hivePrivilege
+ //solrPrivilege2 is equal to solrPrivilege
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ pm.retrieve(role);
+ if (!role.getGmPrivileges().contains(solrPrivilege2)) {
+ fail("unexpect happend: the MSentryGMPrivilege:" + solrPrivilege2 + " already be granted");
+ }
+ if (!role.getPrivileges().contains(hivePrivilege2)) {
+ fail("unexpect happend: the MSentryPrivilege:" + hivePrivilege2 + " already be granted");
+ }
+ commitTransaction(pm);
+ }
+
+ @Test
+ public void testMixedRevokePrivilege() throws Exception {
+ String roleName = "r1";
+ //hive/impala privilege
+ MSentryPrivilege hivePrivilege = new MSentryPrivilege();
+ hivePrivilege.setServerName("hive.server1");
+ hivePrivilege.setDbName("db1");
+ hivePrivilege.setTableName("tb1");
+ hivePrivilege.setPrivilegeScope("table");
+ hivePrivilege.setAction("select");
+ hivePrivilege.setURI(SentryStore.NULL_COL);
+ hivePrivilege.setColumnName(SentryStore.NULL_COL);
+ hivePrivilege.setGrantOption(true);
+
+ //solr privilege
+ MSentryGMPrivilege solrPrivilege = new MSentryGMPrivilege();
+ solrPrivilege.setComponentName("solr");
+ solrPrivilege.setServiceName("solr.server1");
+ solrPrivilege.setAuthorizables(Arrays.asList(new Collection("c1")));
+ solrPrivilege.setAction("query");
+ solrPrivilege.setGrantOption(true);
+
+ PersistenceManager pm = null;
+ //create role
+ pm = openTransaction();
+ pm.makePersistent(new MSentryRole(roleName, System.currentTimeMillis()));
+ commitTransaction(pm);
+
+ //grant hivePrivilege and solrPrivilege to role
+ pm = openTransaction();
+ MSentryRole role = getMSentryRole(pm, roleName);
+ hivePrivilege.appendRole(role);
+ solrPrivilege.appendRole(role);
+ pm.makePersistent(hivePrivilege);
+ pm.makePersistent(solrPrivilege);
+ commitTransaction(pm);
+
+ //check
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ pm.retrieve(role);
+ assertEquals(1, role.getPrivileges().size());
+ assertEquals(1, role.getGmPrivileges().size());
+ commitTransaction(pm);
+
+ //revoke solrPrivilege from role
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ solrPrivilege = (MSentryGMPrivilege)role.getGmPrivileges().toArray()[0];
+ solrPrivilege.removeRole(role);
+ pm.makePersistent(solrPrivilege);
+ commitTransaction(pm);
+
+ //check
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ pm.retrieve(role);
+ assertEquals(1, role.getPrivileges().size());
+ assertEquals(0, role.getGmPrivileges().size());
+ commitTransaction(pm);
+
+ //revoke hivePrivilege from role
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ pm.retrieve(role);
+ hivePrivilege = (MSentryPrivilege)role.getPrivileges().toArray()[0];
+ hivePrivilege.removeRole(role);
+ pm.makePersistent(hivePrivilege);
+ commitTransaction(pm);
+
+ //check
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ pm.retrieve(role);
+ assertEquals(0, role.getPrivileges().size());
+ assertEquals(0, role.getGmPrivileges().size());
+ commitTransaction(pm);
+ }
+
+ @Test
+ public void testDeletePrivilegeAndRole() throws Exception {
+ String roleName = "r1";
+ //hive/impala privilege
+ MSentryPrivilege hivePrivilege = new MSentryPrivilege();
+ hivePrivilege.setServerName("hive.server1");
+ hivePrivilege.setDbName("db1");
+ hivePrivilege.setTableName("tb1");
+ hivePrivilege.setPrivilegeScope("table");
+ hivePrivilege.setAction("select");
+ hivePrivilege.setURI(SentryStore.NULL_COL);
+ hivePrivilege.setColumnName(SentryStore.NULL_COL);
+ hivePrivilege.setGrantOption(true);
+
+ //solr privilege
+ MSentryGMPrivilege solrPrivilege = new MSentryGMPrivilege();
+ solrPrivilege.setComponentName("solr");
+ solrPrivilege.setServiceName("solr.server1");
+ solrPrivilege.setAuthorizables(Arrays.asList(new Collection("c1")));
+ solrPrivilege.setAction("query");
+ solrPrivilege.setGrantOption(true);
+
+ PersistenceManager pm = null;
+ //create role
+ pm = openTransaction();
+ pm.makePersistent(new MSentryRole(roleName, System.currentTimeMillis()));
+ commitTransaction(pm);
+
+ //grant hivePrivilege and solrPrivilege to role
+ pm = openTransaction();
+ MSentryRole role = getMSentryRole(pm, roleName);
+ hivePrivilege.appendRole(role);
+ solrPrivilege.appendRole(role);
+ pm.makePersistent(hivePrivilege);
+ pm.makePersistent(solrPrivilege);
+ commitTransaction(pm);
+
+ //check
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ pm.retrieve(role);
+ assertEquals(1, role.getPrivileges().size());
+ assertEquals(1, role.getGmPrivileges().size());
+ commitTransaction(pm);
+
+ //remove all privileges
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ role.removeGMPrivileges();
+ role.removePrivileges();
+ pm.makePersistent(role);
+ commitTransaction(pm);
+
+ //check
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ pm.retrieve(role);
+ assertEquals(0, role.getPrivileges().size());
+ assertEquals(0, role.getGmPrivileges().size());
+ commitTransaction(pm);
+
+ //delete role
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ pm.deletePersistent(role);
+ commitTransaction(pm);
+
+ //check
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ assertTrue(role == null);
+ commitTransaction(pm);
+ }
+
+ /**
+ * Removes a role and makes sure that privileges are removed from sentry storage
+ * moment they are not associated to any role.
+ * @throws Exception
+ */
+ @Test
+ public void testDeleteRole() throws Exception {
+ String roleName = "r1";
+ //hive/impala privilege
+ MSentryPrivilege hivePrivilege = new MSentryPrivilege();
+ hivePrivilege.setServerName("hive.server1");
+ hivePrivilege.setDbName("db1");
+ hivePrivilege.setTableName("tb1");
+ hivePrivilege.setPrivilegeScope("table");
+ hivePrivilege.setAction("select");
+ hivePrivilege.setURI(SentryStore.NULL_COL);
+ hivePrivilege.setColumnName(SentryStore.NULL_COL);
+ hivePrivilege.setGrantOption(true);
+
+ //solr privilege
+ MSentryGMPrivilege solrPrivilege = new MSentryGMPrivilege();
+ solrPrivilege.setComponentName("solr");
+ solrPrivilege.setServiceName("solr.server1");
+ solrPrivilege.setAuthorizables(Arrays.asList(new Collection("c1")));
+ solrPrivilege.setAction("query");
+ solrPrivilege.setGrantOption(true);
+
+ PersistenceManager pm = null;
+ //create role
+ pm = openTransaction();
+ pm.makePersistent(new MSentryRole(roleName, System.currentTimeMillis()));
+ commitTransaction(pm);
+
+ //grant hivePrivilege and solrPrivilege to role
+ pm = openTransaction();
+ MSentryRole role = getMSentryRole(pm, roleName);
+ hivePrivilege.appendRole(role);
+ solrPrivilege.appendRole(role);
+ pm.makePersistent(hivePrivilege);
+ pm.makePersistent(solrPrivilege);
+ pm.makePersistent(role);
+ commitTransaction(pm);
+
+ //check
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ pm.retrieve(role);
+ assertEquals(1, role.getPrivileges().size());
+ assertEquals(1, role.getGmPrivileges().size());
+ commitTransaction(pm);
+
+ //delete role
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+
+ // pm.deletePersistent(role);
+ role.removePrivileges();
+ role.removeGMPrivileges();
+ pm.deletePersistent(role);
+ commitTransaction(pm);
+
+ //check for privileges
+ //There shouldn't be any privilages
+ pm = openTransaction();
+ Query query = pm.newQuery(MSentryPrivilege.class);
+ List<MSentryPrivilege> results = (List<MSentryPrivilege>) query.execute();
+ assertEquals(1, results.size());
+ Query query1 = pm.newQuery(MSentryGMPrivilege.class);
+ List<MSentryGMPrivilege> results1 = (List<MSentryGMPrivilege>) query1.execute();
+ assertEquals(1, results1.size());
+ commitTransaction(pm);
+
+ //check
+ pm = openTransaction();
+ role = getMSentryRole(pm, roleName);
+ assertTrue(role == null);
+ commitTransaction(pm);
+ }
+
+ /**
+ * Removes a role and makes sure that privileges are not removed from sentry storage if
+ * they are associated to any other role as well.
+ * @throws Exception
+ */
+ @Test
+ public void testDeleteRole1() throws Exception {
+ String roleName1 = "r1";
+ String roleName2 = "r2";
+ //hive/impala privilege
+ MSentryPrivilege hivePrivilege = new MSentryPrivilege();
+ hivePrivilege.setServerName("hive.server1");
+ hivePrivilege.setDbName("db1");
+ hivePrivilege.setTableName("tb1");
+ hivePrivilege.setPrivilegeScope("table");
+ hivePrivilege.setAction("select");
+ hivePrivilege.setURI(SentryStore.NULL_COL);
+ hivePrivilege.setColumnName(SentryStore.NULL_COL);
+ hivePrivilege.setGrantOption(true);
+
+ //solr privilege
+ MSentryGMPrivilege solrPrivilege = new MSentryGMPrivilege();
+ solrPrivilege.setComponentName("solr");
+ solrPrivilege.setServiceName("solr.server1");
+ solrPrivilege.setAuthorizables(Arrays.asList(new Collection("c1")));
+ solrPrivilege.setAction("query");
+ solrPrivilege.setGrantOption(true);
+
+ PersistenceManager pm = null;
+ //create role1
+ pm = openTransaction();
+ pm.makePersistent(new MSentryRole(roleName1, System.currentTimeMillis()));
+ commitTransaction(pm);
+
+ //create role2
+ pm = openTransaction();
+ pm.makePersistent(new MSentryRole(roleName2, System.currentTimeMillis()));
+ commitTransaction(pm);
+
+ //grant hivePrivilege and solrPrivilege to role1 and role2
+ pm = openTransaction();
+ MSentryRole role1 = getMSentryRole(pm, roleName1);
+ MSentryRole role2 = getMSentryRole(pm, roleName2);
+ hivePrivilege.appendRole(role1);
+ solrPrivilege.appendRole(role1);
+ hivePrivilege.appendRole(role2);
+ solrPrivilege.appendRole(role2);
+ pm.makePersistent(hivePrivilege);
+ pm.makePersistent(solrPrivilege);
+ pm.makePersistent(role1);
+ pm.makePersistent(role2);
+ commitTransaction(pm);
+
+ //check
+ pm = openTransaction();
+ role1 = getMSentryRole(pm, roleName1);
+ pm.retrieve(role1);
+ assertEquals(1, role1.getPrivileges().size());
+ assertEquals(1, role1.getGmPrivileges().size());
+ role2 = getMSentryRole(pm, roleName2);
+ pm.retrieve(role2);
+ assertEquals(1, role2.getPrivileges().size());
+ assertEquals(1, role2.getGmPrivileges().size());
+ commitTransaction(pm);
+
+ //delete role
+ pm = openTransaction();
+ role1 = getMSentryRole(pm, roleName1);
+ role1.removePrivileges();
+ role1.removeGMPrivileges();
+ pm.deletePersistent(role1);
+ commitTransaction(pm);
+
+ //check for privileges
+ //Privileges should be present
+ pm = openTransaction();
+ Query query = pm.newQuery(MSentryPrivilege.class);
+ List<MSentryPrivilege> results = (List<MSentryPrivilege>) query.execute();
+ assertEquals(1, results.size());
+ Query query1 = pm.newQuery(MSentryGMPrivilege.class);
+ List<MSentryGMPrivilege> results1 = (List<MSentryGMPrivilege>) query1.execute();
+ assertEquals(1, results1.size());
+ commitTransaction(pm);
+
+ //check
+ pm = openTransaction();
+ role1 = getMSentryRole(pm, roleName1);
+ assertTrue(role1 == null);
+ commitTransaction(pm);
+ }
+ private PersistenceManager openTransaction() {
+ PersistenceManager pm = pmf.getPersistenceManager();
+ Transaction currentTransaction = pm.currentTransaction();
+ currentTransaction.begin();
+ return pm;
+ }
+
+ private void commitTransaction(PersistenceManager pm) {
+ Transaction currentTransaction = pm.currentTransaction();
+ try {
+ Preconditions.checkState(currentTransaction.isActive(), "Transaction is not active");
+ currentTransaction.commit();
+ } finally {
+ pm.close();
+ }
+ }
+
+ private MSentryRole getMSentryRole(PersistenceManager pm, String roleName) {
+ Query query = pm.newQuery(MSentryRole.class);
+ query.setFilter("this.roleName == t");
+ query.declareParameters("java.lang.String t");
+ query.setUnique(true);
+ MSentryRole sentryRole = (MSentryRole) query.execute(roleName);
+ return sentryRole;
+ }
+
+
+}