http://git-wip-us.apache.org/repos/asf/knox/blob/416ee7c1/gateway-test/src/test/java/org/apache/knox/gateway/GatewayDeployFuncTest.java ---------------------------------------------------------------------- diff --cc gateway-test/src/test/java/org/apache/knox/gateway/GatewayDeployFuncTest.java index e9442cd,0000000..9349dca mode 100644,000000..100644 --- a/gateway-test/src/test/java/org/apache/knox/gateway/GatewayDeployFuncTest.java +++ b/gateway-test/src/test/java/org/apache/knox/gateway/GatewayDeployFuncTest.java @@@ -1,315 -1,0 +1,315 @@@ +/** + * 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; + +import io.restassured.response.Response; +import com.mycila.xmltool.XMLDoc; +import com.mycila.xmltool.XMLTag; +import org.apache.commons.io.FileUtils; +import org.apache.directory.server.protocol.shared.transport.TcpTransport; +import org.apache.knox.gateway.config.GatewayConfig; +import org.apache.knox.gateway.security.ldap.SimpleLdapDirectoryServer; +import org.apache.knox.gateway.services.DefaultGatewayServices; +import org.apache.knox.gateway.services.ServiceLifecycleException; +import org.apache.hadoop.test.TestUtils; +import org.apache.hadoop.test.category.ReleaseTest; +import org.apache.http.HttpStatus; +import org.apache.log4j.Appender; +import org.hamcrest.MatcherAssert; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.regex.Pattern; + +import static io.restassured.RestAssured.given; +import static org.apache.hadoop.test.TestUtils.LOG_ENTER; +import static org.apache.hadoop.test.TestUtils.LOG_EXIT; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.Matchers.greaterThan; +import static org.junit.Assert.assertThat; + +@Category(ReleaseTest.class) +public class GatewayDeployFuncTest { + + private static Logger LOG = LoggerFactory.getLogger( GatewayDeployFuncTest.class ); + + public static Enumeration<Appender> appenders; + public static GatewayConfig config; + public static GatewayServer gateway; + public static File gatewayHome; + public static String gatewayUrl; + public static String clusterUrl; + private static GatewayTestDriver driver = new GatewayTestDriver(); + + @BeforeClass + public static void setupSuite() throws Exception { + LOG_ENTER(); + //appenders = NoOpAppender.setUp(); + driver.setupLdap(0); + LOG_EXIT(); + } + + @AfterClass + public static void cleanupSuite() throws Exception { + LOG_ENTER(); + driver.cleanup(); + //FileUtils.deleteQuietly( new File( config.getGatewayHomeDir() ) ); + //NoOpAppender.tearDown( appenders ); + LOG_EXIT(); + } + + @Before + public void setupGateway() throws Exception { + + File targetDir = new File( System.getProperty( "user.dir" ), "target" ); + File gatewayDir = new File( targetDir, "gateway-home-" + UUID.randomUUID() ); + gatewayDir.mkdirs(); + gatewayHome = gatewayDir; + + GatewayTestConfig testConfig = new GatewayTestConfig(); + config = testConfig; + testConfig.setGatewayHomeDir( gatewayDir.getAbsolutePath() ); + + File topoDir = new File( testConfig.getGatewayTopologyDir() ); + topoDir.mkdirs(); + + File deployDir = new File( testConfig.getGatewayDeploymentDir() ); + deployDir.mkdirs(); + + DefaultGatewayServices srvcs = new DefaultGatewayServices(); + Map<String,String> options = new HashMap<>(); + options.put( "persist-master", "false" ); + options.put( "master", "password" ); + try { + srvcs.init( testConfig, options ); + } catch ( ServiceLifecycleException e ) { + e.printStackTrace(); // I18N not required. + } + gateway = GatewayServer.startGateway( testConfig, srvcs ); + MatcherAssert.assertThat( "Failed to start gateway.", gateway, notNullValue() ); + + LOG.info( "Gateway port = " + gateway.getAddresses()[ 0 ].getPort() ); + + gatewayUrl = "http://localhost:" + gateway.getAddresses()[0].getPort() + "/" + config.getGatewayPath(); + clusterUrl = gatewayUrl + "/test-cluster"; + } + + @After + public void cleanupGateway() throws Exception { + gateway.stop(); + FileUtils.deleteQuietly( gatewayHome ); + } + + private static XMLTag createTopology() { + XMLTag xml = XMLDoc.newDocument( true ) + .addRoot( "topology" ) + .addTag( "gateway" ) + + .addTag( "provider" ) + .addTag( "role" ).addText( "authentication" ) + .addTag( "name" ).addText( "ShiroProvider" ) + .addTag( "enabled" ).addText( "true" ) + .addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm" ) + .addTag( "value" ).addText( "org.apache.knox.gateway.shirorealm.KnoxLdapRealm" ).gotoParent() + .addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.userDnTemplate" ) + .addTag( "value" ).addText( "uid={0},ou=people,dc=hadoop,dc=apache,dc=org" ).gotoParent() + .addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.url" ) + .addTag( "value" ).addText( driver.getLdapUrl() ).gotoParent() + .addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.authenticationMechanism" ) + .addTag( "value" ).addText( "simple" ).gotoParent() + .addTag( "param" ) + .addTag( "name" ).addText( "urls./**" ) + .addTag( "value" ).addText( "authcBasic" ).gotoParent().gotoParent() + .addTag( "provider" ) + .addTag( "role" ).addText( "identity-assertion" ) + .addTag( "enabled" ).addText( "true" ) + .addTag( "name" ).addText( "Default" ).gotoParent() + .addTag( "provider" ) + .gotoRoot() + .addTag( "service" ) + .addTag( "role" ).addText( "test-service-role" ) + .gotoRoot(); + return xml; + } + + //@Test + public void waitForManualTesting() throws IOException { + System.in.read(); + } + + @Test( timeout = TestUtils.LONG_TIMEOUT ) + public void testDeployRedeployUndeploy() throws InterruptedException, IOException { + LOG_ENTER(); + long sleep = 200; + int numFilesInWebInf = 4; // # files in WEB-INF (ie gateway.xml, rewrite.xml, shiro.ini, web.xml) + String username = "guest"; + String password = "guest-password"; + String serviceUrl = clusterUrl + "/test-service-path/test-service-resource"; + long topoTimestampBefore, topoTimestampAfter; + + File topoDir = new File( config.getGatewayTopologyDir() ); + File deployDir = new File( config.getGatewayDeploymentDir() ); + File earDir; + + // Make sure deployment directory is empty. + assertThat( topoDir.listFiles().length, is( 0 ) ); + assertThat( deployDir.listFiles().length, is( 0 ) ); + + File descriptor = writeTestTopology( "test-cluster", createTopology() ); + long writeTime = System.currentTimeMillis(); + + earDir = waitForFiles( deployDir, "test-cluster\\.topo\\.[0-9A-Fa-f]+", 1, 0, sleep ); + File warDir = new File( earDir, "%2F" ); + File webInfDir = new File( warDir, "WEB-INF" ); + waitForFiles( webInfDir, ".*", numFilesInWebInf, 0, sleep ); + waitForAccess( serviceUrl, username, password, sleep ); + + // Wait to make sure a second has passed to ensure the the file timestamps are different. + waitForElapsed( writeTime, 1000, 100 ); + + // Redeploy and make sure the timestamp is updated. + topoTimestampBefore = descriptor.lastModified(); + GatewayServer.redeployTopologies( null ); + writeTime = System.currentTimeMillis(); + topoTimestampAfter = descriptor.lastModified(); + assertThat( topoTimestampAfter, greaterThan( topoTimestampBefore ) ); + + // Check to make sure there are two war directories with the same root. + earDir = waitForFiles( deployDir, "test-cluster\\.topo\\.[0-9A-Fa-f]+", 2, 1, sleep ); + warDir = new File( earDir, "%2F" ); + webInfDir = new File( warDir, "WEB-INF" ); + waitForFiles( webInfDir, ".*", numFilesInWebInf, 0, sleep ); + waitForAccess( serviceUrl, username, password, sleep ); + + // Wait to make sure a second has passed to ensure the the file timestamps are different. + waitForElapsed( writeTime, 1000, 100 ); + + // Redeploy and make sure the timestamp is updated. + topoTimestampBefore = descriptor.lastModified(); + GatewayServer.redeployTopologies( "test-cluster" ); + writeTime = System.currentTimeMillis(); + topoTimestampAfter = descriptor.lastModified(); + assertThat( topoTimestampAfter, greaterThan( topoTimestampBefore ) ); + + // Check to make sure there are two war directories with the same root. + earDir = waitForFiles( deployDir, "test-cluster\\.topo\\.[0-9A-Fa-f]+", 3, 2, sleep ); + warDir = new File( earDir, "%2F" ); + webInfDir = new File( warDir, "WEB-INF" ); + waitForFiles( webInfDir, ".*", numFilesInWebInf, 0, sleep ); + waitForAccess( serviceUrl, username, password, sleep ); + + // Delete the test topology. + assertThat( "Failed to delete the topology file.", descriptor.delete(), is( true ) ); + + // Wait to make sure a second has passed to ensure the the file timestamps are different. + waitForElapsed( writeTime, 1000, 100 ); + + waitForFiles( deployDir, ".*", 0, -1, sleep ); + + // Wait a bit more to make sure undeployment finished. + Thread.sleep( sleep ); + + // Make sure the test topology is not accessible. + given().auth().preemptive().basic( username, password ) - .expect().statusCode( HttpStatus.SC_NOT_FOUND ) ++ .then().statusCode( HttpStatus.SC_NOT_FOUND ) + .when().get( serviceUrl ); + + // Make sure deployment directory is empty. + assertThat( topoDir.listFiles().length, is( 0 ) ); + assertThat( deployDir.listFiles().length, is( 0 ) ); + LOG_EXIT(); + } + + private void waitForElapsed( long from, long total, long sleep ) throws InterruptedException { + while( System.currentTimeMillis() - from < total ) { + Thread.sleep( sleep ); + } + } + + private File writeTestTopology( String name, XMLTag xml ) throws IOException { + // Create the test topology. + File tempFile = new File( config.getGatewayTopologyDir(), name + ".xml." + UUID.randomUUID() ); + FileOutputStream stream = new FileOutputStream( tempFile ); + xml.toStream( stream ); + stream.close(); + File descriptor = new File( config.getGatewayTopologyDir(), name + ".xml" ); + tempFile.renameTo( descriptor ); + return descriptor; + } + + private File waitForFiles( File dir, String pattern, int count, int index, long sleep ) throws InterruptedException { + RegexDirFilter filter = new RegexDirFilter( pattern ); + while( true ) { + File[] files = dir.listFiles( filter ); + if( files.length == count ) { + return ( index < 0 ) ? null : files[ index ]; + } + Thread.sleep( sleep ); + } + } + + private void waitForAccess( String url, String username, String password, long sleep ) throws InterruptedException { + while( true ) { + Response response = given() + .auth().preemptive().basic( username, password ) + .when().get( url ).andReturn(); + if( response.getStatusCode() == HttpStatus.SC_NOT_FOUND ) { + Thread.sleep( sleep ); + continue; + } + assertThat( response.getContentType(), containsString( "text/plain" ) ); + assertThat( response.getBody().asString(), is( "test-service-response" ) ); + break; + } + } + + private class RegexDirFilter implements FilenameFilter { + + Pattern pattern; + + RegexDirFilter( String regex ) { + pattern = Pattern.compile( regex ); + } + + @Override + public boolean accept( File dir, String name ) { + return pattern.matcher( name ).matches(); + } + } + +}
http://git-wip-us.apache.org/repos/asf/knox/blob/416ee7c1/gateway-test/src/test/java/org/apache/knox/gateway/GatewayHealthFuncTest.java ---------------------------------------------------------------------- diff --cc gateway-test/src/test/java/org/apache/knox/gateway/GatewayHealthFuncTest.java index a1d00b2,0000000..c7ac9ee mode 100644,000000..100644 --- a/gateway-test/src/test/java/org/apache/knox/gateway/GatewayHealthFuncTest.java +++ b/gateway-test/src/test/java/org/apache/knox/gateway/GatewayHealthFuncTest.java @@@ -1,205 -1,0 +1,205 @@@ +/** + * 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; + +import io.restassured.path.json.JsonPath; +import com.mycila.xmltool.XMLDoc; +import com.mycila.xmltool.XMLTag; +import org.apache.directory.server.protocol.shared.transport.TcpTransport; +import org.apache.knox.gateway.config.GatewayConfig; +import org.apache.knox.gateway.security.ldap.SimpleLdapDirectoryServer; +import org.apache.knox.gateway.services.DefaultGatewayServices; +import org.apache.knox.gateway.services.ServiceLifecycleException; +import org.apache.hadoop.test.TestUtils; +import org.apache.http.HttpStatus; +import org.hamcrest.MatcherAssert; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ws.rs.core.MediaType; +import java.io.File; +import java.io.FileOutputStream; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.UUID; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.notNullValue; + +public class GatewayHealthFuncTest { + + private static Logger LOG = LoggerFactory.getLogger(GatewayAdminFuncTest.class); + + public static GatewayConfig config; + public static GatewayServer gateway; + public static String gatewayUrl; + public static String clusterUrl; + public static SimpleLdapDirectoryServer ldap; + public static TcpTransport ldapTransport; + + @BeforeClass + public static void setupSuite() throws Exception { + TestUtils.LOG_ENTER(); + setupLdap(); + setupGateway(); + TestUtils.LOG_EXIT(); + } + + @AfterClass + public static void cleanupSuite() throws Exception { + TestUtils.LOG_ENTER(); + gateway.stop(); + ldap.stop(true); + TestUtils.LOG_EXIT(); + } + + public static void setupLdap() throws Exception { + String basedir = System.getProperty("basedir"); + if (basedir == null) { + basedir = new File(".").getCanonicalPath(); + } + + final Path path = FileSystems + .getDefault().getPath(basedir, "/src/test/resources/users.ldif"); + + ldapTransport = new TcpTransport(0); + ldap = new SimpleLdapDirectoryServer("dc=hadoop,dc=apache,dc=org", path.toFile(), ldapTransport); + ldap.start(); + LOG.info("LDAP port = " + ldapTransport.getPort()); + } + + public static void setupGateway() throws Exception { + + File targetDir = new File(System.getProperty("user.dir"), "target"); + File gatewayDir = new File(targetDir, "gateway-home-" + UUID.randomUUID()); + gatewayDir.mkdirs(); + + GatewayTestConfig testConfig = new GatewayTestConfig(); + config = testConfig; + testConfig.setGatewayHomeDir(gatewayDir.getAbsolutePath()); + + File topoDir = new File(testConfig.getGatewayTopologyDir()); + topoDir.mkdirs(); + + File deployDir = new File(testConfig.getGatewayDeploymentDir()); + deployDir.mkdirs(); + + File descriptor = new File(topoDir, "test-cluster.xml"); + FileOutputStream stream = new FileOutputStream(descriptor); + createTopology().toStream(stream); + stream.close(); + + DefaultGatewayServices srvcs = new DefaultGatewayServices(); + Map<String, String> options = new HashMap<String, String>(); + options.put("persist-master", "false"); + options.put("master", "password"); + try { + srvcs.init(testConfig, options); + } catch (ServiceLifecycleException e) { + e.printStackTrace(); // I18N not required. + } + gateway = GatewayServer.startGateway(testConfig, srvcs); + MatcherAssert.assertThat("Failed to start gateway.", gateway, notNullValue()); + + LOG.info("Gateway port = " + gateway.getAddresses()[0].getPort()); + + gatewayUrl = "http://localhost:" + gateway.getAddresses()[0].getPort() + "/" + config.getGatewayPath(); + clusterUrl = gatewayUrl + "/test-cluster"; + } + + private static XMLTag createTopology() { + XMLTag xml = XMLDoc.newDocument(true) + .addRoot("topology") + .addTag("gateway") + .addTag("provider") + .addTag("role").addText("authentication") + .addTag("name").addText("ShiroProvider") + .addTag("enabled").addText("true") + .addTag("param") + .addTag("name").addText("main.ldapRealm") + .addTag("value").addText("org.apache.knox.gateway.shirorealm.KnoxLdapRealm").gotoParent() + .addTag("param") + .addTag("name").addText("main.ldapRealm.userDnTemplate") + .addTag("value").addText("uid={0},ou=people,dc=hadoop,dc=apache,dc=org").gotoParent() + .addTag("param") + .addTag("name").addText("main.ldapRealm.contextFactory.url") + .addTag("value").addText("ldap://localhost:" + ldapTransport.getAcceptor().getLocalAddress().getPort()).gotoParent() + .addTag("param") + .addTag("name").addText("main.ldapRealm.contextFactory.authenticationMechanism") + .addTag("value").addText("simple").gotoParent() + .addTag("param") + .addTag("name").addText("urls./**") + .addTag("value").addText("authcBasic").gotoParent().gotoParent() + .addTag("provider") + .addTag("role").addText("identity-assertion") + .addTag("enabled").addText("true") + .addTag("name").addText("Default").gotoParent() + .addTag("provider") + .gotoRoot() + .addTag("service") + .addTag("role").addText("HEALTH") + .gotoRoot(); + return xml; + } + + @Test(timeout = TestUtils.MEDIUM_TIMEOUT) + public void testPingResource() { + TestUtils.LOG_ENTER(); + String username = "guest"; + String password = "guest-password"; + String serviceUrl = clusterUrl + "/v1/ping"; + String body = given() + .auth().preemptive().basic(username, password) + .header("Accept", MediaType.TEXT_PLAIN) - .expect() ++ .then() + .statusCode(HttpStatus.SC_OK) + .contentType(MediaType.TEXT_PLAIN) + .when().get(serviceUrl).asString(); + Assert.assertEquals("OK", body.trim()); + TestUtils.LOG_EXIT(); + } + + @Test(timeout = TestUtils.MEDIUM_TIMEOUT) + public void testMetricsResource() { + TestUtils.LOG_ENTER(); + String username = "guest"; + String password = "guest-password"; + String serviceUrl = clusterUrl + "/v1/metrics"; + String body = given() + .auth().preemptive().basic(username, password) - .expect() ++ .then() + .statusCode(HttpStatus.SC_OK) + .contentType(MediaType.APPLICATION_JSON) + .when().get(serviceUrl).asString(); - String version = JsonPath.from(body).getString("version"); ++ //String version = JsonPath.from(body).getString("version"); + Map<String, String> hm = JsonPath.from(body).getMap(""); + Assert.assertTrue(hm.size() >= 6); + Assert.assertTrue(hm.keySet().containsAll(new HashSet<String>(Arrays.asList(new String[]{"timers", "histograms", + "counters", "gauges", "version", "meters"})))); + TestUtils.LOG_EXIT(); + } + +} http://git-wip-us.apache.org/repos/asf/knox/blob/416ee7c1/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLdapDynamicGroupFuncTest.java ---------------------------------------------------------------------- diff --cc gateway-test/src/test/java/org/apache/knox/gateway/GatewayLdapDynamicGroupFuncTest.java index b66716d,0000000..3a3d776 mode 100755,000000..100755 --- a/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLdapDynamicGroupFuncTest.java +++ b/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLdapDynamicGroupFuncTest.java @@@ -1,287 -1,0 +1,287 @@@ +/** + * 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; + +import static io.restassured.RestAssured.given; +import static org.apache.hadoop.test.TestUtils.LOG_ENTER; +import static org.apache.hadoop.test.TestUtils.LOG_EXIT; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.knox.gateway.config.GatewayConfig; +import org.apache.knox.gateway.services.DefaultGatewayServices; +import org.apache.knox.gateway.services.GatewayServices; +import org.apache.knox.gateway.services.ServiceLifecycleException; +import org.apache.knox.gateway.services.security.AliasService; +import org.apache.hadoop.test.TestUtils; +import org.apache.http.HttpStatus; +import org.apache.log4j.Appender; +import org.hamcrest.MatcherAssert; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.mycila.xmltool.XMLDoc; +import com.mycila.xmltool.XMLTag; + +/** + * Functional test to verify : looking up ldap groups from directory + * and using them in acl authorization checks + * + */ +public class GatewayLdapDynamicGroupFuncTest { + + private static Logger LOG = LoggerFactory.getLogger( GatewayLdapDynamicGroupFuncTest.class ); + + public static Enumeration<Appender> appenders; + public static GatewayConfig config; + public static GatewayServer gateway; + public static String gatewayUrl; + public static String clusterUrl; + public static String serviceUrl; + private static GatewayTestDriver driver = new GatewayTestDriver(); + + @BeforeClass + public static void setupSuite() throws Exception { + LOG_ENTER(); + //appenders = NoOpAppender.setUp(); + String basedir = System.getProperty("basedir"); + if (basedir == null) { + basedir = new File(".").getCanonicalPath(); + } + Path path = FileSystems.getDefault().getPath(basedir, "/src/test/resources/users-dynamic.ldif"); + driver.setupLdap( 0, path.toFile() ); + setupGateway(); + TestUtils.awaitNon404HttpStatus( new URL( serviceUrl ), 10000, 100 ); + LOG_EXIT(); + } + + @AfterClass + public static void cleanupSuite() throws Exception { + LOG_ENTER(); + gateway.stop(); + driver.cleanup(); + //FileUtils.deleteQuietly( new File( config.getGatewayHomeDir() ) ); + //NoOpAppender.tearDown( appenders ); + LOG_EXIT(); + } + + public static void setupGateway() throws IOException, Exception { + + File targetDir = new File( System.getProperty( "user.dir" ), "target" ); + File gatewayDir = new File( targetDir, "gateway-home-" + UUID.randomUUID() ); + gatewayDir.mkdirs(); + + GatewayTestConfig testConfig = new GatewayTestConfig(); + config = testConfig; + testConfig.setGatewayHomeDir( gatewayDir.getAbsolutePath() ); + + File topoDir = new File( testConfig.getGatewayTopologyDir() ); + topoDir.mkdirs(); + + File deployDir = new File( testConfig.getGatewayDeploymentDir() ); + deployDir.mkdirs(); + + DefaultGatewayServices srvcs = new DefaultGatewayServices(); + Map<String,String> options = new HashMap<>(); + options.put( "persist-master", "false" ); + options.put( "master", "password" ); + try { + srvcs.init( testConfig, options ); + } catch ( ServiceLifecycleException e ) { + e.printStackTrace(); // I18N not required. + } + + /* + System.setProperty(GatewayConfig.GATEWAY_HOME_VAR, gatewayDir.getAbsolutePath()); + System.err.println("GH 10: " + System.getProperty(GatewayConfig.GATEWAY_HOME_VAR)); + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + String[] argvals = {"create-alias", "ldcSystemPassword", "--value", "guest-password", "--master", "hadoop", "--cluster", "testdg-cluster"}; + KnoxCLI cli = new KnoxCLI(); + cli.setConf(new GatewayConfigImpl()); + cli.run(argvals); + + outContent.reset(); + String[] args1 = {"list-alias", "--cluster", "testdg-cluster", "--master", "hadoop"}; + cli = new KnoxCLI(); + cli.run(args1); + System.err.println("ALIAS LIST: " + outContent.toString()); + + AliasService as1 = cli.getGatewayServices().getService(GatewayServices.ALIAS_SERVICE); + char[] passwordChars1 = as1.getPasswordFromAliasForCluster( "test-cluster", "ldcsystemPassword"); + System.err.println("ALIAS value1: " + new String(passwordChars1)); + */ + + gateway = GatewayServer.startGateway( testConfig, srvcs ); + MatcherAssert.assertThat( "Failed to start gateway.", gateway, notNullValue() ); + + LOG.info( "Gateway port = " + gateway.getAddresses()[ 0 ].getPort() ); + + gatewayUrl = "http://localhost:" + gateway.getAddresses()[0].getPort() + "/" + config.getGatewayPath(); + clusterUrl = gatewayUrl + "/testdg-cluster"; + serviceUrl = clusterUrl + "/test-service-path/test-service-resource"; + + ///* + GatewayServices services = GatewayServer.getGatewayServices(); + AliasService aliasService = (AliasService)services.getService(GatewayServices.ALIAS_SERVICE); + aliasService.addAliasForCluster("testdg-cluster", "ldcSystemPassword", "guest-password"); + - char[] password1 = aliasService.getPasswordFromAliasForCluster( "testdg-cluster", "ldcSystemPassword"); ++ //char[] password1 = aliasService.getPasswordFromAliasForCluster( "testdg-cluster", "ldcSystemPassword"); + //System.err.println("SETUP password 10: " + ((password1 == null) ? "NULL" : new String(password1))); + + File descriptor = new File( topoDir, "testdg-cluster.xml" ); + FileOutputStream stream = new FileOutputStream( descriptor ); + createTopology().toStream( stream ); + stream.close(); + + } + + private static XMLTag createTopology() { + XMLTag xml = XMLDoc.newDocument( true ) + .addRoot( "topology" ) + .addTag( "gateway" ) + + .addTag( "provider" ) + .addTag( "role" ).addText( "authentication" ) + .addTag( "name" ).addText( "ShiroProvider" ) + .addTag( "enabled" ).addText( "true" ) + .addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm" ) + .addTag( "value" ).addText( "org.apache.knox.gateway.shirorealm.KnoxLdapRealm" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapGroupContextFactory" ) + .addTag( "value" ).addText( "org.apache.knox.gateway.shirorealm.KnoxLdapContextFactory" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory" ) + .addTag( "value" ).addText( "$ldapGroupContextFactory" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.authenticationMechanism" ) + .addTag( "value" ).addText( "simple" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.url" ) + .addTag( "value" ).addText( driver.getLdapUrl()) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.userDnTemplate" ) + .addTag( "value" ).addText( "uid={0},ou=people,dc=hadoop,dc=apache,dc=org" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.authorizationEnabled" ) + .addTag( "value" ).addText( "true" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.systemAuthenticationMechanism" ) + .addTag( "value" ).addText( "simple" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.searchBase" ) + .addTag( "value" ).addText( "ou=groups,dc=hadoop,dc=apache,dc=org" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.groupObjectClass" ) + .addTag( "value" ).addText( "groupofurls" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.memberAttribute" ) + .addTag( "value" ).addText( "memberurl" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.memberAttributeValueTemplate" ) + .addTag( "value" ).addText( "uid={0},ou=people,dc=hadoop,dc=apache,dc=org" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.systemUsername" ) + .addTag( "value" ).addText( "uid=guest,ou=people,dc=hadoop,dc=apache,dc=org" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.clusterName" ) + .addTag( "value" ).addText( "testdg-cluster" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.systemPassword" ) + .addTag( "value" ).addText( "S{ALIAS=ldcSystemPassword}" ) + // .addTag( "value" ).addText( "guest-password" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "urls./**" ) + .addTag( "value" ).addText( "authcBasic" ) + + .gotoParent().gotoParent().addTag( "provider" ) + .addTag( "role" ).addText( "authorization" ) + .addTag( "name" ).addText( "AclsAuthz" ) + .addTag( "enabled" ).addText( "true" ) + .addTag( "param" ) + .addTag( "name" ).addText( "test-service-role.acl" ) // FIXME[dilli] + .addTag( "value" ).addText( "*;directors;*" ) + + .gotoParent().gotoParent().addTag( "provider" ) + .addTag( "role" ).addText( "identity-assertion" ) + .addTag( "enabled" ).addText( "true" ) + .addTag( "name" ).addText( "Default" ).gotoParent() + + .gotoRoot() + .addTag( "service" ) + .addTag( "role" ).addText( "test-service-role" ) + .gotoRoot(); + // System.out.println( "GATEWAY=" + xml.toString() ); + return xml; + } + + // @Test + public void waitForManualTesting() throws IOException { + System.in.read(); + } + + @Test( timeout = TestUtils.MEDIUM_TIMEOUT ) + public void testGroupMember() throws ClassNotFoundException, Exception { + LOG_ENTER(); + String username = "bob"; + String password = "bob-password"; + String serviceUrl = clusterUrl + "/test-service-path/test-service-resource"; + given() + //.log().all() + .auth().preemptive().basic( username, password ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_OK ) + .contentType( "text/plain" ) + .body( is( "test-service-response" ) ) + .when().get( serviceUrl ); + LOG_EXIT(); + } + + @Test( timeout = TestUtils.MEDIUM_TIMEOUT ) + public void testNonGroupMember() throws ClassNotFoundException { + LOG_ENTER(); + String username = "guest"; + String password = "guest-password"; + String serviceUrl = clusterUrl + "/test-service-path/test-service-resource"; + given() + //.log().all() + .auth().preemptive().basic( username, password ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_FORBIDDEN ) + .when().get( serviceUrl ); + LOG_EXIT(); + } + +} http://git-wip-us.apache.org/repos/asf/knox/blob/416ee7c1/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLdapGroupFuncTest.java ---------------------------------------------------------------------- diff --cc gateway-test/src/test/java/org/apache/knox/gateway/GatewayLdapGroupFuncTest.java index 60e3250,0000000..37ee90c mode 100644,000000..100644 --- a/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLdapGroupFuncTest.java +++ b/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLdapGroupFuncTest.java @@@ -1,283 -1,0 +1,283 @@@ +/** + * 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; + +import static io.restassured.RestAssured.given; +import static org.apache.hadoop.test.TestUtils.LOG_ENTER; +import static org.apache.hadoop.test.TestUtils.LOG_EXIT; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + + +import org.apache.knox.gateway.config.GatewayConfig; +import org.apache.knox.gateway.services.DefaultGatewayServices; +import org.apache.knox.gateway.services.GatewayServices; +import org.apache.knox.gateway.services.ServiceLifecycleException; +import org.apache.knox.gateway.services.security.AliasService; +import org.apache.hadoop.test.TestUtils; +import org.apache.http.HttpStatus; +import org.apache.log4j.Appender; +import org.hamcrest.MatcherAssert; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.mycila.xmltool.XMLDoc; +import com.mycila.xmltool.XMLTag; + +/** + * Functional test to verify : looking up ldap groups from directory + * and using them in acl authorization checks + * + */ +public class GatewayLdapGroupFuncTest { + + private static Logger LOG = LoggerFactory.getLogger( GatewayLdapGroupFuncTest.class ); + + public static Enumeration<Appender> appenders; + public static GatewayConfig config; + public static GatewayServer gateway; + public static String gatewayUrl; + public static String clusterUrl; + public static String serviceUrl; + private static GatewayTestDriver driver = new GatewayTestDriver(); + + @BeforeClass + public static void setupSuite() throws Exception { + LOG_ENTER(); + //appenders = NoOpAppender.setUp(); + driver.setupLdap(0); + setupGateway(); + TestUtils.awaitNon404HttpStatus( new URL( serviceUrl ), 10000, 100 ); + LOG_EXIT(); + } + + @AfterClass + public static void cleanupSuite() throws Exception { + LOG_ENTER(); + gateway.stop(); + driver.cleanup(); + //FileUtils.deleteQuietly( new File( config.getGatewayHomeDir() ) ); + //NoOpAppender.tearDown( appenders ); + LOG_EXIT(); + } + + public static void setupGateway() throws Exception { + + File targetDir = new File( System.getProperty( "user.dir" ), "target" ); + File gatewayDir = new File( targetDir, "gateway-home-" + UUID.randomUUID() ); + gatewayDir.mkdirs(); + + GatewayTestConfig testConfig = new GatewayTestConfig(); + config = testConfig; + testConfig.setGatewayHomeDir( gatewayDir.getAbsolutePath() ); + + File topoDir = new File( testConfig.getGatewayTopologyDir() ); + topoDir.mkdirs(); + + File deployDir = new File( testConfig.getGatewayDeploymentDir() ); + deployDir.mkdirs(); + + DefaultGatewayServices srvcs = new DefaultGatewayServices(); + Map<String,String> options = new HashMap<>(); + options.put( "persist-master", "true" ); + options.put( "master", "hadoop" ); + + try { + srvcs.init( testConfig, options ); + } catch ( ServiceLifecycleException e ) { + e.printStackTrace(); // I18N not required. + } + + /* + System.setProperty(GatewayConfig.GATEWAY_HOME_VAR, gatewayDir.getAbsolutePath()); + System.err.println("GH 10: " + System.getProperty(GatewayConfig.GATEWAY_HOME_VAR)); + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + String[] argvals = {"create-alias", "ldcSystemPassword", "--value", "guest-password", "--master", "hadoop", "--cluster", "test-cluster"}; + KnoxCLI cli = new KnoxCLI(); + cli.setConf(new GatewayConfigImpl()); + cli.run(argvals); + + outContent.reset(); + String[] args1 = {"list-alias", "--cluster", "test-cluster", "--master", "hadoop"}; + cli = new KnoxCLI(); + cli.run(args1); + System.err.println("ALIAS LIST: " + outContent.toString()); + + AliasService as1 = cli.getGatewayServices().getService(GatewayServices.ALIAS_SERVICE); + char[] passwordChars1 = as1.getPasswordFromAliasForCluster( "test-cluster", "ldcsystemPassword"); + System.err.println("ALIAS value1: " + new String(passwordChars1)); + */ + + gateway = GatewayServer.startGateway( testConfig, srvcs ); + MatcherAssert.assertThat( "Failed to start gateway.", gateway, notNullValue() ); + + LOG.info( "Gateway port = " + gateway.getAddresses()[ 0 ].getPort() ); + + gatewayUrl = "http://localhost:" + gateway.getAddresses()[0].getPort() + "/" + config.getGatewayPath(); + clusterUrl = gatewayUrl + "/test-cluster"; + serviceUrl = clusterUrl + "/test-service-path/test-service-resource"; + + ///* + GatewayServices services = GatewayServer.getGatewayServices(); + AliasService aliasService = (AliasService)services.getService(GatewayServices.ALIAS_SERVICE); + aliasService.addAliasForCluster("test-cluster", "ldcSystemPassword", "guest-password"); + + // char[] password1 = aliasService.getPasswordFromAliasForCluster( "test-cluster", "ldcSystemPassword"); + //System.err.println("SETUP password 10: " + ((password1 == null) ? "NULL" : new String(password1))); + + File descriptor = new File( topoDir, "test-cluster.xml" ); + FileOutputStream stream = new FileOutputStream( descriptor ); + createTopology().toStream( stream ); + stream.close(); + } + + private static XMLTag createTopology() { + XMLTag xml = XMLDoc.newDocument( true ) + .addRoot( "topology" ) + .addTag( "gateway" ) + + .addTag( "provider" ) + .addTag( "role" ).addText( "authentication" ) + .addTag( "name" ).addText( "ShiroProvider" ) + .addTag( "enabled" ).addText( "true" ) + .addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm" ) + .addTag( "value" ).addText( "org.apache.knox.gateway.shirorealm.KnoxLdapRealm" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapGroupContextFactory" ) + .addTag( "value" ).addText( "org.apache.knox.gateway.shirorealm.KnoxLdapContextFactory" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory" ) + .addTag( "value" ).addText( "$ldapGroupContextFactory" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.authenticationMechanism" ) + .addTag( "value" ).addText( "simple" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.url" ) + .addTag( "value" ).addText( driver.getLdapUrl()) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.userDnTemplate" ) + .addTag( "value" ).addText( "uid={0},ou=people,dc=hadoop,dc=apache,dc=org" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.authorizationEnabled" ) + .addTag( "value" ).addText( "true" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.systemAuthenticationMechanism" ) + .addTag( "value" ).addText( "simple" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.searchBase" ) + .addTag( "value" ).addText( "ou=groups,dc=hadoop,dc=apache,dc=org" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.groupObjectClass" ) + .addTag( "value" ).addText( "groupofnames" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.memberAttribute" ) + .addTag( "value" ).addText( "member" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.memberAttributeValueTemplate" ) + .addTag( "value" ).addText( "uid={0},ou=people,dc=hadoop,dc=apache,dc=org" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.clusterName" ) + .addTag( "value" ).addText( "test-cluster" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.systemUsername" ) + .addTag( "value" ).addText( "uid=guest,ou=people,dc=hadoop,dc=apache,dc=org" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.systemPassword" ) + .addTag( "value" ).addText( "S{ALIAS=ldcSystemPassword}" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "urls./**" ) + .addTag( "value" ).addText( "authcBasic" ) + + .gotoParent().gotoParent().addTag( "provider" ) + .addTag( "role" ).addText( "authorization" ) + .addTag( "name" ).addText( "AclsAuthz" ) + .addTag( "enabled" ).addText( "true" ) + .addTag( "param" ) + .addTag( "name" ).addText( "test-service-role.acl" ) // FIXME[dilli] + .addTag( "value" ).addText( "*;analyst;*" ) + + .gotoParent().gotoParent().addTag( "provider" ) + .addTag( "role" ).addText( "identity-assertion" ) + .addTag( "enabled" ).addText( "true" ) + .addTag( "name" ).addText( "Default" ).gotoParent() + + .gotoRoot() + .addTag( "service" ) + .addTag( "role" ).addText( "test-service-role" ) + .gotoRoot(); + // System.out.println( "GATEWAY=" + xml.toString() ); + return xml; + } + + @Ignore + // @Test + public void waitForManualTesting() throws IOException { + System.in.read(); + } + + @Test( timeout = TestUtils.MEDIUM_TIMEOUT ) + public void testGroupMember() throws ClassNotFoundException, Exception { + LOG_ENTER(); + String username = "sam"; + String password = "sam-password"; + String serviceUrl = clusterUrl + "/test-service-path/test-service-resource"; + given() + //.log().all() + .auth().preemptive().basic( username, password ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_OK ) + .contentType( "text/plain" ) + .body( is( "test-service-response" ) ) + .when().get( serviceUrl ); + LOG_EXIT(); + } + + @Test( timeout = TestUtils.MEDIUM_TIMEOUT ) + public void testNonGroupMember() throws ClassNotFoundException { + LOG_ENTER(); + String username = "guest"; + String password = "guest-password"; + String serviceUrl = clusterUrl + "/test-service-path/test-service-resource"; + given() + //.log().all() + .auth().preemptive().basic( username, password ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_FORBIDDEN ) + .when().get( serviceUrl ); + LOG_EXIT(); + } + +} http://git-wip-us.apache.org/repos/asf/knox/blob/416ee7c1/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLdapPosixGroupFuncTest.java ---------------------------------------------------------------------- diff --cc gateway-test/src/test/java/org/apache/knox/gateway/GatewayLdapPosixGroupFuncTest.java index f1dc3ad,0000000..b623f06 mode 100644,000000..100644 --- a/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLdapPosixGroupFuncTest.java +++ b/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLdapPosixGroupFuncTest.java @@@ -1,273 -1,0 +1,264 @@@ +/** + * 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; + +import com.mycila.xmltool.XMLDoc; +import com.mycila.xmltool.XMLTag; +import org.apache.directory.server.protocol.shared.transport.TcpTransport; +import org.apache.knox.gateway.config.GatewayConfig; +import org.apache.knox.gateway.security.ldap.SimpleLdapDirectoryServer; +import org.apache.knox.gateway.services.DefaultGatewayServices; +import org.apache.knox.gateway.services.GatewayServices; +import org.apache.knox.gateway.services.ServiceLifecycleException; +import org.apache.knox.gateway.services.security.AliasService; +import org.apache.hadoop.test.TestUtils; +import org.apache.hadoop.test.category.ReleaseTest; +import org.apache.http.HttpStatus; +import org.apache.log4j.Appender; +import org.hamcrest.MatcherAssert; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import static io.restassured.RestAssured.given; +import static org.apache.hadoop.test.TestUtils.LOG_ENTER; +import static org.apache.hadoop.test.TestUtils.LOG_EXIT; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; + +/** + * Functional test to verify : looking up ldap groups from directory + * and using them in acl authorization checks + * + */ +@Category(ReleaseTest.class) +public class GatewayLdapPosixGroupFuncTest { + - private static final Class<?> RESOURCE_BASE_CLASS = GatewayLdapPosixGroupFuncTest.class; + private static Logger LOG = LoggerFactory.getLogger( GatewayLdapPosixGroupFuncTest.class ); + + public static Enumeration<Appender> appenders; + public static GatewayConfig config; + public static GatewayServer gateway; + public static String gatewayUrl; + public static String clusterUrl; + public static String serviceUrl; + private static GatewayTestDriver driver = new GatewayTestDriver(); + + @BeforeClass + public static void setupSuite() throws Exception { + LOG_ENTER(); + //appenders = NoOpAppender.setUp(); + URL usersUrl = TestUtils.getResourceUrl( GatewayLdapPosixGroupFuncTest.class, "users.ldif" ); + driver.setupLdap( 0, new File( usersUrl.toURI() ) ); + setupGateway(); + TestUtils.awaitNon404HttpStatus( new URL( serviceUrl ), 10000, 100 ); + LOG_EXIT(); + } + + @AfterClass + public static void cleanupSuite() throws Exception { + LOG_ENTER(); + gateway.stop(); + driver.cleanup(); + //FileUtils.deleteQuietly( new File( config.getGatewayHomeDir() ) ); + //NoOpAppender.tearDown( appenders ); + LOG_EXIT(); + } + + public static void setupGateway() throws Exception { + + File targetDir = new File( System.getProperty( "user.dir" ), "target" ); + File gatewayDir = new File( targetDir, "gateway-home-" + UUID.randomUUID() ); + gatewayDir.mkdirs(); + + GatewayTestConfig testConfig = new GatewayTestConfig(); + config = testConfig; + testConfig.setGatewayHomeDir( gatewayDir.getAbsolutePath() ); + + File topoDir = new File( testConfig.getGatewayTopologyDir() ); + topoDir.mkdirs(); + + File deployDir = new File( testConfig.getGatewayDeploymentDir() ); + deployDir.mkdirs(); + + DefaultGatewayServices srvcs = new DefaultGatewayServices(); + Map<String,String> options = new HashMap<>(); + options.put( "persist-master", "true" ); + options.put( "master", "hadoop" ); + + try { + srvcs.init( testConfig, options ); + } catch ( ServiceLifecycleException e ) { + e.printStackTrace(); // I18N not required. + } + + gateway = GatewayServer.startGateway( testConfig, srvcs ); + MatcherAssert.assertThat( "Failed to start gateway.", gateway, notNullValue() ); + + LOG.info( "Gateway port = " + gateway.getAddresses()[ 0 ].getPort() ); + + gatewayUrl = "http://localhost:" + gateway.getAddresses()[0].getPort() + "/" + config.getGatewayPath(); + clusterUrl = gatewayUrl + "/test-cluster"; + serviceUrl = clusterUrl + "/test-service-path/test-service-resource"; + + GatewayServices services = GatewayServer.getGatewayServices(); + AliasService aliasService = (AliasService)services.getService(GatewayServices.ALIAS_SERVICE); + aliasService.addAliasForCluster("test-cluster", "ldcSystemPassword", "guest-password"); + + char[] password1 = aliasService.getPasswordFromAliasForCluster( "test-cluster", "ldcSystemPassword"); + + File descriptor = new File( topoDir, "test-cluster.xml" ); + OutputStream stream = new FileOutputStream( descriptor ); + createTopology().toStream( stream ); + stream.close(); + + } + + private static XMLTag createTopology() { + XMLTag xml = XMLDoc.newDocument( true ) + .addRoot( "topology" ) + .addTag( "gateway" ) + + .addTag( "provider" ) + .addTag( "role" ).addText( "authentication" ) + .addTag( "name" ).addText( "ShiroProvider" ) + .addTag( "enabled" ).addText( "true" ) + .addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm" ) + .addTag( "value" ).addText( "org.apache.knox.gateway.shirorealm.KnoxLdapRealm" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapGroupContextFactory" ) + .addTag( "value" ).addText( "org.apache.knox.gateway.shirorealm.KnoxLdapContextFactory" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory" ) + .addTag( "value" ).addText( "$ldapGroupContextFactory" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.authenticationMechanism" ) + .addTag( "value" ).addText( "simple" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.url" ) + .addTag( "value" ).addText( driver.getLdapUrl() ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.userDnTemplate" ) + .addTag( "value" ).addText( "uid={0},ou=people,dc=hadoop,dc=apache,dc=org" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.authorizationEnabled" ) + .addTag( "value" ).addText( "true" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.systemAuthenticationMechanism" ) + .addTag( "value" ).addText( "simple" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.searchBase" ) + .addTag( "value" ).addText( "ou=groups,dc=hadoop,dc=apache,dc=org" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.groupObjectClass" ) + .addTag( "value" ).addText( "posixGroup" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.memberAttribute" ) + .addTag( "value" ).addText( "memberUid" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.memberAttributeValueTemplate" ) + .addTag( "value" ).addText( "uid={0}" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.clusterName" ) + .addTag( "value" ).addText( "test-cluster" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.systemUsername" ) + .addTag( "value" ).addText( "uid=guest,ou=people,dc=hadoop,dc=apache,dc=org" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.systemPassword" ) + .addTag( "value" ).addText( "S{ALIAS=ldcSystemPassword}" ) + .gotoParent().addTag( "param" ) + .addTag( "name" ).addText( "urls./**" ) + .addTag( "value" ).addText( "authcBasic" ) + + .gotoParent().gotoParent().addTag( "provider" ) + .addTag( "role" ).addText( "authorization" ) + .addTag( "name" ).addText( "AclsAuthz" ) + .addTag( "enabled" ).addText( "true" ) + .addTag( "param" ) + .addTag( "name" ).addText( "test-service-role.acl" ) + .addTag( "value" ).addText( "*;analyst;*" ) + + .gotoParent().gotoParent().addTag( "provider" ) + .addTag( "role" ).addText( "identity-assertion" ) + .addTag( "enabled" ).addText( "true" ) + .addTag( "name" ).addText( "Default" ).gotoParent() + + .gotoRoot() + .addTag( "service" ) + .addTag( "role" ).addText( "test-service-role" ) + .gotoRoot(); + + return xml; + } + - private static String getResourceName( String resource ) { - return getResourceBaseName() + resource; - } - - private static String getResourceBaseName() { - return RESOURCE_BASE_CLASS.getName().replaceAll( "\\.", "/" ) + "/"; - } - + @Ignore + // @Test + public void waitForManualTesting() throws IOException { + System.in.read(); + } + + @Test( timeout = TestUtils.MEDIUM_TIMEOUT ) + public void testGroupMember() throws ClassNotFoundException, Exception { + LOG_ENTER(); + String username = "sam"; + String password = "sam-password"; + given() + //.log().all() + .auth().preemptive().basic( username, password ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_OK ) + .contentType( "text/plain" ) + .body( is( "test-service-response" ) ) + .when().get( serviceUrl ); + LOG_EXIT(); + } + + @Test( timeout = TestUtils.MEDIUM_TIMEOUT ) + public void testNonGroupMember() throws ClassNotFoundException { + LOG_ENTER(); + String username = "guest"; + String password = "guest-password"; + given() + //.log().all() + .auth().preemptive().basic( username, password ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_FORBIDDEN ) + .when().get( serviceUrl ); + LOG_EXIT(); + } + +} http://git-wip-us.apache.org/repos/asf/knox/blob/416ee7c1/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLocalServiceFuncTest.java ---------------------------------------------------------------------- diff --cc gateway-test/src/test/java/org/apache/knox/gateway/GatewayLocalServiceFuncTest.java index 4ade255,0000000..442a767 mode 100644,000000..100644 --- a/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLocalServiceFuncTest.java +++ b/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLocalServiceFuncTest.java @@@ -1,185 -1,0 +1,185 @@@ +/** + * 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; + +import com.mycila.xmltool.XMLDoc; +import com.mycila.xmltool.XMLTag; +import org.apache.commons.io.FileUtils; +import org.apache.directory.server.protocol.shared.transport.TcpTransport; +import org.apache.knox.gateway.config.GatewayConfig; +import org.apache.knox.gateway.security.ldap.SimpleLdapDirectoryServer; +import org.apache.knox.gateway.services.DefaultGatewayServices; +import org.apache.knox.gateway.services.ServiceLifecycleException; +import org.apache.hadoop.test.TestUtils; +import org.apache.hadoop.test.log.NoOpAppender; +import org.apache.http.HttpStatus; +import org.apache.log4j.Appender; +import org.hamcrest.MatcherAssert; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileOutputStream; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import static io.restassured.RestAssured.given; +import static org.apache.hadoop.test.TestUtils.LOG_ENTER; +import static org.apache.hadoop.test.TestUtils.LOG_EXIT; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; + +public class GatewayLocalServiceFuncTest { + + private static Logger LOG = LoggerFactory.getLogger( GatewayTestDriver.class ); + + public static Enumeration<Appender> appenders; + public static GatewayConfig config; + public static GatewayServer gateway; + public static String gatewayUrl; + public static String clusterUrl; + private static GatewayTestDriver driver = new GatewayTestDriver(); + + @BeforeClass + public static void setupSuite() throws Exception { + LOG_ENTER(); + appenders = NoOpAppender.setUp(); + driver.setupLdap(0); + setupGateway(); + LOG_EXIT(); + } + + @AfterClass + public static void cleanupSuite() throws Exception { + LOG_ENTER(); + gateway.stop(); + driver.cleanup(); + FileUtils.deleteQuietly( new File( config.getGatewayConfDir() ) ); + FileUtils.deleteQuietly( new File( config.getGatewayDataDir() ) ); + NoOpAppender.tearDown( appenders ); + LOG_EXIT(); + } + + public static void setupGateway() throws Exception { + + File targetDir = new File( System.getProperty( "user.dir" ), "target" ); + File gatewayDir = new File( targetDir, "gateway-home-" + UUID.randomUUID() ); + gatewayDir.mkdirs(); + + GatewayTestConfig testConfig = new GatewayTestConfig(); + config = testConfig; + testConfig.setGatewayHomeDir( gatewayDir.getAbsolutePath() ); + + File topoDir = new File( testConfig.getGatewayTopologyDir() ); + topoDir.mkdirs(); + + File deployDir = new File( testConfig.getGatewayDeploymentDir() ); + deployDir.mkdirs(); + + File descriptor = new File( topoDir, "cluster.xml" ); + FileOutputStream stream = new FileOutputStream( descriptor ); + createTopology().toStream( stream ); + stream.close(); + + DefaultGatewayServices srvcs = new DefaultGatewayServices(); + Map<String,String> options = new HashMap<>(); + options.put( "persist-master", "false" ); + options.put( "master", "password" ); + try { + srvcs.init( testConfig, options ); + } catch ( ServiceLifecycleException e ) { + e.printStackTrace(); // I18N not required. + } + gateway = GatewayServer.startGateway( testConfig, srvcs ); + MatcherAssert.assertThat( "Failed to start gateway.", gateway, notNullValue() ); + + LOG.info( "Gateway port = " + gateway.getAddresses()[ 0 ].getPort() ); + + gatewayUrl = "http://localhost:" + gateway.getAddresses()[0].getPort() + "/" + config.getGatewayPath(); + clusterUrl = gatewayUrl + "/cluster"; + } + + private static XMLTag createTopology() { + XMLTag xml = XMLDoc.newDocument( true ) + .addRoot( "topology" ) + .addTag( "gateway" ) + .addTag( "provider" ) + .addTag( "role" ).addText( "authentication" ) + .addTag( "name" ).addText( "ShiroProvider" ) + .addTag( "enabled" ).addText( "true" ) + .addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm" ) + .addTag( "value" ).addText( "org.apache.knox.gateway.shirorealm.KnoxLdapRealm" ).gotoParent() + .addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.userDnTemplate" ) + .addTag( "value" ).addText( "uid={0},ou=people,dc=hadoop,dc=apache,dc=org" ).gotoParent() + .addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.url" ) + .addTag( "value" ).addText( driver.getLdapUrl() ).gotoParent() + .addTag( "param" ) + .addTag( "name" ).addText( "main.ldapRealm.contextFactory.authenticationMechanism" ) + .addTag( "value" ).addText( "simple" ).gotoParent() + .addTag( "param" ) + .addTag( "name" ).addText( "urls./**" ) + .addTag( "value" ).addText( "authcBasic" ).gotoParent().gotoParent() + .addTag( "provider" ) + .addTag( "role" ).addText( "identity-assertion" ) + .addTag( "enabled" ).addText( "true" ) + .addTag( "name" ).addText( "Default" ).gotoParent() + .addTag( "provider" ) + .gotoRoot() + .addTag( "service" ) + .addTag( "role" ).addText( "test-jersey-service-role" ) + .gotoRoot(); + // System.out.println( "GATEWAY=" + xml.toString() ); + return xml; + } + + @Test( timeout = TestUtils.MEDIUM_TIMEOUT ) + public void testJerseyService() throws ClassNotFoundException { + LOG_ENTER(); + assertThat( ClassLoader.getSystemClassLoader().loadClass( "org.glassfish.jersey.servlet.ServletContainer" ), notNullValue() ); + assertThat( ClassLoader.getSystemClassLoader().loadClass( + "org.apache.knox.gateway.jersey.JerseyDispatchDeploymentContributor"), notNullValue() ); + assertThat( ClassLoader.getSystemClassLoader().loadClass( + "org.apache.knox.gateway.jersey.JerseyServiceDeploymentContributorBase"), notNullValue() ); + assertThat( ClassLoader.getSystemClassLoader().loadClass( + "org.apache.knox.gateway.TestJerseyService"), notNullValue() ); + + String username = "guest"; + String password = "guest-password"; + String serviceUrl = clusterUrl + "/test-jersey-service/test-jersey-resource-path"; + given() + //.log().all() + .auth().preemptive().basic( username, password ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_OK ) + .contentType( "text/plain" ) + .body( is( "test-jersey-resource-response" ) ) + .when().get( serviceUrl ); + LOG_EXIT(); + } + +} http://git-wip-us.apache.org/repos/asf/knox/blob/416ee7c1/gateway-test/src/test/java/org/apache/knox/gateway/GatewayMultiFuncTest.java ---------------------------------------------------------------------- diff --cc gateway-test/src/test/java/org/apache/knox/gateway/GatewayMultiFuncTest.java index 01fdd84,0000000..6dc469c mode 100644,000000..100644 --- a/gateway-test/src/test/java/org/apache/knox/gateway/GatewayMultiFuncTest.java +++ b/gateway-test/src/test/java/org/apache/knox/gateway/GatewayMultiFuncTest.java @@@ -1,443 -1,0 +1,443 @@@ +/** + * 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; + +import java.io.File; +import java.net.URL; +import java.nio.charset.Charset; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.directory.server.protocol.shared.transport.TcpTransport; +import org.apache.knox.gateway.security.ldap.SimpleLdapDirectoryServer; +import org.apache.knox.gateway.services.DefaultGatewayServices; +import org.apache.knox.gateway.services.GatewayServices; +import org.apache.knox.gateway.services.ServiceLifecycleException; +import org.apache.knox.gateway.services.topology.TopologyService; +import org.apache.hadoop.test.TestUtils; +import org.apache.hadoop.test.category.ReleaseTest; +import org.apache.hadoop.test.mock.MockServer; +import org.apache.http.HttpHost; +import org.apache.http.HttpStatus; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.AuthCache; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.impl.auth.BasicScheme; +import org.apache.http.impl.client.BasicAuthCache; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.log4j.Appender; +import org.hamcrest.MatcherAssert; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static io.restassured.RestAssured.given; +import static org.apache.hadoop.test.TestUtils.LOG_ENTER; +import static org.apache.hadoop.test.TestUtils.LOG_EXIT; +import static org.hamcrest.CoreMatchers.endsWith; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.xmlmatchers.XmlMatchers.hasXPath; +import static org.xmlmatchers.transform.XmlConverters.the; + +@Category(ReleaseTest.class) +public class GatewayMultiFuncTest { + + private static Logger LOG = LoggerFactory.getLogger( GatewayMultiFuncTest.class ); + private static Class<?> DAT = GatewayMultiFuncTest.class; + + private static Enumeration<Appender> appenders; + private static GatewayTestConfig config; + private static DefaultGatewayServices services; + private static GatewayServer gateway; + private static int gatewayPort; + private static String gatewayUrl; + private static TcpTransport ldapTransport; + private static Properties params; + private static TopologyService topos; + private static GatewayTestDriver driver = new GatewayTestDriver(); + + @BeforeClass + public static void setupSuite() throws Exception { + LOG_ENTER(); + //appenders = NoOpAppender.setUp(); + driver.setupLdap(0); + setupGateway(); + LOG_EXIT(); + } + + @AfterClass + public static void cleanupSuite() throws Exception { + LOG_ENTER(); + gateway.stop(); + driver.cleanup(); + FileUtils.deleteQuietly( new File( config.getGatewayHomeDir() ) ); + //NoOpAppender.tearDown( appenders ); + LOG_EXIT(); + } + + public static void setupGateway() throws Exception { + + File targetDir = new File( System.getProperty( "user.dir" ), "target" ); + File gatewayDir = new File( targetDir, "gateway-home-" + UUID.randomUUID() ); + gatewayDir.mkdirs(); + + config = new GatewayTestConfig(); + config.setGatewayHomeDir( gatewayDir.getAbsolutePath() ); + + URL svcsFileUrl = TestUtils.getResourceUrl( DAT, "services/readme.txt" ); + File svcsFile = new File( svcsFileUrl.getFile() ); + File svcsDir = svcsFile.getParentFile(); + config.setGatewayServicesDir( svcsDir.getAbsolutePath() ); + + URL appsFileUrl = TestUtils.getResourceUrl( DAT, "applications/readme.txt" ); + File appsFile = new File( appsFileUrl.getFile() ); + File appsDir = appsFile.getParentFile(); + config.setGatewayApplicationsDir( appsDir.getAbsolutePath() ); + + File topoDir = new File( config.getGatewayTopologyDir() ); + topoDir.mkdirs(); + + File deployDir = new File( config.getGatewayDeploymentDir() ); + deployDir.mkdirs(); + + startGatewayServer(); + } + + public static void startGatewayServer() throws Exception { + services = new DefaultGatewayServices(); + Map<String,String> options = new HashMap<>(); + options.put( "persist-master", "false" ); + options.put( "master", "password" ); + try { + services.init( config, options ); + } catch ( ServiceLifecycleException e ) { + e.printStackTrace(); // I18N not required. + } + topos = services.getService(GatewayServices.TOPOLOGY_SERVICE); + + gateway = GatewayServer.startGateway( config, services ); + MatcherAssert.assertThat( "Failed to start gateway.", gateway, notNullValue() ); + + gatewayPort = gateway.getAddresses()[0].getPort(); + gatewayUrl = "http://localhost:" + gatewayPort + "/" + config.getGatewayPath(); + + LOG.info( "Gateway port = " + gateway.getAddresses()[ 0 ].getPort() ); + + params = new Properties(); + params.put( "LDAP_URL", driver.getLdapUrl() ); + } + + @Test( timeout = TestUtils.MEDIUM_TIMEOUT ) + public void testDefaultJsonMimeTypeHandlingKnox678() throws Exception { + LOG_ENTER(); + + MockServer mock = new MockServer( "REPEAT", true ); + + params = new Properties(); + params.put( "LDAP_URL", driver.getLdapUrl() ); + params.put( "MOCK_SERVER_PORT", mock.getPort() ); + + String topoStr = TestUtils.merge( DAT, "topologies/test-knox678-utf8-chars-topology.xml", params ); + File topoFile = new File( config.getGatewayTopologyDir(), "knox678.xml" ); + FileUtils.writeStringToFile( topoFile, topoStr ); + + topos.reloadTopologies(); + + String uname = "guest"; + String pword = uname + "-password"; + + mock.expect().method( "GET" ) + .respond().contentType( "application/json" ).contentLength( -1 ).content( "{\"msg\":\"H\u00eallo\"}", Charset.forName( "UTF-8" ) ); + String json = given() + //.log().all() + .auth().preemptive().basic( uname, pword ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_OK ) + .contentType( "application/json; charset=UTF-8" ) + .when().get( gatewayUrl + "/knox678/repeat" ).andReturn().asString(); + assertThat( json, is("{\"msg\":\"H\u00eallo\"}") ); + assertThat( mock.isEmpty(), is(true) ); + + mock.expect().method( "GET" ) + .respond().contentType( "application/octet-stream" ).contentLength( -1 ).content( "H\u00eallo".getBytes() ); + byte[] bytes = given() + //.log().all() + .auth().preemptive().basic( uname, pword ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_OK ) + .contentType( "application/octet-stream" ) + .when().get( gatewayUrl + "/knox678/repeat" ).andReturn().asByteArray(); + assertThat( bytes, is(equalTo("H\u00eallo".getBytes())) ); + assertThat( mock.isEmpty(), is(true) ); + + mock.stop(); + + LOG_EXIT(); + } + + @Test( timeout = TestUtils.MEDIUM_TIMEOUT ) + public void testPostWithContentTypeKnox681() throws Exception { + LOG_ENTER(); + + MockServer mock = new MockServer( "REPEAT", true ); + + params = new Properties(); + params.put( "MOCK_SERVER_PORT", mock.getPort() ); + params.put( "LDAP_URL", driver.getLdapUrl() ); + + String topoStr = TestUtils.merge( DAT, "topologies/test-knox678-utf8-chars-topology.xml", params ); + File topoFile = new File( config.getGatewayTopologyDir(), "knox681.xml" ); + FileUtils.writeStringToFile( topoFile, topoStr ); + + topos.reloadTopologies(); + + mock + .expect() + .method( "PUT" ) + .pathInfo( "/repeat-context/" ) + .respond() + .status( HttpStatus.SC_CREATED ) + .content( "{\"name\":\"value\"}".getBytes() ) + .contentLength( -1 ) + .contentType( "application/json; charset=UTF-8" ) + .header( "Location", gatewayUrl + "/knox681/repeat" ); + + String uname = "guest"; + String pword = uname + "-password"; + + HttpHost targetHost = new HttpHost( "localhost", gatewayPort, "http" ); + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials( + new AuthScope( targetHost.getHostName(), targetHost.getPort() ), + new UsernamePasswordCredentials( uname, pword ) ); + + AuthCache authCache = new BasicAuthCache(); + BasicScheme basicAuth = new BasicScheme(); + authCache.put( targetHost, basicAuth ); + + HttpClientContext context = HttpClientContext.create(); + context.setCredentialsProvider( credsProvider ); + context.setAuthCache( authCache ); + + CloseableHttpClient client = HttpClients.createDefault(); + HttpPut request = new HttpPut( gatewayUrl + "/knox681/repeat" ); + request.addHeader( "X-XSRF-Header", "jksdhfkhdsf" ); + request.addHeader( "Content-Type", "application/json" ); + CloseableHttpResponse response = client.execute( request, context ); + assertThat( response.getStatusLine().getStatusCode(), is( HttpStatus.SC_CREATED ) ); + assertThat( response.getFirstHeader( "Location" ).getValue(), endsWith("/gateway/knox681/repeat" ) ); + assertThat( response.getFirstHeader( "Content-Type" ).getValue(), is("application/json; charset=UTF-8") ); + String body = new String( IOUtils.toByteArray( response.getEntity().getContent() ), Charset.forName( "UTF-8" ) ); + assertThat( body, is( "{\"name\":\"value\"}" ) ); + response.close(); + client.close(); + + mock + .expect() + .method( "PUT" ) + .pathInfo( "/repeat-context/" ) + .respond() + .status( HttpStatus.SC_CREATED ) + .content( "<test-xml/>".getBytes() ) + .contentType( "application/xml; charset=UTF-8" ) + .header( "Location", gatewayUrl + "/knox681/repeat" ); + + client = HttpClients.createDefault(); + request = new HttpPut( gatewayUrl + "/knox681/repeat" ); + request.addHeader( "X-XSRF-Header", "jksdhfkhdsf" ); + request.addHeader( "Content-Type", "application/xml" ); + response = client.execute( request, context ); + assertThat( response.getStatusLine().getStatusCode(), is( HttpStatus.SC_CREATED ) ); + assertThat( response.getFirstHeader( "Location" ).getValue(), endsWith("/gateway/knox681/repeat" ) ); + assertThat( response.getFirstHeader( "Content-Type" ).getValue(), is("application/xml; charset=UTF-8") ); + body = new String( IOUtils.toByteArray( response.getEntity().getContent() ), Charset.forName( "UTF-8" ) ); + assertThat( the(body), hasXPath( "/test-xml" ) ); + response.close(); + client.close(); + + mock.stop(); + + LOG_EXIT(); + } + + @Test( timeout = TestUtils.MEDIUM_TIMEOUT ) + public void testLdapSearchConfigEnhancementsKnox694() throws Exception { + LOG_ENTER(); + + String topoStr; + File topoFile; + + String adminUName = "uid=admin,ou=people,dc=hadoop,dc=apache,dc=org"; + String adminPWord = "admin-password"; + String uname = "people\\guest"; + String pword = "guest-password"; + String invalidPword = "invalid-guest-password"; + + params = new Properties(); + params.put( "LDAP_URL", driver.getLdapUrl() ); + params.put( "LDAP_SYSTEM_USERNAME", adminUName ); + params.put( "LDAP_SYSTEM_PASSWORD", adminPWord ); + + topoStr = TestUtils.merge( DAT, "topologies/test-knox694-principal-regex-user-dn-template.xml", params ); + topoFile = new File( config.getGatewayTopologyDir(), "knox694-1.xml" ); + FileUtils.writeStringToFile( topoFile, topoStr ); + topos.reloadTopologies(); + + given() + //.log().all() + .auth().preemptive().basic( uname, pword ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_OK ) + .contentType( "text/plain" ) + .body( is( "test-service-response" ) ) + .when().get( gatewayUrl + "/knox694-1/test-service-path/test-resource-path" ); + given() + //.log().all() + .auth().preemptive().basic( uname, invalidPword ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_UNAUTHORIZED ) + .when().get( gatewayUrl + "/knox694-1/test-service-path/test-resource-path" ); + + topoStr = TestUtils.merge( DAT, "topologies/test-knox694-principal-regex-search-attribute.xml", params ); + topoFile = new File( config.getGatewayTopologyDir(), "knox694-2.xml" ); + FileUtils.writeStringToFile( topoFile, topoStr ); + topos.reloadTopologies(); + + given() + //.log().all() + .auth().preemptive().basic( uname, pword ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_OK ) + .contentType( "text/plain" ) + .body( is( "test-service-response" ) ) + .when().get( gatewayUrl + "/knox694-2/test-service-path/test-resource-path" ); + given() + //.log().all() + .auth().preemptive().basic( uname, invalidPword ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_UNAUTHORIZED ) + .when().get( gatewayUrl + "/knox694-2/test-service-path/test-resource-path" ); + + topoStr = TestUtils.merge( DAT, "topologies/test-knox694-principal-regex-search-filter.xml", params ); + topoFile = new File( config.getGatewayTopologyDir(), "knox694-3.xml" ); + FileUtils.writeStringToFile( topoFile, topoStr ); + topos.reloadTopologies(); + + given() + //.log().all() + .auth().preemptive().basic( uname, pword ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_OK ) + .contentType( "text/plain" ) + .body( is( "test-service-response" ) ) + .when().get( gatewayUrl + "/knox694-3/test-service-path/test-resource-path" ); + given() + //.log().all() + .auth().preemptive().basic( uname, invalidPword ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_UNAUTHORIZED ) + .when().get( gatewayUrl + "/knox694-3/test-service-path/test-resource-path" ); + + topoStr = TestUtils.merge( DAT, "topologies/test-knox694-principal-regex-search-scope-object.xml", params ); + topoFile = new File( config.getGatewayTopologyDir(), "knox694-4.xml" ); + FileUtils.writeStringToFile( topoFile, topoStr ); + topos.reloadTopologies(); + + given() + //.log().all() + .auth().preemptive().basic( uname, pword ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_OK ) + .contentType( "text/plain" ) + .body( is( "test-service-response" ) ) + .when().get( gatewayUrl + "/knox694-4/test-service-path/test-resource-path" ); + given() + //.log().all() + .auth().preemptive().basic( uname, invalidPword ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_UNAUTHORIZED ) + .when().get( gatewayUrl + "/knox694-4/test-service-path/test-resource-path" ); + + topoStr = TestUtils.merge( DAT, "topologies/test-knox694-principal-regex-search-scope-onelevel-positive.xml", params ); + topoFile = new File( config.getGatewayTopologyDir(), "knox694-5.xml" ); + FileUtils.writeStringToFile( topoFile, topoStr ); + topos.reloadTopologies(); + + given() + //.log().all() + .auth().preemptive().basic( uname, pword ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_OK ) + .contentType( "text/plain" ) + .body( is( "test-service-response" ) ) + .when().get( gatewayUrl + "/knox694-5/test-service-path/test-resource-path" ); + given() + //.log().all() + .auth().preemptive().basic( uname, invalidPword ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_UNAUTHORIZED ) + .when().get( gatewayUrl + "/knox694-5/test-service-path/test-resource-path" ); + + topoStr = TestUtils.merge( DAT, "topologies/test-knox694-principal-regex-search-scope-onelevel-negative.xml", params ); + topoFile = new File( config.getGatewayTopologyDir(), "knox694-6.xml" ); + FileUtils.writeStringToFile( topoFile, topoStr ); + topos.reloadTopologies(); + + given() + //.log().all() + .auth().preemptive().basic( uname, pword ) - .expect() ++ .then() + //.log().all() + .statusCode( HttpStatus.SC_UNAUTHORIZED ) + .when().get( gatewayUrl + "/knox694-6/test-service-path/test-resource-path" ); + + LOG_EXIT(); + } + +} + +