You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ve...@apache.org on 2015/10/30 23:33:08 UTC

[4/4] incubator-ranger git commit: Ranger-684: Added support for Ranger Usersync to transform AD usernames and/or group names to linux compliant format

Ranger-684: Added support for Ranger Usersync to transform AD usernames and/or group names to linux compliant format

Signed-off-by: Velmurugan Periasamy <ve...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/a57740e2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/a57740e2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/a57740e2

Branch: refs/heads/master
Commit: a57740e277bf777e78cc0807349a9bcd96a80f3e
Parents: f1135ea
Author: Sailaja Polavarapu <sp...@hortonworks.com>
Authored: Wed Oct 28 13:14:24 2015 -0700
Committer: Velmurugan Periasamy <ve...@apache.org>
Committed: Fri Oct 30 18:32:07 2015 -0400

----------------------------------------------------------------------
 ugsync/pom.xml                                  |  5 ++
 .../process/LdapUserGroupBuilder.java           | 50 +++++++++++
 .../config/UserGroupSyncConfig.java             | 47 +++++++++++
 .../ranger/usergroupsync/AbstractMapper.java    | 40 +++++++++
 .../org/apache/ranger/usergroupsync/Mapper.java | 26 ++++++
 .../org/apache/ranger/usergroupsync/RegEx.java  | 83 ++++++++++++++++++
 .../apache/ranger/usergroupsync/RegExTest.java  | 89 ++++++++++++++++++++
 7 files changed, 340 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/a57740e2/ugsync/pom.xml
----------------------------------------------------------------------
diff --git a/ugsync/pom.xml b/ugsync/pom.xml
index c72eeee..d0ecb2f 100644
--- a/ugsync/pom.xml
+++ b/ugsync/pom.xml
@@ -105,6 +105,11 @@
         <version>${project.version}</version>
       </dependency>
 
+	  <dependency>
+		<groupId>junit</groupId>
+		<artifactId>junit</artifactId>
+		<scope>test</scope>
+	  </dependency>
 
     </dependencies>
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/a57740e2/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapUserGroupBuilder.java
----------------------------------------------------------------------
diff --git a/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapUserGroupBuilder.java b/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapUserGroupBuilder.java
index 63643c0..911c5d5 100644
--- a/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapUserGroupBuilder.java
+++ b/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapUserGroupBuilder.java
@@ -42,6 +42,7 @@ import javax.naming.ldap.PagedResultsResponseControl;
 
 import org.apache.log4j.Logger;
 import org.apache.ranger.unixusersync.config.UserGroupSyncConfig;
+import org.apache.ranger.usergroupsync.AbstractMapper;
 import org.apache.ranger.usergroupsync.UserGroupSink;
 import org.apache.ranger.usergroupsync.UserGroupSource;
 
@@ -91,6 +92,9 @@ public class LdapUserGroupBuilder implements UserGroupSource {
 	private boolean groupNameLowerCaseFlag = false ;
 
   private boolean  groupUserMapSyncEnabled = false;
+  
+  AbstractMapper userNameRegExInst = null;
+  AbstractMapper groupNameRegExInst = null;
 
 	public static void main(String[] args) throws Throwable {
 		LdapUserGroupBuilder  ugBuilder = new LdapUserGroupBuilder();
@@ -120,6 +124,39 @@ public class LdapUserGroupBuilder implements UserGroupSource {
 		    groupNameLowerCaseFlag = UserGroupSyncConfig.UGSYNC_LOWER_CASE_CONVERSION_VALUE.equalsIgnoreCase(groupNameCaseConversion) ;
 		}
 		
+		String mappingUserNameHandler = config.getUserSyncMappingUserNameHandler();
+		try {
+			if (mappingUserNameHandler != null) {
+				Class<AbstractMapper> regExClass = (Class<AbstractMapper>)Class.forName(mappingUserNameHandler);
+				userNameRegExInst = regExClass.newInstance();
+				if (userNameRegExInst != null) {
+					userNameRegExInst.init(UserGroupSyncConfig.SYNC_MAPPING_USERNAME);
+				} else {
+					LOG.error("RegEx handler instance for username is null!");
+				}
+			}
+		} catch (ClassNotFoundException cne) {
+			LOG.error("Failed to load " + mappingUserNameHandler + " " + cne);
+		} catch (Throwable te) {
+			LOG.error("Failed to instantiate " + mappingUserNameHandler + " " + te);
+		}
+
+		String mappingGroupNameHandler = config.getUserSyncMappingGroupNameHandler();
+		try {
+			if (mappingGroupNameHandler != null) {
+				Class<AbstractMapper> regExClass = (Class<AbstractMapper>)Class.forName(mappingGroupNameHandler);
+				groupNameRegExInst = regExClass.newInstance();
+				if (groupNameRegExInst != null) {
+					groupNameRegExInst.init(UserGroupSyncConfig.SYNC_MAPPING_GROUPNAME);
+				} else {
+					LOG.error("RegEx handler instance for groupname is null!");
+				}
+			}
+		} catch (ClassNotFoundException cne) {
+			LOG.error("Failed to load " + mappingGroupNameHandler + " " + cne);
+		} catch (Throwable te) {
+			LOG.error("Failed to instantiate " + mappingGroupNameHandler + " " + te);
+		}		
 	}
 
 	@Override
@@ -320,6 +357,10 @@ public class LdapUserGroupBuilder implements UserGroupSource {
 							userName = userName.toUpperCase() ;
 						}
 					}
