[PATCHv3 0/2] UI: LDAP integration of VM permission

From: Royce Lv <lvroyce@linux.vnet.ibm.com> v1>v3, Delete useless elements according to YuXin's comments. Royce Lv (2): UI: support ldap vm permission tag Change guest edit permission logic ui/css/theme-default/guest-edit.css | 81 +++++++--- ui/js/src/kimchi.api.js | 15 +- ui/js/src/kimchi.guest_edit_main.js | 289 ++++++++++++++++++++++++------------ ui/pages/guest-edit.html.tmpl | 22 ++- 4 files changed, 284 insertions(+), 123 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 | 81 ++++++++++++++++++++++++++++--------- ui/pages/guest-edit.html.tmpl | 22 +++++++++- 2 files changed, 83 insertions(+), 20 deletions(-) diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css index b1d3931..80e061f 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,116 @@ 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 { + 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 512909a..327098a 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"> <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,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" 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"> @@ -237,7 +257,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 | 15 +- ui/js/src/kimchi.guest_edit_main.js | 289 ++++++++++++++++++++++++------------ 2 files changed, 201 insertions(+), 103 deletions(-) diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 78c6d66..d868a4a 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 + '/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); } @@ -1103,7 +1110,7 @@ var kimchi = { getHostGroups : 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 9d87a73..ad0c976 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,107 +256,180 @@ kimchi.guest_edit_main = function() { }; var setupPermission = function() { - 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; - } - } - } - }; - subArray(users, vm.users); subArray(groups, vm.groups); - init(users, groups, vm.users, vm.groups); - }); + //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 sortNodes = function(container, isUser){ - nodes = container.children(); - var keys = []; - nodes.each(function(){ - keys.push($("label", this).text()); + 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(); }); - keys.sort(); - container.empty(); - for(var i=0; i<keys.length; i++){ - var itemNode = isUser ? userNodes[keys[i]] : groupNodes[keys[i]]; - $(itemNode).click(function(){ - $(this).toggleClass("item-picked"); - }); - container.append(itemNode); + $("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 init = function(availUsers, availGroups, selUsers, selGroups){ - var initNode = function(key, isUserNode){ - var nodeGroups = isUserNode ? userNodes : groupNodes; - nodeGroups[key] = $.parseHTML(kimchi.substitute($('#permission-item').html(), { - val: key, - class: isUserNode? "user-icon" : "group-icon" - })); - }; - for(var i=0; i<availUsers.length; i++){ - initNode(availUsers[i], true); - $("#permission-avail-users").append(userNodes[availUsers[i]]); - sortNodes($("#permission-avail-users"), true); + 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.getCapabilities(function(result) { + authType = result.auth; + if (authType == 'pam') { + $("#form-guest-edit-permission .ldap").hide(); + 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); + }); + }); + }); } - for(var i=0; i<selUsers.length; i++){ - initNode(selUsers[i], true); - $("#permission-sel-users").append(userNodes[selUsers[i]]); - sortNodes($("#permission-sel-users"), true); + 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++) { + 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}); + }); + } + }); } - for(var i=0; i<availGroups.length; i++){ - initNode(availGroups[i], false); - $("#permission-avail-groups").append(groupNodes[availGroups[i]]); - sortNodes($("#permission-avail-groups"), false); + var sortNodes = function(container, isUser){ + nodes = container.children(); + var keys = []; + nodes.each(function(){ + keys.push($("label", this).text()); + }); + keys.sort(); + container.empty(); + for(var i=0; i<keys.length; i++){ + var itemNode = isUser ? userNodes[keys[i]] : groupNodes[keys[i]]; + $(itemNode).click(function(){ + $(this).toggleClass("item-picked"); + }); + container.append(itemNode); + } + }; + var init = function(availUsers, availGroups, selUsers, selGroups){ + var initNode = function(key, isUserNode){ + var nodeGroups = isUserNode ? userNodes : groupNodes; + nodeGroups[key] = $.parseHTML(kimchi.substitute($('#permission-item-pam').html(), { + val: key, + class: isUserNode? "user-icon" : "group-icon" + })); + }; + for(var i=0; i<availUsers.length; i++){ + initNode(availUsers[i], true); + $("#permission-avail-users").append(userNodes[availUsers[i]]); + sortNodes($("#permission-avail-users"), true); + } + for(var i=0; i<selUsers.length; i++){ + initNode(selUsers[i], true); + $("#permission-sel-users").append(userNodes[selUsers[i]]); + sortNodes($("#permission-sel-users"), true); + } + for(var i=0; i<availGroups.length; i++){ + initNode(availGroups[i], false); + $("#permission-avail-groups").append(groupNodes[availGroups[i]]); + sortNodes($("#permission-avail-groups"), false); + } + for(var i=0; i<selGroups.length; i++){ + initNode(selGroups[i], false); + $("#permission-sel-groups").append(groupNodes[selGroups[i]]); + sortNodes($("#permission-sel-groups"), false); + } + }; + var filterNodes = function(key, container){ + container.children().each(function(){ + $(this).css("display", $("label", this).text().indexOf(key)==-1 ? "none" : ""); + }); } - for(var i=0; i<selGroups.length; i++){ - initNode(selGroups[i], false); - $("#permission-sel-groups").append(groupNodes[selGroups[i]]); + $("#permission-avail-searchBox").on("keyup", function() { + var key = $(this).val(); + filterNodes(key, $("#permission-avail-users")); + filterNodes(key, $("#permission-avail-groups")); + }); + $("#permission-sel-searchBox").on("keyup", function() { + var key = $(this).val(); + filterNodes(key, $("#permission-sel-users")); + filterNodes(key, $("#permission-sel-groups")); + }); + $('#permissionGo').button().click(function(evt) { + evt.preventDefault(); + $("#permission-avail-users").children(".item-picked").appendTo("#permission-sel-users").removeClass("item-picked"); + sortNodes($("#permission-sel-users"), true); + $("#permission-avail-groups").children(".item-picked").appendTo("#permission-sel-groups").removeClass("item-picked"); sortNodes($("#permission-sel-groups"), false); - } - }; - var filterNodes = function(key, container){ - container.children().each(function(){ - $(this).css("display", $("label", this).text().indexOf(key)==-1 ? "none" : ""); + $("#permission-sel-searchBox").val(""); + filterNodes("", $("#permission-sel-users")); + filterNodes("", $("#permission-sel-groups")); + }); + $('#permissionBack').button().click(function(evt) { + evt.preventDefault(); + $("#permission-sel-users").children(".item-picked").appendTo("#permission-avail-users").removeClass("item-picked"); + sortNodes($("#permission-avail-users"), true); + $("#permission-sel-groups").children(".item-picked").appendTo("#permission-avail-groups").removeClass("item-picked"); + sortNodes($("#permission-avail-groups"), false); + $("#permission-avail-searchBox").val(""); + filterNodes("", $("#permission-avail-users")); + filterNodes("", $("#permission-avail-groups")); }); - } - $("#permission-avail-searchBox").on("keyup", function() { - var key = $(this).val(); - filterNodes(key, $("#permission-avail-users")); - filterNodes(key, $("#permission-avail-groups")); - }); - $("#permission-sel-searchBox").on("keyup", function() { - var key = $(this).val(); - filterNodes(key, $("#permission-sel-users")); - filterNodes(key, $("#permission-sel-groups")); - }); - $('#permissionGo').button().click(function(evt) { - evt.preventDefault(); - $("#permission-avail-users").children(".item-picked").appendTo("#permission-sel-users").removeClass("item-picked"); - sortNodes($("#permission-sel-users"), true); - $("#permission-avail-groups").children(".item-picked").appendTo("#permission-sel-groups").removeClass("item-picked"); - sortNodes($("#permission-sel-groups"), false); - $("#permission-sel-searchBox").val(""); - filterNodes("", $("#permission-sel-users")); - filterNodes("", $("#permission-sel-groups")); - }); - $('#permissionBack').button().click(function(evt) { - evt.preventDefault(); - $("#permission-sel-users").children(".item-picked").appendTo("#permission-avail-users").removeClass("item-picked"); - sortNodes($("#permission-avail-users"), true); - $("#permission-sel-groups").children(".item-picked").appendTo("#permission-avail-groups").removeClass("item-picked"); - sortNodes($("#permission-avail-groups"), false); - $("#permission-avail-searchBox").val(""); - filterNodes("", $("#permission-avail-users")); - filterNodes("", $("#permission-avail-groups")); }); - }; - + } var setupPCIDevice = function(){ kimchi.getHostPCIDevices(function(hostPCIs){ kimchi.getVMPCIDevices(kimchi.selectedGuest, function(vmPCIs){ @@ -531,14 +604,32 @@ 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(); + kimchi.getCapabilities(function(result) { + authType = result.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()); + }); + } + 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) { + $("label", tmp).toggleClass("hide", false); + $("input", tmp).toggleClass("hide", true); + }, function (data) { + $("input", tmp).addClass("checked"); + }); + content.users.push($(this).attr("id")); + }); + } + kimchi.updateVM(kimchi.selectedGuest, content, function(){ + kimchi.window.close(); + }); }); } -- 1.8.3.2
participants (1)
-
lvroyce@linux.vnet.ibm.com