Repository: sentry
Updated Branches:
  refs/heads/master 04881fa7a -> 68949951e


http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
 
b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
index 02f98e2..ddd42c5 100644
--- 
a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
+++ 
b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java
@@ -22,6 +22,7 @@ import java.io.File;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.io.FileUtils;
@@ -40,17 +41,18 @@ import 
org.apache.sentry.provider.db.service.thrift.TSentryAuthorizable;
 import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
 import org.apache.sentry.provider.db.service.thrift.TSentryGroup;
 import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
+import org.apache.sentry.provider.db.service.thrift.TSentryRole;
 import org.apache.sentry.provider.file.PolicyFile;
 import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
 import org.junit.After;
 import org.junit.AfterClass;
-import static org.junit.Assert.assertArrayEquals;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
 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;
 
@@ -135,12 +137,19 @@ public class TestSentryStore extends org.junit.Assert {
     privilege.setAction(AccessConstants.ALL);
     privilege.setCreateTime(System.currentTimeMillis());
 
+    Set<String> users = Sets.newHashSet("user1");
+
     long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
     assertEquals(seqId + 1, sentryStore.alterSentryRoleAddGroups(grantor, 
roleName, groups).getSequenceId());
     assertEquals(seqId + 2, sentryStore.alterSentryRoleDeleteGroups(roleName, 
groups).getSequenceId());
-    assertEquals(seqId + 3, sentryStore.alterSentryRoleGrantPrivilege(grantor, 
roleName, privilege).getSequenceId());
-    assertEquals(seqId + 4, 
sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, 
privilege).getSequenceId());
+    assertEquals(seqId + 3, sentryStore.alterSentryRoleAddUsers(roleName, 
users).getSequenceId());
+    assertEquals(seqId + 4, sentryStore.alterSentryRoleDeleteUsers(roleName, 
users).getSequenceId());
+    assertEquals(seqId + 5, sentryStore.alterSentryRoleGrantPrivilege(grantor, 
roleName, privilege)
+        .getSequenceId());
+    assertEquals(seqId + 6, sentryStore
+        .alterSentryRoleRevokePrivilege(grantor, roleName, 
privilege).getSequenceId());
   }
+
   @Test
   public void testURI() throws Exception {
     String roleName = "test-dup-role";
@@ -163,14 +172,30 @@ public class TestSentryStore extends org.junit.Assert {
     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)));
 
-    Set<String> privs =
-        sentryStore.listSentryPrivilegesForProvider(new 
HashSet<String>(Arrays.asList("group1")), thriftRoleSet, tSentryAuthorizable);
+    // 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
@@ -194,6 +219,7 @@ public class TestSentryStore extends org.junit.Assert {
     sentryPrivilege.setDbName("db1");
     assertEquals(seqId + 1, sentryStore.alterSentryRoleGrantPrivilege(grantor, 
roleName, sentryPrivilege).getSequenceId());
   }
