diff --git a/src/cli/oneuser b/src/cli/oneuser index e3501b0439..1041b01e64 100755 --- a/src/cli/oneuser +++ b/src/cli/oneuser @@ -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 diff --git a/src/oca/ruby/opennebula/user_pool.rb b/src/oca/ruby/opennebula/user_pool.rb index 86f916bfcb..34ac33f067 100644 --- a/src/oca/ruby/opennebula/user_pool.rb +++ b/src/oca/ruby/opennebula/user_pool.rb @@ -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 diff --git a/src/sunstone/public/app/tabs/users-tab/datatable.js b/src/sunstone/public/app/tabs/users-tab/datatable.js index c910b61627..a0f16f6110 100644 --- a/src/sunstone/public/app/tabs/users-tab/datatable.js +++ b/src/sunstone/public/app/tabs/users-tab/datatable.js @@ -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 += '