
v1 > v2, Change according to LDAP backend api change. v2 > v3, Change alert icon to red border of input box to be more clear, commented by YuXin v3 > v4, Fix alignment and use place holder to inform user what to fill. commented by Aline. v4 > v5, Use cached capabilities values and rename functions Royce Lv (2): UI: support ldap vm permission tag Change guest edit permission logic ui/css/theme-default/guest-edit.css | 94 ++++++++++++++++-------- ui/js/src/kimchi.api.js | 23 ++++-- ui/js/src/kimchi.guest_edit_main.js | 140 +++++++++++++++++++++++++++++------- ui/pages/guest-edit.html.tmpl | 22 +++++- 4 files changed, 217 insertions(+), 62 deletions(-) -- 1.9.3

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 | 94 +++++++++++++++++++++++++------------ ui/pages/guest-edit.html.tmpl | 22 ++++++++- 2 files changed, 85 insertions(+), 31 deletions(-) diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css index 74d72f2..eb8ede4 100644 --- a/ui/css/theme-default/guest-edit.css +++ b/ui/css/theme-default/guest-edit.css @@ -28,8 +28,7 @@ padding: 0; } -#form-guest-edit-general, -#form-guest-edit-storage { +#form-guest-edit-general { padding: 1em; } @@ -97,7 +96,8 @@ #form-guest-edit-storage .header, .guest-edit-snapshot .header, -.guest-edit-interface .header { +.guest-edit-interface .header, +#form-guest-edit-permission .ldap .header { margin-bottom: 8px; padding-bottom: 2px; font-weight: bold; @@ -123,7 +123,7 @@ } .guest-edit-snapshot .sel { - width: 35px; + width: 25px; vertical-align: top; } @@ -180,12 +180,6 @@ height: 20px; } -#form-guest-edit-storage .header button, -.guest-edit-snapshot .header button, -.guest-edit-interface .header button { - margin-bottom: 1px; -} - #form-guest-edit-storage .body button:not(:last-child), .guest-edit-interface .body button:not(:last-child) { margin-right: 2px; @@ -196,27 +190,31 @@ display: none!important; } -.guest-edit-permission { +.guest-edit-permission .pam { height: 240px; 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; @@ -224,77 +222,113 @@ 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 .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 input[type="text"] { + width: 300px; +} + +#form-guest-edit-permission .ldap .header button { + margin-bottom: 1px; +} + +#form-guest-edit-permission .ldap .checked { + border-color: red; + border-style: solid; + border-width: 1px; +} + +#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 e1626a0..9db1e1c 100644 --- a/ui/pages/guest-edit.html.tmpl +++ b/ui/pages/guest-edit.html.tmpl @@ -115,6 +115,7 @@ <div class="body"></div> </form> <form id="form-guest-edit-permission" class="guest-edit-permission"> + <div class="pam"> <div class="column avail"> <div class="title">$_("Available system users and groups")</div> <input type="text" id="permission-avail-searchBox"> @@ -143,6 +144,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"> @@ -231,6 +240,17 @@ </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" placeholder="LDAP User ID,e.g.foo@foo.com" class="{editMode}"/> + </span> + <span class="action-area"> + <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"> @@ -250,7 +270,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.9.3

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 | 23 ++++-- ui/js/src/kimchi.guest_edit_main.js | 140 +++++++++++++++++++++++++++++------- 2 files changed, 132 insertions(+), 31 deletions(-) diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 67ef1e4..2abe8f5 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -1087,9 +1087,24 @@ var kimchi = { }); }, - getHostUsers : function(suc, err) { + getUserById : function(data, suc, err) { kimchi.requestJSON({ - url : kimchi.url + 'host/users', + url : kimchi.url + 'users?_user_id=' + data.user_id, + type : 'GET', + contentType : 'application/json', + dataType : 'json', + resend : true, + async : false, + success : suc && suc(data), + error : err ? err : function(data) { + kimchi.message.error(data.responseJSON.reason); + } + }); + }, + + getUsers : function(suc, err) { + kimchi.requestJSON({ + url : kimchi.url + 'users', type : 'GET', contentType : 'application/json', dataType : 'json', @@ -1101,9 +1116,9 @@ var kimchi = { }); }, - getHostGroups : function(suc, err) { + getGroups : function(suc, err) { kimchi.requestJSON({ - url : kimchi.url + 'host/groups', + url : kimchi.url + 'groups', type : 'GET', contentType : 'application/json', dataType : 'json', diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js index e033743..dcd525d 100644 --- a/ui/js/src/kimchi.guest_edit_main.js +++ b/ui/js/src/kimchi.guest_edit_main.js @@ -35,6 +35,7 @@ kimchi.guest_edit_main = function() { var guestEditForm = $('#form-guest-edit-general'); var saveButton = $('#guest-edit-button-save'); + var authType; var refreshCDROMs = function() { kimchi.listVMStorages({ @@ -42,7 +43,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(); @@ -256,25 +256,86 @@ 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); + $(".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); + }); + $("input").focusin(function() { + $(this).removeClass("checked"); + }); + + if (data.checked == true) { + $(".checked", itemNode).addClass("hide"); + } + }; + 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; + authType = kimchi.capabilities['auth'] + if (authType == 'pam') { + $("#form-guest-edit-permission .ldap").hide(); + kimchi.retrieveVM(kimchi.selectedGuest, function(vm){ + kimchi.getUsers(function(users){ + kimchi.getGroups(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') { + $("#form-guest-edit-permission .pam").hide(); + kimchi.retrieveVM(kimchi.selectedGuest, function(vm){ + for (var i=0; i<vm.users.length; i++) { + addItem({ + user: vm.users[i], + viewMode: "", + freeze: true, + editMode: "hide", + checked: true}); + } + }); + } var sortNodes = function(container, isUser){ nodes = container.children(); var keys = []; @@ -294,7 +355,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" })); @@ -355,8 +416,7 @@ kimchi.guest_edit_main = function() { filterNodes("", $("#permission-avail-users")); filterNodes("", $("#permission-avail-groups")); }); - }; - + } var setupPCIDevice = function(){ kimchi.getHostPCIDevices(function(hostPCIs){ kimchi.getVMPCIDevices(kimchi.selectedGuest, function(vmPCIs){ @@ -637,15 +697,41 @@ kimchi.guest_edit_main = function() { var permissionSubmit = function(event) { 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(); - }); + authType = kimchi.capabilities['auth'] + 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()); + }); + kimchi.updateVM(kimchi.selectedGuest, content, function(){ + kimchi.window.close(); + }); + } else if (authType == 'ldap') { + $(saveButton).prop('disabled', true); + var errors = 0; + + $(".body", "#form-guest-edit-permission .ldap").children().each(function () { + var elem = $(this); + content.users.push(elem.attr("id")); + + if (!$('input', elem).hasClass('hide')) { + var user = {'user_id': $(this).attr("id")}; + kimchi.getUserById(user, null, function (data) { + errors += 1; + $("input", elem).addClass("checked"); + }); + } + }); + if (errors == 0) { + kimchi.updateVM(kimchi.selectedGuest, content, function(){ + kimchi.window.close(); + }); + } else { + $(saveButton).prop('disabled', false); + } + } } // tap map, "general": 0, "storage": 1, "interface": 2, "permission": 3, "password": 4 -- 1.9.3

The tab "Permission" added an unnecessary scroll bar to the left. In previous commits*, that scroll bar didn't exist. Check the attached image. I'm using Chrome 39.0.2171.71 (64-bit) on Fedora 20. * Actually, the command "GET /host/users" is not working here since commit 5846a81 ("Split users and groups for permission query") with the message "Nothing matches the given URI" (404), so the tab "Permission" is empty in the current master branch, without applying this patchset. Even with that empty list or with a filled list (from commits prior to that one), that scroll bar didn't exist, so it's been added by this patchset. On 26-11-2014 15:17, Aline Manera wrote:
v1 > v2, Change according to LDAP backend api change. v2 > v3, Change alert icon to red border of input box to be more clear, commented by YuXin v3 > v4, Fix alignment and use place holder to inform user what to fill. commented by Aline. v4 > v5, Use cached capabilities values and rename functions
Royce Lv (2): UI: support ldap vm permission tag Change guest edit permission logic
ui/css/theme-default/guest-edit.css | 94 ++++++++++++++++-------- ui/js/src/kimchi.api.js | 23 ++++-- ui/js/src/kimchi.guest_edit_main.js | 140 +++++++++++++++++++++++++++++------- ui/pages/guest-edit.html.tmpl | 22 +++++- 4 files changed, 217 insertions(+), 62 deletions(-)
participants (2)
-
Aline Manera
-
Crístian Viana