/* * JBoss, Home of Professional Open Source * Copyright 2012, Red Hat Middleware LLC, and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * Licensed 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.jboss.as.test.integration.security.perimeter; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.FAILURE_DESCRIPTION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OUTCOME; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_ATTRIBUTE_OPERATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_RESOURCE_OPERATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RECURSIVE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RESULT; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUCCESS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpOptions; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpTrace; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.as.arquillian.api.ServerSetup; import org.jboss.as.arquillian.api.ServerSetupTask; import org.jboss.as.arquillian.container.ManagementClient; import org.jboss.as.arquillian.container.NetworkUtils; import org.jboss.as.controller.client.ModelControllerClient; import org.jboss.dmr.ModelNode; import org.jboss.logging.Logger; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.Test; import org.junit.runner.RunWith; /** * Test verifies that the web management console is secured * * @author jlanik@redhat.com */ @RunWith(Arquillian.class) @RunAsClient @ServerSetup(WebConsoleSecurityTestCase.ConnectionManager.class) public class WebConsoleSecurityTestCase { public static class ConnectionManager implements ServerSetupTask { private static Logger log = Logger.getLogger(WebConsoleSecurityTestCase.ConnectionManager.class); private static URL consoleURL; private static URL getConsoleUrl() throws MalformedURLException { if (null == consoleURL) { throw new AssertionError("consoleURL should have been initialized!"); } return consoleURL; } public void setup(ManagementClient managementClient, String containerId) throws Exception { log.trace("Setup started"); consoleURL = new URL(getBinding("http", "management-http", managementClient.getControllerClient()).toURL() + "/management"); log.debug("management web console URL retrieved: " + consoleURL); } public void tearDown(ManagementClient managementClient, String containerId) throws Exception { // this is intentionaly empty } private URI getBinding(final String protocol, final String socketBinding, ModelControllerClient client) { try { //TODO: resolve socket binding group correctly (copied from ModelControllerClient) final String NAME = "name"; final String socketBindingGroupName = readRootNode(client).get("socket-binding-group").keys().iterator().next(); final ModelNode operation = new ModelNode(); operation.get(OP_ADDR).get("socket-binding-group").set(socketBindingGroupName); operation.get(OP_ADDR).get("socket-binding").set(socketBinding); operation.get(OP).set(READ_ATTRIBUTE_OPERATION); operation.get(NAME).set("bound-address"); String ip = executeForResult(operation, client).asString(); //it appears some system can return a binding with the zone specifier on the end if (ip.contains(":") && ip.contains("%")) { ip = ip.split("%")[0]; } final ModelNode portOp = new ModelNode(); portOp.get(OP_ADDR).get("socket-binding-group").set(socketBindingGroupName); portOp.get(OP_ADDR).get("socket-binding").set(socketBinding); portOp.get(OP).set(READ_ATTRIBUTE_OPERATION); portOp.get(NAME).set("bound-port"); final int port = defined(executeForResult(portOp, client), socketBindingGroupName + " -> " + socketBinding + " -> bound-port is undefined").asInt(); return URI.create(protocol + "://" + NetworkUtils.formatPossibleIpv6Address(ip) + ":" + port); } catch (Exception e) { throw new RuntimeException(e); } } private ModelNode executeForResult(final ModelNode operation, ModelControllerClient client) throws Exception { final ModelNode result = client.execute(operation); checkSuccessful(result, operation); return result.get(RESULT); } private static ModelNode defined(final ModelNode node, final String message) { if (!node.isDefined()) { throw new IllegalStateException(message); } return node; } private ModelNode readRootNode(ModelControllerClient client) throws Exception { final ModelNode operation = new ModelNode(); operation.get(OP).set(READ_RESOURCE_OPERATION); operation.get(RECURSIVE).set("true"); operation.get(OP_ADDR).set(new ModelNode()); return executeForResult(operation, client); } private void checkSuccessful(final ModelNode result, final ModelNode operation) throws UnSuccessfulOperationException { if (!SUCCESS.equals(result.get(OUTCOME).asString())) { throw new UnSuccessfulOperationException(result.get( FAILURE_DESCRIPTION).toString()); } } private static class UnSuccessfulOperationException extends Exception { private static final long serialVersionUID = 1L; UnSuccessfulOperationException(String message) { super(message); } } } private static HttpURLConnection connection; private static Logger log = Logger.getLogger(WebConsoleSecurityTestCase.class); private HttpURLConnection getConnection() throws Exception { connection = (HttpURLConnection) ConnectionManager.getConsoleUrl().openConnection(); assertNotNull(connection); log.debug("connection opened"); connection.setDoInput(true); connection.setRequestProperty("Cookie", "MODIFY ME IF NEEDED"); return connection; } @Deployment public static JavaArchive createTestArchive() { return ShrinkWrap.create(JavaArchive.class, "test.jar"); } @Test public void testGet() throws Exception { getConnection().setRequestMethod(HttpGet.METHOD_NAME); getConnection().connect(); assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, getConnection().getResponseCode()); } @Test public void testPost() throws Exception { getConnection().setRequestMethod(HttpPost.METHOD_NAME); getConnection().connect(); assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, getConnection().getResponseCode()); } @Test public void testHead() throws Exception { getConnection().setRequestMethod(HttpHead.METHOD_NAME); getConnection().connect(); assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, getConnection().getResponseCode()); } @Test public void testOptions() throws Exception { getConnection().setRequestMethod(HttpOptions.METHOD_NAME); getConnection().connect(); assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, getConnection().getResponseCode()); } @Test public void testPut() throws Exception { getConnection().setRequestMethod(HttpPut.METHOD_NAME); getConnection().connect(); assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, getConnection().getResponseCode()); } @Test public void testTrace() throws Exception { getConnection().setRequestMethod(HttpTrace.METHOD_NAME); getConnection().connect(); assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, getConnection().getResponseCode()); } @Test public void testDelete() throws Exception { getConnection().setRequestMethod(HttpDelete.METHOD_NAME); getConnection().connect(); assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, getConnection().getResponseCode()); } }