sentry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From co...@apache.org
Subject [01/18] sentry git commit: SENTRY-1291: SimpleCacheProviderBackend.getPrivileges should return the permission based on authorizationhierarchy (Hao Hao, Reviewed by: Lenni Kuff, Colin Ma)
Date Mon, 13 Jun 2016 02:52:05 GMT
Repository: sentry
Updated Branches:
  refs/heads/SENTRY-1205 8f453adfc -> 38098b461


SENTRY-1291: SimpleCacheProviderBackend.getPrivileges should return the permission based on
authorizationhierarchy (Hao Hao, Reviewed by: Lenni Kuff, Colin Ma)

Change-Id: I8e69f9f55c2a63a718eb5e63bd75ee2070735cab


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

Branch: refs/heads/SENTRY-1205
Commit: 42744cc97918fdd528a53745b7518957edd1506d
Parents: 8f453ad
Author: hahao <hao.hao@cloudera.com>
Authored: Wed Jun 1 14:40:49 2016 -0700
Committer: hahao <hao.hao@cloudera.com>
Committed: Wed Jun 1 14:40:49 2016 -0700

----------------------------------------------------------------------
 .../hive/TestCommonPrivilegeForHive.java        |  19 ++-
 .../kafka/TestKafkaWildcardPrivilege.java       |   7 +
 .../solr/TestCommonPrivilegeForSearch.java      |   7 +
 .../sqoop/TestCommonPrivilegeForSqoop.java      |   7 +
 .../sentry/policy/common/CommonPrivilege.java   |  18 +++
 .../apache/sentry/policy/common/Privilege.java  |  14 ++
 .../engine/common/CommonPolicyEngine.java       |   4 +-
 .../indexer/IndexerWildcardPrivilege.java       |  15 ++
 .../indexer/TestCommonPrivilegeForIndexer.java  |   7 +
 .../sentry/provider/cache/PrivilegeCache.java   |  11 +-
 .../cache/SimpleCacheProviderBackend.java       |   2 +-
 .../provider/cache/SimplePrivilegeCache.java    | 162 ++++++++++++++++++-
 .../provider/cache/PrivilegeCacheTestImpl.java  |   7 +
 .../cache/TestSimplePrivilegeCache.java         |  90 +++++++++++
 .../generic/SentryGenericProviderBackend.java   |   2 +-
 15 files changed, 363 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/sentry/blob/42744cc9/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/privilege/hive/TestCommonPrivilegeForHive.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/privilege/hive/TestCommonPrivilegeForHive.java
b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/privilege/hive/TestCommonPrivilegeForHive.java
index c719802..6a8b871 100644
--- a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/privilege/hive/TestCommonPrivilegeForHive.java
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/privilege/hive/TestCommonPrivilegeForHive.java
@@ -16,7 +16,6 @@
  */
 package org.apache.sentry.privilege.hive;
 
-import junit.framework.Assert;
 import org.apache.sentry.core.common.Model;
 import org.apache.sentry.core.common.utils.KeyValue;
 import org.apache.sentry.core.common.utils.PathUtils;
