You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by co...@apache.org on 2016/05/08 10:53:06 UTC

sentry git commit: SENTRY-1222: Improve SentryIniPolicyFileFormatter to support user section in .ini file(Colin Ma, reviewed by Dapeng Sun)

Repository: sentry
Updated Branches:
  refs/heads/master d89955bd6 -> 0db74b863


SENTRY-1222: Improve SentryIniPolicyFileFormatter to support user section in .ini file(Colin Ma, reviewed by Dapeng Sun)


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

Branch: refs/heads/master
Commit: 0db74b863824c03a2d0164b86c7a1330afc76b97
Parents: d89955b
Author: Colin Ma <co...@apache.org>
Authored: Sun May 8 19:27:42 2016 +0800
Committer: Colin Ma <co...@apache.org>
Committed: Sun May 8 19:27:42 2016 +0800

----------------------------------------------------------------------
 .../hive/SentryIniPolicyFileFormatter.java      | 80 +++++++++++---------
 .../hive/TestSentryIniPolicyFileFormatter.java  | 40 +++++++++-
 .../provider/common/PolicyFileConstants.java    |  1 +
 .../SentryPolicyServiceClientDefaultImpl.java   |  4 +-
 .../thrift/TestSentryServiceImportExport.java   |  6 +-
 5 files changed, 88 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/sentry/blob/0db74b86/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java
index 06fe1fe..dd5781a 100644
--- a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java
+++ b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java
@@ -23,11 +23,15 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import com.google.common.collect.Sets;
+import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
+import org.apache.sentry.core.common.SentryConfigurationException;
 import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.provider.common.PolicyFileConstants;
-import org.apache.sentry.provider.common.ProviderBackendContext;
-import org.apache.sentry.provider.file.SimpleFileProviderBackend;
+import org.apache.sentry.provider.file.PolicyFiles;
+import org.apache.shiro.config.Ini;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -35,8 +39,6 @@ import com.google.common.base.Charsets;
 import com.google.common.base.Joiner;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.collect.Table;
 import com.google.common.io.Files;
 
 /**
@@ -61,6 +63,8 @@ public class SentryIniPolicyFileFormatter implements SentryPolicyFileFormatter {
    * @param sentryMappingData
    *        The map for sentry mapping data, eg:
    *        for the following mapping data:
+   *        user1=role1,role2
+   *        user2=role2,role3
    *        group1=role1,role2
    *        group2=role2,role3
    *        role1=server=server1->db=db1
@@ -69,6 +73,7 @@ public class SentryIniPolicyFileFormatter implements SentryPolicyFileFormatter {
    *
    *        The sentryMappingData will be inputed as:
    *        {
+   *        users={[user1={role1, role2}], group2=[role2, role3]},
    *        groups={[group1={role1, role2}], group2=[role2, role3]},
    *        roles={role1=[server=server1->db=db1],
    *        role2=[server=server1->db=db1->table=tbl1,server=server1->db=db1->table=tbl2],
@@ -86,6 +91,8 @@ public class SentryIniPolicyFileFormatter implements SentryPolicyFileFormatter {
     String contents = Joiner
         .on(NL)
         .join(
+        generateSection(PolicyFileConstants.USER_ROLES,
+            sentryMappingData.get(PolicyFileConstants.USER_ROLES)),
         generateSection(PolicyFileConstants.GROUPS,
                 sentryMappingData.get(PolicyFileConstants.GROUPS)),
         generateSection(PolicyFileConstants.ROLES,
@@ -105,45 +112,48 @@ public class SentryIniPolicyFileFormatter implements SentryPolicyFileFormatter {
    * @return the result of sentry mapping data in map structure.
    */
   @Override
