http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreImportExport.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreImportExport.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreImportExport.java new file mode 100644 index 0000000..ebc8c31 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreImportExport.java @@ -0,0 +1,1167 @@ +/** + * 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.service.persistent; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.io.FileUtils; +import org.apache.hadoop.conf.Configuration; +import org.apache.sentry.core.model.db.AccessConstants; +import org.apache.sentry.provider.db.service.model.MSentryGroup; +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.model.MSentryUser; +import org.apache.sentry.api.common.ApiConstants.PrivilegeScope; +import org.apache.sentry.api.service.thrift.TSentryGrantOption; +import org.apache.sentry.api.service.thrift.TSentryMappingData; +import org.apache.sentry.api.service.thrift.TSentryPrivilege; +import org.apache.sentry.provider.file.PolicyFile; +import org.apache.sentry.api.common.SentryServiceUtil; +import org.apache.sentry.service.common.ServiceConstants.ServerConfig; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.common.io.Files; + +public class TestSentryStoreImportExport { + + private static File dataDir; + private static String[] adminGroups = { "adminGroup1" }; + private static PolicyFile policyFile; + private static File policyFilePath; + private static SentryStore sentryStore; + private TSentryPrivilege tSentryPrivilege1; + private TSentryPrivilege tSentryPrivilege2; + private TSentryPrivilege tSentryPrivilege3; + private TSentryPrivilege tSentryPrivilege4; + private TSentryPrivilege tSentryPrivilege5; + private TSentryPrivilege tSentryPrivilege6; + private TSentryPrivilege tSentryPrivilege7; + private TSentryPrivilege tSentryPrivilege8; + private TSentryPrivilege tSentryPrivilege9; + + @BeforeClass + public static void setupEnv() throws Exception { + dataDir = new File(Files.createTempDir(), "sentry_policy_db"); + Configuration conf = new Configuration(false); + 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, "sentry"); + conf.setStrings(ServerConfig.ADMIN_GROUPS, adminGroups); + conf.set(ServerConfig.SENTRY_STORE_GROUP_MAPPING, ServerConfig.SENTRY_STORE_LOCAL_GROUP_MAPPING); + policyFilePath = new File(dataDir, "local_policy_file.ini"); + conf.set(ServerConfig.SENTRY_STORE_GROUP_MAPPING_RESOURCE, policyFilePath.getPath()); + policyFile = new PolicyFile(); + boolean hdfsSyncEnabled = SentryServiceUtil.isHDFSSyncEnabled(conf); + sentryStore = new SentryStore(conf); + sentryStore.setPersistUpdateDeltas(hdfsSyncEnabled); + + String adminUser = "g1"; + addGroupsToUser(adminUser, adminGroups); + writePolicyFile(); + } + + @Before + public void setupPrivilege() { + preparePrivilege(); + } + + @After + public void clearStore() { + sentryStore.clearAllTables(); + } + + // create the privileges instance for test case: + // privilege1=[server=server1] + // privilege2=[server=server1, action=select, grantOption=false] + // privilege3=[server=server1, db=db2, action=insert, grantOption=true] + // privilege4=[server=server1, db=db1, table=tbl1, action=insert, grantOption=false] + // privilege5=[server=server1, db=db1, table=tbl2, column=col1, action=insert, grantOption=false] + // privilege6=[server=server1, db=db1, table=tbl3, column=col1, action=*, grantOption=true] + // privilege7=[server=server1, db=db1, table=tbl4, column=col1, action=all, grantOption=true] + // privilege8=[server=server1, uri=hdfs://testserver:9999/path1, action=insert, grantOption=false] + // privilege9=[server=server1, db=db2, table=tbl1, action=insert, grantOption=false] + private void preparePrivilege() { + tSentryPrivilege1 = createTSentryPrivilege(PrivilegeScope.SERVER.name(), "server1", "", "", "", + "", "", TSentryGrantOption.UNSET); + tSentryPrivilege2 = createTSentryPrivilege(PrivilegeScope.SERVER.name(), "server1", "", "", "", + "", AccessConstants.SELECT, TSentryGrantOption.FALSE); + tSentryPrivilege3 = createTSentryPrivilege(PrivilegeScope.DATABASE.name(), "server1", "db2", + "", "", "", AccessConstants.INSERT, TSentryGrantOption.TRUE); + tSentryPrivilege4 = createTSentryPrivilege(PrivilegeScope.TABLE.name(), "server1", "db1", + "tbl1", "", "", AccessConstants.INSERT, TSentryGrantOption.FALSE); + tSentryPrivilege5 = createTSentryPrivilege(PrivilegeScope.COLUMN.name(), "server1", "db1", + "tbl2", "col1", "", AccessConstants.INSERT, TSentryGrantOption.FALSE); + tSentryPrivilege6 = createTSentryPrivilege(PrivilegeScope.COLUMN.name(), "server1", "db1", + "tbl3", "col1", "", AccessConstants.ALL, TSentryGrantOption.TRUE); + tSentryPrivilege7 = createTSentryPrivilege(PrivilegeScope.COLUMN.name(), "server1", "db1", + "tbl4", "col1", "", AccessConstants.ACTION_ALL, TSentryGrantOption.TRUE); + tSentryPrivilege8 = createTSentryPrivilege(PrivilegeScope.URI.name(), "server1", "", "", "", + "hdfs://testserver:9999/path1", AccessConstants.INSERT, TSentryGrantOption.FALSE); + tSentryPrivilege9 = createTSentryPrivilege(PrivilegeScope.TABLE.name(), "server1", "db2", + "tbl1", "", "", AccessConstants.INSERT, TSentryGrantOption.FALSE); + } + + @AfterClass + public static void teardown() { + if (sentryStore != null) { + sentryStore.stop(); + } + if (dataDir != null) { + FileUtils.deleteQuietly(dataDir); + } + } + + protected static void addGroupsToUser(String user, String... groupNames) { + policyFile.addGroupsToUser(user, groupNames); + } + + protected static void writePolicyFile() throws Exception { + policyFile.write(policyFilePath); + } + + // Befor import, database is empty. + // The following information is imported: + // group1=role1,role2,role3 + // group2=role1,role2,role3 + // group3=role1,role2,role3 + // role1=privilege1,privilege2,privilege3,privilege4,privilege5,privilege6,privilege7,privilege8 + // role2=privilege1,privilege2,privilege3,privilege4,privilege5,privilege6,privilege7,privilege8 + // role3=privilege1,privilege2,privilege3,privilege4,privilege5,privilege6,privilege7,privilege8 + // Both import API importSentryMetaData and export APIs getRolesMap, getGroupsMap, + // getPrivilegesList are tested. + @Test + public void testImportExportPolicy1() throws Exception { + TSentryMappingData tSentryMappingData = new TSentryMappingData(); + Map<String, Set<String>> sentryGroupRolesMap = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap = Maps.newHashMap(); + sentryGroupRolesMap.put("group1", Sets.newHashSet("Role1", "role2", "role3")); + sentryGroupRolesMap.put("group2", Sets.newHashSet("Role1", "role2", "role3")); + sentryGroupRolesMap.put("group3", Sets.newHashSet("Role1", "role2", "role3")); + sentryRolePrivilegesMap.put("Role1", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + sentryRolePrivilegesMap.put("role2", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + sentryRolePrivilegesMap.put("role3", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + tSentryMappingData.setGroupRolesMap(sentryGroupRolesMap); + tSentryMappingData.setRolePrivilegesMap(sentryRolePrivilegesMap); + sentryStore.importSentryMetaData(tSentryMappingData, false); + + Map<String, MSentryRole> rolesMap = sentryStore.getRolesMap(); + Map<String, MSentryGroup> groupsMap = sentryStore.getGroupNameToGroupMap(); + List<MSentryPrivilege> privilegesList = sentryStore.getPrivilegesList(); + + // test the result data for the role + verifyRoles(rolesMap, Sets.newHashSet("role1", "role2", "role3")); + + // test the result data for the group + verifyGroups(groupsMap, Sets.newHashSet("group1", "group2", "group3")); + + // test the result data for the privilege + verifyPrivileges(privilegesList, Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + + // test the mapping data for group and role + List<Map<String, Set<String>>> mapList = sentryStore.getGroupUserRoleMapList(null); + Map<String, Set<String>> actualGroupRolesMap = mapList.get( + SentryStore.INDEX_GROUP_ROLES_MAP); + Map<String, Set<String>> exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group1", Sets.newHashSet("role1", "role2", "role3")); + exceptedGroupRolesMap.put("group2", Sets.newHashSet("role1", "role2", "role3")); + exceptedGroupRolesMap.put("group3", Sets.newHashSet("role1", "role2", "role3")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + + // test the mapping data for role and privilege + Map<String, Set<TSentryPrivilege>> actualRolePrivilegesMap = sentryStore + .getRoleNameTPrivilegesMap(); + Map<String, Set<TSentryPrivilege>> exceptedRolePrivilegesMap = Maps.newHashMap(); + exceptedRolePrivilegesMap.put("role1", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + exceptedRolePrivilegesMap.put("role2", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + exceptedRolePrivilegesMap.put("role3", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + + verifyRolePrivilegesMap(actualRolePrivilegesMap, exceptedRolePrivilegesMap); + } + + // call import twice, and there has no duplicate data: + // The data for 1st import: + // group1=role1 + // role1=privilege1,privilege2,privilege3,privilege4 + // The data for 2nd import: + // group2=role2,role3 + // group3=role2,role3 + // role2=privilege5,privilege6,privilege7,privilege8 + // role3=privilege5,privilege6,privilege7,privilege8 + // Both import API importSentryMetaData and export APIs getRolesMap, getGroupsMap, + // getPrivilegesList are tested. + @Test + public void testImportExportPolicy2() throws Exception { + TSentryMappingData tSentryMappingData1 = new TSentryMappingData(); + Map<String, Set<String>> sentryGroupRolesMap1 = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap1 = Maps.newHashMap(); + sentryGroupRolesMap1.put("group1", Sets.newHashSet("role1")); + sentryRolePrivilegesMap1 + .put("role1", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, tSentryPrivilege3, + tSentryPrivilege4)); + tSentryMappingData1.setGroupRolesMap(sentryGroupRolesMap1); + tSentryMappingData1.setRolePrivilegesMap(sentryRolePrivilegesMap1); + sentryStore.importSentryMetaData(tSentryMappingData1, false); + + TSentryMappingData tSentryMappingData2 = new TSentryMappingData(); + Map<String, Set<String>> sentryGroupRolesMap2 = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap2 = Maps.newHashMap(); + sentryGroupRolesMap2.put("group2", Sets.newHashSet("role2", "role3")); + sentryGroupRolesMap2.put("group3", Sets.newHashSet("role2", "role3")); + sentryRolePrivilegesMap2 + .put("role2", Sets.newHashSet(tSentryPrivilege5, tSentryPrivilege6, tSentryPrivilege7, + tSentryPrivilege8)); + sentryRolePrivilegesMap2 + .put("role3", Sets.newHashSet(tSentryPrivilege5, tSentryPrivilege6, tSentryPrivilege7, + tSentryPrivilege8)); + tSentryMappingData2.setGroupRolesMap(sentryGroupRolesMap2); + tSentryMappingData2.setRolePrivilegesMap(sentryRolePrivilegesMap2); + sentryStore.importSentryMetaData(tSentryMappingData2, false); + + Map<String, MSentryRole> rolesMap = sentryStore.getRolesMap(); + Map<String, MSentryGroup> groupsMap = sentryStore.getGroupNameToGroupMap(); + List<MSentryPrivilege> privilegesList = sentryStore.getPrivilegesList(); + + // test the result data for the role + verifyRoles(rolesMap, Sets.newHashSet("role1", "role2", "role3")); + + // test the result data for the group + verifyGroups(groupsMap, Sets.newHashSet("group1", "group2", "group3")); + + // test the result data for the privilege + verifyPrivileges(privilegesList, Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + + // test the mapping data for group and role + List<Map<String, Set<String>>> mapList = sentryStore.getGroupUserRoleMapList(null); + Map<String, Set<String>> actualGroupRolesMap = mapList.get( + SentryStore.INDEX_GROUP_ROLES_MAP); + Map<String, Set<String>> exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group1", Sets.newHashSet("role1")); + exceptedGroupRolesMap.put("group2", Sets.newHashSet("role2", "role3")); + exceptedGroupRolesMap.put("group3", Sets.newHashSet("role2", "role3")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + + // test the mapping data for role and privilege + Map<String, Set<TSentryPrivilege>> actualRolePrivilegesMap = sentryStore + .getRoleNameTPrivilegesMap(); + Map<String, Set<TSentryPrivilege>> exceptedRolePrivilegesMap = Maps.newHashMap(); + exceptedRolePrivilegesMap + .put("role1", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, tSentryPrivilege3, + tSentryPrivilege4)); + exceptedRolePrivilegesMap + .put("role2", Sets.newHashSet(tSentryPrivilege5, tSentryPrivilege6, tSentryPrivilege7, + tSentryPrivilege8)); + exceptedRolePrivilegesMap + .put("role3", Sets.newHashSet(tSentryPrivilege5, tSentryPrivilege6, tSentryPrivilege7, + tSentryPrivilege8)); + verifyRolePrivilegesMap(actualRolePrivilegesMap, exceptedRolePrivilegesMap); + } + + // call import twice, and there has data overlap: + // The data for 1st import: + // group1=role1, role2 + // group2=role1, role2 + // group3=role1, role2 + // role1=privilege1,privilege2,privilege3,privilege4,privilege5 + // role2=privilege1,privilege2,privilege3,privilege4,privilege5 + // The data for 2nd import: + // group1=role2,role3 + // group2=role2,role3 + // group3=role2,role3 + // role2=privilege4,privilege5,privilege6,privilege7,privilege8 + // role3=privilege4,privilege5,privilege6,privilege7,privilege8 + // Both import API importSentryMetaData and export APIs getRolesMap, getGroupsMap, + // getPrivilegesList are tested. + @Test + public void testImportExportPolicy3() throws Exception { + TSentryMappingData tSentryMappingData1 = new TSentryMappingData(); + Map<String, Set<String>> sentryGroupRolesMap1 = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap1 = Maps.newHashMap(); + sentryGroupRolesMap1.put("group1", Sets.newHashSet("role1", "role2")); + sentryGroupRolesMap1.put("group2", Sets.newHashSet("role1", "role2")); + sentryGroupRolesMap1.put("group3", Sets.newHashSet("role1", "role2")); + sentryRolePrivilegesMap1.put("role1", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5)); + sentryRolePrivilegesMap1.put("role2", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5)); + tSentryMappingData1.setGroupRolesMap(sentryGroupRolesMap1); + tSentryMappingData1.setRolePrivilegesMap(sentryRolePrivilegesMap1); + sentryStore.importSentryMetaData(tSentryMappingData1, false); + + TSentryMappingData tSentryMappingData2 = new TSentryMappingData(); + Map<String, Set<String>> sentryGroupRolesMap2 = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap2 = Maps.newHashMap(); + sentryGroupRolesMap2.put("group1", Sets.newHashSet("role2", "role3")); + sentryGroupRolesMap2.put("group2", Sets.newHashSet("role2", "role3")); + sentryGroupRolesMap2.put("group3", Sets.newHashSet("role2", "role3")); + sentryRolePrivilegesMap2.put("role2", Sets.newHashSet(tSentryPrivilege4, tSentryPrivilege5, + tSentryPrivilege6, tSentryPrivilege7, tSentryPrivilege8)); + sentryRolePrivilegesMap2.put("role3", Sets.newHashSet(tSentryPrivilege4, tSentryPrivilege5, + tSentryPrivilege6, tSentryPrivilege7, tSentryPrivilege8)); + tSentryMappingData2.setGroupRolesMap(sentryGroupRolesMap2); + tSentryMappingData2.setRolePrivilegesMap(sentryRolePrivilegesMap2); + sentryStore.importSentryMetaData(tSentryMappingData2, false); + + Map<String, MSentryRole> rolesMap = sentryStore.getRolesMap(); + Map<String, MSentryGroup> groupsMap = sentryStore.getGroupNameToGroupMap(); + List<MSentryPrivilege> privilegesList = sentryStore.getPrivilegesList(); + + // test the result data for the role + verifyRoles(rolesMap, Sets.newHashSet("role1", "role2", "role3")); + + // test the result data for the group + verifyGroups(groupsMap, Sets.newHashSet("group1", "group2", "group3")); + + // test the result data for the privilege + verifyPrivileges(privilegesList, Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + + // test the mapping data for group and role + List<Map<String, Set<String>>> mapList = sentryStore.getGroupUserRoleMapList(null); + Map<String, Set<String>> actualGroupRolesMap = mapList.get( + SentryStore.INDEX_GROUP_ROLES_MAP); + Map<String, Set<String>> exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group1", Sets.newHashSet("role1", "role2", "role3")); + exceptedGroupRolesMap.put("group2", Sets.newHashSet("role1", "role2", "role3")); + exceptedGroupRolesMap.put("group3", Sets.newHashSet("role1", "role2", "role3")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + + // test the mapping data for role and privilege + Map<String, Set<TSentryPrivilege>> actualRolePrivilegesMap = sentryStore + .getRoleNameTPrivilegesMap(); + Map<String, Set<TSentryPrivilege>> exceptedRolePrivilegesMap = Maps.newHashMap(); + exceptedRolePrivilegesMap.put("role1", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5)); + exceptedRolePrivilegesMap.put("role2", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + exceptedRolePrivilegesMap.put("role3", Sets.newHashSet(tSentryPrivilege4, tSentryPrivilege5, + tSentryPrivilege6, tSentryPrivilege7, tSentryPrivilege8)); + verifyRolePrivilegesMap(actualRolePrivilegesMap, exceptedRolePrivilegesMap); + } + + // call import twice, and there has one role without group. + // The data for 1st import: + // group1=role1, role2 + // role1=privilege1,privilege2 + // role2=privilege3,privilege4 + // The data for 2nd import: + // group2=role2 + // role2=privilege5,privilege6 + // role3=privilege7,privilege8 + // role3 is without group, will be imported also + @Test + public void testImportExportPolicy4() throws Exception { + TSentryMappingData tSentryMappingData1 = new TSentryMappingData(); + Map<String, Set<String>> sentryGroupRolesMap1 = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap1 = Maps.newHashMap(); + sentryGroupRolesMap1.put("group1", Sets.newHashSet("role1", "role2")); + sentryRolePrivilegesMap1.put("role1", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2)); + sentryRolePrivilegesMap1.put("role2", Sets.newHashSet(tSentryPrivilege3, tSentryPrivilege4)); + tSentryMappingData1.setGroupRolesMap(sentryGroupRolesMap1); + tSentryMappingData1.setRolePrivilegesMap(sentryRolePrivilegesMap1); + sentryStore.importSentryMetaData(tSentryMappingData1, false); + + TSentryMappingData tSentryMappingData2 = new TSentryMappingData(); + Map<String, Set<String>> sentryGroupRolesMap2 = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap2 = Maps.newHashMap(); + sentryGroupRolesMap2.put("group2", Sets.newHashSet("role2")); + sentryRolePrivilegesMap2.put("role2", Sets.newHashSet(tSentryPrivilege5, tSentryPrivilege6)); + sentryRolePrivilegesMap2.put("role3", Sets.newHashSet(tSentryPrivilege7, tSentryPrivilege8)); + tSentryMappingData2.setGroupRolesMap(sentryGroupRolesMap2); + tSentryMappingData2.setRolePrivilegesMap(sentryRolePrivilegesMap2); + sentryStore.importSentryMetaData(tSentryMappingData2, false); + + Map<String, MSentryRole> rolesMap = sentryStore.getRolesMap(); + Map<String, MSentryGroup> groupsMap = sentryStore.getGroupNameToGroupMap(); + List<MSentryPrivilege> privilegesList = sentryStore.getPrivilegesList(); + + // test the result data for the role + verifyRoles(rolesMap, Sets.newHashSet("role1", "role2", "role3")); + + // test the result data for the group + verifyGroups(groupsMap, Sets.newHashSet("group1", "group2")); + + // test the result data for the privilege + verifyPrivileges(privilegesList, Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + + // test the mapping data for group and role + List<Map<String, Set<String>>> mapList = sentryStore.getGroupUserRoleMapList(null); + Map<String, Set<String>> actualGroupRolesMap = mapList.get( + SentryStore.INDEX_GROUP_ROLES_MAP); + Map<String, Set<String>> exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group1", Sets.newHashSet("role1", "role2")); + exceptedGroupRolesMap.put("group2", Sets.newHashSet("role2")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + + // test the mapping data for role and privilege + Map<String, Set<TSentryPrivilege>> actualRolePrivilegesMap = sentryStore + .getRoleNameTPrivilegesMap(); + Map<String, Set<TSentryPrivilege>> exceptedRolePrivilegesMap = Maps.newHashMap(); + exceptedRolePrivilegesMap.put("role1", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2)); + exceptedRolePrivilegesMap + .put("role2", Sets.newHashSet(tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5, + tSentryPrivilege6)); + exceptedRolePrivilegesMap.put("role3", Sets.newHashSet(tSentryPrivilege7, tSentryPrivilege8)); + verifyRolePrivilegesMap(actualRolePrivilegesMap, exceptedRolePrivilegesMap); + } + + // test for import mapping data for [group,role] only: + // group1=role1, role2 + @Test + public void testImportExportPolicy5() throws Exception { + TSentryMappingData tSentryMappingData1 = new TSentryMappingData(); + Map<String, Set<String>> sentryGroupRolesMap1 = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap1 = Maps.newHashMap(); + sentryGroupRolesMap1.put("group1", Sets.newHashSet("role1", "role2")); + tSentryMappingData1.setGroupRolesMap(sentryGroupRolesMap1); + tSentryMappingData1.setRolePrivilegesMap(sentryRolePrivilegesMap1); + sentryStore.importSentryMetaData(tSentryMappingData1, false); + + Map<String, MSentryRole> rolesMap = sentryStore.getRolesMap(); + Map<String, MSentryGroup> groupsMap = sentryStore.getGroupNameToGroupMap(); + List<MSentryPrivilege> privilegesList = sentryStore.getPrivilegesList(); + + // test the result data for the role + verifyRoles(rolesMap, Sets.newHashSet("role1", "role2")); + + // test the result data for the group + verifyGroups(groupsMap, Sets.newHashSet("group1")); + + // test the result data for the privilege + assertTrue(privilegesList.isEmpty()); + + // test the mapping data for group and role + List<Map<String, Set<String>>> mapList = sentryStore.getGroupUserRoleMapList(null); + Map<String, Set<String>> actualGroupRolesMap = mapList.get( + SentryStore.INDEX_GROUP_ROLES_MAP); + Map<String, Set<String>> exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group1", Sets.newHashSet("role1", "role2")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + + // test the mapping data for role and privilege + Map<String, Set<TSentryPrivilege>> actualRolePrivilegesMap = sentryStore + .getRoleNameTPrivilegesMap(); + assertTrue(actualRolePrivilegesMap.isEmpty()); + } + + // test for filter the orphaned group: + // group1=role1, role2 + // group2=role2 + @Test + public void testImportExportPolicy6() throws Exception { + TSentryMappingData tSentryMappingData1 = new TSentryMappingData(); + Map<String, Set<String>> sentryGroupRolesMap1 = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap1 = Maps.newHashMap(); + sentryGroupRolesMap1.put("group1", Sets.newHashSet("role1", "role2")); + sentryGroupRolesMap1.put("group2", Sets.newHashSet("role2")); + tSentryMappingData1.setGroupRolesMap(sentryGroupRolesMap1); + tSentryMappingData1.setRolePrivilegesMap(sentryRolePrivilegesMap1); + sentryStore.importSentryMetaData(tSentryMappingData1, false); + + // drop the role2, the group2 is orphaned group + sentryStore.dropSentryRole("role2"); + + Map<String, MSentryRole> rolesMap = sentryStore.getRolesMap(); + Map<String, MSentryGroup> groupsMap = sentryStore.getGroupNameToGroupMap(); + List<MSentryPrivilege> privilegesList = sentryStore.getPrivilegesList(); + + // test the result data for the role + verifyRoles(rolesMap, Sets.newHashSet("role1")); + + // test the result data for the group + verifyGroups(groupsMap, Sets.newHashSet("group1", "group2")); + + // test the result data for the privilege + assertTrue(privilegesList.isEmpty()); + + // test the mapping data for group and role + List<Map<String, Set<String>>> mapList = sentryStore.getGroupUserRoleMapList(null); + Map<String, Set<String>> actualGroupRolesMap = mapList.get( + SentryStore.INDEX_GROUP_ROLES_MAP); + Map<String, Set<String>> exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group1", Sets.newHashSet("role1")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + + // test the mapping data for role and privilege + Map<String, Set<TSentryPrivilege>> actualRolePrivilegesMap = sentryStore + .getRoleNameTPrivilegesMap(); + assertTrue(actualRolePrivilegesMap.isEmpty()); + } + + // call import twice, and there has no duplicate data, the import will be with the overwrite mode: + // The data for 1st import: + // group1=role1 + // role1=privilege1 + // The data for 2nd import: + // group2=role2,role3 + // group3=role2,role3 + // role2=privilege2 + // role3=privilege2 + // Both import API importSentryMetaData and export APIs getRolesMap, getGroupsMap, + // getPrivilegesList are tested. + @Test + public void testImportExportPolicy7() throws Exception { + TSentryMappingData tSentryMappingData1 = new TSentryMappingData(); + Map<String, Set<String>> sentryGroupRolesMap1 = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap1 = Maps.newHashMap(); + sentryGroupRolesMap1.put("group1", Sets.newHashSet("role1")); + sentryRolePrivilegesMap1.put("role1", Sets.newHashSet(tSentryPrivilege1)); + tSentryMappingData1.setGroupRolesMap(sentryGroupRolesMap1); + tSentryMappingData1.setRolePrivilegesMap(sentryRolePrivilegesMap1); + // the import with overwrite mode + sentryStore.importSentryMetaData(tSentryMappingData1, true); + + TSentryMappingData tSentryMappingData2 = new TSentryMappingData(); + Map<String, Set<String>> sentryGroupRolesMap2 = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap2 = Maps.newHashMap(); + sentryGroupRolesMap2.put("group2", Sets.newHashSet("role2", "role3")); + sentryGroupRolesMap2.put("group3", Sets.newHashSet("role2", "role3")); + sentryRolePrivilegesMap2.put("role2", Sets.newHashSet(tSentryPrivilege2)); + sentryRolePrivilegesMap2.put("role3", Sets.newHashSet(tSentryPrivilege2)); + tSentryMappingData2.setGroupRolesMap(sentryGroupRolesMap2); + tSentryMappingData2.setRolePrivilegesMap(sentryRolePrivilegesMap2); + // the import with overwrite mode + sentryStore.importSentryMetaData(tSentryMappingData2, true); + + Map<String, MSentryRole> rolesMap = sentryStore.getRolesMap(); + Map<String, MSentryGroup> groupsMap = sentryStore.getGroupNameToGroupMap(); + List<MSentryPrivilege> privilegesList = sentryStore.getPrivilegesList(); + + // test the result data for the role + verifyRoles(rolesMap, Sets.newHashSet("role1", "role2", "role3")); + + // test the result data for the group + verifyGroups(groupsMap, Sets.newHashSet("group1", "group2", "group3")); + + // test the result data for the privilege + verifyPrivileges(privilegesList, Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2)); + + // test the mapping data for group and role + List<Map<String, Set<String>>> mapList = sentryStore.getGroupUserRoleMapList(null); + Map<String, Set<String>> actualGroupRolesMap = mapList.get( + SentryStore.INDEX_GROUP_ROLES_MAP); + Map<String, Set<String>> exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group1", Sets.newHashSet("role1")); + exceptedGroupRolesMap.put("group2", Sets.newHashSet("role2", "role3")); + exceptedGroupRolesMap.put("group3", Sets.newHashSet("role2", "role3")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + + // test the mapping data for role and privilege + Map<String, Set<TSentryPrivilege>> actualRolePrivilegesMap = sentryStore + .getRoleNameTPrivilegesMap(); + Map<String, Set<TSentryPrivilege>> exceptedRolePrivilegesMap = Maps.newHashMap(); + exceptedRolePrivilegesMap.put("role1", Sets.newHashSet(tSentryPrivilege1)); + exceptedRolePrivilegesMap.put("role2", Sets.newHashSet(tSentryPrivilege2)); + exceptedRolePrivilegesMap.put("role3", Sets.newHashSet(tSentryPrivilege2)); + verifyRolePrivilegesMap(actualRolePrivilegesMap, exceptedRolePrivilegesMap); + } + + // call import twice, and there has data overlap, the import will be with the overwrite mode: + // The data for 1st import: + // group1=role1, role2 + // group2=role1, role2 + // group3=role1, role2 + // role1=privilege1,privilege2,privilege3,privilege4,privilege5 + // role2=privilege1,privilege2,privilege3,privilege4,privilege5 + // The data for 2nd import: + // group1=role2,role3 + // group2=role2,role3 + // group3=role2,role3 + // role2=privilege4,privilege5,privilege6,privilege7,privilege8 + // role3=privilege4,privilege5,privilege6,privilege7,privilege8 + // Both import API importSentryMetaData and export APIs getRolesMap, getGroupsMap, + // getPrivilegesList are tested. + @Test + public void testImportExportPolicy8() throws Exception { + TSentryMappingData tSentryMappingData1 = new TSentryMappingData(); + Map<String, Set<String>> sentryGroupRolesMap1 = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap1 = Maps.newHashMap(); + sentryGroupRolesMap1.put("group1", Sets.newHashSet("role1", "role2")); + sentryGroupRolesMap1.put("group2", Sets.newHashSet("role1", "role2")); + sentryGroupRolesMap1.put("group3", Sets.newHashSet("role1", "role2")); + sentryRolePrivilegesMap1.put("role1", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5)); + sentryRolePrivilegesMap1.put("role2", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5)); + tSentryMappingData1.setGroupRolesMap(sentryGroupRolesMap1); + tSentryMappingData1.setRolePrivilegesMap(sentryRolePrivilegesMap1); + // the import with overwrite mode + sentryStore.importSentryMetaData(tSentryMappingData1, true); + + TSentryMappingData tSentryMappingData2 = new TSentryMappingData(); + Map<String, Set<String>> sentryGroupRolesMap2 = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap2 = Maps.newHashMap(); + sentryGroupRolesMap2.put("group1", Sets.newHashSet("role2", "role3")); + sentryGroupRolesMap2.put("group2", Sets.newHashSet("role2", "role3")); + sentryGroupRolesMap2.put("group3", Sets.newHashSet("role2", "role3")); + sentryRolePrivilegesMap2.put("role2", Sets.newHashSet(tSentryPrivilege4, tSentryPrivilege5, + tSentryPrivilege6, tSentryPrivilege7, tSentryPrivilege8)); + sentryRolePrivilegesMap2.put("role3", Sets.newHashSet(tSentryPrivilege4, tSentryPrivilege5, + tSentryPrivilege6, tSentryPrivilege7, tSentryPrivilege8)); + tSentryMappingData2.setGroupRolesMap(sentryGroupRolesMap2); + tSentryMappingData2.setRolePrivilegesMap(sentryRolePrivilegesMap2); + // the import with overwrite mode + sentryStore.importSentryMetaData(tSentryMappingData2, true); + + Map<String, MSentryRole> rolesMap = sentryStore.getRolesMap(); + Map<String, MSentryGroup> groupsMap = sentryStore.getGroupNameToGroupMap(); + List<MSentryPrivilege> privilegesList = sentryStore.getPrivilegesList(); + + // test the result data for the role + verifyRoles(rolesMap, Sets.newHashSet("role1", "role2", "role3")); + + // test the result data for the group + verifyGroups(groupsMap, Sets.newHashSet("group1", "group2", "group3")); + + // test the result data for the privilege + verifyPrivileges(privilegesList, Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + + // test the mapping data for group and role + List<Map<String, Set<String>>> mapList = sentryStore.getGroupUserRoleMapList(null); + Map<String, Set<String>> actualGroupRolesMap = mapList.get( + SentryStore.INDEX_GROUP_ROLES_MAP); + Map<String, Set<String>> exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group1", Sets.newHashSet("role1", "role2", "role3")); + exceptedGroupRolesMap.put("group2", Sets.newHashSet("role1", "role2", "role3")); + exceptedGroupRolesMap.put("group3", Sets.newHashSet("role1", "role2", "role3")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + + // test the mapping data for role and privilege + Map<String, Set<TSentryPrivilege>> actualRolePrivilegesMap = sentryStore + .getRoleNameTPrivilegesMap(); + Map<String, Set<TSentryPrivilege>> exceptedRolePrivilegesMap = Maps.newHashMap(); + exceptedRolePrivilegesMap.put("role1", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5)); + // role2 should be overwrite + exceptedRolePrivilegesMap.put("role2", Sets.newHashSet(tSentryPrivilege4, tSentryPrivilege5, + tSentryPrivilege6, tSentryPrivilege7, tSentryPrivilege8)); + exceptedRolePrivilegesMap.put("role3", Sets.newHashSet(tSentryPrivilege4, tSentryPrivilege5, + tSentryPrivilege6, tSentryPrivilege7, tSentryPrivilege8)); + verifyRolePrivilegesMap(actualRolePrivilegesMap, exceptedRolePrivilegesMap); + } + + // test the import privileges with the action: All, *, select, insert + // All and * should replace the select and insert + // The data for import: + // group1=role1, role2 + // role1=testPrivilege1,testPrivilege2,testPrivilege3,testPrivilege4 + // role2=testPrivilege5, testPrivilege6,testPrivilege7,testPrivilege8 + @Test + public void testImportExportPolicy9() throws Exception { + TSentryPrivilege testPrivilege1 = createTSentryPrivilege(PrivilegeScope.TABLE.name(), + "server1", "db1", "tbl1", "", "", AccessConstants.SELECT, TSentryGrantOption.TRUE); + TSentryPrivilege testPrivilege2 = createTSentryPrivilege(PrivilegeScope.TABLE.name(), + "server1", "db1", "tbl1", "", "", AccessConstants.INSERT, TSentryGrantOption.FALSE); + TSentryPrivilege testPrivilege3 = createTSentryPrivilege(PrivilegeScope.TABLE.name(), + "server1", "db1", "tbl1", "", "", AccessConstants.ACTION_ALL, TSentryGrantOption.TRUE); + TSentryPrivilege testPrivilege4 = createTSentryPrivilege(PrivilegeScope.TABLE.name(), + "server1", "db1", "tbl1", "", "", AccessConstants.INSERT, TSentryGrantOption.TRUE); + TSentryPrivilege testPrivilege5 = createTSentryPrivilege(PrivilegeScope.TABLE.name(), + "server1", "db1", "tbl2", "", "", AccessConstants.SELECT, TSentryGrantOption.TRUE); + TSentryPrivilege testPrivilege6 = createTSentryPrivilege(PrivilegeScope.TABLE.name(), + "server1", "db1", "tbl2", "", "", AccessConstants.INSERT, TSentryGrantOption.FALSE); + TSentryPrivilege testPrivilege7 = createTSentryPrivilege(PrivilegeScope.TABLE.name(), + "server1", "db1", "tbl2", "", "", AccessConstants.ALL, TSentryGrantOption.TRUE); + TSentryPrivilege testPrivilege8 = createTSentryPrivilege(PrivilegeScope.TABLE.name(), + "server1", "db1", "tbl2", "", "", AccessConstants.INSERT, TSentryGrantOption.TRUE); + + TSentryMappingData tSentryMappingData1 = new TSentryMappingData(); + Map<String, Set<String>> sentryGroupRolesMap1 = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap1 = Maps.newHashMap(); + sentryGroupRolesMap1.put("group1", Sets.newHashSet("role1", "role2")); + // after import there should be only testPrivilege2, testPrivilege3 + sentryRolePrivilegesMap1.put("role1", + Sets.newHashSet(testPrivilege1, testPrivilege2, testPrivilege3, testPrivilege4)); + // after import there should be only testPrivilege6,testPrivilege7 + sentryRolePrivilegesMap1.put("role2", + Sets.newHashSet(testPrivilege5, testPrivilege6, testPrivilege7, testPrivilege8)); + tSentryMappingData1.setGroupRolesMap(sentryGroupRolesMap1); + tSentryMappingData1.setRolePrivilegesMap(sentryRolePrivilegesMap1); + // the import with overwrite mode + sentryStore.importSentryMetaData(tSentryMappingData1, true); + + Map<String, MSentryRole> rolesMap = sentryStore.getRolesMap(); + Map<String, MSentryGroup> groupsMap = sentryStore.getGroupNameToGroupMap(); + + // test the result data for the role + verifyRoles(rolesMap, Sets.newHashSet("role1", "role2")); + + // test the result data for the group + verifyGroups(groupsMap, Sets.newHashSet("group1")); + + // test the mapping data for group and role + List<Map<String, Set<String>>> mapList = sentryStore.getGroupUserRoleMapList(null); + Map<String, Set<String>> actualGroupRolesMap = mapList.get( + SentryStore.INDEX_GROUP_ROLES_MAP); + Map<String, Set<String>> exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group1", Sets.newHashSet("role1", "role2")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + + // test the mapping data for role and privilege + Map<String, Set<TSentryPrivilege>> actualRolePrivilegesMap = sentryStore + .getRoleNameTPrivilegesMap(); + Map<String, Set<TSentryPrivilege>> exceptedRolePrivilegesMap = Maps.newHashMap(); + exceptedRolePrivilegesMap.put("role1", Sets.newHashSet(testPrivilege2, testPrivilege3)); + exceptedRolePrivilegesMap.put("role2", Sets.newHashSet(testPrivilege6, testPrivilege7)); + verifyRolePrivilegesMap(actualRolePrivilegesMap, exceptedRolePrivilegesMap); + } + + // The following data is imported: + // group1=role1 + // group2=role1,role2 + // group3=role2,role3 + // group4=role1,role2,role3 + // role1=privilege3,privilege4,privilege9 + // role2=privilege3,privilege4,privilege5,privilege6,privilege7 + // role3=privilege4,privilege5,privilege6,privilege7,privilege8 + // Export APIs getRoleNameTPrivilegesMap, getGroupNameRoleNamesMap are tested. + @Test + public void testExportPolicyWithSpecificObject() throws Exception { + // import the data for test + TSentryMappingData tSentryMappingData = new TSentryMappingData(); + Map<String, Set<String>> sentryGroupRolesMap = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap = Maps.newHashMap(); + sentryGroupRolesMap.put("group1", Sets.newHashSet("role1")); + sentryGroupRolesMap.put("group2", Sets.newHashSet("role1", "role2")); + sentryGroupRolesMap.put("group3", Sets.newHashSet("role2", "role3")); + sentryGroupRolesMap.put("group4", Sets.newHashSet("role1", "role2", "role3")); + sentryRolePrivilegesMap.put("role1", Sets.newHashSet( + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege9)); + sentryRolePrivilegesMap.put("role2", Sets.newHashSet( + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7)); + sentryRolePrivilegesMap.put("role3", Sets.newHashSet( + tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + tSentryMappingData.setGroupRolesMap(sentryGroupRolesMap); + tSentryMappingData.setRolePrivilegesMap(sentryRolePrivilegesMap); + sentryStore.importSentryMetaData(tSentryMappingData, false); + + // verify the rolePrivilegesMap and groupRolesMap for db=db1 + Map<String, Set<TSentryPrivilege>> actualRolePrivilegesMap = + sentryStore.getRoleNameTPrivilegesMap("db1", ""); + Map<String, Set<TSentryPrivilege>> exceptedRolePrivilegesMap = Maps.newHashMap(); + exceptedRolePrivilegesMap.put("role1", Sets.newHashSet(tSentryPrivilege4)); + exceptedRolePrivilegesMap.put("role2", Sets.newHashSet(tSentryPrivilege4, + tSentryPrivilege5, tSentryPrivilege6, tSentryPrivilege7)); + exceptedRolePrivilegesMap.put("role3", Sets.newHashSet(tSentryPrivilege4, + tSentryPrivilege5, tSentryPrivilege6, tSentryPrivilege7)); + verifyRolePrivilegesMap(actualRolePrivilegesMap, exceptedRolePrivilegesMap); + + List<Map<String, Set<String>>> mapList = sentryStore.getGroupUserRoleMapList( + actualRolePrivilegesMap.keySet()); + Map<String, Set<String>> actualGroupRolesMap = mapList.get( + SentryStore.INDEX_GROUP_ROLES_MAP); + Map<String, Set<String>> exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group1", Sets.newHashSet("role1")); + exceptedGroupRolesMap.put("group2", Sets.newHashSet("role1", "role2")); + exceptedGroupRolesMap.put("group3", Sets.newHashSet("role2", "role3")); + exceptedGroupRolesMap.put("group4", Sets.newHashSet("role1", "role2", "role3")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + + // verify the rolePrivilegesMap and groupRolesMap for db=db2 + actualRolePrivilegesMap = sentryStore.getRoleNameTPrivilegesMap("db2", ""); + exceptedRolePrivilegesMap = Maps.newHashMap(); + exceptedRolePrivilegesMap.put("role1", Sets.newHashSet(tSentryPrivilege3, tSentryPrivilege9)); + exceptedRolePrivilegesMap.put("role2", Sets.newHashSet(tSentryPrivilege3)); + verifyRolePrivilegesMap(actualRolePrivilegesMap, exceptedRolePrivilegesMap); + + mapList = sentryStore.getGroupUserRoleMapList(actualRolePrivilegesMap.keySet()); + actualGroupRolesMap = mapList.get(SentryStore.INDEX_GROUP_ROLES_MAP); + exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group1", Sets.newHashSet("role1")); + exceptedGroupRolesMap.put("group2", Sets.newHashSet("role1", "role2")); + exceptedGroupRolesMap.put("group3", Sets.newHashSet("role2")); + exceptedGroupRolesMap.put("group4", Sets.newHashSet("role1", "role2")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + + // verify the rolePrivilegesMap and groupRolesMap for db=db1 and table=tbl1 + actualRolePrivilegesMap = sentryStore.getRoleNameTPrivilegesMap("db1", "tbl1"); + exceptedRolePrivilegesMap = Maps.newHashMap(); + exceptedRolePrivilegesMap.put("role1", Sets.newHashSet(tSentryPrivilege4)); + exceptedRolePrivilegesMap.put("role2", Sets.newHashSet(tSentryPrivilege4)); + exceptedRolePrivilegesMap.put("role3", Sets.newHashSet(tSentryPrivilege4)); + verifyRolePrivilegesMap(actualRolePrivilegesMap, exceptedRolePrivilegesMap); + + mapList = sentryStore.getGroupUserRoleMapList(actualRolePrivilegesMap.keySet()); + actualGroupRolesMap = mapList.get(SentryStore.INDEX_GROUP_ROLES_MAP); + exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group1", Sets.newHashSet("role1")); + exceptedGroupRolesMap.put("group2", Sets.newHashSet("role1", "role2")); + exceptedGroupRolesMap.put("group3", Sets.newHashSet("role2", "role3")); + exceptedGroupRolesMap.put("group4", Sets.newHashSet("role1", "role2", "role3")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + + // verify the rolePrivilegesMap and groupRolesMap for db=db1 and table=tbl2 + actualRolePrivilegesMap = sentryStore.getRoleNameTPrivilegesMap("db1", "tbl2"); + exceptedRolePrivilegesMap = Maps.newHashMap(); + exceptedRolePrivilegesMap.put("role2", Sets.newHashSet(tSentryPrivilege5)); + exceptedRolePrivilegesMap.put("role3", Sets.newHashSet(tSentryPrivilege5)); + verifyRolePrivilegesMap(actualRolePrivilegesMap, exceptedRolePrivilegesMap); + + mapList = sentryStore.getGroupUserRoleMapList(actualRolePrivilegesMap.keySet()); + actualGroupRolesMap = mapList.get(SentryStore.INDEX_GROUP_ROLES_MAP); + exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group2", Sets.newHashSet("role2")); + exceptedGroupRolesMap.put("group3", Sets.newHashSet("role2", "role3")); + exceptedGroupRolesMap.put("group4", Sets.newHashSet("role2", "role3")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + + // verify the rolePrivilegesMap and groupRolesMap for table=tbl1 + actualRolePrivilegesMap = sentryStore.getRoleNameTPrivilegesMap("", "tbl1"); + exceptedRolePrivilegesMap = Maps.newHashMap(); + exceptedRolePrivilegesMap.put("role1", Sets.newHashSet(tSentryPrivilege4, tSentryPrivilege9)); + exceptedRolePrivilegesMap.put("role2", Sets.newHashSet(tSentryPrivilege4)); + exceptedRolePrivilegesMap.put("role3", Sets.newHashSet(tSentryPrivilege4)); + verifyRolePrivilegesMap(actualRolePrivilegesMap, exceptedRolePrivilegesMap); + + mapList = sentryStore.getGroupUserRoleMapList(actualRolePrivilegesMap.keySet()); + actualGroupRolesMap = mapList.get(SentryStore.INDEX_GROUP_ROLES_MAP); + exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group1", Sets.newHashSet("role1")); + exceptedGroupRolesMap.put("group2", Sets.newHashSet("role1", "role2")); + exceptedGroupRolesMap.put("group3", Sets.newHashSet("role2", "role3")); + exceptedGroupRolesMap.put("group4", Sets.newHashSet("role1", "role2", "role3")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + + // verify the rolePrivilegesMap and groupRolesMap for empty parameter + actualRolePrivilegesMap = sentryStore.getRoleNameTPrivilegesMap("", ""); + exceptedRolePrivilegesMap = Maps.newHashMap(); + exceptedRolePrivilegesMap.put("role1", Sets.newHashSet(tSentryPrivilege3, + tSentryPrivilege4, tSentryPrivilege9)); + exceptedRolePrivilegesMap.put("role2", Sets.newHashSet(tSentryPrivilege3, + tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, tSentryPrivilege7)); + exceptedRolePrivilegesMap.put("role3", Sets.newHashSet(tSentryPrivilege4, + tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + verifyRolePrivilegesMap(actualRolePrivilegesMap, exceptedRolePrivilegesMap); + + mapList = sentryStore.getGroupUserRoleMapList(actualRolePrivilegesMap.keySet()); + actualGroupRolesMap = mapList.get(SentryStore.INDEX_GROUP_ROLES_MAP); + exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group1", Sets.newHashSet("role1")); + exceptedGroupRolesMap.put("group2", Sets.newHashSet("role1", "role2")); + exceptedGroupRolesMap.put("group3", Sets.newHashSet("role2", "role3")); + exceptedGroupRolesMap.put("group4", Sets.newHashSet("role1", "role2", "role3")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + } + + // Befor import, database is empty. + // The following information is imported: + // group1=role1,role2,role3 + // user1=role1,role2 + // user2=role2,role3 + // role1=privilege1,privilege2,privilege3,privilege4 + // role2=privilege5,privilege6,privilege7,privilege8 + // role3=privilege3,privilege4,privilege5,privilege6 + // Both import API importSentryMetaData and export APIs getRolesMap, getGroupsMap, + // getUsersMap getPrivilegesList are tested. + @Test + public void testImportExportWithUser() throws Exception { + TSentryMappingData tSentryMappingData = new TSentryMappingData(); + Map<String, Set<String>> groupRolesMap = Maps.newHashMap(); + Map<String, Set<String>> userRolesMap = Maps.newHashMap(); + Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap = Maps.newHashMap(); + groupRolesMap.put("group1", Sets.newHashSet("Role1", "role2", "role3")); + userRolesMap.put("user1", Sets.newHashSet("Role1", "role2")); + userRolesMap.put("user2", Sets.newHashSet("role2", "role3")); + sentryRolePrivilegesMap.put("Role1", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4)); + sentryRolePrivilegesMap.put("role2", Sets.newHashSet(tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + sentryRolePrivilegesMap.put("role3", Sets.newHashSet(tSentryPrivilege3, + tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6)); + tSentryMappingData.setGroupRolesMap(groupRolesMap); + tSentryMappingData.setRolePrivilegesMap(sentryRolePrivilegesMap); + tSentryMappingData.setUserRolesMap(userRolesMap); + sentryStore.importSentryMetaData(tSentryMappingData, false); + + Map<String, MSentryRole> rolesMap = sentryStore.getRolesMap(); + Map<String, MSentryGroup> groupsMap = sentryStore.getGroupNameToGroupMap(); + Map<String, MSentryUser> usersMap = sentryStore.getUserNameToUserMap(); + List<MSentryPrivilege> privilegesList = sentryStore.getPrivilegesList(); + + // test the result data for the role + verifyRoles(rolesMap, Sets.newHashSet("role1", "role2", "role3")); + + // test the result data for the group + verifyGroups(groupsMap, Sets.newHashSet("group1")); + + // test the result data for the user + verifyUsers(usersMap, Sets.newHashSet("user1", "user2")); + + // test the result data for the privilege + verifyPrivileges(privilegesList, Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + + // test the mapping data for group and role + List<Map<String, Set<String>>> mapList = sentryStore.getGroupUserRoleMapList(null); + Map<String, Set<String>> actualGroupRolesMap = mapList.get( + SentryStore.INDEX_GROUP_ROLES_MAP); + Map<String, Set<String>> exceptedGroupRolesMap = Maps.newHashMap(); + exceptedGroupRolesMap.put("group1", Sets.newHashSet("role1", "role2", "role3")); + verifyUserGroupRolesMap(actualGroupRolesMap, exceptedGroupRolesMap); + + Map<String, Set<String>> actualUserRolesMap = mapList.get( + SentryStore.INDEX_USER_ROLES_MAP); + Map<String, Set<String>> exceptedUserRolesMap = Maps.newHashMap(); + exceptedUserRolesMap.put("user1", Sets.newHashSet("role1", "role2")); + exceptedUserRolesMap.put("user2", Sets.newHashSet("role2", "role3")); + verifyUserGroupRolesMap(actualUserRolesMap, exceptedUserRolesMap); + + // test the mapping data for role and privilege + Map<String, Set<TSentryPrivilege>> actualRolePrivilegesMap = sentryStore + .getRoleNameTPrivilegesMap(); + Map<String, Set<TSentryPrivilege>> exceptedRolePrivilegesMap = Maps.newHashMap(); + exceptedRolePrivilegesMap.put("role1", Sets.newHashSet(tSentryPrivilege1, tSentryPrivilege2, + tSentryPrivilege3, tSentryPrivilege4)); + exceptedRolePrivilegesMap.put("role2", Sets.newHashSet(tSentryPrivilege5, tSentryPrivilege6, + tSentryPrivilege7, tSentryPrivilege8)); + exceptedRolePrivilegesMap.put("role3", Sets.newHashSet(tSentryPrivilege3, + tSentryPrivilege4, tSentryPrivilege5, tSentryPrivilege6)); + + verifyRolePrivilegesMap(actualRolePrivilegesMap, exceptedRolePrivilegesMap); + } + + private void verifyRoles(Map<String, MSentryRole> actualRoleMap, Set<String> expectedRoleNameSet) { + assertEquals(expectedRoleNameSet.size(), actualRoleMap.keySet().size()); + for (String roleName : actualRoleMap.keySet()) { + assertTrue(expectedRoleNameSet.contains(roleName)); + } + } + + private void verifyGroups(Map<String, MSentryGroup> actualGroupsMap, + Set<String> expectedGroupNameSet) { + assertEquals(expectedGroupNameSet.size(), actualGroupsMap.keySet().size()); + for (String groupName : actualGroupsMap.keySet()) { + assertTrue(expectedGroupNameSet.contains(groupName)); + } + } + + private void verifyUsers(Map<String, MSentryUser> actualUsersMap, + Set<String> expectedUserNameSet) { + assertEquals(expectedUserNameSet.size(), actualUsersMap.keySet().size()); + for (String userName : actualUsersMap.keySet()) { + assertTrue(expectedUserNameSet.contains(userName)); + } + } + + private void verifyPrivileges(List<MSentryPrivilege> actualPrivileges, + Set<TSentryPrivilege> expectedTSentryPrivilegeSet) { + assertEquals(expectedTSentryPrivilegeSet.size(), actualPrivileges.size()); + for (MSentryPrivilege mSentryPrivilege : actualPrivileges) { + boolean isFound = false; + for (TSentryPrivilege tSentryPrivilege : expectedTSentryPrivilegeSet) { + isFound = compareTSentryPrivilege(sentryStore.convertToTSentryPrivilege(mSentryPrivilege), + tSentryPrivilege); + if (isFound) { + break; + } + } + assertTrue(isFound); + } + } + + private void verifyUserGroupRolesMap(Map<String, Set<String>> actualMap, + Map<String, Set<String>> exceptedMap) { + assertEquals(exceptedMap.keySet().size(), actualMap.keySet().size()); + for (String name : actualMap.keySet()) { + Set<String> exceptedRoles = exceptedMap.get(name); + Set<String> actualRoles = actualMap.get(name); + assertEquals(actualRoles.size(), exceptedRoles.size()); + assertTrue(actualRoles.equals(exceptedRoles)); + } + } + + private void verifyRolePrivilegesMap(Map<String, Set<TSentryPrivilege>> actualRolePrivilegesMap, + Map<String, Set<TSentryPrivilege>> expectedRolePrivilegesMap) { + assertEquals(expectedRolePrivilegesMap.keySet().size(), actualRolePrivilegesMap.keySet().size()); + for (String roleName : expectedRolePrivilegesMap.keySet()) { + Set<TSentryPrivilege> exceptedTSentryPrivileges = expectedRolePrivilegesMap.get(roleName); + Set<TSentryPrivilege> actualTSentryPrivileges = actualRolePrivilegesMap.get(roleName); + assertEquals(exceptedTSentryPrivileges.size(), actualTSentryPrivileges.size()); + for (TSentryPrivilege actualPrivilege : actualTSentryPrivileges) { + boolean isFound = false; + for (TSentryPrivilege expectedPrivilege : exceptedTSentryPrivileges) { + isFound = compareTSentryPrivilege(expectedPrivilege, actualPrivilege); + if (isFound) { + break; + } + } + assertTrue(isFound); + } + } + } + + private TSentryPrivilege createTSentryPrivilege(String scope, String server, String dbName, + String tableName, String columnName, String uri, String action, TSentryGrantOption grantOption) { + TSentryPrivilege tSentryPrivilege = new TSentryPrivilege(); + tSentryPrivilege.setPrivilegeScope(scope); + tSentryPrivilege.setServerName(server); + tSentryPrivilege.setDbName(dbName); + tSentryPrivilege.setTableName(tableName); + tSentryPrivilege.setColumnName(columnName); + tSentryPrivilege.setURI(uri); + tSentryPrivilege.setAction(action); + tSentryPrivilege.setGrantOption(grantOption); + return tSentryPrivilege; + } + + // compare the TSentryPrivilege without the create time + private boolean compareTSentryPrivilege(TSentryPrivilege tSentryPrivilege1, + TSentryPrivilege tSentryPrivilege2) { + if (tSentryPrivilege1 == null) { + if (tSentryPrivilege2 == null) { + return true; + } else { + return false; + } + } else { + if (tSentryPrivilege2 == null) { + return false; + } + } + + boolean this_present_privilegeScope = true && tSentryPrivilege1.isSetPrivilegeScope(); + boolean that_present_privilegeScope = true && tSentryPrivilege2.isSetPrivilegeScope(); + if (this_present_privilegeScope || that_present_privilegeScope) { + if (!(this_present_privilegeScope && that_present_privilegeScope)) { + return false; + } + if (!tSentryPrivilege1.getPrivilegeScope().equalsIgnoreCase( + tSentryPrivilege2.getPrivilegeScope())) { + return false; + } + } + + boolean this_present_serverName = true && tSentryPrivilege1.isSetServerName(); + boolean that_present_serverName = true && tSentryPrivilege2.isSetServerName(); + if (this_present_serverName || that_present_serverName) { + if (!(this_present_serverName && that_present_serverName)) { + return false; + } + if (!tSentryPrivilege1.getServerName().equalsIgnoreCase(tSentryPrivilege2.getServerName())) { + return false; + } + } + + boolean this_present_dbName = true && tSentryPrivilege1.isSetDbName(); + boolean that_present_dbName = true && tSentryPrivilege2.isSetDbName(); + if (this_present_dbName || that_present_dbName) { + if (!(this_present_dbName && that_present_dbName)) { + return false; + } + if (!tSentryPrivilege1.getDbName().equalsIgnoreCase(tSentryPrivilege2.getDbName())) { + return false; + } + } + + boolean this_present_tableName = true && tSentryPrivilege1.isSetTableName(); + boolean that_present_tableName = true && tSentryPrivilege2.isSetTableName(); + if (this_present_tableName || that_present_tableName) { + if (!(this_present_tableName && that_present_tableName)) { + return false; + } + if (!tSentryPrivilege1.getTableName().equalsIgnoreCase(tSentryPrivilege2.getTableName())) { + return false; + } + } + + boolean this_present_URI = true && tSentryPrivilege1.isSetURI(); + boolean that_present_URI = true && tSentryPrivilege2.isSetURI(); + if (this_present_URI || that_present_URI) { + if (!(this_present_URI && that_present_URI)) { + return false; + } + if (!tSentryPrivilege1.getURI().equalsIgnoreCase(tSentryPrivilege2.getURI())) { + return false; + } + } + + boolean this_present_action = true && tSentryPrivilege1.isSetAction(); + boolean that_present_action = true && tSentryPrivilege2.isSetAction(); + if (this_present_action || that_present_action) { + if (!(this_present_action && that_present_action)) { + return false; + } + if (!tSentryPrivilege1.getAction().equalsIgnoreCase(tSentryPrivilege2.getAction())) { + return false; + } + } + + boolean this_present_grantOption = true && tSentryPrivilege1.isSetGrantOption(); + boolean that_present_grantOption = true && tSentryPrivilege2.isSetGrantOption(); + if (this_present_grantOption || that_present_grantOption) { + if (!(this_present_grantOption && that_present_grantOption)) { + return false; + } + if (!tSentryPrivilege1.getGrantOption().equals(tSentryPrivilege2.getGrantOption())) { + return false; + } + } + + boolean this_present_columnName = true && tSentryPrivilege1.isSetColumnName(); + boolean that_present_columnName = true && tSentryPrivilege2.isSetColumnName(); + if (this_present_columnName || that_present_columnName) { + if (!(this_present_columnName && that_present_columnName)) { + return false; + } + if (!tSentryPrivilege1.getColumnName().equalsIgnoreCase(tSentryPrivilege2.getColumnName())) { + return false; + } + } + + return true; + } +}
http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreToAuthorizable.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreToAuthorizable.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreToAuthorizable.java new file mode 100644 index 0000000..25f94fa --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreToAuthorizable.java @@ -0,0 +1,86 @@ +/** + * 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.service.persistent; + +import static org.junit.Assert.assertEquals; + +import org.apache.sentry.core.model.db.AccessConstants; +import org.apache.sentry.provider.db.service.model.MSentryPrivilege; +import org.junit.Test; + +public class TestSentryStoreToAuthorizable { + + private MSentryPrivilege privilege; + + @Test + public void testServer() { + privilege = new MSentryPrivilege(null, "server1", null, null, null, null, null); + assertEquals("server=server1", + SentryStore.toAuthorizable(privilege)); + privilege = new MSentryPrivilege(null, "server1", null, null, null, null, + AccessConstants.ALL); + assertEquals("server=server1", + SentryStore.toAuthorizable(privilege)); + } + + @Test + public void testTable() { + privilege = new MSentryPrivilege(null, "server1", "db1", "tbl1", null, null, null); + assertEquals("server=server1->db=db1->table=tbl1", + SentryStore.toAuthorizable(privilege)); + privilege = new MSentryPrivilege(null, "server1", "db1", "tbl1", null, null, + AccessConstants.INSERT); + assertEquals("server=server1->db=db1->table=tbl1->action=insert", + SentryStore.toAuthorizable(privilege)); + privilege = new MSentryPrivilege(null, "server1", "db1", "tbl1", null, null, + AccessConstants.SELECT); + assertEquals("server=server1->db=db1->table=tbl1->action=select", + SentryStore.toAuthorizable(privilege)); + privilege = new MSentryPrivilege(null, "server1", "db1", "tbl1", null, null, + AccessConstants.ALL); + assertEquals("server=server1->db=db1->table=tbl1", + SentryStore.toAuthorizable(privilege)); + } + + @Test + public void testDb() { + privilege = new MSentryPrivilege(null, "server1", "db1", null, null, null, null); + assertEquals("server=server1->db=db1", + SentryStore.toAuthorizable(privilege)); + privilege = new MSentryPrivilege(null, "server1", "db1", null, null, null, + AccessConstants.ALL); + assertEquals("server=server1->db=db1", + SentryStore.toAuthorizable(privilege)); + } + + @Test + public void testUri() { + privilege = new MSentryPrivilege(null, "server1", null, null, null, "file:///", null); + assertEquals("server=server1->uri=file:///", + SentryStore.toAuthorizable(privilege)); + privilege = new MSentryPrivilege(null, "server1", null, null, null, "file:///", + AccessConstants.SELECT); + assertEquals("server=server1->uri=file:///->action=select", + SentryStore.toAuthorizable(privilege)); + privilege = new MSentryPrivilege(null, "server1", null, null, null, "file:///", + AccessConstants.ALL); + assertEquals("server=server1->uri=file:///", + SentryStore.toAuthorizable(privilege)); + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryVersion.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryVersion.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryVersion.java new file mode 100644 index 0000000..21aa7f9 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryVersion.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.service.persistent; + +import static org.junit.Assert.assertEquals; + +import java.io.File; + +import org.apache.hadoop.conf.Configuration; +import org.apache.sentry.core.common.exception.SentryNoSuchObjectException; +import org.apache.sentry.api.common.SentryServiceUtil; +import org.apache.sentry.service.common.ServiceConstants.ServerConfig; +import org.junit.Before; +import org.junit.Test; + +import com.google.common.io.Files; + +public class TestSentryVersion { + + private File dataDir; + private Configuration conf; + + @Before + public void setup() throws Exception { + dataDir = new File(Files.createTempDir(), "sentry_policy_db"); + conf = new Configuration(false); + conf.set(ServerConfig.SENTRY_STORE_JDBC_URL, "jdbc:derby:;databaseName=" + + dataDir.getPath() + ";create=true"); + conf.set(ServerConfig.SENTRY_STORE_JDBC_PASS, "dummy"); + } + + /** + * Create the schema using auto creation Create new sentry store without + * implicit schema creation on the same backend db and make sure it starts + * + * @throws Exception + */ + @Test + public void testVerifySentryVersionCheck() throws Exception { + conf.set(ServerConfig.SENTRY_VERIFY_SCHEM_VERSION, "false"); + boolean hdfsSyncEnabled = SentryServiceUtil.isHDFSSyncEnabled(conf); + SentryStore sentryStore = new SentryStore(conf); + sentryStore.setPersistUpdateDeltas(hdfsSyncEnabled); + sentryStore.stop(); + conf.set(ServerConfig.SENTRY_VERIFY_SCHEM_VERSION, "true"); + sentryStore = new SentryStore(conf); + sentryStore.setPersistUpdateDeltas(hdfsSyncEnabled); + } + + /** + * Verify that store is not initialized by default without schema pre-created + * + * @throws Exception + */ + @Test(expected = SentryNoSuchObjectException.class) + public void testNegSentrySchemaDefault() throws Exception { + new SentryStore(conf); + } + + /** + * With schema verification turned off, Sentry Store should autoCreate the + * schema + * @throws Exception + */ + @Test + public void testSentryImplicitVersion() throws Exception { + conf.set(ServerConfig.SENTRY_VERIFY_SCHEM_VERSION, "false"); + boolean hdfsSyncEnabled = SentryServiceUtil.isHDFSSyncEnabled(conf); + SentryStore sentryStore = new SentryStore(conf); + sentryStore.setPersistUpdateDeltas(hdfsSyncEnabled); + assertEquals(SentryStoreSchemaInfo.getSentryVersion(), + sentryStore.getSentryVersion()); + } + +} http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryServiceIntegrationBase.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryServiceIntegrationBase.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryServiceIntegrationBase.java new file mode 100644 index 0000000..7e5e91d --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryServiceIntegrationBase.java @@ -0,0 +1,309 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.sentry.service.thrift; +import java.io.File; +import java.security.PrivilegedExceptionAction; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.TimeoutException; + + +import com.google.common.io.Resources; +import org.apache.commons.io.FileUtils; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.minikdc.MiniKdc; +import org.apache.hadoop.net.NetUtils; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.sentry.api.common.ApiConstants; +import org.apache.sentry.api.common.Status; +import org.apache.sentry.api.service.thrift.SentryMiniKdcTestcase; +import org.apache.sentry.api.service.thrift.SentryPolicyServiceClient; +import org.apache.sentry.api.service.thrift.TSentryRole; +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.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Strings; +import com.google.common.io.Files; + +public abstract class SentryServiceIntegrationBase extends SentryMiniKdcTestcase { + private static final Logger LOGGER = LoggerFactory.getLogger(SentryServiceIntegrationBase.class); + + protected static final String SERVER_HOST = NetUtils.createSocketAddr("localhost:80").getAddress().getCanonicalHostName(); + protected static final String REALM = "EXAMPLE.COM"; + protected static final String SERVER_PRINCIPAL = "sentry/" + SERVER_HOST; + protected static String SERVER_KERBEROS_NAME = "sentry/" + SERVER_HOST + "@" + REALM; + protected static final String HTTP_PRINCIPAL = "HTTP/" + SERVER_HOST; + protected static final String CLIENT_PRINCIPAL = "hive/" + SERVER_HOST; + protected static final String CLIENT_KERBEROS_SHORT_NAME = "hive"; + protected static final String ADMIN_USER = "admin_user"; + protected static final String ADMIN_GROUP = "admin_group"; + + protected static SentryService server; + protected SentryPolicyServiceClient client; + protected static MiniKdc kdc; + protected static File kdcWorkDir; + protected static File dbDir; + protected static File serverKeytab; + protected static File httpKeytab; + protected static File clientKeytab; + protected static UserGroupInformation clientUgi; + protected static boolean kerberos; + protected final static Configuration conf = new Configuration(false); + protected PolicyFile policyFile; + protected File policyFilePath; + protected static Properties kdcConfOverlay = new Properties(); + + protected static boolean webServerEnabled = false; + protected static int webServerPort = ServerConfig.SENTRY_WEB_PORT_DEFAULT; + protected static boolean webSecurity = false; + + protected static boolean pooled = false; + + protected static boolean useSSL = false; + protected static String allowedUsers = "hive,USER1"; + + @BeforeClass + public static void setup() throws Exception { + kerberos = true; + pooled = true; + beforeSetup(); + setupConf(); + startSentryService(); + afterSetup(); + } + + private static void setupKdc() throws Exception { + startMiniKdc(kdcConfOverlay); + } + + public static void startSentryService() throws Exception { + server.start(); + final long start = System.currentTimeMillis(); + while(!server.isRunning()) { + Thread.sleep(1000); + if(System.currentTimeMillis() - start > 60000L) { + throw new TimeoutException("Server did not start after 60 seconds"); + } + } + } + + public void stopSentryService() throws Exception { + server.stop(); + Thread.sleep(30000); + } + + public static void setupConf() throws Exception { + if (kerberos) { + setupKdc(); + kdc = getKdc(); + kdcWorkDir = getWorkDir(); + serverKeytab = new File(kdcWorkDir, "server.keytab"); + clientKeytab = new File(kdcWorkDir, "client.keytab"); + kdc.createPrincipal(serverKeytab, SERVER_PRINCIPAL); + kdc.createPrincipal(clientKeytab, CLIENT_PRINCIPAL); + conf.set(ServerConfig.PRINCIPAL, getServerKerberosName()); + conf.set(ServerConfig.KEY_TAB, serverKeytab.getPath()); + conf.set(ServerConfig.ALLOW_CONNECT, CLIENT_KERBEROS_SHORT_NAME); + conf.set(ServerConfig.SERVER_HA_ZOOKEEPER_CLIENT_PRINCIPAL, + getServerKerberosName()); + conf.set(ServerConfig.SERVER_HA_ZOOKEEPER_CLIENT_KEYTAB, + serverKeytab.getPath()); + + conf.set(ServerConfig.SECURITY_USE_UGI_TRANSPORT, "true"); + conf.set("hadoop.security.authentication", "kerberos"); + UserGroupInformation.setConfiguration(conf); + UserGroupInformation.loginUserFromKeytab(CLIENT_PRINCIPAL, clientKeytab.getPath()); + clientUgi = UserGroupInformation.getLoginUser(); + } else { + LOGGER.info("Stopped KDC"); + conf.set(ServerConfig.SECURITY_MODE, ServerConfig.SECURITY_MODE_NONE); + } + + if (webServerEnabled) { + conf.set(ServerConfig.SENTRY_WEB_ENABLE, "true"); + conf.set(ServerConfig.SENTRY_WEB_PORT, String.valueOf(webServerPort)); + conf.set(ServerConfig.SENTRY_WEB_PUBSUB_SERVLET_ENABLED, "true"); + if (webSecurity) { + httpKeytab = new File(kdcWorkDir, "http.keytab"); + kdc.createPrincipal(httpKeytab, HTTP_PRINCIPAL); + conf.set(ServerConfig.SENTRY_WEB_SECURITY_TYPE, + ServerConfig.SENTRY_WEB_SECURITY_TYPE_KERBEROS); + conf.set(ServerConfig.SENTRY_WEB_SECURITY_PRINCIPAL, HTTP_PRINCIPAL); + conf.set(ServerConfig.SENTRY_WEB_SECURITY_KEYTAB, httpKeytab.getPath()); + conf.set(ServerConfig.SENTRY_WEB_SECURITY_ALLOW_CONNECT_USERS, allowedUsers); + } else { + conf.set(ServerConfig.SENTRY_WEB_SECURITY_TYPE, + ServerConfig.SENTRY_WEB_SECURITY_TYPE_NONE); + } + } else { + conf.set(ServerConfig.SENTRY_WEB_ENABLE, "false"); + } + if (pooled) { + conf.set(ApiConstants.ClientConfig.SENTRY_POOL_ENABLED, "true"); + } + if (useSSL) { + String keystorePath = Resources.getResource("keystore.jks").getPath(); + conf.set(ServerConfig.SENTRY_WEB_USE_SSL, "true"); + conf.set(ServerConfig.SENTRY_WEB_SSL_KEYSTORE_PATH, keystorePath); + conf.set(ServerConfig.SENTRY_WEB_SSL_KEYSTORE_PASSWORD, "password"); + + LOGGER.debug("{} is at {}", ServerConfig.SENTRY_WEB_SSL_KEYSTORE_PATH, keystorePath); + } + conf.set(ServerConfig.SENTRY_VERIFY_SCHEM_VERSION, "false"); + conf.set(ServerConfig.ADMIN_GROUPS, ADMIN_GROUP); + conf.set(ServerConfig.RPC_ADDRESS, SERVER_HOST); + conf.set(ServerConfig.RPC_PORT, String.valueOf(0)); + dbDir = new File(Files.createTempDir(), "sentry_policy_db"); + conf.set(ServerConfig.SENTRY_STORE_JDBC_URL, + "jdbc:derby:;databaseName=" + dbDir.getPath() + ";create=true"); + conf.set(ServerConfig.SENTRY_STORE_JDBC_PASS, "dummy"); + server = SentryServiceFactory.create(conf); + conf.set(ApiConstants.ClientConfig.SERVER_RPC_ADDRESS, server.getAddress().getHostName()); + conf.set(ApiConstants.ClientConfig.SERVER_RPC_PORT, String.valueOf(server.getAddress().getPort())); + conf.set(ServerConfig.SENTRY_STORE_GROUP_MAPPING, + ServerConfig.SENTRY_STORE_LOCAL_GROUP_MAPPING); + } + + @Before + public void before() throws Exception { + policyFilePath = new File(dbDir, "local_policy_file.ini"); + conf.set(ServerConfig.SENTRY_STORE_GROUP_MAPPING_RESOURCE, + policyFilePath.getPath()); + policyFile = new PolicyFile(); + connectToSentryService(); + } + + @After + public void after() { + try { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + if (client != null) { + Set<TSentryRole> tRoles = client.listAllRoles(ADMIN_USER); + if (tRoles != null) { + for (TSentryRole tRole : tRoles) { + client.dropRole(ADMIN_USER, tRole.getRoleName()); + } + } + client.close(); + } + } + }); + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + } finally { + policyFilePath.delete(); + } + } + + public void connectToSentryService() throws Exception { + if (kerberos) { + client = clientUgi.doAs(new PrivilegedExceptionAction<SentryPolicyServiceClient>() { + @Override + public SentryPolicyServiceClient run() throws Exception { + return SentryServiceClientFactory.create(conf); + } + }); + } else { + client = SentryServiceClientFactory.create(conf); + } + } + + @AfterClass + public static void tearDown() throws Exception { + beforeTeardown(); + + if(server != null) { + server.stop(); + } + if (dbDir != null) { + FileUtils.deleteQuietly(dbDir); + } + stopMiniKdc(); + afterTeardown(); + } + + public static String getServerKerberosName() { + return SERVER_KERBEROS_NAME; + } + + public static void beforeSetup() throws Exception { + + } + public static void afterSetup() throws Exception { + + } + public static void beforeTeardown() throws Exception { + + } + public static void afterTeardown() throws Exception { + + } + protected static void assertOK(TSentryResponseStatus resp) { + assertStatus(Status.OK, resp); + } + + protected static void assertStatus(Status status, TSentryResponseStatus resp) { + if (resp.getValue() != status.getCode()) { + String message = "Expected: " + status + ", Response: " + Status.fromCode(resp.getValue()) + + ", Code: " + resp.getValue() + ", Message: " + resp.getMessage(); + String stackTrace = Strings.nullToEmpty(resp.getStack()).trim(); + if (!stackTrace.isEmpty()) { + message += ", StackTrace: " + stackTrace; + } + Assert.fail(message); + } + } + + protected void setLocalGroupMapping(String user, Set<String> groupSet) { + for (String group : groupSet) { + policyFile.addGroupsToUser(user, group); + } + } + + protected void writePolicyFile() throws Exception { + policyFile.write(policyFilePath); + } + + protected void runTestAsSubject(final TestOperation test) throws Exception { + /*if (false) { + clientUgi.doAs(new PrivilegedExceptionAction<Void>() { + @Override + public Void run() throws Exception { + test.runTestAsSubject(); + return null; + }}); + } else { + */ test.runTestAsSubject(); + //} + } + + protected interface TestOperation { + void runTestAsSubject() throws Exception; + } + +} http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryStateBankTestHelper.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryStateBankTestHelper.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryStateBankTestHelper.java new file mode 100644 index 0000000..48212a0 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryStateBankTestHelper.java @@ -0,0 +1,29 @@ +/** + * 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.service.thrift; + +/** + * + */ +public class SentryStateBankTestHelper { + + public static void clearAllStates() { + SentryStateBank.clearAllStates(); + } + + public static void resetComponentState(String component) { + SentryStateBank.resetComponentState(component); + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryWebMetricParser.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryWebMetricParser.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryWebMetricParser.java new file mode 100644 index 0000000..8446d95 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/SentryWebMetricParser.java @@ -0,0 +1,86 @@ +/* + * 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.service.thrift; + +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.map.ObjectMapper; + +import java.io.IOException; + + +/** + * The SentryWebMetricParser is used to parse the metrics displayed on the sentry web ui. + */ +public class SentryWebMetricParser { + private JsonNode root; + private final String sentryService = SentryService.class.getName(); + private ObjectMapper mapper; + + public SentryWebMetricParser(String response) throws IOException { + this.mapper = new ObjectMapper(); + this.root = mapper.readTree(response); + } + + public void refreshRoot(String response) throws IOException { + root = mapper.readTree(response); + } + + public JsonNode getRoot() { + return root; + } + + public JsonNode getGauges(JsonNode root) { + JsonNode gauges = root.findPath("gauges"); + return gauges; + } + + public JsonNode getCounters(JsonNode root) { + JsonNode counters = root.findPath("counters"); + return counters; + } + + public JsonNode getHistograms(JsonNode root) { + JsonNode histograms = root.findPath("histograms"); + return histograms; + } + + public JsonNode getMeters(JsonNode root) { + JsonNode meters = root.findPath("meters"); + return meters; + } + + public JsonNode getTimers(JsonNode root) { + JsonNode timers = root.findPath("timers"); + return timers; + } + + public JsonNode getValue(JsonNode node) { + return node.findPath("value"); + } + + public boolean isHA() { + JsonNode gauges = getGauges(root); + JsonNode obj = getValue(gauges.findPath(sentryService + ".is_ha")); + return obj.getValueAsBoolean(); + } + + public boolean isActive() { + JsonNode gauges = getGauges(root); + JsonNode obj = getValue(gauges.findPath(sentryService + ".is_active")); + return obj.getBooleanValue(); + } +} \ No newline at end of file