diff options
| author | Keith Wall <kwall@apache.org> | 2015-01-20 13:12:49 +0000 |
|---|---|---|
| committer | Keith Wall <kwall@apache.org> | 2015-01-20 13:12:49 +0000 |
| commit | 82033b2f28c22bf48851502a75bada14ed513e7a (patch) | |
| tree | 4e83b4bf3f61e35e86a76ff983dea5bc968453eb /qpid/java/broker-plugins | |
| parent | f759ba5b3a919149622c656a2bb06f21d893ac1e (diff) | |
| download | qpid-python-82033b2f28c22bf48851502a75bada14ed513e7a.tar.gz | |
QPID-6316: [Java Broker] Make UI support the upload of ACL files
Work completed by Andrew MacBean <macbean@apache.org>
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1653244 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/broker-plugins')
5 files changed, 373 insertions, 134 deletions
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/accesscontrolprovider/aclfile/add.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/accesscontrolprovider/aclfile/add.html new file mode 100644 index 0000000000..f4058d5180 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/accesscontrolprovider/aclfile/add.html @@ -0,0 +1,62 @@ +<!-- + ~ 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> + <div class="clear"> + <div id="addAccessControlProvider.serverPathLabel" class="formLabel-labelCell tableContainer-labelCell">Server path or upload*:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addAccessControlProvider.serverPath" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'serverPath', + placeHolder: 'access control provider file server path', + required: true, + excluded: true, + promptMessage: 'Location of the access control provider file on the server', + title: 'Enter the access control provider file path'" /> + + <!-- Hidden and used purely for form submission --> + <input type="hidden" id="addAccessControlProvider.path" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'path', + required: true" /> + </div> + + <div id="addAccessControlProvider.uploadFields"> + <div id="addAccessControlProvider.fileLabel" class="formLabel-labelCell tableContainer-labelCell"></div> + <div class="fileUpload clear"> + <span id="addAccessControlProvider.selectedFile" class="infoMessage"></span> + <span id="addAccessControlProvider.selectedFileStatus"></span> + </div> + + <div class="fileUpload clear"> + <input type="file" id="addAccessControlProvider.file" + multiple="false" + data-dojo-type="dojox/form/Uploader" + data-dojo-props="label: 'Upload'"/> + <button id="addAccessControlProvider.fileClearButton" + data-dojo-type="dijit/form/Button" + data-dojo-props="label: 'Clear', + disabled: true" /> + </div> + </div> + + </div> +</div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/addAccessControlProvider.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/addAccessControlProvider.html new file mode 100644 index 0000000000..07a0c4cf83 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/addAccessControlProvider.html @@ -0,0 +1,66 @@ +<!-- + ~ 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" data-dojo-props="title:'Access Control Provider'" id="addAccessControlProvider"> + <div id="addAccessControlProvider.contentPane"> + <form id="addAccessControlProvider.form" method="post" data-dojo-type="dijit/form/Form"> + <div class="formBox"> + <div class="clear"> + <div class="formLabel-labelCell tableContainer-labelCell">Name*:</div> + <div class="formLabel-controlCell tableContainer-valueCell"> + <input type="text" id="addAccessControlProvider.name" + data-dojo-type="dijit/form/ValidationTextBox" + data-dojo-props=" + name: 'name', + placeHolder: 'access control provider name', + required: true, + promptMessage: 'Name of access control provider, must be unique', + title: 'Enter a unique access control provider name per broker'" /> + </div> + </div> + <div class="clear"> + <div class="formLabel-labelCell tableContainer-labelCell">Type*:</div> + <div class="tableContainer-valueCell formLabel-controlCell"> + <select id="addAccessControlProvider.type" data-dojo-type="dijit/form/FilteringSelect" + data-dojo-props=" + name: 'type', + required: true, + placeHolder: 'select access control provider type', + promptMessage: 'Type of access control provider', + title: 'Select access control provider type', + searchAttr: 'name'"> + </select> + </div> + </div> + + <div class="clear"> + <div id="addAccessControlProvider.typeFields"></div> + </div> + </div> + </form> + <div class="clear"> + </div> + </div> + + <div class="dijitDialogPaneActionBar"> + <button data-dojo-type="dijit/form/Button" id="addAccessControlProvider.addButton" data-dojo-props="label: 'Save'" type="submit"></button> + <button data-dojo-type="dijit/form/Button" id="addAccessControlProvider.cancelButton" data-dojo-props="label: 'Cancel'" ></button> + </div> + </div> +</div> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css b/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css index 3c9b28e34d..a18562fa1a 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/css/common.css @@ -233,6 +233,12 @@ div .messages { display: inline-block; } +.fileUpload +{ + float: right; + padding: 5px; +} + .infoMessage { padding: 5px; diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/accesscontrolprovider/aclfile/add.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/accesscontrolprovider/aclfile/add.js new file mode 100644 index 0000000000..8f7baec063 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/accesscontrolprovider/aclfile/add.js @@ -0,0 +1,119 @@ +/* + * + * 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/dom","dojo/query","dijit/registry","qpid/common/util"], + function (dom, query, registry, util) + { + var addACLFileAccessControlProvider = + { + init: function() + { + // Readers are HTML5 + this.reader = window.FileReader ? new FileReader() : undefined; + }, + show: function(data) + { + var that=this; + util.parseHtmlIntoDiv(data.containerNode, "accesscontrolprovider/aclfile/add.html"); + + this.aclServerPath = registry.byId("addAccessControlProvider.serverPath"); + this.aclUploadFields = dom.byId("addAccessControlProvider.uploadFields"); + this.aclSelectedFileContainer = dom.byId("addAccessControlProvider.selectedFile"); + this.aclSelectedFileStatusContainer = dom.byId("addAccessControlProvider.selectedFileStatus"); + this.aclFile = registry.byId("addAccessControlProvider.file"); + this.aclFileClearButton = registry.byId("addAccessControlProvider.fileClearButton"); + + //Only submitted field + this.aclPath = registry.byId("addAccessControlProvider.path"); + + this.addButton = data.parent.addButton; + + if (this.reader) + { + this.reader.onload = function(evt) {that._aclUploadFileComplete(evt);}; + this.reader.onerror = function(ex) {console.error("Failed to load ACL file", ex);}; + this.aclFile.on("change", function(selected){that._aclFileChanged(selected)}); + this.aclFileClearButton.on("click", function(event){that._aclFileClearButtonClicked(event)}); + } + else + { + // Fall back for IE8/9 which do not support FileReader + this.aclUploadFields.style.display = "none"; + } + + this.aclServerPath.on("blur", function(){that._aclServerPathChanged()}); + }, + _aclFileChanged: function (evt) + { + // We only ever expect a single file + var file = this.aclFile.domNode.children[0].files[0]; + + this.addButton.setDisabled(true); + this.aclSelectedFileContainer.innerHTML = file.name; + this.aclSelectedFileStatusContainer.className = "loadingIcon"; + + console.log("Beginning to read ACL file " + file.name); + this.reader.readAsDataURL(file); + }, + _aclUploadFileComplete: function(evt) + { + var reader = evt.target; + var result = reader.result; + console.log("ACL file read complete, contents " + result); + this.addButton.setDisabled(false); + this.aclSelectedFileStatusContainer.className = "loadedIcon"; + + this.aclServerPath.set("value", ""); + this.aclServerPath.setDisabled(true); + this.aclServerPath.set("required", false); + + this.aclFileClearButton.setDisabled(false); + + this.aclPath.set("value", result); + }, + _aclFileClearButtonClicked: function(event) + { + this.aclFile.reset(); + this.aclSelectedFileStatusContainer.className = ""; + this.aclSelectedFileContainer.innerHTML = ""; + this.aclServerPath.set("required", true); + this.aclServerPath.setDisabled(false); + this.aclFileClearButton.setDisabled(true); + + this.aclPath.set("value", ""); + }, + _aclServerPathChanged: function() + { + var serverPathValue = this.aclServerPath.get("value"); + this.aclPath.set("value", serverPathValue); + } + }; + + try + { + addACLFileAccessControlProvider.init(); + } + catch(e) + { + console.warn(e); + } + return addACLFileAccessControlProvider; + } +); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAccessControlProvider.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAccessControlProvider.js index ac0493bfa5..38a6c8e841 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAccessControlProvider.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addAccessControlProvider.js @@ -26,8 +26,10 @@ define(["dojo/_base/lang", "dojo/parser", "dojo/_base/array", "dojo/_base/event", - 'dojo/_base/json', + 'dojo/json', "qpid/common/util", + "qpid/common/metadata", + "dojo/text!addAccessControlProvider.html", "dojo/store/Memory", "dojox/validate/us", "dojox/validate/web", @@ -42,140 +44,124 @@ define(["dojo/_base/lang", "dijit/layout/ContentPane", "dojox/layout/TableContainer", "dojo/domReady!"], - function (lang, xhr, dom, construct, registry, parser, array, event, json, util) { - - var addAccessControlProvider = {}; - - addAccessControlProvider.show = function(accessControlProvider) { - var fields = [{ - name: "name", - createWidget: function(accessControlProvider) { - return new dijit.form.ValidationTextBox({ - required: true, - value: accessControlProvider.name, - disabled: accessControlProvider.name ? true : false, - label: "Name*:", - regexp: "^[\x20-\x2e\x30-\x7F]{1,255}$", - promptMessage: "Name of access control provider.", - placeHolder: "name", - name: "name"}); - } - }, { - name: "type", - createWidget: function(accessControlProvider) { - - var typeContainer = construct.create("div"); - - var typeListContainer = new dojox.layout.TableContainer({ - cols: 1, - "labelWidth": "300", - customClass: "formLabel", - showLabels: true, - orientation: "horiz" - }); - - typeContainer.appendChild(typeListContainer.domNode); - - var providers = []; - var fieldSetContainers = {}; - xhr.get({ - url: "service/helper?action=ListAccessControlProviderAttributes", - handleAs: "json", - sync: true - }).then( - function(data) { - var providerIndex = 0; - - for (var providerType in data) { - if (data.hasOwnProperty(providerType)) { - providers[providerIndex++] = {id: providerType, name: providerType}; - - var attributes = data[providerType].attributes; - var descriptions = data[providerType].descriptions; - - var layout = new dojox.layout.TableContainer( { - cols: 1, - "labelWidth": "300", - customClass: "formLabel", - showLabels: true, - orientation: "horiz" - }); - - for(var i=0; i < attributes.length; i++) { - if ("type" == attributes[i]) - { - continue; - } - var labelValue = attributes[i]; - if (descriptions && descriptions[attributes[i]]) - { - labelValue = descriptions[attributes[i]]; - } - var text = new dijit.form.TextBox({ - label: labelValue + ":", - name: attributes[i] - }); - layout.addChild(text); - } - - typeContainer.appendChild(layout.domNode); - fieldSetContainers[providerType] = layout; - } - } - }); - - var providersStore = new dojo.store.Memory({ data: providers }); - - var typeList = new dijit.form.FilteringSelect({ - required: true, - value: accessControlProvider.type, - store: providersStore, - label: "Type*:", - name: "type"}); - - typeListContainer.addChild(typeList); - - var onChangeHandler = function onChangeHandler(newValue){ - for (var i in fieldSetContainers) { - var container = fieldSetContainers[i]; - var descendants = container.getChildren(); - for(var i in descendants){ - var descendant = descendants[i]; - var propName = descendant.name; - if (propName) { - descendant.set("disabled", true); - } + function (lang, xhr, dom, construct, registry, parser, array, event, json, util, metadata, template) + { + + var addAccessControlProvider = + { + init: function() + { + var that=this; + this.containerNode = construct.create("div", {innerHTML: template}); + parser.parse(this.containerNode); + + this.accessControlProviderName = registry.byId("addAccessControlProvider.name"); + this.accessControlProviderName.set("regExpGen", util.nameOrContextVarRegexp); + + this.dialog = registry.byId("addAccessControlProvider"); + this.addButton = registry.byId("addAccessControlProvider.addButton"); + this.cancelButton = registry.byId("addAccessControlProvider.cancelButton"); + this.cancelButton.on("click", function(e){that._cancel(e);}); + this.addButton.on("click", function(e){that._add(e);}); + + this.accessControlProviderTypeFieldsContainer = dom.byId("addAccessControlProvider.typeFields"); + this.accessControlProviderForm = registry.byId("addAccessControlProvider.form"); + this.accessControlProviderType = registry.byId("addAccessControlProvider.type"); + this.supportedAccessControlProviderTypes = metadata.getTypesForCategory("AccessControlProvider"); + this.supportedAccessControlProviderTypes.sort(); + var accessControlProviderTypeStore = util.makeTypeStore(this.supportedAccessControlProviderTypes); + this.accessControlProviderType.set("store", accessControlProviderTypeStore); + this.accessControlProviderType.on("change", function(type){that._accessControlProviderTypeChanged(type);}); + }, + show: function(effectiveData) + { + this.accessControlProviderForm.reset(); + this.dialog.show(); + }, + _cancel: function(e) + { + event.stop(e); + if (this.reader) + { + this.reader.abort(); + } + this.dialog.hide(); + }, + _add: function(e) + { + event.stop(e); + this._submit(); + }, + _submit: function() + { + if (this.accessControlProviderForm.validate()) + { + var success = false,failureReason=null; + + var accessControlProviderData = util.getFormWidgetValues(this.accessControlProviderForm, this.initialData); + var encodedAccessControlProviderName = encodeURIComponent(this.accessControlProviderName.value); + + xhr.put( + { + url: "api/latest/accesscontrolprovider/" + encodedAccessControlProviderName, + sync: true, + handleAs: "json", + headers: { "Content-Type": "application/json"}, + putData: json.stringify(accessControlProviderData), + load: function(x) {success = true; }, + error: function(error) {success = false; failureReason = error;} + }); + + if (success == true) + { + this.dialog.hide(); } - container.domNode.style.display = "none"; - } - var container = fieldSetContainers[newValue]; - if (container) - { - container.domNode.style.display = "block"; - var descendants = container.getChildren(); - for(var i in descendants){ - var descendant = descendants[i]; - var propName = descendant.name; - if (propName) { - descendant.set("disabled", false); - } + else + { + util.xhrErrorHandler(failureReason); } - } - }; - typeList.on("change", onChangeHandler); - onChangeHandler(typeList.value); - return new dijit.layout.ContentPane({content: typeContainer, style:{padding: 0}}); - } - }]; - - util.showSetAttributesDialog( - fields, - accessControlProvider ? accessControlProvider : {}, - "api/latest/accesscontrolprovider" + (name ? "/" + encodeURIComponent(name.name) : ""), - accessControlProvider ? "Edit access control provider - " + accessControlProvider.name : "Add access control provider", - "AccessControlProvider", - accessControlProvider && accessControlProvider.type ? accessControlProvider.type : "AclFile", - accessControlProvider ? false : true); + } + else + { + alert('Form contains invalid data. Please correct first'); + } + }, + _accessControlProviderTypeChanged: function(type) + { + this._typeChanged(type, this.accessControlProviderTypeFieldsContainer, "qpid/management/accesscontrolprovider/", "AccessControlProvider" ); + }, + _typeChanged: function(type, typeFieldsContainer, baseUrl, category ) + { + var widgets = registry.findWidgets(typeFieldsContainer); + array.forEach(widgets, function(item) { item.destroyRecursive();}); + construct.empty(typeFieldsContainer); + + if (type) + { + var that = this; + require([ baseUrl + type.toLowerCase() + "/add"], function(typeUI) + { + try + { + typeUI.show({containerNode:typeFieldsContainer, parent: that, data: that.initialData, effectiveData: that.effectiveData}); + util.applyMetadataToWidgets(typeFieldsContainer, category, type); + } + catch(e) + { + console.warn(e); + } + }); + } + } }; + + try + { + addAccessControlProvider.init(); + } + catch(e) + { + console.warn(e); + } return addAccessControlProvider; - });
\ No newline at end of file + }); |
