Repository: sentry
Updated Branches:
  refs/heads/master 4d9bc9cea -> 3278c714c


SENTRY-2251: Update user privileges based on changes to authorizables (Kalyan 
Kumar Kalvagadda reviewed by Sergio Pena and Arjun Mishra)


Project: http://git-wip-us.apache.org/repos/asf/sentry/repo
Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/3278c714
Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/3278c714
Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/3278c714

Branch: refs/heads/master
Commit: 3278c714c490d505b84b798bb9b77732f7f7ef7f
Parents: 4d9bc9c
Author: Kalyan Kumar Kalvagadda <kkal...@cloudera.com>
Authored: Fri Jun 22 15:17:55 2018 -0500
Committer: Kalyan Kumar Kalvagadda <kkal...@cloudera.com>
Committed: Fri Jun 22 15:17:55 2018 -0500

----------------------------------------------------------------------
 .../db/service/persistent/SentryStore.java      | 78 ++++++++++----------
 .../db/service/persistent/TestSentryStore.java  | 42 ++++++++++-
 2 files changed, 80 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/sentry/blob/3278c714/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
index 27b8876..aca5c2d 100644
--- 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
@@ -1154,11 +1154,10 @@ public class SentryStore {
     }
 
     if 
(requestedPrivToRevoke.getAction().equalsIgnoreCase(AccessConstants.ALL) ||
-      
requestedPrivToRevoke.getAction().equalsIgnoreCase(AccessConstants.ACTION_ALL)) 
{
-      if (!persistedPriv.getRoles().isEmpty()) {
-        if (mEntity != null) {
-          persistedPriv.removeEntity(mEntity);
-        }
+            
requestedPrivToRevoke.getAction().equalsIgnoreCase(AccessConstants.ACTION_ALL)) 
{
+      if ((!persistedPriv.getRoles().isEmpty() || 
!persistedPriv.getUsers().isEmpty()) &&
+              mEntity != null) {
+        persistedPriv.removeEntity(mEntity);
         persistPrivilege(pm, persistedPriv);
       }
     } else {
@@ -2614,7 +2613,7 @@ public class SentryStore {
   }
 
   /**
-   * Drop the given privilege from all roles.
+   * Drop the given privilege from all entities.
    *
    * @param tAuthorizable the given authorizable object.
    * @throws Exception
@@ -2624,17 +2623,17 @@ public class SentryStore {
             pm -> {
               pm.setDetachAllOnCommit(false); // No need to detach objects
 
-              // Drop the give privilege for all possible actions from all 
roles.
+              // Drop the give privilege for all possible actions from all 
entities.
               TSentryPrivilege tPrivilege = toSentryPrivilege(tAuthorizable);
 
               try {
                 if (isMultiActionsSupported(tPrivilege)) {
                   for (String privilegeAction : ALL_ACTIONS) {
                     tPrivilege.setAction(privilegeAction);
-                    dropPrivilegeForAllRoles(pm, new 
TSentryPrivilege(tPrivilege));
+                    dropPrivilegeForAllEntities(pm, new 
TSentryPrivilege(tPrivilege));
                   }
                 } else {
-                  dropPrivilegeForAllRoles(pm, new 
TSentryPrivilege(tPrivilege));
+                  dropPrivilegeForAllEntities(pm, new 
TSentryPrivilege(tPrivilege));
                 }
               } catch (JDODataStoreException e) {
                 throw new SentryInvalidInputException("Failed to get 
privileges: "
@@ -2645,7 +2644,7 @@ public class SentryStore {
   }
 
   /**
-   * Drop the given privilege from all roles. As well as persist the 
corresponding
+   * Drop the given privilege from all entities. As well as persist the 
corresponding
    * permission change to MSentryPermChange table in a single transaction.
    *
    * @param tAuthorizable the given authorizable object.
@@ -2657,17 +2656,17 @@ public class SentryStore {
     execute(update, pm -> {
       pm.setDetachAllOnCommit(false); // No need to detach objects
 
-      // Drop the give privilege for all possible actions from all roles.
+      // Drop the give privilege for all possible actions from all entities.
       TSentryPrivilege tPrivilege = toSentryPrivilege(tAuthorizable);
 
       try {
         if (isMultiActionsSupported(tPrivilege)) {
           for (String privilegeAction : ALL_ACTIONS) {
             tPrivilege.setAction(privilegeAction);
-            dropPrivilegeForAllRoles(pm, new TSentryPrivilege(tPrivilege));
+            dropPrivilegeForAllEntities(pm, new TSentryPrivilege(tPrivilege));
           }
         } else {
-          dropPrivilegeForAllRoles(pm, new TSentryPrivilege(tPrivilege));
+          dropPrivilegeForAllEntities(pm, new TSentryPrivilege(tPrivilege));
         }
       } catch (JDODataStoreException e) {
         throw new SentryInvalidInputException("Failed to get privileges: "
@@ -2750,7 +2749,7 @@ public class SentryStore {
   }
 
   /**
-   * Rename the privilege for all roles. Drop the old privilege name and 
create the new one.
+   * Rename the privilege for all entities. Drop the old privilege name and 
create the new one.
    *
    * @param oldTAuthorizable the old authorizable name needs to be renamed.
    * @param newTAuthorizable the new authorizable name
@@ -2763,7 +2762,7 @@ public class SentryStore {
             pm -> {
               pm.setDetachAllOnCommit(false); // No need to detach objects
 
-              // Drop the give privilege for all possible actions from all 
roles.
+              // Drop the give privilege for all possible actions from all 
entities.
               TSentryPrivilege tPrivilege = 
toSentryPrivilege(oldTAuthorizable);
               TSentryPrivilege newPrivilege = 
toSentryPrivilege(newTAuthorizable);
 
@@ -2773,10 +2772,10 @@ public class SentryStore {
                   for (String privilegeAction : ALL_ACTIONS) {
                     tPrivilege.setAction(privilegeAction);
                     newPrivilege.setAction(privilegeAction);
-                    renamePrivilegeForAllRoles(pm, tPrivilege, newPrivilege);
+                    renamePrivilegeForAllEntities(pm, tPrivilege, 
newPrivilege);
                   }
                 } else {
-                  renamePrivilegeForAllRoles(pm, tPrivilege, newPrivilege);
+                  renamePrivilegeForAllEntities(pm, tPrivilege, newPrivilege);
                 }
               } catch (JDODataStoreException e) {
                 throw new SentryInvalidInputException("Failed to get 
privileges: "
@@ -2787,7 +2786,7 @@ public class SentryStore {
   }
 
   /**
-   * Rename the privilege for all roles. Drop the old privilege name and 
create the new one.
+   * Rename the privilege for all entities. Drop the old privilege name and 
create the new one.
    * As well as persist the corresponding permission change to 
MSentryPermChange table in a
    * single transaction.
    *
@@ -2804,7 +2803,7 @@ public class SentryStore {
     execute(update, pm -> {
       pm.setDetachAllOnCommit(false); // No need to detach objects
 
-      // Drop the give privilege for all possible actions from all roles.
+      // Drop the give privilege for all possible actions from all entities.
       TSentryPrivilege tPrivilege = toSentryPrivilege(oldTAuthorizable);
       TSentryPrivilege newPrivilege = toSentryPrivilege(newTAuthorizable);
 
@@ -2814,10 +2813,10 @@ public class SentryStore {
           for (String privilegeAction : ALL_ACTIONS) {
             tPrivilege.setAction(privilegeAction);
             newPrivilege.setAction(privilegeAction);
-            renamePrivilegeForAllRoles(pm, tPrivilege, newPrivilege);
+            renamePrivilegeForAllEntities(pm, tPrivilege, newPrivilege);
           }
         } else {
-          renamePrivilegeForAllRoles(pm, tPrivilege, newPrivilege);
+          renamePrivilegeForAllEntities(pm, tPrivilege, newPrivilege);
         }
       } catch (JDODataStoreException e) {
         throw new SentryInvalidInputException("Failed to get privileges: "
@@ -2833,45 +2832,46 @@ public class SentryStore {
 
   }
   // wrapper for dropOrRename
-  private void renamePrivilegeForAllRoles(PersistenceManager pm,
+  private void renamePrivilegeForAllEntities(PersistenceManager pm,
       TSentryPrivilege tPrivilege,
       TSentryPrivilege newPrivilege) throws SentryNoSuchObjectException,
       SentryInvalidInputException {
-    dropOrRenamePrivilegeForAllRoles(pm, tPrivilege, newPrivilege);
+    dropOrRenamePrivilegeForAllEntities(pm, tPrivilege, newPrivilege);
   }
 
   /**
-   * Drop given privilege from all roles
+   * Drop given privilege from all entities
    * @param tPrivilege
    * @throws SentryNoSuchObjectException
    * @throws SentryInvalidInputException
    */
-  private void dropPrivilegeForAllRoles(PersistenceManager pm,
+  private void dropPrivilegeForAllEntities(PersistenceManager pm,
       TSentryPrivilege tPrivilege)
       throws SentryNoSuchObjectException, SentryInvalidInputException {
-    dropOrRenamePrivilegeForAllRoles(pm, tPrivilege, null);
+    dropOrRenamePrivilegeForAllEntities(pm, tPrivilege, null);
   }
 
   /**
-   * Drop given privilege from all roles Create the new privilege if asked
+   * Drop given privilege from all entities Create the new privilege if asked
    * @param tPrivilege
    * @param pm
    * @throws SentryNoSuchObjectException
    * @throws SentryInvalidInputException
    */
-  private void dropOrRenamePrivilegeForAllRoles(PersistenceManager pm,
+  private void dropOrRenamePrivilegeForAllEntities(PersistenceManager pm,
       TSentryPrivilege tPrivilege,
       TSentryPrivilege newTPrivilege) throws SentryNoSuchObjectException,
       SentryInvalidInputException {
-    Collection<MSentryRole> roleSet = new HashSet<>();
+    Collection<PrivilegeEntity> entitySet = new HashSet<>();
     List<MSentryPrivilege> mPrivileges = getMSentryPrivileges(tPrivilege, pm);
     for (MSentryPrivilege mPrivilege : mPrivileges) {
-      roleSet.addAll(ImmutableSet.copyOf(mPrivilege.getRoles()));
+      entitySet.addAll(ImmutableSet.copyOf(mPrivilege.getRoles()));
+      entitySet.addAll(ImmutableSet.copyOf(mPrivilege.getUsers()));
     }
     // Dropping the privilege
     if (newTPrivilege == null) {
-      for (MSentryRole role : roleSet) {
-        alterSentryRevokePrivilegeCore(pm, SentryEntityType.ROLE, 
role.getRoleName(), tPrivilege);
+      for (PrivilegeEntity entity : entitySet) {
+        alterSentryRevokePrivilegeCore(pm, entity.getType(), 
entity.getEntityName(), tPrivilege);
       }
       return;
     }
@@ -2885,18 +2885,22 @@ public class SentryStore {
       // dereferenced. If object has to be used even after that it should have 
been detached.
       parent = pm.detachCopy(parent);
     }
-    for (MSentryRole role : roleSet) {
+    for (PrivilegeEntity entity : entitySet) {
+      // When all the privilege associated for a user are revoked, user will 
be removed from the database.
+      // JDO object should be not used when the associated database entry is 
removed. Application should use
+      // a detached copy instead.
+      PrivilegeEntity detachedEntity = pm.detachCopy(entity);
       // 1. get privilege and child privileges
       Collection<MSentryPrivilege> privilegeGraph = new HashSet<>();
       if (parent != null) {
         privilegeGraph.add(parent);
-        populateChildren(pm, SentryEntityType.ROLE, 
Sets.newHashSet(role.getRoleName()), parent, privilegeGraph);
+        populateChildren(pm, detachedEntity.getType(), 
Sets.newHashSet(detachedEntity.getEntityName()), parent, privilegeGraph);
       } else {
-        populateChildren(pm, SentryEntityType.ROLE, 
Sets.newHashSet(role.getRoleName()), convertToMSentryPrivilege(tPrivilege),
+        populateChildren(pm, detachedEntity.getType(), 
Sets.newHashSet(detachedEntity.getEntityName()), 
convertToMSentryPrivilege(tPrivilege),
           privilegeGraph);
       }
       // 2. revoke privilege and child privileges
-      alterSentryRevokePrivilegeCore(pm, SentryEntityType.ROLE, 
role.getRoleName(), tPrivilege);
+      alterSentryRevokePrivilegeCore(pm, detachedEntity.getType(), 
detachedEntity.getEntityName(), tPrivilege);
       // 3. add new privilege and child privileges with new tableName
       for (MSentryPrivilege mPriv : privilegeGraph) {
         TSentryPrivilege tPriv = convertToTSentryPrivilege(mPriv);
@@ -2907,7 +2911,7 @@ public class SentryStore {
           tPriv.setDbName(newTPrivilege.getDbName());
           tPriv.setTableName(newTPrivilege.getTableName());
         }
-        alterSentryGrantPrivilegeCore(pm, SentryEntityType.ROLE, 
role.getRoleName(), tPriv);
+        alterSentryGrantPrivilegeCore(pm, detachedEntity.getType(), 
detachedEntity.getEntityName(), tPriv);
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/sentry/blob/3278c714/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
index 51048bc..475fc4e 100644
--- 
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
@@ -1905,17 +1905,20 @@ public class TestSentryStore extends org.junit.Assert {
   }
 
   /**
-   * Assign multiple table and SERVER privileges to roles
-   * drop privilege for the object verify that it's removed correctl
+   * Assign multiple table and SERVER privileges to roles and users
+   * drop privilege for the object verify that it's removed correctly
    * @throws Exception
    */
   @Test
   public void testDropDbObject() throws Exception {
     String roleName1 = "list-privs-r1", roleName2 = "list-privs-r2", roleName3 
= "list-privs-r3";
+    String userName1 = "user-1", userName2 = "user-2";
     String grantor = "g1";
     sentryStore.createSentryRole(roleName1);
     sentryStore.createSentryRole(roleName2);
     sentryStore.createSentryRole(roleName3);
+    sentryStore.createSentryUser(userName1);
+    sentryStore.createSentryUser(userName2);
 
     TSentryPrivilege privilege_tbl1 = new TSentryPrivilege();
     privilege_tbl1.setPrivilegeScope("TABLE");
@@ -1959,6 +1962,10 @@ public class TestSentryStore extends org.junit.Assert {
     sentryStore.alterSentryGrantPrivilege(grantor, SentryEntityType.ROLE, 
roleName3, privilege3_1, null);
     sentryStore.alterSentryGrantPrivilege(grantor, SentryEntityType.ROLE, 
roleName3, privilege3_2, null);
 
+    sentryStore.alterSentryGrantPrivilege(grantor, SentryEntityType.USER, 
userName1, privilege1, null);
+    sentryStore.alterSentryGrantPrivilege(grantor, SentryEntityType.USER, 
userName2, privilege2_3, null);
+
+
     sentryStore.dropPrivilege(toTSentryAuthorizable(privilege_tbl1));
     assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1)
         .size());
@@ -1967,6 +1974,15 @@ public class TestSentryStore extends org.junit.Assert {
     assertEquals(1, sentryStore.getAllTSentryPrivilegesByRoleName(roleName3)
         .size());
 
+
+    try {
+      sentryStore.getAllTSentryPrivilegesByUserName(userName1);
+      fail("Should have received an exception");
+    } catch (Exception e) {
+
+    }
+    assertEquals(1, sentryStore.getAllTSentryPrivilegesByUserName(userName2)
+            .size());
     sentryStore.dropPrivilege(toTSentryAuthorizable(privilege_tbl2));
     assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1)
         .size());
@@ -1974,6 +1990,11 @@ public class TestSentryStore extends org.junit.Assert {
         .size());
     assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName3)
         .size());
+    try {
+      sentryStore.getAllTSentryPrivilegesByUserName(userName2);
+      fail("Should have received an exception");
+    } catch (Exception e) {
+    }
   }
 
   /**
@@ -2320,19 +2341,23 @@ public class TestSentryStore extends org.junit.Assert {
   }
 
   /***
-   * Create roles and assign privileges for same table rename the privileges 
for
+   * Create roles and users and assign privileges for same table rename the 
privileges for
    * the table and verify the new privileges
    * @throws Exception
    */
   @Test
   public void testRenameTable() throws Exception {
     String roleName1 = "role1", roleName2 = "role2", roleName3 = "role3";
+    String userName1 = "user-1", userName2 = "user-2", userName3 = "user-3";
     String grantor = "g1";
     String table1 = "tbl1", table2 = "tbl2";
 
     sentryStore.createSentryRole(roleName1);
     sentryStore.createSentryRole(roleName2);
     sentryStore.createSentryRole(roleName3);
+    sentryStore.createSentryUser(userName1);
+    sentryStore.createSentryUser(userName2);
+    sentryStore.createSentryUser(userName3);
 
     TSentryPrivilege privilege_tbl1 = new TSentryPrivilege();
     privilege_tbl1.setPrivilegeScope("TABLE");
@@ -2355,6 +2380,9 @@ public class TestSentryStore extends org.junit.Assert {
     sentryStore.alterSentryGrantPrivilege(grantor, SentryEntityType.ROLE, 
roleName1, privilege_tbl1_insert, null);
     sentryStore.alterSentryGrantPrivilege(grantor, SentryEntityType.ROLE, 
roleName2, privilege_tbl1_select, null);
     sentryStore.alterSentryGrantPrivilege(grantor, SentryEntityType.ROLE, 
roleName3, privilege_tbl1_all, null);
+    sentryStore.alterSentryGrantPrivilege(grantor, SentryEntityType.USER, 
userName1, privilege_tbl1_insert, null);
+    sentryStore.alterSentryGrantPrivilege(grantor, SentryEntityType.USER, 
userName2, privilege_tbl1_select, null);
+    sentryStore.alterSentryGrantPrivilege(grantor, SentryEntityType.USER, 
userName3, privilege_tbl1_all, null);
 
     TSentryAuthorizable oldTable = toTSentryAuthorizable(privilege_tbl1);
     TSentryAuthorizable newTable = toTSentryAuthorizable(privilege_tbl1);
@@ -2369,6 +2397,14 @@ public class TestSentryStore extends org.junit.Assert {
         assertTrue(table2.equalsIgnoreCase(privilege.getTableName()));
       }
     }
+    for (String userName : Sets.newHashSet(userName1, userName2, userName3)) {
+      Set<TSentryPrivilege> privilegeSet = sentryStore
+              .getAllTSentryPrivilegesByUserName(userName);
+      assertEquals(1, privilegeSet.size());
+      for (TSentryPrivilege privilege : privilegeSet) {
+        assertTrue(table2.equalsIgnoreCase(privilege.getTableName()));
+      }
+    }
   }
 
   /**

Reply via email to