+
   @Test
   public void testCreateDropRole() throws Exception {
     String roleName = "test-drop-role";
@@ -201,13 +227,25 @@ public class TestSentryStore extends org.junit.Assert {
     assertEquals(seqId + 1, 
sentryStore.dropSentryRole(roleName).getSequenceId());
   }
 
-  @Test(expected = SentryNoSuchObjectException.class)
+  @Test
   public void testAddDeleteGroupsNonExistantRole()
       throws Exception {
     String roleName = "non-existant-role";
     String grantor = "g1";
     Set<TSentryGroup> groups = Sets.newHashSet();
-    sentryStore.alterSentryRoleAddGroups(grantor, roleName, groups);
+    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
@@ -231,6 +269,80 @@ public class TestSentryStore extends org.junit.Assert {
   }
 
   @Test
+  public void testAddDeleteUsers() throws Exception {
+    String roleName = "test-users";
+    long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
+    Set<String> users = Sets.newHashSet("test-user-u1", "test-user-u2");
+    assertEquals(seqId + 1, sentryStore.alterSentryRoleAddUsers(roleName, 
users).getSequenceId());
+    MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
+    assertEquals(2, role.getUsers().size());
+    assertEquals(seqId + 2, sentryStore.alterSentryRoleDeleteUsers(roleName, 
users).getSequenceId());
+    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 testGrantRevokePrivilege() throws Exception {
     String roleName = "test-privilege";
     String grantor = "g1";
@@ -678,6 +790,7 @@ public class TestSentryStore extends org.junit.Assert {
     String table = "tbl1";
     TSentryGrantOption grantOption = TSentryGrantOption.TRUE;
     long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
+
     TSentryPrivilege privilege = new TSentryPrivilege();
     privilege.setPrivilegeScope("TABLE");
     privilege.setServerName(server);
@@ -727,6 +840,157 @@ public class TestSentryStore extends org.junit.Assert {
   }
 
   @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
@@ -736,8 +1000,8 @@ public class TestSentryStore extends org.junit.Assert {
     // 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"};
-    String[] groups = {"group0","group1","group2","group3","group4"};
     for (int i = 0; i < users.length; i++) {
       addGroupsToUser(users[i], groups[i]);
       sentryStore.createSentryRole(roles[i]);
@@ -802,14 +1066,12 @@ public class TestSentryStore extends org.junit.Assert {
     privilege4.setAction(AccessConstants.INSERT);
     privilege4.setCreateTime(System.currentTimeMillis());
     privilege4.setGrantOption(TSentryGrantOption.FALSE);
-    boolean isGrantOptionException = false;
     try {
       sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege4);
+      fail("Expected SentryGrantDeniedException exception");
     } catch (SentryGrantDeniedException e) {
-      isGrantOptionException = true;
-      System.err.println(e.getMessage());
+      // excepted exception
     }
-    assertTrue(isGrantOptionException);
 
     // 6. user2 has role2, no grant option,
     // grant insert to role4, will throw no grant exception
@@ -823,14 +1085,12 @@ public class TestSentryStore extends org.junit.Assert {
     privilege5.setAction(AccessConstants.INSERT);
     privilege5.setCreateTime(System.currentTimeMillis());
     privilege5.setGrantOption(TSentryGrantOption.FALSE);
-    isGrantOptionException = false;
     try {
       sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege5);
+      fail("Expected SentryGrantDeniedException exception");
     } catch (SentryGrantDeniedException e) {
-      isGrantOptionException = true;
-      System.err.println(e.getMessage());
+      // excepted exception
     }
-    assertTrue(isGrantOptionException);
   }
 
   @Test
@@ -850,6 +1110,7 @@ public class TestSentryStore extends org.junit.Assert {
       TSentryGroup tGroup = new TSentryGroup(groups[i]);
       tGroups.add(tGroup);
       sentryStore.alterSentryRoleAddGroups(grantor, roles[i], tGroups);
+      sentryStore.alterSentryRoleAddUsers(roles[i], Sets.newHashSet(users[i]));
     }
     writePolicyFile();
 
@@ -901,14 +1162,12 @@ public class TestSentryStore extends org.junit.Assert {
     // revoke from role2 will throw no grant exception
     roleName = roles[2];
     grantor = users[1];
-    boolean isGrantOptionException = false;
     try {
       sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, 
privilege3);
+      fail("Expected SentryGrantDeniedException exception");
     } catch (SentryGrantDeniedException e) {
-      isGrantOptionException = true;
-      System.err.println(e.getMessage());
+      // excepted exception
     }
-    assertTrue(isGrantOptionException);
 
     // 6. user0 has role0, only have select,
     // revoke all from role1 will throw no grant exception
@@ -916,11 +1175,10 @@ public class TestSentryStore extends org.junit.Assert {
     grantor = users[0];
     try {
       sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, 
privilege2);
+      fail("Expected SentryGrantDeniedException exception");
     } catch (SentryGrantDeniedException e) {
-      isGrantOptionException = true;
-      System.err.println(e.getMessage());
+      // excepted exception
     }
-    assertTrue(isGrantOptionException);
 
     // 7. user0 has role0, has select and grant option,
     // revoke select from role2
@@ -1038,14 +1296,12 @@ public class TestSentryStore extends org.junit.Assert {
     // 4. user1 revoke table level privilege from user0, will throw grant 
denied exception
     roleName = roles[0];
     grantor = users[1];
-    boolean isGrantOptionException = false;
     try {
       sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, 
privilege1);
+      fail("Expected SentryGrantDeniedException exception");
     } catch (SentryGrantDeniedException e) {
-      isGrantOptionException = true;
-      System.err.println(e.getMessage());
+      // excepted exception
     }
-    assertTrue(isGrantOptionException);
 
     // 5. user0 revoke column level privilege from user1
     roleName = roles[1];
@@ -1089,6 +1345,9 @@ public class TestSentryStore extends org.junit.Assert {
   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";
     long seqId = sentryStore.createSentryRole(roleName1).getSequenceId();
     assertEquals(seqId + 1, 
sentryStore.createSentryRole(roleName2).getSequenceId());
@@ -1110,82 +1369,124 @@ public class TestSentryStore extends org.junit.Assert {
     assertEquals(seqId + 4, sentryStore.alterSentryRoleGrantPrivilege(grantor, 
roleName2, privilege2)
         .getSequenceId());
     Set<TSentryGroup> groups = Sets.newHashSet();
+    Set<String> users = Sets.newHashSet();
     TSentryGroup group = new TSentryGroup();
     group.setGroupName(groupName1);
     groups.add(group);
+    users.add(userName1);
     assertEquals(seqId + 5, sentryStore.alterSentryRoleAddGroups(grantor,
         roleName1, groups).getSequenceId());
+    assertEquals(seqId + 6, sentryStore.alterSentryRoleAddUsers(roleName1, 
users).getSequenceId());
     groups.clear();
+    users.clear();
     group = new TSentryGroup();
     group.setGroupName(groupName2);
     groups.add(group);
-    // group 2 has both roles 1 and 2
-    assertEquals(seqId + 6, sentryStore.alterSentryRoleAddGroups(grantor,
-        roleName1, groups).getSequenceId());
-    assertEquals(seqId + 7, sentryStore.alterSentryRoleAddGroups(grantor,
-        roleName2, groups).getSequenceId());
+    users.add(userName2);
+    // group 2 and user2 has both roles 1 and 2
+    assertEquals(seqId + 7, sentryStore.alterSentryRoleAddGroups(grantor, 
roleName1, groups)
+        .getSequenceId());
+    assertEquals(seqId + 8, sentryStore.alterSentryRoleAddGroups(grantor, 
roleName2, groups)
+        .getSequenceId());
+    assertEquals(seqId + 9, sentryStore.alterSentryRoleAddUsers(roleName1, 
users).getSequenceId());
+    assertEquals(seqId + 10, sentryStore.alterSentryRoleAddUsers(roleName2, 
users).getSequenceId());
     // group1 all roles
     
assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
-        
SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1),
-            new TSentryActiveRoleSet(true, new HashSet<String>()))));
-    // one active role
+        
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(groupName1),
+        
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),
+    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),
+    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),
+    
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),
+    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),
+    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),
+    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),
+    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),
+    
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),
+        
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),
+    
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),
+    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),
+    assertEquals(Sets.newHashSet(), SentryStore.toTrimedLower(sentryStore
+        .listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1, 
groupName2), noRoleUsers,
             new TSentryActiveRoleSet(false, new HashSet<String>()))));
   }
 
@@ -1601,6 +1902,28 @@ public class TestSentryStore extends org.junit.Assert {
   }
 
   @Test
