You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by mo...@apache.org on 2017/09/01 13:17:38 UTC

[40/64] [partial] knox git commit: KNOX-998 - Refactoring save 1

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/knox/gateway/identityasserter/filter/DefaultIdentityAssertionFilterTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/knox/gateway/identityasserter/filter/DefaultIdentityAssertionFilterTest.java b/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/knox/gateway/identityasserter/filter/DefaultIdentityAssertionFilterTest.java
new file mode 100644
index 0000000..adfc95d
--- /dev/null
+++ b/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/knox/gateway/identityasserter/filter/DefaultIdentityAssertionFilterTest.java
@@ -0,0 +1,173 @@
+/**
+ * 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.knox.gateway.identityasserter.filter;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.security.Principal;
+
+import javax.security.auth.Subject;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+
+import org.apache.knox.gateway.security.GroupPrincipal;
+import org.apache.knox.gateway.security.PrimaryPrincipal;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class DefaultIdentityAssertionFilterTest {
+
+  @Test
+  public void testInitParameters() throws Exception {
+    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    ServletContext context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+
+    IdentityAsserterFilter filter = new IdentityAsserterFilter();
+    Subject subject = new Subject();
+    
+    subject.getPrincipals().add(new PrimaryPrincipal("lmccay"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admin"));
+    
+    filter.init(config);
+    String username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
+    String[] groups = filter.mapGroupPrincipals(username, subject);
+    assertEquals("lmccay", username);
+    assertNull(groups); // means for the caller to use the existing subject groups
+    
+    config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "lmccay,kminder=hdfs;newuser=mapred" ).anyTimes();
+    EasyMock.expect(config.getInitParameter("group.principal.mapping") ).andReturn( "kminder=group1;lmccay=mrgroup,mrducks" ).anyTimes();
+    context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.replay( config );
+    filter.init(config);
+    username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
+    String[] mappedGroups = filter.mapGroupPrincipals(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject);
+    assertEquals("hdfs", username);
+    assertTrue("mrgroup not found in groups: " + mappedGroups, groupFoundIn("mrgroup", mappedGroups));
+    assertTrue("mrducks not found in groups: " + mappedGroups, groupFoundIn("mrducks", mappedGroups));
+    assertFalse("group1 WAS found in groups: " + mappedGroups, groupFoundIn("group1", mappedGroups));
+
+    subject = new Subject();
+    
+    subject.getPrincipals().add(new PrimaryPrincipal("kminder"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admin"));
+    
+    config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "lmccay,kminder=hdfs;newuser=mapred" ).anyTimes();
+    EasyMock.expect(config.getInitParameter("group.principal.mapping") ).andReturn( "kminder=group1;lmccay=mrgroup,mrducks" ).anyTimes();
+    context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.replay( config );
+    filter.init(config);
+    username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
+    mappedGroups = filter.mapGroupPrincipals(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject);
+    assertEquals("hdfs", username);
+    assertTrue("group1 not found in groups: " + mappedGroups, groupFoundIn("group1", mappedGroups));
+  }
+
+  /**
+   * @param string
+   * @return
+   */
+  private boolean groupFoundIn(String expected, String[] mappedGroups) {
+    if (mappedGroups == null) return false;
+    for(int i = 0; i < mappedGroups.length; i++) {
+      if (mappedGroups[i].equals(expected)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @Test
+  public void testContextParameters() throws Exception {
+    // for backward compatibility of old deployment contributor's method
+    // of adding init params to the servlet context instead of to the filter.
+    // There is the possibility that previously deployed topologies will have
+    // init params in web.xml at the context level instead of the filter level.
+    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    ServletContext context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+
+    IdentityAsserterFilter filter = new IdentityAsserterFilter();
+    Subject subject = new Subject();
+    
+    subject.getPrincipals().add(new PrimaryPrincipal("lmccay"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admin"));
+    
+    filter.init(config);
+    String username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
+    String[] groups = filter.mapGroupPrincipals(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject);
+//    String[] groups = filter.mapGroupPrincipals(username, subject);
+    assertEquals("lmccay", username);
+    assertNull(groups); // means for the caller to use the existing subject groups
+    
+    config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "lmccay,kminder=hdfs;newuser=mapred" ).anyTimes();
+    EasyMock.expect(context.getInitParameter("group.principal.mapping") ).andReturn( "kminder=group1;lmccay=mrgroup,mrducks" ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+    filter.init(config);
+    username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
+    groups = filter.mapGroupPrincipals(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject);
+    assertEquals("hdfs", username);
+    assertTrue("mrgroup not found in groups: " + groups, groupFoundIn("mrgroup", groups));
+    assertTrue("mrducks not found in groups: " + groups, groupFoundIn("mrducks", groups));
+    assertFalse("group1 WAS found in groups: " + groups, groupFoundIn("group1", groups));
+
+    subject = new Subject();
+    
+    subject.getPrincipals().add(new PrimaryPrincipal("kminder"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admin"));
+    
+    config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "lmccay,kminder=hdfs;newuser=mapred" ).anyTimes();
+    EasyMock.expect(context.getInitParameter("group.principal.mapping") ).andReturn( "kminder=group1;lmccay=mrgroup,mrducks" ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+    filter.init(config);
+    username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
+    assertEquals("hdfs", username);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-pseudo/src/test/resources/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-pseudo/src/test/resources/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml b/gateway-provider-identity-assertion-pseudo/src/test/resources/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml
deleted file mode 100644
index cf28b92..0000000
--- a/gateway-provider-identity-assertion-pseudo/src/test/resources/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-  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.
--->
-<rules>
-
-    <rule name="test-rule-username">
-        <match pattern="*://{host}:{port}/{path=**}?{**}"/>
-        <rewrite template="test-output-scheme://{host}:{port}/test-output-path/{path=**}?user.name={$username}?{**}?test-query-output-name=test-query-output-value"/>
-    </rule>
-
-</rules>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-pseudo/src/test/resources/org/apache/knox/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-pseudo/src/test/resources/org/apache/knox/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml b/gateway-provider-identity-assertion-pseudo/src/test/resources/org/apache/knox/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml
new file mode 100644
index 0000000..cf28b92
--- /dev/null
+++ b/gateway-provider-identity-assertion-pseudo/src/test/resources/org/apache/knox/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml
@@ -0,0 +1,24 @@
+<!--
+  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.
+-->
+<rules>
+
+    <rule name="test-rule-username">
+        <match pattern="*://{host}:{port}/{path=**}?{**}"/>
+        <rewrite template="test-output-scheme://{host}:{port}/test-output-path/{path=**}?user.name={$username}?{**}?test-query-output-name=test-query-output-value"/>
+    </rule>
+
+</rules>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-regex/src/main/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-regex/src/main/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributor.java b/gateway-provider-identity-assertion-regex/src/main/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributor.java
deleted file mode 100644
index 6ce5676..0000000
--- a/gateway-provider-identity-assertion-regex/src/main/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributor.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * 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.hadoop.gateway.identityasserter.regex.filter;
-
-import org.apache.hadoop.gateway.identityasserter.common.filter.AbstractIdentityAsserterDeploymentContributor;
-
-public class RegexIdentityAsserterDeploymentContributor extends AbstractIdentityAsserterDeploymentContributor {
-
-  @Override
-  public String getName() {
-    return "Regex";
-  }
-
-  protected String getFilterClassname() {
-    return RegexIdentityAssertionFilter.class.getName();
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-regex/src/main/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-regex/src/main/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilter.java b/gateway-provider-identity-assertion-regex/src/main/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilter.java
deleted file mode 100644
index 209178b..0000000
--- a/gateway-provider-identity-assertion-regex/src/main/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilter.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * 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.hadoop.gateway.identityasserter.regex.filter;
-
-import javax.security.auth.Subject;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-
-import org.apache.hadoop.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter;
-import org.apache.hadoop.gateway.security.principal.PrincipalMappingException;
-
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-
-public class RegexIdentityAssertionFilter extends CommonIdentityAssertionFilter {
-
-  private String input = null;
-  private String output = null;
-  private Map<String,String> dict;
-  RegexTemplate template;
-  
-  @Override
-  public void init(FilterConfig filterConfig) throws ServletException {
-    super.init(filterConfig);
-    try {
-      input = filterConfig.getInitParameter( "input" );
-      if( input == null ) {
-        input = "";
-      }
-      output = filterConfig.getInitParameter( "output" );
-      if( output == null ) {
-        output = "";
-      }
-      dict = loadDictionary( filterConfig.getInitParameter( "lookup" ) );
-      template = new RegexTemplate( input, output, dict );
-    } catch ( PrincipalMappingException e ) {
-      throw new ServletException( e );
-    }
-  }
-
-  public String[] mapGroupPrincipals(String mappedPrincipalName, Subject subject) {
-    // Returning null will allow existing Subject group principals to remain the same
-    return null;
-  }
-
-  public String mapUserPrincipal(String principalName) {
-    return template.apply( principalName );
-  }
-
-  private Map<String, String> loadDictionary( String config ) throws PrincipalMappingException {
-    Map<String,String> dict = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-    if( config != null && !config.isEmpty() ) {
-      try {
-        StringTokenizer t = new StringTokenizer( config, ";" );
-        while( t.hasMoreTokens() ) {
-          String nvp = t.nextToken();
-          String[] a = nvp.split( "=" );
-          dict.put( a[0].trim(), a[1].trim() );
-        }
-        return dict;
-      } catch( Exception e ) {
-        dict.clear();
-        throw new PrincipalMappingException(
-            "Unable to load lookup dictionary from provided configuration: " + config +
-                ".  No principal mapping will be provided.", e );
-      }
-    }
-    return dict;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-regex/src/main/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexTemplate.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-regex/src/main/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexTemplate.java b/gateway-provider-identity-assertion-regex/src/main/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexTemplate.java
deleted file mode 100644
index 0a9912d..0000000
--- a/gateway-provider-identity-assertion-regex/src/main/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexTemplate.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.hadoop.gateway.identityasserter.regex.filter;
-
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class RegexTemplate {
-
-  private static Pattern directPattern = Pattern.compile( "\\{(\\[?\\d+?\\]?)\\}" );
-  private static Pattern indirectPattern = Pattern.compile( "\\[(\\d+?)\\]" );
-
-  Pattern inputPattern;
-  String outputTemplate;
-  Map<String,String> lookupTable;
-
-  public RegexTemplate( String regex, String template ) {
-    this( regex, template, null );
-  }
-
-  public RegexTemplate( String regex, String template, Map<String,String> map ) {
-    this.inputPattern = Pattern.compile( regex );
-    this.outputTemplate = template;
-    this.lookupTable = map;
-  }
-
-  public String apply( String input ) {
-    String output = outputTemplate;
-    Matcher inputMatcher = inputPattern.matcher( input );
-    if( inputMatcher.find() ) {
-      output = expandTemplate( inputMatcher, output );
-    }
-    return output;
-  }
-
-  private String expandTemplate( Matcher inputMatcher, String output ) {
-    Matcher directMatcher = directPattern.matcher( output );
-    while( directMatcher.find() ) {
-      String lookupValue = null;
-      String lookupStr = directMatcher.group( 1 );
-      Matcher indirectMatcher = indirectPattern.matcher( lookupStr );
-      if( indirectMatcher.find() ) {
-        lookupStr = indirectMatcher.group( 1 );
-        int lookupIndex = Integer.parseInt( lookupStr );
-        if( lookupTable != null ) {
-          String lookupKey = inputMatcher.group( lookupIndex );
-          lookupValue = lookupTable.get( lookupKey );
-        }
-      } else {
-        int lookupIndex = Integer.parseInt( lookupStr );
-        lookupValue = inputMatcher.group( lookupIndex );
-      }
-      output = directMatcher.replaceFirst( lookupValue == null ? "" : lookupValue );
-      directMatcher = directPattern.matcher( output );
-    }
-    return output;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributor.java b/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributor.java
new file mode 100644
index 0000000..f40895b
--- /dev/null
+++ b/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributor.java
@@ -0,0 +1,34 @@
+/**
+ * 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.knox.gateway.identityasserter.regex.filter;
+
+import org.apache.knox.gateway.identityasserter.common.filter.AbstractIdentityAsserterDeploymentContributor;
+
+public class RegexIdentityAsserterDeploymentContributor extends
+    AbstractIdentityAsserterDeploymentContributor {
+
+  @Override
+  public String getName() {
+    return "Regex";
+  }
+
+  protected String getFilterClassname() {
+    return RegexIdentityAssertionFilter.class.getName();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilter.java b/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilter.java
new file mode 100644
index 0000000..4cc86ae
--- /dev/null
+++ b/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilter.java
@@ -0,0 +1,88 @@
+/**
+ * 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.knox.gateway.identityasserter.regex.filter;
+
+import javax.security.auth.Subject;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+
+import org.apache.knox.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter;
+import org.apache.knox.gateway.security.principal.PrincipalMappingException;
+
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+
+public class RegexIdentityAssertionFilter extends
+    CommonIdentityAssertionFilter {
+
+  private String input = null;
+  private String output = null;
+  private Map<String,String> dict;
+  RegexTemplate template;
+  
+  @Override
+  public void init(FilterConfig filterConfig) throws ServletException {
+    super.init(filterConfig);
+    try {
+      input = filterConfig.getInitParameter( "input" );
+      if( input == null ) {
+        input = "";
+      }
+      output = filterConfig.getInitParameter( "output" );
+      if( output == null ) {
+        output = "";
+      }
+      dict = loadDictionary( filterConfig.getInitParameter( "lookup" ) );
+      template = new RegexTemplate( input, output, dict );
+    } catch ( PrincipalMappingException e ) {
+      throw new ServletException( e );
+    }
+  }
+
+  public String[] mapGroupPrincipals(String mappedPrincipalName, Subject subject) {
+    // Returning null will allow existing Subject group principals to remain the same
+    return null;
+  }
+
+  public String mapUserPrincipal(String principalName) {
+    return template.apply( principalName );
+  }
+
+  private Map<String, String> loadDictionary( String config ) throws PrincipalMappingException {
+    Map<String,String> dict = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+    if( config != null && !config.isEmpty() ) {
+      try {
+        StringTokenizer t = new StringTokenizer( config, ";" );
+        while( t.hasMoreTokens() ) {
+          String nvp = t.nextToken();
+          String[] a = nvp.split( "=" );
+          dict.put( a[0].trim(), a[1].trim() );
+        }
+        return dict;
+      } catch( Exception e ) {
+        dict.clear();
+        throw new PrincipalMappingException(
+            "Unable to load lookup dictionary from provided configuration: " + config +
+                ".  No principal mapping will be provided.", e );
+      }
+    }
+    return dict;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexTemplate.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexTemplate.java b/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexTemplate.java
new file mode 100644
index 0000000..e8f108e
--- /dev/null
+++ b/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexTemplate.java
@@ -0,0 +1,75 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.knox.gateway.identityasserter.regex.filter;
+
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class RegexTemplate {
+
+  private static Pattern directPattern = Pattern.compile( "\\{(\\[?\\d+?\\]?)\\}" );
+  private static Pattern indirectPattern = Pattern.compile( "\\[(\\d+?)\\]" );
+
+  Pattern inputPattern;
+  String outputTemplate;
+  Map<String,String> lookupTable;
+
+  public RegexTemplate( String regex, String template ) {
+    this( regex, template, null );
+  }
+
+  public RegexTemplate( String regex, String template, Map<String,String> map ) {
+    this.inputPattern = Pattern.compile( regex );
+    this.outputTemplate = template;
+    this.lookupTable = map;
+  }
+
+  public String apply( String input ) {
+    String output = outputTemplate;
+    Matcher inputMatcher = inputPattern.matcher( input );
+    if( inputMatcher.find() ) {
+      output = expandTemplate( inputMatcher, output );
+    }
+    return output;
+  }
+
+  private String expandTemplate( Matcher inputMatcher, String output ) {
+    Matcher directMatcher = directPattern.matcher( output );
+    while( directMatcher.find() ) {
+      String lookupValue = null;
+      String lookupStr = directMatcher.group( 1 );
+      Matcher indirectMatcher = indirectPattern.matcher( lookupStr );
+      if( indirectMatcher.find() ) {
+        lookupStr = indirectMatcher.group( 1 );
+        int lookupIndex = Integer.parseInt( lookupStr );
+        if( lookupTable != null ) {
+          String lookupKey = inputMatcher.group( lookupIndex );
+          lookupValue = lookupTable.get( lookupKey );
+        }
+      } else {
+        int lookupIndex = Integer.parseInt( lookupStr );
+        lookupValue = inputMatcher.group( lookupIndex );
+      }
+      output = directMatcher.replaceFirst( lookupValue == null ? "" : lookupValue );
+      directMatcher = directPattern.matcher( output );
+    }
+    return output;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-regex/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-regex/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor b/gateway-provider-identity-assertion-regex/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
deleted file mode 100644
index 0dd2d2e..0000000
--- a/gateway-provider-identity-assertion-regex/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
+++ /dev/null
@@ -1,19 +0,0 @@
-##########################################################################
-# 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.
-##########################################################################
-
-org.apache.hadoop.gateway.identityasserter.regex.filter.RegexIdentityAsserterDeploymentContributor
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-regex/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-regex/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor b/gateway-provider-identity-assertion-regex/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
new file mode 100644
index 0000000..4e1b9a4
--- /dev/null
+++ b/gateway-provider-identity-assertion-regex/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
@@ -0,0 +1,19 @@
+##########################################################################
+# 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.
+##########################################################################
+
+org.apache.knox.gateway.identityasserter.regex.filter.RegexIdentityAsserterDeploymentContributor
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-regex/src/test/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributorTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-regex/src/test/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributorTest.java b/gateway-provider-identity-assertion-regex/src/test/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributorTest.java
deleted file mode 100644
index 6d93359..0000000
--- a/gateway-provider-identity-assertion-regex/src/test/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributorTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * 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.hadoop.gateway.identityasserter.regex.filter;
-
-import org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor;
-import org.junit.Test;
-
-import java.util.Iterator;
-import java.util.ServiceLoader;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.fail;
-
-public class RegexIdentityAsserterDeploymentContributorTest {
-
-  @Test
-  public void testServiceLoader() throws Exception {
-    ServiceLoader<ProviderDeploymentContributor> loader = ServiceLoader.load( ProviderDeploymentContributor.class );
-    Iterator<ProviderDeploymentContributor> iterator = loader.iterator();
-    assertThat( "Service iterator empty.", iterator.hasNext() );
-    while( iterator.hasNext() ) {
-      Object object = iterator.next();
-      if( object instanceof RegexIdentityAsserterDeploymentContributor ) {
-        return;
-      }
-    }
-    fail( "Failed to find " + RegexIdentityAsserterDeploymentContributor.class.getName() + " via service loader." );
-  }
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-regex/src/test/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilterTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-regex/src/test/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilterTest.java b/gateway-provider-identity-assertion-regex/src/test/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilterTest.java
deleted file mode 100644
index f8ba323..0000000
--- a/gateway-provider-identity-assertion-regex/src/test/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilterTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- * 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.hadoop.gateway.identityasserter.regex.filter;
-
-import org.apache.hadoop.gateway.security.GroupPrincipal;
-import org.apache.hadoop.gateway.security.PrimaryPrincipal;
-import org.easymock.EasyMock;
-import org.junit.Test;
-
-import javax.security.auth.Subject;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletContext;
-
-import java.security.Principal;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-
-public class RegexIdentityAssertionFilterTest {
-
-  @Test
-  public void testExtractUsernameFromEmail() throws Exception {
-    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
-    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    ServletContext context = EasyMock.createNiceMock(ServletContext.class);
-    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
-    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    EasyMock.replay( config );
-    EasyMock.replay( context );
-
-    RegexIdentityAssertionFilter filter = new RegexIdentityAssertionFilter();
-
-    Subject subject = new Subject();
-    subject.getPrincipals().add(new PrimaryPrincipal( "member@us.apache.org" ) );
-    subject.getPrincipals().add(new GroupPrincipal( "user" ) );
-    subject.getPrincipals().add( new GroupPrincipal( "admin" ) );
-
-    // First test is with no config.  Since the output template is the empty string that should be the result.
-    filter.init(config);
-    String actual = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(actual, subject);
-    assertThat( actual, is( "" ) );
-    assertThat( groups, is( nullValue() ) ); // means for the caller to use the existing subject groups
-
-    // Test what is effectively a static mapping
-    config = EasyMock.createNiceMock( FilterConfig.class );
-    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    context = EasyMock.createNiceMock(ServletContext.class);
-    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
-    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    EasyMock.expect(config.getInitParameter( "output" ) ).andReturn( "test-output" ).anyTimes();
-    EasyMock.replay( config );
-    EasyMock.replay( context );
-    filter.init( config );
-    actual = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    assertEquals( actual, "test-output" );
-
-    // Test username extraction.
-    config = EasyMock.createNiceMock( FilterConfig.class );
-    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    context = EasyMock.createNiceMock(ServletContext.class);
-    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
-    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    EasyMock.expect(config.getInitParameter( "input" ) ).andReturn( "(.*)@.*" ).anyTimes();
-    EasyMock.expect(config.getInitParameter( "output" ) ).andReturn( "prefix_{1}_suffix" ).anyTimes();
-    EasyMock.replay( config );
-    EasyMock.replay( context );
-    filter.init( config );
-    actual = filter.mapUserPrincipal( "member@us.apache.org" );
-    assertEquals( actual, "prefix_member_suffix" );
-
-  }
-
-  @Test
-  public void testMapDomain() throws Exception {
-    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
-    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    ServletContext context = EasyMock.createNiceMock(ServletContext.class);
-    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
-    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    EasyMock.replay( config );
-    EasyMock.replay( context );
-
-    RegexIdentityAssertionFilter filter = new RegexIdentityAssertionFilter();
-
-    Subject subject = new Subject();
-    subject.getPrincipals().add(new PrimaryPrincipal( "member@us.apache.org" ) );
-    subject.getPrincipals().add(new GroupPrincipal( "user" ) );
-    subject.getPrincipals().add( new GroupPrincipal( "admin" ) );
-
-    String actual;
-
-    // Test dictionary lookup.
-    config = EasyMock.createNiceMock( FilterConfig.class );
-    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    context = EasyMock.createNiceMock(ServletContext.class);
-    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
-    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    EasyMock.expect(config.getInitParameter( "input" ) ).andReturn( "(.*)@(.*?)\\..*" ).anyTimes();
-    EasyMock.expect(config.getInitParameter( "output" ) ).andReturn( "prefix_{1}_suffix:{[2]}" ).anyTimes();
-    EasyMock.expect(config.getInitParameter( "lookup" ) ).andReturn( "us=USA;ca=CANADA" ).anyTimes();
-    EasyMock.replay( config );
-    EasyMock.replay( context );
-    filter.init( config );
-    actual = filter.mapUserPrincipal( "member1@us.apache.org" );
-    assertThat( actual, is( "prefix_member1_suffix:USA" ) );
-    actual = filter.mapUserPrincipal( "member2@ca.apache.org" );
-    assertThat( actual, is( "prefix_member2_suffix:CANADA" ) );
-    actual = filter.mapUserPrincipal( "member3@nj.apache.org" );
-    assertThat( actual, is( "prefix_member3_suffix:" ) );
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-regex/src/test/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexTemplateTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-regex/src/test/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexTemplateTest.java b/gateway-provider-identity-assertion-regex/src/test/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexTemplateTest.java
deleted file mode 100644
index b32cd41..0000000
--- a/gateway-provider-identity-assertion-regex/src/test/java/org/apache/hadoop/gateway/identityasserter/regex/filter/RegexTemplateTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.hadoop.gateway.identityasserter.regex.filter;
-
-import org.junit.Test;
-
-import java.util.Map;
-import java.util.TreeMap;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.Is.is;
-
-public class RegexTemplateTest {
-
-  @Test
-  public void testExtractUsernameFromEmailAddress() {
-
-    RegexTemplate template;
-    String actual;
-
-    template = new RegexTemplate( "(.*)@.*", "prefix_{1}_suffix" );
-    actual = template.apply( "member@apache.org" );
-    assertThat( actual, is( "prefix_member_suffix" ) );
-
-    template = new RegexTemplate( "(.*)@.*", "prefix_{0}_suffix" );
-    actual = template.apply( "member@apache.org" );
-    assertThat( actual, is( "prefix_member@apache.org_suffix" ) );
-
-    template = new RegexTemplate( "(.*)@.*", "prefix_{1}_{a}_suffix" );
-    actual = template.apply( "member@apache.org" );
-    assertThat( actual, is( "prefix_member_{a}_suffix" ) );
-
-  }
-
-  @Test
-  public void testExtractUsernameFromEmailAddressAndMapDomain() {
-
-    RegexTemplate template;
-    Map<String,String> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-    map.put( "us", "USA" );
-    map.put( "ca", "CANADA" );
-
-    String actual;
-
-    template = new RegexTemplate( "(.*)@(.*?)\\..*", "prefix_{1}:{[2]}_suffix", map );
-    actual = template.apply( "member@us.apache.org" );
-    assertThat( actual, is( "prefix_member:USA_suffix" ) );
-
-    actual = template.apply( "member@ca.apache.org" );
-    assertThat( actual, is( "prefix_member:CANADA_suffix" ) );
-
-    actual = template.apply( "member@nj.apache.org" );
-    assertThat( actual, is( "prefix_member:_suffix" ) );
-
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributorTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributorTest.java b/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributorTest.java
new file mode 100644
index 0000000..db0c6b3
--- /dev/null
+++ b/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAsserterDeploymentContributorTest.java
@@ -0,0 +1,44 @@
+/**
+ * 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.knox.gateway.identityasserter.regex.filter;
+
+import org.apache.knox.gateway.deploy.ProviderDeploymentContributor;
+import org.junit.Test;
+
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.fail;
+
+public class RegexIdentityAsserterDeploymentContributorTest {
+
+  @Test
+  public void testServiceLoader() throws Exception {
+    ServiceLoader<ProviderDeploymentContributor> loader = ServiceLoader.load( ProviderDeploymentContributor.class );
+    Iterator<ProviderDeploymentContributor> iterator = loader.iterator();
+    assertThat( "Service iterator empty.", iterator.hasNext() );
+    while( iterator.hasNext() ) {
+      Object object = iterator.next();
+      if( object instanceof RegexIdentityAsserterDeploymentContributor ) {
+        return;
+      }
+    }
+    fail( "Failed to find " + RegexIdentityAsserterDeploymentContributor.class.getName() + " via service loader." );
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilterTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilterTest.java b/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilterTest.java
new file mode 100644
index 0000000..3a61c37
--- /dev/null
+++ b/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilterTest.java
@@ -0,0 +1,130 @@
+/**
+ * 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.knox.gateway.identityasserter.regex.filter;
+
+import org.apache.knox.gateway.security.GroupPrincipal;
+import org.apache.knox.gateway.security.PrimaryPrincipal;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import javax.security.auth.Subject;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+
+import java.security.Principal;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+public class RegexIdentityAssertionFilterTest {
+
+  @Test
+  public void testExtractUsernameFromEmail() throws Exception {
+    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    ServletContext context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+
+    RegexIdentityAssertionFilter filter = new RegexIdentityAssertionFilter();
+
+    Subject subject = new Subject();
+    subject.getPrincipals().add(new PrimaryPrincipal( "member@us.apache.org" ) );
+    subject.getPrincipals().add(new GroupPrincipal( "user" ) );
+    subject.getPrincipals().add( new GroupPrincipal( "admin" ) );
+
+    // First test is with no config.  Since the output template is the empty string that should be the result.
+    filter.init(config);
+    String actual = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
+    String[] groups = filter.mapGroupPrincipals(actual, subject);
+    assertThat( actual, is( "" ) );
+    assertThat( groups, is( nullValue() ) ); // means for the caller to use the existing subject groups
+
+    // Test what is effectively a static mapping
+    config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    EasyMock.expect(config.getInitParameter( "output" ) ).andReturn( "test-output" ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+    filter.init( config );
+    actual = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
+    assertEquals( actual, "test-output" );
+
+    // Test username extraction.
+    config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    EasyMock.expect(config.getInitParameter( "input" ) ).andReturn( "(.*)@.*" ).anyTimes();
+    EasyMock.expect(config.getInitParameter( "output" ) ).andReturn( "prefix_{1}_suffix" ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+    filter.init( config );
+    actual = filter.mapUserPrincipal( "member@us.apache.org" );
+    assertEquals( actual, "prefix_member_suffix" );
+
+  }
+
+  @Test
+  public void testMapDomain() throws Exception {
+    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    ServletContext context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+
+    RegexIdentityAssertionFilter filter = new RegexIdentityAssertionFilter();
+
+    Subject subject = new Subject();
+    subject.getPrincipals().add(new PrimaryPrincipal( "member@us.apache.org" ) );
+    subject.getPrincipals().add(new GroupPrincipal( "user" ) );
+    subject.getPrincipals().add( new GroupPrincipal( "admin" ) );
+
+    String actual;
+
+    // Test dictionary lookup.
+    config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    EasyMock.expect(config.getInitParameter( "input" ) ).andReturn( "(.*)@(.*?)\\..*" ).anyTimes();
+    EasyMock.expect(config.getInitParameter( "output" ) ).andReturn( "prefix_{1}_suffix:{[2]}" ).anyTimes();
+    EasyMock.expect(config.getInitParameter( "lookup" ) ).andReturn( "us=USA;ca=CANADA" ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+    filter.init( config );
+    actual = filter.mapUserPrincipal( "member1@us.apache.org" );
+    assertThat( actual, is( "prefix_member1_suffix:USA" ) );
+    actual = filter.mapUserPrincipal( "member2@ca.apache.org" );
+    assertThat( actual, is( "prefix_member2_suffix:CANADA" ) );
+    actual = filter.mapUserPrincipal( "member3@nj.apache.org" );
+    assertThat( actual, is( "prefix_member3_suffix:" ) );
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexTemplateTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexTemplateTest.java b/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexTemplateTest.java
new file mode 100644
index 0000000..3c3b06f
--- /dev/null
+++ b/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexTemplateTest.java
@@ -0,0 +1,72 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.knox.gateway.identityasserter.regex.filter;
+
+import org.junit.Test;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+public class RegexTemplateTest {
+
+  @Test
+  public void testExtractUsernameFromEmailAddress() {
+
+    RegexTemplate template;
+    String actual;
+
+    template = new RegexTemplate( "(.*)@.*", "prefix_{1}_suffix" );
+    actual = template.apply( "member@apache.org" );
+    assertThat( actual, is( "prefix_member_suffix" ) );
+
+    template = new RegexTemplate( "(.*)@.*", "prefix_{0}_suffix" );
+    actual = template.apply( "member@apache.org" );
+    assertThat( actual, is( "prefix_member@apache.org_suffix" ) );
+
+    template = new RegexTemplate( "(.*)@.*", "prefix_{1}_{a}_suffix" );
+    actual = template.apply( "member@apache.org" );
+    assertThat( actual, is( "prefix_member_{a}_suffix" ) );
+
+  }
+
+  @Test
+  public void testExtractUsernameFromEmailAddressAndMapDomain() {
+
+    RegexTemplate template;
+    Map<String,String> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+    map.put( "us", "USA" );
+    map.put( "ca", "CANADA" );
+
+    String actual;
+
+    template = new RegexTemplate( "(.*)@(.*?)\\..*", "prefix_{1}:{[2]}_suffix", map );
+    actual = template.apply( "member@us.apache.org" );
+    assertThat( actual, is( "prefix_member:USA_suffix" ) );
+
+    actual = template.apply( "member@ca.apache.org" );
+    assertThat( actual, is( "prefix_member:CANADA_suffix" ) );
+
+    actual = template.apply( "member@nj.apache.org" );
+    assertThat( actual, is( "prefix_member:_suffix" ) );
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/hadoop/gateway/identityasserter/switchcase/SwitchCaseIdentityAsserterDeploymentContributor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/hadoop/gateway/identityasserter/switchcase/SwitchCaseIdentityAsserterDeploymentContributor.java b/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/hadoop/gateway/identityasserter/switchcase/SwitchCaseIdentityAsserterDeploymentContributor.java
deleted file mode 100644
index e58665b..0000000
--- a/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/hadoop/gateway/identityasserter/switchcase/SwitchCaseIdentityAsserterDeploymentContributor.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * 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.hadoop.gateway.identityasserter.switchcase;
-
-import org.apache.hadoop.gateway.identityasserter.common.filter.AbstractIdentityAsserterDeploymentContributor;
-
-public class SwitchCaseIdentityAsserterDeploymentContributor extends AbstractIdentityAsserterDeploymentContributor {
-
-  public String getName() {
-    return "SwitchCase";
-  }
-
-  protected String getFilterClassname() {
-    return SwitchCaseIdentityAssertionFilter.class.getName();
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/hadoop/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/hadoop/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilter.java b/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/hadoop/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilter.java
deleted file mode 100644
index 09163b7..0000000
--- a/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/hadoop/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilter.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * 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.hadoop.gateway.identityasserter.switchcase;
-
-import java.util.Set;
-import javax.security.auth.Subject;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-
-import org.apache.hadoop.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter;
-import org.apache.hadoop.gateway.security.GroupPrincipal;
-
-public class SwitchCaseIdentityAssertionFilter extends CommonIdentityAssertionFilter {
-
-  private static final String USER_INIT_PARAM = "principal.case";
-  private static final String GROUP_INIT_PARAM = "group.principal.case";
-
-  private enum SwitchCase { UPPER, LOWER, NONE }
-
-  private SwitchCase userCase = SwitchCase.LOWER;
-  private SwitchCase groupCase = SwitchCase.LOWER;
-
-  @Override
-  public void init( FilterConfig filterConfig ) throws ServletException {
-    super.init(filterConfig);
-
-    String s;
-    s = filterConfig.getInitParameter( USER_INIT_PARAM );
-    if ( s != null ) {
-      s = s.trim().toUpperCase();
-      try {
-        userCase = SwitchCase.valueOf( s );
-        groupCase = userCase;
-      } catch ( IllegalArgumentException e ) {
-        // Ignore it and use the default.
-      }
-    }
-    s = filterConfig.getInitParameter( GROUP_INIT_PARAM );
-    if ( s != null ) {
-      s = s.trim().toUpperCase();
-      try {
-        groupCase = SwitchCase.valueOf( s );
-      } catch ( IllegalArgumentException e ) {
-        // Ignore it and use the default.
-      }
-    }
-  }
-
-  @Override
-  public String mapUserPrincipal( String principalName ) {
-    return switchCase( principalName, userCase );
-  }
-
-  @Override
-  public String[] mapGroupPrincipals( String mappedPrincipalName, Subject subject ) {
-    String[] groupNames = null;
-    if ( groupCase != SwitchCase.NONE ) {
-      Set<GroupPrincipal> groups = subject.getPrincipals( GroupPrincipal.class );
-      if( groups != null && groups.size() > 0 ) {
-        groupNames = new String[ groups.size() ];
-        int i = 0;
-        for( GroupPrincipal group : groups ) {
-          groupNames[ i++ ] = switchCase( group.getName(), groupCase );
-        }
-      }
-    }
-    return groupNames;
-  }
-
-  private String switchCase( String name, SwitchCase switchCase ) {
-    if ( name != null ) {
-      switch( switchCase ) {
-        case UPPER:
-          return name.toUpperCase();
-        case LOWER:
-          return name.toLowerCase();
-      }
-    }
-    return name;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAsserterDeploymentContributor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAsserterDeploymentContributor.java b/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAsserterDeploymentContributor.java
new file mode 100644
index 0000000..a9677a5
--- /dev/null
+++ b/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAsserterDeploymentContributor.java
@@ -0,0 +1,33 @@
+/**
+ * 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.knox.gateway.identityasserter.switchcase;
+
+import org.apache.knox.gateway.identityasserter.common.filter.AbstractIdentityAsserterDeploymentContributor;
+
+public class SwitchCaseIdentityAsserterDeploymentContributor extends
+    AbstractIdentityAsserterDeploymentContributor {
+
+  public String getName() {
+    return "SwitchCase";
+  }
+
+  protected String getFilterClassname() {
+    return SwitchCaseIdentityAssertionFilter.class.getName();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilter.java b/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilter.java
new file mode 100644
index 0000000..9405c49
--- /dev/null
+++ b/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilter.java
@@ -0,0 +1,98 @@
+/**
+ * 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.knox.gateway.identityasserter.switchcase;
+
+import java.util.Set;
+import javax.security.auth.Subject;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+
+import org.apache.knox.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter;
+import org.apache.knox.gateway.security.GroupPrincipal;
+
+public class SwitchCaseIdentityAssertionFilter extends
+    CommonIdentityAssertionFilter {
+
+  private static final String USER_INIT_PARAM = "principal.case";
+  private static final String GROUP_INIT_PARAM = "group.principal.case";
+
+  private enum SwitchCase { UPPER, LOWER, NONE }
+
+  private SwitchCase userCase = SwitchCase.LOWER;
+  private SwitchCase groupCase = SwitchCase.LOWER;
+
+  @Override
+  public void init( FilterConfig filterConfig ) throws ServletException {
+    super.init(filterConfig);
+
+    String s;
+    s = filterConfig.getInitParameter( USER_INIT_PARAM );
+    if ( s != null ) {
+      s = s.trim().toUpperCase();
+      try {
+        userCase = SwitchCase.valueOf( s );
+        groupCase = userCase;
+      } catch ( IllegalArgumentException e ) {
+        // Ignore it and use the default.
+      }
+    }
+    s = filterConfig.getInitParameter( GROUP_INIT_PARAM );
+    if ( s != null ) {
+      s = s.trim().toUpperCase();
+      try {
+        groupCase = SwitchCase.valueOf( s );
+      } catch ( IllegalArgumentException e ) {
+        // Ignore it and use the default.
+      }
+    }
+  }
+
+  @Override
+  public String mapUserPrincipal( String principalName ) {
+    return switchCase( principalName, userCase );
+  }
+
+  @Override
+  public String[] mapGroupPrincipals( String mappedPrincipalName, Subject subject ) {
+    String[] groupNames = null;
+    if ( groupCase != SwitchCase.NONE ) {
+      Set<GroupPrincipal> groups = subject.getPrincipals( GroupPrincipal.class );
+      if( groups != null && groups.size() > 0 ) {
+        groupNames = new String[ groups.size() ];
+        int i = 0;
+        for( GroupPrincipal group : groups ) {
+          groupNames[ i++ ] = switchCase( group.getName(), groupCase );
+        }
+      }
+    }
+    return groupNames;
+  }
+
+  private String switchCase( String name, SwitchCase switchCase ) {
+    if ( name != null ) {
+      switch( switchCase ) {
+        case UPPER:
+          return name.toUpperCase();
+        case LOWER:
+          return name.toLowerCase();
+      }
+    }
+    return name;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-switchcase/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-switchcase/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor b/gateway-provider-identity-assertion-switchcase/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
deleted file mode 100644
index 98c62ef..0000000
--- a/gateway-provider-identity-assertion-switchcase/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
+++ /dev/null
@@ -1,18 +0,0 @@
-##########################################################################
-# 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.
-##########################################################################
-org.apache.hadoop.gateway.identityasserter.switchcase.SwitchCaseIdentityAsserterDeploymentContributor
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-switchcase/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-switchcase/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor b/gateway-provider-identity-assertion-switchcase/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
new file mode 100644
index 0000000..3e36c87
--- /dev/null
+++ b/gateway-provider-identity-assertion-switchcase/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
@@ -0,0 +1,18 @@
+##########################################################################
+# 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.
+##########################################################################
+org.apache.knox.gateway.identityasserter.switchcase.SwitchCaseIdentityAsserterDeploymentContributor
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-switchcase/src/test/java/org/apache/hadoop/gateway/identityasserter/switchcase/SwitchCaseIdentityAsserterDeploymentContributorTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-switchcase/src/test/java/org/apache/hadoop/gateway/identityasserter/switchcase/SwitchCaseIdentityAsserterDeploymentContributorTest.java b/gateway-provider-identity-assertion-switchcase/src/test/java/org/apache/hadoop/gateway/identityasserter/switchcase/SwitchCaseIdentityAsserterDeploymentContributorTest.java
deleted file mode 100644
index 3c9aacc..0000000
--- a/gateway-provider-identity-assertion-switchcase/src/test/java/org/apache/hadoop/gateway/identityasserter/switchcase/SwitchCaseIdentityAsserterDeploymentContributorTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * 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.hadoop.gateway.identityasserter.switchcase;
-
-import java.util.Iterator;
-import java.util.ServiceLoader;
-
-import org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor;
-import org.junit.Test;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.fail;
-
-public class SwitchCaseIdentityAsserterDeploymentContributorTest {
-
-  @Test
-  public void testServiceLoader() throws Exception {
-    ServiceLoader<ProviderDeploymentContributor> loader = ServiceLoader.load( ProviderDeploymentContributor.class );
-    Iterator<ProviderDeploymentContributor> iterator = loader.iterator();
-    assertThat( "Service iterator empty.", iterator.hasNext() );
-    while( iterator.hasNext() ) {
-      Object object = iterator.next();
-      if( object instanceof SwitchCaseIdentityAsserterDeploymentContributor ) {
-        return;
-      }
-    }
-    fail( "Failed to find " + SwitchCaseIdentityAsserterDeploymentContributor.class.getName() + " via service loader." );
-  }
-}