[PATCH 0/2] UI: support ldap permission tag

From: Royce Lv <lvroyce@linux.vnet.ibm.com> Users added will be validated when press save permission button, invalid user will be labled as notice icon. update vm request with invalid user will be rejected. only user tag is supported for ldap. This is tested agaist ldap integration v2. Note: Due to capabilities query of authentication type is not added. This patch simply hided PAM permission tag part. Will address this issue after backend changed. Royce Lv (2): UI: support ldap vm permission tag Change guest edit permission logic ui/css/theme-default/guest-edit.css | 79 ++++++++++++++----- ui/js/src/kimchi.api.js | 13 +++- ui/js/src/kimchi.guest_edit_main.js | 146 ++++++++++++++++++++++++++++++------ ui/pages/guest-edit.html.tmpl | 28 ++++++- 4 files changed, 218 insertions(+), 48 deletions(-) -- 1.8.3.2

From: Royce Lv <lvroyce@linux.vnet.ibm.com> Add corresponding html and css to support vm permission. Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- ui/css/theme-default/guest-edit.css | 79 ++++++++++++++++++++++++++++--------- ui/pages/guest-edit.html.tmpl | 28 ++++++++++++- 2 files changed, 87 insertions(+), 20 deletions(-) diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css index b1d3931..11d0ff7 100644 --- a/ui/css/theme-default/guest-edit.css +++ b/ui/css/theme-default/guest-edit.css @@ -168,22 +168,26 @@ padding: 5px 10px!important; } -.guest-edit-permission .column { +.guest-edit-permission .hide { + display: none; +} + +.guest-edit-permission .pam .column { display: inline-block; vertical-align: top; } -.guest-edit-permission .title { +.guest-edit-permission .pam .title { margin-bottom: 3px; } -.guest-edit-permission input[type="text"] { +.guest-edit-permission .pam input[type="text"] { margin-bottom: 3px; font-size: 12px; width: 97%; } -.guest-edit-permission .body { +.guest-edit-permission .pam .body { border: 1px solid #999999; font-size: 12px; padding: 1px; @@ -191,77 +195,114 @@ overflow: auto; } -.guest-edit-permission .body .head { +.guest-edit-permission .pam .body .head { margin-bottom: 3px; font-weight: bold; background: linear-gradient(to bottom, #E5E5E5 0%, #C4C4C4 100%) repeat scroll 0 0 transparent; } -.guest-edit-permission .body .item { +.guest-edit-permission .pam .body .item { padding: 2px 3px; margin-bottom: 1px; cursor: pointer; } -.guest-edit-permission .body .item:hover { +.guest-edit-permission .pam .body .item:hover { background-color: #AAAAAA; } -.guest-edit-permission .body .item-picked { +.guest-edit-permission .pam .body .item-picked { background-color: #BBBBBB; } -.guest-edit-permission .body .item .icon { +.guest-edit-permission .pam .body .item .icon { display: inline-block; height: 15px; width: 15px; vertical-align: bottom; } -.guest-edit-permission .body .item .user-icon { +.guest-edit-permission .pam .body .item .user-icon { background: url('/images/theme-default/user.png') no-repeat scroll; background-size: 15px 15px; } -.guest-edit-permission .body .item .group-icon { +.guest-edit-permission .pam .body .item .group-icon { background: url('/images/theme-default/group.png') no-repeat scroll; background-size: 15px 15px; } -.guest-edit-permission .body .column-user { +.guest-edit-permission .pam .body .column-user { width: 48%; } -.guest-edit-permission .body .column-group { +.guest-edit-permission .pam .body .column-group { width: 50%; } -.guest-edit-permission .control { +.guest-edit-permission .pam .control { width: 5%; } -.guest-edit-permission .control button { +.guest-edit-permission .pam .control button { width: 26px; margin-left: 7px; } -.guest-edit-permission .control button:first-child { +.guest-edit-permission .pam .control button:first-child { margin-top: 110px; margin-bottom: 2px; } -.guest-edit-permission .control .ui-button-text-only .ui-button-text { +.guest-edit-permission .pam .control .ui-button-text-only .ui-button-text { padding: 2px 8px; } -.guest-edit-permission .avail { +.guest-edit-permission .pam .avail { width: 46%; } -.guest-edit-permission .selected { +.guest-edit-permission .pam .selected { width: 46%; float: right; } +#form-guest-edit-permission .ldap .header { + font-weight: bold; + padding-bottom: 2px; + margin-bottom: 8px; + border-bottom: 1px solid #999; +} + +#form-guest-edit-permission .ldap .body .item { + margin: 8px 0; +} + +#form-guest-edit-permission .ldap .cell { + width: 250px; +} + +#form-guest-edit-permission .ldap .action-area { + float: right; + line-height: 24px; +} + +#form-guest-edit-permission .ldap button { + width: 20px; + height: 20px; +} + +#form-guest-edit-permission .ldap .header button { + margin-bottom: 1px; +} + +#form-guest-edit-permission .ldap .checked { + display: inline-block; +} + +#form-guest-edit-permission .ldap .checked.hide { + display: none; +} + .guest-edit-pci { height: 79%; overflow: auto; diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl index 512909a..429bf8a 100644 --- a/ui/pages/guest-edit.html.tmpl +++ b/ui/pages/guest-edit.html.tmpl @@ -112,6 +112,7 @@ <div class="body"></div> </form> <form id="form-guest-edit-permission" class="guest-edit-permission"> + <div class="pam hide"> <div class="column avail"> <div class="title">$_("Available system users and groups")</div> <input type="text" id="permission-avail-searchBox"> @@ -140,6 +141,14 @@ <div id="permission-sel-groups" class="column column-group"></div> </div> </div> + </div> + <div class="ldap"> + <div class="header"> + <span class="cell">$_("User")</span> + <button type="button" id="guest-edit-add-user-button" class="action-area add"></button> + </div> + <div class="body"></div> + </div> </form> <form id="form-guest-edit-pci" class="guest-edit-pci"> <div class="guest-scroll-indent"> @@ -218,6 +227,23 @@ </span> <div> </script> +<script id="ldap-user-tmpl" type="text/html"> + <div class="item" id="{user}"> + <span class="cell"> + <label class="{viewMode}">{user}</label> + <input type="text" class="{editMode}"/> + </span> + <span class="checked ui-icon ui-icon-notice"> + </span> + <span class="action-area {editMode}"> + <button class="cancel"></button> + </span> + <span class="action-area {viewMode}"> + <button class="edit"></button> + <button class="delete"></button> + </span> + <div> +</script> <script id="disk-row-tmpl" type="text/html"> <div class="item" id="cdrom-{dev}"> <span class="cell dev"> @@ -237,7 +263,7 @@ </span> </div> </script> -<script id="permission-item" type="text/html"> +<script id="permission-item-pam" type="text/html"> <div class="item"> <span class="icon {class}"></span> <label>{val}</label> -- 1.8.3.2

From: Royce Lv <lvroyce@linux.vnet.ibm.com> Update api for ldap user query, also adopt guest edit permission, validate user when change permission, add notice icon to indicate invalid user input. Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- ui/js/src/kimchi.api.js | 13 +++- ui/js/src/kimchi.guest_edit_main.js | 146 ++++++++++++++++++++++++++++++------ 2 files changed, 131 insertions(+), 28 deletions(-) diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index ebf826b..1483b02 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -1087,14 +1087,21 @@ var kimchi = { }); }, - getHostUsers : function(suc, err) { + getHostUsers : function(usr_data, suc, err) { + var usr = usr_data ? '?_user_id='+usr_data.user_id : ''; + var handler = function(data) { + if (usr_data) { + data['_kimchi_user'] = usr_data.user_id; + } + suc(data); + } kimchi.requestJSON({ - url : kimchi.url + 'host/users', + url : kimchi.url + 'host/users' + usr, type : 'GET', contentType : 'application/json', dataType : 'json', resend : true, - success : suc, + success : handler, error : err ? err : function(data) { kimchi.message.error(data.responseJSON.reason); } diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js index ed8c689..701c101 100644 --- a/ui/js/src/kimchi.guest_edit_main.js +++ b/ui/js/src/kimchi.guest_edit_main.js @@ -42,7 +42,6 @@ kimchi.guest_edit_main = function() { }, function(storages) { var container = $('#form-guest-edit-storage .body'); $(container).empty(); - $.each(storages, function(index, storage) { storage['vm'] = kimchi.selectedGuest; rowHTML = $('#' + storage['type'] + '-row-tmpl').html(); @@ -258,25 +257,108 @@ kimchi.guest_edit_main = function() { }; var setupPermission = function() { + //set up for LDAP + $(".add", "#form-guest-edit-permission").button({ + icons: { primary: "ui-icon-plusthick" }, + text: false + }).click(function(evt){ + evt.preventDefault(); + addItem({ + user: "", + freeze: false, + viewMode: "hide", + editMode: "", + checked: true + }); + }); + var addItem = function(data) { + var itemNode = $.parseHTML(kimchi.substitute($('#ldap-user-tmpl').html(),data)); + $(".body", "#form-guest-edit-permission .ldap").append(itemNode); + $(".edit", itemNode).button({ + disabled: data.freeze, + icons: { primary: "ui-icon-pencil" }, + text: false + }).click(function(evt){ + evt.preventDefault(); + toggleEdit($(this).parent().parent(), true); + }); + $(".delete", itemNode).button({ + icons: { primary: "ui-icon-trash" }, + text: false + }).click(function(evt){ + evt.preventDefault(); + var item = $(this).parent().parent(); + item.remove(); + }); + $("input").focusout(function() { + var item = $(this).parent().parent(); + var user= $(this).val(); + item.prop("id", user); + $("label", item).text(user); + toggleEdit(item, false); + }); + if (data.checked == true) { + $(".checked", itemNode).addClass("hide"); + } + $(".cancel", itemNode).button({ + icons: { primary: "ui-icon-arrowreturnthick-1-w" }, + text: false + }).click(function(evt){ + evt.preventDefault(); + var item = $(this).parent().parent(); + $("label", item).text()==="" ? item.remove() : toggleEdit(item, false); + }); + }; + var toggleEdit = function(item, on){ + $("label", item).toggleClass("hide", on); + $("input", item).toggleClass("hide", !on); + $(".action-area", item).toggleClass("hide"); + }; + //set up for PAM var userNodes = {}, groupNodes = {}; - kimchi.retrieveVM(kimchi.selectedGuest, function(vm){ - kimchi.getHostUsers(function(users){ - kimchi.getHostGroups(function(groups){ - var subArray = function(a1, a2){ //a1-a2 - for(var i=0; i<a2.length; i++){ - for(var j=0; j<a1.length; j++){ - if(a2[i] == a1[j]){ - a1.splice(j, 1); - break; + var authType = 'ldap'; + if (authType == 'pam') { + kimchi.retrieveVM(kimchi.selectedGuest, function(vm){ + kimchi.getHostUsers(undefined, function(users){ + kimchi.getHostGroups(function(groups){ + var subArray = function(a1, a2){ //a1-a2 + for(var i=0; i<a2.length; i++){ + for(var j=0; j<a1.length; j++){ + if(a2[i] == a1[j]){ + a1.splice(j, 1); + break; + } } } - } - }; - subArray(users, vm.users); subArray(groups, vm.groups); - init(users, groups, vm.users, vm.groups); + }; + subArray(users, vm.users); subArray(groups, vm.groups); + init(users, groups, vm.users, vm.groups); + }); }); }); - }); + } + else if (authType == 'ldap') { + kimchi.retrieveVM(kimchi.selectedGuest, function(vm){ + for (var i=0; i<vm.users.length; i++) { + var user = {'user_id' :vm.users[i]}; + kimchi.getHostUsers(user, function(data) { + addItem({ + user: data._kimchi_user, + viewMode: "", + freeze: true, + editMode: "hide", + checked: true}); + }, function (data) { + addItem({ + user: data._kimchi_user, + viewMode: "", + freeze: true, + editMode: "hide", + checked: false}); + }); + } + }); + } var sortNodes = function(container, isUser){ nodes = container.children(); var keys = []; @@ -296,7 +378,7 @@ kimchi.guest_edit_main = function() { var init = function(availUsers, availGroups, selUsers, selGroups){ var initNode = function(key, isUserNode){ var nodeGroups = isUserNode ? userNodes : groupNodes; - nodeGroups[key] = $.parseHTML(kimchi.substitute($('#permission-item').html(), { + nodeGroups[key] = $.parseHTML(kimchi.substitute($('#permission-item-pam').html(), { val: key, class: isUserNode? "user-icon" : "group-icon" })); @@ -534,16 +616,30 @@ kimchi.guest_edit_main = function() { } var permissionSubmit = function(event) { + var authType = 'ldap'; var content = { users: [], groups: [] }; - $("#permission-sel-users").children().each(function(){ - content.users.push($("label", this).text()); - }); - $("#permission-sel-groups").children().each(function(){ - content.groups.push($("label", this).text()); - }); - kimchi.updateVM(kimchi.selectedGuest, content, function(){ - kimchi.window.close(); - }); + if (authType == 'pam') { + $("#permission-sel-users").children().each(function(){ + content.users.push($("label", this).text()); + }); + $("#permission-sel-groups").children().each(function(){ + content.groups.push($("label", this).text()); + }); + } + else if (authType == 'ldap') { + $(".body","#form-guest-edit-permission .ldap").children().each(function () { + var user = {'user_id': $(this).attr("id")}; + var tmp = $(this); + kimchi.getHostUsers(user, function(data) { + }, function (data) { + $(".checked", tmp).removeClass("hide"); + }); + content.users.push($(this).attr("id")); + }); + kimchi.updateVM(kimchi.selectedGuest, content, function(){ + kimchi.window.close(); + }); + } } // tap map, "general": 0, "storage": 1, "interface": 2, "permission": 3, "password": 4 -- 1.8.3.2

Following is the LDAP and PAM interfaces: My suggestion is to keep the same UI layout used by PAM authentication. The difference will be: - Remove the groups columns on LDAP - And display the users list empty in a first moment - The filter will be used only for search LDAP users - Aside the text input we should add a new button "Search" - Once the "Search" button is selected we update the users list below with the returned data - Then user can select how many users he want to assign to the VM and the same way we did for PAM. On 11/05/2014 08:21 AM, lvroyce@linux.vnet.ibm.com wrote:
From: Royce Lv <lvroyce@linux.vnet.ibm.com>
Users added will be validated when press save permission button, invalid user will be labled as notice icon. update vm request with invalid user will be rejected. only user tag is supported for ldap. This is tested agaist ldap integration v2.
Note: Due to capabilities query of authentication type is not added. This patch simply hided PAM permission tag part. Will address this issue after backend changed.
Royce Lv (2): UI: support ldap vm permission tag Change guest edit permission logic
ui/css/theme-default/guest-edit.css | 79 ++++++++++++++----- ui/js/src/kimchi.api.js | 13 +++- ui/js/src/kimchi.guest_edit_main.js | 146 ++++++++++++++++++++++++++++++------ ui/pages/guest-edit.html.tmpl | 28 ++++++- 4 files changed, 218 insertions(+), 48 deletions(-)
participants (2)
-
Aline Manera
-
lvroyce@linux.vnet.ibm.com