+					
+					if (userNameRegExInst != null) {
+                        userName = userNameRegExInst.transform(userName);
+					}
 
           Set<String> groups = new HashSet<String>();
 
@@ -337,6 +378,9 @@ public class LdapUserGroupBuilder implements UserGroupSource {
                     gName = gName.toUpperCase();
                   }
                 }
+                if (groupNameRegExInst != null) {
+                    gName = groupNameRegExInst.transform(gName);
+                }
                 groups.add(gName);
               }
             }
@@ -361,6 +405,9 @@ public class LdapUserGroupBuilder implements UserGroupSource {
                     gName = gName.toUpperCase();
                   }
                 }
+                if (groupNameRegExInst != null) {
+                    gName = groupNameRegExInst.transform(gName);
+                }
                 computedGroups.add(gName);
               }
             }
@@ -453,6 +500,9 @@ public class LdapUserGroupBuilder implements UserGroupSource {
               gName = gName.toUpperCase();
             }
           }
+          if (groupNameRegExInst != null) {
+              gName = groupNameRegExInst.transform(gName);
+          }
           groupNames.add(gName);
         }
         if (LOG.isInfoEnabled())  {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/a57740e2/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
----------------------------------------------------------------------
diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
index c1b305b..ceeb836 100644
--- a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
+++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
@@ -24,7 +24,10 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Properties;
 import java.util.Set;
 import java.util.StringTokenizer;
@@ -174,6 +177,17 @@ public class UserGroupSyncConfig  {
 	private static final String SYNC_SOURCE = "ranger.usersync.sync.source";
 	private static final String LGSYNC_REFERRAL = "ranger.usersync.ldap.referral";
 	private static final String DEFAULT_LGSYNC_REFERRAL = "ignore";
+	
+	public static final String SYNC_MAPPING_USERNAME = "ranger.usersync.mapping.username.regex";
+
+    public static final String SYNC_MAPPING_GROUPNAME = "ranger.usersync.mapping.groupname.regex";
+
+    private static final String SYNC_MAPPING_USERNAME_HANDLER = "ranger.usersync.mapping.username.handler";
+    private static final String DEFAULT_SYNC_MAPPING_USERNAME_HANDLER = "org.apache.ranger.usergroupsync.RegEx";
+
+    private static final String SYNC_MAPPING_GROUPNAME_HANDLER = "ranger.usersync.mapping.groupname.handler";
+    private static final String DEFAULT_SYNC_MAPPING_GROUPNAME_HANDLER = "org.apache.ranger.usergroupsync.RegEx";
+    
 	private Properties prop = new Properties() ;
 	
 	private static volatile UserGroupSyncConfig me = null ;
@@ -738,4 +752,37 @@ public class UserGroupSyncConfig  {
 		}
 		return referral;
 	}
+	
+	public List<String> getAllRegexPatterns(String baseProperty) {
+		List<String> regexPatterns = new ArrayList<String>();
+		if (prop != null) {
+			Enumeration<?> propertyNames = prop.propertyNames();
+			while (propertyNames != null && propertyNames.hasMoreElements()) {
+				String propertyName = (String)propertyNames.nextElement();
+				if (propertyName != null && propertyName.contains(baseProperty)) {
+					regexPatterns.add(prop.getProperty(propertyName));
+				}
+			}
+
+		}
+		return regexPatterns;
+	}
+
+	public String getUserSyncMappingUserNameHandler() {
+		String val =  prop.getProperty(SYNC_MAPPING_USERNAME_HANDLER) ;
+
+		if(val == null) {
+			val = DEFAULT_SYNC_MAPPING_USERNAME_HANDLER;
+		}
+		return val;
+	}
+
+	public String getUserSyncMappingGroupNameHandler() {
+		String val =  prop.getProperty(SYNC_MAPPING_GROUPNAME_HANDLER) ;
+
+		if(val == null) {
+			val = DEFAULT_SYNC_MAPPING_GROUPNAME_HANDLER;
+		}
+		return val;
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/a57740e2/ugsync/src/main/java/org/apache/ranger/usergroupsync/AbstractMapper.java
----------------------------------------------------------------------
diff --git a/ugsync/src/main/java/org/apache/ranger/usergroupsync/AbstractMapper.java b/ugsync/src/main/java/org/apache/ranger/usergroupsync/AbstractMapper.java
new file mode 100644
index 0000000..fc5d10b
--- /dev/null
+++ b/ugsync/src/main/java/org/apache/ranger/usergroupsync/AbstractMapper.java
@@ -0,0 +1,40 @@
+/*
+ * 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.ranger.usergroupsync;
+
+import org.apache.log4j.Logger;
+
+public abstract class AbstractMapper implements Mapper {
+	
+	static Logger logger = Logger.getLogger(AbstractMapper.class);
+
+	@Override
+	public void init(String baseProperty) {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	public String transform(String attrValue) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/a57740e2/ugsync/src/main/java/org/apache/ranger/usergroupsync/Mapper.java
----------------------------------------------------------------------
diff --git a/ugsync/src/main/java/org/apache/ranger/usergroupsync/Mapper.java b/ugsync/src/main/java/org/apache/ranger/usergroupsync/Mapper.java
new file mode 100644
index 0000000..820fe20
--- /dev/null
+++ b/ugsync/src/main/java/org/apache/ranger/usergroupsync/Mapper.java
@@ -0,0 +1,26 @@
+/*
+ * 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.ranger.usergroupsync;
+
+public interface Mapper {
+	public void init(String baseProperty);
+
+    public String transform(String attrValue);
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/a57740e2/ugsync/src/main/java/org/apache/ranger/usergroupsync/RegEx.java
----------------------------------------------------------------------
diff --git a/ugsync/src/main/java/org/apache/ranger/usergroupsync/RegEx.java b/ugsync/src/main/java/org/apache/ranger/usergroupsync/RegEx.java
new file mode 100644
index 0000000..b655536
--- /dev/null
+++ b/ugsync/src/main/java/org/apache/ranger/usergroupsync/RegEx.java
@@ -0,0 +1,83 @@
+/*
+ * 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.ranger.usergroupsync;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.ranger.unixusersync.config.UserGroupSyncConfig;
+
+public class RegEx extends AbstractMapper {
+	private UserGroupSyncConfig config = UserGroupSyncConfig.getInstance();
+	private LinkedHashMap<String, String> replacementPattern;
+
+	public LinkedHashMap<String, String> getReplacementPattern() {
+		return replacementPattern;
+	}
+
+	@Override
+	public void init (String baseProperty) {
+		logger.info("Initializing for " + baseProperty);
+		List<String> regexPatterns = config.getAllRegexPatterns(baseProperty);
+		populateReplacementPatterns(baseProperty, regexPatterns);
+	}
+
+	protected void populateReplacementPatterns(String baseProperty, List<String> regexPatterns) {
+		replacementPattern = new LinkedHashMap<String, String>();
+		Pattern p = Pattern.compile("s/([^/]*)/([^/]*)/(g)?");
+		for (String regexPattern : regexPatterns) {
+			Matcher m = p.matcher(regexPattern);
+			if (!m.matches()) {
+				logger.warn("Invalid RegEx " + regexPattern + " and hence skipping this regex property");
+			}
+			m = m.reset();
+			while (m.find()) {
+				String matchPattern = m.group(1);
+				String replacement = m.group(2);
+				if (matchPattern != null && !matchPattern.isEmpty() && replacement != null) {
+					replacementPattern.put(matchPattern, Matcher.quoteReplacement(replacement));
+					if (logger.isDebugEnabled()) {
+						logger.debug(baseProperty + " match pattern = " + matchPattern + " and replacement string = " + replacement);
+					}
+				}
+			}
+		}
+	}
+
+	@Override
+	public String transform (String attrValue) {
+		String result = attrValue;
+		if (replacementPattern != null && !replacementPattern.isEmpty()) {
+			for (String matchPattern : replacementPattern.keySet()) {
+				Pattern p = Pattern.compile(matchPattern);
+				Matcher m = p.matcher(result);
+				if (m.find()) {
+					String replacement = replacementPattern.get(matchPattern);
+					if (replacement != null) {
+						result = m.replaceAll(replacement);
+					}
+				}
+			}
+		}
+		return result;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/a57740e2/ugsync/src/test/java/org/apache/ranger/usergroupsync/RegExTest.java
----------------------------------------------------------------------
diff --git a/ugsync/src/test/java/org/apache/ranger/usergroupsync/RegExTest.java b/ugsync/src/test/java/org/apache/ranger/usergroupsync/RegExTest.java
new file mode 100644
index 0000000..d74eb2b
--- /dev/null
+++ b/ugsync/src/test/java/org/apache/ranger/usergroupsync/RegExTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.ranger.usergroupsync;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class RegExTest {
+	protected String userNameBaseProperty = "ranger.usersync.mapping.username.regex";
+    protected String groupNameBaseProperty = "ranger.usersync.mapping.groupname.regex";
+    protected RegEx userNameRegEx = null;
+    protected RegEx groupNameRegEx = null;
+    List<String> userRegexPatterns = null;
+    List<String> groupRegexPatterns = null;
+
+	@Before
+	public void setUp() throws Exception {
+		userNameRegEx = new RegEx();
+        //userNameRegEx.init(userNameBaseProperty);
+        userRegexPatterns = new ArrayList<String>();
+        groupNameRegEx = new RegEx();
+        //groupNameRegEx.init(groupNameBaseProperty);
+        groupRegexPatterns = new ArrayList<String>();
+	}
+
+	@Test
+    public void testUserNameTransform() {
+            userRegexPatterns.add("s/\\s/_/");
+            userNameRegEx.populateReplacementPatterns(userNameBaseProperty, userRegexPatterns);
+            assertEquals("test_user", userNameRegEx.transform("test user"));
+    }
+
+    @Test
+    public void testGroupNameTransform() {
+            groupRegexPatterns.add("s/\\s/_/g");
+            groupRegexPatterns.add("s/_/$/g");
+            groupNameRegEx.populateReplacementPatterns(userNameBaseProperty, groupRegexPatterns);
+            assertEquals("ldap$grp", groupNameRegEx.transform("ldap grp"));
+    }
+
+    @Test
+    public void testEmptyTransform() {
+            assertEquals("test user", userNameRegEx.transform("test user"));
+            assertEquals("ldap grp", groupNameRegEx.transform("ldap grp"));
+    }
+
+    @Test
+    public void testTransform() {
+            userRegexPatterns.add("s/\\s/_/g");
+            userNameRegEx.populateReplacementPatterns(userNameBaseProperty, userRegexPatterns);
+            assertEquals("test_user", userNameRegEx.transform("test user"));
+            assertEquals("ldap grp", groupNameRegEx.transform("ldap grp"));
+    }
+
+    @Test
+    public void testTransform1() {
+            userRegexPatterns.add("s/\\\\/ /g");
+            userRegexPatterns.add("s//_/g");
+            userNameRegEx.populateReplacementPatterns(userNameBaseProperty, userRegexPatterns);
+            groupRegexPatterns.add("s/\\s//g");
+            groupRegexPatterns.add("s/\\s");
+            groupNameRegEx.populateReplacementPatterns(userNameBaseProperty, groupRegexPatterns);
+            assertEquals("test user", userNameRegEx.transform("test\\user"));
+            assertEquals("ldapgrp", groupNameRegEx.transform("ldap grp"));
+    }
+
+}