1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-23 22:50:09 +03:00

Merge remote-tracking branch 'origin/feature-4614'

This commit is contained in:
Carlos Martín 2016-07-01 12:21:01 +02:00
commit 3637812d38
7 changed files with 164 additions and 10 deletions

View File

@ -516,4 +516,18 @@ cmd=CommandParser::CmdParser.new(ARGV) do
0
end
passwdsearch_desc = <<-EOT.unindent
Searches for users with a specific auth driver that has the given
string in their password field
EOT
command :passwdsearch, passwdsearch_desc, :driver, :password,
:options=>[CLIHelper::CSV_OPT, OpenNebulaHelper::XML] do
options[:list] = ["ID", "NAME", "AUTH", "PASSWORD"]
options[:filter] = ["AUTH=#{args[0]}", "PASSWORD=#{args[1]}"]
helper.list_pool(options)
end
end

View File

@ -51,5 +51,27 @@ module OpenNebula
end
alias_method :info!, :info
#######################################################################
# Helpers to get information
#######################################################################
# Returns a list of user IDs that have the given password. info() needs
# to be called before.
#
# @param driver [String] auth driver to match
# @param password [String] password to match
# @return [Array] an array of IDs
def users_with_password(driver, password)
ids = []
each do |user|
if user["PASSWORD"] == password
ids << user["ID"]
end
end
return ids
end
end
end

View File