+  public void testSentryUsersSize() throws Exception {
+    String role1 = "role1";
+    String role2 = "role2";
+
+    sentryStore.createSentryRole(role1);
+    sentryStore.createSentryRole(role2);
+
+    Set<String> users = Sets.newHashSet("user1");
+
+    sentryStore.alterSentryRoleAddUsers(role1, users);
+    assertEquals(Long.valueOf(1), sentryStore.getUserCountGauge().getValue());
+
+    sentryStore.alterSentryRoleAddUsers(role2, users);
+    assertEquals(Long.valueOf(1), sentryStore.getUserCountGauge().getValue());
+
+    users.add("user2");
+    sentryStore.alterSentryRoleAddUsers(role2, users);
+    assertEquals(Long.valueOf(2), sentryStore.getUserCountGauge().getValue());
+
+  }
+
+  @Test
   public void testRenameTableWithColumn() throws Exception {
     String roleName1 = "role1", roleName2 = "role2";
     String grantor = "g1";
@@ -1684,7 +2007,8 @@ public class TestSentryStore extends org.junit.Assert {
     TSentryActiveRoleSet thriftRoleSet = new TSentryActiveRoleSet(true, new 
HashSet<String>(Arrays.asList(roleName)));
 
     Set<String> privs =
-        sentryStore.listSentryPrivilegesForProvider(new 
HashSet<String>(Arrays.asList("group1")), thriftRoleSet, tSentryAuthorizable);
+        sentryStore.listSentryPrivilegesForProvider(new 
HashSet<String>(Arrays.asList("group1")),
+            Sets.newHashSet(grantor), thriftRoleSet, tSentryAuthorizable);
 
     assertTrue(privs.size()==1);
     assertTrue(privs.contains("server=server1->db=" + dbName + "->table=" + 
table + "->action=all"));
@@ -1724,7 +2048,8 @@ public class TestSentryStore extends org.junit.Assert {
     TSentryActiveRoleSet thriftRoleSet = new TSentryActiveRoleSet(true, new 
HashSet<String>(Arrays.asList(roleName)));
 
     Set<String> privs =
-        sentryStore.listSentryPrivilegesForProvider(new 
HashSet<String>(Arrays.asList("group1")), thriftRoleSet, tSentryAuthorizable);
+        sentryStore.listSentryPrivilegesForProvider(new 
HashSet<String>(Arrays.asList("group1")), Sets.newHashSet(grantor),
+                thriftRoleSet, tSentryAuthorizable);
 
     assertTrue(privs.size() == 1);
     assertTrue(privs.contains("server=server1->db=" + dbName + "->table=" + 
table + "->column="

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServerForHaWithoutKerberos.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServerForHaWithoutKerberos.java
 
b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServerForHaWithoutKerberos.java
index ac4df77..6c78942 100644
--- 
a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServerForHaWithoutKerberos.java
+++ 
b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServerForHaWithoutKerberos.java
@@ -104,18 +104,18 @@ public class TestSentryServerForHaWithoutKerberos extends 
SentryServiceIntegrati
     listPrivilegesByRoleName = 
client.listPrivilegesByRoleName(requestorUserName, roleName2, 
Lists.newArrayList(new Server("server"), new Database("db3")));
     assertEquals("Privilege not assigned to role2 !!", 1, 
listPrivilegesByRoleName.size());
 
-    Set<String> listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), 
ActiveRoleSet.ALL, new Server("server"), new Database("db2"));
+    Set<String> listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), null, 
ActiveRoleSet.ALL, new Server("server"), new Database("db2"));
     assertEquals("Privilege not correctly assigned to roles !!",
         Sets.newHashSet("server=server->db=db2->table=table4->action=all", 
"server=server->db=db2->table=table3->action=all"),
         listPrivilegesForProvider);
 
-    listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), 
ActiveRoleSet.ALL, new Server("server"), new Database("db3"));
+    listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), null, 
ActiveRoleSet.ALL, new Server("server"), new Database("db3"));
     assertEquals("Privilege not correctly assigned to roles !!", 
Sets.newHashSet("server=server->db=db3->table=table5->action=all"), 
listPrivilegesForProvider);
 
-    listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), new 
ActiveRoleSet(Sets.newHashSet(roleName1)), new Server("server"), new 
Database("db3"));
+    listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), null, new 
ActiveRoleSet(Sets.newHashSet(roleName1)), new Server("server"), new 
Database("db3"));
     assertEquals("Privilege not correctly assigned to roles !!", 
Sets.newHashSet("server=+"), listPrivilegesForProvider);
 
-    listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), new 
ActiveRoleSet(Sets.newHashSet(roleName1)), new Server("server1"));
+    listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), null, new 
ActiveRoleSet(Sets.newHashSet(roleName1)), new Server("server1"));
     assertEquals("Privilege not correctly assigned to roles !!", new 
HashSet<String>(), listPrivilegesForProvider);
   }
 
@@ -141,28 +141,68 @@ public class TestSentryServerForHaWithoutKerberos extends 
SentryServiceIntegrati
     client.grantRoleToGroup(requestorUserName, ADMIN_GROUP, roleName);
     client.grantDatabasePrivilege(requestorUserName, roleName, "server1", 
"db2", AccessConstants.ALL);
     client.grantTablePrivilege(requestorUserName, roleName, "server1", "db3", 
"tab3", "ALL");
-    assertEquals(2, client.listPrivilegesForProvider(requestorUserGroupNames,
+    assertEquals(2, client.listPrivilegesForProvider(requestorUserGroupNames, 
null,
             ActiveRoleSet.ALL).size());
 
     // drop role and verify privileges
     client.dropRole(requestorUserName, roleName);
-    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames,
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
null,
             ActiveRoleSet.ALL).size());
 
     // recreate the role
     client.createRole(requestorUserName, roleName);
     client.grantRoleToGroup(requestorUserName, ADMIN_GROUP, roleName);
-    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames,
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
null,
             ActiveRoleSet.ALL).size());
 
     // grant different privileges and verify
     client.grantDatabasePrivilege(requestorUserName, roleName, "server1", 
"db2", AccessConstants.ALL);
-    assertEquals(1, client.listPrivilegesForProvider(requestorUserGroupNames,
+    assertEquals(1, client.listPrivilegesForProvider(requestorUserGroupNames, 
null,
             ActiveRoleSet.ALL).size());
     client.dropRole(requestorUserName, roleName);
-    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames,
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
null,
             ActiveRoleSet.ALL).size());
