From 78fc282233a22276b42f27d3cef787e65e957b18 Mon Sep 17 00:00:00 2001 From: Endi S. Dewata Date: Thu, 18 Nov 2010 20:17:14 -0600 Subject: [PATCH] SUDO Rule Search and Details Pages The search and details pages for SUDO Rule have been added. Codes that are shared with HBAC have been moved to rule.js. The following methods were renamed for consistency: - ipa_details_load() -> ipa_details_refresh() - ipa_details_display() -> ipa_details_load() The ipa_details_cache has been removed because the cache is now stored in each widget. The index.xhtml has been removed. All references to it has been changed to index.html. The Unselect All checkbox has been fixed. Unnecessary parameter 'container' has been removed. The unit test has been updated and new test data has been added. --- install/conf/ipa.conf | 2 +- install/static/Makefile.am | 2 + install/static/add.js | 6 +- install/static/associate.js | 21 +- install/static/certificate.js | 4 +- install/static/details.js | 173 +++++++------ install/static/entity.js | 11 +- install/static/hbac.js | 390 ++++++--------------------- install/static/hbacsvc.js | 5 +- install/static/hbacsvcgroup.js | 6 +- install/static/host.js | 4 +- install/static/index.html | 2 + install/static/policy.js | 28 +- install/static/rule.js | 246 +++++++++++++++++ install/static/search.js | 95 +++++-- install/static/service.js | 24 +- install/static/sudorule.js | 261 ++++++++++++++++++ install/static/test/data/batch.json | 33 +++- install/static/test/data/sudorule_find.json | 17 ++ install/static/test/data/sudorule_show.json | 72 +++++ install/static/test/details_tests.js | 10 +- install/static/user.js | 24 +- install/static/webui.js | 1 + install/static/widget.js | 139 +++++----- lite-server.py | 2 +- 25 files changed, 1029 insertions(+), 549 deletions(-) create mode 100755 install/static/rule.js create mode 100755 install/static/sudorule.js create mode 100644 install/static/test/data/sudorule_find.json create mode 100644 install/static/test/data/sudorule_show.json diff --git a/install/conf/ipa.conf b/install/conf/ipa.conf index d547b50d9d898a95ff2f627eebbb77584b17f01f..0bc53548f54c6c5cd0a5393086ccc7369b68b903 100644 --- a/install/conf/ipa.conf +++ b/install/conf/ipa.conf @@ -7,7 +7,7 @@ ProxyRequests Off #We use xhtml, a file format that the browser validates -DirectoryIndex index.xhtml +DirectoryIndex index.html diff --git a/install/static/Makefile.am b/install/static/Makefile.am index 795498934634849c53f37975a9fcb5910a5377eb..0e3effeef63ef4e0b1c8def6e3369480988880d6 100644 --- a/install/static/Makefile.am +++ b/install/static/Makefile.am @@ -28,8 +28,10 @@ app_DATA = \ netgroup.js \ service.js \ serverconfig.js \ + sudorule.js \ policy.js \ search.js \ + rule.js \ details.js \ entity.js \ webui.js \ diff --git a/install/static/add.js b/install/static/add.js index 4325857fb4233f9fb7b7e3e0df070a22ccae8208..d587b80d9525c26c5ad1ea73de3698366222f312 100644 --- a/install/static/add.js +++ b/install/static/add.js @@ -41,7 +41,7 @@ function ipa_add_dialog(spec) { var entity = IPA.get_entity(that.entity_name); var facet = entity.get_facet('search'); var table = facet.table; - table.refresh(that.container); + table.refresh(); that.close(); } ); @@ -56,8 +56,8 @@ function ipa_add_dialog(spec) { var entity = IPA.get_entity(that.entity_name); var facet = entity.get_facet('search'); var table = facet.table; - table.refresh(that.container); - that.clear(that.container); + table.refresh(); + that.clear(); } ); }); diff --git a/install/static/associate.js b/install/static/associate.js index 7dd81caec0cecca1d8297e2f083af917a5acf807..f0239a44e12670f5399d9dd30c99a5e553a2aba0 100644 --- a/install/static/associate.js +++ b/install/static/associate.js @@ -257,7 +257,10 @@ function ipa_association_widget(spec) { that.superior_create(container); - var ul = $('.action-panel ul'); + var entity_container = $('#' + that.entity_name); + var action_panel = $('.action-panel', entity_container); + + var ul = $('ul', action_panel); var li = $('
  • ').appendTo(ul); // creating generic buttons for layout @@ -324,11 +327,11 @@ function ipa_association_widget(spec) { 'associator': that.associator, 'method': that.add_method, 'on_success': function() { - that.refresh(that.container); + that.refresh(); dialog.close(); }, 'on_error': function() { - that.refresh(that.container); + that.refresh(); dialog.close(); } }); @@ -360,11 +363,11 @@ function ipa_association_widget(spec) { 'associator': that.associator, 'method': that.delete_method, 'on_success': function() { - that.refresh(that.container); + that.refresh(); dialog.close(); }, 'on_error': function() { - that.refresh(that.container); + that.refresh(); dialog.close(); } }); @@ -374,7 +377,7 @@ function ipa_association_widget(spec) { dialog.open(that.container); }; - that.refresh = function(container) { + that.refresh = function() { function on_success(data, text_status, xhr) { @@ -390,7 +393,7 @@ function ipa_association_widget(spec) { for (var i = 0; i tags i.e. all attribute values */ $('dd', that.container).remove(); @@ -67,8 +71,8 @@ function ipa_details_field(spec) { var rights = 'rsc'; - if (result.attributelevelrights){ - rights = result.attributelevelrights[this.name] || rights ; + if (that.record.attributelevelrights){ + rights = that.record.attributelevelrights[this.name] || rights ; } if (that.values) { @@ -100,9 +104,9 @@ function ipa_details_field(spec) { dd.appendTo(that.container); } } - } + }; - function save(container) { + function save() { var values = []; $('dd', that.container).each(function () { @@ -219,7 +223,7 @@ function ipa_details_section(spec){ that.setup = function(container) { - this.container = container; + that.container = container; if (that.template) return; @@ -245,7 +249,7 @@ function ipa_details_section(spec){ var field = fields[i]; var span = $('span[name='+field.name+']', this.container).first(); field.setup(span); - field.load(span, result); + field.load(result); } } ); @@ -255,7 +259,7 @@ function ipa_details_section(spec){ for (var j=0; j', { 'class': 'content' }).appendTo(container); + var entity_container = $('#' + that.entity_name); + var action_panel = $('.action-panel', entity_container); + + var ul = $('ul', action_panel); var buttons = $('
  • ', { 'class': 'details-buttons' - }).prependTo($('.action-panel ul')); + }).prependTo(ul); - buttons.append(ipa_button({ - 'label': 'Reset', - 'icon': 'ui-icon-refresh', - 'class': 'details-reset', - 'click': function() { - facet.reset(container); - return false; - } - })); + $('', { + 'type': 'text', + 'name': 'reset' + }).appendTo(buttons); - var pkey_name = IPA.metadata[facet.entity_name].primary_key; - - buttons.append(ipa_button({ - 'label': 'Update', - 'icon': 'ui-icon-check', - 'class': 'details-update', - 'click': function() { - facet.update(container, ipa_details_cache[facet.entity_name][pkey_name][0]); - return false; - } - })); + $('', { + 'type': 'text', + 'name': 'update' + }).appendTo(buttons); details.append('
    '); details.append('
    '); - for (var i = 0; i < facet.sections.length; ++i) { - var section = facet.sections[i]; + for (var i = 0; i < that.sections.length; ++i) { + var section = that.sections[i]; - details.append($('

    ',{ - click: function(){_h2_on_click(this)}, - html:"− "+section.label - })); + $('

    ', { + 'name': section.name, + 'html':"− "+section.label + }).appendTo(details); var div = $('
    ', { - 'id': facet.entity_name+'-'+facet.name+'-'+section.name, + 'id': that.entity_name+'-'+that.name+'-'+section.name, 'class': 'details-section' }).appendTo(details); @@ -498,19 +498,48 @@ function ipa_details_setup(container) { var that = this; + that.facet_setup(container); + + var button = $('input[name=reset]', that.container); + that.reset_button = ipa_button({ + 'label': 'Reset', + 'icon': 'ui-icon-refresh', + 'class': 'details-reset', + 'click': function() { + that.reset(); + return false; + } + }); + button.replaceWith(that.reset_button); + + button = $('input[name=update]', that.container); + that.update_button = ipa_button({ + 'label': 'Update', + 'icon': 'ui-icon-check', + 'class': 'details-update', + 'click': function() { + that.update(); + return false; + } + }); + button.replaceWith(that.update_button); + for (var i = 0; i < that.sections.length; ++i) { var section = that.sections[i]; + var header = $('h2[name='+section.name+']', that.container); + header.click(function(){ _h2_on_click(this) }); + var div = $( '#'+that.entity_name+'-'+that.name+'-'+section.name, - container + that.container ); section.setup(div); } } -function ipa_details_load(container) { +function ipa_details_refresh() { var that = this; var entity = IPA.get_entity(that.entity_name); @@ -519,17 +548,11 @@ function ipa_details_load(container) { if (!that.pkey && !entity.default_facet) return; function on_success(data, text_status, xhr) { - var result = data.result.result; - - ipa_details_cache[that.entity_name] = $.extend(true, {}, result); - for (var i = 0; i < that.sections.length; ++i) { - var section = that.sections[i]; - section.load(result); - } + that.load(data.result.result); } function on_failure(xhr, text_status, error_thrown) { - var details = $('.details', container).empty(); + var details = $('.details', that.container).empty(); details.append('

    Error: '+error_thrown.name+'

    '); details.append('

    '+error_thrown.title+'

    '); details.append('

    '+error_thrown.message+'

    '); @@ -543,10 +566,12 @@ function ipa_details_load(container) { ); } -function ipa_details_update(container, pkey, on_win, on_fail) +function ipa_details_update(on_win, on_fail) { - var facet = this; - var entity_name = facet.entity_name; + var that = this; + var entity_name = that.entity_name; + + var pkey = that.get_primary_key(); function update_on_win(data, text_status, xhr) { if (on_win) @@ -555,8 +580,7 @@ function ipa_details_update(container, pkey, on_win, on_fail) return; var result = data.result.result; - ipa_details_cache[entity_name] = $.extend(true, {}, result); - facet.display(result); + that.load(result); } function update_on_fail(xhr, text_status, error_thrown) { @@ -571,16 +595,17 @@ function ipa_details_update(container, pkey, on_win, on_fail) var modlist = {'all': true, 'setattr': [], 'addattr': [], 'rights': true}; var attrs_wo_option = {}; - for (var i=0; i 1){ modlist[field.name] = values; } else if (param_info['multivalue']){ - modlist[field.name] = []; + modlist[field.name] = []; } } else { if (values.length) attrs_wo_option[field.name] = values; @@ -615,13 +640,14 @@ var _ipa_span_hint_template = 'Hint: D'; -function ipa_details_display(result) +function ipa_details_load(record) { - var facet = this; + var that = this; + that.record = record; - for (var i=0; i', { @@ -127,9 +115,11 @@ function ipa_hbac_search_facet(spec) { left_buttons.append(ipa_button({ 'label': 'Cull Disabled Rules' })); - */ - var ul = $('.action-panel ul'); + var entity_container = $('#' + that.entity_name); + var action_panel = $('.action-panel', entity_container); + + var ul = $('ul', action_panel); $('
  • ', { title: 'hbacsvc', @@ -153,7 +143,7 @@ function ipa_hbac_search_facet(spec) { } }).appendTo(ul); - that.superior_create(container); + that.search_facet_create(container); // TODO: replace with IPA.metadata[that.entity_name].label container.children().last().prepend( @@ -171,10 +161,6 @@ function ipa_hbac_details_facet(spec) { var that = ipa_details_facet(spec); - that.superior_init = that.superior('init'); - that.superior_create = that.superior('create'); - that.superior_setup = that.superior('setup'); - that.init = function() { var section; @@ -207,7 +193,7 @@ function ipa_hbac_details_facet(spec) { }); } else { - section = ipa_hbac_details_tables_section({ + section = ipa_rule_details_section({ 'name': 'user', 'label': 'Who', 'text': 'Rule applies when access is requested by:', @@ -228,12 +214,12 @@ function ipa_hbac_details_facet(spec) { section.add_field(ipa_hbac_association_widget({ 'id': that.entity_name+'-memberuser_user', 'name': 'memberuser_user', 'label': 'Users', 'category': category, - 'other_entity': 'user', 'add_method': 'add_user', 'delete_method': 'remove_user' + 'other_entity': 'user', 'add_method': 'add_user', 'remove_method': 'remove_user' })); section.add_field(ipa_hbac_association_widget({ 'id': that.entity_name+'-memberuser_group', 'name': 'memberuser_group', 'label': 'Groups', 'category': category, - 'other_entity': 'group', 'add_method': 'add_user', 'delete_method': 'remove_user' + 'other_entity': 'group', 'add_method': 'add_user', 'remove_method': 'remove_user' })); if (IPA.layout) { @@ -244,7 +230,7 @@ function ipa_hbac_details_facet(spec) { }); } else { - section = ipa_hbac_details_tables_section({ + section = ipa_rule_details_section({ 'name': 'host', 'label': 'Accessing', 'text': 'Rule applies when access is requested to:', @@ -265,12 +251,12 @@ function ipa_hbac_details_facet(spec) { section.add_field(ipa_hbac_association_widget({ 'id': that.entity_name+'-memberhost_host', 'name': 'memberhost_host', 'label': 'Hosts', 'category': category, - 'other_entity': 'host', 'add_method': 'add_host', 'delete_method': 'remove_host' + 'other_entity': 'host', 'add_method': 'add_host', 'remove_method': 'remove_host' })); section.add_field(ipa_hbac_association_widget({ 'id': that.entity_name+'-memberhost_hostgroup', 'name': 'memberhost_hostgroup', 'label': 'Host Groups', 'category': category, - 'other_entity': 'hostgroup', 'add_method': 'add_host', 'delete_method': 'remove_host' + 'other_entity': 'hostgroup', 'add_method': 'add_host', 'remove_method': 'remove_host' })); if (IPA.layout) { @@ -281,7 +267,7 @@ function ipa_hbac_details_facet(spec) { }); } else { - section = ipa_hbac_details_tables_section({ + section = ipa_rule_details_section({ 'name': 'service', 'label': 'Via Service', 'text': 'Rule applies when access is requested via:', @@ -302,12 +288,12 @@ function ipa_hbac_details_facet(spec) { section.add_field(ipa_hbac_association_widget({ 'id': that.entity_name+'-memberservice_hbacsvc', 'name': 'memberservice_hbacsvc', 'label': 'Services', 'category': category, - 'other_entity': 'hbacsvc', 'add_method': 'add_service', 'delete_method': 'remove_service' + 'other_entity': 'hbacsvc', 'add_method': 'add_service', 'remove_method': 'remove_service' })); section.add_field(ipa_hbac_association_widget({ 'id': that.entity_name+'-memberservice_hbacsvcgroup', 'name': 'memberservice_hbacsvcgroup', 'label': 'Service Groups', 'category': category, - 'other_entity': 'hbacsvcgroup', 'add_method': 'add_service', 'delete_method': 'remove_service' + 'other_entity': 'hbacsvcgroup', 'add_method': 'add_service', 'remove_method': 'remove_service' })); if (IPA.layout) { @@ -318,7 +304,7 @@ function ipa_hbac_details_facet(spec) { }); } else { - section = ipa_hbac_details_tables_section({ + section = ipa_rule_details_section({ 'name': 'sourcehost', 'label': 'From', 'text': 'Rule applies when access is being initiated from:', @@ -339,12 +325,12 @@ function ipa_hbac_details_facet(spec) { section.add_field(ipa_hbac_association_widget({ 'id': that.entity_name+'-sourcehost_host', 'name': 'sourcehost_host', 'label': 'Host', 'category': category, - 'other_entity': 'host', 'add_method': 'add_sourcehost', 'delete_method': 'remove_sourcehost' + 'other_entity': 'host', 'add_method': 'add_sourcehost', 'remove_method': 'remove_sourcehost' })); section.add_field(ipa_hbac_association_widget({ 'id': that.entity_name+'-sourcehost_hostgroup', 'name': 'sourcehost_hostgroup', 'label': 'Host Groups', 'category': category, - 'other_entity': 'hostgroup', 'add_method': 'add_sourcehost', 'delete_method': 'remove_sourcehost' + 'other_entity': 'hostgroup', 'add_method': 'add_sourcehost', 'remove_method': 'remove_sourcehost' })); if (IPA.layout) { @@ -360,7 +346,7 @@ function ipa_hbac_details_facet(spec) { 'label': 'When' }); /* - section = ipa_hbac_details_tables_section({ + section = ipa_rule_details_section({ 'name': 'accesstime', 'label': 'When', 'text': 'Rule applies when access is being requested at:', @@ -383,10 +369,10 @@ function ipa_hbac_details_facet(spec) { ] })); - that.superior_init(); + that.details_facet_init(); }; - that.update = function(container) { + that.update = function() { var pkey = $.bbq.getState(that.entity_name + '-pkey', true) || ''; @@ -466,13 +452,13 @@ function ipa_hbac_details_facet(spec) { for (var i=0; i', { 'name': that.field_name }).appendTo(container); - - for (var i=0; i', { - 'type': 'radio', - 'name': that.field_name, - 'value': option.value - }).appendTo(span); - - span.append(option.label); - } - - span.append(' '); - - $('', { - 'name': 'undo', - 'class': 'ui-state-highlight ui-corner-all', - 'style': 'display: none;', - 'html': 'undo' - }).appendTo(span); - - span.append('
    '); - - for (var i=0; i', { 'name': table.field_name }).appendTo(span); - - var field = that.get_field(table.field_name); - field.create(table_span); - } - }; - - return that; -} - function ipa_hbac_association_widget(spec) { spec = spec || {}; - var that = ipa_table_widget(spec); + var that = ipa_rule_association_widget(spec); - that.other_entity = spec.other_entity; that.category = spec.category; - that.add_method = spec.add_method; - that.delete_method = spec.delete_method; - - that.superior_init = that.superior('init'); - that.superior_create = that.superior('create'); - - that.init = function() { - // create a column if none defined - if (!that.columns.length) { - that.create_column({ - 'name': that.name, - 'label': IPA.metadata[that.other_entity].label, - 'primary_key': true - }); - } - - that.superior_init(); - }; - - that.create = function(container) { - - that.superior_create(container); - - var buttons = $('span[name=buttons]', container); - - $('', { - 'type': 'button', - 'name': 'remove', - 'value': 'Remove '+that.label - }).appendTo(buttons); - - $('', { - 'type': 'button', - 'name': 'add', - 'value': 'Add '+that.label - }).appendTo(buttons); - }; - - that.setup = function(container) { - - that.table_setup(container); - - var button = $('input[name=remove]', that.table); - button.replaceWith(ipa_button({ - 'label': button.val(), - 'icon': 'ui-icon-trash', - 'click': function() { that.remove(that.container); } - })); - - button = $('input[name=add]', that.table); - button.replaceWith(ipa_button({ - 'label': button.val(), - 'icon': 'ui-icon-plus', - 'click': function() { that.add(that.container) } - })); - - var entity = IPA.get_entity(that.entity_name); - var association = entity.get_association(that.other_entity); - - if (association && association.associator == 'serial') { - that.associator = serial_associator; - } else { - that.associator = bulk_associator; - } - }; - - that.load = function(container, result) { - - that.values = result[that.name] || []; - that.hide_undo(that.container); - that.set_values(that.container, that.values); - }; - - that.set_values = function(container, values) { - - that.tbody.empty(); - for (var i=0; values && iError: '+error_thrown.name+'

    '); - summary.append('

    '+error_thrown.title+'

    '); - summary.append('

    '+error_thrown.message+'

    '); - } - - var pkey = $.bbq.getState(that.entity_name + '-pkey', true) || ''; - ipa_cmd('show', [pkey], {'rights': true}, on_success, on_error, that.entity_name); + command.execute(); }; return that; @@ -1008,10 +781,6 @@ function ipa_hbac_accesstime_widget(spec) { that.text = spec.text; that.options = spec.options || []; - that.superior_init = that.superior('init'); - that.superior_create = that.superior('create'); - that.superior_setup = that.superior('setup'); - that.init = function() { that.table = ipa_table_widget({ @@ -1025,12 +794,12 @@ function ipa_hbac_accesstime_widget(spec) { 'primary_key': true }); - that.superior_init(); + that.widget_init(); }; that.create = function(container) { - that.superior_create(container); + that.widget_create(container); var span = $('', { 'name': 'text' }).appendTo(container); @@ -1101,32 +870,31 @@ function ipa_hbac_accesstime_widget(spec) { var input = $('input[name="'+that.name+'"]', that.container); input.change(function() { - that.show_undo(that.container); + that.show_undo(); }); - var undo = that.get_undo(that.container); + var undo = that.get_undo(); undo.click(function() { - that.reset(that.container); + that.reset(); }); }; - that.save = function(container) { + that.save = function() { var value = $('input[name="'+that.name+'"]:checked', that.container).val(); if (value == '') { - return that.table.save(that.container); + return that.table.save(); } else { return []; } }; - that.load = function(container, result) { + that.load = function(result) { that.values = result[that.name] || []; - that.set_values(that.container, that.values); - that.hide_undo(that.container); + that.reset(); }; - that.set_values = function(container, values) { + that.set_values = function(values) { that.set_radio_value(that.container, values && values.length ? '' : 'all'); @@ -1134,7 +902,7 @@ function ipa_hbac_accesstime_widget(spec) { for (var i=0; values && i', { title: 'hbac', diff --git a/install/static/hbacsvcgroup.js b/install/static/hbacsvcgroup.js index e6845b9b44ba0601e43e21d3b438802ded744554..30cb2c86e8c3b2bdfa441cde87d357a04d79a06d 100755 --- a/install/static/hbacsvcgroup.js +++ b/install/static/hbacsvcgroup.js @@ -107,10 +107,10 @@ function ipa_hbacsvcgroup_search_facet(spec) { that.create = function(container) { - var that = this; + var entity_container = $('#' + that.entity_name); + var action_panel = $('.action-panel', entity_container); - - var ul = $('.action-panel ul'); + var ul = $('ul', action_panel); $('
  • ', { title: 'hbac', diff --git a/install/static/host.js b/install/static/host.js index a721dd212a8a93e8a4a0fc465bea54cd8c738293..93a4c2731a5a80fc44b69740759f098d7b425d8d 100644 --- a/install/static/host.js +++ b/install/static/host.js @@ -233,7 +233,7 @@ function host_provisioning_status_widget(spec) { that.setup = function(container) { - that.container = container; + that.widget_setup(container); that.valid = $('li.key-status-valid', that.container); that.missing = $('li.key-status-missing', that.container); @@ -299,7 +299,7 @@ function host_provisioning_status_widget(spec) { alert(that.otp.val()); }; - that.load = function(container, result) { + that.load = function(result) { that.result = result; var krblastpwdchange = result['krblastpwdchange']; set_status(krblastpwdchange ? 'valid' : 'missing'); diff --git a/install/static/index.html b/install/static/index.html index 064dada5bfe2429511f499fb74556ac4db36d6cf..643c076ca59012908cf9dc590651889056180a07 100644 --- a/install/static/index.html +++ b/install/static/index.html @@ -18,6 +18,7 @@ + @@ -30,6 +31,7 @@ + diff --git a/install/static/policy.js b/install/static/policy.js index c56e4d51282ebd7ae8840b86b223cfea1e9b7934..db60e10a386777718a36be612d9c8066fbf38aaa 100644 --- a/install/static/policy.js +++ b/install/static/policy.js @@ -254,20 +254,20 @@ function ipa_records_facet(spec){ function setup(container){ + that.facet_setup(container); + that.pkey = $.bbq.getState(that.entity_name + '-pkey', true) || ''; that.record = $.bbq.getState(that.entity_name + '-record', true) || ''; - that.container = container; - - container.attr('title', that.entity_name); + that.container.attr('title', that.entity_name); var h2 = $('

    ',{ text: "Records for DNS Zone:" + that.pkey - }).appendTo(container); + }).appendTo(that.container); var div = $('
    ') - .appendTo(container); + .appendTo(that.container); var control_span =$('').appendTo(div); @@ -294,7 +294,7 @@ function ipa_records_facet(spec){ ipa_button({ 'label': IPA.messages.button.find, 'icon': 'ui-icon-search', - 'click': function(){load(container)} + 'click': function(){refresh()} }).appendTo(control_span); ipa_button({ @@ -314,7 +314,7 @@ function ipa_records_facet(spec){ var records_results = $('
    ', { 'class': 'records-results' - }).appendTo(container); + }).appendTo(that.container); var records_table = $('', { 'class': 'search-table' @@ -338,7 +338,7 @@ function ipa_records_facet(spec){ tr.append($('')); tr.append($('')); - load(container); + refresh(); } @@ -351,26 +351,26 @@ function ipa_records_facet(spec){ } function reload(){ - load(that.container); + refresh(); } - function load(container){ + function refresh(){ var options = {}; - var resource_filter = container.find("#dns-record-resource-filter") + var resource_filter = that.container.find("#dns-record-resource-filter") .val(); if (resource_filter){ options.idnsname = resource_filter; } - var type_filter = container.find("#dns-record-type-filter").val(); + var type_filter = that.container.find("#dns-record-type-filter").val(); if (type_filter){ options.type = type_filter; } - var data_filter = container.find("#dns-record-data-filter").val(); + var data_filter = that.container.find("#dns-record-data-filter").val(); if (data_filter){ options.data = data_filter; } @@ -449,7 +449,7 @@ function ipa_records_facet(spec){ that.create = create; that.setup = setup; - that.load = load; + that.refresh = refresh; return that; } diff --git a/install/static/rule.js b/install/static/rule.js new file mode 100755 index 0000000000000000000000000000000000000000..0fc91835782ebb723ce203e5b503e7669fc05b21 --- /dev/null +++ b/install/static/rule.js @@ -0,0 +1,246 @@ +/* Authors: + * Endi Sukma Dewata + * + * Copyright (C) 2010 Red Hat + * see file 'COPYING' for use and warranty information + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 only + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* REQUIRES: ipa.js, details.js, search.js, add.js, entity.js */ + +function ipa_rule_details_section(spec){ + + spec = spec || {}; + + var that = ipa_details_section(spec); + + that.text = spec.text; + that.field_name = spec.field_name; + that.options = spec.options || []; + that.tables = spec.tables || []; + that.columns = spec.columns; + + that.create = function(container) { + + if (that.template) return; + + if (that.text) container.append(that.text); + + var span = $('', { 'name': that.field_name }).appendTo(container); + + if (that.options.length) { + for (var i=0; i', { + 'type': 'radio', + 'name': that.field_name, + 'value': option.value + }).appendTo(span); + + span.append(option.label); + } + + span.append(' '); + + $('', { + 'name': 'undo', + 'class': 'ui-state-highlight ui-corner-all', + 'style': 'display: none;', + 'html': 'undo' + }).appendTo(span); + + span.append('
    '); + } + + for (var i=0; i', { 'name': table.field_name }).appendTo(span); + + var field = that.get_field(table.field_name); + field.create(table_span); + } + }; + + return that; +} + +function ipa_rule_association_widget(spec) { + + spec = spec || {}; + + var that = ipa_table_widget(spec); + + that.other_entity = spec.other_entity; + + that.add_method = spec.add_method; + that.remove_method = spec.remove_method; + + that.init = function() { + // create a column if none defined + if (!that.columns.length) { + that.create_column({ + 'name': that.name, + 'label': IPA.metadata[that.other_entity].label, + 'primary_key': true + }); + } + + that.table_init(); + }; + + that.create = function(container) { + + that.table_create(container); + + var buttons = $('span[name=buttons]', container); + + $('', { + 'type': 'button', + 'name': 'remove', + 'value': 'Remove '+that.label + }).appendTo(buttons); + + $('', { + 'type': 'button', + 'name': 'add', + 'value': 'Add '+that.label + }).appendTo(buttons); + }; + + that.setup = function(container) { + + that.table_setup(container); + + var button = $('input[name=remove]', that.table); + button.replaceWith(ipa_button({ + 'label': button.val(), + 'icon': 'ui-icon-trash', + 'click': function() { that.show_remove_dialog(); } + })); + + button = $('input[name=add]', that.table); + button.replaceWith(ipa_button({ + 'label': button.val(), + 'icon': 'ui-icon-plus', + 'click': function() { that.show_add_dialog() } + })); + + var entity = IPA.get_entity(that.entity_name); + var association = entity.get_association(that.other_entity); + + if (association && association.associator == 'serial') { + that.associator = serial_associator; + } else { + that.associator = bulk_associator; + } + }; + + that.load = function(result) { + that.values = result[that.name] || []; + that.reset(); + }; + + that.set_values = function(values) { + + that.tbody.empty(); + for (var i=0; values && i', { - 'class': 'search-filter' + 'class': 'search-filter', + 'name': 'search-filter' }).appendTo(search_controls); this.filter = $('', { @@ -45,28 +46,33 @@ function ipa_search_widget(spec) { 'name': 'search-' + that.entity_name + '-filter' }).appendTo(search_filter); - ipa_button({ - 'label': IPA.messages.button.find, - 'icon': 'ui-icon-search', - 'click': function() { that.find(container); } + $('', { + 'type': 'button', + 'name': 'find', + 'value': 'Find' }).appendTo(search_filter); - var li = $('
  • ', { - html: ipa_button({ - 'label': IPA.messages.button.remove, - 'icon': 'ui-icon-trash', - 'click': function() { that.remove(container); } - })}); - li.append( - ipa_button({ - 'label': IPA.messages.button.add, - 'icon': 'ui-icon-plus', - 'click': function() { that.add(container); } - }) - ); - li.prependTo($('.action-panel ul')); + var entity_container = $('#' + that.entity_name); + var action_panel = $('.action-panel', entity_container); - search_controls.append(''); + var ul = $('ul', action_panel); + var li = $('
  • ').prependTo(ul); + + var search_buttons = $('', { + 'class': 'search-buttons' + }).appendTo(li); + + $('', { + 'type': 'button', + 'name': 'remove', + 'value': 'Remove' + }).appendTo(search_buttons); + + $('', { + 'type': 'button', + 'name': 'add', + 'value': 'Add' + }).appendTo(search_buttons); $('
    ', { 'class': 'search-results' @@ -79,6 +85,36 @@ function ipa_search_widget(spec) { that.table_setup(container); + var search_filter = $('span[name=search-filter]', that.container); + + var button = $('input[name=find]', search_filter); + that.find_button = ipa_button({ + 'label': IPA.messages.button.find, + 'icon': 'ui-icon-search', + 'click': function() { that.find(that.container); } + }); + button.replaceWith(that.find_button); + + var entity_container = $('#' + that.entity_name); + var action_panel = $('.action-panel', entity_container); + var search_buttons = $('.search-buttons', action_panel); + + button = $('input[name=remove]', search_buttons); + that.remove_button = ipa_button({ + 'label': IPA.messages.button.remove, + 'icon': 'ui-icon-trash', + 'click': function() { that.remove(that.container); } + }); + button.replaceWith(that.remove_button); + + button = $('input[name=add]', search_buttons); + that.add_button = ipa_button({ + 'label': IPA.messages.button.add, + 'icon': 'ui-icon-plus', + 'click': function() { that.add(that.container); } + }); + button.replaceWith(that.add_button); + var filter = $.bbq.getState(that.entity_name + '-filter', true) || ''; this.filter.val(filter); }; @@ -143,11 +179,11 @@ function ipa_search_widget(spec) { var batch = ipa_batch_command({ 'on_success': function() { - that.refresh(that.container); + that.refresh(); dialog.close(); }, 'on_error': function() { - that.refresh(that.container); + that.refresh(); dialog.close(); } }); @@ -168,7 +204,7 @@ function ipa_search_widget(spec) { dialog.open(that.container); }; - that.refresh = function(container) { + that.refresh = function() { function on_success(data, text_status, xhr) { @@ -177,7 +213,7 @@ function ipa_search_widget(spec) { var result = data.result.result; for (var i = 0; i + * + * Copyright (C) 2010 Red Hat + * see file 'COPYING' for use and warranty information + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 only + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* REQUIRES: ipa.js, details.js, search.js, add.js, entity.js */ + +function ipa_sudorule() { + + var that = ipa_entity({ + 'name': 'sudorule' + }); + + that.init = function() { + + var dialog = ipa_sudorule_add_dialog({ + 'name': 'add', + 'title': 'Add New Rule' + }); + that.add_dialog(dialog); + dialog.init(); + + var facet = ipa_sudorule_search_facet({ + 'name': 'search', + 'label': 'Search' + }); + that.add_facet(facet); + + facet = ipa_sudorule_details_facet({ + 'name': 'details', + 'label': 'Details' + }); + that.add_facet(facet); + + that.entity_init(); + }; + + return that; +} + +IPA.add_entity(ipa_sudorule()); + +function ipa_sudorule_add_dialog(spec) { + + spec = spec || {}; + + var that = ipa_add_dialog(spec); + + that.init = function() { + + that.add_dialog_init(); + + that.add_field(ipa_text_widget({ + 'name': 'cn', + 'label': 'Rule Name', + 'undo': false + })); + }; + + return that; +} + +function ipa_sudorule_search_facet(spec) { + + spec = spec || {}; + + var that = ipa_search_facet(spec); + + that.init = function() { + + that.create_column({name:'cn', label:'Rule Name'}); + that.create_column({name:'description', label:'Description'}); + that.create_column({name:'cmdcategory', label:'Command category'}); + + that.search_facet_init(); + }; + + that.create = function(container) { + + that.search_facet_create(container); + + // TODO: replace with IPA.metadata[that.entity_name].label + container.children().last().prepend( + $('

    ', { 'html': 'SUDO Rules' })); + container.children().last().prepend('

    '); + + }; + + return that; +} + +function ipa_sudorule_details_facet(spec) { + + spec = spec || {}; + + var that = ipa_details_facet(spec); + + that.init = function() { + + var section = ipa_details_list_section({ + 'name': 'general', + 'label': 'General' + }); + that.add_section(section); + + section.create_field({ 'name': 'cn', 'label': 'Name', 'read_only': true }); + section.create_field({ 'name': 'description', 'label': 'Description' }); + section.create_field({ 'name': 'cmdcategory', 'label': 'Command Category' }); + + section = ipa_rule_details_section({ + 'name': 'user', + 'label': 'Who', + 'field_name': 'memberuser', + 'tables': [ + { 'field_name': 'memberuser_user' }, + { 'field_name': 'memberuser_group' } + ] + }); + that.add_section(section); + + section.add_field(ipa_sudorule_association_widget({ + 'id': that.entity_name+'-memberuser_user', + 'name': 'memberuser_user', 'label': 'Users', + 'other_entity': 'user', 'add_method': 'add_user', 'remove_method': 'remove_user' + })); + section.add_field(ipa_sudorule_association_widget({ + 'id': that.entity_name+'-memberuser_group', + 'name': 'memberuser_group', 'label': 'Groups', + 'other_entity': 'group', 'add_method': 'add_user', 'remove_method': 'remove_user' + })); + + section = ipa_rule_details_section({ + 'name': 'host', + 'label': 'Where', + 'field_name': 'memberhost', + 'tables': [ + { 'field_name': 'memberhost_host' }, + { 'field_name': 'memberhost_hostgroup' } + ] + }); + that.add_section(section); + + section.add_field(ipa_sudorule_association_widget({ + 'id': that.entity_name+'-memberhost_host', + 'name': 'memberhost_host', 'label': 'Host', + 'other_entity': 'host', 'add_method': 'add_host', 'remove_method': 'remove_host' + })); + section.add_field(ipa_sudorule_association_widget({ + 'id': that.entity_name+'-memberhost_hostgroup', + 'name': 'memberhost_hostgroup', 'label': 'Groups', + 'other_entity': 'hostgroup', 'add_method': 'add_host', 'remove_method': 'remove_host' + })); + + section = ipa_rule_details_section({ + 'name': 'allow', + 'label': 'Allow', + 'field_name': 'memberallowcmd', + 'tables': [ + { 'field_name': 'memberallowcmd_sudocmd' }, + { 'field_name': 'memberallowcmd_sudocmdgroup' } + ] + }); + that.add_section(section); + + section.add_field(ipa_sudorule_association_widget({ + 'id': that.entity_name+'-memberallowcmd_sudocmd', + 'name': 'memberallowcmd_sudocmd', 'label': 'Command', + 'other_entity': 'sudocmd', 'add_method': 'add_allow_command', 'remove_method': 'remove_allow_command' + })); + section.add_field(ipa_sudorule_association_widget({ + 'id': that.entity_name+'-memberallowcmd_sudocmdgroup', + 'name': 'memberallowcmd_sudocmdgroup', 'label': 'Groups', + 'other_entity': 'sudocmdgroup', 'add_method': 'add_allow_command', 'remove_method': 'remove_allow_command' + })); + + section = ipa_rule_details_section({ + 'name': 'deny', + 'label': 'Deny', + 'field_name': 'memberdenycmd', + 'tables': [ + { 'field_name': 'memberdenycmd_sudocmd' }, + { 'field_name': 'memberdenycmd_sudocmdgroup' } + ] + }); + that.add_section(section); + + section.add_field(ipa_sudorule_association_widget({ + 'id': that.entity_name+'-memberdenycmd_sudocmd', + 'name': 'memberdenycmd_sudocmd', 'label': 'Command', + 'other_entity': 'sudocmd', 'add_method': 'add_deny_command', 'remove_method': 'remove_deny_command' + })); + section.add_field(ipa_sudorule_association_widget({ + 'id': that.entity_name+'-memberdenycmd_sudocmdgroup', + 'name': 'memberdenycmd_sudocmdgroup', 'label': 'Groups', + 'other_entity': 'sudocmdgroup', 'add_method': 'add_deny_command', 'remove_method': 'remove_deny_command' + })); + + that.details_facet_init(); + }; + + return that; +} + +function ipa_sudorule_association_widget(spec) { + + spec = spec || {}; + + var that = ipa_rule_association_widget(spec); + + that.add = function(values, on_success, on_error) { + + var pkey = $.bbq.getState(that.entity_name + '-pkey', true) || ''; + + var command = ipa_command({ + 'method': that.entity_name+'_'+that.add_method, + 'args': [pkey], + 'on_success': on_success, + 'on_error': on_error + }); + command.set_option(that.other_entity, values.join(',')); + + command.execute(); + }; + + that.remove = function(values, on_success, on_error) { + + var pkey = $.bbq.getState(that.entity_name + '-pkey', true) || ''; + + var command = ipa_command({ + 'method': that.entity_name+'_'+that.remove_method, + 'args': [pkey], + 'on_success': on_success, + 'on_error': on_error + }); + + command.set_option(that.other_entity, values.join(',')); + + command.execute(); + }; + + that.save = function() { + return null; + }; + + return that; +} \ No newline at end of file diff --git a/install/static/test/data/batch.json b/install/static/test/data/batch.json index a8a5da0b1b052e4a35e5575f3b7d1bc2162e9dfb..a38cd976760499257e3dd27f533aebff5f9b3b8f 100644 --- a/install/static/test/data/batch.json +++ b/install/static/test/data/batch.json @@ -4099,7 +4099,38 @@ } }, { - "error": "i18n_messages" + "error": null, + "messages": { + "ajax": { + "401": "Your kerberos ticket no longer valid.Please run KInit and then click 'retry'If this is your first time running the IPA Web UI Follow these directions to configure your browser." + }, + "button": { + "add": "Add", + "enroll": "Enroll", + "find": "Find", + "remove": "Delete", + "reset": "Reset", + "update": "Update" + }, + "details": { + "account": "Account Details", + "contact": "Contact Details", + "employee": " Employee Information", + "identity": "Identity Details", + "mailing": "Mailing Address", + "misc": "Misc. Information", + "to_top": "Back to Top" + }, + "login": { + "header": "Logged In As" + }, + "search": { + "delete_confirm": "Do you really want to delete the selected entries?", + "quick_links": "Quick Links", + "select_all": "Select All", + "unselect_all": "Unselect All" + } + } }, { "count": 1, diff --git a/install/static/test/data/sudorule_find.json b/install/static/test/data/sudorule_find.json new file mode 100644 index 0000000000000000000000000000000000000000..ff8474af7704b778acc0de11e317e3efc1f2967a --- /dev/null +++ b/install/static/test/data/sudorule_find.json @@ -0,0 +1,17 @@ +{ + "error": null, + "id": 0, + "result": { + "count": 1, + "result": [ + { + "cn": [ + "test" + ], + "dn": "ipauniqueid=4fc57a02-f23311df-b268e50e-a3b3ef71,cn=sudorules,dc=dev,dc=example,dc=com" + } + ], + "summary": null, + "truncated": false + } +} diff --git a/install/static/test/data/sudorule_show.json b/install/static/test/data/sudorule_show.json new file mode 100644 index 0000000000000000000000000000000000000000..332caa2f014fef120261c04524c58616e78a63a6 --- /dev/null +++ b/install/static/test/data/sudorule_show.json @@ -0,0 +1,72 @@ +{ + "error": null, + "id": 0, + "result": { + "result": { + "attributelevelrights": { + "aci": "rscwo", + "cmdcategory": "rscwo", + "cn": "rscwo", + "description": "rscwo", + "externalhost": "rscwo", + "externaluser": "rscwo", + "hostcategory": "rscwo", + "hostmask": "rscwo", + "ipaenabledflag": "rscwo", + "ipasudoopt": "rscwo", + "ipasudorunas": "rscwo", + "ipasudorunasextgroup": "rscwo", + "ipasudorunasextuser": "rscwo", + "ipasudorunasgroup": "rscwo", + "ipasudorunasgroupcategory": "rscwo", + "ipasudorunasusercategory": "rscwo", + "ipauniqueid": "rsc", + "memberallowcmd": "rscwo", + "memberdenycmd": "rscwo", + "memberhost": "rscwo", + "memberuser": "rscwo", + "nsaccountlock": "rscwo", + "usercategory": "rscwo" + }, + "cn": [ + "test" + ], + "dn": "ipauniqueid=4fc57a02-f23311df-b268e50e-a3b3ef71,cn=sudorules,dc=dev,dc=example,dc=com", + "ipauniqueid": [ + "4fc57a02-f23311df-b268e50e-a3b3ef71" + ], + "memberallowcmd_sudocmd": [ + "/usr/bin/less" + ], + "memberallowcmd_sudocmdgroup": [ + "group1" + ], + "memberdenycmd_sudocmd": [ + "/usr/bin/more" + ], + "memberdenycmd_sudocmdgroup": [ + "group1", + "group2" + ], + "memberhost_host": [ + "dev.example.com" + ], + "memberhost_hostgroup": [ + "production", + "staging" + ], + "memberuser_group": [ + "editors" + ], + "memberuser_user": [ + "test" + ], + "objectclass": [ + "ipaassociation", + "ipasudorule" + ] + }, + "summary": null, + "value": "test" + } +} diff --git a/install/static/test/details_tests.js b/install/static/test/details_tests.js index 04738143c92a16a3fafc03720387087b75f36f0a..baa884e28e420b88d88fbbba439e682068fdc7c9 100644 --- a/install/static/test/details_tests.js +++ b/install/static/test/details_tests.js @@ -179,7 +179,7 @@ test("Testing details lifecycle: create, setup, load.", function(){ var facet = entity.get_facet('details'); facet.create(container); facet.setup(container); - facet.display(result); + facet.load(result); var contact = container.find('dl#contact.entryattrs'); @@ -211,10 +211,10 @@ test("Testing details lifecycle: create, setup, load.", function(){ ok (load_manager_called, 'load manager called'); - facet.update(container, - 'kfrog', - function(){update_success_called = true}, - function(){update_failure_called = true}); + facet.update( + function(){update_success_called = true}, + function(){update_failure_called = true} + ); ok (update_success_called,'update success called'); ok (!update_failure_called,'update failure not called'); diff --git a/install/static/user.js b/install/static/user.js index 2a9bc7d09696f5d123b1a5cba0f7a701e8314488..21619ec5320e960d86fce55e4eb523038983d2a8 100644 --- a/install/static/user.js +++ b/install/static/user.js @@ -88,12 +88,14 @@ ipa_entity_set_association_definition('user', { /* ATTRIBUTE CALLBACKS */ -function user_status_load(container, result) { +function user_status_load(result) { - $('dd', container).remove(); + var that = this; + + $('dd', that.container).remove(); var dd = ipa_create_first_dd(this.name); - dd.appendTo(container); + dd.appendTo(that.container); var lock_field = 'nsaccountlock'; @@ -192,12 +194,14 @@ function resetpwd_on_click(){ return false; } -function user_password_load(container, result) { +function user_password_load(result) { - $('dd', container).remove(); + var that = this; + + $('dd', that.container).remove(); var dd = ipa_create_first_dd(this.name); - dd.appendTo(container); + dd.appendTo(that.container); var link = $('',{ href:"jslink", @@ -219,9 +223,11 @@ var states = [ 'PA', 'PR', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VI', 'VA', 'WA', 'WV', 'WI', 'WY', '' ]; -function user_state_load(container, result) { +function user_state_load(result) { - $('dd', container).remove(); + var that = this; + + $('dd', that.container).remove(); //var next = dt.next(); //next.css('clear', 'none'); @@ -229,7 +235,7 @@ function user_state_load(container, result) { var dd = ipa_create_first_dd(this.name); dd.append(select_temp); - dd.appendTo(container); + dd.appendTo(that.container); var sel = dd.children().first(); for (var i = 0; i < states.length; ++i) diff --git a/install/static/webui.js b/install/static/webui.js index b588876a74a6bbf7cb626f6ed5ec356f34f20bb6..17c08d8f46e4e943ee7033e038e5e2bf69e69ace 100644 --- a/install/static/webui.js +++ b/install/static/webui.js @@ -34,6 +34,7 @@ var admin_tab_set = [ ]}, {name:'policy', children:[ {name:'hbac', setup: ipa_entity_setup}, + {name:'sudorule', setup: ipa_entity_setup}, {name:'dns', setup: ipa_entity_setup}, {name:'automountlocation', setup: ipa_entity_setup}, {name:'pwpolicy', setup: ipa_entity_setup}, diff --git a/install/static/widget.js b/install/static/widget.js index 6ed27decd8e3e553000654162dd4b5106291bcf5..f6bc3d837c1d8ebd1ec6c3aac8ff81b75cdb17f4 100755 --- a/install/static/widget.js +++ b/install/static/widget.js @@ -63,22 +63,22 @@ function ipa_widget(spec) { } function setup(container) { - this.container = container; + that.container = container; } - function load(container, result) { + function load(result) { } - function save(container) { + function save() { return []; } - function clear(container) { + function clear() { } that.is_dirty = function(container) { if (!that.values) return true; - var values = that.save(that.container); + var values = that.save(); if (values.length != that.values.length) return true; for (var i=0; iError: '+error_thrown.name+'

    '); - that.container.append('

    '+error_thrown.title+'

    '); - that.container.append('

    '+error_thrown.message+'

    '); + var summary = $('span[name=summary]', that.tfoot).empty(); + summary.append('

    Error: '+error_thrown.name+'

    '); + summary.append('

    '+error_thrown.title+'

    '); + summary.append('

    '+error_thrown.message+'

    '); } var pkey = $.bbq.getState(that.entity_name + '-pkey', true) || ''; - ipa_cmd('show', [pkey], {'rights': true}, on_success, on_error, that.entity_name); + ipa_cmd('show', [pkey], {'all': true, 'rights': true}, on_success, on_error, that.entity_name); }; if (spec.columns) { @@ -670,6 +669,8 @@ function ipa_table_widget(spec) { } // methods that should be invoked by subclasses + that.table_init = that.init; + that.table_create = that.create; that.table_setup = that.setup; return that; @@ -795,7 +796,7 @@ function ipa_dialog(spec) { var record = {}; for (var i=0; i

  • Record TypeData