@@ -28,8 +27,11 @@ import org.apache.sentry.policy.common.Privilege;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.util.List;
+
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.assertEquals;
 
 public class TestCommonPrivilegeForHive {
 
@@ -209,13 +211,19 @@ public class TestCommonPrivilegeForHive {
       public boolean implies(Privilege p, Model m) {
         return false;
       }
+
+      @Override
+      public List<KeyValue> getAuthorizable() {
+        return null;
+      }
+
     };
     assertFalse(ROLE_SERVER_SERVER1_DB_ALL.implies(null, hivePrivilegeModel));
     assertFalse(ROLE_SERVER_SERVER1_DB_ALL.implies(p, hivePrivilegeModel));
     assertFalse(ROLE_SERVER_SERVER1_DB_ALL.equals(null));
     assertFalse(ROLE_SERVER_SERVER1_DB_ALL.equals(p));
 
-    Assert.assertEquals(ROLE_SERVER_SERVER1_DB_ALL.hashCode(),
+    assertEquals(ROLE_SERVER_SERVER1_DB_ALL.hashCode(),
             create(ROLE_SERVER_SERVER1_DB_ALL.toString()).hashCode());
   }
 
@@ -261,6 +269,13 @@ public class TestCommonPrivilegeForHive {
   }
 
   @Test
+  public void testGetAuthz() throws Exception {
+    CommonPrivilege dbAll = create(new KeyValue("server", "server1"),
+        new KeyValue("db", "db1"), new KeyValue("action", "ALL"));
+    assertEquals(2, dbAll.getAuthorizable().size());
+  }
+
+  @Test
   public void testImpliesURINegative() throws Exception {
     // relative path
     assertFalse(PathUtils.impliesURI("hdfs://namenode:8020/path", "hdfs://namenode:8020/path/to/../../other"));

http://git-wip-us.apache.org/repos/asf/sentry/blob/42744cc9/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/privilege/kafka/TestKafkaWildcardPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/privilege/kafka/TestKafkaWildcardPrivilege.java
b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/privilege/kafka/TestKafkaWildcardPrivilege.java
index a616f67..0a0e2f0 100644
--- a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/privilege/kafka/TestKafkaWildcardPrivilege.java
+++ b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/privilege/kafka/TestKafkaWildcardPrivilege.java
@@ -30,6 +30,8 @@ import org.apache.sentry.policy.common.Privilege;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.util.List;
+
 public class TestKafkaWildcardPrivilege {
 
   private Model kafkaPrivilegeModel;
@@ -137,6 +139,11 @@ public class TestKafkaWildcardPrivilege {
       public boolean implies(Privilege p, Model model) {
         return false;
       }
+
+      @Override
+      public List<KeyValue> getAuthorizable() {
+        return null;
+      }
     };
     Privilege topic1 = create(new KeyValue("HOST", "host"), new KeyValue("TOPIC", "topic1"));
     assertFalse(topic1.implies(null, kafkaPrivilegeModel));

http://git-wip-us.apache.org/repos/asf/sentry/blob/42744cc9/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/privilege/solr/TestCommonPrivilegeForSearch.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/privilege/solr/TestCommonPrivilegeForSearch.java
b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/privilege/solr/TestCommonPrivilegeForSearch.java
index 294091c..de6d6e0 100644
--- a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/privilege/solr/TestCommonPrivilegeForSearch.java
+++ b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/privilege/solr/TestCommonPrivilegeForSearch.java
@@ -26,6 +26,8 @@ import org.apache.sentry.policy.common.Privilege;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.util.List;
+
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
@@ -163,6 +165,11 @@ public class TestCommonPrivilegeForSearch {
       public boolean implies(Privilege p, Model m) {
         return false;
       }
+
+      @Override
+      public List<KeyValue> getAuthorizable() {
+        return null;
+      }
     };
     Privilege collection1 = create(new KeyValue("collection", "coll1"));
     assertFalse(collection1.implies(null, searchPrivilegeModel));

http://git-wip-us.apache.org/repos/asf/sentry/blob/42744cc9/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/privilege/sqoop/TestCommonPrivilegeForSqoop.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/privilege/sqoop/TestCommonPrivilegeForSqoop.java
b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/privilege/sqoop/TestCommonPrivilegeForSqoop.java
index 92e9290..94e9919 100644
--- a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/privilege/sqoop/TestCommonPrivilegeForSqoop.java
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/privilege/sqoop/TestCommonPrivilegeForSqoop.java
@@ -26,6 +26,8 @@ import org.apache.sentry.policy.common.Privilege;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.util.List;
+
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
@@ -145,6 +147,11 @@ public class TestCommonPrivilegeForSqoop {
       public boolean implies(Privilege p, Model m) {
         return false;
       }
+
+      @Override
+      public List<KeyValue> getAuthorizable() {
+        return null;
+      }
     };
     Privilege job1 = create(new KeyValue("SERVER", "server"), new KeyValue("JOB", "job1"));
     assertFalse(job1.implies(null, sqoopPrivilegeModel));

http://git-wip-us.apache.org/repos/asf/sentry/blob/42744cc9/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/CommonPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/CommonPrivilege.java
b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/CommonPrivilege.java
index dedd908..e227535 100644
--- a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/CommonPrivilege.java
+++ b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/CommonPrivilege.java
@@ -27,6 +27,7 @@ import org.apache.sentry.core.common.utils.KeyValue;
 import org.apache.sentry.core.common.utils.PathUtils;
 import org.apache.sentry.core.common.utils.SentryConstants;
 
+import java.util.ArrayList;
 import java.util.List;
 
 // The class is used to compare the privilege
@@ -112,6 +113,23 @@ public class CommonPrivilege implements Privilege {
     return true;
   }
 
+  @Override
+  public List<KeyValue> getAuthorizable() {
+    List<KeyValue> authorizable = new ArrayList<>();
+
+    for (KeyValue part : parts) {
+
+      // Authorizeable is the same as privileges but should exclude action
+      if (!SentryConstants.PRIVILEGE_NAME.equalsIgnoreCase(part.getKey())) {
+        KeyValue keyValue = new KeyValue(part.getKey().toLowerCase(),
+            part.getValue().toLowerCase());
+        authorizable.add(keyValue);
+      }
+    }
+
+    return authorizable;
+  }
+
   // The method is used for compare the value of resource by the ImplyMethodType.
   // for Hive, databaseName, tableName, columnName will be compared using String.equal(wildcard
support)
   //           url will be compared using PathUtils.impliesURI

http://git-wip-us.apache.org/repos/asf/sentry/blob/42744cc9/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/Privilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/Privilege.java
b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/Privilege.java
index e9f4609..6c2737a 100644
--- a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/Privilege.java
+++ b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/Privilege.java
@@ -17,7 +17,21 @@
 package org.apache.sentry.policy.common;
 
 import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.utils.KeyValue;
+
+import java.util.List;
 
 public interface Privilege {
+
+  /**
+   * To check if implies another privilege based on the model.
+   **/
   boolean implies(Privilege p, Model model);
+
+
+  /**
+   * Return the list of authorizeable of the privilege.
+   * @return List of Authorizeable
+   */
+  List<KeyValue> getAuthorizable();
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/42744cc9/sentry-policy/sentry-policy-engine/src/main/java/org/apache/sentry/policy/engine/common/CommonPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-engine/src/main/java/org/apache/sentry/policy/engine/common/CommonPolicyEngine.java
b/sentry-policy/sentry-policy-engine/src/main/java/org/apache/sentry/policy/engine/common/CommonPolicyEngine.java
index ee25427..a819bb0 100644
--- a/sentry-policy/sentry-policy-engine/src/main/java/org/apache/sentry/policy/engine/common/CommonPolicyEngine.java
+++ b/sentry-policy/sentry-policy-engine/src/main/java/org/apache/sentry/policy/engine/common/CommonPolicyEngine.java
@@ -72,7 +72,7 @@ public class CommonPolicyEngine implements PolicyEngine {
       LOGGER.debug("Getting permissions for {}", groups);
     }
 
-    ImmutableSet<String> result = providerBackend.getPrivileges(groups, roleSet);
+    ImmutableSet<String> result = providerBackend.getPrivileges(groups, roleSet, authorizableHierarchy);
     if(LOGGER.isDebugEnabled()) {
       LOGGER.debug("result = " + result);
     }
@@ -85,7 +85,7 @@ public class CommonPolicyEngine implements PolicyEngine {
     if (LOGGER.isDebugEnabled()) {
       LOGGER.debug("Getting permissions for groups: {}, users: {}", groups, users);
     }
-    ImmutableSet<String> result = providerBackend.getPrivileges(groups, users, roleSet);
+    ImmutableSet<String> result = providerBackend.getPrivileges(groups, users, roleSet,
authorizableHierarchy);
     if (LOGGER.isDebugEnabled()) {
       LOGGER.debug("result = " + result);
     }

http://git-wip-us.apache.org/repos/asf/sentry/blob/42744cc9/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerWildcardPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerWildcardPrivilege.java
b/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerWildcardPrivilege.java
index 71d2a66..10e3496 100644
--- a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerWildcardPrivilege.java
+++ b/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerWildcardPrivilege.java
@@ -21,6 +21,8 @@
 
 package org.apache.sentry.policy.indexer;
 
+import java.util.ArrayList;
+import java.util.LinkedList;
 import java.util.List;
 
 import org.apache.sentry.core.common.Model;
@@ -104,6 +106,19 @@ public class IndexerWildcardPrivilege implements Privilege {
     return true;
   }
 
+  @Override
+  public List<KeyValue> getAuthorizable() {
+    List<KeyValue> authorizable = new LinkedList<>();
+
+    for (KeyValue part : parts) {
+      if (!SentryConstants.PRIVILEGE_NAME.equalsIgnoreCase(part.getKey())) {
+        authorizable.add(part);
+      }
+    }
+
+    return authorizable;
+  }
+
   private boolean impliesKeyValue(KeyValue policyPart, KeyValue requestPart) {
     Preconditions.checkState(policyPart.getKey().equalsIgnoreCase(requestPart.getKey()),
         "Please report, this method should not be called with two different keys");

http://git-wip-us.apache.org/repos/asf/sentry/blob/42744cc9/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestCommonPrivilegeForIndexer.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestCommonPrivilegeForIndexer.java
b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestCommonPrivilegeForIndexer.java
index 2a3bde7..aa8aa5f 100644
--- a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestCommonPrivilegeForIndexer.java
+++ b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestCommonPrivilegeForIndexer.java
@@ -26,6 +26,8 @@ import org.apache.sentry.policy.common.Privilege;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.util.List;
+
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
@@ -163,6 +165,11 @@ public class TestCommonPrivilegeForIndexer {
       public boolean implies(Privilege p, Model model) {
         return false;
       }
+
+      @Override
+      public List<KeyValue> getAuthorizable() {
+        return null;
+      }
     };
     CommonPrivilege indexer1 = create(new KeyValue("indexer", "index1"));
     assertFalse(indexer1.implies(null, indexerPrivilegeModel));

http://git-wip-us.apache.org/repos/asf/sentry/blob/42744cc9/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/PrivilegeCache.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/PrivilegeCache.java
b/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/PrivilegeCache.java
index 28c5b76..4bb6d32 100644
--- a/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/PrivilegeCache.java
+++ b/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/PrivilegeCache.java
@@ -20,6 +20,7 @@ package org.apache.sentry.provider.cache;
 import java.util.Set;
 
 import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Authorizable;
 
 public interface PrivilegeCache {
   /**
@@ -31,10 +32,18 @@ public interface PrivilegeCache {
 
   /**
    * Get the privileges for the give set of groups and users with the give active
-   * roles from the cache.
+   * roles from the cache. For performance issue, it is recommended to use
+   * listPrivileges with authorization hierarchy
    */
+  @Deprecated
   Set<String> listPrivileges(Set<String> groups, Set<String> users,
       ActiveRoleSet roleSet);
 
+  /**
+   * Get the privileges for the give set of groups and users with the give active
+   * roles and authorization hierarchy from the cache.
+   */
+  Set<String> listPrivileges(Set<String> groups, Set<String> users, ActiveRoleSet
roleSet,
+      Authorizable... authorizationhierarchy);
   void close();
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/42744cc9/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimpleCacheProviderBackend.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimpleCacheProviderBackend.java
b/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimpleCacheProviderBackend.java
index b3db752..ddb4ec5 100644
--- a/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimpleCacheProviderBackend.java
+++ b/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimpleCacheProviderBackend.java
@@ -73,7 +73,7 @@ public class SimpleCacheProviderBackend implements ProviderBackend {
           "Backend has not been properly initialized");
     }
     return ImmutableSet.copyOf(cacheHandle.listPrivileges(groups, users,
-        roleSet));
+        roleSet, authorizableHierarchy));
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/sentry/blob/42744cc9/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimplePrivilegeCache.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimplePrivilegeCache.java
b/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimplePrivilegeCache.java
index dd0c39a..0ad4616 100644
--- a/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimplePrivilegeCache.java
+++ b/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimplePrivilegeCache.java
@@ -17,20 +17,85 @@
 package org.apache.sentry.provider.cache;
 
 import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.common.utils.KeyValue;
+import org.apache.sentry.core.model.db.DBModelAuthorizable.AuthorizableType;
+import org.apache.sentry.policy.common.CommonPrivilege;
+import org.apache.sentry.policy.common.Privilege;
 
-import java.util.HashSet;
 import java.util.Set;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.List;
+import java.util.LinkedList;
 
 /*
  * The class is used for saving and getting user's privileges when do the hive command like
"show tables".
- * This will enhance the performance for the hive metadata filter.
+ * This will enhance the performance for the hive metadata filter. This class is not thread
safe.
  */
 public class SimplePrivilegeCache implements PrivilegeCache {
 
   private Set<String> cachedPrivileges;
 
+  // <Authorizable, Set<PrivilegeObject>> map, this is a cache for mapping authorizable
+  // to corresponding set of privilege objects.
+  // e.g. (server=server1->database=b1, (server=server1->database=b1->action=insert))
+  private final Map<String, Set<String>> cachedAuthzPrivileges = new HashMap<>();
+
+  // <AuthorizableType, Set<AuthorizableValue>> wild card map
+  private final Map<String, Set<String>> wildCardAuthz = new HashMap<>();
+
   public SimplePrivilegeCache(Set<String> cachedPrivileges) {
     this.cachedPrivileges = cachedPrivileges;
+
+    for (String cachedPrivilege : cachedPrivileges) {
+      Privilege privilege = new CommonPrivilege(cachedPrivilege);
+      List<KeyValue> authorizable = privilege.getAuthorizable();
+      String authzString = getAuthzString(authorizable);
+      updateWildCardAuthzMap(authorizable);
+
+      Set<String> authzPrivileges = cachedAuthzPrivileges.get(authzString);
+      if (authzPrivileges == null) {
+        authzPrivileges = new HashSet();
+        cachedAuthzPrivileges.put(authzString, authzPrivileges);
+      }
+      authzPrivileges.add(cachedPrivilege);
+    }
+  }
+
+  private String getAuthzString(List<KeyValue> authoriable) {
+    List<KeyValue> authz = new LinkedList<>();
+    for (KeyValue auth : authoriable) {
+
+      // For authorizable e.g. sever=server1->uri=hdfs://namenode:8020/path/,
+      // use sever=server1 as the key of cachedAuthzPrivileges, since
+      // cannot do string matchinf on URI paths.
+      if (!AuthorizableType.URI.toString().equalsIgnoreCase(auth.getKey())) {
+        authz.add(auth);
+      }
+    }
+
+    return SentryConstants.AUTHORIZABLE_JOINER.join(authz);
+  }
+
+  private void updateWildCardAuthzMap(List<KeyValue> authz) {
+    for (KeyValue auth : authz) {
+      String authKey = auth.getKey().toLowerCase();
+      String authValue = auth.getValue().toLowerCase();
+      Set<String> authzValue = wildCardAuthz.get(authKey);
+
+      if (authzValue != null ) {
+        if (!authzValue.contains(authValue)) {
+          authzValue.add(authValue);
+        }
+      } else {
+        authzValue = new HashSet<>();
+        authzValue.add(authValue);
+        wildCardAuthz.put(authKey, authzValue);
+      }
+    }
   }
 
   // return the cached privileges
@@ -56,4 +121,97 @@ public class SimplePrivilegeCache implements PrivilegeCache {
     }
     return cachedPrivileges;
   }
+
+  @Override
+  public Set<String> listPrivileges(Set<String> groups, Set<String> users,
ActiveRoleSet roleSet,
+      Authorizable... authorizationHierarchy) {
+    Set<String> privileges = new HashSet<>();
+    Set<StringBuilder> authzKeys = getAuthzKeys(authorizationHierarchy);
+    for (StringBuilder authzKey : authzKeys) {
+      if (cachedAuthzPrivileges.get(authzKey.toString()) != null) {
+        privileges.addAll(cachedAuthzPrivileges.get(authzKey.toString()));
+      }
+    }
+
+    return privileges;
+  }
+
+  /**
+   * Get authoriables from the <Authorizable, Set<PrivilegeObject>> cache map,
+   * based on the authorizable hierarchy. This logic follows Privilege.implies.
+   * e.g. given authorizable hierarchy:server=server1->db=db1, returns matched
+   * privileges including server=server1;server=*;server=server1->db=db1;server=server1->db=*.
+   * @param authorizationHierarchy
+   * @return
+   */
+  private Set<StringBuilder> getAuthzKeys(Authorizable... authorizationHierarchy) {
+    Set<StringBuilder> targets = new HashSet<>();
+    for (Authorizable auth : authorizationHierarchy) {
+      String authzType = auth.getTypeName().toLowerCase();
+      String authzName = auth.getName().toLowerCase();
+
+      // No op for URI authorizable type.
+      if (authzType.equalsIgnoreCase(AuthorizableType.URI.toString())) {
+        continue;
+      }
+      // If authorizable name is a wild card, need to add all possible authorizable objects
+      // basesd on the authorizable type.
+      if (authzName.equals(SentryConstants.RESOURCE_WILDCARD_VALUE) ||
+          authzName.equals(SentryConstants.RESOURCE_WILDCARD_VALUE_SOME)||
+          authzName.equals(SentryConstants.RESOURCE_WILDCARD_VALUE_ALL)) {
+        Set<String> wildcardValues = wildCardAuthz.get(authzType);
+
+        if (wildcardValues != null && wildcardValues.size() > 0) {
+          Set<StringBuilder> newTargets = new HashSet<>(targets);
+          for (StringBuilder target : targets) {
+            for (String wildcardValue : wildcardValues) {
+              newTargets.add(addAuthz(target, authzType, wildcardValue));
+            }
+          }
+
+          targets = newTargets;
+        } else {
+          return targets;
+        }
+      } else {
+        if (targets.isEmpty()) {
+          targets.add(addAuthz(new StringBuilder(), authzType, authzName));
+
+          // Add wild card * search, e.g server=*, server=ALL
+          targets.add(addAuthz(new StringBuilder(), authzType,
+              SentryConstants.RESOURCE_WILDCARD_VALUE.toLowerCase()));
+          targets.add(addAuthz(new StringBuilder(), authzType,
+              SentryConstants.RESOURCE_WILDCARD_VALUE_ALL.toLowerCase()));
+        } else {
+          Set<StringBuilder> newTargets = new HashSet<>(targets);
+
+          for (StringBuilder target : targets) {
+            newTargets.add(addAuthz(target, authzType, authzName));
+
+            // Add wild card * search, e.g server=server1->db=*, server=server1->db=ALL
+            newTargets.add(addAuthz(target, authzType,
+                SentryConstants.RESOURCE_WILDCARD_VALUE.toLowerCase()));
+            newTargets.add(addAuthz(target, authzType,
+                SentryConstants.RESOURCE_WILDCARD_VALUE_ALL.toLowerCase()));
+          }
+
+          targets = newTargets;
+        }
+      }
+    }
+
+    return targets;
+  }
+
+  private StringBuilder addAuthz(StringBuilder authorizable, String authzType, String authzName)
{
+    StringBuilder newAuthrizable = new StringBuilder(authorizable);
+    if (newAuthrizable.length() > 0) {
+      newAuthrizable.append(SentryConstants.AUTHORIZABLE_SEPARATOR);
+      newAuthrizable.append(SentryConstants.KV_JOINER.join(authzType, authzName));
+    } else {
+      newAuthrizable.append(SentryConstants.KV_JOINER.join(authzType, authzName));
+    }
+
+    return newAuthrizable;
+  }
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/42744cc9/sentry-provider/sentry-provider-cache/src/test/java/org/apache/sentry/provider/cache/PrivilegeCacheTestImpl.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-cache/src/test/java/org/apache/sentry/provider/cache/PrivilegeCacheTestImpl.java
b/sentry-provider/sentry-provider-cache/src/test/java/org/apache/sentry/provider/cache/PrivilegeCacheTestImpl.java
index 79e047e..361f273 100644
--- a/sentry-provider/sentry-provider-cache/src/test/java/org/apache/sentry/provider/cache/PrivilegeCacheTestImpl.java
+++ b/sentry-provider/sentry-provider-cache/src/test/java/org/apache/sentry/provider/cache/PrivilegeCacheTestImpl.java
@@ -25,6 +25,7 @@ import java.util.Set;
 import org.apache.commons.io.FileUtils;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Authorizable;
 import org.apache.sentry.provider.common.ProviderBackendContext;
 import org.apache.sentry.provider.file.PolicyFiles;
 import org.apache.sentry.provider.file.SimpleFileProviderBackend;
@@ -65,4 +66,10 @@ public class PrivilegeCacheTestImpl implements PrivilegeCache {
   public Set<String> listPrivileges(Set<String> groups, Set<String> users,
ActiveRoleSet roleSet) {
     return backend.getPrivileges(groups, users, roleSet);
   }
+
+  @Override
+  public Set<String> listPrivileges(Set<String> groups, Set<String> users,
ActiveRoleSet roleSet,
+      Authorizable... authorizationhierarchy) {
+    return backend.getPrivileges(groups, users, roleSet, authorizationhierarchy);
+  }
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/42744cc9/sentry-provider/sentry-provider-cache/src/test/java/org/apache/sentry/provider/cache/TestSimplePrivilegeCache.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-cache/src/test/java/org/apache/sentry/provider/cache/TestSimplePrivilegeCache.java
b/sentry-provider/sentry-provider-cache/src/test/java/org/apache/sentry/provider/cache/TestSimplePrivilegeCache.java
new file mode 100644
index 0000000..891c1d9
--- /dev/null
+++ b/sentry-provider/sentry-provider-cache/src/test/java/org/apache/sentry/provider/cache/TestSimplePrivilegeCache.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.provider.cache;
+
+import com.google.common.collect.Sets;
+import org.apache.sentry.core.common.utils.KeyValue;
+import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.model.db.Database;
+import org.apache.sentry.core.model.db.Table;
+import org.apache.sentry.policy.common.CommonPrivilege;
+import org.junit.Test;
+
+import org.apache.sentry.core.model.db.Server;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestSimplePrivilegeCache {
+
+  @Test
+     public void testListPrivilegesCaseSensitivity() {
+    CommonPrivilege dbSelect = create(new KeyValue("Server", "Server1"),
+    new KeyValue("db", "db1"), new KeyValue("action", "SELECT"));
+
+    SimplePrivilegeCache cache = new SimplePrivilegeCache(Sets.newHashSet(dbSelect.toString()));
+    assertEquals(1, cache.listPrivileges(null, null, null,
+        new Server("server1"), new Database("db1")).size());
+  }
+
+  @Test
+  public void testListPrivilegesWildCard() {
+    CommonPrivilege t1D1Select = create(new KeyValue("Server", "server1"),
+        new KeyValue("db", "db1"), new KeyValue("table", "t1"), new KeyValue("action", "SELECT"));
+    CommonPrivilege t1D2Select = create(new KeyValue("Server", "server1"),
+        new KeyValue("db", "db2"), new KeyValue("table", "t1"), new KeyValue("action", "SELECT"));
+    CommonPrivilege t2Select = create(new KeyValue("Server", "server1"),
+        new KeyValue("db", "db1"), new KeyValue("table", "t2"), new KeyValue("action", "SELECT"));
+    CommonPrivilege wildCardTable = create(new KeyValue("Server", "server1"),
+        new KeyValue("db", "db1"), new KeyValue("table", "*"), new KeyValue("action", "SELECT"));
+    CommonPrivilege allTable = create(new KeyValue("Server", "server1"),
+        new KeyValue("db", "db1"), new KeyValue("table", "ALL"), new KeyValue("action", "SELECT"));
+    CommonPrivilege allDatabase = create(new KeyValue("Server", "server1"),
+        new KeyValue("db", "*"));
+    CommonPrivilege colSelect = create(new KeyValue("Server", "server1"),
+        new KeyValue("db", "db1"), new KeyValue("table", "t1"), new KeyValue("col", "c1"),
new KeyValue("action", "SELECT"));
+
+    SimplePrivilegeCache cache = new SimplePrivilegeCache(Sets.newHashSet(t1D1Select.toString(),
+        t1D2Select.toString(), t2Select.toString(), wildCardTable.toString(), allTable.toString(),
+        allDatabase.toString(), colSelect.toString()));
+
+    assertEquals(0, cache.listPrivileges(null, null, null, new Server("server1")).size());
+    assertEquals(1, cache.listPrivileges(null, null, null, new Server("server1"), new Database("db1")).size());
+    assertEquals(1, cache.listPrivileges(null, null, null, new Server("server1"), new Database("db2")).size());
+    assertEquals(4, cache.listPrivileges(null, null, null, new Server("server1"), new Database("db1"),
new Table("t1")).size());
+  }
+
+  @Test
+  public void testListPrivilegesURI() {
+    CommonPrivilege uri1Select = create(new KeyValue("Server", "server1"),
+        new KeyValue("uri", "hdfs:///uri/path1"));
+    CommonPrivilege uri2Select = create(new KeyValue("Server", "server1"),
+        new KeyValue("uri", "hdfs:///uri/path2"));
+
+    SimplePrivilegeCache cache = new SimplePrivilegeCache(Sets.newHashSet(uri1Select.toString(),
+      uri2Select.toString()));
+
+    assertEquals(2, cache.listPrivileges(null, null, null, new Server("server1")).size());
+  }
+
+  static CommonPrivilege create(KeyValue... keyValues) {
+    return create(SentryConstants.AUTHORIZABLE_JOINER.join(keyValues));
+  }
+
+  static CommonPrivilege create(String s) {
+    return new CommonPrivilege(s);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/42744cc9/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java
index 1d1da5e..134012d 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java
@@ -182,7 +182,7 @@ public class SentryGenericProviderBackend extends CacheProvider implements
Provi
   public ImmutableSet<String> getPrivileges(Set<String> groups, Set<String>
users,
                                               ActiveRoleSet roleSet, Authorizable... authorizableHierarchy)
{
     // SentryGenericProviderBackend doesn't support getPrivileges for user now.
-    return getPrivileges(groups, roleSet, authorizableHierarchy);
+    return getPrivileges(groups, roleSet);
   }
 
   @Override


Mime
View raw message