summaryrefslogtreecommitdiff
path: root/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java')
-rw-r--r--qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java289
1 files changed, 289 insertions, 0 deletions
diff --git a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
new file mode 100644
index 0000000000..aad7290557
--- /dev/null
+++ b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
@@ -0,0 +1,289 @@
+/*
+ *
+ * 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.access.plugins;
+
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.security.Result;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.access.Permission;
+import org.apache.qpid.server.security.access.config.RuleSet;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+/**
+ * This test checks that the {@link RuleSet} object which forms the core of the access control plugin performs correctly.
+ *
+ * The ruleset is configured directly rather than using an external file by adding rules individually, calling the
+ * {@link RuleSet#grant(Integer, String, Permission, Operation, ObjectType, ObjectProperties)} method. Then, the
+ * access control mechanism is validated by checking whether operations would be authorised by calling the
+ * {@link RuleSet#check(String, Operation, ObjectType, ObjectProperties)} method.
+ */
+public class RuleSetTest extends QpidTestCase
+{
+ private RuleSet _ruleSet;
+
+ // Common things that are passed to frame constructors
+ private AMQShortString _queueName = new AMQShortString(this.getClass().getName() + "queue");
+ private AMQShortString _exchangeName = new AMQShortString("amq.direct");
+ private AMQShortString _exchangeType = new AMQShortString("direct");
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ _ruleSet = new RuleSet();
+ _ruleSet.configure(RuleSet.TRANSITIVE, Boolean.FALSE);
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ _ruleSet.clear();
+ super.tearDown();
+ }
+
+ public void assertDenyGrantAllow(String identity, Operation operation, ObjectType objectType)
+ {
+ assertDenyGrantAllow(identity, operation, objectType, ObjectProperties.EMPTY);
+ }
+
+ public void assertDenyGrantAllow(String identity, Operation operation, ObjectType objectType, ObjectProperties properties)
+ {
+ assertEquals(Result.DENIED, _ruleSet.check(identity, operation, objectType, properties));
+ _ruleSet.grant(0, identity, Permission.ALLOW, operation, objectType, properties);
+ assertEquals(1, _ruleSet.getRuleCount());
+ assertEquals(Result.ALLOWED, _ruleSet.check(identity, operation, objectType, properties));
+ }
+
+ public void testEmptyRuleSet()
+ {
+ assertNotNull(_ruleSet);
+ assertEquals(_ruleSet.getRuleCount(), 0);
+ assertEquals(_ruleSet.getDefault(), _ruleSet.check("user", Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ }
+
+ public void testVirtualHostAccess() throws Exception
+ {
+ assertDenyGrantAllow("user", Operation.ACCESS, ObjectType.VIRTUALHOST);
+ }
+
+ public void testQueueCreateNamed() throws Exception
+ {
+ assertDenyGrantAllow("user", Operation.CREATE, ObjectType.QUEUE, new ObjectProperties(_queueName));
+ }
+
+ public void testQueueCreatenamedNullRoutingKey()
+ {
+ ObjectProperties properties = new ObjectProperties(_queueName);
+ properties.put(ObjectProperties.Property.ROUTING_KEY, (String) null);
+
+ assertDenyGrantAllow("user", Operation.CREATE, ObjectType.QUEUE, properties);
+ }
+
+ public void testExchangeCreate()
+ {
+ ObjectProperties properties = new ObjectProperties(_exchangeName);
+ properties.put(ObjectProperties.Property.TYPE, _exchangeType.asString());
+
+ assertDenyGrantAllow("user", Operation.CREATE, ObjectType.EXCHANGE, properties);
+ }
+
+ public void testConsume()
+ {
+ assertDenyGrantAllow("user", Operation.CONSUME, ObjectType.QUEUE);
+ }
+
+ public void testPublish()
+ {
+ assertDenyGrantAllow("user", Operation.PUBLISH, ObjectType.EXCHANGE);
+ }
+
+ /**
+ * If the consume permission for temporary queues is for an unnamed queue then it should
+ * be global for any temporary queue but not for any non-temporary queue
+ */
+ public void testTemporaryUnnamedQueueConsume()
+ {
+ ObjectProperties temporary = new ObjectProperties();
+ temporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
+
+ ObjectProperties normal = new ObjectProperties();
+ normal.put(ObjectProperties.Property.AUTO_DELETE, Boolean.FALSE);
+
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
+ _ruleSet.grant(0, "user", Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, temporary);
+ assertEquals(1, _ruleSet.getRuleCount());
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
+
+ // defer to global if exists, otherwise default answer - this is handled by the security manager
+ assertEquals(Result.DEFER, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, normal));
+ }
+
+ /**
+ * Test that temporary queue permissions before queue perms in the ACL config work correctly
+ */
+ public void testTemporaryQueueFirstConsume()
+ {
+ ObjectProperties temporary = new ObjectProperties(_queueName);
+ temporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
+
+ ObjectProperties normal = new ObjectProperties(_queueName);
+ normal.put(ObjectProperties.Property.AUTO_DELETE, Boolean.FALSE);
+
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
+
+ // should not matter if the temporary permission is processed first or last
+ _ruleSet.grant(1, "user", Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, normal);
+ _ruleSet.grant(2, "user", Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, temporary);
+ assertEquals(2, _ruleSet.getRuleCount());
+
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, normal));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
+ }
+
+ /**
+ * Test that temporary queue permissions after queue perms in the ACL config work correctly
+ */
+ public void testTemporaryQueueLastConsume()
+ {
+ ObjectProperties temporary = new ObjectProperties(_queueName);
+ temporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
+
+ ObjectProperties normal = new ObjectProperties(_queueName);
+ normal.put(ObjectProperties.Property.AUTO_DELETE, Boolean.FALSE);
+
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
+
+ // should not matter if the temporary permission is processed first or last
+ _ruleSet.grant(1, "user", Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, temporary);
+ _ruleSet.grant(2, "user", Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, normal);
+ assertEquals(2, _ruleSet.getRuleCount());
+
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, normal));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
+ }
+
+ /*
+ * Test different rules for temporary queues.
+ */
+
+ /**
+ * The more generic rule first is used, so both requests are allowed.
+ */
+ public void testFirstNamedSecondTemporaryQueueDenied()
+ {
+ ObjectProperties named = new ObjectProperties(_queueName);
+ ObjectProperties namedTemporary = new ObjectProperties(_queueName);
+ namedTemporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
+
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+
+ _ruleSet.grant(1, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
+ _ruleSet.grant(2, "user", Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
+ assertEquals(2, _ruleSet.getRuleCount());
+
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ }
+
+ /**
+ * The more specific rule is first, so those requests are denied.
+ */
+ public void testFirstTemporarySecondNamedQueueDenied()
+ {
+ ObjectProperties named = new ObjectProperties(_queueName);
+ ObjectProperties namedTemporary = new ObjectProperties(_queueName);
+ namedTemporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
+
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+
+ _ruleSet.grant(1, "user", Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
+ _ruleSet.grant(2, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
+ assertEquals(2, _ruleSet.getRuleCount());
+
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ }
+
+ /**
+ * The more specific rules are first, so those requests are denied.
+ */
+ public void testFirstTemporarySecondDurableThirdNamedQueueDenied()
+ {
+ ObjectProperties named = new ObjectProperties(_queueName);
+ ObjectProperties namedTemporary = new ObjectProperties(_queueName);
+ namedTemporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
+ ObjectProperties namedDurable = new ObjectProperties(_queueName);
+ namedDurable.put(ObjectProperties.Property.DURABLE, Boolean.TRUE);
+
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedDurable));
+
+ _ruleSet.grant(1, "user", Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
+ _ruleSet.grant(2, "user", Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedDurable);
+ _ruleSet.grant(3, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
+ assertEquals(3, _ruleSet.getRuleCount());
+
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedDurable));
+ }
+
+ public void testNamedTemporaryQueueAllowed()
+ {
+ ObjectProperties named = new ObjectProperties(_queueName);
+ ObjectProperties namedTemporary = new ObjectProperties(_queueName);
+ namedTemporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
+
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+
+ _ruleSet.grant(1, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
+ _ruleSet.grant(2, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
+ assertEquals(2, _ruleSet.getRuleCount());
+
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ }
+
+ public void testNamedTemporaryQueueDeniedAllowed()
+ {
+ ObjectProperties named = new ObjectProperties(_queueName);
+ ObjectProperties namedTemporary = new ObjectProperties(_queueName);
+ namedTemporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
+
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+
+ _ruleSet.grant(1, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
+ _ruleSet.grant(2, "user", Permission.DENY, Operation.CREATE, ObjectType.QUEUE, named);
+ assertEquals(2, _ruleSet.getRuleCount());
+
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ }
+}