summaryrefslogtreecommitdiff
path: root/qpid/java/bdbstore/src
diff options
context:
space:
mode:
authorKeith Wall <kwall@apache.org>2014-07-04 14:40:13 +0000
committerKeith Wall <kwall@apache.org>2014-07-04 14:40:13 +0000
commitfce3f24c6745e0def3cf98725a949dfca07b9a0d (patch)
tree0d9c786584f21c57657f4600656e9d1726aee69f /qpid/java/bdbstore/src
parent67b6cafa1b23daa3edb36325e2e1c0970130106d (diff)
downloadqpid-python-fce3f24c6745e0def3cf98725a949dfca07b9a0d.tar.gz
QPID-5873: [Java Broker] Allow ACL rules to be applied to VirtualHostNode objects
* ACL rules using the new operation VIRTUALHOSTNODE apply to VHN model objects. * ACL rules using the operation VIRTUALHOST apply to VH model objects for CREATE, UPDATE and DELETE. This is a change from previous version where BROKER operation permission was required. * For HA, VIRTUALHOSTNODE permission is required to perform updates on RemoteReplicationNodes. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1607868 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/bdbstore/src')
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHARemoteReplicationNodeImpl.java26
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHARemoteReplicationNodeTest.java160
2 files changed, 186 insertions, 0 deletions
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHARemoteReplicationNodeImpl.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHARemoteReplicationNodeImpl.java
index 5327997498..64b29b8daf 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHARemoteReplicationNodeImpl.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHARemoteReplicationNodeImpl.java
@@ -24,6 +24,7 @@ package org.apache.qpid.server.virtualhostnode.berkeleydb;
import static com.sleepycat.je.rep.ReplicatedEnvironment.State.MASTER;
import static com.sleepycat.je.rep.ReplicatedEnvironment.State.REPLICA;
+import java.security.AccessControlException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
@@ -33,11 +34,13 @@ import com.sleepycat.je.rep.MasterStateException;
import org.apache.log4j.Logger;
import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.model.AbstractConfiguredObject;
+import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.IllegalStateTransitionException;
import org.apache.qpid.server.model.ManagedAttributeField;
import org.apache.qpid.server.model.State;
import org.apache.qpid.server.model.StateTransition;
+import org.apache.qpid.server.security.access.Operation;
import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironmentFacade;
public class BDBHARemoteReplicationNodeImpl extends AbstractConfiguredObject<BDBHARemoteReplicationNodeImpl> implements BDBHARemoteReplicationNode<BDBHARemoteReplicationNodeImpl>
@@ -46,6 +49,7 @@ public class BDBHARemoteReplicationNodeImpl extends AbstractConfiguredObject<BDB
private final ReplicatedEnvironmentFacade _replicatedEnvironmentFacade;
private final String _address;
+ private final Broker _broker;
private volatile long _joinTime;
private volatile long _lastTransactionId;
@@ -59,6 +63,7 @@ public class BDBHARemoteReplicationNodeImpl extends AbstractConfiguredObject<BDB
public BDBHARemoteReplicationNodeImpl(BDBHAVirtualHostNode<?> virtualHostNode, Map<String, Object> attributes, ReplicatedEnvironmentFacade replicatedEnvironmentFacade)
{
super(parentsMap(virtualHostNode), attributes);
+ _broker = virtualHostNode.getParent(Broker.class);
_address = (String)attributes.get(ADDRESS);
_replicatedEnvironmentFacade = replicatedEnvironmentFacade;
_state = new AtomicReference<State>(State.ACTIVE);
@@ -113,6 +118,27 @@ public class BDBHARemoteReplicationNodeImpl extends AbstractConfiguredObject<BDB
super.deleted();
}
+
+ @Override
+ protected void authoriseSetAttributes(final ConfiguredObject<?> proxyForValidation,
+ final Set<String> modifiedAttributes)
+ {
+ _broker.getSecurityManager().authoriseVirtualHostNode(getName(), Operation.UPDATE);
+ }
+
+ @Override
+ protected void authoriseSetDesiredState(State desiredState) throws AccessControlException
+ {
+ if(desiredState == State.DELETED)
+ {
+ _broker.getSecurityManager().authoriseVirtualHostNode(getName(), Operation.DELETE);
+ }
+ else
+ {
+ _broker.getSecurityManager().authoriseVirtualHostNode(getName(), Operation.UPDATE);
+ }
+ }
+
@Override
public String toString()
{
diff --git a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHARemoteReplicationNodeTest.java b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHARemoteReplicationNodeTest.java
new file mode 100644
index 0000000000..ffefc65484
--- /dev/null
+++ b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHARemoteReplicationNodeTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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.virtualhostnode.berkeleydb;
+
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.security.AccessControlException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObjectFactory;
+import org.apache.qpid.server.model.RemoteReplicationNode;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.store.DurableConfigurationStore;
+import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironmentFacade;
+import org.apache.qpid.server.util.BrokerTestHelper;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class BDBHARemoteReplicationNodeTest extends QpidTestCase
+{
+ private final org.apache.qpid.server.security.SecurityManager _mockSecurityManager = mock(SecurityManager.class);
+
+ private Broker _broker;
+ private TaskExecutor _taskExecutor;
+ private BDBHAVirtualHostNode<?> _virtualHostNode;
+ private DurableConfigurationStore _configStore;
+ private ReplicatedEnvironmentFacade _facade;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ _facade = mock(ReplicatedEnvironmentFacade.class);
+
+ _broker = BrokerTestHelper.createBrokerMock();
+
+ _taskExecutor = new CurrentThreadTaskExecutor();
+ _taskExecutor.start();
+ when(_broker.getTaskExecutor()).thenReturn(_taskExecutor);
+
+ _virtualHostNode = mock(BDBHAVirtualHostNode.class);
+ _configStore = mock(DurableConfigurationStore.class);
+ when(_virtualHostNode.getConfigurationStore()).thenReturn(_configStore);
+
+ // Virtualhost needs the EventLogger from the SystemContext.
+ when(_virtualHostNode.getParent(Broker.class)).thenReturn(_broker);
+
+ ConfiguredObjectFactory objectFactory = _broker.getObjectFactory();
+ when(_virtualHostNode.getModel()).thenReturn(objectFactory.getModel());
+ when(_virtualHostNode.getTaskExecutor()).thenReturn(_taskExecutor);
+ }
+
+ public void testUpdateRole()
+ {
+ String remoteReplicationName = getName();
+ BDBHARemoteReplicationNode remoteReplicationNode = createRemoteReplicationNode(remoteReplicationName);
+
+ remoteReplicationNode.setAttribute(BDBHARemoteReplicationNode.ROLE, null, "MASTER");
+
+ verify(_facade).transferMasterAsynchronously(remoteReplicationName);
+ }
+
+ public void testDelete()
+ {
+ String remoteReplicationName = getName();
+ BDBHARemoteReplicationNode remoteReplicationNode = createRemoteReplicationNode(remoteReplicationName);
+
+ remoteReplicationNode.delete();
+
+ verify(_facade).removeNodeFromGroup(remoteReplicationName);
+ }
+
+ // *************** ReplicationNode Access Control Tests ***************
+
+ public void testUpdateDeniedByACL()
+ {
+ when(_broker.getSecurityManager()).thenReturn(_mockSecurityManager);
+
+ String remoteReplicationName = getName();
+ BDBHARemoteReplicationNode remoteReplicationNode = createRemoteReplicationNode(remoteReplicationName);
+
+ doThrow(new AccessControlException("mocked ACL exception")).when(_mockSecurityManager).authoriseVirtualHostNode(
+ remoteReplicationName,
+ Operation.UPDATE);
+
+ assertNull(remoteReplicationNode.getDescription());
+
+ try
+ {
+ remoteReplicationNode.setAttribute(VirtualHost.DESCRIPTION, null, "My description");
+ fail("Exception not thrown");
+ }
+ catch (AccessControlException ace)
+ {
+ // PASS
+ }
+ }
+
+ public void testDeleteDeniedByACL()
+ {
+ when(_broker.getSecurityManager()).thenReturn(_mockSecurityManager);
+
+ String remoteReplicationName = getName();
+ BDBHARemoteReplicationNode remoteReplicationNode = createRemoteReplicationNode(remoteReplicationName);
+
+ doThrow(new AccessControlException("mocked ACL exception")).when(_mockSecurityManager).authoriseVirtualHostNode(
+ remoteReplicationName,
+ Operation.DELETE);
+
+ assertNull(remoteReplicationNode.getDescription());
+
+ try
+ {
+ remoteReplicationNode.delete();
+ fail("Exception not thrown");
+ }
+ catch (AccessControlException ace)
+ {
+ // PASS
+ }
+ }
+
+ private BDBHARemoteReplicationNode createRemoteReplicationNode(final String replicationNodeName)
+ {
+ Map<String, Object> attributes = new HashMap<>();
+ attributes.put(RemoteReplicationNode.NAME, replicationNodeName);
+
+ BDBHARemoteReplicationNodeImpl node = new BDBHARemoteReplicationNodeImpl(_virtualHostNode, attributes, _facade);
+ node.create();
+ return node;
+ }
+
+
+} \ No newline at end of file