diff options
| author | Keith Wall <kwall@apache.org> | 2011-11-24 10:43:24 +0000 |
|---|---|---|
| committer | Keith Wall <kwall@apache.org> | 2011-11-24 10:43:24 +0000 |
| commit | 59c39b43a3d42498d065962aff6e3b5d58da6dbc (patch) | |
| tree | 235fc91e82a30a3ded696e07df9177f052659883 /java/systests/src | |
| parent | 3a8e623a3ad07fce4e7338ecb68896b7405276f1 (diff) | |
| download | qpid-python-59c39b43a3d42498d065962aff6e3b5d58da6dbc.tar.gz | |
QPID-3641: ACLV2 Simplifications and Improvements for Java Broker
Improvements and simplifications to ACL V2 for the Java Broker:
1) Removed 'EXECUTE' operation (we now just have ACCESS and UPDATE like C++ broker)
2) Enable users with management rights for a procedure to complete that procedure without matching AMQP rights (configurable)
3) Fix up system tests (make clearer, remove need for lots of support files)
4) Fix disparity in DENY_LOG and DENY-LOG values between brokers.
5) Get rid of transitive/expand permission rules
Work from Robbie Gemmell and myself.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1205782 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/systests/src')
8 files changed, 432 insertions, 876 deletions
diff --git a/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java b/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java index 2629e82831..e7da4472f5 100644 --- a/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java +++ b/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java @@ -18,7 +18,6 @@ */ package org.apache.qpid.server.logging; -import java.io.File; import java.util.List; import javax.jms.Connection; @@ -29,6 +28,7 @@ import org.apache.qpid.AMQException; import org.apache.qpid.client.AMQSession; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.server.security.acl.AbstractACLTestCase; /** * ACL version 2/3 file testing to verify that ACL actor logging works correctly. @@ -49,13 +49,18 @@ public class AccessControlLoggingTest extends AbstractTestLogging public void setUp() throws Exception { - setConfigurationProperty("virtualhosts.virtualhost.test.security.aclv2", - QpidHome + File.separator + "etc" + File.separator + "test-logging.txt"); - + // Write out ACL for this test + AbstractACLTestCase.writeACLFileUtil(this, "test", + "ACL ALLOW client ACCESS VIRTUALHOST", + "ACL ALLOW client CREATE QUEUE name='allow'", + "ACL ALLOW-LOG client CREATE QUEUE name='allow-log'", + "ACL DENY client CREATE QUEUE name='deny'", + "ACL DENY-LOG client CREATE QUEUE name='deny-log'"); + super.setUp(); + } - /** FIXME This comes from SimpleACLTest and makes me suspicious. */ @Override public void tearDown() throws Exception { @@ -69,7 +74,7 @@ public class AccessControlLoggingTest extends AbstractTestLogging //that we provoked with authentication failures, where the test passes - we can ignore on con close } } - + /** * Test that {@code allow} ACL entries do not log anything. */ diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java index 32b0185f88..a4155d10e2 100644 --- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java +++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java @@ -24,8 +24,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.Collections; -import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -55,29 +53,24 @@ import org.apache.qpid.url.URLSyntaxException; * @see ExternalACLTest * @see ExternalACLFileTest * @see ExternalACLJMXTest - * @see ExternalAdminACLTest * @see ExhaustiveACLTest */ public abstract class AbstractACLTestCase extends QpidBrokerTestCase implements ConnectionListener { /** Used to synchronise {@link #tearDown()} when exceptions are thrown */ - protected CountDownLatch _exceptionReceived; - - /** Override this to return the name of the configuration XML file. */ - public abstract String getConfig(); + protected CountDownLatch _exceptionReceived; - /** Override this to setup external ACL files for virtual hosts. */ - public List<String> getHostList() + /** Override this to return the name of the configuration XML file. */ + public String getConfig() { - return Collections.emptyList(); + return "config-systests.xml"; } - + /** * This setup method checks {@link #getConfig()} and {@link #getHostList()} to initialise the broker with specific * ACL configurations and then runs an optional per-test setup method, which is simply a method with the same name * as the test, but starting with {@code setUp} rather than {@code test}. * - * @see #setUpACLFile(String) * @see org.apache.qpid.test.utils.QpidBrokerTestCase#setUp() */ @Override @@ -85,12 +78,7 @@ public abstract class AbstractACLTestCase extends QpidBrokerTestCase implements { // Initialise ACLs. _configFile = new File("build" + File.separator + "etc" + File.separator + getConfig()); - // Initialise ACL files - for (String virtualHost : getHostList()) - { - setUpACLFile(virtualHost); - } - + // run test specific setup String testSetup = StringUtils.replace(getName(), "test", "setUp"); try @@ -124,73 +112,27 @@ public abstract class AbstractACLTestCase extends QpidBrokerTestCase implements } } - /** - * Configures specific ACL files for a virtual host. - * - * This method checks for ACL files that exist on the filesystem. If dynamically generatyed ACL files are required in a test, - * then it is easier to use the {@code setUp} prefix on a method to generate the ACL file. In order, this method looks - * for three files: - * <ol> - * <li><em>virtualhost</em>-<em>class</em>-<em>test</em>.txt - * <li><em>virtualhost</em>-<em>class</em>.txt - * <li><em>virtualhost</em>-default.txt - * </ol> - * The <em>class</em> and <em>test</em> parts are the test class and method names respectively, with the word {@code test} - * removed and the rest of the text converted to lowercase. For example, the test class and method named - * {@code org.apache.qpid.test.AccessExampleTest#testExampleMethod} on the {@code testhost} virtualhost would use - * one of the following files: - * <ol> - * <li>testhost-accessexample-examplemethod.txt - * <li>testhost-accessexample.txt - * <li>testhost-default.txt - * </ol> - * These files should be copied to the <em>${QPID_HOME}/etc</em> directory when the test is run. - * - * @see #writeACLFile(String, String...) - */ - public void setUpACLFile(String virtualHost) throws IOException, ConfigurationException + public void writeACLFile(final String vhost, final String...rules) throws ConfigurationException, IOException { - String path = "build" + File.separator + "etc"; - String className = StringUtils.substringBeforeLast(getClass().getSimpleName().toLowerCase(), "test"); - String testName = StringUtils.substringAfter(getName(), "test").toLowerCase(); - - File aclFile = new File(path, virtualHost + "-" + className + "-" + testName + ".txt"); - if (!aclFile.exists()) - { - aclFile = new File(path, virtualHost + "-" + className + ".txt"); - if (!aclFile.exists()) - { - aclFile = new File(path, virtualHost + "-" + "default.txt"); - } - } - - // Set the ACL file configuration property - if (virtualHost.equals("global")) - { - setConfigurationProperty("security.aclv2", aclFile.getAbsolutePath()); - } - else - { - setConfigurationProperty("virtualhosts.virtualhost." + virtualHost + ".security.aclv2", aclFile.getAbsolutePath()); - } + writeACLFileUtil(this, vhost, rules); } - public void writeACLFile(String vhost, String...rules) throws ConfigurationException, IOException + public static void writeACLFileUtil(QpidBrokerTestCase testcase, String vhost, String...rules) throws ConfigurationException, IOException { - File aclFile = File.createTempFile(getClass().getSimpleName(), getName()); + File aclFile = File.createTempFile(testcase.getClass().getSimpleName(), testcase.getName()); aclFile.deleteOnExit(); - if ("global".equals(vhost)) + if (vhost == null) { - setConfigurationProperty("security.aclv2", aclFile.getAbsolutePath()); + testcase.setConfigurationProperty("security.aclv2", aclFile.getAbsolutePath()); } else { - setConfigurationProperty("virtualhosts.virtualhost." + vhost + ".security.aclv2", aclFile.getAbsolutePath()); + testcase.setConfigurationProperty("virtualhosts.virtualhost." + vhost + ".security.aclv2", aclFile.getAbsolutePath()); } PrintWriter out = new PrintWriter(new FileWriter(aclFile)); - out.println(String.format("# %s", getTestName())); + out.println(String.format("# %s", testcase.getName())); for (String line : rules) { out.println(line); @@ -265,7 +207,7 @@ public abstract class AbstractACLTestCase extends QpidBrokerTestCase implements public void check403Exception(Throwable t) throws Exception { assertNotNull("There was no linked exception", t); - assertTrue("Wrong linked exception type", t instanceof AMQException); + assertTrue("Wrong linked exception type : " + t.getClass(), t instanceof AMQException); assertEquals("Incorrect error code received", 403, ((AMQException) t).getErrorCode().getCode()); //use the latch to ensure the control thread waits long enough for the exception thread diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExhaustiveACLTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExhaustiveACLTest.java index 1b2c98d30a..4f2464e186 100644 --- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExhaustiveACLTest.java +++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExhaustiveACLTest.java @@ -18,9 +18,6 @@ */ package org.apache.qpid.server.security.acl; -import java.util.Arrays; -import java.util.List; - import javax.jms.Connection; import javax.jms.Session; @@ -31,7 +28,7 @@ import org.apache.qpid.protocol.AMQConstant; /** * ACL version 2/3 file testing to verify that ACL entries control queue creation with specific properties. - * + * * Tests have their own ACL files that setup specific permissions, and then try to create queues with every possible combination * of properties to show that rule matching works correctly. For example, a rule that specified {@code autodelete="true"} for * queues with {@link name="temp.true.*"} as well should not affect queues that have names that do not match, or queues that @@ -39,18 +36,7 @@ import org.apache.qpid.protocol.AMQConstant; */ public class ExhaustiveACLTest extends AbstractACLTestCase { - @Override - public String getConfig() - { - return "config-systests-aclv2.xml"; - } - @Override - public List<String> getHostList() - { - return Arrays.asList("test", "test2"); - } - /** * Creates a queue. * @@ -130,11 +116,6 @@ public class ExhaustiveACLTest extends AbstractACLTestCase createQueueFailure("test", "client", "temp.false.07", true, false); createQueueFailure("test", "server", "temp.true.08", true, false); createQueueFailure("test", "client", "temp.other.09", false, false); - createQueueSuccess("test2", "guest", "temp.true.01", false, false); - createQueueSuccess("test2", "guest", "temp.false.02", true, false); - createQueueSuccess("test2", "guest", "temp.true.03", true, false); - createQueueSuccess("test2", "guest", "temp.false.04", false, false); - createQueueSuccess("test2", "guest", "temp.other.05", false, false); } public void setUpAuthoriseCreateQueue() throws Exception @@ -161,10 +142,6 @@ public class ExhaustiveACLTest extends AbstractACLTestCase createQueueFailure("test", "server", "create.05", true, false); createQueueFailure("test", "server", "create.06", false, true); createQueueFailure("test", "server", "create.07", true, false); - createQueueSuccess("test2", "guest", "create.00", true, true); - createQueueSuccess("test2", "guest", "create.01", true, false); - createQueueSuccess("test2", "guest", "create.02", false, true); - createQueueSuccess("test2", "guest", "create.03", true, false); } public void setUpAuthoriseCreateQueueBoth() throws Exception @@ -190,6 +167,5 @@ public class ExhaustiveACLTest extends AbstractACLTestCase createQueueSuccess("test", "client", "tmp.00", true, false); createQueueSuccess("test", "server", "tmp.01", true, false); createQueueSuccess("test", "guest", "tmp.02", true, false); - createQueueSuccess("test2", "guest", "create.02", false, false); } } diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLFileTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLFileTest.java index 1d08015669..5ab2fede83 100644 --- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLFileTest.java +++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLFileTest.java @@ -18,9 +18,6 @@ */ package org.apache.qpid.server.security.acl; -import java.util.Arrays; -import java.util.List; - import javax.jms.Connection; import javax.jms.Session; @@ -38,18 +35,6 @@ import org.apache.qpid.framing.AMQShortString; */ public class ExternalACLFileTest extends AbstractACLTestCase { - @Override - public String getConfig() - { - return "config-systests-aclv2.xml"; - } - - @Override - public List<String> getHostList() - { - return Arrays.asList("test"); - } - private void createQueuePrefixList(String prefix, int count) { try @@ -99,6 +84,7 @@ public class ExternalACLFileTest extends AbstractACLTestCase { writeACLFile( "test", + "ACL ALLOW-LOG client ACCESS VIRTUALHOST", "acl allow client create queue name=mixed.000", "ACL ALLOW client CREATE QUEUE NAME=mixed.001", "Acl Allow client Create Queue Name=mixed.002", @@ -116,6 +102,7 @@ public class ExternalACLFileTest extends AbstractACLTestCase { writeACLFile( "test", + "ACL ALLOW-LOG client ACCESS VIRTUALHOST", "acl allow client create queue name=continuation.000", "acl allow client create queue \\", " name=continuation.001", @@ -143,6 +130,7 @@ public class ExternalACLFileTest extends AbstractACLTestCase { writeACLFile( "test", + "ACL ALLOW-LOG client ACCESS VIRTUALHOST", "acl allow client create queue name=whitespace.000", "acl\tallow\tclient\tcreate\tqueue\tname=whitespace.001", "acl allow client create queue name = whitespace.002", @@ -160,6 +148,7 @@ public class ExternalACLFileTest extends AbstractACLTestCase { writeACLFile( "test", + "ACL ALLOW-LOG client ACCESS VIRTUALHOST", "acl allow client create queue name='quoting.ABC.000'", "acl allow client create queue name='quoting.*.000'", "acl allow client create queue name='quoting.#.000'", diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java index 4552cf7004..427d253ca5 100644 --- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java +++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java @@ -18,36 +18,26 @@ */ package org.apache.qpid.server.security.acl; -import java.util.Arrays; -import java.util.List; +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; -import org.apache.qpid.AMQConnectionClosedException; -import org.apache.qpid.AMQException; -import org.apache.qpid.AMQSecurityException; -import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.management.common.mbeans.ServerInformation; +import org.apache.qpid.server.management.ManagedObject; +import org.apache.qpid.server.security.access.ObjectType; import org.apache.qpid.test.utils.JMXTestUtils; /** - * Tests that ACL entries that apply to AMQP objects also apply when those objects are accessed via JMX. + * Tests that access to the JMX interface is governed only by {@link ObjectType#METHOD}/{@link ObjectType#ALL} + * rules and AMQP rights have no effect. + * + * Ensures that objects outside the Qpid domain ({@link ManagedObject#DOMAIN}) are not governed by the ACL model. */ public class ExternalACLJMXTest extends AbstractACLTestCase { private JMXTestUtils _jmx; - - private static final String QUEUE_NAME = "kipper"; - private static final String EXCHANGE_NAME = "amq.kipper"; - - @Override - public String getConfig() - { - return "config-systests-aclv2.xml"; - } - @Override - public List<String> getHostList() - { - return Arrays.asList("test"); - } + private static final String TEST_QUEUE_OWNER = "admin"; + private static final String TEST_VHOST = "test"; @Override public void setUp() throws Exception @@ -65,180 +55,264 @@ public class ExternalACLJMXTest extends AbstractACLTestCase super.tearDown(); } - // test-externalacljmx.txt - // create queue owner=client # success - public void testCreateClientQueueSuccess() throws Exception - { - //Queue Parameters - String queueOwner = "client"; - - _jmx.createQueue("test", QUEUE_NAME, queueOwner, true); + /** + * Ensure an empty ACL defaults to DENY ALL. + */ + public void setUpDenyAllIsDefault() throws Exception + { + writeACLFile(null, "#Empty ACL file"); } - // test-externalacljmx.txt - // create queue owner=client # failure - public void testCreateServerQueueFailure() throws Exception - { - //Queue Parameters - String queueOwner = "server"; - + public void testDenyAllIsDefault() throws Exception + { + //try a broker-level method + ServerInformation info = _jmx.getServerInformation(); try { - _jmx.createQueue("test", QUEUE_NAME, queueOwner, true); - - fail("Queue create should fail"); + info.resetStatistics(); + fail("Exception not thrown"); } - catch (Exception e) + catch (SecurityException e) { - assertNotNull("Cause is not set", e.getCause()); - assertEquals("Cause message incorrect", - "org.apache.qpid.AMQSecurityException: Permission denied: queue-name 'kipper' [error code 403: access refused]", e.getCause().getMessage()); + assertEquals("Cause message incorrect", "Permission denied: Update resetStatistics", e.getMessage()); } - } - // no create queue acl in file # failure - public void testCreateQueueFailure() throws Exception - { - //Queue Parameters - String queueOwner = "guest"; - + //try a vhost-level method try { - _jmx.createQueue("test", QUEUE_NAME, queueOwner, true); - - fail("Queue create should fail"); + _jmx.createQueue(TEST_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true); + fail("Exception not thrown"); } catch (Exception e) { - assertNotNull("Cause is not set", e.getCause()); - assertEquals("Cause message incorrect", - "org.apache.qpid.AMQSecurityException: Permission denied: queue-name 'kipper' [error code 403: access refused]", e.getCause().getMessage()); + assertEquals("Cause message incorrect", "Permission denied: Update createNewQueue", e.getMessage()); } + + // Ensure that calls to MBeans outside the Qpid domain are not impeded. + final RuntimeMXBean runtimeBean = _jmx.getManagedObject(RuntimeMXBean.class, ManagementFactory.RUNTIME_MXBEAN_NAME); + runtimeBean.getName(); + // PASS } - // test-externalacljmx.txt - // allow create exchange name=amq.kipper.success - public void testCreateExchangeSuccess() throws Exception - { - _jmx.createExchange("test", EXCHANGE_NAME + ".success", "direct", true); + /** + * Ensure an ALLOW ALL ALL rule allows access to both getters/setters. + */ + public void setUpAllowAll() throws Exception + { + writeACLFile(null, "ACL ALLOW ALL ALL"); } - // test-externalacljmx.txt - // deny create exchange name=amq.kipper.failure - public void testCreateExchangeFailure() throws Exception - { - try - { - _jmx.createExchange("test", EXCHANGE_NAME + ".failure", "direct", true); - - fail("Exchange create should fail"); - } - catch (Exception e) - { - assertNotNull("Cause is not set", e.getCause()); - assertEquals("Cause message incorrect", - "org.apache.qpid.AMQSecurityException: Permission denied: exchange-name 'amq.kipper.failure' [error code 403: access refused]", e.getCause().getMessage()); - } + public void testAllowAll() throws Exception + { + ServerInformation info = _jmx.getServerInformation(); + info.getBuildVersion(); // getter - requires ACCESS + info.resetStatistics(); // setter - requires UPDATE + // PASS } - // test-externalacljmx.txt - // allow create exchange name=amq.kipper.success - // allow delete exchange name=amq.kipper.success - public void testDeleteExchangeSuccess() throws Exception - { - _jmx.createExchange("test", EXCHANGE_NAME + ".success", "direct", true); - _jmx.unregisterExchange("test", EXCHANGE_NAME + ".success"); + /** + * admin user is denied at broker level but allowed at vhost level. + */ + public void setUpVhostAllowOverridesGlobalDeny() throws Exception + { + writeACLFile(null, + "ACL DENY admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'"); + writeACLFile(TEST_VHOST, + "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'"); } - // test-externalacljmx-deleteexchangefailure.txt - // allow create exchange name=amq.kipper.delete - // deny delete exchange name=amq.kipper.delete - public void testDeleteExchangeFailure() throws Exception - { - _jmx.createExchange("test", EXCHANGE_NAME + ".delete", "direct", true); + public void testVhostAllowOverridesGlobalDeny() throws Exception + { + //try a vhost-level method on the allowed vhost + _jmx.createQueue(TEST_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true); + + //try a vhost-level method on a different vhost try { - _jmx.unregisterExchange("test", EXCHANGE_NAME + ".delete"); - - fail("Exchange delete should fail"); + _jmx.createQueue("development", getTestQueueName(), TEST_QUEUE_OWNER, true); + fail("Exception not thrown"); } - catch (Exception e) + catch (SecurityException e) { - assertNotNull("Cause is not set", e.getCause()); - assertEquals("Cause message incorrect", - "org.apache.qpid.AMQSecurityException: Permission denied [error code 403: access refused]", e.getCause().getMessage()); + assertEquals("Cause message incorrect", "Permission denied: Update createNewQueue", e.getMessage()); } } - + + /** - * admin user has JMX right but not AMQP + * admin user is allowed all update methods on the component at broker level. */ - public void setUpCreateQueueJMXRights() throws Exception + public void setUpUpdateComponentOnlyAllow() throws Exception { - writeACLFile("test", - "ACL ALLOW admin EXECUTE METHOD component=\"VirtualHost.VirtualHostManager\" name=\"createNewQueue\"", - "ACL DENY admin CREATE QUEUE"); + writeACLFile(null, + "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager'"); } - - public void testCreateQueueJMXRights() throws Exception + + public void testUpdateComponentOnlyAllow() throws Exception + { + _jmx.createQueue(TEST_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true); + // PASS + _jmx.deleteQueue(TEST_VHOST, getTestQueueName()); + // PASS + } + + + /** + * admin user is allowed all update methods on all components at broker level. + */ + public void setUpUpdateMethodOnlyAllow() throws Exception + { + writeACLFile(null, + "ACL ALLOW admin UPDATE METHOD"); + } + + public void testUpdateMethodOnlyAllow() throws Exception + { + _jmx.createQueue(TEST_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true); + //PASS + _jmx.deleteQueue(TEST_VHOST, getTestQueueName()); + // PASS + } + + + /** + * admin user has JMX right, AMPQ right is irrelevant. + */ + public void setUpCreateQueueSuccess() throws Exception + { + writeACLFile(TEST_VHOST, + "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'"); + } + + public void testCreateQueueSuccess() throws Exception + { + _jmx.createQueue(TEST_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true); + } + + + /** + * admin user has JMX right, verifies lack of AMPQ rights is irrelevant. + */ + public void setUpCreateQueueSuccessNoAMQPRights() throws Exception + { + writeACLFile(TEST_VHOST, + "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'", + "ACL DENY admin CREATE QUEUE"); + } + + public void testCreateQueueSuccessNoAMQPRights() throws Exception + { + _jmx.createQueue(TEST_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true); + } + + + /** + * admin user does not have JMX right, AMPQ right is irrelevant. + */ + public void setUpCreateQueueDenied() throws Exception + { + writeACLFile(TEST_VHOST, + "ACL DENY admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'"); + } + + public void testCreateQueueDenied() throws Exception { try { - _jmx.createQueue("test", QUEUE_NAME, "admin", true); - - fail("Queue create should fail"); + _jmx.createQueue(TEST_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true); + fail("Exception not thrown"); } - catch (Exception e) + catch (SecurityException e) { - assertNotNull("Cause is not set", e.getCause()); - assertEquals("Cause message incorrect", - "org.apache.qpid.AMQSecurityException: Permission denied: queue-name 'kipper' [error code 403: access refused]", e.getCause().getMessage()); + assertEquals("Cause message incorrect", "Permission denied: Update createNewQueue", e.getMessage()); } } + /** - * admin user has AMQP right but not JMX + * admin user does not have JMX right */ - public void setUpCreateQueueAMQPRights() throws Exception + public void setUpServerInformationUpdateDenied() throws Exception { - writeACLFile("test", - "ACL DENY admin EXECUTE METHOD component=\"VirtualHost.VirtualHostManager\" name=\"createNewQueue\"", - "ACL ALLOW admin CREATE QUEUE"); + writeACLFile(null, + "ACL DENY admin UPDATE METHOD component='ServerInformation' name='resetStatistics'"); } - - public void testCreateQueueAMQPRights() throws Exception + + public void testServerInformationUpdateDenied() throws Exception { + ServerInformation info = _jmx.getServerInformation(); try { - _jmx.createQueue("test", QUEUE_NAME, "admin", true); - - fail("Queue create should fail"); + info.resetStatistics(); + fail("Exception not thrown"); } - catch (Exception e) + catch (SecurityException e) { - assertEquals("Cause message incorrect", "Permission denied: Execute createNewQueue", e.getMessage()); + assertEquals("Cause message incorrect", "Permission denied: Update resetStatistics", e.getMessage()); } } + /** - * admin has both JMX and AMQP rights + * admin user has JMX right to check management API major version (but not minor version) */ - public void setUpCreateQueueJMXAMQPRights() throws Exception + public void setUpServerInformationAccessGranted() throws Exception { - writeACLFile("test", - "ACL ALLOW admin EXECUTE METHOD component=\"VirtualHost.VirtualHostManager\" name=\"createNewQueue\"", - "ACL ALLOW admin CREATE QUEUE"); + writeACLFile(null, + "ACL ALLOW-LOG admin ACCESS METHOD component='ServerInformation' name='getManagementApiMajorVersion'"); } - - public void testCreateQueueJMXAMQPRights() throws Exception + + public void testServerInformationAccessGranted() throws Exception { + ServerInformation info = _jmx.getServerInformation(); + info.getManagementApiMajorVersion(); + try { - _jmx.createQueue("test", QUEUE_NAME, "admin", true); + info.getManagementApiMinorVersion(); + fail("Exception not thrown"); } - catch (Exception e) + catch (SecurityException e) { - fail("Queue create should succeed: " + e.getCause().getMessage()); + assertEquals("Cause message incorrect", "Permission denied: Access getManagementApiMinorVersion", e.getMessage()); } } + + + /** + * admin user has JMX right to use the update method + */ + public void setUpServerInformationUpdateMethodPermission() throws Exception + { + writeACLFile(null, + "ACL ALLOW admin UPDATE METHOD component='ServerInformation' name='resetStatistics'"); + } + + public void testServerInformationUpdateMethodPermission() throws Exception + { + ServerInformation info = _jmx.getServerInformation(); + info.resetStatistics(); + // PASS + } + + + /** + * admin user has JMX right to use all types of method on ServerInformation + */ + public void setUpServerInformationAllMethodPermissions() throws Exception + { + writeACLFile(null, "ACL ALLOW admin ALL METHOD component='ServerInformation'"); + } + + public void testServerInformationAllMethodPermissions() throws Exception + { + //try an update method + ServerInformation info = _jmx.getServerInformation(); + info.resetStatistics(); + // PASS + //try an access method + info.getManagementApiMinorVersion(); + // PASS + } + } diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java index 254e1fe6ac..e9b8a2efd5 100644 --- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java +++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java @@ -18,13 +18,8 @@ */ package org.apache.qpid.server.security.acl; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - import javax.jms.Connection; -import javax.jms.DeliveryMode; -import javax.jms.IllegalStateException; +import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; @@ -37,9 +32,6 @@ import javax.jms.TopicSubscriber; import javax.naming.NamingException; import org.apache.qpid.AMQException; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.url.URLSyntaxException; @@ -49,7 +41,13 @@ import org.apache.qpid.url.URLSyntaxException; */ public class ExternalACLTest extends AbstractACLTestCase { - public void testAccessAuthorizedSuccess() throws AMQException, URLSyntaxException, Exception + + public void setUpAccessAuthorizedSuccess() throws Exception + { + writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST"); + } + + public void testAccessAuthorizedSuccess() throws Exception { try { @@ -68,43 +66,9 @@ public class ExternalACLTest extends AbstractACLTestCase } } - public void testAccessVhostAuthorisedGuestSuccess() throws IOException, Exception + public void setUpAccessNoRightsFailure() throws Exception { - //The 'guest' user has no access to the 'test' vhost, as tested below in testAccessNoRights(), and so - //is unable to perform actions such as connecting (and by extension, creating a queue, and consuming - //from a queue etc). In order to test the vhost-wide 'access' ACL right, the 'guest' user has been given - //this right in the 'test2' vhost. - - try - { - //get a connection to the 'test2' vhost using the guest user and perform various actions. - Connection conn = getConnection("test2", "guest", "guest"); - Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - conn.start(); - - //create Queues and consumers for each - Queue namedQueue = sess.createQueue("vhostAccessCreatedQueue" + getTestQueueName()); - Queue tempQueue = sess.createTemporaryQueue(); - MessageConsumer consumer = sess.createConsumer(namedQueue); - MessageConsumer tempConsumer = sess.createConsumer(tempQueue); - - //send a message to each queue (also causing an exchange declare) - MessageProducer sender = ((AMQSession<?, ?>) sess).createProducer(null); - ((org.apache.qpid.jms.MessageProducer) sender).send(namedQueue, sess.createTextMessage("test"), - DeliveryMode.NON_PERSISTENT, 0, 0L, false, false); - ((org.apache.qpid.jms.MessageProducer) sender).send(tempQueue, sess.createTextMessage("test"), - DeliveryMode.NON_PERSISTENT, 0, 0L, false, false); - - //consume the messages from the queues - consumer.receive(2000); - tempConsumer.receive(2000); - - conn.close(); - } - catch (Exception e) - { - fail("Test failed due to:" + e.getMessage()); - } + writeACLFile("test", "ACL DENY-LOG client ACCESS VIRTUALHOST"); } public void testAccessNoRightsFailure() throws Exception @@ -131,228 +95,124 @@ public class ExternalACLTest extends AbstractACLTestCase } } - public void testClientDeleteQueueSuccess() throws Exception + public void setUpClientDeleteQueueSuccess() throws Exception { - try - { - Connection conn = getConnection("test", "client", "guest"); - Session sess = conn.createSession(true, Session.SESSION_TRANSACTED); - conn.start(); - - // create kipper - Topic kipper = sess.createTopic("kipper"); - TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper"); - - subscriber.close(); - sess.unsubscribe("kipper"); - - //Do something to show connection is active. - sess.rollback(); - conn.close(); - } - catch (Exception e) - { - fail("Test failed due to:" + e.getMessage()); - } + writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST", + "ACL ALLOW-LOG client CREATE QUEUE durable=\"true\"" , + "ACL ALLOW-LOG client CONSUME QUEUE name=\"clientid:kipper\"", + "ACL ALLOW-LOG client BIND EXCHANGE name=\"amq.topic\" durable=true routingKey=kipper", + "ACL ALLOW-LOG client DELETE QUEUE durable=\"true\"", + "ACL ALLOW-LOG client UNBIND EXCHANGE name=\"amq.topic\" durable=true routingKey=kipper"); } - public void testServerDeleteQueueFailure() throws Exception + public void testClientDeleteQueueSuccess() throws Exception { - try - { - Connection conn = getConnection("test", "server", "guest"); - Session sess = conn.createSession(true, Session.SESSION_TRANSACTED); - conn.start(); + Connection conn = getConnection("test", "client", "guest"); + Session sess = conn.createSession(true, Session.SESSION_TRANSACTED); + conn.start(); - // create kipper - Topic kipper = sess.createTopic("kipper"); - TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper"); + // create kipper + Topic kipper = sess.createTopic("kipper"); + TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper"); - subscriber.close(); - sess.unsubscribe("kipper"); + subscriber.close(); + sess.unsubscribe("kipper"); - //Do something to show connection is active. - sess.rollback(); - conn.close(); - } - catch (JMSException e) - { - // JMSException -> linedException = AMQException.403 - check403Exception(e.getLinkedException()); - } + //Do something to show connection is active. + sess.rollback(); + conn.close(); } - public void testClientConsumeFromTempQueueSuccess() throws AMQException, URLSyntaxException, Exception - { - try - { - Connection conn = getConnection("test", "client", "guest"); - - Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - - conn.start(); - - sess.createConsumer(sess.createTemporaryQueue()); - conn.close(); - } - catch (Exception e) - { - fail("Test failed due to:" + e.getMessage()); - } + public void setUpClientDeleteQueueFailure() throws Exception + { + writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST", + "ACL ALLOW-LOG client CREATE QUEUE durable=\"true\"" , + "ACL ALLOW-LOG client CONSUME QUEUE name=\"clientid:kipper\"", + "ACL ALLOW-LOG client BIND EXCHANGE name=\"amq.topic\" durable=true routingKey=kipper", + "ACL DENY-LOG client DELETE QUEUE durable=\"true\"", + "ACL DENY-LOG client UNBIND EXCHANGE name=\"amq.topic\" durable=true routingKey=kipper"); } - public void testClientConsumeFromNamedQueueFailure() throws NamingException, Exception + public void testClientDeleteQueueFailure() throws Exception { - try - { - Connection conn = getConnection("test", "client", "guest"); + Connection conn = getConnection("test", "client", "guest"); + Session sess = conn.createSession(true, Session.SESSION_TRANSACTED); + conn.start(); - Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + // create kipper + Topic kipper = sess.createTopic("kipper"); + TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper"); - conn.start(); + subscriber.close(); + try + { + sess.unsubscribe("kipper"); - sess.createConsumer(sess.createQueue("IllegalQueue")); + //Do something to show connection is active. + sess.rollback(); - fail("Test failed as consumer was created."); + fail("Exception was not thrown"); } catch (JMSException e) { + // JMSException -> linedException = AMQException.403 check403Exception(e.getLinkedException()); } } - public void testClientCreateTemporaryQueueSuccess() throws JMSException, URLSyntaxException, Exception - { - try - { - Connection conn = getConnection("test", "client", "guest"); - - Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - - conn.start(); - //Create Temporary Queue - can't use the createTempQueue as QueueName is null. - ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("doesnt_matter_as_autodelete_means_tmp"), - true, false, false); - - conn.close(); - } - catch (Exception e) - { - fail("Test failed due to:" + e.getMessage()); - } - } - - public void testClientCreateNamedQueueFailure() throws NamingException, JMSException, AMQException, Exception + public void testClientConsumeFromTempQueueSuccess() throws Exception { - try - { - Connection conn = getConnection("test", "client", "guest"); + Connection conn = getConnection("test", "client", "guest"); - Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - conn.start(); + conn.start(); - //Create a Named Queue - ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("IllegalQueue"), false, false, false); - - fail("Test failed as Queue creation succeded."); - //conn will be automatically closed - } - catch (AMQException e) - { - check403Exception(e); - } + sess.createConsumer(sess.createTemporaryQueue()); } - public void testClientPublishUsingTransactionSuccess() throws AMQException, URLSyntaxException, Exception + public void setUpClientConsumeFromNamedQueueValid() throws Exception { - try - { - Connection conn = getConnection("test", "client", "guest"); + writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST", + "ACL ALLOW-LOG client CREATE QUEUE name=\"example.RequestQueue\"" , + "ACL ALLOW-LOG client CONSUME QUEUE name=\"example.RequestQueue\"", + "ACL ALLOW-LOG client BIND EXCHANGE name=\"amq.direct\" routingKey=\"example.RequestQueue\""); + } - Session sess = conn.createSession(true, Session.SESSION_TRANSACTED); - conn.start(); - - MessageProducer sender = sess.createProducer(sess.createQueue("example.RequestQueue")); + public void testClientConsumeFromNamedQueueValid() throws Exception + { + Connection conn = getConnection("test", "client", "guest"); - sender.send(sess.createTextMessage("test")); + Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - //Send the message using a transaction as this will allow us to retrieve any errors that occur on the broker. - sess.commit(); + conn.start(); - conn.close(); - } - catch (Exception e) - { - fail("Test publish failed:" + e); - } + sess.createConsumer(sess.createQueue("example.RequestQueue")); } - public void testClientPublishValidQueueSuccess() throws AMQException, URLSyntaxException, Exception + public void setUpClientConsumeFromNamedQueueFailure() throws Exception { - try - { - Connection conn = getConnection("test", "client", "guest"); - - Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - - conn.start(); - - MessageProducer sender = ((AMQSession<?, ?>) sess).createProducer(null); - - Queue queue = sess.createQueue("example.RequestQueue"); - - // Send a message that we will wait to be sent, this should give the broker time to process the msg - // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not - // queue existence. - ((org.apache.qpid.jms.MessageProducer) sender).send(queue, sess.createTextMessage("test"), - DeliveryMode.NON_PERSISTENT, 0, 0L, false, false); - - conn.close(); - } - catch (Exception e) - { - fail("Test publish failed:" + e); - } + writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST", + "ACL ALLOW-LOG client CREATE QUEUE" , + "ACL ALLOW-LOG client BIND EXCHANGE", + "ACL DENY-LOG client CONSUME QUEUE name=\"IllegalQueue\""); } - public void testClientPublishInvalidQueueSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception + public void testClientConsumeFromNamedQueueFailure() throws NamingException, Exception { + Connection conn = getConnection("test", "client", "guest"); + Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + conn.start(); + Destination dest = sess.createQueue("IllegalQueue"); + try { - Connection conn = getConnection("test", "client", "guest"); - - Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - - conn.start(); - - MessageProducer sender = ((AMQSession<?, ?>) session).createProducer(null); - - Queue queue = session.createQueue("Invalid"); - - // Send a message that we will wait to be sent, this should give the broker time to close the connection - // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not - // queue existence. - ((org.apache.qpid.jms.MessageProducer) sender).send(queue, session.createTextMessage("test"), - DeliveryMode.NON_PERSISTENT, 0, 0L, false, false); - - // Test the connection with a valid consumer - // This may fail as the session may be closed before the queue or the consumer created. - Queue temp = session.createTemporaryQueue(); + sess.createConsumer(dest); - session.createConsumer(temp).close(); - - //Connection should now be closed and will throw the exception caused by the above send - conn.close(); - - fail("Close is not expected to succeed."); - } - catch (IllegalStateException e) - { - _logger.info("QPID-2345: Session became closed and we got that error rather than the authentication error."); + fail("Test failed as consumer was created."); } catch (JMSException e) { @@ -360,39 +220,43 @@ public class ExternalACLTest extends AbstractACLTestCase } } - public void testServerConsumeFromNamedQueueValid() throws AMQException, URLSyntaxException, Exception + public void setUpClientCreateTemporaryQueueSuccess() throws Exception { - try - { - Connection conn = getConnection("test", "server", "guest"); - - Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST", + "ACL ALLOW-LOG client CREATE QUEUE temporary=\"true\"" , + "ACL ALLOW-LOG client BIND EXCHANGE name=\"amq.direct\" temporary=true", + "ACL ALLOW-LOG client DELETE QUEUE temporary=\"true\"", + "ACL ALLOW-LOG client UNBIND EXCHANGE name=\"amq.direct\" temporary=true"); + } - conn.start(); + public void testClientCreateTemporaryQueueSuccess() throws JMSException, URLSyntaxException, Exception + { + Connection conn = getConnection("test", "client", "guest"); + Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + conn.start(); - sess.createConsumer(sess.createQueue("example.RequestQueue")); + sess.createTemporaryQueue(); + conn.close(); + } - conn.close(); - } - catch (Exception e) - { - fail("Test failed due to:" + e.getMessage()); - } + public void setUpClientCreateTemporaryQueueFailed() throws Exception + { + writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST", + "ACL DENY-LOG client CREATE QUEUE temporary=\"true\""); } - public void testServerConsumeFromNamedQueueInvalid() throws AMQException, URLSyntaxException, NamingException, Exception + public void testClientCreateTemporaryQueueFailed() throws NamingException, Exception { + Connection conn = getConnection("test", "client", "guest"); + Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + conn.start(); + try { - Connection conn = getConnection("test", "client", "guest"); - - Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - conn.start(); - - sess.createConsumer(sess.createQueue("Invalid")); + session.createTemporaryQueue(); - fail("Test failed as consumer was created."); + fail("Test failed as creation succeded."); } catch (JMSException e) { @@ -400,247 +264,139 @@ public class ExternalACLTest extends AbstractACLTestCase } } - public void testServerConsumeFromTemporaryQueue() throws AMQException, URLSyntaxException, NamingException, Exception + public void setUpClientCreateNamedQueueFailure() throws Exception { - try - { - Connection conn = getConnection("test", "server", "guest"); - - Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - - conn.start(); - - sess.createConsumer(sess.createTemporaryQueue()); - - fail("Test failed as consumer was created."); - } - catch (JMSException e) - { - check403Exception(e.getLinkedException()); - } + writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST", + "ACL ALLOW-LOG client CREATE QUEUE name=\"ValidQueue\"", + "ACL ALLOW-LOG client CONSUME QUEUE"); } - public void testServerCreateNamedQueueValid() throws JMSException, URLSyntaxException, Exception + public void testClientCreateNamedQueueFailure() throws NamingException, JMSException, AMQException, Exception { + Connection conn = getConnection("test", "client", "guest"); + Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + conn.start(); + Destination dest = sess.createQueue("IllegalQueue"); + try { - Connection conn = getConnection("test", "server", "guest"); - - Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - - conn.start(); - - //Create Temporary Queue - ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("example.RequestQueue"), false, false, false); - - conn.close(); + //Create a Named Queue as side effect + sess.createConsumer(dest); + fail("Test failed as Queue creation succeded."); } - catch (Exception e) + catch (JMSException e) { - fail("Test failed due to:" + e.getMessage()); + check403Exception(e.getLinkedException()); } } - public void testServerCreateNamedQueueInvalid() throws JMSException, URLSyntaxException, AMQException, NamingException, Exception + public void setUpClientPublishUsingTransactionSuccess() throws Exception { - try - { - Connection conn = getConnection("test", "server", "guest"); - - Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - - conn.start(); - - //Create a Named Queue - ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("IllegalQueue"), false, false, false); - - fail("Test failed as creation succeded."); - } - catch (Exception e) - { - check403Exception(e); - } + writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST", + "ACL ALLOW-LOG client CREATE QUEUE" , + "ACL ALLOW-LOG client BIND EXCHANGE", + "ACL ALLOW-LOG client PUBLISH EXCHANGE name=\"amq.direct\" routingKey=\"example.RequestQueue\""); } - public void testServerCreateTemporaryQueueInvalid() throws NamingException, Exception + public void testClientPublishUsingTransactionSuccess() throws Exception { - try - { - Connection conn = getConnection("test", "server", "guest"); - Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + Connection conn = getConnection("test", "client", "guest"); - conn.start(); + Session sess = conn.createSession(true, Session.SESSION_TRANSACTED); - session.createTemporaryQueue(); + conn.start(); - fail("Test failed as creation succeded."); - } - catch (JMSException e) - { - check403Exception(e.getLinkedException()); - } - } + MessageProducer sender = sess.createProducer(sess.createQueue("example.RequestQueue")); - public void testServerCreateAutoDeleteQueueInvalid() throws NamingException, JMSException, AMQException, Exception - { - try - { - Connection connection = getConnection("test", "server", "guest"); + sender.send(sess.createTextMessage("test")); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + //Send the message using a transaction as this will allow us to retrieve any errors that occur on the broker. + sess.commit(); - connection.start(); + conn.close(); + } - ((AMQSession<?, ?>) session).createQueue(new AMQShortString("again_ensure_auto_delete_queue_for_temporary"), - true, false, false); - fail("Test failed as creation succeded."); - } - catch (Exception e) - { - check403Exception(e); - } + public void setUpRequestResponseSuccess() throws Exception + { + writeACLFile("test", "GROUP messaging-users client server", + "ACL ALLOW-LOG messaging-users ACCESS VIRTUALHOST", + "# Server side", + "ACL ALLOW-LOG server CREATE QUEUE name=\"example.RequestQueue\"" , + "ACL ALLOW-LOG server BIND EXCHANGE", + "ACL ALLOW-LOG server PUBLISH EXCHANGE name=\"amq.direct\" routingKey=\"TempQueue*\"", + "ACL ALLOW-LOG server CONSUME QUEUE name=\"example.RequestQueue\"", + "# Client side", + "ACL ALLOW-LOG client PUBLISH EXCHANGE name=\"amq.direct\" routingKey=\"example.RequestQueue\"", + "ACL ALLOW-LOG client CONSUME QUEUE temporary=true", + "ACL ALLOW-LOG client BIND EXCHANGE name=\"amq.direct\" temporary=true", + "ACL ALLOW-LOG client UNBIND EXCHANGE name=\"amq.direct\" temporary=true", + "ACL ALLOW-LOG client CREATE QUEUE temporary=true", + "ACL ALLOW-LOG client DELETE QUEUE temporary=true"); } - /** - * This test uses both the cilent and sender to validate that the Server is able to publish to a temporary queue. - * The reason the client must be involved is that the Server is unable to create its own Temporary Queues. - * - * @throws AMQException - * @throws URLSyntaxException - * @throws JMSException - */ - public void testServerPublishUsingTransactionSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception + + public void testRequestResponseSuccess() throws Exception { //Set up the Server Connection serverConnection = getConnection("test", "server", "guest"); - Session serverSession = serverConnection.createSession(true, Session.SESSION_TRANSACTED); - Queue requestQueue = serverSession.createQueue("example.RequestQueue"); - MessageConsumer server = serverSession.createConsumer(requestQueue); - serverConnection.start(); //Set up the consumer Connection clientConnection = getConnection("test", "client", "guest"); - - //Send a test mesage - Session clientSession = clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); - + Session clientSession = clientConnection.createSession(true, Session.SESSION_TRANSACTED); Queue responseQueue = clientSession.createTemporaryQueue(); - MessageConsumer clientResponse = clientSession.createConsumer(responseQueue); - clientConnection.start(); + // Client Message request = clientSession.createTextMessage("Request"); - - assertNotNull("Response Queue is null", responseQueue); - request.setJMSReplyTo(responseQueue); clientSession.createProducer(requestQueue).send(request); - - try - { - Message msg = null; - - msg = server.receive(2000); - - while (msg != null && !((TextMessage) msg).getText().equals("Request")) - { - msg = server.receive(2000); - } - - assertNotNull("Message not received", msg); - - assertNotNull("Reply-To is Null", msg.getJMSReplyTo()); - - MessageProducer sender = serverSession.createProducer(msg.getJMSReplyTo()); - - sender.send(serverSession.createTextMessage("Response")); - - //Send the message using a transaction as this will allow us to retrieve any errors that occur on the broker. - serverSession.commit(); - - //Ensure Response is received. - Message clientResponseMsg = clientResponse.receive(2000); - assertNotNull("Client did not receive response message,", clientResponseMsg); - assertEquals("Incorrect message received", "Response", ((TextMessage) clientResponseMsg).getText()); - - } - catch (Exception e) - { - fail("Test publish failed:" + e); - } - finally - { - try - { - serverConnection.close(); - } - finally - { - clientConnection.close(); - } - } + clientSession.commit(); + + // Server + Message msg = server.receive(2000); + assertNotNull("Server should have received client's request", msg); + assertNotNull("Received msg should have Reply-To", msg.getJMSReplyTo()); + + MessageProducer sender = serverSession.createProducer(msg.getJMSReplyTo()); + sender.send(serverSession.createTextMessage("Response")); + serverSession.commit(); + + // Client + Message clientResponseMsg = clientResponse.receive(2000); + clientSession.commit(); + assertNotNull("Client did not receive response message,", clientResponseMsg); + assertEquals("Incorrect message received", "Response", ((TextMessage) clientResponseMsg).getText()); } - public void testServerPublishInvalidQueueSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception + public void setUpClientDeleteQueueSuccessWithOnlyAllPermissions() throws Exception { - try - { - Connection conn = getConnection("test", "server", "guest"); - - ((AMQConnection) conn).setConnectionListener(this); - - Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - - conn.start(); - - MessageProducer sender = ((AMQSession<?, ?>) session).createProducer(null); - - Queue queue = session.createQueue("Invalid"); - - // Send a message that we will wait to be sent, this should give the broker time to close the connection - // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not - // queue existence. - ((org.apache.qpid.jms.MessageProducer) sender).send(queue, session.createTextMessage("test"), - DeliveryMode.NON_PERSISTENT, 0, 0L, false, false); - - // Test the connection with a valid consumer - // This may not work as the session may be closed before the queue or consumer creation can occur. - // The correct JMSexception with linked error will only occur when the close method is recevied whilst in - // the failover safe block - session.createConsumer(session.createQueue("example.RequestQueue")).close(); - - //Connection should now be closed and will throw the exception caused by the above send - conn.close(); - - fail("Close is not expected to succeed."); - } - catch (IllegalStateException e) - { - _logger.info("QPID-2345: Session became closed and we got that error rather than the authentication error."); - } - catch (JMSException e) - { - check403Exception(e.getLinkedException()); - } + writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST", + "ACL ALLOW-LOG client ALL QUEUE", + "ACL ALLOW-LOG client ALL EXCHANGE"); } - - @Override - public String getConfig() + public void testClientDeleteQueueSuccessWithOnlyAllPermissions() throws Exception { - return "config-systests-aclv2.xml"; - } + Connection conn = getConnection("test", "client", "guest"); + Session sess = conn.createSession(true, Session.SESSION_TRANSACTED); + conn.start(); - @Override - public List<String> getHostList() - { - return Arrays.asList("test", "test2"); + // create kipper + Topic kipper = sess.createTopic("kipper"); + TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper"); + + subscriber.close(); + sess.unsubscribe("kipper"); + + //Do something to show connection is active. + sess.rollback(); + conn.close(); } } diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalAdminACLTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalAdminACLTest.java deleted file mode 100644 index b0bc4fd946..0000000000 --- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalAdminACLTest.java +++ /dev/null @@ -1,186 +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.qpid.server.security.acl; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -import org.apache.qpid.server.logging.management.LoggingManagementMBean; -import org.apache.qpid.test.utils.JMXTestUtils; - -/** - * Tests that ACLs can be applied to mangement operations that do not correspond to a specific AMQP object. - * - * Theses tests use the logging component, exposed as the {@link LoggingManagementMBean}, to get and set properties. - */ -public class ExternalAdminACLTest extends AbstractACLTestCase -{ - private static final String CATEGORY_PRIORITY = "LogManMBeanTest.category.priority"; - private static final String CATEGORY_LEVEL = "LogManMBeanTest.category.level"; - private static final String LOGGER_LEVEL = "LogManMBeanTest.logger.level"; - - private static final String NEWLINE = System.getProperty("line.separator"); - - private JMXTestUtils _jmx; - private File _testConfigFile; - - @Override - public String getConfig() - { - return "config-systests-aclv2.xml"; - } - - @Override - public List<String> getHostList() - { - return Arrays.asList("global"); - } - - @Override - public void setUp() throws Exception - { - _testConfigFile = createTempTestLog4JConfig(); - - _jmx = new JMXTestUtils(this); - _jmx.setUp(); - super.setUp(); - _jmx.open(); - } - - @Override - public void tearDown() throws Exception - { - _jmx.close(); - super.tearDown(); - } - - private File createTempTestLog4JConfig() - { - File tmpFile = null; - try - { - tmpFile = File.createTempFile("LogManMBeanTestLog4jConfig", ".tmp"); - tmpFile.deleteOnExit(); - - FileWriter fstream = new FileWriter(tmpFile); - BufferedWriter writer = new BufferedWriter(fstream); - - writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+NEWLINE); - writer.write("<!DOCTYPE log4j:configuration SYSTEM \"log4j.dtd\">"+NEWLINE); - - writer.write("<log4j:configuration xmlns:log4j=\"http://jakarta.apache.org/log4j/\" debug=\"null\" " + - "threshold=\"null\">"+NEWLINE); - - writer.write(" <appender class=\"org.apache.log4j.ConsoleAppender\" name=\"STDOUT\">"+NEWLINE); - writer.write(" <layout class=\"org.apache.log4j.PatternLayout\">"+NEWLINE); - writer.write(" <param name=\"ConversionPattern\" value=\"%d %-5p [%t] %C{2} (%F:%L) - %m%n\"/>"+NEWLINE); - writer.write(" </layout>"+NEWLINE); - writer.write(" </appender>"+NEWLINE); - - //Example of a 'category' with a 'priority' - writer.write(" <category additivity=\"true\" name=\"" + CATEGORY_PRIORITY +"\">"+NEWLINE); - writer.write(" <priority value=\"info\"/>"+NEWLINE); - writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE); - writer.write(" </category>"+NEWLINE); - - //Example of a 'category' with a 'level' - writer.write(" <category additivity=\"true\" name=\"" + CATEGORY_LEVEL +"\">"+NEWLINE); - writer.write(" <level value=\"warn\"/>"+NEWLINE); - writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE); - writer.write(" </category>"+NEWLINE); - - //Example of a 'logger' with a 'level' - writer.write(" <logger additivity=\"true\" name=\"" + LOGGER_LEVEL + "\">"+NEWLINE); - writer.write(" <level value=\"error\"/>"+NEWLINE); - writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE); - writer.write(" </logger>"+NEWLINE); - - //'root' logger - writer.write(" <root>"+NEWLINE); - writer.write(" <priority value=\"info\"/>"+NEWLINE); - writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE); - writer.write(" </root>"+NEWLINE); - - writer.write("</log4j:configuration>"+NEWLINE); - - writer.flush(); - writer.close(); - } - catch (IOException e) - { - fail("Unable to create temporary test log4j configuration"); - } - - return tmpFile; - } - - public void testGetAllLoggerLevels() throws Exception - { - String[] levels = _jmx.getAvailableLoggerLevels(); - for (int i = 0; i < levels.length; i++) - { - System.out.println(levels[i]); - } - assertEquals("Got incorrect number of log levels", 9, levels.length); - } - - public void testGetAllLoggerLevelsDenied() throws Exception - { - try - { - _jmx.getAvailableLoggerLevels(); - fail("Got list of log levels"); - } - catch (Exception e) - { - // Exception throws - e.printStackTrace(); - assertEquals("Permission denied: Access getAvailableLoggerLevels", e.getMessage()); - } - } - - public void testChangeLoggerLevel() throws Exception - { - String oldLevel = _jmx.getRuntimeRootLoggerLevel(); - System.out.println("old level = " + oldLevel); - _jmx.setRuntimeRootLoggerLevel("DEBUG"); - String newLevel = _jmx.getRuntimeRootLoggerLevel(); - System.out.println("new level = " + newLevel); - assertEquals("Logging level was not changed", "DEBUG", newLevel); - } - - public void testChangeLoggerLevelDenied() throws Exception - { - try - { - _jmx.setRuntimeRootLoggerLevel("DEBUG"); - fail("Logging level was changed"); - } - catch (Exception e) - { - assertEquals("Permission denied: Update setRuntimeRootLoggerLevel", e.getMessage()); - } - } -} diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java b/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java index 71fbf4cc81..14b9bacad4 100644 --- a/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java +++ b/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java @@ -823,7 +823,7 @@ public class QpidBrokerTestCase extends QpidTestCase * @throws ConfigurationException when loading the current config file * @throws IOException when writing the new config file */ - protected void setConfigurationProperty(String property, String value) + public void setConfigurationProperty(String property, String value) throws ConfigurationException, IOException { // Choose which file to write the property to based on prefix. |
