You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by ka...@apache.org on 2019/01/18 19:48:11 UTC

[sentry] branch master updated: SENTRY-2454: Add new sentry store api to gather the privileges for a list of authorizables. (Kalyan Kumar Kalvagadda reviewed by Na Li)

This is an automated email from the ASF dual-hosted git repository.

kalyan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sentry.git


The following commit(s) were added to refs/heads/master by this push:
     new 365e73b  SENTRY-2454: Add new sentry store api to gather the privileges for a list of authorizables. (Kalyan Kumar Kalvagadda reviewed by Na Li)
365e73b is described below

commit 365e73b09c8b95c510250866a11039fde77a5039
Author: Kalyan Kumar Kalvagadda <kk...@cloudera.com>
AuthorDate: Fri Jan 18 13:23:48 2019 -0600

    SENTRY-2454: Add new sentry store api to gather the privileges for a list of authorizables. (Kalyan Kumar Kalvagadda reviewed by Na Li)
---
 .../db/service/persistent/SentryStore.java         |  64 +++++++++
 .../service/persistent/SentryStoreInterface.java   |  11 ++
 .../db/service/persistent/TestSentryStore.java     | 157 +++++++++++++++++++++
 3 files changed, 232 insertions(+)

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 63f5375..ad5a4d0 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
@@ -3931,6 +3931,70 @@ public class SentryStore implements SentryStoreInterface {
   }
 
   /**
+   * @return Privileges granted to Authoriable and it's children.
+   * If the authorizable is server, returns all the privileges granted on that server
+   * If the authorizable is database,returns all the privileges granted on that database and also the tables and
+   * the columns in it.
+   * If the authorizable is an URI, returns all the privileges granted on URI's with the given prefix.
+   */
+  public List<MSentryPrivilege> getPrivilegesForAuthorizables(List<TSentryAuthorizable> authHierarchyList) throws Exception {
+    return tm.executeTransaction(
+            pm -> getPrivilegesForAuthorizables(pm, authHierarchyList)
+    );
+  }
+
+  /**
+   * @return Privileges granted to Authoriables and it's children.
+   * If the authorizable is server, returns all the privileges granted on that server
+   * If the authorizable is database,returns all the privileges granted on that database and also the tables and
+   * the columns in it.
+   * If the authorizable is an URI, returns all the privileges granted on URI's with the given prefix.
+   * If the authHierarchyList is Null or Empty, all the privileges in the sentry store are returned.
+   */
+  private List<MSentryPrivilege> getPrivilegesForAuthorizables(PersistenceManager pm,
+      List<TSentryAuthorizable> authHierarchyList) throws Exception {
+    List<MSentryPrivilege> mSentryPrivileges = Lists.newArrayList();
+    pm.setDetachAllOnCommit(false); // No need to detach objects
+    Query query = pm.newQuery(MSentryPrivilege.class);
+    query.addExtension(LOAD_RESULTS_AT_COMMIT, "false");
+    FetchGroup grp = pm.getFetchGroup(MSentryPrivilege.class, "fetchPrincipals");
+    grp.addMember("roles");
+    grp.addMember("users");
+    pm.getFetchPlan().addGroup("fetchPrincipals");
+
+    // When the list is empty or NULL return every thing.
+    if(authHierarchyList == null || authHierarchyList.isEmpty()) {
+      mSentryPrivileges.addAll((List<MSentryPrivilege>) query.execute());
+      return mSentryPrivileges;
+    }
+
+    for (TSentryAuthorizable authHierarchy : authHierarchyList) {
+      QueryParamBuilder authParamBuilder = QueryParamBuilder.newQueryParamBuilder(QueryParamBuilder.Op.AND);
+      if (authHierarchy.getServer() != null) {
+        authParamBuilder.add(SERVER_NAME, authHierarchy.getServer());
+        if (authHierarchy.getDb() != null) {
+          authParamBuilder.add(DB_NAME, authHierarchy.getDb()).addNull(URI);
+          if (authHierarchy.getTable() != null) {
+            authParamBuilder.add(TABLE_NAME, authHierarchy.getTable());
+            if (authHierarchy.getColumn() != null) {
+              authParamBuilder.add(COLUMN_NAME, authHierarchy.getColumn());
+            }
+          }
+        } else if (authHierarchy.getUri() != null) {
+          authParamBuilder.addNotNull(URI)
+                  .addNotNull(URI)
+                  .addNull(DB_NAME)
+                  .addCustomParam("(URI.startsWith(:authURI))", "authURI", authHierarchy.getUri());
+        }
+      }
+
+      query.setFilter(authParamBuilder.toString());
+      mSentryPrivileges.addAll((List<MSentryPrivilege>) query.executeWithMap(authParamBuilder.getArguments()));
+    }
+    return mSentryPrivileges;
+  }
+
+  /**
    * @return mapping data for [role,privilege] with the specific auth object
    */
   public Map<String, Set<TSentryPrivilege>> getRoleNameTPrivilegesMap(final String dbName,
diff --git a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreInterface.java b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreInterface.java
index 85ea6d1..84cb868 100644
--- a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreInterface.java
+++ b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreInterface.java
@@ -148,6 +148,17 @@ public interface SentryStoreInterface {
   void dropSentryRole(final String roleName) throws Exception;
 
   /**
+   * Get all the privileges granted to Authoriables and it's children.
+   * @param authHierarchyList List of Authorizables
+   * @return Privileges granted to Authoriables and it's children.
+   * If the authorizable is server, returns all the privileges granted on that server
+   * If the authorizable is database,returns all the privileges granted on that database and also the tables and
+   * the columns in it.
+   * If the authorizable is an URI, returns all the privileges granted on URI's with the given prefix.
+   */
+   List<MSentryPrivilege> getPrivilegesForAuthorizables(List<TSentryAuthorizable> authHierarchyList) throws Exception;
+
+  /**
    * Get role names for groups.
    * @param groups the given group names
    * @return set of role names for the given groups.
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 b327e9e..202e959 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
@@ -1829,6 +1829,150 @@ public class TestSentryStore extends org.junit.Assert {
             .size());
   }
 
+
+  @Test
+  public void testgetPrivilegesForAuthorizables() throws Exception {
+
+    String roleName1 = "list-privs-r1";
+    String userName1 = "user1";
+    String uri1 = "file:///var/folders/dt/9zm44z9s6bjfxbrm4v36lzdc0000gp/T/1401860678102-0/data/kv1.dat";
+
+    sentryStore.createSentryRole(roleName1);
+    sentryStore.createSentryUser(userName1);
+
+    TSentryPrivilege privilege_tbl1 = new TSentryPrivilege();
+    privilege_tbl1.setPrivilegeScope("TABLE");
+    privilege_tbl1.setServerName("server1");
+    privilege_tbl1.setDbName("db1");
+    privilege_tbl1.setTableName("tbl1");
+    privilege_tbl1.setCreateTime(System.currentTimeMillis());
+    privilege_tbl1.setAction("SELECT");
+    privilege_tbl1.setGrantOption(TSentryGrantOption.TRUE);
+
+    TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
+    tSentryAuthorizable.setServer("server1");
+    tSentryAuthorizable.setDb("db1");
+    tSentryAuthorizable.setTable("tbl1");
+
+
+    TSentryPrivilege privilege_tbl2 = new TSentryPrivilege();
+    privilege_tbl2.setPrivilegeScope("TABLE");
+    privilege_tbl2.setServerName("server1");
+    privilege_tbl2.setDbName("db1");
+    privilege_tbl2.setTableName("tbl2");
+    privilege_tbl2.setCreateTime(System.currentTimeMillis());
+    privilege_tbl2.setAction("SELECT");
+    privilege_tbl2.setGrantOption(TSentryGrantOption.TRUE);
+
+    TSentryAuthorizable tSentryAuthorizable2 = new TSentryAuthorizable();
+    tSentryAuthorizable2.setServer("server1");
+    tSentryAuthorizable2.setDb("db1");
+    tSentryAuthorizable2.setTable("tbl2");
+
+    TSentryPrivilege privilege_col1 = new TSentryPrivilege(privilege_tbl2);
+    privilege_col1.setPrivilegeScope("TABLE");
+    privilege_col1.setServerName("server1");
+    privilege_col1.setDbName("db3");
+    privilege_col1.setTableName("tbl3");
+    privilege_col1.setCreateTime(System.currentTimeMillis());
+    privilege_col1.setAction("SELECT");
+    privilege_col1.setGrantOption(TSentryGrantOption.TRUE);
+    privilege_col1.setColumnName("Column1");
+
+    TSentryAuthorizable tSentryAuthorizable3 = new TSentryAuthorizable();
+    tSentryAuthorizable3.setServer("server1");
+    tSentryAuthorizable3.setDb("db3");
+    tSentryAuthorizable3.setTable("tbl3");
+    tSentryAuthorizable3.setColumn("Column1");
+
+    TSentryPrivilege tSentryUriPrivilege = new TSentryPrivilege("URI", "server1", "ALL");
+    tSentryUriPrivilege.setURI(uri1);
+
+    TSentryAuthorizable tSentryUriAuthorizable = new TSentryAuthorizable();
+    tSentryUriAuthorizable.setUri(uri1);
+    tSentryUriAuthorizable.setServer("server1");
+
+
+    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1,privilege_tbl2, privilege_col1, tSentryUriPrivilege), null);
+
+    // Verify the privilege count
+    List<MSentryPrivilege> privilege = sentryStore.getPrivilegesForAuthorizables(Lists.newArrayList(tSentryAuthorizable,tSentryAuthorizable2, tSentryUriAuthorizable, tSentryAuthorizable3));
+    assertEquals(4, privilege.size());
+
+   // Verify the behavior when the empty authorizable list provided.
+   privilege = sentryStore.getPrivilegesForAuthorizables(Collections.EMPTY_LIST);
+   assertNotNull(privilege);
+   assertEquals(4, privilege.size());
+
+    // Verify the behvaior when the authorizable list is null.
+    privilege = sentryStore.getPrivilegesForAuthorizables(null);
+    assertNotNull(privilege);
+    assertEquals(4, privilege.size());
+
+    // Verify the privilege granted to URI is returned
+    privilege = sentryStore.getPrivilegesForAuthorizables(Lists.newArrayList(tSentryAuthorizable2));
+    assertEquals(1, privilege.size());
+
+
+    TSentryAuthorizable tSentrDbAuthorizable = new TSentryAuthorizable();
+    tSentrDbAuthorizable.setServer("server1");
+    tSentrDbAuthorizable.setDb("db1");
+
+    // Verify that all the privileges granted to tables in database db1 are returned.
+    privilege = sentryStore.getPrivilegesForAuthorizables(Lists.newArrayList(tSentrDbAuthorizable));
+    assertEquals(2, privilege.size());
+
+
+    // Verify that all the privileges granted to server are returned.
+    privilege = sentryStore.getPrivilegesForAuthorizables(Lists.newArrayList(tSentryAuthorizable3));
+    assertEquals(1, privilege.size());
+
+    TSentryAuthorizable tSentrServerAuthorizable = new TSentryAuthorizable();
+    tSentrServerAuthorizable.setServer("server1");
+
+    // Verify that all the privileges granted to server are returned.
+    privilege = sentryStore.getPrivilegesForAuthorizables(Lists.newArrayList(tSentrServerAuthorizable));
+    assertEquals(4, privilege.size());
+
+    // Grant user1 same privileges granted to role1 and make sure that there are no duplicates in the privileges.
+    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, userName1, Sets.newHashSet(privilege_tbl1,privilege_tbl2, tSentryUriPrivilege), null);
+
+    // Verify that all the privileges granted to server are returned.
+    privilege = sentryStore.getPrivilegesForAuthorizables(Lists.newArrayList(tSentrServerAuthorizable));
+    assertEquals(4, privilege.size());
+  }
+
+
+  @Test
+  public void testgetPrivilegesForURIs() throws Exception {
+
+    String roleName1 = "list-privs-r1";
+    String uriPrefix = "file:///var/folders/dt/9zm44z9s6bjfxbrm4v36lzdc0000gp/T/1401860678102-0/";
+    String uri1 = "file:///var/folders/dt/9zm44z9s6bjfxbrm4v36lzdc0000gp/T/1401860678102-0/data/kv1.dat";
+    String uri2 = "file:///var/folders/dt/9zm44z9s6bjfxbrm4v36lzdc0000gp/T/1401860678102-0/data/kv2.dat";
+
+
+    sentryStore.createSentryRole(roleName1);
+
+    TSentryPrivilege tSentryUriPrivilege1 = new TSentryPrivilege("URI", "server1", "ALL");
+    tSentryUriPrivilege1.setURI(uri1);
+
+    TSentryPrivilege tSentryUriPrivilege2 = new TSentryPrivilege("URI", "server1", "ALL");
+    tSentryUriPrivilege2.setURI(uri2);
+
+    TSentryAuthorizable tSentryUriAuthorizable = new TSentryAuthorizable();
+    tSentryUriAuthorizable.setUri(uriPrefix);
+    tSentryUriAuthorizable.setServer("server1");
+
+
+    // Grant user1 same privileges granted to role1 and make sure that there are no duplicates in the privileges.
+    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(tSentryUriPrivilege1, tSentryUriPrivilege2), null);
+
+    // Verify that all the privileges granted to all the URI;s under given prefix are returned.
+    List<MSentryPrivilege> privilege = sentryStore.getPrivilegesForAuthorizables(Lists.newArrayList(tSentryUriAuthorizable));
+    assertEquals(2, privilege.size());
+  }
+
   @Test
   public void testDropUserOnUpdateOwnerPrivilege() throws Exception {
     String userName1 = "user1", userName2 = "user2";
@@ -3089,6 +3233,19 @@ public class TestSentryStore extends org.junit.Assert {
     assertEquals("(e1 && e2 && (this.v3 == :v3 || this.v4 == :v4 || (e5 && e6)))",
             paramBuilder.toString());
 
+
+    paramBuilder = newQueryParamBuilder();
+    paramBuilder
+            .addString("e1")
+            .addString("e2")
+            .newChild()
+            .add("v3", "e3")
+            .add("v4", "e4")
+            .newChild()
+            .addString("e5")
+            .addString("e6")
+    ;
+
     params = paramBuilder.getArguments();
     assertEquals("e3", params.get("v3"));
     assertEquals("e4", params.get("v4"));