From commits-return-12699-archive-asf-public=cust-asf.ponee.io@sentry.apache.org Thu May 31 05:32:04 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id 24D691807BA for ; Thu, 31 May 2018 05:32:01 +0200 (CEST) Received: (qmail 38119 invoked by uid 500); 31 May 2018 03:32:01 -0000 Mailing-List: contact commits-help@sentry.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@sentry.apache.org Delivered-To: mailing list commits@sentry.apache.org Received: (qmail 34594 invoked by uid 99); 31 May 2018 03:31:43 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 31 May 2018 03:31:43 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 72096E1182; Thu, 31 May 2018 03:31:40 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: spena@apache.org To: commits@sentry.apache.org Date: Thu, 31 May 2018 03:32:28 -0000 Message-Id: In-Reply-To: <5efebc2704cd43a891f304274777fee8@git.apache.org> References: <5efebc2704cd43a891f304274777fee8@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [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 twoGroups = Sets.newHashSet("g1", "g2"); + Set 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 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 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 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 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 oldAuthoriables = Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME)); + List 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 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 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 getActionByCode(int code) { + List 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 getActionsByCode(int actionCode) { + List 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 results = (List) query.execute(); + assertEquals(1, results.size()); + Query query1 = pm.newQuery(MSentryGMPrivilege.class); + List results1 = (List) 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 results = (List) query.execute(); + assertEquals(1, results.size()); + Query query1 = pm.newQuery(MSentryGMPrivilege.class); + List results1 = (List) 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; + } + + +}