summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Rudyy <orudyy@apache.org>2013-03-11 18:29:45 +0000
committerAlex Rudyy <orudyy@apache.org>2013-03-11 18:29:45 +0000
commit66de8678fb2ab2af8dc5b6d653402b1efd70779b (patch)
tree11e91fd6e6305e3b008d87bccbd81d1d8e29a15c
parent8f8a9146dbb5a7116ecd24c1003bd200623a7e03 (diff)
downloadqpid-python-66de8678fb2ab2af8dc5b6d653402b1efd70779b.tar.gz
QPID-4638: Add UI to add/delete/update authentication providers into java broker web management console
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1455273 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java2
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/Action.java32
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/HelperServlet.java109
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/action/ListAuthenticationProviderAttributes.java76
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html38
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js5
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AuthenticationProvider.js79
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js50
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAuthenticationProvider.js268
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/authenticationprovider/PrincipalDatabaseAuthenticationManager.js19
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/showAuthProvider.html3
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java122
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java19
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java66
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java31
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java17
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java19
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactory.java11
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java20
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java20
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PasswordFileAuthenticationProviderAttributeDescriptions.properties19
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactory.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java31
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationProviderAttributeDescriptions.properties24
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/util/ResourceBundleLoader.java49
-rw-r--r--qpid/java/broker/src/main/resources/initial-store.json6
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java2
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java98
31 files changed, 1075 insertions, 187 deletions
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
index 903d322508..5f281504e9 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
@@ -36,6 +36,7 @@ import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
import org.apache.qpid.server.management.plugin.servlet.DefinedFileServlet;
import org.apache.qpid.server.management.plugin.servlet.FileServlet;
import org.apache.qpid.server.management.plugin.servlet.rest.AbstractServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.HelperServlet;
import org.apache.qpid.server.management.plugin.servlet.rest.LogRecordsServlet;
import org.apache.qpid.server.management.plugin.servlet.rest.LogoutServlet;
import org.apache.qpid.server.management.plugin.servlet.rest.MessageContentServlet;
@@ -303,6 +304,7 @@ public class HttpManagement extends AbstractPluginAdapter
root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.json");
root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.txt");
root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.xsl");
+ root.addServlet(new ServletHolder(new HelperServlet()), "/rest/helper");
final SessionManager sessionManager = root.getSessionHandler().getSessionManager();
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/Action.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/Action.java
new file mode 100644
index 0000000000..3241a7560e
--- /dev/null
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/Action.java
@@ -0,0 +1,32 @@
+/*
+ * 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.management.plugin.servlet.rest;
+
+import java.util.Map;
+
+import org.apache.qpid.server.model.Broker;
+
+
+public interface Action
+{
+ String getName();
+ Object perform(Map<String, Object> request, Broker broker);
+}
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/HelperServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/HelperServlet.java
new file mode 100644
index 0000000000..fa82632dc1
--- /dev/null
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/HelperServlet.java
@@ -0,0 +1,109 @@
+/*
+ * 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.management.plugin.servlet.rest;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.qpid.server.management.plugin.servlet.rest.action.ListAuthenticationProviderAttributes;
+import org.apache.qpid.server.model.Broker;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig;
+
+public class HelperServlet extends AbstractServlet
+{
+ private static final String PARAM_ACTION = "action";
+
+ private Map<String, Action> _actions;
+ private ObjectMapper _mapper;
+
+ public HelperServlet()
+ {
+ _mapper = new ObjectMapper();
+ _mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
+ _actions = new HashMap<String, Action>();
+ Action listProviderAttributes = new ListAuthenticationProviderAttributes();
+ _actions.put(listProviderAttributes.getName(), listProviderAttributes);
+ }
+
+ @Override
+ protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws ServletException,
+ IOException
+ {
+ perform(request, response);
+ }
+
+ @Override
+ protected void doPostWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws ServletException,
+ IOException
+ {
+ perform(request, response);
+ }
+
+ private void perform(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ String actionName = request.getParameter(PARAM_ACTION);
+ Action action = _actions.get(actionName);
+ if (action == null)
+ {
+ response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ @SuppressWarnings("unchecked")
+ Enumeration<String> names = request.getParameterNames();
+ while (names.hasMoreElements())
+ {
+ String name = (String) names.nextElement();
+ String[] values = request.getParameterValues(name);
+ if (values.length == 1)
+ {
+ parameters.put(name, values[0]);
+ }
+ else
+ {
+ parameters.put(name, values);
+ }
+ }
+
+ Object output = action.perform(parameters, (Broker) getServletContext().getAttribute(ATTR_BROKER));
+ if (output == null)
+ {
+ response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+ response.setContentType("application/json");
+ final Writer writer = new BufferedWriter(response.getWriter());
+ _mapper.writeValue(writer, output);
+
+ response.setStatus(HttpServletResponse.SC_OK);
+
+ }
+}
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/action/ListAuthenticationProviderAttributes.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/action/ListAuthenticationProviderAttributes.java
new file mode 100644
index 0000000000..5c629587e0
--- /dev/null
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/action/ListAuthenticationProviderAttributes.java
@@ -0,0 +1,76 @@
+/*
+ * 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.management.plugin.servlet.rest.action;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.qpid.server.management.plugin.servlet.rest.Action;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
+
+public class ListAuthenticationProviderAttributes implements Action
+{
+ private static final String ATTRIBUTES = "attributes";
+ private static final String DESCRIPTIONS = "descriptions";
+ private Map<String, AuthenticationManagerFactory> _factories;
+
+ public ListAuthenticationProviderAttributes()
+ {
+ _factories = new TreeMap<String, AuthenticationManagerFactory>();
+ Iterable<AuthenticationManagerFactory> factories = new QpidServiceLoader<AuthenticationManagerFactory>()
+ .instancesOf(AuthenticationManagerFactory.class);
+ for (AuthenticationManagerFactory factory : factories)
+ {
+ _factories.put(factory.getType(), factory);
+ }
+ }
+
+ @Override
+ public String getName()
+ {
+ return ListAuthenticationProviderAttributes.class.getSimpleName();
+ }
+
+ @Override
+ public Object perform(Map<String, Object> request, Broker broker)
+ {
+ Map<String, Object> attributes = new TreeMap<String, Object>();
+ for (String providerType : _factories.keySet())
+ {
+ AuthenticationManagerFactory factory = _factories.get(providerType);
+
+ Map<String, Object> data = new HashMap<String, Object>();
+ data.put(ATTRIBUTES, factory.getAttributeNames());
+ Map<String, String> resources = factory.getAttributeDescriptions();
+ if (resources != null)
+ {
+ data.put(DESCRIPTIONS, resources);
+ }
+
+ attributes.put(factory.getType(), data);
+ }
+ return attributes;
+ }
+
+}
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html
new file mode 100644
index 0000000000..f164ece082
--- /dev/null
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addAuthenticationProvider.html
@@ -0,0 +1,38 @@
+<!--
+ ~ 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.
+ -->
+<div class="dijitHidden">
+ <div data-dojo-type="dijit.Dialog" style="width:600px;" data-dojo-props="title:'Authentication Provider'" id="addAuthenticationProvider">
+ <form id="formAddAuthenticationProvider" method="post" dojoType="dijit.form.Form">
+ <table class="tableContainer-table tableContainer-table-horiz" width="100%" cellspacing="1">
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 300px;">Type*:</td>
+ <td class="tableContainer-valueCell"><div id="addAuthenticationProvider.selectAuthenticationProviderDiv"></div></td>
+ </tr>
+ <tr>
+ <td class="tableContainer-labelCell" style="width: 300px;">Name*:</td>
+ <td class="tableContainer-valueCell"><input type="text" required="true" name="name"
+ id="formAddAuthenticationProvider.name" placeholder="Name"
+ dojoType="dijit.form.ValidationTextBox" missingMessage="A name must be supplied" /></div></td>
+ </tr>
+ </table>
+ <input type="hidden" id="formAddAuthenticationProvider.id" name="id"/>
+ <div id="addAuthenticationProvider.fieldSets"></div>
+ <!-- submit buttons -->
+ <input type="submit" value="Save Authentication Provider" label="Save Authentication Provider" dojoType="dijit.form.Button" />
+ </form>
+ </div>
+</div>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
index 5557c37a2c..e7554e6d9f 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
@@ -117,5 +117,10 @@ define(["dojo/_base/xhr"],
}
}
+ util.isProviderManagingUsers = function(type)
+ {
+ return (type === "PlainPasswordFileAuthenticationProvider" || type === "Base64MD5PasswordFileAuthenticationProvider");
+ };
+
return util;
}); \ No newline at end of file
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AuthenticationProvider.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AuthenticationProvider.js
index 4273ed5b41..0d97eb3a07 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AuthenticationProvider.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/AuthenticationProvider.js
@@ -27,10 +27,14 @@ define(["dojo/_base/xhr",
"qpid/common/util",
"qpid/common/UpdatableStore",
"dojox/grid/EnhancedGrid",
+ "qpid/management/addAuthenticationProvider",
+ "dojo/_base/event",
+ "dijit/registry",
+ "dojo/dom-style",
"dojox/grid/enhanced/plugins/Pagination",
"dojox/grid/enhanced/plugins/IndirectSelection",
"dojo/domReady!"],
- function (xhr, parser, query, connect, properties, updater, util, UpdatableStore, EnhancedGrid) {
+ function (xhr, parser, query, connect, properties, updater, util, UpdatableStore, EnhancedGrid, addAuthenticationProvider, event, registry, domStyle) {
function AuthenticationProvider(name, parent, controller) {
this.name = name;
@@ -55,29 +59,68 @@ define(["dojo/_base/xhr",
contentPane.containerNode.innerHTML = data;
parser.parse(contentPane.containerNode);
- that.authProviderAdapter = new AuthProviderUpdater(contentPane.containerNode, that.modelObj, that.controller);
+ that.authProviderUpdater = new AuthProviderUpdater(contentPane.containerNode, that.modelObj, that.controller, that);
- updater.add( that.authProviderAdapter );
+ updater.add( that.authProviderUpdater );
- that.authProviderAdapter.update();
+ that.authProviderUpdater.update();
+ var editButton = query(".editAuthenticationProviderButton", contentPane.containerNode)[0];
+ var editWidget = registry.byNode(editButton);
+ connect.connect(editWidget, "onClick",
+ function(evt){
+ event.stop(evt);
+ addAuthenticationProvider.show(that.name);
+ });
+
+ var deleteButton = query(".deleteAuthenticationProviderButton", contentPane.containerNode)[0];
+ var deleteWidget = registry.byNode(deleteButton);
+ connect.connect(deleteWidget, "onClick",
+ function(evt){
+ event.stop(evt);
+ that.deleteAuthenticationProvider();
+ });
}});
};
AuthenticationProvider.prototype.close = function() {
- updater.remove( this.authProviderAdapter );
+ updater.remove( this.authProviderUpdater);
+ if (this.authProviderUpdater.details)
+ {
+ updater.remove(this.authProviderUpdater.details.authDatabaseUpdater);
+ }
+ };
+
+ AuthenticationProvider.prototype.deleteAuthenticationProvider = function() {
+ if(confirm("Are you sure you want to delete authentication provider '" + this.name + "'?")) {
+ var query = "rest/authenticationprovider/" +encodeURIComponent(this.name);
+ this.success = true
+ var that = this;
+ xhr.del({url: query, sync: true, handleAs: "json"}).then(
+ function(data) {
+ that.close();
+ that.contentPane.onClose()
+ that.controller.tabContainer.removeChild(that.contentPane);
+ that.contentPane.destroyRecursive();
+ },
+ function(error) {that.success = false; that.failureReason = error;});
+ if(!this.success ) {
+ alert("Error:" + this.failureReason);
+ }
+ }
};
- function AuthProviderUpdater(node, authProviderObj, controller)
+ function AuthProviderUpdater(node, authProviderObj, controller, authenticationProvider)
{
this.controller = controller;
this.name = query(".name", node)[0];
this.type = query(".type", node)[0];
+ this.authenticationProvider = authenticationProvider;
/*this.state = dom.byId("state");
this.durable = dom.byId("durable");
this.lifetimePolicy = dom.byId("lifetimePolicy");
*/
- this.query = "rest/authenticationprovider/"+encodeURIComponent(authProviderObj.name);
+ this.query = "rest/authenticationprovider/" + encodeURIComponent(authProviderObj.name);
var that = this;
@@ -90,20 +133,28 @@ define(["dojo/_base/xhr",
that.updateHeader();
- require(["qpid/management/authenticationprovider/"+that.authProviderData.category],
- function(SpecificProvider) {
- that.details = new SpecificProvider(node, authProviderObj, controller);
- that.details.update();
- });
-
+ var editButton = query(".editAuthenticationProviderButton", node)[0];
+ var editWidget = registry.byNode(editButton);
+ var hideEdit = (that.authProviderData.type === 'AnonymousAuthenticationManager' || that.authProviderData.type === 'ExternalAuthenticationManager')
+ domStyle.set(editWidget.domNode, "display", hideEdit ? "none": "");
+
+ if (util.isProviderManagingUsers(that.authProviderData.type))
+ {
+ require(["qpid/management/authenticationprovider/PrincipalDatabaseAuthenticationManager"],
+ function(PrincipalDatabaseAuthenticationManager) {
+ that.details = new PrincipalDatabaseAuthenticationManager(node, data[0], controller, that);
+ that.details.update();
+ });
+ }
});
}
AuthProviderUpdater.prototype.updateHeader = function()
{
+ this.authenticationProvider.name = this.authProviderData[ "name" ]
this.name.innerHTML = this.authProviderData[ "name" ];
- this.type.innerHTML = this.authProviderData[ "authenticationProviderType" ];
+ this.type.innerHTML = this.authProviderData[ "type" ];
/* this.state.innerHTML = this.brokerData[ "state" ];
this.durable.innerHTML = this.brokerData[ "durable" ];
this.lifetimePolicy.innerHTML = this.brokerData[ "lifetimePolicy" ];
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js
index dcf6711073..9b4e7aa3f9 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Broker.js
@@ -27,10 +27,12 @@ define(["dojo/_base/xhr",
"qpid/common/util",
"qpid/common/UpdatableStore",
"dojox/grid/EnhancedGrid",
+ "dijit/registry",
+ "qpid/management/addAuthenticationProvider",
"dojox/grid/enhanced/plugins/Pagination",
"dojox/grid/enhanced/plugins/IndirectSelection",
"dojo/domReady!"],
- function (xhr, parser, query, connect, properties, updater, util, UpdatableStore, EnhancedGrid) {
+ function (xhr, parser, query, connect, properties, updater, util, UpdatableStore, EnhancedGrid, registry, addAuthenticationProvider) {
function Broker(name, parent, controller) {
this.name = name;
@@ -62,6 +64,20 @@ define(["dojo/_base/xhr",
that.brokerUpdater.update();
+ var addProviderButton = query(".addAuthenticationProvider", contentPane.containerNode)[0];
+ connect.connect(registry.byNode(addProviderButton), "onClick", function(evt){ addAuthenticationProvider.show(); });
+
+ var deleteProviderButton = query(".deleteAuthenticationProvider", contentPane.containerNode)[0];
+ connect.connect(registry.byNode(deleteProviderButton), "onClick",
+ function(evt){
+ util.deleteGridSelections(
+ that.brokerUpdater,
+ that.brokerUpdater.authenticationProvidersGrid.grid,
+ "rest/authenticationprovider",
+ "Are you sure you want to delete authentication provider");
+ }
+ );
+
}});
};
@@ -121,6 +137,36 @@ define(["dojo/_base/xhr",
});
});
+ var gridProperties = {
+ keepSelection: true,
+ plugins: {
+ indirectSelection: true
+ }};
+
+ that.authenticationProvidersGrid =
+ new UpdatableStore(that.brokerData.authenticationproviders, query(".broker-authentication-providers")[0],
+ [ { name: "Name", field: "name", width: "100%"},
+ { name: "Type", field: "type", width: "300px"},
+ { name: "User Management", field: "type", width: "200px",
+ formatter: function(val){
+ return "<input type='radio' disabled='disabled' "+(util.isProviderManagingUsers(val)?"checked='checked'": "")+" />";
+ }
+ },
+ { name: "Default", field: "name", width: "100px",
+ formatter: function(val){
+ return "<input type='radio' disabled='disabled' "+(val == that.brokerData.defaultAuthenticationProvider ? "checked='checked'": "")+" />";
+ }
+ }
+ ], function(obj) {
+ connect.connect(obj.grid, "onRowDblClick", obj.grid,
+ function(evt){
+ var idx = evt.rowIndex,
+ theItem = this.getItem(idx);
+ var name = obj.dataStore.getValue(theItem,"name");
+ that.controller.show("authenticationprovider", name, brokerObj);
+ });
+ }, gridProperties, EnhancedGrid);
+
});
xhr.get({url: "rest/logrecords", sync: properties.useSyncGet, handleAs: "json"})
@@ -186,7 +232,7 @@ define(["dojo/_base/xhr",
that.portsGrid.update(that.brokerData.ports);
-
+ that.authenticationProvidersGrid.update(that.brokerData.authenticationproviders);
});
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAuthenticationProvider.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAuthenticationProvider.js
new file mode 100644
index 0000000000..decc7fa0b3
--- /dev/null
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAuthenticationProvider.js
@@ -0,0 +1,268 @@
+/*
+ *
+ * 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.
+ *
+ */
+define(["dojo/_base/xhr",
+ "dojo/dom",
+ "dojo/dom-construct",
+ "dojo/_base/window",
+ "dijit/registry",
+ "dojo/parser",
+ "dojo/_base/array",
+ "dojo/_base/event",
+ 'dojo/_base/json',
+ "dojo/store/Memory",
+ "dijit/form/FilteringSelect",
+ "dojo/_base/connect",
+ "dojo/dom-style",
+ /* dojox/ validate resources */
+ "dojox/validate/us", "dojox/validate/web",
+ /* basic dijit classes */
+ "dijit/Dialog",
+ "dijit/form/CheckBox", "dijit/form/Textarea",
+ "dijit/form/TextBox",
+ "dijit/form/ValidationTextBox",
+ "dijit/form/Button",
+ "dijit/form/Form",
+ /* basic dojox classes */
+ "dojox/form/BusyButton", "dojox/form/CheckedMultiSelect",
+ "dojox/layout/TableContainer",
+ "dojo/domReady!"],
+ function (xhr, dom, construct, win, registry, parser, array, event, json, Memory, FilteringSelect, connect, domStyle) {
+
+ var addAuthenticationProvider = {};
+
+ var node = construct.create("div", null, win.body(), "last");
+
+ var convertToAuthenticationProvider = function convertToAuthenticationProvider(formValues)
+ {
+ var newProvider = {};
+
+ newProvider.name = dijit.byId("formAddAuthenticationProvider.name").value;
+ newProvider.type = dijit.byId("authenticationProviderType").value;
+ var id = dojo.byId("formAddAuthenticationProvider.id").value;
+ if (id)
+ {
+ newProvider.id = id;
+ }
+ for(var propName in formValues)
+ {
+ if(formValues.hasOwnProperty(propName))
+ {
+ if(formValues[ propName ] !== "") {
+ newProvider[ propName ] = formValues[propName];
+ }
+
+ }
+ }
+ return newProvider;
+ }
+
+ var showFieldSets = function showFieldSets(providerType, fieldSets)
+ {
+ for(var key in fieldSets)
+ {
+ var layout = fieldSets[key];
+ var disabled = key != providerType;
+ var displayValue = key == providerType ? "block" : "none";
+ var widgets = layout.getDescendants();
+ array.forEach(widgets, function(widget)
+ {
+ widget.set("disabled", disabled);
+ });
+
+ domStyle.set(fieldSets[key].domNode, "display", displayValue);
+ }
+ if (fieldSets[providerType])
+ {
+ fieldSets[providerType].getParent().resize();
+ }
+ }
+
+ var getAuthenticationProviderWidgetId = function getAuthenticationProviderWidgetId(providerType, attribute)
+ {
+ return "ap_" + providerType + "Field" + attribute;
+ }
+
+ var loadProviderAndDisplayForm = function loadProviderAndDisplayForm(providerName, dialog)
+ {
+ if (providerName)
+ {
+ xhr.get({
+ url: "rest/authenticationprovider/" + encodeURIComponent(providerName),
+ handleAs: "json"
+ }).then(
+ function(data) {
+ var provider = data[0];
+ var providerType = provider.type;
+ var nameField = dijit.byId("formAddAuthenticationProvider.name");
+ nameField.set("value", provider.name);
+ nameField.set("disabled", true);
+ dialog.providerChooser.set("value", providerType);
+ dialog.providerChooser.set("disabled", true);
+ dojo.byId("formAddAuthenticationProvider.id").value=provider.id;
+ for(var attribute in provider)
+ {
+ if (provider.hasOwnProperty(attribute))
+ {
+ var widject = dijit.byId(getAuthenticationProviderWidgetId(providerType, attribute));
+ if (widject)
+ {
+ widject.set("value", provider[attribute]);
+ }
+ }
+ }
+ registry.byId("addAuthenticationProvider").show();
+ });
+ }
+ else
+ {
+ registry.byId("addAuthenticationProvider").show();
+ }
+ }
+
+ xhr.get({url: "addAuthenticationProvider.html",
+ sync: true,
+ load: function(data) {
+ var theForm;
+ node.innerHTML = data;
+ addAuthenticationProvider.dialogNode = dom.byId("addAuthenticationProvider");
+ parser.instantiate([addAuthenticationProvider.dialogNode]);
+ theForm = registry.byId("formAddAuthenticationProvider");
+ theForm.on("submit", function(e) {
+
+ event.stop(e);
+ if(theForm.validate()){
+
+ var newAuthenticationManager = convertToAuthenticationProvider(theForm.getValues());
+ var that = this;
+
+ xhr.put({url: "rest/authenticationprovider/" + encodeURIComponent(newAuthenticationManager.name),
+ sync: true, handleAs: "json",
+ headers: { "Content-Type": "application/json"},
+ putData: json.toJson(newAuthenticationManager),
+ load: function(x) {that.success = true; },
+ error: function(error) {that.success = false; that.failureReason = error;}});
+
+ if(this.success === true)
+ {
+ registry.byId("addAuthenticationProvider").hide();
+ }
+ else
+ {
+ alert("Error:" + this.failureReason);
+ }
+ return false;
+ }else{
+ alert('Form contains invalid data. Please correct first');
+ return false;
+ }
+ });
+ }});
+
+ addAuthenticationProvider.show = function(providerName) {
+ var that = this;
+ registry.byId("formAddAuthenticationProvider").reset();
+ dojo.byId("formAddAuthenticationProvider.id").value="";
+ registry.byId("formAddAuthenticationProvider.name").set("disabled", false);
+ if (this.providerChooser)
+ {
+ this.providerChooser.set("disabled", false);
+ }
+
+ if (!that.hasOwnProperty("providerFieldSets"))
+ {
+ xhr.get({
+ url: "rest/helper?action=ListAuthenticationProviderAttributes",
+ handleAs: "json"
+ }).then(
+ function(data) {
+ var providers = [];
+ var providerIndex = 0;
+ that.providerFieldSetsContainer = dom.byId("addAuthenticationProvider.fieldSets");
+ that.providerFieldSets = [];
+
+ for (var providerType in data) {
+ if (data.hasOwnProperty(providerType)) {
+ providers[providerIndex++] = {id: providerType, name: providerType};
+
+ var attributes = data[providerType].attributes;
+ var resources = data[providerType].descriptions;
+ var layout = new dojox.layout.TableContainer( {
+ id: providerType + "FieldSet",
+ cols: 1,
+ "labelWidth": "300",
+ showLabels: true,
+ orientation: "horiz"
+ });
+ for(var i=0; i < attributes.length; i++) {
+ if ("type" == attributes[i])
+ {
+ continue;
+ }
+ var labelValue = attributes[i];
+ if (resources && resources[attributes[i]])
+ {
+ labelValue = resources[attributes[i]];
+ }
+ var text = new dijit.form.TextBox({
+ label: labelValue + ":",
+ id: getAuthenticationProviderWidgetId(providerType, attributes[i]),
+ name: attributes[i]
+ });
+ layout.addChild(text);
+ }
+ layout.placeAt("addAuthenticationProvider.fieldSets");
+ that.providerFieldSets[providerType]=layout;
+ layout.startup();
+ }
+ }
+
+ var providersStore = new Memory({ data: providers });
+ if(that.providerChooser) {
+ that.providerChooser.destroy( false );
+ }
+
+ var providersDiv = dom.byId("addAuthenticationProvider.selectAuthenticationProviderDiv");
+ var input = construct.create("input", {id: "addAuthenticationProviderType"}, providersDiv);
+
+ that.providerChooser = new FilteringSelect({ id: "authenticationProviderType",
+ name: "type",
+ store: providersStore,
+ searchAttr: "name"}, input);
+ connect.connect(that.providerChooser, "onChange",
+ function(event)
+ {
+ showFieldSets(that.providerChooser.value, that.providerFieldSets);
+ }
+ );
+ var providerType = providers[0].name;
+ that.providerChooser.set("value", providerType);
+ showFieldSets(providerType, that.providerFieldSets);
+ loadProviderAndDisplayForm(providerName, that)
+ });
+ }
+ else
+ {
+ loadProviderAndDisplayForm(providerName, that);
+ }
+ }
+
+ return addAuthenticationProvider;
+ }); \ No newline at end of file
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/authenticationprovider/PrincipalDatabaseAuthenticationManager.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/authenticationprovider/PrincipalDatabaseAuthenticationManager.js
index 8e5ac862bd..0a607c71d4 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/authenticationprovider/PrincipalDatabaseAuthenticationManager.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/authenticationprovider/PrincipalDatabaseAuthenticationManager.js
@@ -44,7 +44,7 @@ define(["dojo/_base/xhr",
"dijit/form/DateTextBox",
"dojo/domReady!"],
function (xhr, dom, parser, query, construct, connect, win, event, json, registry, util, properties, updater, UpdatableStore, EnhancedGrid) {
- function DatabaseAuthManager(containerNode, authProviderObj, controller) {
+ function DatabaseAuthManager(containerNode, authProviderObj, controller, authenticationManagerUpdater) {
var node = construct.create("div", null, containerNode, "last");
var that = this;
this.name = authProviderObj.name;
@@ -55,8 +55,7 @@ define(["dojo/_base/xhr",
parser.parse(node);
- that.authDatabaseUpdater= new AuthProviderUpdater(node, authProviderObj, controller);
-
+ that.authDatabaseUpdater= new AuthProviderUpdater(node, authProviderObj, controller, authenticationManagerUpdater);
updater.add( that.authDatabaseUpdater);
that.authDatabaseUpdater.update();
@@ -73,17 +72,18 @@ define(["dojo/_base/xhr",
updater.remove( this.authDatabaseUpdater );
};
- function AuthProviderUpdater(node, authProviderObj, controller)
+ function AuthProviderUpdater(node, authProviderObj, controller, authenticationManagerUpdater)
{
this.controller = controller;
- this.query = "rest/authenticationprovider/"+encodeURIComponent(authProviderObj.name);
+ this.query = "rest/authenticationprovider?id="+encodeURIComponent(authProviderObj.id);
this.name = authProviderObj.name;
+ this.authenticationManagerUpdater = authenticationManagerUpdater;
var that = this;
xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"})
.then(function(data) {
that.authProviderData = data[0];
-
+ that.name = data[0].name
util.flattenStatistics( that.authProviderData );
var userDiv = query(".users")[0];
@@ -116,13 +116,13 @@ define(["dojo/_base/xhr",
theItem = this.getItem(idx);
var name = obj.dataStore.getValue(theItem,"name");
var id = obj.dataStore.getValue(theItem,"id");
- setPassword.show(authProviderObj.name, {name: name, id: id});
+ setPassword.show(that.name, {name: name, id: id});
});
}, gridProperties, EnhancedGrid);
var addUserButton = query(".addUserButton", node)[0];
- connect.connect(registry.byNode(addUserButton), "onClick", function(evt){ addUser.show(authProviderObj.name) });
+ connect.connect(registry.byNode(addUserButton), "onClick", function(evt){ addUser.show(that.name) });
var deleteMessagesButton = query(".deleteUserButton", node)[0];
var deleteWidget = registry.byNode(deleteMessagesButton);
@@ -176,10 +176,13 @@ define(["dojo/_base/xhr",
xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"})
.then(function(data) {
that.authProviderData = data[0];
+ that.name = data[0].name
util.flattenStatistics( that.authProviderData );
that.usersGrid.update(that.authProviderData.users);
+ that.authenticationManagerUpdater.authProviderData = data[0];
+ that.authenticationManagerUpdater.updateHeader();
});
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showAuthProvider.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showAuthProvider.html
index c5d4e48a75..bea5db2829 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showAuthProvider.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showAuthProvider.html
@@ -22,4 +22,7 @@
<span style="">Name:</span><span class="name" style="position:absolute; left:6em"></span>
<br/>
<span style="">Type:</span><span class="type" style="position:absolute; left:6em"></span>
+ <br/>
+ <button data-dojo-type="dijit.form.Button" class="editAuthenticationProviderButton">Edit</button>
+ <button data-dojo-type="dijit.form.Button" class="deleteAuthenticationProviderButton">Delete</button>
</div> \ No newline at end of file
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html
index f8d80faba8..f656124a2a 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html
@@ -36,7 +36,12 @@
<div class="broker-ports"></div>
</div>
<br/>
-
+ <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Authentication Providers'">
+ <div class="broker-authentication-providers"></div>
+ <button data-dojo-type="dijit.form.Button" class="addAuthenticationProvider">Add Provider</button>
+ <button data-dojo-type="dijit.form.Button" class="deleteAuthenticationProvider">Delete Provider</button>
+ </div>
+ <br/>
<div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Log File', open: false">
<div class="broker-logfile"></div>
</div>
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java
index c7d3aa76af..2e5c3a0cc7 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java
@@ -39,8 +39,8 @@ public interface AuthenticationProvider extends ConfiguredObject
public static final String TIME_TO_LIVE = "timeToLive";
public static final String CREATED = "created";
public static final String UPDATED = "updated";
- public static final String CATEGORY = "category";
- public static final String TYPE = "authenticationProviderType";
+
+ public static final String TYPE = "type";
public static final Collection<String> AVAILABLE_ATTRIBUTES =
Collections.unmodifiableList(
@@ -53,8 +53,8 @@ public interface AuthenticationProvider extends ConfiguredObject
TIME_TO_LIVE,
CREATED,
UPDATED,
- CATEGORY,
- TYPE));
+ TYPE
+ ));
//children
Collection<VirtualHostAlias> getVirtualHostPortBindings();
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 fbecf1965b..c2b8b9886f 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
@@ -44,6 +44,7 @@ public interface Broker extends ConfiguredObject
String PROCESS_PID = "processPid";
String PRODUCT_VERSION = "productVersion";
String SUPPORTED_STORE_TYPES = "supportedStoreTypes";
+ String SUPPORTED_AUTHENTICATION_PROVIDERS = "supportedAuthenticationProviders";
String CREATED = "created";
String DURABLE = "durable";
String ID = "id";
@@ -103,6 +104,7 @@ public interface Broker extends ConfiguredObject
PROCESS_PID,
PRODUCT_VERSION,
SUPPORTED_STORE_TYPES,
+ SUPPORTED_AUTHENTICATION_PROVIDERS,
CREATED,
DURABLE,
ID,
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
index afab8a4900..d77b58458a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
@@ -69,14 +69,16 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
private GroupPrincipalAccessor _groupAccessor;
- protected String _category;
+ protected Collection<String> _supportedAttributes;
+ Map<String, AuthenticationManagerFactory> _factories;
- private AuthenticationProviderAdapter(UUID id, Broker broker, final T authManager, Map<String, Object> attributes)
+ private AuthenticationProviderAdapter(UUID id, Broker broker, final T authManager, Map<String, Object> attributes, Collection<String> attributeNames)
{
super(id, null, attributes, broker.getTaskExecutor());
_authManager = authManager;
_broker = broker;
- _category = authManager instanceof PrincipalDatabaseAuthenticationManager? PrincipalDatabaseAuthenticationManager.class.getSimpleName() : AuthenticationManager.class.getSimpleName() ;
+ _supportedAttributes = createSupportedAttributes(attributeNames);
+ _factories = getAuthenticationManagerFactories();
addParent(Broker.class, broker);
}
@@ -156,17 +158,13 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
@Override
public Collection<String> getAttributeNames()
{
- return AuthenticationProvider.AVAILABLE_ATTRIBUTES;
+ return _supportedAttributes;
}
@Override
public Object getAttribute(String name)
{
- if(CATEGORY.equals(name))
- {
- return _category;
- }
- else if(CREATED.equals(name))
+ if(CREATED.equals(name))
{
// TODO
}
@@ -224,7 +222,6 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
throw new IntegrityViolationException("Authentication provider '" + providerName + "' is set on port " + port.getName());
}
}
-
return true;
}
else if(desiredState == State.ACTIVE)
@@ -255,28 +252,74 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
_groupAccessor = groupAccessor;
}
- public AuthenticationManager createAuthenticationManager(Map<String, Object> attributes)
+ @Override
+ protected void changeAttributes(Map<String, Object> attributes)
+ {
+ AuthenticationManager manager = validateAttributes(attributes);
+ manager.initialise();
+ _authManager = (T)manager;
+ String type = (String)attributes.get(AuthenticationManagerFactory.ATTRIBUTE_TYPE);
+ AuthenticationManagerFactory managerFactory = _factories.get(type);
+ _supportedAttributes = createSupportedAttributes(managerFactory.getAttributeNames());
+ super.changeAttributes(attributes);
+ }
+
+ private Map<String, AuthenticationManagerFactory> getAuthenticationManagerFactories()
{
QpidServiceLoader<AuthenticationManagerFactory> loader = new QpidServiceLoader<AuthenticationManagerFactory>();
Iterable<AuthenticationManagerFactory> factories = loader.atLeastOneInstanceOf(AuthenticationManagerFactory.class);
+ Map<String, AuthenticationManagerFactory> factoryMap = new HashMap<String, AuthenticationManagerFactory>();
for (AuthenticationManagerFactory factory : factories)
{
- AuthenticationManager manager = factory.createInstance(attributes);
- if (manager != null)
- {
- return manager;
- }
+ factoryMap.put(factory.getType(), factory);
}
- return null;
+ return factoryMap;
+ }
+
+ 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);
+ }
+
+ protected AuthenticationManager validateAttributes(Map<String, Object> attributes)
+ {
+ String newName = (String)attributes.get(NAME);
+ String currentName = getName();
+ if (!currentName.equals(newName))
+ {
+ throw new IllegalConfigurationException("Changing the name of authentication provider is not supported");
+ }
+ String newType = (String)attributes.get(AuthenticationManagerFactory.ATTRIBUTE_TYPE);
+ String currentType = (String)getAttribute(AuthenticationManagerFactory.ATTRIBUTE_TYPE);
+ if (!currentType.equals(newType))
+ {
+ throw new IllegalConfigurationException("Changing the type of authentication provider is not supported");
+ }
+ AuthenticationManagerFactory managerFactory = _factories.get(newType);
+ if (managerFactory == null)
+ {
+ throw new IllegalConfigurationException("Cannot find authentication provider factory for type " + newType);
+ }
+ AuthenticationManager manager = managerFactory.createInstance(attributes);
+ if (manager == null)
+ {
+ throw new IllegalConfigurationException("Cannot change authentication provider " + newName + " of type " + newType + " with the given attributes");
+ }
+ return manager;
}
public static class SimpleAuthenticationProviderAdapter extends AuthenticationProviderAdapter<AuthenticationManager>
{
public SimpleAuthenticationProviderAdapter(
- UUID id, Broker broker, AuthenticationManager authManager, Map<String, Object> attributes)
+ UUID id, Broker broker, AuthenticationManager authManager, Map<String, Object> attributes, Collection<String> attributeNames)
{
- super(id, broker,authManager, attributes);
+ super(id, broker,authManager, attributes, attributeNames);
}
@Override
@@ -287,21 +330,7 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
throw new UnsupportedOperationException();
}
- @Override
- protected void changeAttributes(Map<String, Object> attributes)
- {
- AuthenticationManager manager = createAuthenticationManager(attributes);
- if (manager == null)
- {
- throw new IllegalConfigurationException("Cannot create authentication manager from " + attributes);
- }
- if (manager instanceof PrincipalDatabaseAuthenticationManager)
- {
- throw new IllegalConfigurationException("Cannot change the category of the authentication provider");
- }
- _authManager = manager;
- super.changeAttributes(attributes);
- }
+
}
@@ -310,9 +339,9 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
implements PasswordCredentialManagingAuthenticationProvider
{
public PrincipalDatabaseAuthenticationManagerAdapter(
- UUID id, Broker broker, PrincipalDatabaseAuthenticationManager authManager, Map<String, Object> attributes)
+ UUID id, Broker broker, PrincipalDatabaseAuthenticationManager authManager, Map<String, Object> attributes, Collection<String> attributeNames)
{
- super(id, broker, authManager, attributes);
+ super(id, broker, authManager, attributes, attributeNames);
}
@Override
@@ -333,7 +362,6 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
{
if(getSecurityManager().authoriseUserOperation(Operation.DELETE, username))
{
-
getPrincipalDatabase().deletePrincipal(new UsernamePrincipal(username));
}
else
@@ -431,19 +459,15 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
}
@Override
- protected void changeAttributes(Map<String, Object> attributes)
+ protected void childAdded(ConfiguredObject child)
{
- AuthenticationManager manager = createAuthenticationManager(attributes);
- if (manager == null)
- {
- throw new IllegalConfigurationException("Cannot create authentication manager from " + attributes);
- }
- if (!(manager instanceof PrincipalDatabaseAuthenticationManager))
- {
- throw new IllegalConfigurationException("Cannot change the category of the authentication provider");
- }
- _authManager = (PrincipalDatabaseAuthenticationManager)manager;
- super.changeAttributes(attributes);
+ // no-op, prevent storing users in the broker store
+ }
+
+ @Override
+ protected void childRemoved(ConfiguredObject child)
+ {
+ // no-op, as per above, users are not in the store
}
private class PrincipalAdapter extends AbstractAdapter implements User
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java
index e5108ebbcf..721282fb9c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java
@@ -20,6 +20,10 @@
*/
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;
@@ -36,10 +40,17 @@ import org.apache.qpid.server.model.adapter.AuthenticationProviderAdapter.Simple
public class AuthenticationProviderFactory
{
private final Iterable<AuthenticationManagerFactory> _factories;
+ private Collection<String> _supportedAuthenticationProviders;
public AuthenticationProviderFactory(QpidServiceLoader<AuthenticationManagerFactory> authManagerFactoryServiceLoader)
{
_factories = authManagerFactoryServiceLoader.atLeastOneInstanceOf(AuthenticationManagerFactory.class);
+ List<String> supportedAuthenticationProviders = new ArrayList<String>();
+ for (AuthenticationManagerFactory factory : _factories)
+ {
+ supportedAuthenticationProviders.add(factory.getType());
+ }
+ _supportedAuthenticationProviders = Collections.unmodifiableCollection(supportedAuthenticationProviders);
}
/**
@@ -60,11 +71,11 @@ public class AuthenticationProviderFactory
if (manager instanceof PrincipalDatabaseAuthenticationManager)
{
authenticationProvider = new PrincipalDatabaseAuthenticationManagerAdapter(id, broker,
- (PrincipalDatabaseAuthenticationManager) manager, attributes);
+ (PrincipalDatabaseAuthenticationManager) manager, attributes, factory.getAttributeNames());
}
else
{
- authenticationProvider = new SimpleAuthenticationProviderAdapter(id, broker, manager, attributes);
+ authenticationProvider = new SimpleAuthenticationProviderAdapter(id, broker, manager, attributes, factory.getAttributeNames());
}
authenticationProvider.setGroupAccessor(groupPrincipalAccessor);
return authenticationProvider;
@@ -74,4 +85,8 @@ public class AuthenticationProviderFactory
throw new IllegalArgumentException("No authentication provider factory found for configuration attributes " + attributes);
}
+ public Collection<String> getSupportedAuthenticationProviders()
+ {
+ return _supportedAuthenticationProviders;
+ }
}
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 4008b419de..6b7cf98c8a 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
@@ -55,6 +55,8 @@ import org.apache.qpid.server.model.TrustStore;
import org.apache.qpid.server.model.UUIDGenerator;
import org.apache.qpid.server.model.VirtualHost;
import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.security.auth.manager.Base64MD5PasswordFileAuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.manager.PlainPasswordFileAuthenticationManagerFactory;
import org.apache.qpid.server.security.group.FileGroupManager;
import org.apache.qpid.server.security.group.GroupManager;
import org.apache.qpid.server.security.group.GroupPrincipalAccessor;
@@ -152,7 +154,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat
private final Map<String, VirtualHost> _vhostAdapters = new HashMap<String, VirtualHost>();
private final Map<Integer, Port> _portAdapters = new HashMap<Integer, Port>();
- private final Map<String, AuthenticationProvider> _authenticationProviders = new HashMap<String, AuthenticationProvider>();
+ private final Map<UUID, AuthenticationProvider> _authenticationProviders = new HashMap<UUID, AuthenticationProvider>();
private final Map<String, GroupProvider> _groupProviders = new HashMap<String, GroupProvider>();
private final Map<UUID, ConfiguredObject> _plugins = new HashMap<UUID, ConfiguredObject>();
private final Map<UUID, KeyStore> _keyStores = new HashMap<UUID, KeyStore>();
@@ -456,11 +458,46 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat
private AuthenticationProvider createAuthenticationProvider(Map<String, Object> attributes)
{
- // it's cheap to create the groupPrincipalAccessor on the fly
- GroupPrincipalAccessor groupPrincipalAccessor = new GroupPrincipalAccessor(_groupProviders.values());
+ String type = (String)attributes.get(AuthenticationProvider.TYPE);
+ if (type == null)
+ {
+ throw new IllegalConfigurationException("Authentication provider type is not specified");
+ }
+
+ AuthenticationProvider authenticationProvider = null;
+ synchronized (_authenticationProviders)
+ {
+ // a temporary restriction to prevent creation of several instances
+ // of PlainPasswordFileAuthenticationProvider/Base64MD5PasswordFileAuthenticationProvider
+ // due to current limitation of JMX management which cannot cope
+ // with several user management MBeans as MBEan type is used as a name.
+
+ // TODO: Remove this check after fixing the JMX management
+ if (type.equals(PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE)
+ || type.equals(Base64MD5PasswordFileAuthenticationManagerFactory.PROVIDER_TYPE))
+ {
+
+ for (AuthenticationProvider provider : _authenticationProviders.values())
+ {
+ String providerType = (String) provider.getAttribute(AuthenticationProvider.TYPE);
+ if (providerType.equals(PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE)
+ || providerType.equals(Base64MD5PasswordFileAuthenticationManagerFactory.PROVIDER_TYPE))
+ {
+ throw new IllegalConfigurationException("Authentication provider managing users alredy exists ["
+ + provider.getName() + "]. Only one instance is allowed.");
+ }
+ }
+
+ }
- AuthenticationProvider authenticationProvider = _authenticationProviderFactory.create(UUID.randomUUID(), this, attributes, groupPrincipalAccessor);
- addAuthenticationProvider(authenticationProvider);
+ // it's cheap to create the groupPrincipalAccessor on the fly
+ GroupPrincipalAccessor groupPrincipalAccessor = new GroupPrincipalAccessor(_groupProviders.values());
+
+ authenticationProvider = _authenticationProviderFactory.create(UUID.randomUUID(), this, attributes,
+ groupPrincipalAccessor);
+ addAuthenticationProvider(authenticationProvider);
+ }
+ authenticationProvider.setDesiredState(State.INITIALISING, State.ACTIVE);
return authenticationProvider;
}
@@ -472,11 +509,18 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat
String name = authenticationProvider.getName();
synchronized (_authenticationProviders)
{
- if(_authenticationProviders.containsKey(name))
+ if (_authenticationProviders.containsKey(authenticationProvider.getId()))
{
- throw new IllegalConfigurationException("Cannot add AuthenticationProvider because one with name " + name + " already exists");
+ throw new IllegalConfigurationException("Cannot add AuthenticationProvider because one with id " + authenticationProvider.getId() + " already exists");
}
- _authenticationProviders.put(name, authenticationProvider);
+ for (AuthenticationProvider provider : _authenticationProviders.values())
+ {
+ if (provider.getName().equals(name))
+ {
+ throw new IllegalConfigurationException("Cannot add AuthenticationProvider because one with name " + name + " already exists");
+ }
+ }
+ _authenticationProviders.put(authenticationProvider.getId(), authenticationProvider);
}
authenticationProvider.addChangeListener(this);
}
@@ -604,6 +648,10 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat
{
// TODO
}
+ else if(SUPPORTED_AUTHENTICATION_PROVIDERS.equals(name))
+ {
+ return _authenticationProviderFactory.getSupportedAuthenticationProviders();
+ }
else if (DEFAULT_AUTHENTICATION_PROVIDER.equals(name))
{
return _defaultAuthenticationProvider == null ? null : _defaultAuthenticationProvider.getName();
@@ -634,7 +682,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat
AuthenticationProvider removedAuthenticationProvider = null;
synchronized (_authenticationProviders)
{
- removedAuthenticationProvider = _authenticationProviders.remove(authenticationProvider.getName());
+ removedAuthenticationProvider = _authenticationProviders.remove(authenticationProvider.getId());
}
return removedAuthenticationProvider != null;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java
index 95e6b4feb0..9a2a3c9d3b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java
@@ -18,14 +18,41 @@
*/
package org.apache.qpid.server.plugin;
+import java.util.Collection;
import java.util.Map;
+import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-
public interface AuthenticationManagerFactory
{
- public static final String ATTRIBUTE_TYPE = "authenticationProviderType";
+ public static final String ATTRIBUTE_TYPE = AuthenticationProvider.TYPE;
+
+ /**
+ * Returns the authentication provider type
+ * @return authentication provider type
+ */
+ String getType();
+ /**
+ * Creates authentication manager from the provided attributes
+ *
+ * @param attributes
+ * attributes to create authentication manager
+ * @return authentication manager instance
+ */
AuthenticationManager createInstance(Map<String, Object> attributes);
+
+ /**
+ * Get the names of attributes the authentication manager which can be passed into {@link #createInstance(Map)} to create the
+ * authentication 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/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java
index ff21d63c87..2cf8c4619a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java
@@ -20,6 +20,9 @@
package org.apache.qpid.server.security.auth.manager;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import org.apache.log4j.Logger;
@@ -33,10 +36,16 @@ import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
*/
public abstract class AbstractPrincipalDatabaseAuthManagerFactory implements AuthenticationManagerFactory
{
+ public static final String RESOURCE_BUNDLE = "org.apache.qpid.server.security.auth.manager.PasswordFileAuthenticationProviderAttributeDescriptions";
public static final String ATTRIBUTE_PATH = "path";
private static final Logger LOGGER = Logger.getLogger(AbstractPrincipalDatabaseAuthManagerFactory.class);
+ public static final Collection<String> ATTRIBUTES = Collections.unmodifiableList(Arrays.asList(
+ ATTRIBUTE_TYPE,
+ ATTRIBUTE_PATH));
+
+
@Override
public AuthenticationManager createInstance(Map<String, Object> attributes)
{
@@ -65,7 +74,11 @@ public abstract class AbstractPrincipalDatabaseAuthManagerFactory implements Aut
return new PrincipalDatabaseAuthenticationManager(principalDatabase);
}
- abstract String getType();
-
abstract PrincipalDatabase createPrincipalDatabase();
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return ATTRIBUTES;
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java
index 1b1995500c..0c6aa75636 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java
@@ -19,6 +19,8 @@
*/
package org.apache.qpid.server.security.auth.manager;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
@@ -37,4 +39,21 @@ public class AnonymousAuthenticationManagerFactory implements AuthenticationMana
return null;
}
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return Collections.<String>singletonList(ATTRIBUTE_TYPE);
+ }
+
+ @Override
+ public String getType()
+ {
+ return PROVIDER_TYPE;
+ }
+
+ @Override
+ public Map<String, String> getAttributeDescriptions()
+ {
+ return null;
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactory.java
index c61567ef77..c0c0b8e3c1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactory.java
@@ -20,15 +20,18 @@
*/
package org.apache.qpid.server.security.auth.manager;
+import java.util.Map;
+
import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.util.ResourceBundleLoader;
public class Base64MD5PasswordFileAuthenticationManagerFactory extends AbstractPrincipalDatabaseAuthManagerFactory
{
public static final String PROVIDER_TYPE = "Base64MD5PasswordFileAuthenticationProvider";
@Override
- String getType()
+ public String getType()
{
return PROVIDER_TYPE;
}
@@ -39,4 +42,10 @@ public class Base64MD5PasswordFileAuthenticationManagerFactory extends AbstractP
return new Base64MD5PasswordFilePrincipalDatabase();
}
+ @Override
+ public Map<String, String> getAttributeDescriptions()
+ {
+ return ResourceBundleLoader.getResources(RESOURCE_BUNDLE);
+ }
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
index 3c3628e9db..29cfb2ad29 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
@@ -19,6 +19,8 @@
*/
package org.apache.qpid.server.security.auth.manager;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
@@ -37,4 +39,22 @@ public class ExternalAuthenticationManagerFactory implements AuthenticationManag
return null;
}
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return Collections.<String>singletonList(ATTRIBUTE_TYPE);
+ }
+
+ @Override
+ public String getType()
+ {
+ return PROVIDER_TYPE;
+ }
+
+ @Override
+ public Map<String, String> getAttributeDescriptions()
+ {
+ return null;
+ }
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java
index 7af6727280..e60f37a18e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java
@@ -19,6 +19,8 @@
*/
package org.apache.qpid.server.security.auth.manager;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
@@ -36,4 +38,22 @@ public class KerberosAuthenticationManagerFactory implements AuthenticationManag
}
return null;
}
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return Collections.<String>singletonList(ATTRIBUTE_TYPE);
+ }
+
+ @Override
+ public String getType()
+ {
+ return PROVIDER_TYPE;
+ }
+
+ @Override
+ public Map<String, String> getAttributeDescriptions()
+ {
+ return null;
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PasswordFileAuthenticationProviderAttributeDescriptions.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PasswordFileAuthenticationProviderAttributeDescriptions.properties
new file mode 100644
index 0000000000..e847e90f57
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PasswordFileAuthenticationProviderAttributeDescriptions.properties
@@ -0,0 +1,19 @@
+#
+# 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.
+
+path=File location* \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactory.java
index 43b92735f1..c08b00f907 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactory.java
@@ -20,15 +20,18 @@
*/
package org.apache.qpid.server.security.auth.manager;
+import java.util.Map;
+
import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.util.ResourceBundleLoader;
public class PlainPasswordFileAuthenticationManagerFactory extends AbstractPrincipalDatabaseAuthManagerFactory
{
public static final String PROVIDER_TYPE = "PlainPasswordFileAuthenticationProvider";
@Override
- String getType()
+ public String getType()
{
return PROVIDER_TYPE;
}
@@ -39,4 +42,9 @@ public class PlainPasswordFileAuthenticationManagerFactory extends AbstractPrinc
return new PlainPasswordFilePrincipalDatabase();
}
+ @Override
+ public Map<String, String> getAttributeDescriptions()
+ {
+ return ResourceBundleLoader.getResources(AbstractPrincipalDatabaseAuthManagerFactory.RESOURCE_BUNDLE);
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java
index 05a692fb0e..ff468dc56a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java
@@ -19,12 +19,17 @@
*/
package org.apache.qpid.server.security.auth.manager;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.util.ResourceBundleLoader;
public class SimpleLDAPAuthenticationManagerFactory implements AuthenticationManagerFactory
{
+ public static final String RESOURCE_BUNDLE = "org.apache.qpid.server.security.auth.manager.SimpleLDAPAuthenticationProviderAttributeDescriptions";
private static final String DEFAULT_LDAP_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
public static final String PROVIDER_TYPE = SimpleLDAPAuthenticationManager.class.getSimpleName();
@@ -36,6 +41,15 @@ public class SimpleLDAPAuthenticationManagerFactory implements AuthenticationMan
public static final String ATTRIBUTE_PROVIDER_SEARCH_URL = "providerSearchUrl";
public static final String ATTRIBUTE_PROVIDER_URL = "providerUrl";
+ public static final Collection<String> ATTRIBUTES = Collections.<String> unmodifiableList(Arrays.asList(
+ ATTRIBUTE_TYPE,
+ ATTRIBUTE_LDAP_CONTEXT_FACTORY,
+ ATTRIBUTE_SEARCH_FILTER,
+ ATTRIBUTE_SEARCH_CONTEXT,
+ ATTRIBUTE_PROVIDER_AUTH_URL,
+ ATTRIBUTE_PROVIDER_SEARCH_URL,
+ ATTRIBUTE_PROVIDER_URL));
+
@Override
public AuthenticationManager createInstance(Map<String, Object> attributes)
{
@@ -66,4 +80,21 @@ public class SimpleLDAPAuthenticationManagerFactory implements AuthenticationMan
ldapContextFactory);
}
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return ATTRIBUTES;
+ }
+
+ @Override
+ public String getType()
+ {
+ return PROVIDER_TYPE;
+ }
+
+ @Override
+ public Map<String, String> getAttributeDescriptions()
+ {
+ return ResourceBundleLoader.getResources(RESOURCE_BUNDLE);
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationProviderAttributeDescriptions.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationProviderAttributeDescriptions.properties
new file mode 100644
index 0000000000..1fadfcf758
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationProviderAttributeDescriptions.properties
@@ -0,0 +1,24 @@
+#
+# 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.
+
+ldapContextFactory= LDAP context factory
+searchFilter=Search filter*
+searchContext=Search context*
+providerAuthUrl=LDAP authentication URL
+providerSearchUrl=LDAP search URL
+providerUrl=LDAP server URL* \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/util/ResourceBundleLoader.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/util/ResourceBundleLoader.java
new file mode 100644
index 0000000000..a0ed4e27f4
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/util/ResourceBundleLoader.java
@@ -0,0 +1,49 @@
+/*
+ * 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.util;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class ResourceBundleLoader
+{
+ public static Map<String, String> getResources(String baseName)
+ {
+ try
+ {
+ ResourceBundle bundle = ResourceBundle.getBundle(baseName);
+ Map<String, String> resources = new HashMap<String, String>();
+ Enumeration<String> en = bundle.getKeys();
+ while (en.hasMoreElements())
+ {
+ String key = (String) en.nextElement();
+ resources.put(key, bundle.getString(key));
+ }
+ return resources;
+ }
+ catch(MissingResourceException e)
+ {
+ return null;
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/resources/initial-store.json b/qpid/java/broker/src/main/resources/initial-store.json
index a80ad95bd4..8e278120fc 100644
--- a/qpid/java/broker/src/main/resources/initial-store.json
+++ b/qpid/java/broker/src/main/resources/initial-store.json
@@ -20,11 +20,11 @@
*/
{
"name": "QpidBroker",
- "defaultAuthenticationProvider" : "defaultAuthenticationProvider",
+ "defaultAuthenticationProvider" : "passwordFile",
"defaultVirtualHost" : "default",
"authenticationproviders" : [ {
- "name" : "defaultAuthenticationProvider",
- "authenticationProviderType" : "PlainPasswordFileAuthenticationProvider",
+ "name" : "passwordFile",
+ "type" : "PlainPasswordFileAuthenticationProvider",
"path" : "${QPID_HOME}/etc/passwd"
} ],
"ports" : [ {
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 c1ebe26f52..883f88cc36 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
@@ -66,6 +66,7 @@ public class BrokerRecovererTest extends TestCase
private Map<String, Collection<ConfigurationEntry>> _brokerEntryChildren = new HashMap<String, Collection<ConfigurationEntry>>();
private ConfigurationEntry _authenticationProviderEntry1;
private AuthenticationProvider _authenticationProvider1;
+ private UUID _authenticationProvider1Id = UUID.randomUUID();
@Override
protected void setUp() throws Exception
@@ -80,6 +81,7 @@ public class BrokerRecovererTest extends TestCase
//Add a base AuthenticationProvider for all tests
_authenticationProvider1 = mock(AuthenticationProvider.class);
when(_authenticationProvider1.getName()).thenReturn("authenticationProvider1");
+ when(_authenticationProvider1.getId()).thenReturn(_authenticationProvider1Id);
_authenticationProviderEntry1 = mock(ConfigurationEntry.class);
_brokerEntryChildren.put(AuthenticationProvider.class.getSimpleName(), Arrays.asList(_authenticationProviderEntry1));
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java
index 157945f2be..89645507c4 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java
@@ -37,9 +37,6 @@ import org.apache.qpid.test.utils.TestBrokerConfiguration;
public class AuthenticationProviderRestTest extends QpidRestTestCase
{
- private static final String PRINCIPAL_DATABASE_AUTHENTICATION_MANAGER = "PrincipalDatabaseAuthenticationManager";
- private static final String AUTHENTICATION_MANAGER = "AuthenticationManager";
-
public void testGet() throws Exception
{
List<Map<String, Object>> providerDetails = getRestTestHelper().getJsonAsList("/rest/authenticationprovider");
@@ -47,11 +44,11 @@ public class AuthenticationProviderRestTest extends QpidRestTestCase
assertEquals("Unexpected number of providers", 1, providerDetails.size());
for (Map<String, Object> provider : providerDetails)
{
- assertProvider(PRINCIPAL_DATABASE_AUTHENTICATION_MANAGER, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE, provider);
+ assertProvider(true, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE, provider);
Map<String, Object> data = getRestTestHelper().getJsonAsSingletonList("/rest/authenticationprovider/"
+ provider.get(AuthenticationProvider.NAME));
assertNotNull("Cannot load data for " + provider.get(AuthenticationProvider.NAME), data);
- assertProvider(PRINCIPAL_DATABASE_AUTHENTICATION_MANAGER, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE, data);
+ assertProvider(true, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE, data);
}
}
@@ -72,7 +69,7 @@ public class AuthenticationProviderRestTest extends QpidRestTestCase
assertNotNull("Providers details cannot be null", providerDetails);
assertEquals("Unexpected number of providers", 1, providerDetails.size());
Map<String, Object> provider = providerDetails.get(0);
- assertProvider(PRINCIPAL_DATABASE_AUTHENTICATION_MANAGER, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE, provider);
+ assertProvider(true, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE, provider);
// provider should exists after broker restart
restartBroker();
@@ -95,7 +92,7 @@ public class AuthenticationProviderRestTest extends QpidRestTestCase
assertNotNull("Providers details cannot be null", providerDetails);
assertEquals("Unexpected number of providers", 1, providerDetails.size());
Map<String, Object> provider = providerDetails.get(0);
- assertProvider(AUTHENTICATION_MANAGER, AnonymousAuthenticationManagerFactory.PROVIDER_TYPE, provider);
+ assertProvider(false, AnonymousAuthenticationManagerFactory.PROVIDER_TYPE, provider);
}
public void testDeleteOfDefaultAuthenticationProviderFails() throws Exception
@@ -108,7 +105,7 @@ public class AuthenticationProviderRestTest extends QpidRestTestCase
List<Map<String, Object>> providerDetails = getRestTestHelper().getJsonAsList("/rest/authenticationprovider/" + providerName);
assertNotNull("Providers details cannot be null", providerDetails);
assertEquals("Unexpected number of providers", 1, providerDetails.size());
- assertProvider(PRINCIPAL_DATABASE_AUTHENTICATION_MANAGER, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE, providerDetails.get(0));
+ assertProvider(true, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE, providerDetails.get(0));
}
public void testDeleteOfUsedAuthenticationProviderFails() throws Exception
@@ -138,7 +135,7 @@ public class AuthenticationProviderRestTest extends QpidRestTestCase
List<Map<String, Object>> providerDetails = getRestTestHelper().getJsonAsList("/rest/authenticationprovider/" + providerName);
assertNotNull("Providers details cannot be null", providerDetails);
assertEquals("Unexpected number of providers", 1, providerDetails.size());
- assertProvider(AUTHENTICATION_MANAGER, AnonymousAuthenticationManagerFactory.PROVIDER_TYPE, providerDetails.get(0));
+ assertProvider(false, AnonymousAuthenticationManagerFactory.PROVIDER_TYPE, providerDetails.get(0));
}
public void testDeleteOfUnusedAuthenticationProvider() throws Exception
@@ -160,82 +157,7 @@ public class AuthenticationProviderRestTest extends QpidRestTestCase
assertEquals("Unexpected number of providers", 0, providerDetails.size());
}
- public void testPutUpdateAuthenticationProvider() throws Exception
- {
- File principalDatabase = getRestTestHelper().createTemporaryPasswdFile(new String[]{"admin2", "guest2", "test2"});
-
- String providerName = "test-provider";
- Map<String, Object> attributes = new HashMap<String, Object>();
- attributes.put(AuthenticationProvider.NAME, providerName);
- attributes.put(AuthenticationProvider.TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
- attributes.put(PlainPasswordFileAuthenticationManagerFactory.ATTRIBUTE_PATH, principalDatabase.getAbsolutePath());
-
- int responseCode = getRestTestHelper().submitRequest("/rest/authenticationprovider/" + providerName, "PUT", attributes);
- assertEquals("Unexpected response code", 201, responseCode);
-
- List<Map<String, Object>> providerDetails = getRestTestHelper().getJsonAsList("/rest/authenticationprovider/" + providerName);
- assertNotNull("Providers details cannot be null", providerDetails);
- assertEquals("Unexpected number of providers", 1, providerDetails.size());
-
- String[] users = new String[]{"admin3", "guest3", "test3"};
- File principalDatabase2 = getRestTestHelper().createTemporaryPasswdFile(users);
-
- Map<String, Object> newAttributes = new HashMap<String, Object>();
- newAttributes.put(AuthenticationProvider.NAME, providerName);
- newAttributes.put(AuthenticationProvider.TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
- newAttributes.put(PlainPasswordFileAuthenticationManagerFactory.ATTRIBUTE_PATH, principalDatabase2.getAbsolutePath());
-
- responseCode = getRestTestHelper().submitRequest("/rest/authenticationprovider/" + providerName, "PUT", newAttributes);
- assertEquals("Unexpected response code", 200, responseCode);
-
- providerDetails = getRestTestHelper().getJsonAsList("/rest/authenticationprovider/" + providerName);
- assertNotNull("Providers details cannot be null", providerDetails);
- assertEquals("Unexpected number of providers", 1, providerDetails.size());
-
- List<Map<String, Object>> userData = getRestTestHelper().getJsonAsList("/rest/user/" + providerName);
- assertEquals(3, userData.size());
- for (int i = 0; i < users.length; i++)
- {
- boolean userFound = false;
- for (Map<String, Object> userEntry : userData)
- {
- String name = (String)userEntry.get(User.NAME);
- if (users[i].equals(name))
- {
- userFound = true;
- break;
- }
- }
- assertTrue("User " + users[i] + " is not found", userFound);
- }
- }
-
- public void testPutUpdateAuthenticationProviderToDifferrentCategoryFails() throws Exception
- {
- File principalDatabase = getRestTestHelper().createTemporaryPasswdFile(new String[]{"admin2", "guest2", "test2"});
-
- String providerName = "test-provider";
- Map<String, Object> attributes = new HashMap<String, Object>();
- attributes.put(AuthenticationProvider.NAME, providerName);
- attributes.put(AuthenticationProvider.TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
- attributes.put(PlainPasswordFileAuthenticationManagerFactory.ATTRIBUTE_PATH, principalDatabase.getAbsolutePath());
-
- int responseCode = getRestTestHelper().submitRequest("/rest/authenticationprovider/" + providerName, "PUT", attributes);
- assertEquals("Unexpected response code", 201, responseCode);
-
- List<Map<String, Object>> providerDetails = getRestTestHelper().getJsonAsList("/rest/authenticationprovider/" + providerName);
- assertNotNull("Providers details cannot be null", providerDetails);
- assertEquals("Unexpected number of providers", 1, providerDetails.size());
-
- Map<String, Object> newAttributes = new HashMap<String, Object>();
- newAttributes.put(AuthenticationProvider.NAME, providerName);
- newAttributes.put(AuthenticationProvider.TYPE, AnonymousAuthenticationManagerFactory.PROVIDER_TYPE);
-
- responseCode = getRestTestHelper().submitRequest("/rest/authenticationprovider/" + providerName, "PUT", newAttributes);
- assertEquals("Unexpected response code", 409, responseCode);
- }
-
- private void assertProvider(String category, String subType, Map<String, Object> provider)
+ private void assertProvider(boolean managesPrincipals, String type, Map<String, Object> provider)
{
Asserts.assertAttributesPresent(provider, AuthenticationProvider.AVAILABLE_ATTRIBUTES,
AuthenticationProvider.CREATED, AuthenticationProvider.UPDATED, AuthenticationProvider.DESCRIPTION,
@@ -246,12 +168,10 @@ public class AuthenticationProviderRestTest extends QpidRestTestCase
LifetimePolicy.PERMANENT.name(), provider.get(AuthenticationProvider.LIFETIME_POLICY));
assertEquals("Unexpected value of provider attribute " + AuthenticationProvider.DURABLE, Boolean.TRUE,
provider.get(AuthenticationProvider.DURABLE));
- assertEquals("Unexpected value of provider attribute " + AuthenticationProvider.CATEGORY, category,
- provider.get(AuthenticationProvider.CATEGORY));
- assertEquals("Unexpected value of provider attribute " + AuthenticationProvider.TYPE, subType,
+ assertEquals("Unexpected value of provider attribute " + AuthenticationProvider.TYPE, type,
provider.get(AuthenticationProvider.TYPE));
- if (PRINCIPAL_DATABASE_AUTHENTICATION_MANAGER.equals(category))
+ if (managesPrincipals)
{
@SuppressWarnings("unchecked")
List<Map<String, Object>> users = (List<Map<String, Object>>) provider.get("users");