-    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames,
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
null,
+            ActiveRoleSet.ALL).size());
+  }
+
+  @Test
+  public void testDropRoleOnUser() throws Exception {
+    String requestorUserName = ADMIN_USER;
+    Set<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP);
+    Set<String> requestorUserNames = Sets.newHashSet(ADMIN_USER);
+    setLocalGroupMapping(requestorUserName, requestorUserGroupNames);
+    writePolicyFile();
+    String roleName = "admin_r";
+
+    // create role and add privileges
+    client.dropRoleIfExists(requestorUserName, roleName);
+    client.createRole(requestorUserName, roleName);
+    client.grantRoleToUser(requestorUserName, ADMIN_USER, roleName);
+    client.grantDatabasePrivilege(requestorUserName, roleName, "server1", 
"db2", AccessConstants.ALL);
+    client.grantTablePrivilege(requestorUserName, roleName, "server1", "db3", 
"tab3", "ALL");
+    assertEquals(2, client.listPrivilegesForProvider(requestorUserGroupNames, 
requestorUserNames,
+            ActiveRoleSet.ALL).size());
+
+    // drop role and verify privileges
+    client.dropRole(requestorUserName, roleName);
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
requestorUserNames,
+            ActiveRoleSet.ALL).size());
+
+    // recreate the role
+    client.createRole(requestorUserName, roleName);
+    client.grantRoleToGroup(requestorUserName, ADMIN_GROUP, roleName);
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
requestorUserNames,
+            ActiveRoleSet.ALL).size());
+
+    // grant different privileges and verify
+    client.grantDatabasePrivilege(requestorUserName, roleName, "server1", 
"db2", AccessConstants.ALL);
+    assertEquals(1, client.listPrivilegesForProvider(requestorUserGroupNames, 
requestorUserNames,
+            ActiveRoleSet.ALL).size());
+    client.dropRole(requestorUserName, roleName);
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
requestorUserNames,
+            ActiveRoleSet.ALL).size());
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
requestorUserNames,
             ActiveRoleSet.ALL).size());
   }
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServerWithoutKerberos.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServerWithoutKerberos.java
 
b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServerWithoutKerberos.java
index 0792eb6..b37f057 100644
--- 
a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServerWithoutKerberos.java
+++ 
b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServerWithoutKerberos.java
@@ -110,18 +110,18 @@ public class TestSentryServerWithoutKerberos extends 
SentryServiceIntegrationBas
     listPrivilegesByRoleName = 
client.listPrivilegesByRoleName(requestorUserName, roleName2, 
Lists.newArrayList(new Server("server"), new Database("db3")));
     assertEquals("Privilege not assigned to role2 !!", 1, 
listPrivilegesByRoleName.size());
 
-    Set<String> listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), 
ActiveRoleSet.ALL, new Server("server"), new Database("db2"));
+    Set<String> listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), null, 
ActiveRoleSet.ALL, new Server("server"), new Database("db2"));
     assertEquals("Privilege not correctly assigned to roles !!",
         Sets.newHashSet("server=server->db=db2->table=table4->action=all", 
"server=server->db=db2->table=table3->action=all"),
         listPrivilegesForProvider);
 
-    listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), 
ActiveRoleSet.ALL, new Server("server"), new Database("db3"));
+    listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), null, 
ActiveRoleSet.ALL, new Server("server"), new Database("db3"));
     assertEquals("Privilege not correctly assigned to roles !!", 
Sets.newHashSet("server=server->db=db3->table=table5->action=all"), 
listPrivilegesForProvider);
 
-    listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), new 
ActiveRoleSet(Sets.newHashSet(roleName1)), new Server("server"), new 
Database("db3"));
+    listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), null, new 
ActiveRoleSet(Sets.newHashSet(roleName1)), new Server("server"), new 
Database("db3"));
     assertEquals("Privilege not correctly assigned to roles !!", 
Sets.newHashSet("server=+"), listPrivilegesForProvider);
 
-    listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), new 
ActiveRoleSet(Sets.newHashSet(roleName1)), new Server("server1"));
+    listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1, group2), null, new 
ActiveRoleSet(Sets.newHashSet(roleName1)), new Server("server1"));
     assertEquals("Privilege not correctly assigned to roles !!", new 
HashSet<String>(), listPrivilegesForProvider);
   }
 
@@ -147,29 +147,68 @@ public class TestSentryServerWithoutKerberos extends 
SentryServiceIntegrationBas
     client.grantRoleToGroup(requestorUserName, ADMIN_GROUP, roleName);
     client.grantDatabasePrivilege(requestorUserName, roleName, "server1", 
"db2", AccessConstants.ALL);
     client.grantTablePrivilege(requestorUserName, roleName, "server1", "db3", 
"tab3", "ALL");
-    assertEquals(2, client.listPrivilegesForProvider(requestorUserGroupNames,
+    assertEquals(2, client.listPrivilegesForProvider(requestorUserGroupNames, 
null,
             ActiveRoleSet.ALL).size());
 
     // drop role and verify privileges
     client.dropRole(requestorUserName, roleName);
-    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames,
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
null,
             ActiveRoleSet.ALL).size());
 
     // recreate the role
     client.createRole(requestorUserName, roleName);
     client.grantRoleToGroup(requestorUserName, ADMIN_GROUP, roleName);
-    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames,
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
null,
             ActiveRoleSet.ALL).size());
 
     // grant different privileges and verify
     client.grantDatabasePrivilege(requestorUserName, roleName, "server1", 
"db2", AccessConstants.ALL);
-    assertEquals(1, client.listPrivilegesForProvider(requestorUserGroupNames,
+    assertEquals(1, client.listPrivilegesForProvider(requestorUserGroupNames, 
null,
             ActiveRoleSet.ALL).size());
     client.dropRole(requestorUserName, roleName);
-    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames,
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
null,
             ActiveRoleSet.ALL).size());
-    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames,
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
null,
             ActiveRoleSet.ALL).size());
   }
 