@ -26,6 +26,7 @@ define(function(require) {
var QuotaWidgets = require('utils/quotas/quota-widgets');
var TemplateUtils = require('utils/template-utils');
var LabelsUtils = require('utils/labels/utils');
var SearchDropdown = require('hbs!./datatable/search');
/*
CONSTANTS
@ -86,6 +87,8 @@ define(function(require) {
this.totalUsers = 0;
this.conf.searchDropdownHTML = SearchDropdown();
TabDataTable.call(this);
}
@ -94,6 +97,7 @@ define(function(require) {
Table.prototype.elementArray = _elementArray;
Table.prototype.preUpdateView = _preUpdateView;
Table.prototype.postUpdateView = _postUpdateView;
Table.prototype.setupSearch = _setupSearch;
return Table;
@ -101,6 +105,58 @@ define(function(require) {
FUNCTION DEFINITIONS
*/
function _setupSearch(context) {
var that = this;
$(".pass-search", context).on('input', function(){
var val = $(".pass-search", context).val();
if(val == undefined || val == ""){
$("button.search-dropdown", context).addClass("hollow");
} else {
$("button.search-dropdown", context).removeClass("hollow");
}
that.dataTable.fnDraw(true);
}).on("keyup keypress", function(e) {
var code = e.keyCode || e.which;
if (code == 13) {
$("button.advanced-search", context).click();
}
});
$("a.advanced-search-clear", context).on('click', function(){
$(".pass-search", context).val("").trigger("input");
$("button.advanced-search", context).click();
});
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
// This is a global search function, we need to apply it only if the
// search is triggered for the current table
if(that.dataTableId != settings.nTable.id){
return true;
}
var val = $(".pass-search", context).val();
if(val == undefined || val == ""){
return true;
}
try {
var pass = $("input.check_item", that.dataTable.fnGetNodes(dataIndex)).attr("password64");
pass = atob(pass);
return pass == val;
} catch (err) {}
return true;
}
);
}
function _elementArray(element_json) {
this.totalUsers++;
@ -134,10 +190,13 @@ define(function(require) {
// Build hidden user template
var hidden_template = TemplateUtils.templateToString(element);
this.passwordList += '<option value="' + element.PASSWORD + '">'
return [
'<input class="check_item" type="checkbox" id="'+RESOURCE.toLowerCase()+'_' +
element.ID + '" name="selected_items" value="' +
element.ID + '"/>',
element.ID + '" name="selected_items" ' +
'value="' + element.ID + '" ' +
'password64="' + btoa(element.PASSWORD) + '"/>',
element.ID,
element.NAME,
element.GNAME,
@ -153,9 +212,12 @@ define(function(require) {
function _preUpdateView() {
this.totalUsers = 0;
this.passwordList = "";
}
function _postUpdateView() {
$(".total_users").text(this.totalUsers);
$("#userSearchPasswordList", $("#"+TAB_NAME)).html(this.passwordList);
}
});

View File

@ -0,0 +1,10 @@
<div class="row">
<div class="small-12 columns">
<label>
{{tr "Password"}}
<input class="pass-search" type="text" list="userSearchPasswordList"/>
<datalist id="userSearchPasswordList">
</datalist>
</label>
</div>
</div>

View File

@ -90,6 +90,8 @@ define(function(require) {
buttons. By default it will be the parent tab
'customTrListener': function executed when a tr is clicked. Arguments
are (tableObj, tr)
'searchDropdownHTML': optional HTML to place inside a dropdown next to
the search input
}
1. The table HTML is returned calling the table.dataTableHTML attr
@ -144,7 +146,10 @@ define(function(require) {
'conf': this.conf,
'selectOptions': this.selectOptions});
that.searchInputHTML = TemplateSearchInputHTML({'dataTableSearchId': this.dataTableId + 'Search'});
that.searchInputHTML = TemplateSearchInputHTML({
'dataTableSearchId': this.dataTableId + 'Search',
'searchDropdownHTML': this.conf.searchDropdownHTML
});
return that;
}
@ -212,6 +217,18 @@ define(function(require) {
return false;
});
if(that.conf.searchDropdownHTML != undefined){
var context = $('#' + this.dataTableId + 'Search-wrapper');
that.setupSearch(context);
$("button.advanced-search", context).on('click', function(){
$('#' + that.dataTableId + 'Search-dropdown', context).foundation('close');
that.dataTable.fnDraw(true);
return false;
});
}
this.dataTable.on('draw.dt', function() {
that.recountCheckboxes();
})
@ -243,6 +260,8 @@ define(function(require) {
if (this.conf.select) {
that.dataTable.fnSetColumnVis(0, false);
}
Foundation.reflow($('#' + this.dataTableId + 'Search-dropdown'), 'dropdown');
}
function _defaultTrListener(tableObj, tr) {
@ -508,6 +527,10 @@ define(function(require) {
}
}
if(that.conf.searchDropdownHTML != undefined){
this.dataTable.fnDraw(true);
}
if (that.postUpdateView) {
that.postUpdateView();
}

View File

@ -14,4 +14,29 @@
{{! limitations under the License. }}
{{! -------------------------------------------------------------------------- }}
{{#if searchDropdownHTML}}
<div id="{{dataTableSearchId}}-wrapper" class="input-group">
<input class="input-group-field" id="{{dataTableSearchId}}" type="search" placeholder="{{tr "Search"}}" />
<div class="input-group-button">
<button type="button" class="button search-dropdown hollow secondary" data-toggle="{{dataTableSearchId}}-dropdown">
<i class="fa fa-fw fa-caret-down"/>
</button>
</div>
<div class="dropdown-pane left" id="{{dataTableSearchId}}-dropdown" data-dropdown data-auto-focus="true" style="width:500px">
{{{searchDropdownHTML}}}
<div class="row">
<div class="small-12 columns">
<button type="button" class="button advanced-search">
<i class="fa fa-fw fa-search"/>
</button>
<a class="advanced-search-clear right">{{tr "Clear search"}}</a>
</div>
</div>
<button class="close-button" data-close aria-label="{{tr "Close"}}" type="button">
<span aria-hidden="true">&times;</span>
</button>
</div>
</div>
{{else}}
<input id="{{dataTableSearchId}}" type="search" placeholder="{{tr "Search"}}" />
{{/if}}

View File

@ -66,13 +66,6 @@ table {
}
}
.dataTableSearchRow {
input[type="search"],
.button {
margin-bottom: 0;
}
}
.select-resources {
.refresh-table {
margin-top: 0.5rem;
@ -88,3 +81,8 @@ table{
span .fa-times:hover {
cursor: pointer;
}
button.search-dropdown {
box-shadow: none !important;
border-style: none !important;
}