Repository: knox Updated Branches: refs/heads/master 68416ccfd -> ce3ca3ced
http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-provider-identity-assertion-concat/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-concat/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor b/gateway-provider-identity-assertion-concat/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor new file mode 100644 index 0000000..bbfd4ae --- /dev/null +++ b/gateway-provider-identity-assertion-concat/src/main/resources/META-INF/services/org.apache.hadoop.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.hadoop.gateway.identityasserter.concat.filter.ConcatIdentityAsserterDeploymentContributor \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributorTest.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributorTest.java b/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributorTest.java new file mode 100644 index 0000000..b046ef6 --- /dev/null +++ b/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributorTest.java @@ -0,0 +1,45 @@ +/** + * 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.concat.filter; + +import org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor; +import org.apache.hadoop.gateway.identityasserter.concat.filter.ConcatIdentityAsserterDeploymentContributor; +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 ConcatIdentityAsserterDeploymentContributorTest { + + @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 ConcatIdentityAsserterDeploymentContributor ) { + return; + } + } + fail( "Failed to find " + ConcatIdentityAsserterDeploymentContributor.class.getName() + " via service loader." ); + } +} http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java b/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java new file mode 100644 index 0000000..924f9d3 --- /dev/null +++ b/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java @@ -0,0 +1,78 @@ +/** + * 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.concat.filter; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.security.Principal; + +import javax.security.auth.Subject; +import javax.servlet.FilterConfig; + +import org.apache.hadoop.gateway.security.GroupPrincipal; +import org.apache.hadoop.gateway.security.PrimaryPrincipal; +import org.easymock.EasyMock; +import org.junit.Test; + +/** + * + */ +public class ConcatIdentityAssertionFilterTest { + + @Test + public void testPrefixAndSuffix() throws Exception { + FilterConfig config = EasyMock.createNiceMock( FilterConfig.class ); + EasyMock.replay( config ); + + ConcatIdentityAssertionFilter filter = new ConcatIdentityAssertionFilter(); + Subject subject = new Subject(); + + subject.getPrincipals().add(new PrimaryPrincipal("larry")); + 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(username, "larry"); + assertNull(groups); // means for the caller to use the existing subject groups + + config = EasyMock.createNiceMock( FilterConfig.class ); + EasyMock.expect(config.getInitParameter("concat.prefix") ).andReturn( "sir-" ).anyTimes(); + EasyMock.replay( config ); + filter.init(config); + username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName()); + assertEquals(username, "sir-larry"); + + config = EasyMock.createNiceMock( FilterConfig.class ); + EasyMock.expect(config.getInitParameter("concat.suffix") ).andReturn( "-tenant-1" ).anyTimes(); + EasyMock.replay( config ); + filter.init(config); + username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName()); + assertEquals(username, "larry-tenant-1"); + + config = EasyMock.createNiceMock( FilterConfig.class ); + EasyMock.expect(config.getInitParameter("concat.prefix") ).andReturn( "sir-" ).anyTimes(); + EasyMock.expect(config.getInitParameter("concat.suffix") ).andReturn( "-tenant-1" ).anyTimes(); + EasyMock.replay( config ); + filter.init(config); + username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName()); + assertEquals(username, "sir-larry-tenant-1"); + } +} http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-provider-identity-assertion-pseudo/pom.xml ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-pseudo/pom.xml b/gateway-provider-identity-assertion-pseudo/pom.xml index 191c602..8fd7269 100644 --- a/gateway-provider-identity-assertion-pseudo/pom.xml +++ b/gateway-provider-identity-assertion-pseudo/pom.xml @@ -47,7 +47,7 @@ <dependency> <groupId>${gateway-group}</groupId> - <artifactId>gateway-spi</artifactId> + <artifactId>gateway-provider-identity-assertion-common</artifactId> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAsserterDeploymentContributor.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAsserterDeploymentContributor.java b/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAsserterDeploymentContributor.java index bb5cd99..b261138 100644 --- a/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAsserterDeploymentContributor.java +++ b/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAsserterDeploymentContributor.java @@ -21,43 +21,38 @@ import org.apache.hadoop.gateway.deploy.DeploymentContext; import org.apache.hadoop.gateway.deploy.ProviderDeploymentContributorBase; import org.apache.hadoop.gateway.descriptor.FilterParamDescriptor; import org.apache.hadoop.gateway.descriptor.ResourceDescriptor; +import org.apache.hadoop.gateway.identityasserter.common.filter.AbstractIdentityAsserterDeploymentContributor; import org.apache.hadoop.gateway.topology.Provider; import org.apache.hadoop.gateway.topology.Service; import java.util.List; -public class IdentityAsserterDeploymentContributor extends ProviderDeploymentContributorBase { +public class IdentityAsserterDeploymentContributor extends AbstractIdentityAsserterDeploymentContributor { private static final String FILTER_CLASSNAME = IdentityAsserterFilter.class.getName(); private static final String PRINCIPAL_MAPPING_PARAM_NAME = "principal.mapping"; private static final String GROUP_PRINCIPAL_MAPPING_PARAM_NAME = "group.principal.mapping"; @Override - public String getRole() { - return "identity-assertion"; - } - - @Override public String getName() { return "Pseudo"; } @Override public void contributeProvider( DeploymentContext context, Provider provider ) { + super.contributeProvider(context, provider); String mappings = provider.getParams().get(PRINCIPAL_MAPPING_PARAM_NAME); String groupMappings = provider.getParams().get(GROUP_PRINCIPAL_MAPPING_PARAM_NAME); -// ServletType<WebAppDescriptor> servlet = findServlet( context, context.getTopology().getName() ); -// servlet.createInitParam() -// .paramName( PRINCIPAL_MAPPING_PARAM_NAME ) -// .paramValue( mappings ); - context.getWebAppDescriptor().createContextParam().paramName(PRINCIPAL_MAPPING_PARAM_NAME).paramValue(mappings); context.getWebAppDescriptor().createContextParam().paramName(GROUP_PRINCIPAL_MAPPING_PARAM_NAME).paramValue(groupMappings); } + /* (non-Javadoc) + * @see org.apache.hadoop.gateway.identityasserter.common.filter.AbstractIdentityAsserterDeploymentContributor#getFilterClassname() + */ @Override - public void contributeFilter( DeploymentContext context, Provider provider, Service service, ResourceDescriptor resource, List<FilterParamDescriptor> params ) { - resource.addFilter().name( getName() ).role( getRole() ).impl( FILTER_CLASSNAME ).params( params ); + protected String getFilterClassname() { + return FILTER_CLASSNAME; } } http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAsserterFilter.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAsserterFilter.java b/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAsserterFilter.java index b39fd90..c3fffba 100644 --- a/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAsserterFilter.java +++ b/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAsserterFilter.java @@ -19,39 +19,43 @@ package org.apache.hadoop.gateway.identityasserter.filter; import javax.security.auth.Subject; -import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; - -import org.apache.hadoop.gateway.filter.security.AbstractIdentityAssertionFilter; - -import java.io.IOException; -import java.security.AccessController; - -public class IdentityAsserterFilter extends AbstractIdentityAssertionFilter { - - /** - * Obtain the standard javax.security.auth.Subject, retrieve the caller principal, map - * to the identity to be asserted as appropriate and create the provider specific - * assertion token. Add the assertion token to the request. - */ - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { -// System.out.println("+++++++++++++ Identity Assertion Filtering"); - Subject subject = Subject.getSubject(AccessController.getContext()); +import org.apache.hadoop.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter; +import org.apache.hadoop.gateway.security.principal.PrincipalMappingException; +import org.apache.hadoop.gateway.security.principal.SimplePrincipalMapper; + +public class IdentityAsserterFilter extends CommonIdentityAssertionFilter { + private static final String GROUP_PRINCIPAL_MAPPING = "group.principal.mapping"; + private static final String PRINCIPAL_MAPPING = "principal.mapping"; + private SimplePrincipalMapper mapper = new SimplePrincipalMapper(); + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + String principalMapping = filterConfig.getInitParameter(PRINCIPAL_MAPPING); + if (principalMapping == null || principalMapping.isEmpty()) { + principalMapping = filterConfig.getServletContext().getInitParameter(PRINCIPAL_MAPPING); + } + String groupPrincipalMapping = filterConfig.getInitParameter(GROUP_PRINCIPAL_MAPPING); + if (groupPrincipalMapping == null || groupPrincipalMapping.isEmpty()) { + groupPrincipalMapping = filterConfig.getServletContext().getInitParameter(GROUP_PRINCIPAL_MAPPING); + } + if (principalMapping != null && !principalMapping.isEmpty() || groupPrincipalMapping != null && !groupPrincipalMapping.isEmpty()) { + try { + mapper.loadMappingTable(principalMapping, groupPrincipalMapping); + } catch (PrincipalMappingException e) { + throw new ServletException("Unable to load principal mapping table.", e); + } + } + } - String principalName = getPrincipalName(subject); - String mappedPrincipalName = mapper.mapUserPrincipal(principalName); - - // wrap the request so that the proper principal is returned - // from request methods - IdentityAsserterHttpServletRequestWrapper wrapper = - new IdentityAsserterHttpServletRequestWrapper( - (HttpServletRequest)request, - mappedPrincipalName); + @Override + public String[] mapGroupPrincipals(String mappedPrincipalName, Subject subject) { + return mapper.mapGroupPrincipal(mappedPrincipalName); + } - continueChainAsPrincipal(wrapper, response, chain, mappedPrincipalName); + @Override + public String mapUserPrincipal(String principalName) { + return mapper.mapUserPrincipal(principalName); } } http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAsserterHttpServletRequestWrapper.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAsserterHttpServletRequestWrapper.java b/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAsserterHttpServletRequestWrapper.java deleted file mode 100644 index 633abee..0000000 --- a/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAsserterHttpServletRequestWrapper.java +++ /dev/null @@ -1,227 +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.filter; - -import org.apache.commons.io.IOUtils; -import org.apache.hadoop.gateway.IdentityAsserterMessages; -import org.apache.hadoop.gateway.config.GatewayConfig; -import org.apache.hadoop.gateway.i18n.messages.MessagesFactory; - -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; - -public class IdentityAsserterHttpServletRequestWrapper extends HttpServletRequestWrapper { - - private static IdentityAsserterMessages log = MessagesFactory.get( IdentityAsserterMessages.class ); - - private static final String PRINCIPAL_PARAM = "user.name"; - private static final String DOAS_PRINCIPAL_PARAM = "doAs"; - - String username = null; - - public IdentityAsserterHttpServletRequestWrapper( HttpServletRequest request, String principal ) { - super(request); - username = principal; - } - - @Override - public String getParameter(String name) { - if (name.equals(PRINCIPAL_PARAM)) { - return username; - } - return super.getParameter(name); - } - - @SuppressWarnings("rawtypes") - @Override - public Map getParameterMap() { - return getParams(); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public Enumeration getParameterNames() { - Map<String, String[]> params = getParams(); - Enumeration<String> e = Collections.enumeration((Collection<String>) params); - - return e; - } - - @Override - public String[] getParameterValues(String name) { - Map<String, String[]> params = getParams(); - - return params.get(name); - } - - private Map<String, String[]> getParams( String qString ) { - Map<String, String[]> params = null; - if (getMethod().equals("GET")) { - if (qString != null && qString.length() > 0) { - params = parseQueryString(qString); - } - else { - params = new HashMap<String, String[]>(); - } - } - else { - if (qString == null || qString.length() == 0) { - return null; - } - else { - params = parseQueryString(qString); - } - } - return params; - } - - private Map<String, String[]> getParams() { - return getParams( super.getQueryString() ); - } - - @Override - public String getQueryString() { - String q = null; - Map<String, String[]> params = getParams(); - - if (params == null) { - params = new HashMap<String, String[]>(); - } - - ArrayList<String> al = new ArrayList<String>(); - al.add(username); - String[] a = { "" }; - - if ("true".equals(System.getProperty(GatewayConfig.HADOOP_KERBEROS_SECURED))) { - params.put(DOAS_PRINCIPAL_PARAM, al.toArray(a)); - params.remove(PRINCIPAL_PARAM); - } else { - params.put(PRINCIPAL_PARAM, al.toArray(a)); - } - - String encoding = getCharacterEncoding(); - if (encoding == null) { - encoding = Charset.defaultCharset().name(); - } - q = urlEncode(params, encoding); - return q; - } - - @Override - public int getContentLength() { - int len; - String contentType = getContentType(); - // If the content type is a form we might rewrite the body so default it to -1. - if( contentType != null && contentType.startsWith( "application/x-www-form-urlencoded" ) ) { - len = -1; - } else { - len = super.getContentLength(); - } - return len; - } - - @Override - public ServletInputStream getInputStream() throws java.io.IOException { - String contentType = getContentType(); - if( contentType != null && contentType.startsWith( "application/x-www-form-urlencoded" ) ) { - String encoding = getCharacterEncoding(); - if( encoding == null ) { - encoding = Charset.defaultCharset().name(); - } - String body = IOUtils.toString( super.getInputStream(), encoding ); - Map<String, String[]> params = getParams( body ); - body = urlEncode( params, encoding ); - // ASCII is OK here because the urlEncode about should have already escaped - return new ServletInputStreamWrapper( new ByteArrayInputStream( body.getBytes( "US-ASCII" ) ) ); - } else { - return super.getInputStream(); - } - } - - static String urlEncode( String string, String encoding ) { - try { - return URLEncoder.encode( string, encoding ); - } catch (UnsupportedEncodingException e) { - throw new UnsupportedOperationException(e); - } - } - - static String urlEncode( Map<String, String[]> map, String encoding ) { - StringBuilder sb = new StringBuilder(); - for( Map.Entry<String,String[]> entry : map.entrySet() ) { - String name = entry.getKey(); - if( name != null && name.length() > 0 ) { - String[] values = entry.getValue(); - if( values == null || values.length == 0 ) { - sb.append( entry.getKey() ); - } else { - for( int i = 0; i < values.length; i++ ) { - String value = values[ i ]; - if( value != null ) { - if( sb.length() > 0 ) { - sb.append( "&" ); - } - try { - sb.append( urlEncode( name, encoding ) ); - sb.append( "=" ); - sb.append( urlEncode( value, encoding ) ); - } catch( IllegalArgumentException e ) { - log.skippingUnencodableParameter( name, value, encoding, e ); - } - } - } - } - } - } - return sb.toString(); - } - - @SuppressWarnings({ "deprecation", "unchecked" }) - private static Map<String,String[]> parseQueryString( String queryString ) { - return javax.servlet.http.HttpUtils.parseQueryString( queryString ); - } - - private class ServletInputStreamWrapper extends ServletInputStream { - - private InputStream stream; - - private ServletInputStreamWrapper( InputStream stream ) { - this.stream = stream; - } - - @Override - public int read() throws IOException { - return stream.read(); - } - - } - -} http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionDescriptor.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionDescriptor.java b/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionDescriptor.java deleted file mode 100644 index d2aa441..0000000 --- a/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionDescriptor.java +++ /dev/null @@ -1,31 +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.function; - -import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor; - -public class UsernameFunctionDescriptor implements UrlRewriteFunctionDescriptor<UsernameFunctionDescriptor> { - - public static final String FUNCTION_NAME = "username"; - - @Override - public String name() { - return FUNCTION_NAME; - } - -} http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessor.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessor.java b/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessor.java deleted file mode 100644 index 1e65f89..0000000 --- a/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessor.java +++ /dev/null @@ -1,74 +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.function; - -import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteEnvironment; -import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteContext; -import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor; -import org.apache.hadoop.gateway.filter.security.AbstractIdentityAssertionBase; -import org.apache.hadoop.gateway.i18n.GatewaySpiMessages; -import org.apache.hadoop.gateway.i18n.messages.MessagesFactory; -import org.apache.hadoop.gateway.security.SubjectUtils; - -import javax.security.auth.Subject; -import java.security.AccessController; -import java.util.ArrayList; -import java.util.List; - -public class UsernameFunctionProcessor - implements UrlRewriteFunctionProcessor<UsernameFunctionDescriptor> { - - private static final GatewaySpiMessages LOG = MessagesFactory.get( GatewaySpiMessages.class ); -// private PrincipalMapper mapper = null; - - @Override - public String name() { - return UsernameFunctionDescriptor.FUNCTION_NAME; - } - - @Override - public void initialize( UrlRewriteEnvironment environment, UsernameFunctionDescriptor descriptor ) throws Exception { -// if( environment != null ) { -// GatewayServices services = environment.getAttribute( GatewayServices.GATEWAY_SERVICES_ATTRIBUTE ); -// if( services != null ) { -// mapper = (PrincipalMapper)services.getService( "PrincipalMapperService" /*GatewayServices.PRINCIPAL_MAPPER_SERVICE*/ ); -// } -// } - } - - @Override - public void destroy() throws Exception { - } - - @Override - public List<String> resolve( UrlRewriteContext context, List<String> parameters ) throws Exception { - List<String> results = null; - Subject subject = SubjectUtils.getCurrentSubject( ); - if( subject != null ) { - results = new ArrayList<String>( 1 ); - String username = SubjectUtils.getEffectivePrincipalName(subject); - results.add( username ); - } else if( parameters != null && parameters.size() > 0 ) { - results = new ArrayList<String>( 1 ); - results.add( parameters.get( 0 ) ); - } - return results; - } - -} - http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-provider-identity-assertion-pseudo/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-pseudo/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor b/gateway-provider-identity-assertion-pseudo/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor deleted file mode 100644 index b42eb32..0000000 --- a/gateway-provider-identity-assertion-pseudo/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor +++ /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.function.UsernameFunctionDescriptor \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-provider-identity-assertion-pseudo/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-pseudo/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor b/gateway-provider-identity-assertion-pseudo/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor deleted file mode 100644 index 74e0a96..0000000 --- a/gateway-provider-identity-assertion-pseudo/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor +++ /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.function.UsernameFunctionProcessor \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/gateway/identityasserter/filter/DefaultIdentityAssertionFilterTest.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/gateway/identityasserter/filter/DefaultIdentityAssertionFilterTest.java b/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/gateway/identityasserter/filter/DefaultIdentityAssertionFilterTest.java new file mode 100644 index 0000000..9795a99 --- /dev/null +++ b/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/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.hadoop.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.hadoop.gateway.security.GroupPrincipal; +import org.apache.hadoop.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/ce3ca3ce/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAssertionHttpServletRequestWrapperTest.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAssertionHttpServletRequestWrapperTest.java b/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAssertionHttpServletRequestWrapperTest.java deleted file mode 100644 index 079540e..0000000 --- a/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAssertionHttpServletRequestWrapperTest.java +++ /dev/null @@ -1,233 +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.filter; - -import org.apache.commons.io.IOUtils; -import org.apache.hadoop.test.category.FastTests; -import org.apache.hadoop.test.category.UnitTests; -import org.apache.hadoop.test.mock.MockHttpServletRequest; -import org.apache.hadoop.test.mock.MockServletInputStream; -import org.junit.Test; -import org.junit.experimental.categories.Category; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.HashMap; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; - -@Category( { UnitTests.class, FastTests.class } ) -public class IdentityAssertionHttpServletRequestWrapperTest { - - @Test - public void testInsertUserNameInPostMethod() throws IOException { - String inputBody = "jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput"; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( "UTF-8" ) ) ) ); - request.setCharacterEncoding( "UTF-8" ); - request.setContentType( "application/x-www-form-urlencoded" ); - request.setMethod("POST"); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String outputBody = IOUtils.toString( wrapper.getInputStream(), wrapper.getCharacterEncoding() ); - String output = wrapper.getQueryString(); - assertThat( output, containsString( "user.name=output-user" ) ); - } - - @Test - public void testInsertUserNameInPostMethodWithoutEncoding() throws IOException { - String inputBody = "jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput"; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( "UTF-8" ) ) ) ); - request.setContentType( "application/x-www-form-urlencoded" ); - request.setMethod("POST"); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String outputBody = IOUtils.toString( wrapper.getInputStream(), wrapper.getCharacterEncoding() ); - String output = wrapper.getQueryString(); - assertThat( output, containsString( "user.name=output-user" ) ); - } - - @Test - public void testInsertUserNameInPostMethodWithIso88591Encoding() throws IOException { - String inputBody = "jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput"; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( "UTF-8" ) ) ) ); - request.setContentType( "application/x-www-form-urlencoded" ); - request.setCharacterEncoding( "ISO-8859-1" ); - request.setMethod("POST"); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String outputBody = IOUtils.toString( wrapper.getInputStream(), wrapper.getCharacterEncoding() ); - String output = wrapper.getQueryString(); - assertThat( output, containsString( "user.name=output-user" ) ); - } - - @Test - public void testOverwriteUserNameInPostMethod() throws IOException { - String inputBody = "user.name=input-user&jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput"; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( "UTF-8" ) ) ) ); - request.setCharacterEncoding( "UTF-8" ); - request.setContentType( "application/x-www-form-urlencoded" ); - request.setMethod("POST"); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String outputBody = IOUtils.toString( wrapper.getInputStream(), wrapper.getCharacterEncoding() ); - String output = wrapper.getQueryString(); - assertThat( output, containsString( "user.name=output-user" ) ); - assertThat( output, not( containsString( "input-user" ) ) ); - } - - @Test - public void testIngoreNonFormBody() throws IOException { - String inputBody = "user.name=input-user&jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput"; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( "UTF-8" ) ) ) ); - request.setCharacterEncoding( "UTF-8" ); - request.setContentType( "text/plain" ); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String outputBody = IOUtils.toString( wrapper.getInputStream(), wrapper.getCharacterEncoding() ); - - assertThat( outputBody, containsString( "user.name=input-user" ) ); - assertThat( outputBody, not( containsString( "output-user" ) ) ); - } - - @Test - public void testInsertUserNameInQueryString() { - String input = "param=value"; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString( input ); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String output = wrapper.getQueryString(); - - assertThat( output, containsString( "user.name=output-user" ) ); - } - - @Test - public void testInsertUserNameInNullQueryString() { - String input = null; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString( input ); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String output = wrapper.getQueryString(); - - assertThat( output, containsString( "user.name=output-user" ) ); - } - - @Test - public void testInsertUserNameInNullQueryStringForGET() { - String input = null; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString( input ); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String output = wrapper.getQueryString(); - - assertThat( output, containsString( "user.name=output-user" ) ); - } - - @Test - public void testInsertUserNameInQueryStringForPOST() { - String input = null; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString( input ); - request.setMethod("POST"); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String output = wrapper.getQueryString(); - - assertThat( output, containsString( "user.name=output-user" ) ); - } - - @Test - public void testOverwriteUserNameInQueryString() { - String input = "user.name=input-user"; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString( input ); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String output = wrapper.getQueryString(); - - assertThat( output, containsString( "user.name=output-user" ) ); - assertThat( output, not( containsString( "input-user" ) ) ); - } - - @Test - public void testUrlEncode() { - String s; - HashMap<String,String[]> m; - - m = new HashMap<String,String[]>(); - m.put( "null-values", null ); - s = IdentityAsserterHttpServletRequestWrapper.urlEncode( m, "UTF-8" ); - assertThat( s, is( "null-values" ) ); - - m = new HashMap<String,String[]>(); - m.put( "no-values", new String[0] ); - s = IdentityAsserterHttpServletRequestWrapper.urlEncode( m, "UTF-8" ); - assertThat( s, is( "no-values" ) ); - - m = new HashMap<String,String[]>(); - m.put( "one-value", new String[]{ "value1" } ); - s = IdentityAsserterHttpServletRequestWrapper.urlEncode( m, "UTF-8" ); - assertThat( s, is( "one-value=value1" ) ); - - m = new HashMap<String,String[]>(); - m.put( "two-values", new String[]{ "value1", "value2" } ); - s = IdentityAsserterHttpServletRequestWrapper.urlEncode( m, "UTF-8" ); - assertThat( s, is( "two-values=value1&two-values=value2" ) ); - } - -} http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionDescriptorTest.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionDescriptorTest.java b/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionDescriptorTest.java deleted file mode 100644 index 3d835bf..0000000 --- a/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionDescriptorTest.java +++ /dev/null @@ -1,51 +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.function; - -import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor; -import org.junit.Test; - -import java.util.Iterator; -import java.util.ServiceLoader; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.fail; - -public class UsernameFunctionDescriptorTest { - - @Test - public void testName() throws Exception { - UsernameFunctionDescriptor descriptor = new UsernameFunctionDescriptor(); - assertThat( descriptor.name(), is( "username" ) ); - } - - @Test - public void testServiceLoader() throws Exception { - ServiceLoader loader = ServiceLoader.load( UrlRewriteFunctionDescriptor.class ); - Iterator iterator = loader.iterator(); - while( iterator.hasNext() ) { - Object object = iterator.next(); - if( object instanceof UsernameFunctionDescriptor ) { - return; - } - } - fail( "Failed to find UsernameFunctionDescriptor via service loader." ); - } - -} http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest.java b/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest.java deleted file mode 100644 index dffa4b0..0000000 --- a/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest.java +++ /dev/null @@ -1,247 +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.function; - -import org.apache.hadoop.gateway.filter.AbstractGatewayFilter; -import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteServletContextListener; -import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteServletFilter; -import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor; -import org.apache.hadoop.gateway.security.PrimaryPrincipal; -import org.apache.hadoop.gateway.util.urltemplate.Parser; -import org.apache.hadoop.test.log.NoOpLogger; -import org.apache.hadoop.test.mock.MockInteraction; -import org.apache.hadoop.test.mock.MockServlet; -import org.apache.http.auth.BasicUserPrincipal; -import org.eclipse.jetty.servlet.FilterHolder; -import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.testing.HttpTester; -import org.eclipse.jetty.testing.ServletTester; -import org.eclipse.jetty.util.ArrayQueue; -import org.eclipse.jetty.util.log.Log; -import org.hamcrest.core.Is; -import org.junit.After; -import org.junit.Test; - -import javax.security.auth.Subject; -import javax.servlet.DispatcherType; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.charset.Charset; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.ServiceLoader; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.nullValue; -import static org.hamcrest.collection.IsIterableContainingInOrder.contains; -import static org.junit.Assert.fail; - -public class UsernameFunctionProcessorTest { - - private ServletTester server; - private HttpTester request; - private HttpTester response; - private ArrayQueue<MockInteraction> interactions; - private MockInteraction interaction; - - private static URL getTestResource( String name ) { - name = UsernameFunctionProcessorTest.class.getName().replaceAll( "\\.", "/" ) + "/" + name; - URL url = ClassLoader.getSystemResource( name ); - return url; - } - - public void setUp( String username, Map<String,String> initParams ) throws Exception { - String descriptorUrl = getTestResource( "rewrite.xml" ).toExternalForm(); - - Log.setLog( new NoOpLogger() ); - - server = new ServletTester(); - server.setContextPath( "/" ); - server.getContext().addEventListener( new UrlRewriteServletContextListener() ); - server.getContext().setInitParameter( - UrlRewriteServletContextListener.DESCRIPTOR_LOCATION_INIT_PARAM_NAME, descriptorUrl ); - - FilterHolder setupFilter = server.addFilter( SetupFilter.class, "/*", EnumSet.of( DispatcherType.REQUEST ) ); - setupFilter.setFilter( new SetupFilter( username ) ); - FilterHolder rewriteFilter = server.addFilter( UrlRewriteServletFilter.class, "/*", EnumSet.of( DispatcherType.REQUEST ) ); - if( initParams != null ) { - for( Map.Entry<String,String> entry : initParams.entrySet() ) { - rewriteFilter.setInitParameter( entry.getKey(), entry.getValue() ); - } - } - rewriteFilter.setFilter( new UrlRewriteServletFilter() ); - - interactions = new ArrayQueue<MockInteraction>(); - - ServletHolder servlet = server.addServlet( MockServlet.class, "/" ); - servlet.setServlet( new MockServlet( "mock-servlet", interactions ) ); - - server.start(); - - interaction = new MockInteraction(); - request = new HttpTester(); - response = new HttpTester(); - } - - @After - public void tearDown() throws Exception { - if( server != null ) { - server.stop(); - } - } - - @Test - public void testInitialize() throws Exception { - UsernameFunctionProcessor processor = new UsernameFunctionProcessor(); - // Shouldn't fail. - processor.initialize( null, null ); - } - - @Test - public void testDestroy() throws Exception { - UsernameFunctionProcessor processor = new UsernameFunctionProcessor(); - // Shouldn't fail. - processor.destroy(); - } - - @Test - public void testResolve() throws Exception { - final UsernameFunctionProcessor processor = new UsernameFunctionProcessor(); - assertThat( processor.resolve( null, null ), nullValue() ); - assertThat( processor.resolve( null, Arrays.asList( "test-input" ) ), contains( "test-input" ) ); - Subject subject = new Subject(); - subject.getPrincipals().add( new PrimaryPrincipal( "test-username" ) ); - subject.setReadOnly(); - Subject.doAs( subject, new PrivilegedExceptionAction<Object>() { - @Override - public Object run() throws Exception { - assertThat( processor.resolve( null, null ), contains( "test-username" ) ); - assertThat( processor.resolve( null, Arrays.asList( "test-ignored" ) ), contains( "test-username" ) ); - return null; - } - } ); - } - - @Test - public void testServiceLoader() throws Exception { - ServiceLoader loader = ServiceLoader.load( UrlRewriteFunctionProcessor.class ); - Iterator iterator = loader.iterator(); - while( iterator.hasNext() ) { - Object object = iterator.next(); - if( object instanceof UsernameFunctionProcessor ) { - return; - } - } - fail( "Failed to find UsernameFunctionProcessor via service loader." ); - } - - @Test - public void testRequestUrlRewriteOfUsernameViaRewriteRule() throws Exception { - Map<String,String> initParams = new HashMap<String,String>(); - initParams.put( "request.url", "test-rule-username" ); - setUp( "test-user", initParams ); - - String input = "<root/>"; - String expect = "<root/>"; - - // Setup the server side request/response interaction. - interaction.expect() - .method( "PUT" ) - .requestUrl( "test-output-scheme://test-input-host:777/test-output-path/test-input-path" ) - .queryParam( "user.name", "test-user" ) - .queryParam( "test-query-input-name", "test-query-input-value" ) - .queryParam( "test-query-output-name", "test-query-output-value" ) - .contentType( "text/xml" ) - .characterEncoding( "UTF-8" ) - .content( expect, Charset.forName( "UTF-8" ) ); - interaction.respond() - .status( 200 ); - interactions.add( interaction ); - request.setMethod( "PUT" ); - request.setURI( "/test-input-path?test-query-input-name=test-query-input-value" ); - request.setVersion( "HTTP/1.1" ); - request.setHeader( "Host", "test-input-host:777" ); - request.setContentType( "text/xml; charset=UTF-8" ); - request.setContent( input ); - - response.parse( server.getResponses( request.generate() ) ); - - // Test the results. - assertThat( response.getStatus(), Is.is( 200 ) ); - } - - private static class SetupFilter implements Filter { - private Subject subject; - - public SetupFilter( String userName ) { - subject = new Subject(); - subject.getPrincipals().add( new BasicUserPrincipal( userName ) ); - } - - @Override - public void init( FilterConfig filterConfig ) throws ServletException { - } - - @Override - public void doFilter( final ServletRequest request, final ServletResponse response, final FilterChain chain ) throws IOException, ServletException { - HttpServletRequest httpRequest = ((HttpServletRequest)request); - StringBuffer sourceUrl = httpRequest.getRequestURL(); - String queryString = httpRequest.getQueryString(); - if( queryString != null ) { - sourceUrl.append( "?" ); - sourceUrl.append( queryString ); - } - try { - request.setAttribute( - AbstractGatewayFilter.SOURCE_REQUEST_URL_ATTRIBUTE_NAME, - Parser.parse( sourceUrl.toString() ) ); - } catch( URISyntaxException e ) { - throw new ServletException( e ); - } - try { - Subject.doAs( subject, new PrivilegedExceptionAction<Void>() { - @Override - public Void run() throws Exception { - chain.doFilter( request, response ); - return null; - } - } ); - } catch( PrivilegedActionException e ) { - throw new ServletException( e ); - } - } - - @Override - public void destroy() { - } - } - -} http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-release/pom.xml ---------------------------------------------------------------------- diff --git a/gateway-release/pom.xml b/gateway-release/pom.xml index adb7c52..7f84ca7 100644 --- a/gateway-release/pom.xml +++ b/gateway-release/pom.xml @@ -220,6 +220,14 @@ </dependency> <dependency> <groupId>${gateway-group}</groupId> + <artifactId>gateway-provider-identity-assertion-common</artifactId> + </dependency> + <dependency> + <groupId>${gateway-group}</groupId> + <artifactId>gateway-provider-identity-assertion-concat</artifactId> + </dependency> + <dependency> + <groupId>${gateway-group}</groupId> <artifactId>gateway-provider-identity-assertion-pseudo</artifactId> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/gateway-spi/src/main/java/org/apache/hadoop/gateway/SpiGatewayMessages.java ---------------------------------------------------------------------- diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/SpiGatewayMessages.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/SpiGatewayMessages.java index 5ff8a86..34ec105 100644 --- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/SpiGatewayMessages.java +++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/SpiGatewayMessages.java @@ -51,4 +51,8 @@ public interface SpiGatewayMessages { @Message( level = MessageLevel.WARN, text = "Error occurred when closing HTTP client : {0}" ) void errorClosingHttpClient(@StackTrace(level=MessageLevel.WARN) Exception e); + + @Message( level = MessageLevel.WARN, text = "Skipping unencodable parameter {0}={1}, {2}: {3}" ) + void skippingUnencodableParameter( String name, String value, String encoding, @StackTrace( level = MessageLevel.DEBUG ) Exception e ); + } http://git-wip-us.apache.org/repos/asf/knox/blob/ce3ca3ce/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 2dcffea..9bba00a 100644 --- a/pom.xml +++ b/pom.xml @@ -58,6 +58,8 @@ <module>gateway-provider-security-hadoopauth</module> <module>gateway-provider-security-shiro</module> <module>gateway-provider-security-authz-acls</module> + <module>gateway-provider-identity-assertion-common</module> + <module>gateway-provider-identity-assertion-concat</module> <module>gateway-provider-identity-assertion-pseudo</module> <module>gateway-provider-jersey</module> <module>gateway-provider-ha</module> @@ -416,6 +418,16 @@ </dependency> <dependency> <groupId>${gateway-group}</groupId> + <artifactId>gateway-provider-identity-assertion-common</artifactId> + <version>${gateway-version}</version> + </dependency> + <dependency> + <groupId>${gateway-group}</groupId> + <artifactId>gateway-provider-identity-assertion-concat</artifactId> + <version>${gateway-version}</version> + </dependency> + <dependency> + <groupId>${gateway-group}</groupId> <artifactId>gateway-provider-identity-assertion-pseudo</artifactId> <version>${gateway-version}</version> </dependency>