diff options
| author | Alex Rudyy <orudyy@apache.org> | 2013-04-19 16:16:20 +0000 |
|---|---|---|
| committer | Alex Rudyy <orudyy@apache.org> | 2013-04-19 16:16:20 +0000 |
| commit | 8735514651a4873dc0b9b0ea4cf0fc58267e6fb3 (patch) | |
| tree | b6375211efcd355c8a00690c56f2ffab40aa3c17 /qpid/java/broker | |
| parent | 8daa35c9f6fc4f4e8f18e7fa5dafb2cd0a6c3460 (diff) | |
| download | qpid-python-8735514651a4873dc0b9b0ea4cf0fc58267e6fb3.tar.gz | |
QPID-4753: move ACL config from broker attribute to a top level entity
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1469937 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/broker')
21 files changed, 799 insertions, 138 deletions
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AccessControlProviderRecoverer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AccessControlProviderRecoverer.java new file mode 100644 index 0000000000..df80b9fe5f --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AccessControlProviderRecoverer.java @@ -0,0 +1,54 @@ +/* + * + * 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.configuration.startup; + +import java.util.Map; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.AccessControlProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.adapter.AccessControlProviderFactory; + +public class AccessControlProviderRecoverer implements ConfiguredObjectRecoverer<AccessControlProvider> +{ + private final AccessControlProviderFactory _accessControlProviderFactory; + + public AccessControlProviderRecoverer(AccessControlProviderFactory authenticationProviderFactory) + { + _accessControlProviderFactory = authenticationProviderFactory; + } + + @Override + public AccessControlProvider create(RecovererProvider recovererProvider, ConfigurationEntry configurationEntry, ConfiguredObject... parents) + { + Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents); + Map<String, Object> attributes = configurationEntry.getAttributes(); + AccessControlProvider authenticationProvider = _accessControlProviderFactory.recover( + configurationEntry.getId(), + broker, + attributes); + + return authenticationProvider; + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java index 3290c827c9..81aff002d1 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java @@ -51,5 +51,4 @@ public class AuthenticationProviderRecoverer implements ConfiguredObjectRecovere return authenticationProvider; } - } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java index 9f6bda67df..35c96bc993 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java @@ -40,6 +40,7 @@ import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.KeyStore; import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.server.model.adapter.AccessControlProviderFactory; import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory; import org.apache.qpid.server.model.adapter.BrokerAdapter; import org.apache.qpid.server.model.adapter.GroupProviderFactory; @@ -54,18 +55,20 @@ public class BrokerRecoverer implements ConfiguredObjectRecoverer<Broker> private final LogRecorder _logRecorder; private final RootMessageLogger _rootMessageLogger; private final AuthenticationProviderFactory _authenticationProviderFactory; + private final AccessControlProviderFactory _accessControlProviderFactory; private final PortFactory _portFactory; private final TaskExecutor _taskExecutor; private final BrokerOptions _brokerOptions; private final GroupProviderFactory _groupProviderFactory; public BrokerRecoverer(AuthenticationProviderFactory authenticationProviderFactory, GroupProviderFactory groupProviderFactory, - PortFactory portFactory, StatisticsGatherer statisticsGatherer, VirtualHostRegistry virtualHostRegistry, - LogRecorder logRecorder, RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor, BrokerOptions brokerOptions) + AccessControlProviderFactory accessControlProviderFactory, PortFactory portFactory, StatisticsGatherer statisticsGatherer, + VirtualHostRegistry virtualHostRegistry, LogRecorder logRecorder, RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor, BrokerOptions brokerOptions) { _groupProviderFactory = groupProviderFactory; _portFactory = portFactory; _authenticationProviderFactory = authenticationProviderFactory; + _accessControlProviderFactory = accessControlProviderFactory; _statisticsGatherer = statisticsGatherer; _virtualHostRegistry = virtualHostRegistry; _logRecorder = logRecorder; @@ -79,8 +82,8 @@ public class BrokerRecoverer implements ConfiguredObjectRecoverer<Broker> { StoreConfigurationChangeListener storeChangeListener = new StoreConfigurationChangeListener(entry.getStore()); BrokerAdapter broker = new BrokerAdapter(entry.getId(), entry.getAttributes(), _statisticsGatherer, _virtualHostRegistry, - _logRecorder, _rootMessageLogger, _authenticationProviderFactory, _groupProviderFactory, _portFactory, - _taskExecutor, entry.getStore(), _brokerOptions); + _logRecorder, _rootMessageLogger, _authenticationProviderFactory, _groupProviderFactory, _accessControlProviderFactory, + _portFactory, _taskExecutor, entry.getStore(), _brokerOptions); broker.addChangeListener(storeChangeListener); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java index 89f949d8d8..2de454c34f 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java @@ -25,6 +25,7 @@ import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; import org.apache.qpid.server.configuration.RecovererProvider; import org.apache.qpid.server.logging.LogRecorder; import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.model.AccessControlProvider; import org.apache.qpid.server.model.AuthenticationProvider; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.GroupProvider; @@ -33,10 +34,12 @@ import org.apache.qpid.server.model.Plugin; import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.TrustStore; import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.adapter.AccessControlProviderFactory; import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory; import org.apache.qpid.server.model.adapter.GroupProviderFactory; import org.apache.qpid.server.model.adapter.PortFactory; import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.plugin.AccessControlFactory; import org.apache.qpid.server.plugin.AuthenticationManagerFactory; import org.apache.qpid.server.plugin.GroupManagerFactory; import org.apache.qpid.server.plugin.PluginFactory; @@ -52,6 +55,7 @@ public class DefaultRecovererProvider implements RecovererProvider private final LogRecorder _logRecorder; private final RootMessageLogger _rootMessageLogger; private final AuthenticationProviderFactory _authenticationProviderFactory; + private final AccessControlProviderFactory _accessControlProviderFactory; private final PortFactory _portFactory; private final GroupProviderFactory _groupProviderFactory; private final QpidServiceLoader<PluginFactory> _pluginFactoryServiceLoader; @@ -62,6 +66,7 @@ public class DefaultRecovererProvider implements RecovererProvider LogRecorder logRecorder, RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor, BrokerOptions brokerOptions) { _authenticationProviderFactory = new AuthenticationProviderFactory(new QpidServiceLoader<AuthenticationManagerFactory>()); + _accessControlProviderFactory = new AccessControlProviderFactory(new QpidServiceLoader<AccessControlFactory>()); _groupProviderFactory = new GroupProviderFactory(new QpidServiceLoader<GroupManagerFactory>()); _portFactory = new PortFactory(); _brokerStatisticsGatherer = brokerStatisticsGatherer; @@ -78,13 +83,17 @@ public class DefaultRecovererProvider implements RecovererProvider { if (Broker.class.getSimpleName().equals(type)) { - return new BrokerRecoverer(_authenticationProviderFactory, _groupProviderFactory, _portFactory, _brokerStatisticsGatherer, _virtualHostRegistry, - _logRecorder, _rootMessageLogger, _taskExecutor, _brokerOptions); + return new BrokerRecoverer(_authenticationProviderFactory, _groupProviderFactory, _accessControlProviderFactory, _portFactory, _brokerStatisticsGatherer, + _virtualHostRegistry, _logRecorder, _rootMessageLogger, _taskExecutor, _brokerOptions); } else if(VirtualHost.class.getSimpleName().equals(type)) { return new VirtualHostRecoverer(_brokerStatisticsGatherer); } + else if(AccessControlProvider.class.getSimpleName().equals(type)) + { + return new AccessControlProviderRecoverer(_accessControlProviderFactory); + } else if(AuthenticationProvider.class.getSimpleName().equals(type)) { return new AuthenticationProviderRecoverer(_authenticationProviderFactory); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java index 24d5edf00f..abf1537ef7 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java @@ -12,6 +12,7 @@ import org.apache.qpid.server.BrokerOptions; import org.apache.qpid.server.configuration.ConfigurationEntry; import org.apache.qpid.server.configuration.ConfigurationEntryStore; import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.AccessControlProvider; import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.Protocol; import org.apache.qpid.server.model.State; @@ -25,6 +26,7 @@ public class ManagementModeStoreHandler implements ConfigurationEntryStore private static final String MANAGEMENT_MODE_PORT_PREFIX = "MANAGEMENT-MODE-PORT-"; private static final String PORT_TYPE = Port.class.getSimpleName(); private static final String VIRTUAL_HOST_TYPE = VirtualHost.class.getSimpleName(); + private static final String ACCESS_CONTROL_PROVIDER_TYPE = AccessControlProvider.class.getSimpleName(); private static final String ATTRIBUTE_STATE = VirtualHost.STATE; private static final Object MANAGEMENT_MODE_AUTH_PROVIDER = "mm-auth"; @@ -253,6 +255,10 @@ public class ManagementModeStoreHandler implements ConfigurationEntryStore { quiesce = true; } + else if (ACCESS_CONTROL_PROVIDER_TYPE.equals(entryType)) + { + quiesce = true; + } else if (PORT_TYPE.equalsIgnoreCase(entryType)) { if (attributes == null) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AccessControlProvider.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AccessControlProvider.java new file mode 100644 index 0000000000..d96bef0463 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AccessControlProvider.java @@ -0,0 +1,56 @@ +/* + * 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.model; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +import org.apache.qpid.server.security.AccessControl; + +public interface AccessControlProvider extends ConfiguredObject +{ + public static final String ID = "id"; + public static final String DESCRIPTION = "description"; + public static final String NAME = "name"; + public static final String STATE = "state"; + public static final String DURABLE = "durable"; + public static final String LIFETIME_POLICY = "lifetimePolicy"; + public static final String TIME_TO_LIVE = "timeToLive"; + public static final String CREATED = "created"; + public static final String UPDATED = "updated"; + public static final String TYPE = "type"; + + public static final Collection<String> AVAILABLE_ATTRIBUTES = + Collections.unmodifiableList( + Arrays.asList(ID, + NAME, + DESCRIPTION, + STATE, + DURABLE, + LIFETIME_POLICY, + TIME_TO_LIVE, + CREATED, + UPDATED, + TYPE)); + + //retrieve the underlying AccessControl object + AccessControl getAccessControl(); +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java index 2cdc62d2dc..f666eb29f1 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java @@ -21,11 +21,9 @@ package org.apache.qpid.server.model; import java.net.SocketAddress; -import java.security.AccessControlException; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Map; import org.apache.qpid.server.logging.LogRecorder; import org.apache.qpid.server.logging.RootMessageLogger; @@ -81,12 +79,6 @@ public interface Broker extends ConfiguredObject String VIRTUALHOST_STORE_TRANSACTION_OPEN_TIMEOUT_CLOSE = "virtualhost.storeTransactionOpenTimeoutClose"; String VIRTUALHOST_STORE_TRANSACTION_OPEN_TIMEOUT_WARN = "virtualhost.storeTransactionOpenTimeoutWarn"; - /* - * A temporary attribute to pass the path to ACL file. - * TODO: It should be a part of AuthorizationProvider. - */ - String ACL_FILE = "aclFile"; - // Attributes Collection<String> AVAILABLE_ATTRIBUTES = Collections.unmodifiableList( @@ -129,8 +121,7 @@ public interface Broker extends ConfiguredObject VIRTUALHOST_STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE, VIRTUALHOST_STORE_TRANSACTION_IDLE_TIMEOUT_WARN, VIRTUALHOST_STORE_TRANSACTION_OPEN_TIMEOUT_CLOSE, - VIRTUALHOST_STORE_TRANSACTION_OPEN_TIMEOUT_WARN, - ACL_FILE + VIRTUALHOST_STORE_TRANSACTION_OPEN_TIMEOUT_WARN )); //children @@ -140,9 +131,7 @@ public interface Broker extends ConfiguredObject Collection<AuthenticationProvider> getAuthenticationProviders(); - VirtualHost createVirtualHost(String name, State initialState, boolean durable, - LifetimePolicy lifetime, long ttl, Map<String, Object> attributes) - throws AccessControlException, IllegalArgumentException; + Collection<AccessControlProvider> getAccessControlProviders(); Collection<GroupProvider> getGroupProviders(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java index bf4c40815a..bccb6b48ee 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java @@ -52,6 +52,7 @@ public class Model { addRelationship(Broker.class, VirtualHost.class); addRelationship(Broker.class, Port.class); + addRelationship(Broker.class, AccessControlProvider.class); addRelationship(Broker.class, AuthenticationProvider.class); addRelationship(Broker.class, GroupProvider.class); addRelationship(Broker.class, TrustStore.class); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AccessControlProviderAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AccessControlProviderAdapter.java new file mode 100644 index 0000000000..75b80eb56c --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AccessControlProviderAdapter.java @@ -0,0 +1,283 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model.adapter; + +import java.security.AccessControlException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; + +import org.apache.qpid.server.model.AccessControlProvider; +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.LifetimePolicy; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.Statistics; +import org.apache.qpid.server.plugin.AccessControlFactory; +import org.apache.qpid.server.security.AccessControl; +import org.apache.qpid.server.security.access.Operation; +import org.apache.qpid.server.util.MapValueConverter; + +public class AccessControlProviderAdapter extends AbstractAdapter implements AccessControlProvider +{ + protected AccessControl _accessControl; + protected final Broker _broker; + + protected Collection<String> _supportedAttributes; + protected Map<String, AccessControlFactory> _factories; + private AtomicReference<State> _state; + + public AccessControlProviderAdapter(UUID id, Broker broker, AccessControl accessControl, Map<String, Object> attributes, Collection<String> attributeNames) + { + super(id, null, null, broker.getTaskExecutor()); + + if (accessControl == null) + { + throw new IllegalArgumentException("AccessControl must not be null"); + } + + _accessControl = accessControl; + _broker = broker; + _supportedAttributes = createSupportedAttributes(attributeNames); + addParent(Broker.class, broker); + + State state = MapValueConverter.getEnumAttribute(State.class, STATE, attributes, State.INITIALISING); + _state = new AtomicReference<State>(state); + + // set attributes now after all attribute names are known + if (attributes != null) + { + for (String name : _supportedAttributes) + { + if (attributes.containsKey(name)) + { + changeAttribute(name, null, attributes.get(name)); + } + } + } + } + + protected Collection<String> createSupportedAttributes(Collection<String> factoryAttributes) + { + List<String> attributesNames = new ArrayList<String>(AVAILABLE_ATTRIBUTES); + if (factoryAttributes != null) + { + attributesNames.addAll(factoryAttributes); + } + + return Collections.unmodifiableCollection(attributesNames); + } + + @Override + public String getName() + { + return (String)getAttribute(AccessControlProvider.NAME); + } + + @Override + public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException + { + return null; + } + + @Override + public State getActualState() + { + return _state.get(); + } + + @Override + public boolean isDurable() + { + return true; + } + + @Override + public void setDurable(boolean durable) + throws IllegalStateException, AccessControlException, IllegalArgumentException + { + } + + @Override + public LifetimePolicy getLifetimePolicy() + { + return LifetimePolicy.PERMANENT; + } + + @Override + public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) + throws IllegalStateException, AccessControlException, IllegalArgumentException + { + return null; + } + + @Override + public long getTimeToLive() + { + return 0; + } + + @Override + public long setTimeToLive(long expected, long desired) + throws IllegalStateException, AccessControlException, IllegalArgumentException + { + return 0; + } + + @Override + public Statistics getStatistics() + { + return NoStatistics.getInstance(); + } + + @Override + public Collection<String> getAttributeNames() + { + return _supportedAttributes; + } + + @Override + public Object getAttribute(String name) + { + if(CREATED.equals(name)) + { + // TODO + } + else if(DURABLE.equals(name)) + { + return true; + } + else if(ID.equals(name)) + { + return getId(); + } + else if(LIFETIME_POLICY.equals(name)) + { + return LifetimePolicy.PERMANENT; + } + else if(STATE.equals(name)) + { + return getActualState(); + } + else if(TIME_TO_LIVE.equals(name)) + { + // TODO + } + else if(UPDATED.equals(name)) + { + // TODO + } + return super.getAttribute(name); + } + + @Override + public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz) + { + return Collections.emptySet(); + } + + @Override + public boolean setState(State currentState, State desiredState) + throws IllegalStateTransitionException, AccessControlException + { + State state = _state.get(); + + if(desiredState == State.DELETED) + { + return _state.compareAndSet(state, State.DELETED); + } + else if (desiredState == State.QUIESCED) + { + return _state.compareAndSet(state, State.QUIESCED); + } + else if(desiredState == State.ACTIVE) + { + if ((state == State.INITIALISING || state == State.QUIESCED) && _state.compareAndSet(state, State.ACTIVE)) + { + _accessControl.open(); + return true; + } + else + { + throw new IllegalStateException("Can't activate access control provider in " + state + " state"); + } + } + else if(desiredState == State.STOPPED) + { + if(_state.compareAndSet(state, State.STOPPED)) + { + _accessControl.close(); + return true; + } + + return false; + } + + return false; + } + + + @Override + protected void changeAttributes(Map<String, Object> attributes) + { + throw new UnsupportedOperationException("Changing attributes on AccessControlProvider is not supported"); + } + + @Override + protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException + { + if(desiredState == State.DELETED) + { + if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), AccessControlProvider.class, Operation.DELETE)) + { + throw new AccessControlException("Deletion of AccessControlProvider is denied"); + } + } + } + + @Override + protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException + { + if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), AccessControlProvider.class, Operation.UPDATE)) + { + throw new AccessControlException("Setting of AccessControlProvider attributes is denied"); + } + } + + @Override + protected void authoriseSetAttributes(Map<String, Object> attributes) throws AccessControlException + { + if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), AccessControlProvider.class, Operation.UPDATE)) + { + throw new AccessControlException("Setting of AccessControlProvider attributes is denied"); + } + } + + public AccessControl getAccessControl() + { + return _accessControl; + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AccessControlProviderFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AccessControlProviderFactory.java new file mode 100644 index 0000000000..6cdf2f2c1a --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AccessControlProviderFactory.java @@ -0,0 +1,90 @@ +/* + * + * 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.model.adapter; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.model.AccessControlProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.plugin.AccessControlFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; +import org.apache.qpid.server.security.AccessControl; + +public class AccessControlProviderFactory +{ + private final Iterable<AccessControlFactory> _factories; + private Collection<String> _supportedAcessControlProviders; + + public AccessControlProviderFactory(QpidServiceLoader<AccessControlFactory> accessControlFactoryServiceLoader) + { + _factories = accessControlFactoryServiceLoader.instancesOf(AccessControlFactory.class); + List<String> supportedAccessControlProviders = new ArrayList<String>(); + for (AccessControlFactory factory : _factories) + { + supportedAccessControlProviders.add(factory.getType()); + } + _supportedAcessControlProviders = Collections.unmodifiableCollection(supportedAccessControlProviders); + } + + /** + * Creates {@link AccessControlProvider} for given ID, {@link Broker} and attributes. + * <p> + * The configured {@link AccessControlFactory}'s are used to try to create the {@link AccessControlProvider}. + * The first non-null instance is returned. The factories are used in non-deterministic order. + */ + public AccessControlProvider create(UUID id, Broker broker, Map<String, Object> attributes) + { + AccessControlProvider ac = createAccessControlProvider(id, broker, attributes); + ac.getAccessControl().onCreate(); + + return ac; + } + + public AccessControlProvider recover(UUID id, Broker broker, Map<String, Object> attributes) + { + return createAccessControlProvider(id, broker, attributes); + } + + private AccessControlProvider createAccessControlProvider(UUID id, + Broker broker, Map<String, Object> attributes) + { + for (AccessControlFactory factory : _factories) + { + AccessControl accessControl = factory.createInstance(attributes); + if (accessControl != null) + { + return new AccessControlProviderAdapter(id, broker,accessControl, attributes, factory.getAttributeNames()); + } + } + + throw new IllegalArgumentException("No access control provider factory found for configuration attributes " + attributes); + } + + public Collection<String> getSupportedAuthenticationProviders() + { + return _supportedAcessControlProviders; + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java index b0e57d339a..c715f1989c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java @@ -43,6 +43,7 @@ import org.apache.qpid.server.logging.RootMessageLogger; import org.apache.qpid.server.logging.actors.BrokerActor; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.messages.BrokerMessages; +import org.apache.qpid.server.model.AccessControlProvider; import org.apache.qpid.server.model.AuthenticationProvider; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfigurationChangeListener; @@ -92,7 +93,6 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat put(CONNECTION_HEART_BEAT_DELAY, Integer.class); put(STATISTICS_REPORTING_PERIOD, Integer.class); - put(ACL_FILE, String.class); put(NAME, String.class); put(DEFAULT_VIRTUAL_HOST, String.class); @@ -166,9 +166,11 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat private final Map<UUID, ConfiguredObject> _plugins = new HashMap<UUID, ConfiguredObject>(); private final Map<String, KeyStore> _keyStores = new HashMap<String, KeyStore>(); private final Map<String, TrustStore> _trustStores = new HashMap<String, TrustStore>(); + private final Map<UUID, AccessControlProvider> _accessControlProviders = new HashMap<UUID, AccessControlProvider>(); private final GroupProviderFactory _groupProviderFactory; private final AuthenticationProviderFactory _authenticationProviderFactory; + private final AccessControlProviderFactory _accessControlProviderFactory; private final PortFactory _portFactory; private final SecurityManager _securityManager; @@ -182,8 +184,8 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat public BrokerAdapter(UUID id, Map<String, Object> attributes, StatisticsGatherer statisticsGatherer, VirtualHostRegistry virtualHostRegistry, LogRecorder logRecorder, RootMessageLogger rootMessageLogger, AuthenticationProviderFactory authenticationProviderFactory, - GroupProviderFactory groupProviderFactory, PortFactory portFactory, TaskExecutor taskExecutor, ConfigurationEntryStore brokerStore, - BrokerOptions brokerOptions) + GroupProviderFactory groupProviderFactory, AccessControlProviderFactory accessControlProviderFactory, PortFactory portFactory, TaskExecutor taskExecutor, + ConfigurationEntryStore brokerStore, BrokerOptions brokerOptions) { super(id, DEFAULTS, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), taskExecutor); _statisticsGatherer = statisticsGatherer; @@ -193,13 +195,13 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat _statistics = new StatisticsAdapter(statisticsGatherer); _authenticationProviderFactory = authenticationProviderFactory; _groupProviderFactory = groupProviderFactory; + _accessControlProviderFactory = accessControlProviderFactory; _portFactory = portFactory; - _securityManager = new SecurityManager((String)getAttribute(ACL_FILE)); - addChangeListener(_securityManager); + _brokerOptions = brokerOptions; + _securityManager = new SecurityManager(this, _brokerOptions.isManagementMode()); _supportedVirtualHostStoreTypes = new MessageStoreCreator().getStoreTypes(); _supportedBrokerStoreTypes = new BrokerConfigurationStoreCreator().getStoreTypes(); _brokerStore = brokerStore; - _brokerOptions = brokerOptions; if (_brokerOptions.isManagementMode()) { AuthenticationManager authManager = new SimpleAuthenticationManager(BrokerOptions.MANAGEMENT_MODE_USER_NAME, _brokerOptions.getManagementModePassword()); @@ -278,17 +280,6 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat } } - public VirtualHost createVirtualHost(final String name, - final State initialState, - final boolean durable, - final LifetimePolicy lifetime, - final long ttl, - final Map<String, Object> attributes) - throws AccessControlException, IllegalArgumentException - { - return null; //TODO - } - private VirtualHost createVirtualHost(final Map<String, Object> attributes) throws AccessControlException, IllegalArgumentException { @@ -388,6 +379,10 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat { return (Collection<C>) getPorts(); } + else if(clazz == AccessControlProvider.class) + { + return (Collection<C>) getAccessControlProviders(); + } else if(clazz == AuthenticationProvider.class) { return (Collection<C>) getAuthenticationProviders(); @@ -424,6 +419,10 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat { return (C) createPort(attributes); } + else if(childClass == AccessControlProvider.class) + { + return (C) createAccessControlProvider(attributes); + } else if(childClass == AuthenticationProvider.class) { return (C) createAuthenticationProvider(attributes); @@ -477,6 +476,64 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat return port; } + private AccessControlProvider createAccessControlProvider(Map<String, Object> attributes) + { + AccessControlProvider accessControlProvider = null; + synchronized (_accessControlProviders) + { + accessControlProvider = _accessControlProviderFactory.create(UUID.randomUUID(), this, attributes); + addAccessControlProvider(accessControlProvider); + } + + boolean quiesce = isManagementMode() ; + accessControlProvider.setDesiredState(State.INITIALISING, quiesce ? State.QUIESCED : State.ACTIVE); + + return accessControlProvider; + } + + /** + * @throws IllegalConfigurationException if an AuthenticationProvider with the same name already exists + */ + private void addAccessControlProvider(AccessControlProvider accessControlProvider) + { + String name = accessControlProvider.getName(); + synchronized (_authenticationProviders) + { + if (_accessControlProviders.containsKey(accessControlProvider.getId())) + { + throw new IllegalConfigurationException("Can't add AccessControlProvider because one with id " + accessControlProvider.getId() + " already exists"); + } + for (AccessControlProvider provider : _accessControlProviders.values()) + { + if (provider.getName().equals(name)) + { + throw new IllegalConfigurationException("Can't add AccessControlProvider because one with name " + name + " already exists"); + } + } + _accessControlProviders.put(accessControlProvider.getId(), accessControlProvider); + } + + accessControlProvider.addChangeListener(this); + accessControlProvider.addChangeListener(_securityManager); + } + + private boolean deleteAccessControlProvider(AccessControlProvider accessControlProvider) + { + AccessControlProvider removedAccessControlProvider = null; + synchronized (_accessControlProviders) + { + removedAccessControlProvider = _accessControlProviders.remove(accessControlProvider.getId()); + } + + if(removedAccessControlProvider != null) + { + removedAccessControlProvider.removeChangeListener(this); + removedAccessControlProvider.removeChangeListener(_securityManager); + } + + return removedAccessControlProvider != null; + } + private AuthenticationProvider createAuthenticationProvider(Map<String, Object> attributes) { AuthenticationProvider authenticationProvider = null; @@ -771,6 +828,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat { changeState(_groupProviders, currentState, State.ACTIVE, false); changeState(_authenticationProviders, currentState, State.ACTIVE, false); + changeState(_accessControlProviders, currentState, State.ACTIVE, false); CurrentActor.set(new BrokerActor(getRootMessageLogger())); try @@ -847,6 +905,10 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat { childDeleted = deleteAuthenticationProvider((AuthenticationProvider)object); } + else if(object instanceof AccessControlProvider) + { + childDeleted = deleteAccessControlProvider((AccessControlProvider)object); + } else if(object instanceof Port) { childDeleted = deletePort((Port)object); @@ -921,6 +983,10 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat { addAuthenticationProvider((AuthenticationProvider)object); } + else if(object instanceof AccessControlProvider) + { + addAccessControlProvider((AccessControlProvider)object); + } else if(object instanceof Port) { addPort((Port)object); @@ -1051,13 +1117,6 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat private void validateAttributes(Map<String, Object> convertedAttributes) { - String aclFile = (String) convertedAttributes.get(ACL_FILE); - if (aclFile != null) - { - // create a security manager to validate the ACL specified in file - new SecurityManager(aclFile); - } - String defaultVirtualHost = (String) convertedAttributes.get(DEFAULT_VIRTUAL_HOST); if (defaultVirtualHost != null) { @@ -1129,4 +1188,13 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat { return _brokerOptions.isManagementMode(); } + + @Override + public Collection<AccessControlProvider> getAccessControlProviders() + { + synchronized (_accessControlProviders) + { + return new ArrayList<AccessControlProvider>(_accessControlProviders.values()); + } + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/AccessControlFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/AccessControlFactory.java index 7708b90efc..0694032db2 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/AccessControlFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/AccessControlFactory.java @@ -18,11 +18,34 @@ */ package org.apache.qpid.server.plugin; +import java.util.Collection; import java.util.Map; +import org.apache.qpid.server.model.AccessControlProvider; import org.apache.qpid.server.security.AccessControl; public interface AccessControlFactory { + public static final String ATTRIBUTE_TYPE = AccessControlProvider.TYPE; + AccessControl createInstance(Map<String, Object> attributes); + + /** + * Returns the access control provider type + * @return authentication provider type + */ + String getType(); + + /** + * Get the names of attributes of the access control which can be passed into + * {@link #createInstance(Map)} to create the group manager + * + * @return the collection of attribute names + */ + Collection<String> getAttributeNames(); + + /** + * @return returns human readable descriptions for the attributes + */ + Map<String, String> getAttributeDescriptions(); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AccessControl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AccessControl.java index b4831f83e5..61e928a38c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AccessControl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AccessControl.java @@ -42,4 +42,25 @@ public interface AccessControl * Authorise an operation on an object defined by a set of properties. */ Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties); + + /** + * Called to open any resources required by the implementation. + */ + void open(); + + /** + * Called to close any resources required by the implementation. + */ + void close(); + + /** + * Called when deleting to allow clearing any resources used by the implementation. + */ + void onDelete(); + + /** + * Called when first creating (but not when recovering after startup) to allow + * creating any resources required by the implementation. + */ + void onCreate(); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java index 3fb3f70f2e..375b731d85 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java @@ -23,6 +23,7 @@ import org.apache.log4j.Logger; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.model.AccessControlProvider; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfigurationChangeListener; import org.apache.qpid.server.model.ConfiguredObject; @@ -30,6 +31,7 @@ import org.apache.qpid.server.model.State; import org.apache.qpid.server.plugin.AccessControlFactory; import org.apache.qpid.server.plugin.QpidServiceLoader; import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.security.access.FileAccessControlProviderConstants; import org.apache.qpid.server.security.access.ObjectProperties; import org.apache.qpid.server.security.access.ObjectType; import org.apache.qpid.server.security.access.Operation; @@ -53,22 +55,13 @@ import static org.apache.qpid.server.security.access.Operation.UNBIND; import javax.security.auth.Subject; import java.net.SocketAddress; -import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; -/** - * The security manager contains references to all loaded {@link AccessControl}s and delegates security decisions to them based - * on virtual host name. The plugins can be external <em>OSGi</em> .jar files that export the required classes or just internal - * objects for simpler plugins. - * - * @see AccessControl - */ public class SecurityManager implements ConfigurationChangeListener { private static final Logger _logger = Logger.getLogger(SecurityManager.class); @@ -78,9 +71,12 @@ public class SecurityManager implements ConfigurationChangeListener public static final ThreadLocal<Boolean> _accessChecksDisabled = new ClearingThreadLocal(false); - private Map<String, AccessControl> _globalPlugins = new ConcurrentHashMap<String, AccessControl>(); - private Map<String, AccessControl> _hostPlugins = new ConcurrentHashMap<String, AccessControl>(); - private Map<String, List<String>> _aclConfigurationToPluginNamesMapping = new ConcurrentHashMap<String, List<String>>(); + private ConcurrentHashMap<String, AccessControl> _globalPlugins = new ConcurrentHashMap<String, AccessControl>(); + private ConcurrentHashMap<String, AccessControl> _hostPlugins = new ConcurrentHashMap<String, AccessControl>(); + + private boolean _managementMode; + + private Broker _broker; /** * A special ThreadLocal, which calls remove() on itself whenever the value is @@ -128,34 +124,53 @@ public class SecurityManager implements ConfigurationChangeListener } /* - * Used by the VirtualHost to allow deferring to the broker level security plugins if required. + * Used by the Broker. */ - public SecurityManager(SecurityManager parent, String aclFile) + public SecurityManager(Broker broker, boolean managementMode) { - this(aclFile); - - // our global plugins are the parent's host plugins - _globalPlugins = parent._hostPlugins; + _managementMode = managementMode; + _broker = broker; } - public SecurityManager(String aclFile) + /* + * Used by the VirtualHost to allow deferring to the broker level security plugins if required. + */ + public SecurityManager(SecurityManager parent, String aclFile, String vhostName) { - configureACLPlugin(aclFile); + if(!_managementMode) + { + configureVirtualHostAclPlugin(aclFile, vhostName); + + // our global plugins are the parent's host plugins + _globalPlugins = parent._hostPlugins; + } } - private void configureACLPlugin(String aclFile) + private void configureVirtualHostAclPlugin(String aclFile, String vhostName) { - Map<String, Object> attributes = new HashMap<String, Object>(); - attributes.put("aclFile", aclFile); - - for (AccessControlFactory provider : (new QpidServiceLoader<AccessControlFactory>()).instancesOf(AccessControlFactory.class)) + if(aclFile != null) { - AccessControl accessControl = provider.createInstance(attributes); - if(accessControl != null) - { - addHostPlugin(accessControl); + Map<String, Object> attributes = new HashMap<String, Object>(); - mapAclConfigurationToPluginName(aclFile, accessControl.getClass().getName()); + attributes.put(AccessControlProvider.TYPE, FileAccessControlProviderConstants.ACL_FILE_PROVIDER_TYPE); + attributes.put(FileAccessControlProviderConstants.PATH, aclFile); + + for (AccessControlFactory provider : (new QpidServiceLoader<AccessControlFactory>()).instancesOf(AccessControlFactory.class)) + { + AccessControl accessControl = provider.createInstance(attributes); + accessControl.open(); + if(accessControl != null) + { + String pluginTypeName = getPluginTypeName(accessControl); + _hostPlugins.put(pluginTypeName, accessControl); + + if(_logger.isDebugEnabled()) + { + _logger.debug("Added access control to host plugins with name: " + vhostName); + } + + break; + } } } @@ -165,15 +180,9 @@ public class SecurityManager implements ConfigurationChangeListener } } - private void mapAclConfigurationToPluginName(String aclFile, String pluginName) + private String getPluginTypeName(AccessControl accessControl) { - List<String> pluginNames = _aclConfigurationToPluginNamesMapping.get(aclFile); - if (pluginNames == null) - { - pluginNames = new ArrayList<String>(); - _aclConfigurationToPluginNamesMapping.put(aclFile, pluginNames); - } - pluginNames.add(pluginName); + return accessControl.getClass().getName(); } public static Subject getThreadSubject() @@ -191,15 +200,6 @@ public class SecurityManager implements ConfigurationChangeListener return _logger; } - private static class CachedPropertiesMap extends LinkedHashMap<String, PublishAccessCheck> - { - @Override - protected boolean removeEldestEntry(Entry<String, PublishAccessCheck> eldest) - { - return size() >= 200; - } - } - private abstract class AccessCheck { abstract Result allowed(AccessControl plugin); @@ -500,16 +500,72 @@ public class SecurityManager implements ConfigurationChangeListener } } - - public void addHostPlugin(AccessControl plugin) - { - _hostPlugins.put(plugin.getClass().getName(), plugin); - } - @Override public void stateChanged(ConfiguredObject object, State oldState, State newState) { - // no op + if(_managementMode) + { + //AccessControl is disabled in ManagementMode + return; + } + + if(object instanceof AccessControlProvider) + { + if(newState == State.ACTIVE) + { + synchronized (_hostPlugins) + { + AccessControl accessControl = ((AccessControlProvider)object).getAccessControl(); + String pluginTypeName = getPluginTypeName(accessControl); + + _hostPlugins.put(pluginTypeName, accessControl); + } + } + else if(newState == State.DELETED) + { + synchronized (_hostPlugins) + { + AccessControl control = ((AccessControlProvider)object).getAccessControl(); + String pluginTypeName = getPluginTypeName(control); + + // Remove the type->control mapping for this type key only if the + // given control is actually referred to. + if(_hostPlugins.containsValue(control)) + { + // If we are removing this control, check if another of the same + // type already exists on the broker and use it in instead. + AccessControl other = null; + Collection<AccessControlProvider> providers = _broker.getAccessControlProviders(); + for(AccessControlProvider p : providers) + { + if(p == object || p.getActualState() != State.ACTIVE) + { + //we don't count ourself as another + continue; + } + + AccessControl ac = p.getAccessControl(); + if(pluginTypeName.equals(getPluginTypeName(ac))) + { + other = ac; + break; + } + } + + if(other != null) + { + //Another control of this type was found, use it instead + _hostPlugins.replace(pluginTypeName, control, other); + } + else + { + //No other was found, remove the type entirely + _hostPlugins.remove(pluginTypeName); + } + } + } + } + } } @Override @@ -527,29 +583,7 @@ public class SecurityManager implements ConfigurationChangeListener @Override public void attributeSet(ConfiguredObject object, String attributeName, Object oldAttributeValue, Object newAttributeValue) { - if (object instanceof Broker && Broker.ACL_FILE.equals(attributeName)) - { - // the code below is not thread safe, however, it should be fine in a management mode - // as there will be no user connected - - if (oldAttributeValue != null) - { - List<String> pluginNames = _aclConfigurationToPluginNamesMapping.remove(oldAttributeValue); - if (pluginNames != null) - { - for (String name : pluginNames) - { - _hostPlugins.remove(name); - } - } - } - if (newAttributeValue != null) - { - configureACLPlugin((String)newAttributeValue); - } - _immediatePublishPropsCache.clear(); - _publishPropsCache.clear(); - } + // no op } public boolean authoriseConfiguringBroker(String configuredObjectName, Class<? extends ConfiguredObject> configuredObjectType, Operation configuredObjectOperation) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/FileAccessControlProviderConstants.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/FileAccessControlProviderConstants.java new file mode 100644 index 0000000000..3a98a947df --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/FileAccessControlProviderConstants.java @@ -0,0 +1,27 @@ +/* + * + * 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; + +public class FileAccessControlProviderConstants +{ + public static final String ACL_FILE_PROVIDER_TYPE = "AclFile"; + public static final String PATH = "path"; +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java index 8e72afad22..2eab47802a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java @@ -131,7 +131,7 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr CurrentActor.get().message(VirtualHostMessages.CREATED(_name)); - _securityManager = new SecurityManager(parentSecurityManager, _vhostConfig.getConfig().getString("security.acl")); + _securityManager = new SecurityManager(parentSecurityManager, _vhostConfig.getConfig().getString("security.acl"), _name); _connectionRegistry = new ConnectionRegistry(); _connectionRegistry.addRegistryChangeListener(this); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java index 5c3f062cae..64b432f471 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java @@ -48,6 +48,7 @@ import org.apache.qpid.server.model.Plugin; import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.TrustStore; import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.adapter.AccessControlProviderFactory; import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory; import org.apache.qpid.server.model.adapter.GroupProviderFactory; import org.apache.qpid.server.model.adapter.PortFactory; @@ -71,8 +72,8 @@ public class BrokerRecovererTest extends TestCase { super.setUp(); - _brokerRecoverer = new BrokerRecoverer(mock(AuthenticationProviderFactory.class), mock(GroupProviderFactory.class), mock(PortFactory.class), mock(StatisticsGatherer.class), - mock(VirtualHostRegistry.class), mock(LogRecorder.class), mock(RootMessageLogger.class), mock(TaskExecutor.class), mock(BrokerOptions.class)); + _brokerRecoverer = new BrokerRecoverer(mock(AuthenticationProviderFactory.class), mock(GroupProviderFactory.class), mock(AccessControlProviderFactory.class), mock(PortFactory.class), + mock(StatisticsGatherer.class), mock(VirtualHostRegistry.class), mock(LogRecorder.class), mock(RootMessageLogger.class), mock(TaskExecutor.class), mock(BrokerOptions.class)); when(_brokerEntry.getId()).thenReturn(_brokerId); when(_brokerEntry.getChildren()).thenReturn(_brokerEntryChildren); @@ -98,7 +99,6 @@ public class BrokerRecovererTest extends TestCase attributes.put(Broker.QUEUE_MAXIMUM_DELIVERY_ATTEMPTS, 2); attributes.put(Broker.QUEUE_DEAD_LETTER_QUEUE_ENABLED, true); attributes.put(Broker.VIRTUALHOST_HOUSEKEEPING_CHECK_PERIOD, 1l); - attributes.put(Broker.ACL_FILE, "/path/to/acl"); attributes.put(Broker.CONNECTION_SESSION_COUNT_LIMIT, 1000); attributes.put(Broker.CONNECTION_HEART_BEAT_DELAY, 2000); attributes.put(Broker.STATISTICS_REPORTING_PERIOD, 4000); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ConfigurationEntryStoreTestCase.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ConfigurationEntryStoreTestCase.java index fc21706bc0..d56481340b 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ConfigurationEntryStoreTestCase.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ConfigurationEntryStoreTestCase.java @@ -70,7 +70,6 @@ public abstract class ConfigurationEntryStoreTestCase extends QpidTestCase _brokerAttributes.put(Broker.QUEUE_MAXIMUM_DELIVERY_ATTEMPTS, 2); _brokerAttributes.put(Broker.QUEUE_DEAD_LETTER_QUEUE_ENABLED, true); _brokerAttributes.put(Broker.VIRTUALHOST_HOUSEKEEPING_CHECK_PERIOD, 1); - _brokerAttributes.put(Broker.ACL_FILE, "/path/to/acl"); _brokerAttributes.put(Broker.CONNECTION_SESSION_COUNT_LIMIT, 1000); _brokerAttributes.put(Broker.CONNECTION_HEART_BEAT_DELAY, 2000); _brokerAttributes.put(Broker.STATISTICS_REPORTING_PERIOD, 4000); @@ -180,7 +179,6 @@ public abstract class ConfigurationEntryStoreTestCase extends QpidTestCase attributes.put(Broker.QUEUE_MAXIMUM_DELIVERY_ATTEMPTS, 12); attributes.put(Broker.QUEUE_DEAD_LETTER_QUEUE_ENABLED, false); attributes.put(Broker.VIRTUALHOST_HOUSEKEEPING_CHECK_PERIOD, 11); - attributes.put(Broker.ACL_FILE, "/path/to/acl1"); attributes.put(Broker.CONNECTION_SESSION_COUNT_LIMIT, 11000); attributes.put(Broker.CONNECTION_HEART_BEAT_DELAY, 12000); attributes.put(Broker.STATISTICS_REPORTING_PERIOD, 14000); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java index 1cb760f611..b30508ee0b 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java @@ -72,20 +72,20 @@ public class JsonConfigurationEntryStoreTest extends ConfigurationEntryStoreTest public void testAttributeIsResolvedFromSystemProperties() { - String aclLocation = "path/to/acl/" + getTestName(); - setTestSystemProperty("my.test.property", aclLocation); + String defaultVhost = getTestName(); + setTestSystemProperty("my.test.property", defaultVhost); ConfigurationEntryStore store = getStore(); ConfigurationEntry brokerConfigEntry = store.getRootEntry(); Map<String, Object> attributes = new HashMap<String, Object>(brokerConfigEntry.getAttributes()); - attributes.put(Broker.ACL_FILE, "${my.test.property}"); + attributes.put(Broker.DEFAULT_VIRTUAL_HOST, "${my.test.property}"); ConfigurationEntry updatedBrokerEntry = new ConfigurationEntry(brokerConfigEntry.getId(), Broker.class.getSimpleName(), attributes, brokerConfigEntry.getChildrenIds(), store); store.save(updatedBrokerEntry); JsonConfigurationEntryStore store2 = new JsonConfigurationEntryStore(_storeFile.getAbsolutePath(), null); - assertEquals("Unresolved ACL value", aclLocation, store2.getRootEntry().getAttributes().get(Broker.ACL_FILE)); + assertEquals("Unresolved default virtualhost value", defaultVhost, store2.getRootEntry().getAttributes().get(Broker.DEFAULT_VIRTUAL_HOST)); } public void testCreateEmptyStore() diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java index 3edbc852a0..4d10058d17 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java @@ -77,7 +77,7 @@ public class BrokerTestHelper RootMessageLogger rootMessageLogger = CurrentActor.get().getRootMessageLogger(); when(broker.getRootMessageLogger()).thenReturn(rootMessageLogger); when(broker.getVirtualHostRegistry()).thenReturn(new VirtualHostRegistry()); - when(broker.getSecurityManager()).thenReturn(new SecurityManager(null)); + when(broker.getSecurityManager()).thenReturn(new SecurityManager(mock(Broker.class), false)); GenericActor.setDefaultMessageLogger(rootMessageLogger); return broker; } @@ -96,14 +96,14 @@ public class BrokerTestHelper throws Exception { StatisticsGatherer statisticsGatherer = mock(StatisticsGatherer.class); - VirtualHost host = new VirtualHostImpl(virtualHostRegistry, statisticsGatherer, new SecurityManager(null), virtualHostConfiguration); + VirtualHost host = new VirtualHostImpl(virtualHostRegistry, statisticsGatherer, new SecurityManager(mock(Broker.class), false), virtualHostConfiguration); virtualHostRegistry.registerVirtualHost(host); return host; } public static VirtualHost createVirtualHost(VirtualHostConfiguration virtualHostConfiguration) throws Exception { - return new VirtualHostImpl(null, mock(StatisticsGatherer.class), new SecurityManager(null), virtualHostConfiguration); + return new VirtualHostImpl(null, mock(StatisticsGatherer.class), new SecurityManager(mock(Broker.class), false), virtualHostConfiguration); } public static VirtualHost createVirtualHost(String name, VirtualHostRegistry virtualHostRegistry) throws Exception @@ -156,7 +156,7 @@ public class BrokerTestHelper public static Exchange createExchange(String hostName) throws Exception { - SecurityManager securityManager = new SecurityManager(null); + SecurityManager securityManager = new SecurityManager(mock(Broker.class), false); VirtualHost virtualHost = mock(VirtualHost.class); when(virtualHost.getName()).thenReturn(hostName); when(virtualHost.getSecurityManager()).thenReturn(securityManager); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualHostImplTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualHostImplTest.java index 559a7f8aaf..4e58eae1d2 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualHostImplTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualHostImplTest.java @@ -211,7 +211,7 @@ public class VirtualHostImplTest extends QpidTestCase _virtualHostRegistry = broker.getVirtualHostRegistry(); VirtualHostConfiguration configuration = new VirtualHostConfiguration(vhostName, config, broker); - VirtualHost host = new VirtualHostImpl(_virtualHostRegistry, mock(StatisticsGatherer.class), new SecurityManager(null), configuration); + VirtualHost host = new VirtualHostImpl(_virtualHostRegistry, mock(StatisticsGatherer.class), new SecurityManager(mock(Broker.class), false), configuration); _virtualHostRegistry.registerVirtualHost(host); return host; @@ -295,7 +295,7 @@ public class VirtualHostImplTest extends QpidTestCase Configuration config = new PropertiesConfiguration(); config.setProperty("store.type", MemoryMessageStore.TYPE); VirtualHostConfiguration configuration = new VirtualHostConfiguration(virtualHostName, config, broker); - VirtualHost host = new VirtualHostImpl(_virtualHostRegistry, mock(StatisticsGatherer.class), new SecurityManager(null), configuration); + VirtualHost host = new VirtualHostImpl(_virtualHostRegistry, mock(StatisticsGatherer.class), new SecurityManager(mock(Broker.class), false), configuration); _virtualHostRegistry.registerVirtualHost(host); return host; } |