-  public Map<String, Map<String, Set<String>>> parse(String resourcePath, Configuration conf)
-      throws Exception {
+  public Map<String, Map<String, Set<String>>> parse(String resourcePath, Configuration conf) {
     Map<String, Map<String, Set<String>>> resultMap = Maps.newHashMap();
-    // SimpleFileProviderBackend is used for parse the ini file
-    SimpleFileProviderBackend policyFileBackend = new SimpleFileProviderBackend(conf, resourcePath);
-    ProviderBackendContext context = new ProviderBackendContext();
-    context.setAllowPerDatabase(true);
-    // parse the ini file
-    policyFileBackend.initialize(context);
+    Path path = new Path(resourcePath);
+    Ini ini;
 
-    // SimpleFileProviderBackend parsed the input file and output the data in Table format.
-    Table<String, String, Set<String>> groupRolePrivilegeTable = policyFileBackend
-        .getGroupRolePrivilegeTable();
-    Map<String, Set<String>> groupRolesMap = Maps.newHashMap();
-    Map<String, Set<String>> rolePrivilegesMap = Maps.newHashMap();
-    for (String groupName : groupRolePrivilegeTable.rowKeySet()) {
-      for (String roleName : groupRolePrivilegeTable.columnKeySet()) {
-        // get the roles set for the current groupName
-        Set<String> tempRoles = groupRolesMap.get(groupName);
-        if (tempRoles == null) {
-          tempRoles = Sets.newHashSet();
-        }
-        Set<String> privileges = groupRolePrivilegeTable.get(groupName, roleName);
-        // if there has privilege for [group,role], if no privilege exist, the [group, role] info
-        // will be discard.
-        if (privileges != null) {
-          // update [group, role] mapping data
-          tempRoles.add(roleName);
-          groupRolesMap.put(groupName, tempRoles);
-          // update [role, privilege] mapping data
-          rolePrivilegesMap.put(roleName, privileges);
-        }
-      }
+    try {
+      ini = PolicyFiles.loadFromPath(path.getFileSystem(conf), path);
+    } catch (Exception e) {
+      throw new SentryConfigurationException("Error loading policy file "
+          + resourcePath, e);
     }
+    Map<String, Set<String>> userRolesMap = parseSection(ini,
+        PolicyFileConstants.USER_ROLES);
+    Map<String, Set<String>> groupRolesMap = parseSection(ini,
+        PolicyFileConstants.GROUPS);
+    Map<String, Set<String>> rolePrivilegesMap = parseSection(ini,
+        PolicyFileConstants.ROLES);
+    resultMap.put(PolicyFileConstants.USER_ROLES, userRolesMap);
     resultMap.put(PolicyFileConstants.GROUPS, groupRolesMap);
     resultMap.put(PolicyFileConstants.ROLES, rolePrivilegesMap);
     return resultMap;
   }
 
+  private Map<String, Set<String>> parseSection(Ini ini, String sctionName) {
+    Map<String, Set<String>> resultMap = Maps.newHashMap();
+    Ini.Section sction = ini.getSection(sctionName);
+    if (sction == null) {
+      return resultMap;
+    }
+    for (String key : sction.keySet()) {
+      String value = sction.get(key);
+      Set<String> roles = Sets.newHashSet();
+      for (String role : value.split(SentryConstants.ROLE_SEPARATOR)) {
+        if (StringUtils.isNotEmpty(role)) {
+          roles.add(role);
+        }
+      }
+      resultMap.put(key, roles);
+    }
+    return resultMap;
+  }
+
   // generate the ini section according to the mapping data.
   private String generateSection(String name, Map<String, Set<String>> mappingData) {
     if (mappingData.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/sentry/blob/0db74b86/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java
index 0e7ee3d..6fd1aa5 100644
--- a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java
@@ -55,6 +55,10 @@ public class TestSentryIniPolicyFileFormatter {
 
   private void prepareTestData() {
     // test data for:
+    // [users]
+    // user1=role1,role2,role3
+    // user2=role1,role2,role3
+    // user3=role1,role2,role3
     // [groups]
     // group1=role1,role2,role3
     // group2=role1,role2,role3
@@ -64,9 +68,13 @@ public class TestSentryIniPolicyFileFormatter {
     // role2=privilege1,privilege2,privilege3,privilege4,privilege5,privilege6,privilege7,privilege8
     // role3=privilege1,privilege2,privilege3,privilege4,privilege5,privilege6,privilege7,privilege8
     policyFileMappingData1 = Maps.newHashMap();
+    Map<String, Set<String>> userRolesMap = Maps.newHashMap();
     Map<String, Set<String>> groupRolesMap = Maps.newHashMap();
     Map<String, Set<String>> rolePrivilegesMap = Maps.newHashMap();
     Set<String> roles = Sets.newHashSet("role1", "role2", "role3");
+    userRolesMap.put("user1", roles);
+    userRolesMap.put("user2", roles);
+    userRolesMap.put("user3", roles);
     groupRolesMap.put("group1", roles);
     groupRolesMap.put("group2", roles);
     groupRolesMap.put("group3", roles);
@@ -74,10 +82,15 @@ public class TestSentryIniPolicyFileFormatter {
       rolePrivilegesMap.put(roleName, Sets.newHashSet(PRIVILIEGE1, PRIVILIEGE2, PRIVILIEGE3,
           PRIVILIEGE4, PRIVILIEGE5, PRIVILIEGE6, PRIVILIEGE7, PRIVILIEGE8));
     }
+    policyFileMappingData1.put(PolicyFileConstants.USER_ROLES, userRolesMap);
     policyFileMappingData1.put(PolicyFileConstants.GROUPS, groupRolesMap);
     policyFileMappingData1.put(PolicyFileConstants.ROLES, rolePrivilegesMap);
 
     // test data for:
+    // [users]
+    // user1=role1
+    // user2=role2
+    // user3=role3
     // [groups]
     // group1=role1
     // group2=role2
@@ -87,18 +100,27 @@ public class TestSentryIniPolicyFileFormatter {
     // role2=privilege4,privilege5,privilege6
     // role3=privilege7,privilege8
     policyFileMappingData2 = Maps.newHashMap();
+    userRolesMap = Maps.newHashMap();
     groupRolesMap = Maps.newHashMap();
     rolePrivilegesMap = Maps.newHashMap();
+    userRolesMap.put("user1", Sets.newHashSet("role1"));
+    userRolesMap.put("user2", Sets.newHashSet("role2"));
+    userRolesMap.put("user3", Sets.newHashSet("role3"));
     groupRolesMap.put("group1", Sets.newHashSet("role1"));
     groupRolesMap.put("group2", Sets.newHashSet("role2"));
     groupRolesMap.put("group3", Sets.newHashSet("role3"));
     rolePrivilegesMap.put("role1", Sets.newHashSet(PRIVILIEGE1, PRIVILIEGE2, PRIVILIEGE3));
     rolePrivilegesMap.put("role2", Sets.newHashSet(PRIVILIEGE4, PRIVILIEGE5, PRIVILIEGE6));
     rolePrivilegesMap.put("role3", Sets.newHashSet(PRIVILIEGE7, PRIVILIEGE8));
+    policyFileMappingData2.put(PolicyFileConstants.USER_ROLES, userRolesMap);
     policyFileMappingData2.put(PolicyFileConstants.GROUPS, groupRolesMap);
     policyFileMappingData2.put(PolicyFileConstants.ROLES, rolePrivilegesMap);
 
     // test data for:
+    // [users]
+    // user1=role1,role2
+    // user2=role1,role2,role3
+    // user3=role2,role3
     // [groups]
     // group1=role1,role2
     // group2=role1,role2,role3
@@ -108,8 +130,12 @@ public class TestSentryIniPolicyFileFormatter {
     // role2=privilege3,privilege4,privilege5,privilege6
     // role3=privilege5,privilege6,privilege7,privilege8
     policyFileMappingData3 = Maps.newHashMap();
+    userRolesMap = Maps.newHashMap();
     groupRolesMap = Maps.newHashMap();
     rolePrivilegesMap = Maps.newHashMap();
+    userRolesMap.put("user1", Sets.newHashSet("role1", "role2"));
+    userRolesMap.put("user2", Sets.newHashSet("role1", "role2", "role3"));
+    userRolesMap.put("user3", Sets.newHashSet("role2", "role3"));
     groupRolesMap.put("group1", Sets.newHashSet("role1", "role2"));
     groupRolesMap.put("group2", Sets.newHashSet("role1", "role2", "role3"));
     groupRolesMap.put("group3", Sets.newHashSet("role2", "role3"));
@@ -119,21 +145,27 @@ public class TestSentryIniPolicyFileFormatter {
         Sets.newHashSet(PRIVILIEGE3, PRIVILIEGE4, PRIVILIEGE5, PRIVILIEGE6));
     rolePrivilegesMap.put("role3",
         Sets.newHashSet(PRIVILIEGE5, PRIVILIEGE6, PRIVILIEGE7, PRIVILIEGE8));
+    policyFileMappingData3.put(PolicyFileConstants.USER_ROLES, userRolesMap);
     policyFileMappingData3.put(PolicyFileConstants.GROUPS, groupRolesMap);
     policyFileMappingData3.put(PolicyFileConstants.ROLES, rolePrivilegesMap);
 
-    // test data for groups only
+    // test data for users, groups only
     policyFileMappingData4 = Maps.newHashMap();
+    userRolesMap = Maps.newHashMap();
     groupRolesMap = Maps.newHashMap();
     rolePrivilegesMap = Maps.newHashMap();
+    userRolesMap.put("user1", Sets.newHashSet("role1", "role2"));
     groupRolesMap.put("group1", Sets.newHashSet("role1", "role2"));
+    policyFileMappingData4.put(PolicyFileConstants.USER_ROLES, userRolesMap);
     policyFileMappingData4.put(PolicyFileConstants.GROUPS, groupRolesMap);
     policyFileMappingData4.put(PolicyFileConstants.ROLES, rolePrivilegesMap);
 
     // test empty data
     policyFileMappingData5 = Maps.newHashMap();
+    userRolesMap = Maps.newHashMap();
     groupRolesMap = Maps.newHashMap();
     rolePrivilegesMap = Maps.newHashMap();
+    policyFileMappingData5.put(PolicyFileConstants.USER_ROLES, userRolesMap);
     policyFileMappingData5.put(PolicyFileConstants.GROUPS, groupRolesMap);
     policyFileMappingData5.put(PolicyFileConstants.ROLES, rolePrivilegesMap);
   }
@@ -165,12 +197,12 @@ public class TestSentryIniPolicyFileFormatter {
     // test data4
     iniFormatter.write(resourcePath, policyFileMappingData4);
     parsedMappingData = iniFormatter.parse(resourcePath, authzConf);
-    assertTrue(parsedMappingData.get(PolicyFileConstants.GROUPS).isEmpty());
-    assertTrue(parsedMappingData.get(PolicyFileConstants.ROLES).isEmpty());
+    validateSentryMappingData(parsedMappingData, policyFileMappingData4);
 
     // test data5
     iniFormatter.write(resourcePath, policyFileMappingData5);
     parsedMappingData = iniFormatter.parse(resourcePath, authzConf);
+    assertTrue(parsedMappingData.get(PolicyFileConstants.USER_ROLES).isEmpty());
     assertTrue(parsedMappingData.get(PolicyFileConstants.GROUPS).isEmpty());
     assertTrue(parsedMappingData.get(PolicyFileConstants.ROLES).isEmpty());
     (new File(baseDir, RESOURCE_PATH)).delete();
@@ -179,6 +211,8 @@ public class TestSentryIniPolicyFileFormatter {
   // verify the mapping data
   public void validateSentryMappingData(Map<String, Map<String, Set<String>>> actualMappingData,
       Map<String, Map<String, Set<String>>> expectedMappingData) {
+    validateGroupRolesMap(actualMappingData.get(PolicyFileConstants.USER_ROLES),
+        expectedMappingData.get(PolicyFileConstants.USER_ROLES));
     validateGroupRolesMap(actualMappingData.get(PolicyFileConstants.GROUPS),
         expectedMappingData.get(PolicyFileConstants.GROUPS));
     validateRolePrivilegesMap(actualMappingData.get(PolicyFileConstants.ROLES),

http://git-wip-us.apache.org/repos/asf/sentry/blob/0db74b86/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/PolicyFileConstants.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/PolicyFileConstants.java b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/PolicyFileConstants.java
index dfe4fe0..5627fa2 100644
--- a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/PolicyFileConstants.java
+++ b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/PolicyFileConstants.java
@@ -21,6 +21,7 @@ public class PolicyFileConstants {
   public static final String GROUPS = "groups";
   public static final String ROLES = "roles";
   public static final String USERS = "users";
+  public static final String USER_ROLES = "userroles";
   public static final String PRIVILEGE_SERVER_NAME = "server";
   public static final String PRIVILEGE_DATABASE_NAME = "db";
   public static final String PRIVILEGE_TABLE_NAME = "table";

http://git-wip-us.apache.org/repos/asf/sentry/blob/0db74b86/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java
index a52ad8f..616553f 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java
@@ -940,7 +940,7 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
       // convert the mapping data for [group,role] from map structure to
       // TSentryMappingData.GroupRolesMap
       tSentryMappingData.setGroupRolesMap(policyFileMappingData.get(PolicyFileConstants.GROUPS));
-      tSentryMappingData.setUserRolesMap(policyFileMappingData.get(PolicyFileConstants.USERS));
+      tSentryMappingData.setUserRolesMap(policyFileMappingData.get(PolicyFileConstants.USER_ROLES));
       // convert the mapping data for [role,privilege] from map structure to
       // TSentryMappingData.RolePrivilegesMap
       tSentryMappingData
@@ -985,7 +985,7 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
       Status.throwIfNotOk(response.getStatus());
       TSentryMappingData tSentryMappingData = response.getMappingData();
       Map<String, Map<String, Set<String>>> resultMap = Maps.newHashMap();
-      resultMap.put(PolicyFileConstants.USERS, tSentryMappingData.getUserRolesMap());
+      resultMap.put(PolicyFileConstants.USER_ROLES, tSentryMappingData.getUserRolesMap());
       resultMap.put(PolicyFileConstants.GROUPS, tSentryMappingData.getGroupRolesMap());
       resultMap.put(PolicyFileConstants.ROLES,
           convertRolePrivilegesMapForPolicyFile(tSentryMappingData.getRolePrivilegesMap()));

http://git-wip-us.apache.org/repos/asf/sentry/blob/0db74b86/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceImportExport.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceImportExport.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceImportExport.java
index 2665db1..5aec49c 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceImportExport.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceImportExport.java
@@ -690,7 +690,7 @@ public class TestSentryServiceImportExport extends SentryServiceIntegrationBase
           rolePrivilegesMap.put(roleName, Sets.newHashSet(PRIVILIEGE1,
               PRIVILIEGE2, PRIVILIEGE3, PRIVILIEGE4));
         }
-        policyFileMappingData.put(PolicyFileConstants.USERS, userRolesMap);
+        policyFileMappingData.put(PolicyFileConstants.USER_ROLES, userRolesMap);
         policyFileMappingData.put(PolicyFileConstants.GROUPS, groupRolesMap);
         policyFileMappingData.put(PolicyFileConstants.ROLES, rolePrivilegesMap);
         client.importPolicy(policyFileMappingData, ADMIN_USER, false);
@@ -698,8 +698,8 @@ public class TestSentryServiceImportExport extends SentryServiceIntegrationBase
         Map<String, Map<String, Set<String>>> sentryMappingData =
             client.exportPolicy(ADMIN_USER, null);
         // validate the [user, role] mapping
-        validateRolesMap(sentryMappingData.get(PolicyFileConstants.USERS),
-            policyFileMappingData.get(PolicyFileConstants.USERS));
+        validateRolesMap(sentryMappingData.get(PolicyFileConstants.USER_ROLES),
+            policyFileMappingData.get(PolicyFileConstants.USER_ROLES));
         validateSentryMappingData(sentryMappingData,
             policyFileMappingData);
       }