+  @Test
+  public void testDropRoleOnUser() throws Exception {
+    String requestorUserName = ADMIN_USER;
+    Set<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP);
+    Set<String> requestorUserNames = Sets.newHashSet(ADMIN_USER);
+    setLocalGroupMapping(requestorUserName, requestorUserGroupNames);
+    writePolicyFile();
+    String roleName = "admin_r";
+
+    // create role and add privileges
+    client.dropRoleIfExists(requestorUserName, roleName);
+    client.createRole(requestorUserName, roleName);
+    client.grantRoleToUser(requestorUserName, ADMIN_USER, roleName);
+    client.grantDatabasePrivilege(requestorUserName, roleName, "server1", 
"db2", AccessConstants.ALL);
+    client.grantTablePrivilege(requestorUserName, roleName, "server1", "db3", 
"tab3", "ALL");
+    assertEquals(2, client.listPrivilegesForProvider(requestorUserGroupNames, 
requestorUserNames,
+            ActiveRoleSet.ALL).size());
+
+    // drop role and verify privileges
+    client.dropRole(requestorUserName, roleName);
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
requestorUserNames,
+            ActiveRoleSet.ALL).size());
+
+    // recreate the role
+    client.createRole(requestorUserName, roleName);
+    client.grantRoleToGroup(requestorUserName, ADMIN_GROUP, roleName);
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
requestorUserNames,
+            ActiveRoleSet.ALL).size());
+
+    // grant different privileges and verify
+    client.grantDatabasePrivilege(requestorUserName, roleName, "server1", 
"db2", AccessConstants.ALL);
+    assertEquals(1, client.listPrivilegesForProvider(requestorUserGroupNames, 
requestorUserNames,
+            ActiveRoleSet.ALL).size());
+    client.dropRole(requestorUserName, roleName);
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
requestorUserNames,
+            ActiveRoleSet.ALL).size());
+    assertEquals(0, client.listPrivilegesForProvider(requestorUserGroupNames, 
requestorUserNames,
+            ActiveRoleSet.ALL).size());
+  }
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceIntegration.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceIntegration.java
 
b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceIntegration.java
index 07c7f7a..a076475 100644
--- 
a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceIntegration.java
+++ 
b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceIntegration.java
@@ -135,6 +135,232 @@ public class TestSentryServiceIntegration extends 
SentryServiceIntegrationBase {
   }
 
   @Test
