You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by sp...@apache.org on 2018/05/31 03:32:24 UTC
[46/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/service/persistent/TestSentryStore.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
new file mode 100644
index 0000000..e2d24e5
--- /dev/null
+++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
@@ -0,0 +1,4036 @@
+/**
+ * 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 java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.io.FileUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.alias.CredentialProvider;
+import org.apache.hadoop.security.alias.CredentialProviderFactory;
+import org.apache.hadoop.security.alias.UserProvider;
+import org.apache.sentry.core.common.exception.SentryAccessDeniedException;
+import org.apache.sentry.core.common.exception.SentryInvalidInputException;
+import org.apache.sentry.core.model.db.AccessConstants;
+import org.apache.sentry.core.common.exception.SentryAlreadyExistsException;
+import org.apache.sentry.core.common.exception.SentryGrantDeniedException;
+import org.apache.sentry.core.common.exception.SentryNoSuchObjectException;
+import org.apache.sentry.hdfs.PathsUpdate;
+import org.apache.sentry.hdfs.PermissionsUpdate;
+import org.apache.sentry.hdfs.UniquePathsUpdate;
+import org.apache.sentry.hdfs.Updateable;
+import org.apache.sentry.hdfs.service.thrift.TPathEntry;
+import org.apache.sentry.hdfs.service.thrift.TPathsDump;
+import org.apache.sentry.hdfs.service.thrift.TPathsUpdate;
+import org.apache.sentry.hdfs.service.thrift.TPrivilegeChanges;
+import org.apache.sentry.hdfs.service.thrift.TPrivilegeEntity;
+import org.apache.sentry.hdfs.service.thrift.TPrivilegeEntityType;
+import org.apache.sentry.hdfs.service.thrift.TRoleChanges;
+import org.apache.sentry.provider.db.service.model.MSentryPermChange;
+import org.apache.sentry.provider.db.service.model.MSentryPathChange;
+import org.apache.sentry.provider.db.service.model.MSentryPrivilege;
+import org.apache.sentry.provider.db.service.model.MSentryRole;
+import org.apache.sentry.api.service.thrift.TSentryActiveRoleSet;
+import org.apache.sentry.api.service.thrift.TSentryAuthorizable;
+import org.apache.sentry.api.service.thrift.TSentryGrantOption;
+import org.apache.sentry.api.service.thrift.TSentryGroup;
+import org.apache.sentry.api.service.thrift.TSentryPrivilege;
+import org.apache.sentry.api.service.thrift.TSentryRole;
+import org.apache.sentry.provider.db.service.model.MSentryUser;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.apache.sentry.api.common.SentryServiceUtil;
+import org.apache.sentry.service.common.ServiceConstants;
+import org.apache.sentry.service.common.ServiceConstants.SentryEntityType;
+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.Iterables;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.sentry.provider.db.service.persistent.QueryParamBuilder.newQueryParamBuilder;
+
+import javax.jdo.JDODataStoreException;
+
+public class TestSentryStore extends org.junit.Assert {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(TestSentryStore.class);
+
+ private static File dataDir;
+ private static SentryStore sentryStore;
+ private static String[] adminGroups = { "adminGroup1" };
+ private static PolicyFile policyFile;
+ private static File policyFilePath;
+ final long NUM_PRIVS = 5; // > SentryStore.PrivCleaner.NOTIFY_THRESHOLD
+ private static Configuration conf = null;
+ private static char[] passwd = new char[] { '1', '2', '3'};
+
+ @BeforeClass
+ public static void setup() throws Exception {
+ conf = new Configuration(false);
+ final String ourUrl = UserProvider.SCHEME_NAME + ":///";
+ conf.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, ourUrl);
+
+ // enable HDFS sync, so perm and path changes will be saved into DB
+ conf.set(ServiceConstants.ServerConfig.PROCESSOR_FACTORIES, "org.apache.sentry.hdfs.SentryHDFSServiceProcessorFactory");
+ conf.set(ServiceConstants.ServerConfig.SENTRY_POLICY_STORE_PLUGINS, "org.apache.sentry.hdfs.SentryPlugin");
+
+ // THis should be a UserGroupInformation provider
+ CredentialProvider provider = CredentialProviderFactory.getProviders(conf).get(0);
+
+
+ // The user credentials are stored as a static variable by UserGrouoInformation provider.
+ // We need to only set the password the first time, an attempt to set it for the second
+ // time fails with an exception.
+ if(provider.getCredentialEntry(ServerConfig.SENTRY_STORE_JDBC_PASS) == null) {
+ provider.createCredentialEntry(ServerConfig.SENTRY_STORE_JDBC_PASS, passwd);
+ provider.flush();
+ }
+
+ 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(dataDir, "local_policy_file.ini");
+ conf.set(ServerConfig.SENTRY_STORE_GROUP_MAPPING_RESOURCE,
+ policyFilePath.getPath());
+
+ // These tests do not need to retry transactions, so setting to 1 to reduce testing time
+ conf.setInt(ServerConfig.SENTRY_STORE_TRANSACTION_RETRY, 1);
+
+ // SentryStore should be initialized only once. The tables created by the test cases will
+ // be cleaned up during the @After method.
+ sentryStore = new SentryStore(conf);
+
+ boolean hdfsSyncEnabled = SentryServiceUtil.isHDFSSyncEnabled(conf);
+ sentryStore.setPersistUpdateDeltas(hdfsSyncEnabled);
+ }
+
+ @Before
+ public void before() throws Exception {
+ policyFile = new PolicyFile();
+ String adminUser = "g1";
+ addGroupsToUser(adminUser, adminGroups);
+ writePolicyFile();
+ }
+
+ @After
+ public void after() {
+ sentryStore.clearAllTables();
+ }
+
+ @AfterClass
+ public static void teardown() {
+ if (dataDir != null) {
+ FileUtils.deleteQuietly(dataDir);
+ }
+
+ sentryStore.stop();
+ }
+
+ /**
+ * Fail test if role already exists
+ * @param roleName Role name to checl
+ * @throws Exception
+ */
+ private void checkRoleDoesNotExist(String roleName) throws Exception {
+ try {
+ sentryStore.getMSentryRoleByName(roleName);
+ fail("Role " + roleName + "already exists");
+ } catch (SentryNoSuchObjectException e) {
+ // Ok
+ }
+ }
+
+ /**
+ * Fail test if role doesn't exist
+ * @param roleName Role name to checl
+ * @throws Exception
+ */
+ private void checkRoleExists(String roleName) throws Exception {
+ assertEquals(roleName.toLowerCase(),
+ sentryStore.getMSentryRoleByName(roleName).getRoleName());
+ }
+
+ /**
+ * Create a role with the given name and verify that it is created
+ * @param roleName
+ * @throws Exception
+ */
+ private void createRole(String roleName) throws Exception {
+ checkRoleDoesNotExist(roleName);
+ sentryStore.createSentryRole(roleName);
+ checkRoleExists(roleName);
+ }
+
+ @Test
+ public void testCredentialProvider() throws Exception {
+ assertArrayEquals(passwd, conf.getPassword(ServerConfig.
+ SENTRY_STORE_JDBC_PASS));
+ }
+
+ @Test
+ public void testCaseInsensitiveRole() throws Exception {
+ String roleName = "newRole";
+ String grantor = "g1";
+ Set<TSentryGroup> groups = Sets.newHashSet();
+ TSentryGroup group = new TSentryGroup();
+ group.setGroupName("test-groups-g1");
+ groups.add(group);
+
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("TABLE");
+ privilege.setServerName("server1");
+ privilege.setDbName("default");
+ privilege.setTableName("table1");
+ privilege.setAction(AccessConstants.ALL);
+ privilege.setCreateTime(System.currentTimeMillis());
+
+ Set<String> users = Sets.newHashSet("user1");
+
+ createRole(roleName);
+
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName, groups);
+ sentryStore.alterSentryRoleDeleteGroups(roleName, groups);
+ sentryStore.alterSentryRoleAddUsers(roleName, users);
+ sentryStore.alterSentryRoleDeleteUsers(roleName, users);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege);
+ }
+
+ @Test
+ public void testURI() throws Exception {
+ String roleName = "test-dup-role";
+ String grantor = "g1";
+ String uri = "file:///var/folders/dt/9zm44z9s6bjfxbrm4v36lzdc0000gp/T/1401860678102-0/data/kv1.dat";
+ createRole(roleName);
+ TSentryPrivilege tSentryPrivilege = new TSentryPrivilege("URI", "server1", "ALL");
+ tSentryPrivilege.setURI(uri);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, tSentryPrivilege);
+
+ TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
+ tSentryAuthorizable.setUri(uri);
+ tSentryAuthorizable.setServer("server1");
+
+ Set<TSentryPrivilege> privileges =
+ sentryStore.getTSentryPrivileges(SentryEntityType.ROLE, new HashSet<String>(Arrays.asList(roleName)), tSentryAuthorizable);
+
+ assertTrue(privileges.size() == 1);
+
+ Set<TSentryGroup> tSentryGroups = new HashSet<TSentryGroup>();
+ tSentryGroups.add(new TSentryGroup("group1"));
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName, tSentryGroups);
+ sentryStore.alterSentryRoleAddUsers(roleName, Sets.newHashSet("user1"));
+
+ TSentryActiveRoleSet thriftRoleSet = new TSentryActiveRoleSet(true, new HashSet<String>(Arrays.asList(roleName)));
+
+ // list privilege for group only
+ Set<String> privs = sentryStore.listSentryPrivilegesForProvider(
+ new HashSet<String>(Arrays.asList("group1")), Sets.newHashSet(""), thriftRoleSet,
+ tSentryAuthorizable);
+
+ assertTrue(privs.size()==1);
+ assertTrue(privs.contains("server=server1->uri=" + uri + "->action=all"));
+
+ // list privilege for user only
+ privs = sentryStore.listSentryPrivilegesForProvider(new HashSet<String>(Arrays.asList("")),
+ Sets.newHashSet("user1"), thriftRoleSet, tSentryAuthorizable);
+ assertTrue(privs.size() == 1);
+ assertTrue(privs.contains("server=server1->uri=" + uri + "->action=all"));
+
+ // list privilege for both user and group
+ privs = sentryStore.listSentryPrivilegesForProvider(
+ new HashSet<String>(Arrays.asList("group1")), Sets.newHashSet("user1"), thriftRoleSet,
+ tSentryAuthorizable);
+ assertTrue(privs.size() == 1);
+ assertTrue(privs.contains("server=server1->uri=" + uri + "->action=all"));
+ }
+
+ @Test
+ public void testURIGrantRevokeOnEmptyPath() throws Exception {
+ String roleName = "test-empty-uri-role";
+ String grantor = "g1";
+ String uri = "";
+ createRole(roleName);
+ TSentryPrivilege tSentryPrivilege = new TSentryPrivilege("URI", "server1", "ALL");
+ tSentryPrivilege.setURI(uri);
+ //Test grant on empty URI
+ try {
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, tSentryPrivilege);
+ fail("Expected SentryInvalidInputException");
+ } catch(SentryInvalidInputException e) {
+ // expected
+ }
+ //Test revoke on empty URI
+ try {
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, tSentryPrivilege);
+ fail("Expected SentryInvalidInputException");
+ } catch(SentryInvalidInputException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testCreateDuplicateRole() throws Exception {
+ String roleName = "test-dup-role";
+ createRole(roleName);
+ try {
+ sentryStore.createSentryRole(roleName);
+ fail("Expected SentryAlreadyExistsException");
+ } catch(SentryAlreadyExistsException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testCaseSensitiveScope() throws Exception {
+ String roleName = "role1";
+ String grantor = "g1";
+ createRole(roleName);
+ TSentryPrivilege sentryPrivilege = new TSentryPrivilege("Database", "server1", "all");
+ sentryPrivilege.setDbName("db1");
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, sentryPrivilege);
+ }
+
+ /**
+ * Create a new role and then destroy it
+ * @throws Exception
+ */
+ @Test
+ public void testCreateDropRole() throws Exception {
+ String roleName = "test-drop-role";
+ createRole(roleName);
+ sentryStore.dropSentryRole(roleName);
+ checkRoleDoesNotExist(roleName);
+ }
+
+ @Test
+ public void testAddDeleteGroupsNonExistantRole()
+ throws Exception {
+ String roleName = "non-existant-role";
+ String grantor = "g1";
+ Set<TSentryGroup> groups = Sets.newHashSet();
+ Set<String> users = Sets.newHashSet(grantor);
+ try {
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName, groups);
+ fail("Expected SentryNoSuchObjectException exception");
+ } catch (SentryNoSuchObjectException e) {
+ // excepted exception
+ }
+ try {
+ sentryStore.alterSentryRoleAddUsers(roleName, users);
+ fail("Expected SentryNoSuchObjectException exception");
+ } catch (SentryNoSuchObjectException e) {
+ // excepted exception
+ }
+ }
+
+ @Test
+ public void testAddDeleteGroups() throws Exception {
+ String roleName = "test-groups";
+ String grantor = "g1";
+ createRole(roleName);
+ Set<TSentryGroup> groups = Sets.newHashSet();
+ TSentryGroup group = new TSentryGroup();
+ group.setGroupName("test-groups-g1");
+ groups.add(group);
+ group = new TSentryGroup();
+ group.setGroupName("test-groups-g2");
+ groups.add(group);
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName, groups);
+ sentryStore.alterSentryRoleDeleteGroups(roleName, groups);
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ assertEquals(Collections.emptySet(), role.getGroups());
+ }
+
+ @Test
+ public void testAddDeleteUsers() throws Exception {
+ String roleName = "test-users";
+ createRole(roleName);
+ Set<String> users = Sets.newHashSet("test-user-u1", "test-user-u2");
+ sentryStore.alterSentryRoleAddUsers(roleName, users);
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ role.getUsers().size();
+ sentryStore.alterSentryRoleDeleteUsers(roleName, users);
+ role = sentryStore.getMSentryRoleByName(roleName);
+ assertEquals(0, role.getUsers().size());
+ }
+
+ @Test
+ public void testGetTSentryRolesForUser() throws Exception {
+ // Test the method GetTSentryRolesForUser according to the following test data:
+ // user1->group1
+ // user2->group1
+ // user3->group1, group2
+ // user4->group2, group3
+ // group1->r1
+ // group2->r2
+ // group3->r2
+ // user2->r3
+ // user4->r3
+ String roleName1 = "r1";
+ String roleName2 = "r2";
+ String roleName3 = "r3";
+ String user1 = "u1";
+ String user2 = "u2";
+ String user3 = "u3";
+ String user4 = "u4";
+ String group1 = "group1";
+ String group2 = "group2";
+ String group3 = "group3";
+ Map<String, Set<String>> userToGroups = Maps.newHashMap();
+ userToGroups.put(user1, Sets.newHashSet(group1));
+ userToGroups.put(user2, Sets.newHashSet(group1));
+ userToGroups.put(user3, Sets.newHashSet(group1, group2));
+ userToGroups.put(user4, Sets.newHashSet(group2, group3));
+
+ sentryStore.createSentryRole(roleName1);
+ sentryStore.createSentryRole(roleName2);
+ sentryStore.createSentryRole(roleName3);
+ sentryStore.alterSentryRoleAddUsers(roleName1, Sets.newHashSet(user1));
+ sentryStore.alterSentryRoleAddUsers(roleName2, Sets.newHashSet(user2));
+ sentryStore.alterSentryRoleAddUsers(roleName2, Sets.newHashSet(user3));
+ sentryStore.alterSentryRoleAddUsers(roleName3, Sets.newHashSet(user2, user4));
+
+ Set<TSentryRole> roles = sentryStore.getTSentryRolesByUserNames(Sets.newHashSet(user1));
+ assertEquals(1, roles.size());
+ for (TSentryRole role : roles) {
+ assertTrue(roleName1.equals(role.getRoleName()));
+ }
+
+ roles = sentryStore.getTSentryRolesByUserNames(Sets.newHashSet(user2));
+ assertEquals(2, roles.size());
+ for (TSentryRole role : roles) {
+ assertTrue(roleName2.equals(role.getRoleName()) || roleName3.equals(role.getRoleName()));
+ }
+
+ roles = sentryStore.getTSentryRolesByUserNames(Sets.newHashSet(user3));
+ assertEquals(1, roles.size());
+ for (TSentryRole role : roles) {
+ assertTrue(roleName2.equals(role.getRoleName()));
+ }
+
+ roles = sentryStore.getTSentryRolesByUserNames(Sets.newHashSet(user4));
+ assertEquals(1, roles.size());
+ for (TSentryRole role : roles) {
+ assertTrue(roleName3.equals(role.getRoleName()));
+ }
+ }
+
+ @Test
+ public void testGetTSentryRolesForUsers() throws Exception {
+ // Test the method getTSentryRolesByUserNames according to the following test data:
+ // user1->r1
+ // user2->r3
+ // user3->r2
+ // user4->r3, r2
+ String roleName1 = "r1";
+ String roleName2 = "r2";
+ String roleName3 = "r3";
+ String user1 = "u1";
+ String user2 = "u2";
+ String user3 = "u3";
+ String user4 = "u4";
+
+ createRole(roleName1);
+ createRole(roleName2);
+ createRole(roleName3);
+ sentryStore.alterSentryRoleAddUsers(roleName1, Sets.newHashSet(user1));
+ sentryStore.alterSentryRoleAddUsers(roleName2, Sets.newHashSet(user3));
+ sentryStore.alterSentryRoleAddUsers(roleName2, Sets.newHashSet(user4));
+ sentryStore.alterSentryRoleAddUsers(roleName3, Sets.newHashSet(user2, user4));
+
+ Set<String> userSet1 = Sets.newHashSet(user1, user2, user3);
+ Set<String> roleSet1 = Sets.newHashSet(roleName1, roleName2, roleName3);
+
+ Set<String> userSet2 = Sets.newHashSet(user4);
+ Set<String> roleSet2 = Sets.newHashSet(roleName2, roleName3);
+
+ Set<String> userSet3 = Sets.newHashSet("foo");
+ Set<String> roleSet3 = Sets.newHashSet();
+
+ // Query for multiple users
+ Set<String> roles = convertToRoleNameSet(sentryStore.getTSentryRolesByUserNames(userSet1));
+ assertEquals("Returned roles should match the expected roles", 0, Sets.symmetricDifference(roles, roleSet1).size());
+
+ // Query for single users
+ roles = convertToRoleNameSet(sentryStore.getTSentryRolesByUserNames(userSet2));
+ assertEquals("Returned roles should match the expected roles", 0, Sets.symmetricDifference(roles, roleSet2).size());
+
+ // Query for non-existing user
+ roles = convertToRoleNameSet(sentryStore.getTSentryRolesByUserNames(userSet3));
+ assertEquals("Returned roles should match the expected roles", 0, Sets.symmetricDifference(roles, roleSet3).size());
+ }
+
+ private Set<String> convertToRoleNameSet(Set<TSentryRole> tSentryRoles) {
+ Set<String> roleNameSet = Sets.newHashSet();
+ for (TSentryRole role : tSentryRoles) {
+ roleNameSet.add(role.getRoleName());
+ }
+ return roleNameSet;
+ }
+
+ @Test
+ public void testGetTSentryRolesForGroups() throws Exception {
+ // Test the method getRoleNamesForGroups according to the following test data:
+ // group1->r1
+ // group2->r2
+ // group3->r2
+ String grantor = "g1";
+ String roleName1 = "r1";
+ String roleName2 = "r2";
+ String roleName3 = "r3";
+ String group1 = "group1";
+ String group2 = "group2";
+ String group3 = "group3";
+
+ createRole(roleName1);
+ createRole(roleName2);
+ createRole(roleName3);
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName1, Sets.newHashSet(new TSentryGroup(group1)));
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName2, Sets.newHashSet(new TSentryGroup(group2),
+ new TSentryGroup(group3)));
+
+ Set<String> groupSet1 = Sets.newHashSet(group1, group2, group3);
+ Set<String> roleSet1 = Sets.newHashSet(roleName1, roleName2);
+
+ Set<String> groupSet2 = Sets.newHashSet(group1);
+ Set<String> roleSet2 = Sets.newHashSet(roleName1);
+
+ Set<String> groupSet3 = Sets.newHashSet("foo");
+ Set<String> roleSet3 = Sets.newHashSet();
+
+ // Query for multiple groups
+ Set<String> roles = sentryStore.getRoleNamesForGroups(groupSet1);
+ assertEquals("Returned roles should match the expected roles", 0, Sets.symmetricDifference(roles, roleSet1).size());
+
+ // Query for single group
+ roles = sentryStore.getRoleNamesForGroups(groupSet2);
+ assertEquals("Returned roles should match the expected roles", 0, Sets.symmetricDifference(roles, roleSet2).size());
+
+ // Query for non-existing group
+ roles = sentryStore.getRoleNamesForGroups(groupSet3);
+ assertEquals("Returned roles should match the expected roles", 0, Sets.symmetricDifference(roles, roleSet3).size());
+ }
+
+ @Test
+ public void testGrantRevokePrivilege() throws Exception {
+ String roleName = "test-privilege";
+ String grantor = "g1";
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ createRole(roleName);
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("TABLE");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setAction(AccessConstants.ALL);
+ privilege.setCreateTime(System.currentTimeMillis());
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ Set<MSentryPrivilege> privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 1, privileges.size());
+ privilege.setAction(AccessConstants.SELECT);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege);
+ // after having ALL and revoking SELECT, we should have INSERT
+ role = sentryStore.getMSentryRoleByName(roleName);
+ privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 1, privileges.size());
+ for (MSentryPrivilege mPrivilege : privileges) {
+ assertEquals(server, mPrivilege.getServerName());
+ assertEquals(db, mPrivilege.getDbName());
+ assertEquals(table, mPrivilege.getTableName());
+ assertNotSame(AccessConstants.SELECT, mPrivilege.getAction());
+ assertFalse(mPrivilege.getGrantOption());
+ }
+ long numDBPrivs = sentryStore.countMSentryPrivileges();
+ assertEquals("Privilege count", numDBPrivs,1);
+ }
+
+ private void verifyOrphanCleanup() throws Exception {
+ assertFalse("Failed to cleanup orphaned privileges", sentryStore.findOrphanedPrivileges());
+ }
+
+ /**
+ * Create several privileges in the database, then delete the role that
+ * created them. This makes them all orphans. Wait a bit to ensure the
+ * cleanup thread runs, and expect them all to be gone from the database.
+ * @throws Exception
+ */
+ // @Ignore("Disabled with SENTRY-545 following SENTRY-140 problems")
+ @Test
+ public void testPrivilegeCleanup() throws Exception {
+ final String roleName = "test-priv-cleanup";
+ final String grantor = "g1";
+ final String server = "server";
+ final String dBase = "db";
+ final String table = "table-";
+
+ createRole(roleName);
+
+ // Create NUM_PRIVS unique privilege objects in the database
+ for (int i = 0; i < NUM_PRIVS; i++) {
+ TSentryPrivilege priv = new TSentryPrivilege();
+ priv.setPrivilegeScope("TABLE");
+ priv.setServerName(server);
+ priv.setAction(AccessConstants.ALL);
+ priv.setCreateTime(System.currentTimeMillis());
+ priv.setTableName(table + i);
+ priv.setDbName(dBase);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, priv);
+ }
+
+ // Make sure we really have the expected number of privs in the database
+ assertEquals(sentryStore.countMSentryPrivileges(), NUM_PRIVS);
+
+ // Now to make a bunch of orphans, we just remove the role that
+ // created them.
+ sentryStore.dropSentryRole(roleName);
+
+ // Now wait and see if the orphans get cleaned up
+ verifyOrphanCleanup();
+
+ List<MSentryPrivilege> list = sentryStore.getAllMSentryPrivileges();
+ assertEquals(list.size(), 0);
+ }
+
+ /**
+ * Much like testPrivilegeCleanup, make a lot of privileges and make sure
+ * they get cleaned up. The difference here is that the privileges are
+ * created by granting ALL and then removing SELECT - thus leaving INSERT.
+ * This test exists because the revocation plays havoc with the orphan
+ * cleanup thread.
+ * @throws Exception
+ */
+ // @Ignore("Disabled with SENTRY-545 following SENTRY-140 problems")
+ @Test
+ public void testPrivilegeCleanup2() throws Exception {
+ final String roleName = "test-priv-cleanup";
+ final String grantor = "g1";
+ final String server = "server";
+ final String dBase = "db";
+ final String table = "table-";
+
+ createRole(roleName);
+
+ // Create NUM_PRIVS unique privilege objects in the database once more,
+ // this time granting ALL and revoking SELECT to make INSERT.
+ for (int i=0 ; i < NUM_PRIVS; i++) {
+ TSentryPrivilege priv = new TSentryPrivilege();
+ priv.setPrivilegeScope("DATABASE");
+ priv.setServerName(server);
+ priv.setAction(AccessConstants.ALL);
+ priv.setCreateTime(System.currentTimeMillis());
+ priv.setTableName(table + i);
+ priv.setDbName(dBase);
+ priv.setGrantOption(TSentryGrantOption.TRUE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, priv);
+
+ priv.setAction(AccessConstants.SELECT);
+ priv.setGrantOption(TSentryGrantOption.UNSET);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, priv);
+ // after having ALL and revoking SELECT, we should have INSERT
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ Set<MSentryPrivilege> privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 1 * (i+1), privileges.size());
+ for ( MSentryPrivilege mSentryPrivilege : privileges) {
+ assertNotSame(AccessConstants.INSERT, mSentryPrivilege.getAction());
+ assertNotSame(AccessConstants.ALL, mSentryPrivilege.getAction());
+ }
+ }
+
+ // Drop the role and clean up as before
+ sentryStore.dropSentryRole(roleName);
+ verifyOrphanCleanup();
+ //There should not be any Privileges left
+ List<MSentryPrivilege> list = sentryStore.getAllMSentryPrivileges();
+ assertEquals(list.size(), 0);
+ }
+
+ /**
+ * This method tries to add ALL privileges on
+ * databases to a role and immediately revokes
+ * SELECT and INSERT privileges. At the end of
+ * each iteration we should not find any privileges
+ * for that role. Finally we should not find any
+ * privileges, as we are cleaning up orphan privileges
+ * immediately.
+ * @throws Exception
+ */
+ @Test
+ public void testPrivilegeCleanup3() throws Exception {
+ final String roleName = "test-priv-cleanup";
+ final String grantor = "g1";
+ final String server = "server";
+ final String dBase = "db";
+ final String table = "table-";
+
+ createRole(roleName);
+
+ // Create NUM_PRIVS unique privilege objects in the database once more,
+ // this time granting ALL and revoking SELECT to make INSERT.
+ for (int i=0 ; i < NUM_PRIVS; i++) {
+ TSentryPrivilege priv = new TSentryPrivilege();
+ priv.setPrivilegeScope("DATABASE");
+ priv.setServerName(server);
+ priv.setAction(AccessConstants.ALL);
+ priv.setCreateTime(System.currentTimeMillis());
+ priv.setTableName(table + i);
+ priv.setDbName(dBase);
+ priv.setGrantOption(TSentryGrantOption.TRUE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, priv);
+
+ priv.setAction(AccessConstants.SELECT);
+ priv.setGrantOption(TSentryGrantOption.UNSET);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, priv);
+
+ assertFalse(sentryStore.findOrphanedPrivileges());
+
+ //After having ALL and revoking SELECT, we should have INSERT
+ //Remove the INSERT privilege as well.
+ //There should not be any more privileges in the sentry store
+ priv.setAction(AccessConstants.INSERT);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, priv);
+
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ assertEquals("Privilege Count", 0, role.getPrivileges().size());
+
+ priv.setAction(AccessConstants.CREATE);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, priv);
+
+ role = sentryStore.getMSentryRoleByName(roleName);
+ assertEquals("Privilege Count", 0, role.getPrivileges().size());
+
+ priv.setAction(AccessConstants.DROP);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, priv);
+
+ role = sentryStore.getMSentryRoleByName(roleName);
+ assertEquals("Privilege Count", 0, role.getPrivileges().size());
+
+ priv.setAction(AccessConstants.ALTER);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, priv);
+
+ role = sentryStore.getMSentryRoleByName(roleName);
+ assertEquals("Privilege Count", 0, role.getPrivileges().size());
+ }
+
+ // Drop the role and clean up as before
+ verifyOrphanCleanup();
+
+ //There should not be any Privileges left
+ List<MSentryPrivilege> list = sentryStore.getAllMSentryPrivileges();
+ assertEquals(list.size(), 0);
+
+ }
+
+ /**
+ * This method "n" privileges with action "ALL" on
+ * tables to a role. Later we are revoking insert
+ * and select privileges to of the tables making the
+ * the privilege orphan. Finally we should find only
+ * n -1 privileges, as we are cleaning up orphan
+ * privileges immediately.
+ * @throws Exception
+ */
+ @Test
+ public void testPrivilegeCleanup4 () throws Exception {
+ final String roleName = "test-priv-cleanup";
+ final String grantor = "g1";
+ final String server = "server";
+ final String dBase = "db";
+ final String table = "table-";
+
+ createRole(roleName);
+
+ // Create NUM_PRIVS unique privilege objects in the database
+ for (int i = 0; i < NUM_PRIVS; i++) {
+ TSentryPrivilege priv = new TSentryPrivilege();
+ priv.setPrivilegeScope("TABLE");
+ priv.setServerName(server);
+ priv.setAction(AccessConstants.ALL);
+ priv.setCreateTime(System.currentTimeMillis());
+ priv.setTableName(table + i);
+ priv.setDbName(dBase);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, priv);
+ }
+
+ // Make sure we really have the expected number of privs in the database
+ assertEquals(sentryStore.countMSentryPrivileges(), NUM_PRIVS);
+
+ //Revoking INSERT privilege. This is change the privilege to SELECT, CREATE, DROP, ALTER
+ TSentryPrivilege priv = new TSentryPrivilege();
+ priv.setPrivilegeScope("TABLE");
+ priv.setServerName(server);
+ priv.setAction(AccessConstants.INSERT);
+ priv.setCreateTime(System.currentTimeMillis());
+ priv.setTableName(table + '0');
+ priv.setDbName(dBase);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, priv);
+
+ //There should be SELECT privilege in the sentry store
+ priv = new TSentryPrivilege();
+ priv.setPrivilegeScope("TABLE");
+ priv.setServerName(server);
+ priv.setAction(AccessConstants.SELECT);
+ priv.setCreateTime(System.currentTimeMillis());
+ priv.setTableName(table + '0');
+ priv.setDbName(dBase);
+ MSentryPrivilege mPriv = sentryStore.findMSentryPrivilegeFromTSentryPrivilege(priv);
+ assertNotNull(mPriv);
+
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+
+ // should have NUM_PRIVS - 1 ALL privileges, and 4 privileges (SELECT, CREATE, DROP, ALTER)
+ assertEquals("Privilege Count", NUM_PRIVS, role.getPrivileges().size());
+
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, priv);
+ role = sentryStore.getMSentryRoleByName(roleName);
+ assertEquals("Privilege Count", NUM_PRIVS - 1, role.getPrivileges().size());
+
+ }
+
+ /**
+ * This method tries to add alter privileges on
+ * databases to a role and immediately revokes
+ * them. At the end of each iteration we should
+ * not find any privileges for that role
+ * Finally we should not find any privileges, as
+ * we are cleaning up orphan privileges immediately.
+ * @throws Exception
+ */
+ @Test
+ public void testPrivilegeCleanup5() throws Exception {
+ final String roleName = "test-priv-cleanup";
+ final String grantor = "g1";
+ final String server = "server";
+ final String dBase = "db";
+ final String table = "table-";
+
+ createRole(roleName);
+
+ // Create NUM_PRIVS unique privilege objects in the database once more,
+ // this time granting ALL and revoking SELECT to make INSERT.
+ for (int i=0 ; i < NUM_PRIVS; i++) {
+ TSentryPrivilege priv = new TSentryPrivilege();
+ priv.setPrivilegeScope("DATABASE");
+ priv.setServerName(server);
+ priv.setAction(AccessConstants.ALTER);
+ priv.setCreateTime(System.currentTimeMillis());
+ priv.setTableName(table + i);
+ priv.setDbName(dBase);
+ priv.setGrantOption(TSentryGrantOption.TRUE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, priv);
+
+ priv.setAction(AccessConstants.ALTER);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, priv);
+
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ assertEquals("Privilege Count", 0, role.getPrivileges().size());
+ }
+ //There should not be any Privileges left
+ List<MSentryPrivilege> list = sentryStore.getAllMSentryPrivileges();
+ assertEquals(list.size(), 0);
+
+ }
+
+ //TODO Use new transaction Manager logic, Instead of
+
+ @Test
+ public void testGrantRevokeMultiPrivileges() throws Exception {
+ String roleName = "test-privilege";
+ String grantor = "g1";
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ String[] columns = {"c1","c2","c3","c4"};
+ createRole(roleName);
+ Set<TSentryPrivilege> tPrivileges = Sets.newHashSet();
+ for (String column : columns) {
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("Column");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setColumnName(column);
+ privilege.setAction(AccessConstants.SELECT);
+ privilege.setCreateTime(System.currentTimeMillis());
+ tPrivileges.add(privilege);
+ }
+ sentryStore.alterSentryRoleGrantPrivileges(grantor, roleName, tPrivileges);
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ Set<MSentryPrivilege> privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 4, privileges.size());
+
+ tPrivileges = Sets.newHashSet();
+ for (int i = 0; i < 2; i++) {
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("Column");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setColumnName(columns[i]);
+ privilege.setAction(AccessConstants.SELECT);
+ privilege.setCreateTime(System.currentTimeMillis());
+ tPrivileges.add(privilege);
+ }
+ sentryStore.alterSentryRoleRevokePrivileges(grantor, roleName, tPrivileges);
+ role = sentryStore.getMSentryRoleByName(roleName);
+ privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 2, privileges.size());
+
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("Table");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setAction(AccessConstants.SELECT);
+ privilege.setCreateTime(System.currentTimeMillis());
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege);
+ // After revoking table scope, we will have 0 privileges
+ role = sentryStore.getMSentryRoleByName(roleName);
+ privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 0, privileges.size());
+ }
+
+ /**
+ * Regression test for SENTRY-74 and SENTRY-552
+ */
+ @Test
+ public void testGrantRevokePrivilegeWithColumn() throws Exception {
+ String roleName = "test-col-privilege";
+ String grantor = "g1";
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ String column1 = "c1";
+ String column2 = "c2";
+ createRole(roleName);
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("COLUMN");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setColumnName(column1);
+ privilege.setAction(AccessConstants.ALL);
+ privilege.setCreateTime(System.currentTimeMillis());
+
+ // Grant ALL on c1 and c2
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);
+ privilege.setColumnName(column2);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ Set<MSentryPrivilege> privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 2, privileges.size());
+
+ // Revoke SELECT on c2
+ privilege.setAction(AccessConstants.SELECT);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege);
+
+ // At this point c1 has ALL privileges and c2 should have (INSERT, CREATE, DROP, ALTER)
+ // after revoking SELECT
+ role = sentryStore.getMSentryRoleByName(roleName);
+ privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 2, privileges.size());
+ for (MSentryPrivilege mPrivilege: privileges) {
+ assertEquals(server, mPrivilege.getServerName());
+ assertEquals(db, mPrivilege.getDbName());
+ assertEquals(table, mPrivilege.getTableName());
+ assertFalse(mPrivilege.getGrantOption());
+ if (mPrivilege.getColumnName().equals(column1)) {
+ assertEquals(AccessConstants.ALL, mPrivilege.getAction());
+ } else if (mPrivilege.getColumnName().equals(column2)) {
+ assertNotSame(AccessConstants.SELECT, mPrivilege.getAction());
+ assertNotSame(AccessConstants.ALL, mPrivilege.getAction());
+ } else {
+ fail("Unexpected column name: " + mPrivilege.getColumnName());
+ }
+ }
+
+ // after revoking INSERT table level privilege will remove INSERT privileges from column2
+ // and downgrade column1 to (SELECT) privileges.
+ privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("TABLE");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setAction(AccessConstants.INSERT);
+ privilege.setCreateTime(System.currentTimeMillis());
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege);
+ role = sentryStore.getMSentryRoleByName(roleName);
+ privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 1, privileges.size());
+
+ // Revoke ALL from the table should now remove all the column privileges.
+ privilege.setAction(AccessConstants.ALL);
+ privilege.setCreateTime(System.currentTimeMillis());
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege);
+ role = sentryStore.getMSentryRoleByName(roleName);
+ privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 0, privileges.size());
+ }
+
+ /**
+ * Regression test for SENTRY-552
+ */
+ @Test
+ public void testGrantRevokeTablePrivilegeDowngradeByDb() throws Exception {
+ String roleName = "test-table-db-downgrade-privilege";
+ String grantor = "g1";
+ String server = "server1";
+ String db = "db1";
+ String table1 = "tbl1";
+ String table2 = "tbl2";
+ createRole(roleName);
+ TSentryPrivilege privilegeTable1 = new TSentryPrivilege();
+ privilegeTable1.setPrivilegeScope("TABLE");
+ privilegeTable1.setServerName(server);
+ privilegeTable1.setDbName(db);
+ privilegeTable1.setTableName(table1);
+ privilegeTable1.setAction(AccessConstants.ALL);
+ privilegeTable1.setCreateTime(System.currentTimeMillis());
+ TSentryPrivilege privilegeTable2 = privilegeTable1.deepCopy();
+ privilegeTable2.setTableName(table2);
+
+ // Grant ALL on table1 and table2
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilegeTable1);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilegeTable2);
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ Set<MSentryPrivilege> privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 2, privileges.size());
+
+ // Revoke SELECT on table2
+ privilegeTable2.setAction(AccessConstants.SELECT);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilegeTable2);
+ // after having ALL and revoking SELECT, we should have (INSERT) at table2
+ role = sentryStore.getMSentryRoleByName(roleName);
+ privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 2, privileges.size());
+
+ for (MSentryPrivilege mPrivilege: privileges) {
+ assertEquals(server, mPrivilege.getServerName());
+ assertEquals(db, mPrivilege.getDbName());
+ assertFalse(mPrivilege.getGrantOption());
+ if (mPrivilege.getTableName().equals(table1)) {
+ assertEquals(AccessConstants.ALL, mPrivilege.getAction());
+ } else if (mPrivilege.getTableName().equals(table2)) {
+ assertNotSame(AccessConstants.SELECT, mPrivilege.getAction());
+ assertNotSame(AccessConstants.ALL, mPrivilege.getAction());
+ } else {
+ fail("Unexpected table name: " + mPrivilege.getTableName());
+ }
+ }
+
+ // Revoke INSERT on Database
+ privilegeTable2.setAction(AccessConstants.INSERT);
+ privilegeTable2.setPrivilegeScope("DATABASE");
+ privilegeTable2.unsetTableName();
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilegeTable2);
+ role = sentryStore.getMSentryRoleByName(roleName);
+ privileges = role.getPrivileges();
+
+ // after revoking INSERT database level privilege
+ // table1 should have (SELECT)
+ // table2 should have ()
+ assertEquals(privileges.toString(), 1, privileges.size());
+ for (MSentryPrivilege mPrivilege : privileges) {
+ assertEquals(server, mPrivilege.getServerName());
+ assertEquals(db, mPrivilege.getDbName());
+ if (table1.equals(mPrivilege.getTableName())) {
+ assertNotSame(AccessConstants.INSERT, mPrivilege.getAction());
+ assertNotSame(AccessConstants.ALL, mPrivilege.getAction());
+ } else if (table2.equals(mPrivilege.getTableName())) {
+ assertNotSame(AccessConstants.INSERT, mPrivilege.getAction());
+ assertNotSame(AccessConstants.SELECT, mPrivilege.getAction());
+ assertNotSame(AccessConstants.ALL, mPrivilege.getAction());
+ }
+ assertFalse(mPrivilege.getGrantOption());
+ }
+ }
+
+ /**
+ * Regression test for SENTRY-552
+ */
+ @Test
+ public void testGrantRevokeColumnPrivilegeDowngradeByDb() throws Exception {
+ String roleName = "test-column-db-downgrade-privilege";
+ String grantor = "g1";
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ String column1 = "c1";
+ String column2 = "c2";
+ createRole(roleName);
+ TSentryPrivilege privilegeCol1 = new TSentryPrivilege();
+ privilegeCol1.setPrivilegeScope("COLUMN");
+ privilegeCol1.setServerName(server);
+ privilegeCol1.setDbName(db);
+ privilegeCol1.setTableName(table);
+ privilegeCol1.setColumnName(column1);
+ privilegeCol1.setAction(AccessConstants.ALL);
+ privilegeCol1.setCreateTime(System.currentTimeMillis());
+ TSentryPrivilege privilegeCol2 = privilegeCol1.deepCopy();
+ privilegeCol2.setColumnName(column2);
+
+ // Grant ALL on column1 and column2
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilegeCol1);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilegeCol2);
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ Set<MSentryPrivilege> privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 2, privileges.size());
+
+ // Revoke SELECT on column2
+ privilegeCol2.setAction(AccessConstants.SELECT);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilegeCol2);
+ // after having ALL and revoking SELECT, we should have (INSERT)
+ role = sentryStore.getMSentryRoleByName(roleName);
+ privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 2, privileges.size());
+
+ for (MSentryPrivilege mPrivilege: privileges) {
+ assertEquals(server, mPrivilege.getServerName());
+ assertEquals(db, mPrivilege.getDbName());
+ assertEquals(table, mPrivilege.getTableName());
+ assertFalse(mPrivilege.getGrantOption());
+ if (mPrivilege.getColumnName().equals(column1)) {
+ assertEquals(AccessConstants.ALL, mPrivilege.getAction());
+ } else if (mPrivilege.getColumnName().equals(column2)) {
+ assertNotSame(AccessConstants.SELECT, mPrivilege.getAction());
+ } else {
+ fail("Unexpected column name: " + mPrivilege.getColumnName());
+ }
+ }
+
+ // Revoke INSERT on Database
+ privilegeCol2.setAction(AccessConstants.INSERT);
+ privilegeCol2.setPrivilegeScope("DATABASE");
+ privilegeCol2.unsetTableName();
+ privilegeCol2.unsetColumnName();
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilegeCol2);
+ role = sentryStore.getMSentryRoleByName(roleName);
+ privileges = role.getPrivileges();
+
+ // after revoking INSERT database level privilege
+ // column2 has ()
+ // and downgrade column1 to (SELECT) privileges.
+ assertEquals(privileges.toString(), 1, privileges.size());
+ for (MSentryPrivilege mPrivilege : privileges) {
+ assertEquals(server, mPrivilege.getServerName());
+ assertEquals(db, mPrivilege.getDbName());
+ assertEquals(table, mPrivilege.getTableName());
+ if (column1.equals(mPrivilege.getColumnName())) {
+ assertNotSame(AccessConstants.INSERT, mPrivilege.getAction());
+ } else if (column1.equals(mPrivilege.getColumnName())) {
+ assertNotSame(AccessConstants.SELECT, mPrivilege.getAction());
+ assertNotSame(AccessConstants.INSERT, mPrivilege.getAction());
+ }
+ assertFalse(mPrivilege.getGrantOption());
+ }
+ }
+
+ @Test
+ public void testGrantRevokePrivilegeWithGrantOption() throws Exception {
+ String roleName = "test-grantOption-table";
+ String grantor = "g1";
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ TSentryGrantOption grantOption = TSentryGrantOption.TRUE;
+ createRole(roleName);
+
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("TABLE");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setAction(AccessConstants.ALL);
+ privilege.setCreateTime(System.currentTimeMillis());
+ privilege.setGrantOption(grantOption);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ Set<MSentryPrivilege> privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 1, privileges.size());
+ assertEquals(Boolean.valueOf(privilege.getGrantOption().toString()), Iterables.get(privileges, 0).getGrantOption());
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege);
+ role = sentryStore.getMSentryRoleByName(roleName);
+ privileges = role.getPrivileges();
+ assertEquals(0, privileges.size());
+
+ roleName = "test-grantOption-db";
+
+ createRole(roleName);
+ privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("DATABASE");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setAction(AccessConstants.ALL);
+ privilege.setGrantOption(TSentryGrantOption.TRUE);
+ privilege.setCreateTime(System.currentTimeMillis());
+ privilege.setGrantOption(grantOption);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);
+ role = sentryStore.getMSentryRoleByName(roleName);
+ privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 1, privileges.size());
+
+ privilege.setAction(AccessConstants.SELECT);
+ privilege.setGrantOption(TSentryGrantOption.UNSET);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege);
+ // after having ALL and revoking SELECT, we should have (INSERT)
+ role = sentryStore.getMSentryRoleByName(roleName);
+ privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 1, privileges.size());
+ for (MSentryPrivilege mPrivilege : privileges) {
+ assertEquals(server, mPrivilege.getServerName());
+ assertEquals(db, mPrivilege.getDbName());
+ assertNotSame(AccessConstants.SELECT, mPrivilege.getAction());
+ }
+ }
+
+ @Test
+ public void testGrantCheckWithGroupAndUser() throws Exception {
+ // 1. set local group mapping and group-role, user-role mapping
+ // user0_0->group0
+ // user0_1->group0
+ // user1_0->group1
+ // user1_1->group1
+ // group0->roleG0
+ // group1->roleG1
+ // user0_0->roleU00
+ // user0_1->roleU01
+ // user1_0->roleU10
+ // user1_1->roleU11
+ String grantor = "g1";
+ String[][] users = { { "user0_0", "user0_1" }, { "user1_0", "user1_1" } };
+ String[] groups = { "group0", "group1" };
+ String[] rolesForGroup = { "roleG0", "roleG1" };
+ String[] rolesForUser = { "roleU0", "roleU1", "roleU2", "roleU3" };
+ for (int i = 0; i < groups.length; i++) {
+ for (int j = 0; j < users[i].length; j++) {
+ addGroupsToUser(users[i][j], groups[i]);
+ sentryStore.createSentryRole(rolesForUser[i * 2 + j]);
+ sentryStore.alterSentryRoleAddUsers(rolesForUser[i * 2 + j], Sets.newHashSet(users[i][j]));
+ }
+ sentryStore.createSentryRole(rolesForGroup[i]);
+ Set<TSentryGroup> tGroups = Sets.newHashSet();
+ TSentryGroup tGroup = new TSentryGroup(groups[i]);
+ tGroups.add(tGroup);
+ sentryStore.alterSentryRoleAddGroups(grantor, rolesForGroup[i], tGroups);
+ }
+ writePolicyFile();
+
+ // 2. g1 grant all on database db1 to roleG0, roleU0 without grant option
+ String server = "server1";
+ String db = "db1";
+ grantor = "g1";
+ TSentryPrivilege privilege1 = new TSentryPrivilege();
+ privilege1.setPrivilegeScope("DATABASE");
+ privilege1.setServerName(server);
+ privilege1.setDbName(db);
+ privilege1.setAction(AccessConstants.ALL);
+ privilege1.setCreateTime(System.currentTimeMillis());
+ privilege1.setGrantOption(TSentryGrantOption.FALSE);
+ // user0_0 has the privilege without grant option
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, "roleG0", privilege1);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, "roleU0", privilege1);
+ try {
+ sentryStore.alterSentryRoleGrantPrivilege("user0_0", "roleG1", privilege1);
+ fail("Expected SentryGrantDeniedException exception");
+ } catch (SentryGrantDeniedException e) {
+ // excepted exception
+ }
+ try {
+ sentryStore.alterSentryRoleRevokePrivilege("user0_0", "roleG1", privilege1);
+ fail("Expected SentryGrantDeniedException exception");
+ } catch (SentryGrantDeniedException e) {
+ // excepted exception
+ }
+
+ // 3. g1 grant all on database db1 to roleG0 with grant option
+ TSentryPrivilege privilege2 = new TSentryPrivilege();
+ privilege2.setPrivilegeScope("DATABASE");
+ privilege2.setServerName(server);
+ privilege2.setDbName(db);
+ privilege2.setAction(AccessConstants.ALL);
+ privilege2.setCreateTime(System.currentTimeMillis());
+ privilege2.setGrantOption(TSentryGrantOption.TRUE);
+ // user0_0, user0_1 can grant the same privilege to other roles
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, "roleG0", privilege2);
+ sentryStore.alterSentryRoleGrantPrivilege("user0_0", "roleG1", privilege2);
+ validatePrivilegeByRoleName("roleG1", privilege2);
+ sentryStore.alterSentryRoleRevokePrivilege("user0_0", "roleG1", privilege2);
+ validateEmptyPrivilegeByRoleName("roleG1");
+ sentryStore.alterSentryRoleGrantPrivilege("user0_1", "roleG1", privilege2);
+ validatePrivilegeByRoleName("roleG1", privilege2);
+ sentryStore.alterSentryRoleRevokePrivilege("user0_1", "roleG1", privilege2);
+ validateEmptyPrivilegeByRoleName("roleG1");
+ // clear privilege for roleG0
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, "roleG0", privilege2);
+
+ // 4. g1 grant all on database db1 to roleU0 with grant option
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, "roleU0", privilege2);
+ sentryStore.alterSentryRoleGrantPrivilege("user0_0", "roleG1", privilege2);
+ validatePrivilegeByRoleName("roleG1", privilege2);
+ sentryStore.alterSentryRoleRevokePrivilege("user0_0", "roleG1", privilege2);
+ validateEmptyPrivilegeByRoleName("roleG1");
+ try {
+ sentryStore.alterSentryRoleGrantPrivilege("user0_1", "roleG1", privilege2);
+ fail("Expected SentryGrantDeniedException exception");
+ } catch (SentryGrantDeniedException e) {
+ // excepted exception
+ }
+ try {
+ sentryStore.alterSentryRoleRevokePrivilege("user0_1", "roleG1", privilege2);
+ fail("Expected SentryGrantDeniedException exception");
+ } catch (SentryGrantDeniedException e) {
+ // excepted exception
+ }
+ // clear privilege for roleG0
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, "roleU0", privilege2);
+
+ // 5. g1 grant all on database db1 to roleU2, roleG0 with grant option
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, "roleU2", privilege2);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, "roleG0", privilege2);
+ sentryStore.alterSentryRoleGrantPrivilege("user0_0", "roleG1", privilege2);
+ validatePrivilegeByRoleName("roleG1", privilege2);
+ sentryStore.alterSentryRoleRevokePrivilege("user0_0", "roleG1", privilege2);
+ validateEmptyPrivilegeByRoleName("roleG1");
+ sentryStore.alterSentryRoleGrantPrivilege("user0_1", "roleG1", privilege2);
+ validatePrivilegeByRoleName("roleG1", privilege2);
+ sentryStore.alterSentryRoleRevokePrivilege("user0_1", "roleG1", privilege2);
+ validateEmptyPrivilegeByRoleName("roleG1");
+
+ sentryStore.alterSentryRoleGrantPrivilege("user1_0", "roleG1", privilege2);
+ validatePrivilegeByRoleName("roleG1", privilege2);
+ sentryStore.alterSentryRoleRevokePrivilege("user1_0", "roleG1", privilege2);
+ validateEmptyPrivilegeByRoleName("roleG1");
+ try {
+ sentryStore.alterSentryRoleGrantPrivilege("user1_1", "roleG1", privilege2);
+ fail("Expected SentryGrantDeniedException exception");
+ } catch (SentryGrantDeniedException e) {
+ // excepted exception
+ }
+ try {
+ sentryStore.alterSentryRoleRevokePrivilege("user1_1", "roleG1", privilege2);
+ fail("Expected SentryGrantDeniedException exception");
+ } catch (SentryGrantDeniedException e) {
+ // excepted exception
+ }
+ // clear privilege for roleG0
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, "roleG0", privilege2);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, "roleU2", privilege2);
+ }
+
+ private void validatePrivilegeByRoleName(String roleName, TSentryPrivilege exceptedTPrivelege)
+ throws Exception {
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ Set<MSentryPrivilege> privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 1, privileges.size());
+ MSentryPrivilege mPrivilege = Iterables.get(privileges, 0);
+ assertEquals(exceptedTPrivelege.getServerName(), mPrivilege.getServerName());
+ assertEquals(exceptedTPrivelege.getDbName(), mPrivilege.getDbName());
+ assertEquals(AccessConstants.ALL, mPrivilege.getAction());
+ }
+
+ private void validateEmptyPrivilegeByRoleName(String roleName) throws Exception {
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ Set<MSentryPrivilege> privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 0, privileges.size());
+ }
+
+ @Test
+ public void testGrantCheckWithGrantOption() throws Exception {
+ // 1. set local group mapping
+ // user0->group0->role0
+ // user1->group1->role1
+ // user2->group2->role2
+ // user3->group3->role3
+ // user4->group4->role4
+ String grantor = "g1";
+ String[] users = {"user0","user1","user2","user3","user4"};
+ String[] groups = { "group0", "group1", "group2", "group3", "group4" };
+ String[] roles = {"role0","role1","role2","role3","role4"};
+ for (int i = 0; i < users.length; i++) {
+ addGroupsToUser(users[i], groups[i]);
+ sentryStore.createSentryRole(roles[i]);
+ Set<TSentryGroup> tGroups = Sets.newHashSet();
+ TSentryGroup tGroup = new TSentryGroup(groups[i]);
+ tGroups.add(tGroup);
+ sentryStore.alterSentryRoleAddGroups(grantor, roles[i], tGroups);
+ }
+ writePolicyFile();
+
+ // 2. g1 grant all on database db1 to role0 with grant option
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ String roleName = roles[0];
+ grantor = "g1";
+ TSentryPrivilege privilege1 = new TSentryPrivilege();
+ privilege1.setPrivilegeScope("DATABASE");
+ privilege1.setServerName(server);
+ privilege1.setDbName(db);
+ privilege1.setAction(AccessConstants.ALL);
+ privilege1.setCreateTime(System.currentTimeMillis());
+ privilege1.setGrantOption(TSentryGrantOption.TRUE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege1);
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ Set<MSentryPrivilege> privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 1, privileges.size());
+
+ // 3. user0 grant select on database db1 to role1, with grant option
+ roleName = roles[1];
+ grantor = users[0];
+ TSentryPrivilege privilege2 = new TSentryPrivilege();
+ privilege2.setPrivilegeScope("DATABASE");
+ privilege2.setServerName(server);
+ privilege2.setDbName(db);
+ privilege2.setAction(AccessConstants.SELECT);
+ privilege2.setCreateTime(System.currentTimeMillis());
+ privilege2.setGrantOption(TSentryGrantOption.TRUE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege2);
+
+ // 4. user0 grant all on table tb1 to role2, no grant option
+ roleName = roles[2];
+ grantor = users[0];
+ TSentryPrivilege privilege3 = new TSentryPrivilege();
+ privilege3.setPrivilegeScope("TABLE");
+ privilege3.setServerName(server);
+ privilege3.setDbName(db);
+ privilege3.setTableName(table);
+ privilege3.setAction(AccessConstants.ALL);
+ privilege3.setCreateTime(System.currentTimeMillis());
+ privilege3.setGrantOption(TSentryGrantOption.FALSE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege3);
+
+ // 5. user1 has role1, no insert privilege,
+ // grant insert to role3, will throw no grant exception
+ roleName = roles[3];
+ grantor = users[1];
+ TSentryPrivilege privilege4 = new TSentryPrivilege();
+ privilege4.setPrivilegeScope("DATABASE");
+ privilege4.setServerName(server);
+ privilege4.setDbName(db);
+ privilege4.setAction(AccessConstants.INSERT);
+ privilege4.setCreateTime(System.currentTimeMillis());
+ privilege4.setGrantOption(TSentryGrantOption.FALSE);
+ try {
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege4);
+ fail("Expected SentryGrantDeniedException exception");
+ } catch (SentryGrantDeniedException e) {
+ // excepted exception
+ }
+
+ // 6. user2 has role2, no grant option,
+ // grant insert to role4, will throw no grant exception
+ roleName = roles[4];
+ grantor = users[2];
+ TSentryPrivilege privilege5 = new TSentryPrivilege();
+ privilege5.setPrivilegeScope("TABLE");
+ privilege5.setServerName(server);
+ privilege5.setDbName(db);
+ privilege5.setTableName(table);
+ privilege5.setAction(AccessConstants.INSERT);
+ privilege5.setCreateTime(System.currentTimeMillis());
+ privilege5.setGrantOption(TSentryGrantOption.FALSE);
+ try {
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege5);
+ fail("Expected SentryGrantDeniedException exception");
+ } catch (SentryGrantDeniedException e) {
+ // excepted exception
+ }
+ }
+
+ @Test
+ public void testRevokeCheckWithGrantOption() throws Exception {
+ // 1. set local group mapping
+ // user0->group0->role0
+ // user1->group1->role1
+ // user2->group2->role2
+ String grantor = "g1";
+ String[] users = {"user0","user1","user2"};
+ String[] roles = {"role0","role1","role2"};
+ String[] groups = {"group0","group1","group2"};
+ for (int i = 0; i < users.length; i++) {
+ addGroupsToUser(users[i], groups[i]);
+ sentryStore.createSentryRole(roles[i]);
+ Set<TSentryGroup> tGroups = Sets.newHashSet();
+ TSentryGroup tGroup = new TSentryGroup(groups[i]);
+ tGroups.add(tGroup);
+ sentryStore.alterSentryRoleAddGroups(grantor, roles[i], tGroups);
+ sentryStore.alterSentryRoleAddUsers(roles[i], Sets.newHashSet(users[i]));
+ }
+ writePolicyFile();
+
+ // 2. g1 grant select on database db1 to role0, with grant option
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ String roleName = roles[0];
+ grantor = "g1";
+ TSentryPrivilege privilege1 = new TSentryPrivilege();
+ privilege1.setPrivilegeScope("DATABASE");
+ privilege1.setServerName(server);
+ privilege1.setDbName(db);
+ privilege1.setAction(AccessConstants.SELECT);
+ privilege1.setCreateTime(System.currentTimeMillis());
+ privilege1.setGrantOption(TSentryGrantOption.TRUE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege1);
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ Set<MSentryPrivilege> privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 1, privileges.size());
+
+ // 3. g1 grant all on table tb1 to role1, no grant option
+ roleName = roles[1];
+ grantor = "g1";
+ TSentryPrivilege privilege2 = new TSentryPrivilege();
+ privilege2.setPrivilegeScope("TABLE");
+ privilege2.setServerName(server);
+ privilege2.setDbName(db);
+ privilege2.setTableName(table);
+ privilege2.setAction(AccessConstants.ALL);
+ privilege2.setCreateTime(System.currentTimeMillis());
+ privilege2.setGrantOption(TSentryGrantOption.FALSE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege2);
+
+ // 4. g1 grant select on table tb1 to role2, no grant option
+ roleName = roles[2];
+ grantor = "g1";
+ TSentryPrivilege privilege3 = new TSentryPrivilege();
+ privilege3.setPrivilegeScope("TABLE");
+ privilege3.setServerName(server);
+ privilege3.setDbName(db);
+ privilege3.setTableName(table);
+ privilege3.setAction(AccessConstants.SELECT);
+ privilege3.setCreateTime(System.currentTimeMillis());
+ privilege3.setGrantOption(TSentryGrantOption.FALSE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege3);
+
+ // 5. user1 has role1, no grant option,
+ // revoke from role2 will throw no grant exception
+ roleName = roles[2];
+ grantor = users[1];
+ try {
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege3);
+ fail("Expected SentryGrantDeniedException exception");
+ } catch (SentryGrantDeniedException e) {
+ // excepted exception
+ }
+
+ // 6. user0 has role0, only have select,
+ // revoke all from role1 will throw no grant exception
+ roleName = roles[1];
+ grantor = users[0];
+ try {
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege2);
+ fail("Expected SentryGrantDeniedException exception");
+ } catch (SentryGrantDeniedException e) {
+ // excepted exception
+ }
+
+ // 7. user0 has role0, has select and grant option,
+ // revoke select from role2
+ roleName = roles[2];
+ grantor = users[0];
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege3);
+ role = sentryStore.getMSentryRoleByName(roleName);
+ privileges = role.getPrivileges();
+ assertEquals(0, privileges.size());
+ }
+
+ @Test
+ public void testRevokeAllGrantOption() throws Exception {
+ // 1. set local group mapping
+ // user0->group0->role0
+ String grantor = "g1";
+ String[] users = {"user0"};
+ String[] roles = {"role0"};
+ String[] groups = {"group0"};
+ for (int i = 0; i < users.length; i++) {
+ addGroupsToUser(users[i], groups[i]);
+ sentryStore.createSentryRole(roles[i]);
+ Set<TSentryGroup> tGroups = Sets.newHashSet();
+ TSentryGroup tGroup = new TSentryGroup(groups[i]);
+ tGroups.add(tGroup);
+ sentryStore.alterSentryRoleAddGroups(grantor, roles[i], tGroups);
+ }
+ writePolicyFile();
+
+ // 2. g1 grant select on table tb1 to role0, with grant option
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ String roleName = roles[0];
+ grantor = "g1";
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("TABLE");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setAction(AccessConstants.SELECT);
+ privilege.setCreateTime(System.currentTimeMillis());
+ privilege.setGrantOption(TSentryGrantOption.TRUE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);
+
+ // 3. g1 grant select on table tb1 to role0, no grant option
+ roleName = roles[0];
+ grantor = "g1";
+ privilege.setGrantOption(TSentryGrantOption.FALSE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);
+
+ // 4. g1 revoke all privilege from role0
+ roleName = roles[0];
+ grantor = "g1";
+ privilege.setGrantOption(TSentryGrantOption.UNSET);
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege);
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ Set<MSentryPrivilege> privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 0, privileges.size());
+ }
+
+ @Test
+ public void testGrantCheckWithColumn() throws Exception {
+ // 1. set local group mapping
+ // user0->group0->role0
+ // user1->group1->role1
+ String grantor = "g1";
+ String[] users = {"user0","user1"};
+ String[] roles = {"role0","role1"};
+ String[] groups = {"group0","group1"};
+ for (int i = 0; i < users.length; i++) {
+ addGroupsToUser(users[i], groups[i]);
+ sentryStore.createSentryRole(roles[i]);
+ Set<TSentryGroup> tGroups = Sets.newHashSet();
+ TSentryGroup tGroup = new TSentryGroup(groups[i]);
+ tGroups.add(tGroup);
+ sentryStore.alterSentryRoleAddGroups(grantor, roles[i], tGroups);
+ }
+ writePolicyFile();
+
+ // 2. g1 grant select on table tb1 to role0, with grant option
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ String roleName = roles[0];
+ grantor = "g1";
+ TSentryPrivilege privilege1 = new TSentryPrivilege();
+ privilege1.setPrivilegeScope("TABLE");
+ privilege1.setServerName(server);
+ privilege1.setDbName(db);
+ privilege1.setTableName(table);
+ privilege1.setAction(AccessConstants.SELECT);
+ privilege1.setCreateTime(System.currentTimeMillis());
+ privilege1.setGrantOption(TSentryGrantOption.TRUE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege1);
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ Set<MSentryPrivilege> privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 1, privileges.size());
+
+ // 3. user0 grant select on column tb1.c1 to role1, with grant option
+ roleName = roles[1];
+ grantor = users[0];
+ String column = "c1";
+ TSentryPrivilege privilege2 = new TSentryPrivilege();
+ privilege2.setPrivilegeScope("COLUMN");
+ privilege2.setServerName(server);
+ privilege2.setDbName(db);
+ privilege2.setTableName(table);
+ privilege2.setColumnName(column);
+ privilege2.setAction(AccessConstants.SELECT);
+ privilege2.setCreateTime(System.currentTimeMillis());
+ privilege2.setGrantOption(TSentryGrantOption.TRUE);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege2);
+
+ // 4. user1 revoke table level privilege from user0, will throw grant denied exception
+ roleName = roles[0];
+ grantor = users[1];
+ try {
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege1);
+ fail("Expected SentryGrantDeniedException exception");
+ } catch (SentryGrantDeniedException e) {
+ // excepted exception
+ }
+
+ // 5. user0 revoke column level privilege from user1
+ roleName = roles[1];
+ grantor = users[0];
+ sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege2);
+ role = sentryStore.getMSentryRoleByName(roleName);
+ privileges = role.getPrivileges();
+ assertEquals(0, privileges.size());
+ }
+
+ @Test
+ public void testGrantDuplicatePrivilege() throws Exception {
+ String roleName = "test-privilege";
+ String grantor = "g1";
+ String server = "server1";
+ String db = "db1";
+ String table = "tbl1";
+ createRole(roleName);
+ TSentryPrivilege privilege = new TSentryPrivilege();
+ privilege.setPrivilegeScope("TABLE");
+ privilege.setServerName(server);
+ privilege.setDbName(db);
+ privilege.setTableName(table);
+ privilege.setAction(AccessConstants.ALL);
+ privilege.setCreateTime(System.currentTimeMillis());
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);
+ privilege.setServerName("Server1");
+ privilege.setDbName("DB1");
+ privilege.setTableName("TBL1");
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);
+ MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+ Set<MSentryPrivilege> privileges = role.getPrivileges();
+ assertEquals(privileges.toString(), 1, privileges.size());
+ }
+
+ @Test
+ public void testListSentryPrivilegesForProvider() throws Exception {
+ String roleName1 = "list-privs-r1", roleName2 = "list-privs-r2";
+ String groupName1 = "list-privs-g1", groupName2 = "list-privs-g2";
+ String userName1 = "list-privs-u1", userName2 = "list-privs-u2";
+ String userWithoutRole = "user-no-privs";
+ Set<String> noRoleUsers = Sets.newHashSet(userWithoutRole);
+ String grantor = "g1";
+ sentryStore.createSentryRole(roleName1);
+ sentryStore.createSentryRole(roleName2);
+ TSentryPrivilege privilege1 = new TSentryPrivilege();
+ privilege1.setPrivilegeScope("TABLE");
+ privilege1.setServerName("server1");
+ privilege1.setDbName("db1");
+ privilege1.setTableName("tbl1");
+ privilege1.setAction("SELECT");
+ privilege1.setCreateTime(System.currentTimeMillis());
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege1);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege1);
+ TSentryPrivilege privilege2 = new TSentryPrivilege();
+ privilege2.setPrivilegeScope("SERVER");
+ privilege2.setServerName("server1");
+ privilege2.setCreateTime(System.currentTimeMillis());
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege2);
+ Set<TSentryGroup> groups = Sets.newHashSet();
+ Set<String> users = Sets.newHashSet();
+ TSentryGroup group = new TSentryGroup();
+ group.setGroupName(groupName1);
+ groups.add(group);
+ users.add(userName1);
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName1, groups);
+ sentryStore.alterSentryRoleAddUsers(roleName1, users);
+ groups.clear();
+ users.clear();
+ group = new TSentryGroup();
+ group.setGroupName(groupName2);
+ groups.add(group);
+ users.add(userName2);
+ // group 2 and user2 has both roles 1 and 2
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName1, groups);
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName2, groups);
+ sentryStore.alterSentryRoleAddUsers(roleName1, users);
+ sentryStore.alterSentryRoleAddUsers(roleName2, users);
+ // group1 all roles
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
+ SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets
+ .newHashSet(groupName1), noRoleUsers, new TSentryActiveRoleSet(true,
+ new HashSet<String>()))));
+ // user1 all roles
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
+ SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets
+ .newHashSet(""), Sets.newHashSet(userName1), new TSentryActiveRoleSet(true,
+ new HashSet<String>()))));
+ // group1 and user1 all roles
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
+ SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets
+ .newHashSet(groupName1), Sets.newHashSet(userName1), new TSentryActiveRoleSet(true,
+ new HashSet<String>()))));
+ // one active role
+ assertEquals(
+ Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
+ SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
+ Sets.newHashSet(groupName1), noRoleUsers,
+ new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
+ // unknown active role
+ assertEquals(
+ Sets.newHashSet(),
+ SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
+ Sets.newHashSet(groupName1), noRoleUsers,
+ new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
+ // no active roles
+ assertEquals(Sets.newHashSet(), SentryStore.toTrimedLower(sentryStore
+ .listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1), noRoleUsers,
+ new TSentryActiveRoleSet(false, new HashSet<String>()))));
+
+ // group2 all roles
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select",
+ "server=server1"), SentryStore.toTrimedLower(sentryStore
+ .listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2), Sets.newHashSet(""),
+ new TSentryActiveRoleSet(true, new HashSet<String>()))));
+ // user2 all roles
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select",
+ "server=server1"), SentryStore.toTrimedLower(sentryStore
+ .listAllSentryPrivilegesForProvider(Sets.newHashSet(""), Sets.newHashSet(userName2),
+ new TSentryActiveRoleSet(true, new HashSet<String>()))));
+ // user2 and group2 all roles
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select",
+ "server=server1"), SentryStore.toTrimedLower(sentryStore
+ .listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
+ Sets.newHashSet(userName2), new TSentryActiveRoleSet(true, new HashSet<String>()))));
+
+ // one active role
+ assertEquals(
+ Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
+ SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
+ Sets.newHashSet(groupName2), noRoleUsers,
+ new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
+ assertEquals(
+ Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select", "server=server1"),
+ SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
+ Sets.newHashSet(groupName2), noRoleUsers,
+ new TSentryActiveRoleSet(false, Sets.newHashSet(roleName2)))));
+ // unknown active role
+ assertEquals(
+ Sets.newHashSet(),
+ SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
+ Sets.newHashSet(groupName2), noRoleUsers,
+ new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
+ // no active roles
+ assertEquals(Sets.newHashSet(), SentryStore.toTrimedLower(sentryStore
+ .listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2), noRoleUsers,
+ new TSentryActiveRoleSet(false, new HashSet<String>()))));
+
+ // both groups, all active roles
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select",
+ "server=server1"), SentryStore.toTrimedLower(sentryStore
+ .listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1, groupName2), noRoleUsers,
+ new TSentryActiveRoleSet(true, new HashSet<String>()))));
+ // both users and groups, all active roles
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select",
+ "server=server1"), SentryStore.toTrimedLower(sentryStore
+ .listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1, groupName2), Sets
+ .newHashSet(userName1, userName2),
+ new TSentryActiveRoleSet(true, new HashSet<String>()))));
+ // one active role
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
+ SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(
+ groupName1, groupName2), noRoleUsers,
+ new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
+ assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select",
+ "server=server1"), SentryStore.toTrimedLower(sentryStore
+ .listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1, groupName2), noRoleUsers,
+ new TSentryActiveRoleSet(false, Sets.newHashSet(roleName2)))));
+ // unknown active role
+ assertEquals(Sets.newHashSet(), SentryStore.toTrimedLower(sentryStore
+ .listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1, groupName2), noRoleUsers,
+ new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
+ // no active roles
+ assertEquals(Sets.newHashSet(), SentryStore.toTrimedLower(sentryStore
+ .listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1, groupName2), noRoleUsers,
+ new TSentryActiveRoleSet(false, new HashSet<String>()))));
+ }
+
+ @Test
+ public void testListRole() throws Exception {
+ String roleName1 = "role1", roleName2 = "role2", roleName3 = "role3";
+ String group1 = "group1", group2 = "group2";
+ String grantor = "g1";
+
+ sentryStore.createSentryRole(roleName1);
+ sentryStore.createSentryRole(roleName2);
+ sentryStore.createSentryRole(roleName3);
+
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName1, Sets.newHashSet(new TSentryGroup(group1)));
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName2, Sets.newHashSet(new TSentryGroup(group2)));
+ sentryStore.alterSentryRoleAddGroups(grantor, roleName3,
+ Sets.newHashSet(new TSentryGroup(group1), new TSentryGroup(group2)));
+
+ assertEquals(2, sentryStore.getTSentryRolesByGroupName(Sets.newHashSet(group1), false).size());
+ assertEquals(2, sentryStore.getTSentryRolesByGroupName(Sets.newHashSet(group2), false).size());
+ assertEquals(3, sentryStore.getTSentryRolesByGroupName(Sets.newHashSet(group1,group2), false).size());
+ assertEquals(0,
+ sentryStore.getTSentryRolesByGroupName(Sets.newHashSet("foo"), true)
+ .size());
+ }
+
+ /**
+ * Assign multiple table and SERVER privileges to roles
+ * drop privilege for the object verify that it's removed correctl
+ * @throws Exception
+ */
+ @Test
+ public void testDropDbObject() throws Exception {
+ String roleName1 = "list-privs-r1", roleName2 = "list-privs-r2", roleName3 = "list-privs-r3";
+ String grantor = "g1";
+ sentryStore.createSentryRole(roleName1);
+ sentryStore.createSentryRole(roleName2);
+ sentryStore.createSentryRole(roleName3);
+
+ TSentryPrivilege privilege_tbl1 = new TSentryPrivilege();
+ privilege_tbl1.setPrivilegeScope("TABLE");
+ privilege_tbl1.setServerName("server1");
+ privilege_tbl1.setDbName("db1");
+ privilege_tbl1.setTableName("tbl1");
+ privilege_tbl1.setCreateTime(System.currentTimeMillis());
+
+ TSentryPrivilege privilege1 = new TSentryPrivilege(privilege_tbl1);
+ privilege1.setAction("SELECT");
+
+ TSentryPrivilege privilege2_1 = new TSentryPrivilege(privilege_tbl1);
+ privilege2_1.setAction("INSERT");
+ TSentryPrivilege privilege3_1 = new TSentryPrivilege(privilege_tbl1);
+ privilege3_1.setAction("*");
+
+ TSentryPrivilege privilege_server = new TSentryPrivilege();
+ privilege_server.setPrivilegeScope("SERVER");
+ privilege_server.setServerName("server1");
+ privilege_server.setCreateTime(System.currentTimeMillis());
+
+ TSentryPrivilege privilege_tbl2 = new TSentryPrivilege();
+ privilege_tbl2.setPrivilegeScope("TABLE");
+ privilege_tbl2.setServerName("server1");
+ privilege_tbl2.setDbName("db1");
+ privilege_tbl2.setTableName("tbl2");
+ privilege_tbl2.setCreateTime(System.currentTimeMillis());
+
+ TSentryPrivilege privilege2_3 = new TSentryPrivilege(privilege_tbl2);
+ privilege2_3.setAction("SELECT");
+
+ TSentryPrivilege privilege3_2 = new TSentryPrivilege(privilege_tbl2);
+ privilege3_2.setAction("INSERT");
+
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege1);
+
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege2_1);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege_server);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege2_3);
+
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName3, privilege3_1);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName3, privilege3_2);
+
+ sentryStore.dropPrivilege(toTSentryAuthorizable(privilege_tbl1));
+ assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1)
+ .size());
+ assertEquals(2, sentryStore.getAllTSentryPrivilegesByRoleName(roleName2)
+ .size());
+ assertEquals(1, sentryStore.getAllTSentryPrivilegesByRoleName(roleName3)
+ .size());
+
+ sentryStore.dropPrivilege(toTSentryAuthorizable(privilege_tbl2));
+ assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1)
+ .size());
+ assertEquals(1, sentryStore.getAllTSentryPrivilegesByRoleName(roleName2)
+ .size());
+ assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName3)
+ .size());
+ }
+
+ /**
+ * Regression test for SENTRY-547 and SENTRY-548
+ * Use case:
+ * GRANT INSERT on TABLE tbl1 to ROLE role1
+ * GRANT SELECT on TABLE tbl1 to ROLE role1
+ * GRANT ALTER on TABLE tbl1 to ROLE role1
+ * GRANT DROP on TABLE tbl1 to ROLE role1
+ * DROP TABLE tbl1
+ *
+ * After drop tbl1, role1 should have 0 privileges
+ */
+ @Test
+ public void testDropTableWithMultiAction() throws Exception {
+ String roleName1 = "role1";
+ String grantor = "g1";
+ sentryStore.createSentryRole(roleName1);
+
+ TSentryPrivilege privilege_tbl1 = new TSentryPrivilege();
+ privilege_tbl1.setPrivilegeScope("TABLE");
+ privilege_tbl1.setServerName("server1");
+ privilege_tbl1.setDbName("db1");
+ privilege_tbl1.setTableName("tbl1");
+ privilege_tbl1.setCreateTime(System.currentTimeMillis());
+
+ TSentryPrivilege privilege_tbl1_insert = new TSentryPrivilege(
+ privilege_tbl1);
+ privilege_tbl1_insert.setAction(AccessConstants.INSERT);
+
+ TSentryPrivilege privilege_tbl1_select = new TSentryPrivilege(
+ privilege_tbl1);
+ privilege_tbl1_select.setAction(AccessConstants.SELECT);
+
+ TSentryPrivilege privilege_tbl1_alter = new TSentryPrivilege(
+ privilege_tbl1);
+ privilege_tbl1_alter.setAction(AccessConstants.ALTER);
+
+ TSentryPrivilege privilege_tbl1_drop = new TSentryPrivilege(
+ privilege_tbl1);
+ privilege_tbl1_drop.setAction(AccessConstants.DROP);
+
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_insert);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_select);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_alter);
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_drop);
+
+ assertEquals(4, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1).size());
+
+ // after drop privilege_tbl1, role1 should have 0 privileges
+ sentryStore.dropPrivilege(toTSentryAuthorizable(privilege_tbl1));
+ assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1).size());
+ }
+
+ @Test
+ public void testDropTableWithColumn() throws Exception {
+ String roleName1 = "role1", roleName2 = "role2";
+ String grantor = "g1";
+ String table1 = "tbl1";
+
+ sentryStore.createSentryRole(roleName1);
+ sentryStore.createSentryRole(roleName2);
+
+ TSentryPrivilege privilege_tbl1 = new TSentryPrivilege();
+ privilege_tbl1.setPrivilegeScope("TABLE");
+ privilege_tbl1.setServerName("server1");
+ privilege_tbl1.setDbName("db1");
+ privilege_tbl1.setTableName(table1);
+ privilege_tbl1.setAction(AccessConstants.SELECT);
+ privilege_tbl1.setCreateTime(System.currentTimeMillis());
+
+ TSentryPrivilege privilege_tbl1_c1 = new TSentryPrivilege(privilege_tbl1);
+ privilege_tbl1_c1.setPrivilegeScope("COLUMN");
+ privilege_tbl1_c1.setColumnName("c1");
+ privilege_tbl1_c1.setCreateTime(System.currentTimeMillis());
+
+ TSentryPrivilege privilege_tbl1_c2 = new TSentryPrivilege(privilege_tbl1);
+ privilege_tbl1_c2.setPrivilegeScope("COLUMN");
+ privilege_tbl1_c2.setColumnName("c2");
+ privilege_tbl1_c2.setCreateTime(System.currentTimeMillis());
+
+ TSentryPrivilege privilege_tbl1_c3 = new TSentryPrivilege(privilege_tbl1);
+ privilege_tbl1_c3.setPrivilegeScope("COLUMN");
+ privilege_tbl1_c3.setColumnName("c3");
+ privilege_tbl1_c3.setCreateTime(System.currentTimeMillis());
+
+ sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_c1);
+ sentryStore.alterSentryRoleGra
<TRUNCATED>