diff options
author | Alex Rudyy <orudyy@apache.org> | 2013-03-11 18:29:45 +0000 |
---|---|---|
committer | Alex Rudyy <orudyy@apache.org> | 2013-03-11 18:29:45 +0000 |
commit | 66de8678fb2ab2af8dc5b6d653402b1efd70779b (patch) | |
tree | 11e91fd6e6305e3b008d87bccbd81d1d8e29a15c | |
parent | 8f8a9146dbb5a7116ecd24c1003bd200623a7e03 (diff) | |
download | qpid-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
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"); |