+  public void testAddDeleteRolesForUser() throws Exception {
+    runTestAsSubject(new TestOperation() {
+      @Override
+      public void runTestAsSubject() throws Exception {
+        String requestorUserName = ADMIN_USER;
+        Set<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP);
+        setLocalGroupMapping(requestorUserName, requestorUserGroupNames);
+
+        // 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 = "g1";
+        String group2 = "g2";
+        String group3 = "g3";
+        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));
+
+        setLocalGroupMapping(user1, Sets.newHashSet(group1));
+        setLocalGroupMapping(user2, Sets.newHashSet(group1));
+        setLocalGroupMapping(user3, Sets.newHashSet(group1, group2));
+        setLocalGroupMapping(user4, Sets.newHashSet(group2, group3));
+        writePolicyFile();
+
+        client.dropRoleIfExists(requestorUserName, roleName1);
+        client.dropRoleIfExists(requestorUserName, roleName2);
+        client.dropRoleIfExists(requestorUserName, roleName3);
+        client.createRole(requestorUserName, roleName1);
+        client.createRole(requestorUserName, roleName2);
+        client.createRole(requestorUserName, roleName3);
+
+        client.grantRoleToGroup(requestorUserName, group1, roleName1);
+        client.grantRoleToUser(requestorUserName, user2, roleName2);
+        client.grantRoleToUser(requestorUserName, user3, roleName2);
+        client.grantRoleToUser(requestorUserName, user2, roleName3);
+        client.grantRoleToUsers(requestorUserName, roleName3, 
Sets.newHashSet(user4));
+        // following test cases also test the grantRoleToUser() and 
grantRoleToUsers() implicity
+        // admin always can get the role list
+        Set<TSentryRole> roles = client.listRolesByUserName(requestorUserName, 
user1);
+        assertEquals(0, roles.size());
+        // the role list includes the role for user and the role for user's 
group
+        roles = client.listRolesByUserName(requestorUserName, user2);
+        assertEquals(2, roles.size());
+        for (TSentryRole role : roles) {
+          assertTrue(roleName2.equals(role.getRoleName()) || 
roleName3.equals(role.getRoleName()));
+        }
+        // user has 2 groups whose role list are different
+        roles = client.listRolesByUserName(requestorUserName, user3);
+        assertEquals(1, roles.size());
+        for (TSentryRole role : roles) {
+          assertTrue(roleName2.equals(role.getRoleName()));
+        }
+        // user has 2 groups whose role list are the same
+        roles = client.listRolesByUserName(requestorUserName, user4);
+        assertEquals(1, roles.size());
+        for (TSentryRole role : roles) {
+          assertTrue(roleName3.equals(role.getRoleName()));
+        }
+        // user can get his own role list if he isn't an admin
+        roles = client.listRolesByUserName(user3, user3);
+        assertEquals(1, roles.size());
+        // user can't get other's role list if he isn't an admin
+        try {
+          client.listRolesByUserName(user3, user2);
+          fail("SentryAccessDeniedException should be caught.");
+        } catch (SentryAccessDeniedException e) {
+          // excepted exception
+        }
+        // the user's name can't be empty
+        try {
+          client.listRolesByUserName(user3, "");
+          fail("SentryAccessDeniedException should be caught.");
+        } catch (SentryAccessDeniedException e) {
+          // excepted exception
+        }
+        client.revokeRoleFromUser(requestorUserName, user2, roleName3);
+        client.revokeRoleFromUsers(requestorUserName, roleName3, 
Sets.newHashSet(user4));
+        // test the result of revokeRoleFromUser() and revokeRoleFromUsers()
+        roles = client.listRolesByUserName(requestorUserName, user2);
+        assertEquals(1, roles.size());
+        for (TSentryRole role : roles) {
+          assertTrue(roleName2.equals(role.getRoleName()));
+        }
+        roles = client.listRolesByUserName(requestorUserName, user4);
+        assertEquals(0, roles.size());
+      }
+    });
+  }
+
+  @Test
+  public void testGranRevokePrivilegeForRoleWithUG() throws Exception {
+    runTestAsSubject(new TestOperation() {
+      @Override
+      public void runTestAsSubject() throws Exception {
+        String requestorUserName = ADMIN_USER;
+        Set<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP);
+        setLocalGroupMapping(requestorUserName, requestorUserGroupNames);
+
+        // user1_1->group1
+        // user1_2->group1
+        // user2_1->group2
+        // user2_2->group2
+        // group1->r1
+        // group2->r2
+        // user1_1->r3
+        // user2_1->r4
+        String roleName1 = "r1";
+        String roleName2 = "r2";
+        String roleName3 = "r3";
+        String roleName4 = "r4";
+        String user1_1 = "u1_1";
+        String user1_2 = "u1_2";
+        String user2_1 = "u2_1";
+        String user2_2 = "u2_2";
+        String group1 = "g1";
+        String group2 = "g2";
+        Map<String, String> userToGroup = Maps.newHashMap();
+        userToGroup.put(user1_1, group1);
+        userToGroup.put(user1_2, group1);
+        userToGroup.put(user2_1, group2);
+        userToGroup.put(user2_2, user2_1);
+
+        Set<String> groupSet = Sets.newHashSet(group1);
+        setLocalGroupMapping(user1_1, groupSet);
+        setLocalGroupMapping(user1_2, groupSet);
+        groupSet = Sets.newHashSet(group2);
+        setLocalGroupMapping(user2_1, groupSet);
+        setLocalGroupMapping(user2_2, groupSet);
+        writePolicyFile();
+
+        client.dropRoleIfExists(requestorUserName, roleName1);
+        client.dropRoleIfExists(requestorUserName, roleName2);
+        client.dropRoleIfExists(requestorUserName, roleName3);
+        client.dropRoleIfExists(requestorUserName, roleName4);
+        client.createRole(requestorUserName, roleName1);
+        client.createRole(requestorUserName, roleName2);
+        client.createRole(requestorUserName, roleName3);
+        client.createRole(requestorUserName, roleName4);
+
+        client.grantRoleToGroup(requestorUserName, group1, roleName1);
+        client.grantRoleToGroup(requestorUserName, group2, roleName2);
+        client.grantRoleToUser(requestorUserName, user1_1, roleName3);
+        client.grantRoleToUsers(requestorUserName, roleName4, 
Sets.newHashSet(user2_1));
+
+        client
+            .grantTablePrivilege(requestorUserName, roleName1, "server", 
"db1", "table1_1", "ALL");
+        client
+            .grantTablePrivilege(requestorUserName, roleName1, "server", 
"db1", "table1_2", "ALL");
+        client
+            .grantTablePrivilege(requestorUserName, roleName2, "server", 
"db1", "table2_1", "ALL");
+        client
+            .grantTablePrivilege(requestorUserName, roleName2, "server", 
"db1", "table2_2", "ALL");
+        client
+            .grantTablePrivilege(requestorUserName, roleName3, "server", 
"db1", "table3_1", "ALL");
+        client
+            .grantTablePrivilege(requestorUserName, roleName3, "server", 
"db1", "table3_2", "ALL");
+        client
+            .grantTablePrivilege(requestorUserName, roleName4, "server", 
"db1", "table4_1", "ALL");
+        client
+            .grantTablePrivilege(requestorUserName, roleName4, "server", 
"db1", "table4_2", "ALL");
+
+        Set<String> listPrivilegesForProvider = 
client.listPrivilegesForProvider(
+            Sets.newHashSet(group1), Sets.newHashSet(""), ActiveRoleSet.ALL, 
(Authorizable[]) null);
+        assertEquals("Privilege not correctly assigned to roles !!", 
Sets.newHashSet(
+            "server=server->db=db1->table=table1_1->action=all",
+            "server=server->db=db1->table=table1_2->action=all"), 
listPrivilegesForProvider);
+
+        listPrivilegesForProvider = client.listPrivilegesForProvider(
+            Sets.newHashSet(userToGroup.get(user1_2)),
+            Sets.newHashSet(user1_2), ActiveRoleSet.ALL, (Authorizable[]) 
null);
+        assertEquals("Privilege not correctly assigned to roles !!", 
Sets.newHashSet(
+            "server=server->db=db1->table=table1_1->action=all",
+            "server=server->db=db1->table=table1_2->action=all"), 
listPrivilegesForProvider);
+
+        listPrivilegesForProvider = client.listPrivilegesForProvider(
+            Sets.newHashSet(userToGroup.get(user1_1)),
+            Sets.newHashSet(user1_1), ActiveRoleSet.ALL, (Authorizable[]) 
null);
+        assertEquals("Privilege not correctly assigned to roles !!", 
Sets.newHashSet(
+            "server=server->db=db1->table=table1_1->action=all",
+            "server=server->db=db1->table=table1_2->action=all",
+            "server=server->db=db1->table=table3_1->action=all",
+            "server=server->db=db1->table=table3_2->action=all"), 
listPrivilegesForProvider);
+
+        listPrivilegesForProvider = 
client.listPrivilegesForProvider(Sets.newHashSet(group1),
+            Sets.newHashSet(user1_1, user1_2), ActiveRoleSet.ALL, 
(Authorizable[]) null);
+        assertEquals("Privilege not correctly assigned to roles !!", 
Sets.newHashSet(
+            "server=server->db=db1->table=table1_1->action=all",
+            "server=server->db=db1->table=table1_2->action=all",
+            "server=server->db=db1->table=table3_1->action=all",
+            "server=server->db=db1->table=table3_2->action=all"), 
listPrivilegesForProvider);
+
+        listPrivilegesForProvider = client.listPrivilegesForProvider(
+            Sets.newHashSet(group1, group2), Sets.newHashSet(user1_1, user1_2, 
user2_1, user2_2),
+            ActiveRoleSet.ALL, (Authorizable[]) null);
+        assertEquals("Privilege not correctly assigned to roles !!", 
Sets.newHashSet(
+            "server=server->db=db1->table=table1_1->action=all",
+            "server=server->db=db1->table=table1_2->action=all",
+            "server=server->db=db1->table=table2_1->action=all",
+            "server=server->db=db1->table=table2_2->action=all",
+            "server=server->db=db1->table=table3_1->action=all",
+            "server=server->db=db1->table=table3_2->action=all",
+            "server=server->db=db1->table=table4_1->action=all",
+            "server=server->db=db1->table=table4_2->action=all"), 
listPrivilegesForProvider);
+
+        client.revokeRoleFromUser(requestorUserName, user1_1, roleName3);
+        client.revokeRoleFromUsers(requestorUserName, roleName4, 
Sets.newHashSet(user2_1));
+      }
+    });
+  }
+
+  @Test
   public void testMultipleRolesSamePrivilege() throws Exception {
     runTestAsSubject(new TestOperation(){
       @Override

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/SimpleFileProviderBackend.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/SimpleFileProviderBackend.java
 
b/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/SimpleFileProviderBackend.java
index 884de16..8924657 100644
--- 
a/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/SimpleFileProviderBackend.java
+++ 
b/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/SimpleFileProviderBackend.java
@@ -156,6 +156,13 @@ public class SimpleFileProviderBackend implements 
ProviderBackend {
     return resultBuilder.build();
   }
 
+  @Override
+  public ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> 
users,
+      ActiveRoleSet roleSet, Authorizable... authorizableHierarchy) {
+    // SimpleFileProviderBackend doesn't support getPrivileges for user now.
+    return getPrivileges(groups, roleSet, authorizableHierarchy);
+  }
+
   /**
    * {@inheritDoc}
    */

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbDDLAuditLog.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbDDLAuditLog.java
 
b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbDDLAuditLog.java
index 3afd6b2..e105f00 100644
--- 
a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbDDLAuditLog.java
+++ 
b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbDDLAuditLog.java
@@ -61,6 +61,7 @@ public class TestDbDDLAuditLog extends 
AbstractTestWithStaticConfiguration {
   public void testBasic() throws Exception {
     String roleName = "testRole";
     String groupName = "testGroup";
+    String userName = "testUser";
     String dbName = "dbTest";
     String tableName = "tableTest";
     Connection connection = context.createConnection(ADMIN1);
@@ -84,9 +85,18 @@ public class TestDbDDLAuditLog extends 
AbstractTestWithStaticConfiguration {
     fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
     assertAuditLog(fieldValueMap);
 
+    statement.execute("GRANT ROLE " + roleName + " TO USER " + userName);
+    fieldValueMap.clear();
+    fieldValueMap.put(Constants.LOG_FIELD_OPERATION, 
Constants.OPERATION_ADD_ROLE_USER);
+    fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "GRANT ROLE " + 
roleName + " TO USER "
+        + userName);
+    fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE);
+    assertAuditLog(fieldValueMap);
+
     statement.execute("create database " + dbName);
     statement.execute("use " + dbName);
     statement.execute("CREATE TABLE " + tableName + " (c1 string)");
+
     statement.execute("GRANT ALL ON DATABASE " + dbName + " TO ROLE " + 
roleName);
     fieldValueMap.clear();
     fieldValueMap.put(Constants.LOG_FIELD_OPERATION, 
Constants.OPERATION_GRANT_PRIVILEGE);
@@ -210,6 +220,14 @@ public class TestDbDDLAuditLog extends 
AbstractTestWithStaticConfiguration {
     fieldValueMap.put(Constants.LOG_FIELD_IP_ADDRESS, null);
     assertAuditLog(fieldValueMap);
 
+    statement.execute("REVOKE ROLE " + roleName + " FROM USER " + userName);
+    fieldValueMap.clear();
+    fieldValueMap.put(Constants.LOG_FIELD_OPERATION, 
Constants.OPERATION_DELETE_ROLE_USER);
+    fieldValueMap.put(Constants.LOG_FIELD_OPERATION_TEXT, "REVOKE ROLE " + 
roleName + " FROM USER "
+        + userName);
+    fieldValueMap.put(Constants.LOG_FIELD_ALLOWED, Constants.TRUE);
+    assertAuditLog(fieldValueMap);
+
     statement.execute("DROP ROLE " + roleName);
     fieldValueMap.clear();
     fieldValueMap.put(Constants.LOG_FIELD_OPERATION, 
Constants.OPERATION_DROP_ROLE);

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestGrantUserToRole.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestGrantUserToRole.java
 
b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestGrantUserToRole.java
new file mode 100644
index 0000000..4ce30c1
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestGrantUserToRole.java
@@ -0,0 +1,237 @@
+/*
+ * 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.tests.e2e.dbprovider;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.Set;
+
+import org.apache.sentry.tests.e2e.hive.AbstractTestWithStaticConfiguration;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Sets;
+
+public class TestGrantUserToRole extends AbstractTestWithStaticConfiguration {
+
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(TestGrantUserToRole.class);
+
+  private static String ROLENAME1 = "testGrantUserToRole_r1";
+  private static String ROLENAME2 = "testGrantUserToRole_r2";
+  private static String ROLENAME3 = "testGrantUserToRole_r3";
+
+  @BeforeClass
+  public static void setupTestStaticConfiguration() throws Exception {
+    useSentryService = true;
+    AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
+  }
+
+  @Override
+  @Before
+  public void setup() throws Exception {
+    super.setupAdmin();
+    super.setup();
+    prepareTestData();
+  }
+
+  private void prepareTestData() throws Exception {
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+    statement.execute("CREATE ROLE " + ROLENAME1);
+    statement.execute("CREATE ROLE " + ROLENAME2);
+    statement.execute("CREATE ROLE " + ROLENAME3);
+    // grant role to groups and users as the following:
+    statement.execute("GRANT ROLE " + ROLENAME1 + " TO GROUP " + USERGROUP1);
+    statement.execute("GRANT ROLE " + ROLENAME2 + " TO GROUP " + USERGROUP2);
+    statement.execute("GRANT ROLE " + ROLENAME3 + " TO USER " + USER2_1);
+    statement.execute("GRANT ROLE " + ROLENAME2 + " TO USER " + USER3_1);
+    statement.execute("GRANT ROLE " + ROLENAME2 + " TO USER " + USER4_1);
+    statement.execute("GRANT ROLE " + ROLENAME3 + " TO USER " + USER4_1);
+    statement.close();
+    connection.close();
+  }
+
+  @Test
+  public void testAddDeleteRolesForUser() throws Exception {
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+    Set<String> emptyRoleSet = Sets.newHashSet();
+    // admin can get all roles for users
+    // user1 get the role1 for group1
+    ResultSet resultSet = statement.executeQuery("SHOW ROLE GRANT USER " + 
USER1_1);
+    verifyResultRoles(resultSet, emptyRoleSet);
+
+    // user2 get the role1 for group1 and role2 for user2
+    resultSet = statement.executeQuery("SHOW ROLE GRANT USER " + USER2_1);
+    verifyResultRoles(resultSet, Sets.newHashSet(ROLENAME3.toLowerCase()));
+
+    // user3 get the role1 for group1 and role2 for group2
+    resultSet = statement.executeQuery("SHOW ROLE GRANT USER " + USER3_1);
+    verifyResultRoles(resultSet, Sets.newHashSet(ROLENAME2.toLowerCase()));
+
+    // user4 get the role2 for group2 and group3, role3 for user4
+    resultSet = statement.executeQuery("SHOW ROLE GRANT USER " + USER4_1);
+    verifyResultRoles(resultSet, Sets.newHashSet(ROLENAME2.toLowerCase(), 
ROLENAME3.toLowerCase()));
+    statement.close();
+    connection.close();
+
+    connection = context.createConnection(USER1_1);
+    statement = context.createStatement(connection);
+    // user1 can show his own roles
+    resultSet = statement.executeQuery("SHOW ROLE GRANT USER " + USER1_1);
+    verifyResultRoles(resultSet, emptyRoleSet);
+    // test the command : show current roles
+    resultSet = statement.executeQuery("SHOW CURRENT ROLES");
+    verifyResultRoles(resultSet, Sets.newHashSet(ROLENAME1.toLowerCase()));
+
+    try {
+      // user1 can't show other's roles if he isn't an admin
+      resultSet = statement.executeQuery("SHOW ROLE GRANT USER " + USER2_1);
+      fail("Can't show other's role if the user is not an admin.");
+    } catch (Exception e) {
+      // excepted exception
+    }
+    statement.close();
+    connection.close();
+
+    connection = context.createConnection(USER2_1);
+    statement = context.createStatement(connection);
+    // user2 can show his own roles
+    resultSet = statement.executeQuery("SHOW ROLE GRANT USER " + USER2_1);
+    verifyResultRoles(resultSet, Sets.newHashSet(ROLENAME3.toLowerCase()));
+    // test the command : show current roles
+    resultSet = statement.executeQuery("SHOW CURRENT ROLES");
+    verifyResultRoles(resultSet, Sets.newHashSet(ROLENAME2.toLowerCase(), 
ROLENAME3.toLowerCase()));
+    statement.close();
+    connection.close();
+
+    connection = context.createConnection(ADMIN1);
+    statement = context.createStatement(connection);
+    // revoke the role from user
+    statement.execute("REVOKE ROLE " + ROLENAME3 + " FROM USER " + USER2_1);
+    statement.execute("REVOKE ROLE " + ROLENAME3 + " FROM USER " + USER4_1);
+
+    resultSet = statement.executeQuery("SHOW ROLE GRANT USER " + USER2_1);
+    verifyResultRoles(resultSet, emptyRoleSet);
+
+    resultSet = statement.executeQuery("SHOW ROLE GRANT USER " + USER4_1);
+    verifyResultRoles(resultSet, Sets.newHashSet(ROLENAME2.toLowerCase()));
+    statement.close();
+    connection.close();
+  }
+
+  @Test
+  public void testAuthorizationForUsersWithRoles() throws Exception {
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+    statement.execute("CREATE TABLE t1 (c1 string)");
+    statement.execute("CREATE TABLE t2 (c1 string)");
+    statement.execute("CREATE TABLE t3 (c1 string)");
+    statement.execute("GRANT SELECT ON TABLE t1 TO ROLE " + ROLENAME1);
+    statement.execute("GRANT SELECT ON TABLE t2 TO ROLE " + ROLENAME2);
+    statement.execute("GRANT SELECT ON TABLE t3 TO ROLE " + ROLENAME3);
+    statement.close();
+    connection.close();
+
+    // user1 can access the t1
+    connection = context.createConnection(USER1_1);
+    statement = context.createStatement(connection);
+    statement.execute("select c1 from t1");
+    try {
+      statement.execute("select c1 from t2");
+      fail("Can't access the table t2");
+    } catch (Exception e) {
+      // excepted exception
+    }
+    try {
+      statement.execute("select c1 from t3");
+      fail("Can't access the table t3");
+    } catch (Exception e) {
+      // excepted exception
+    }
+    statement.close();
+    connection.close();
+
+    // user2 can access the t2, t3
+    connection = context.createConnection(USER2_1);
+    statement = context.createStatement(connection);
+    try {
+      statement.execute("select c1 from t1");
+      fail("Can't access the table t1");
+    } catch (Exception e) {
+      // excepted exception
+    }
+    statement.execute("select c1 from t2");
+    statement.execute("select c1 from t3");
+    statement.close();
+    connection.close();
+
+    // user3 can access the t2
+    connection = context.createConnection(USER3_1);
+    statement = context.createStatement(connection);
+    try {
+      statement.execute("select c1 from t1");
+      fail("Can't access the table t1");
+    } catch (Exception e) {
+      // excepted exception
+    }
+    statement.execute("select c1 from t2");
+    try {
+      statement.execute("select c1 from t3");
+      fail("Can't access the table t3");
+    } catch (Exception e) {
+      // excepted exception
+    }
+    statement.close();
+    connection.close();
+
+    // user4 can access the t2,t3
+    connection = context.createConnection(USER4_1);
+    statement = context.createStatement(connection);
+    try {
+      statement.execute("select c1 from t1");
+      fail("Can't access the table t1");
+    } catch (Exception e) {
+      // excepted exception
+    }
+    statement.execute("select c1 from t2");
+    statement.execute("select c1 from t3");
+    statement.close();
+    connection.close();
+  }
+
+  private void verifyResultRoles(ResultSet resultSet, Set<String> 
exceptedRoles) throws Exception {
+    int size = 0;
+    while (resultSet.next()) {
+      String tempRole = resultSet.getString(1);
+      LOGGER.debug("tempRole:" + tempRole);
+      assertTrue(exceptedRoles.contains(tempRole));
+      size++;
+    }
+    assertEquals(exceptedRoles.size(), size);
+    resultSet.close();
+  }
+}

Reply via email to