From c90bff232dcc9dbab2cd6d5a1bb482cb1c5f16f9 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Fri, 19 Nov 2010 23:52:33 -0600 Subject: Multicolumn association facet The association facet has been modified to support multiple columns. By default the facet will have one column which is the primary key of the associated object (e.g. username of a group member), so the existing code will work like before. Other fields (e.g. user's full name) can be added by subclassing the ipa_association_facet class and specifying the additional columns to display. These additional fields will be retrieved using a batch operation. Previously a single association facet instance will be used for all associations in an entity. Now each association will have its own association facet. This way each association facet can be customized differently as needed. The -enroll URL parameter has been removed because it's no longer needed. The ipa_entity.create_association_facets() is provided to generate the default association facets with one column for the primary key. The column click handler has been moved out of ipa_column to provide more flexibility for customization. The get_action_panel() and get_client_area() have been modified to search within the entity's container. The group entity has been fully converted to use the new UI framework. Association facets that have been modified to use multiple columns are: - User Group's member_user - HBAC Service Group's member_hbacsvc - SUDO Command Group's member_sudocmd - Service's managedby_host New test data files have been added. Unit tests have been updated. --- install/static/associate.js | 153 +++++++++++++++---- install/static/entity.js | 85 ++++++----- install/static/group.js | 168 +++++++++++++++++---- install/static/hbacsvc.js | 14 +- install/static/hbacsvcgroup.js | 56 +++++-- install/static/host.js | 18 ++- install/static/ipa.js | 15 +- install/static/search.js | 44 ++++-- install/static/service.js | 51 ++++++- install/static/sudocmd.js | 14 +- install/static/sudocmdgroup.js | 56 +++++-- install/static/test/data/group_member_user.json | 150 ++++++++++++++++++ .../test/data/hbacsvcgroup_member_hbacsvc.json | 57 +++++++ install/static/test/data/host_show.json | 77 ++++++++++ .../static/test/data/hostgroup_member_host.json | 70 +++++++++ .../static/test/data/service_managedby_host.json | 110 ++++++++++++++ .../test/data/sudocmdgroup_member_sudocmd.json | 57 +++++++ install/static/test/data/user_memberof_group.json | 64 ++++++++ install/static/test/entity_tests.js | 47 +++--- install/static/widget.js | 115 ++++++++------ 20 files changed, 1168 insertions(+), 253 deletions(-) create mode 100644 install/static/test/data/group_member_user.json create mode 100644 install/static/test/data/hbacsvcgroup_member_hbacsvc.json create mode 100644 install/static/test/data/host_show.json create mode 100644 install/static/test/data/hostgroup_member_host.json create mode 100644 install/static/test/data/service_managedby_host.json create mode 100644 install/static/test/data/sudocmdgroup_member_sudocmd.json create mode 100644 install/static/test/data/user_memberof_group.json diff --git a/install/static/associate.js b/install/static/associate.js index ddfd78c2..fbd1c63c 100644 --- a/install/static/associate.js +++ b/install/static/associate.js @@ -147,17 +147,25 @@ function ipa_association_adder_dialog(spec) { that.on_success = spec.on_success; that.on_error = spec.on_error; + that.init = function() { + if (!that.columns.length) { + var pkey_name = IPA.metadata[that.other_entity].primary_key; + that.create_column({ + name: pkey_name, + primary_key: true + }); + } + }; + that.search = function() { function on_success(data, text_status, xhr) { var results = data.result; that.clear_available_values(); - var pkey = IPA.metadata[that.other_entity].primary_key; - for (var i=0; i', { + 'href': '#'+value, + 'html': value, + 'click': function (value) { + return function() { + var state = IPA.tab_state(that.other_entity); + state[that.other_entity + '-facet'] = 'details'; + state[that.other_entity + '-pkey'] = value; + $.bbq.pushState(state); + return false; + } + }(value) + }).appendTo(container); + }; + } that.superior_create(container); var action_panel = that.facet.get_action_panel(); - - var ul = $('ul', action_panel); - var li = $('
  • ').prependTo(ul); + var li = $('.action-controls', action_panel); // creating generic buttons for layout $('', { @@ -381,23 +410,59 @@ function ipa_association_widget(spec) { dialog.open(that.container); }; + that.get_records = function(pkeys, on_success, on_error) { + + var batch = ipa_batch_command({ + 'name': that.entity_name+'_'+that.name, + 'on_success': on_success, + 'on_error': on_error + }); + + for (var i=0; i',{ html: header_message }) }).appendTo(container); - that.table = ipa_association_widget({ + that.table = ipa_association_table_widget({ 'id': that.entity_name+'-'+that.other_entity, - 'name': that.other_entity, + 'name': that.name, 'label': label, 'entity_name': that.entity_name, 'other_entity': that.other_entity, 'facet': that }); + if (that.columns.length) { + that.table.set_columns(that.columns); + } + var span = $('', { 'name': 'association' }).appendTo(container); that.table.create(span); @@ -466,12 +552,13 @@ function ipa_association_facet(spec) { var span = $('span[name=association]', that.container); that.table.setup(span); - that.table.refresh(); }; - //TODO find out why this is needed that.refresh = function(){ - } + that.table.refresh(); + }; + + that.association_facet_init = that.init; return that; } diff --git a/install/static/entity.js b/install/static/entity.js index 713dbf31..5d59b3c7 100644 --- a/install/static/entity.js +++ b/install/static/entity.js @@ -68,11 +68,11 @@ function ipa_facet(spec) { } that.get_client_area = function() { - return $('#' + that.entity_name+' .client'); + return $('.client', that.container); }; that.get_action_panel = function() { - return $('#' + that.entity_name+' .action-panel'); + return $('.action-panel', that.container); }; that.facet_init = that.init; @@ -100,6 +100,8 @@ function ipa_entity(spec) { that.facet_name = null; + that.autogenerate_associations = false; + that.associations = []; that.associations_by_name = {}; @@ -149,7 +151,46 @@ function ipa_entity(spec) { return config; }; + that.create_association_facet = function(other_entity, attribute_member) { + + var label = IPA.metadata[other_entity].label; + + if (!attribute_member) { + attribute_member = ipa_get_member_attribute( + that.entity_name, other_entity + ); + } + + return ipa_association_facet({ + 'name': attribute_member+'_'+other_entity, + 'label': label, + 'other_entity': other_entity + }); + }; + + that.create_association_facets = function() { + + var attribute_members = IPA.metadata[that.name].attribute_members; + + for (var attribute_member in attribute_members) { + var other_entities = attribute_members[attribute_member]; + + for (var j = 0; j < other_entities.length; j++) { + var other_entity = other_entities[j]; + + var facet = that.create_association_facet(other_entity, attribute_member); + if (that.get_facet(facet.name)) continue; + that.add_facet(facet); + } + } + }; + that.init = function() { + + if (that.autogenerate_associations) { + that.create_association_facets(); + } + for (var i=0; i', { "class" : other_facet.display_class, - title: other_entity, + title: other_facet.name, text: label, click: function(entity_name, other_facet_name) { return function() { @@ -366,7 +392,7 @@ function ipa_facet_create_action_panel(container) { var this_pkey = $('input[id=pkey]', action_panel).val(); IPA.switch_and_show_page( entity_name, other_facet_name, - this_pkey, other_entity); + this_pkey); return false; }; @@ -390,7 +416,7 @@ function ipa_facet_create_action_panel(container) { var other_facet = entity.facets[0]; var other_facet_name = other_facet.name; - var main_facet = build_link(other_facet,other_facet.label) + var main_facet = build_link(other_facet,other_facet.label); /*assumeing for now that entities with only a single facet do not have search*/ @@ -404,20 +430,7 @@ function ipa_facet_create_action_panel(container) { other_facet = entity.facets[i]; other_facet_name = other_facet.name; - if (other_facet.label) { - ul.append(build_link(other_facet,other_facet.label)); - - } else { // For now empty label indicates an association facet - var attribute_members = IPA.metadata[entity_name].attribute_members; - for (var attribute_member in attribute_members) { - var other_entities = attribute_members[attribute_member]; - for (var j = 0; j < other_entities.length; j++) { - var other_entity = other_entities[j]; - var label = IPA.metadata[other_entity].label; - ul.append(build_link(other_facet,label,other_entity)); - } - } - } + ul.append(build_link(other_facet,other_facet.label)); } /*When we land on the search page, disable all facets diff --git a/install/static/group.js b/install/static/group.js index f94a7dea..0dfae2fd 100644 --- a/install/static/group.js +++ b/install/static/group.js @@ -26,10 +26,23 @@ function ipa_group() { 'name': 'group' }); - that.superior_init = that.superior('init'); - that.init = function() { + that.create_association({ + name: 'netgroup', + associator: 'serial' + }); + + that.create_association({ + name: 'rolegroup', + associator: 'serial' + }); + + that.create_association({ + name: 'taskgroup', + associator: 'serial' + }); + var dialog = ipa_group_add_dialog({ 'name': 'add', 'title': 'Add New Group' @@ -37,7 +50,28 @@ function ipa_group() { that.add_dialog(dialog); dialog.init(); - that.superior_init(); + var facet = ipa_group_search_facet({ + 'name': 'search', + 'label': 'Search' + }); + that.add_facet(facet); + + facet = ipa_group_details_facet({ + 'name': 'details', + 'label': 'Details' + }); + that.add_facet(facet); + + facet = ipa_group_member_user_facet({ + 'name': 'member_user', + 'label': 'Users', + 'other_entity': 'user' + }); + that.add_facet(facet); + + that.create_association_facets(); + + that.entity_init(); }; return that; @@ -51,36 +85,116 @@ function ipa_group_add_dialog(spec) { var that = ipa_add_dialog(spec); - that.superior_init = that.superior('init'); + that.init = function() { + + that.add_dialog_init(); + + that.add_field(ipa_text_widget({name:'cn', label:'Name', undo: false})); + that.add_field(ipa_text_widget({name:'description', label:'Description', undo: false})); + that.add_field(ipa_checkbox_widget({name:'posix', label:'Is this a POSIX group?', undo: false})); + that.add_field(ipa_text_widget({name:'gidnumber', label:'GID', undo: false})); + }; + + return that; +} + +function ipa_group_search_facet(spec) { + + spec = spec || {}; + + var that = ipa_search_facet(spec); + + that.init = function() { + + that.create_column({name:'cn', label:'Name'}); + that.create_column({name:'gidnumber', label:'GID'}); + that.create_column({name:'description', label:'Description'}); + + that.search_facet_init(); + }; + + return that; +} + +function ipa_group_details_facet(spec) { + + spec = spec || {}; + + var that = ipa_details_facet(spec); that.init = function() { - this.superior_init(); + var section = ipa_details_list_section({ + name: 'details', + label: 'Group Details' + }); + that.add_section(section); + + section.create_field({ + name: 'cn', + label: 'Group Name' + }); + + section.create_field({ + name: 'description', + label: 'Description' + }); + + section.create_field({ + name: 'gidnumber', + label: 'Group ID' + }); - this.add_field(ipa_text_widget({name:'cn', label:'Name', undo: false})); - this.add_field(ipa_text_widget({name:'description', label:'Description', undo: false})); - this.add_field(ipa_checkbox_widget({name:'posix', label:'Is this a POSIX group?', undo: false})); - this.add_field(ipa_text_widget({name:'gidnumber', label:'GID', undo: false})); + that.details_facet_init(); }; return that; } -ipa_entity_set_search_definition('group', [ - ['cn', 'Name', null], - ['gidnumber', 'GID', null], - ['description', 'Description', null] -]); - -ipa_entity_set_details_definition('group',[ - ipa_stanza({name:'identity', label:'Group Details'}). - input({name:'cn', label:'Group Name'}). - input({name:'description', label:'Description'}). - input({name:'gidnumber', label:'Group ID'}) -]); - -ipa_entity_set_association_definition('group', { - 'netgroup': { associator: 'serial' }, - 'rolegroup': { associator: 'serial' }, - 'taskgroup': { associator: 'serial' } -}); +function ipa_group_member_user_facet(spec) { + + spec = spec || {}; + + var that = ipa_association_facet(spec); + + that.init = function() { + + that.create_column({name: 'cn', label: 'Name'}); + + var column = that.create_column({ + name: 'uid', + label: 'Login', + primary_key: true + }); + + column.setup = function(container, record) { + container.empty(); + + var value = record[column.name]; + value = value ? value.toString() : ''; + + $('', { + 'href': '#'+value, + 'html': value, + 'click': function (value) { + return function() { + var state = IPA.tab_state(that.other_entity); + state[that.other_entity + '-facet'] = 'details'; + state[that.other_entity + '-pkey'] = value; + $.bbq.pushState(state); + return false; + } + }(value) + }).appendTo(container); + }; + + that.create_column({name: 'uidnumber', label: 'UID'}); + that.create_column({name: 'mail', label: 'EMAIL'}); + that.create_column({name: 'telephonenumber', label: 'Phone'}); + that.create_column({name: 'title', label: 'Job Title'}); + + that.association_facet_init(); + }; + + return that; +} \ No newline at end of file diff --git a/install/static/hbacsvc.js b/install/static/hbacsvc.js index 7dca90ec..c4140272 100755 --- a/install/static/hbacsvc.js +++ b/install/static/hbacsvc.js @@ -65,10 +65,10 @@ function ipa_hbacsvc_add_dialog(spec) { that.init = function() { - this.superior_init(); + that.superior_init(); - this.add_field(ipa_text_widget({name:'cn', label:'Name', undo: false})); - this.add_field(ipa_text_widget({name:'description', label:'Description', undo: false})); + that.add_field(ipa_text_widget({name:'cn', label:'Name', undo: false})); + that.add_field(ipa_text_widget({name:'description', label:'Description', undo: false})); }; return that; @@ -80,10 +80,6 @@ function ipa_hbacsvc_search_facet(spec) { var that = ipa_search_facet(spec); - that.get_action_panel = function() { - return $('#hbac .action-panel'); - }; - that.init = function() { that.create_column({name:'cn', label:'Service', primary_key: true}); @@ -156,10 +152,6 @@ function ipa_hbacsvc_details_facet(spec) { that.superior_create = that.superior('create'); that.superior_setup = that.superior('setup'); - that.get_action_panel = function() { - return $('#hbac .action-panel'); - }; - that.init = function() { var section = ipa_details_list_section({ diff --git a/install/static/hbacsvcgroup.js b/install/static/hbacsvcgroup.js index 121fad67..914c7354 100755 --- a/install/static/hbacsvcgroup.js +++ b/install/static/hbacsvcgroup.js @@ -53,8 +53,10 @@ function ipa_hbacsvcgroup() { }); that.add_facet(facet); - facet = ipa_hbacsvcgroup_association_facet({ - 'name': 'associate' + facet = ipa_hbacsvcgroup_member_hbacsvc_facet({ + 'name': 'member_hbacsvc', + 'label': 'Services', + 'other_entity': 'hbacsvc' }); that.add_facet(facet); @@ -76,10 +78,10 @@ function ipa_hbacsvcgroup_add_dialog(spec) { that.init = function() { - this.superior_init(); + that.superior_init(); - this.add_field(ipa_text_widget({name:'cn', label:'Name', undo: false})); - this.add_field(ipa_text_widget({name:'description', label:'Description', undo: false})); + that.add_field(ipa_text_widget({name:'cn', label:'Name', undo: false})); + that.add_field(ipa_text_widget({name:'description', label:'Description', undo: false})); }; return that; @@ -91,10 +93,6 @@ function ipa_hbacsvcgroup_search_facet(spec) { var that = ipa_search_facet(spec); - that.get_action_panel = function() { - return $('#hbac .action-panel'); - }; - that.init = function() { that.create_column({name:'cn', label:'Group', primary_key: true}); @@ -164,10 +162,6 @@ function ipa_hbacsvcgroup_details_facet(spec) { var that = ipa_details_facet(spec); - that.get_action_panel = function() { - return $('#hbac .action-panel'); - }; - that.init = function() { var section = ipa_details_list_section({ @@ -185,14 +179,44 @@ function ipa_hbacsvcgroup_details_facet(spec) { return that; } -function ipa_hbacsvcgroup_association_facet(spec) { +function ipa_hbacsvcgroup_member_hbacsvc_facet(spec) { spec = spec || {}; var that = ipa_association_facet(spec); - that.get_action_panel = function() { - return $('#hbac .action-panel'); + that.init = function() { + + var column = that.create_column({ + name: 'cn', + label: 'Service', + primary_key: true + }); + + column.setup = function(container, record) { + container.empty(); + + var value = record[column.name]; + value = value ? value.toString() : ''; + + $('', { + 'href': '#'+value, + 'html': value, + 'click': function (value) { + return function() { + var state = IPA.tab_state(that.other_entity); + state[that.other_entity + '-facet'] = 'details'; + state[that.other_entity + '-pkey'] = value; + $.bbq.pushState(state); + return false; + } + }(value) + }).appendTo(container); + }; + + that.create_column({name: 'description', label: 'Description'}); + + that.association_facet_init(); }; return that; diff --git a/install/static/host.js b/install/static/host.js index 37222337..5cfceba5 100644 --- a/install/static/host.js +++ b/install/static/host.js @@ -58,10 +58,7 @@ function ipa_host() { }); that.add_facet(facet); - facet = ipa_association_facet({ - 'name': 'associate' - }); - that.add_facet(facet); + that.create_association_facets(); that.entity_init(); }; @@ -100,10 +97,10 @@ function ipa_host_search_facet(spec) { that.init = function() { - this.create_column({name:'fqdn', label:'Name'}); - this.create_column({name:'description', label:'Description'}); - this.create_column({name:'enrolled', label:'Enrolled?'}); - this.create_column({name:'manages', label:'Manages?'}); + that.create_column({name:'fqdn', label:'Name'}); + that.create_column({name:'description', label:'Description'}); + that.create_column({name:'enrolled', label:'Enrolled?'}); + that.create_column({name:'manages', label:'Manages?'}); that.search_facet_init(); }; @@ -140,6 +137,11 @@ function ipa_host_details_facet(spec) { 'label': 'Server Host Name' }); + section.create_field({ + 'name': 'description', + 'label': 'Description' + }); + section = ipa_details_list_section({ 'name': 'enrollment', 'label': 'Enrollment' diff --git a/install/static/ipa.js b/install/static/ipa.js index 6167b9f4..6f44e358 100644 --- a/install/static/ipa.js +++ b/install/static/ipa.js @@ -116,24 +116,21 @@ var IPA = ( function () { }; - that.show_page = function (entity_name, facet_name, other_entity) { + that.show_page = function (entity_name, facet_name) { var state = {}; state[entity_name + '-facet'] = facet_name; - state[entity_name + '-enroll'] = other_entity ? other_entity : ''; $.bbq.pushState(state); }; - that.switch_and_show_page = function ( - this_entity, facet_name, pkey, other_entity) { + that.switch_and_show_page = function (this_entity, facet_name, pkey) { if (!pkey){ - that.show_page(this_entity, facet_name, other_entity); + that.show_page(this_entity, facet_name); return; } var state = {}; state[this_entity+'-pkey'] = pkey; state[this_entity + '-facet'] = facet_name; - state[this_entity + '-enroll'] = other_entity ? other_entity : ''; $.bbq.pushState(state); }; @@ -267,7 +264,9 @@ function ipa_batch_command(spec) { function(xhr, text_status, error_thrown) { // TODO: undefined behavior if (that.on_error) that.on_error(xhr, text_status, error_thrown) - } + }, + null, + that.name ); }; @@ -295,7 +294,7 @@ function ipa_cmd(name, args, options, win_callback, fail_callback, objname, comm buttons: { 'Retry': function () { IPA.error_dialog.dialog('close'); - ipa_cmd(name, args, options, win_callback, fail_callback, objname); + ipa_cmd(name, args, options, win_callback, fail_callback, objname, command_name); }, 'Cancel': function () { IPA.error_dialog.dialog('close'); diff --git a/install/static/search.js b/install/static/search.js index 5b42cf11..e79a534a 100644 --- a/install/static/search.js +++ b/install/static/search.js @@ -53,8 +53,7 @@ function ipa_search_widget(spec) { }).appendTo(search_filter); var action_panel = that.facet.get_action_panel(); - - var li = $('.action-controls',action_panel); + var li = $('.action-controls', action_panel); var search_buttons = $('', { 'class': 'search-buttons' @@ -243,15 +242,6 @@ function ipa_search_widget(spec) { return that; } -function ipa_search_column(spec) { - - spec = spec || {}; - - var that = ipa_column_widget(spec); - - return that; -} - function ipa_search_facet(spec) { spec = spec || {}; @@ -295,11 +285,34 @@ function ipa_search_facet(spec) { }; that.create_column = function(spec) { - var column = ipa_search_column(spec); + var column = ipa_column(spec); that.add_column(column); return column; }; + that.setup_column = function(column) { + column.setup = function(container, record) { + container.empty(); + + var value = record[column.name]; + value = value ? value.toString() : ''; + + $('', { + 'href': '#'+value, + 'html': value, + 'click': function (value) { + return function() { + var state = IPA.tab_state(that.entity_name); + state[that.entity_name + '-facet'] = 'details'; + state[that.entity_name + '-pkey'] = value; + $.bbq.pushState(state); + return false; + } + }(value) + }).appendTo(container); + }; + }; + function init() { that.table = ipa_search_widget({ @@ -313,10 +326,11 @@ function ipa_search_facet(spec) { var column = that.columns[i]; var param_info = ipa_get_param_info(that.entity_name, column.name); - var primary_key = param_info && param_info['primary_key']; + column.primary_key = param_info && param_info['primary_key']; - column.primary_key = primary_key; - column.link = primary_key; + if (column.primary_key) { + that.setup_column(column); + } that.table.add_column(column); } diff --git a/install/static/service.js b/install/static/service.js index 229602dd..39081289 100644 --- a/install/static/service.js +++ b/install/static/service.js @@ -53,8 +53,10 @@ function ipa_service() { }); that.add_facet(facet); - facet = ipa_association_facet({ - 'name': 'associate' + facet = ipa_service_managedby_host_facet({ + 'name': 'managedby_host', + 'label': 'Hosts', + 'other_entity': 'host' }); that.add_facet(facet); @@ -157,7 +159,7 @@ function ipa_service_search_facet(spec) { that.init = function() { - this.create_column({name:'krbprincipalname', label:'Principal'}); + that.create_column({name:'krbprincipalname', label:'Principal'}); that.search_facet_init(); }; @@ -392,3 +394,46 @@ function service_certificate_status_widget(spec) { return that; } + +function ipa_service_managedby_host_facet(spec) { + + spec = spec || {}; + + var that = ipa_association_facet(spec); + + that.init = function() { + + var column = that.create_column({ + name: 'fqdn', + label: 'Name', + primary_key: true + }); + + column.setup = function(container, record) { + container.empty(); + + var value = record[column.name]; + value = value ? value.toString() : ''; + + $('', { + 'href': '#'+value, + 'html': value, + 'click': function (value) { + return function() { + var state = IPA.tab_state(that.other_entity); + state[that.other_entity + '-facet'] = 'details'; + state[that.other_entity + '-pkey'] = value; + $.bbq.pushState(state); + return false; + } + }(value) + }).appendTo(container); + }; + + that.create_column({name: 'description', label: 'Description'}); + + that.association_facet_init(); + }; + + return that; +} \ No newline at end of file diff --git a/install/static/sudocmd.js b/install/static/sudocmd.js index b4492c25..0e335627 100755 --- a/install/static/sudocmd.js +++ b/install/static/sudocmd.js @@ -65,10 +65,10 @@ function ipa_sudocmd_add_dialog(spec) { that.init = function() { - this.superior_init(); + that.superior_init(); - this.add_field(ipa_text_widget({name:'sudocmd', label:'Command', undo: false})); - this.add_field(ipa_text_widget({name:'description', label:'Description', undo: false})); + that.add_field(ipa_text_widget({name:'sudocmd', label:'Command', undo: false})); + that.add_field(ipa_text_widget({name:'description', label:'Description', undo: false})); }; return that; @@ -80,10 +80,6 @@ function ipa_sudocmd_search_facet(spec) { var that = ipa_search_facet(spec); - that.get_action_panel = function() { - return $('#sudorule .action-panel'); - }; - that.init = function() { that.create_column({name:'sudocmd', label:'Command', primary_key: true}); @@ -153,10 +149,6 @@ function ipa_sudocmd_details_facet(spec) { that.superior_create = that.superior('create'); that.superior_setup = that.superior('setup'); - that.get_action_panel = function() { - return $('#sudorule .action-panel'); - }; - that.init = function() { var section = ipa_details_list_section({ diff --git a/install/static/sudocmdgroup.js b/install/static/sudocmdgroup.js index 2e53ce79..c8b7edf8 100755 --- a/install/static/sudocmdgroup.js +++ b/install/static/sudocmdgroup.js @@ -53,8 +53,10 @@ function ipa_sudocmdgroup() { }); that.add_facet(facet); - facet = ipa_sudocmdgroup_association_facet({ - 'name': 'associate' + facet = ipa_sudocmdgroup_member_sudocmd_facet({ + 'name': 'member_sudocmd', + 'label': 'Commands', + 'other_entity': 'sudocmd' }); that.add_facet(facet); @@ -76,10 +78,10 @@ function ipa_sudocmdgroup_add_dialog(spec) { that.init = function() { - this.superior_init(); + that.superior_init(); - this.add_field(ipa_text_widget({name:'cn', label:'Name', undo: false})); - this.add_field(ipa_text_widget({name:'description', label:'Description', undo: false})); + that.add_field(ipa_text_widget({name:'cn', label:'Name', undo: false})); + that.add_field(ipa_text_widget({name:'description', label:'Description', undo: false})); }; return that; @@ -91,10 +93,6 @@ function ipa_sudocmdgroup_search_facet(spec) { var that = ipa_search_facet(spec); - that.get_action_panel = function() { - return $('#sudorule .action-panel'); - }; - that.init = function() { that.create_column({name:'cn', label:'Group', primary_key: true}); @@ -164,10 +162,6 @@ function ipa_sudocmdgroup_details_facet(spec) { var that = ipa_details_facet(spec); - that.get_action_panel = function() { - return $('#sudorule .action-panel'); - }; - that.init = function() { var section = ipa_details_list_section({ @@ -185,14 +179,44 @@ function ipa_sudocmdgroup_details_facet(spec) { return that; } -function ipa_sudocmdgroup_association_facet(spec) { +function ipa_sudocmdgroup_member_sudocmd_facet(spec) { spec = spec || {}; var that = ipa_association_facet(spec); - that.get_action_panel = function() { - return $('#sudorule .action-panel'); + that.init = function() { + + var column = that.create_column({ + name: 'sudocmd', + label: 'Command', + primary_key: true + }); + + column.setup = function(container, record) { + container.empty(); + + var value = record[column.name]; + value = value ? value.toString() : ''; + + $('', { + 'href': '#'+value, + 'html': value, + 'click': function (value) { + return function() { + var state = IPA.tab_state(that.other_entity); + state[that.other_entity + '-facet'] = 'details'; + state[that.other_entity + '-pkey'] = value; + $.bbq.pushState(state); + return false; + } + }(value) + }).appendTo(container); + }; + + that.create_column({name: 'description', label: 'Description'}); + + that.association_facet_init(); }; return that; diff --git a/install/static/test/data/group_member_user.json b/install/static/test/data/group_member_user.json new file mode 100644 index 00000000..636e7f0e --- /dev/null +++ b/install/static/test/data/group_member_user.json @@ -0,0 +1,150 @@ +{ + "error": null, + "id": 0, + "result": { + "count": 2, + "results": [ + { + "error": null, + "result": { + "cn": [ + "Administrator" + ], + "dn": "uid=admin,cn=users,cn=accounts,dc=dev,dc=example,dc=com", + "gecos": [ + "Administrator" + ], + "gidnumber": [ + "1662072955" + ], + "homedirectory": [ + "/home/admin" + ], + "ipauniqueid": [ + "ffb8d002-f46c-11df-8cc1-00163e72f2d9" + ], + "krblastpwdchange": [ + "20101120061333Z" + ], + "krbpasswordexpiration": [ + "20110218061333Z" + ], + "krbprincipalname": [ + "admin@DEV.EXAMPLE.COM" + ], + "loginshell": [ + "/bin/bash" + ], + "memberof_group": [ + "admins", + "ipausers" + ], + "memberof_rolegroup": [ + "replicaadmin" + ], + "memberof_taskgroup": [ + "managereplica", + "deletereplica" + ], + "mepmanagedentry": [ + "cn=admin,cn=groups,cn=accounts,dc=dev,dc=example,dc=com" + ], + "nsaccountlock": [ + "False" + ], + "objectclass": [ + "top", + "person", + "posixaccount", + "krbprincipalaux", + "krbticketpolicyaux", + "inetuser", + "ipaobject", + "mepOriginEntry" + ], + "sn": [ + "Administrator" + ], + "uid": [ + "admin" + ], + "uidnumber": [ + "1662072955" + ] + }, + "summary": null, + "value": "admin" + }, + { + "error": null, + "result": { + "cn": [ + "Test User" + ], + "dn": "uid=test,cn=users,cn=accounts,dc=dev,dc=example,dc=com", + "gecos": [ + "test" + ], + "gidnumber": [ + "1662072958" + ], + "givenname": [ + "Test" + ], + "homedirectory": [ + "/home/test" + ], + "ipauniqueid": [ + "c0724e5e-f472-11df-8186-00163e72f2d9" + ], + "krbprincipalname": [ + "test@DEV.EXAMPLE.COM" + ], + "krbpwdpolicyreference": [ + "cn=global_policy,cn=DEV.EXAMPLE.COM,cn=kerberos,dc=dev,dc=example,dc=com" + ], + "loginshell": [ + "/bin/sh" + ], + "mail": [ + "test" + ], + "memberof_group": [ + "ipausers", + "editors" + ], + "mepmanagedentry": [ + "cn=test,cn=groups,cn=accounts,dc=dev,dc=example,dc=com" + ], + "nsaccountlock": [ + "False" + ], + "objectclass": [ + "top", + "person", + "organizationalperson", + "inetorgperson", + "inetuser", + "posixaccount", + "krbprincipalaux", + "krbticketpolicyaux", + "radiusprofile", + "ipaobject", + "mepOriginEntry" + ], + "sn": [ + "User" + ], + "uid": [ + "test" + ], + "uidnumber": [ + "1662072958" + ] + }, + "summary": null, + "value": "test" + } + ] + } +} diff --git a/install/static/test/data/hbacsvcgroup_member_hbacsvc.json b/install/static/test/data/hbacsvcgroup_member_hbacsvc.json new file mode 100644 index 00000000..9819a2f2 --- /dev/null +++ b/install/static/test/data/hbacsvcgroup_member_hbacsvc.json @@ -0,0 +1,57 @@ +{ + "error": null, + "id": 0, + "result": { + "count": 2, + "results": [ + { + "error": null, + "result": { + "cn": [ + "sudo" + ], + "description": [ + "sudo" + ], + "dn": "cn=sudo,cn=hbacservices,cn=accounts,dc=dev,dc=example,dc=com", + "ipauniqueid": [ + "42927a86-f46d-11df-8cc1-00163e72f2d9" + ], + "memberof": [ + "cn=SUDO,cn=hbacservicegroups,cn=accounts,dc=dev,dc=example,dc=com" + ], + "objectclass": [ + "ipahbacservice", + "ipaobject" + ] + }, + "summary": null, + "value": "sudo" + }, + { + "error": null, + "result": { + "cn": [ + "sudo-i" + ], + "description": [ + "sudo-i" + ], + "dn": "cn=sudo-i,cn=hbacservices,cn=accounts,dc=dev,dc=example,dc=com", + "ipauniqueid": [ + "42970a6a-f46d-11df-8cc1-00163e72f2d9" + ], + "memberof": [ + "cn=SUDO,cn=hbacservicegroups,cn=accounts,dc=dev,dc=example,dc=com" + ], + "objectclass": [ + "ipahbacservice", + "ipaobject" + ] + }, + "summary": null, + "value": "sudo-i" + } + ] + } +} diff --git a/install/static/test/data/host_show.json b/install/static/test/data/host_show.json new file mode 100644 index 00000000..b858970e --- /dev/null +++ b/install/static/test/data/host_show.json @@ -0,0 +1,77 @@ +{ + "error": null, + "id": 0, + "result": { + "result": { + "attributelevelrights": { + "aci": "rscwo", + "cn": "rscwo", + "description": "rscwo", + "enrolledby": "rsc", + "fqdn": "rscwo", + "ipaclientversion": "rscwo", + "ipauniqueid": "rsc", + "krbcanonicalname": "rscwo", + "krbextradata": "rscwo", + "krblastfailedauth": "rscwo", + "krblastpwdchange": "rscwo", + "krblastsuccessfulauth": "rscwo", + "krbloginfailedcount": "rscwo", + "krbobjectreferences": "rscwo", + "krbpasswordexpiration": "rscwo", + "krbprincipalaliases": "rscwo", + "krbprincipalexpiration": "rscwo", + "krbprincipalkey": "wo", + "krbprincipalname": "rscwo", + "krbprincipaltype": "rscwo", + "krbpwdhistory": "rscwo", + "krbpwdpolicyreference": "rscwo", + "krbticketpolicyreference": "rscwo", + "krbupenabled": "rscwo", + "l": "rscwo", + "managedby": "rscwo", + "memberof": "rsc", + "nsaccountlock": "rscwo", + "nshardwareplatform": "rscwo", + "nshostlocation": "rscwo", + "nsosversion": "rscwo", + "objectclass": "rscwo", + "serverhostname": "rsc", + "usercertificate": "rscwo", + "userpassword": "wo" + }, + "cn": [ + "test.example.com" + ], + "dn": "fqdn=test.example.com,cn=computers,cn=accounts,dc=dev,dc=example,dc=com", + "fqdn": [ + "test.example.com" + ], + "has_keytab": false, + "ipauniqueid": [ + "ac28dca0-f3b5-11df-879f-00163e72f2d9" + ], + "krbprincipalname": [ + "host/test.example.com@DEV.EXAMPLE.COM" + ], + "managedby": [ + "fqdn=test.example.com,cn=computers,cn=accounts,dc=dev,dc=example,dc=com" + ], + "objectclass": [ + "ipaobject", + "nshost", + "ipahost", + "pkiuser", + "ipaservice", + "krbprincipalaux", + "krbprincipal", + "top" + ], + "serverhostname": [ + "test" + ] + }, + "summary": null, + "value": "test.example.com" + } +} diff --git a/install/static/test/data/hostgroup_member_host.json b/install/static/test/data/hostgroup_member_host.json new file mode 100644 index 00000000..c4c7dfa9 --- /dev/null +++ b/install/static/test/data/hostgroup_member_host.json @@ -0,0 +1,70 @@ +{ + "error": null, + "id": 0, + "result": { + "count": 1, + "results": [ + { + "error": null, + "result": { + "cn": [ + "dev.example.com" + ], + "description": [ + "Development" + ], + "dn": "fqdn=dev.example.com,cn=computers,cn=accounts,dc=dev,dc=example,dc=com", + "fqdn": [ + "dev.example.com" + ], + "has_keytab": true, + "ipauniqueid": [ + "0568a298-f46d-11df-9ef8-00163e72f2d9" + ], + "krbextradata": [ + { + "__base64__": "AAKTZudMYWRtaW4vYWRtaW5AREVWLkVYQU1QTEUuQ09NAA==" + }, + { + "__base64__": "AAgBAA==" + } + ], + "krblastpwdchange": [ + "20101120061131Z" + ], + "krbpasswordexpiration": [ + "19700101000000Z" + ], + "krbprincipalname": [ + "host/dev.example.com@DEV.EXAMPLE.COM" + ], + "krbticketflags": [ + "0" + ], + "managedby_host": [ + "dev.example.com" + ], + "memberof_hostgroup": [ + "test" + ], + "objectclass": [ + "top", + "ipaobject", + "nshost", + "ipahost", + "ipaservice", + "pkiuser", + "krbprincipalaux", + "krbprincipal", + "krbticketpolicyaux" + ], + "serverhostname": [ + "dev" + ] + }, + "summary": null, + "value": "dev.example.com" + } + ] + } +} diff --git a/install/static/test/data/service_managedby_host.json b/install/static/test/data/service_managedby_host.json new file mode 100644 index 00000000..181fc5b9 --- /dev/null +++ b/install/static/test/data/service_managedby_host.json @@ -0,0 +1,110 @@ +{ + "error": null, + "id": 0, + "result": { + "count": 1, + "results": [ + { + "error": null, + "result": { + "attributelevelrights": { + "aci": "rscwo", + "cn": "rscwo", + "description": "rscwo", + "enrolledby": "rsc", + "fqdn": "rscwo", + "ipaclientversion": "rscwo", + "ipauniqueid": "rscwo", + "krbcanonicalname": "rscwo", + "krbextradata": "rscwo", + "krblastfailedauth": "rscwo", + "krblastpwdchange": "rscwo", + "krblastsuccessfulauth": "rscwo", + "krbloginfailedcount": "rscwo", + "krbmaxrenewableage": "rscwo", + "krbmaxticketlife": "rscwo", + "krbobjectreferences": "rscwo", + "krbpasswordexpiration": "rscwo", + "krbprincipalaliases": "rscwo", + "krbprincipalexpiration": "rscwo", + "krbprincipalkey": "wo", + "krbprincipalname": "rscwo", + "krbprincipaltype": "rscwo", + "krbpwdhistory": "rscwo", + "krbpwdpolicyreference": "rscwo", + "krbticketflags": "rscwo", + "krbticketpolicyreference": "rscwo", + "krbupenabled": "rscwo", + "l": "rscwo", + "managedby": "rscwo", + "memberof": "rsc", + "nsaccountlock": "rscwo", + "nshardwareplatform": "rscwo", + "nshostlocation": "rscwo", + "nsosversion": "rscwo", + "objectclass": "rscwo", + "serverhostname": "rsc", + "usercertificate": "rscwo", + "userpassword": "wo" + }, + "cn": [ + "dev.example.com" + ], + "description": [ + "Development" + ], + "dn": "fqdn=dev.example.com,cn=computers,cn=accounts,dc=dev,dc=example,dc=com", + "fqdn": [ + "dev.example.com" + ], + "has_keytab": true, + "ipauniqueid": [ + "0568a298-f46d-11df-9ef8-00163e72f2d9" + ], + "krbextradata": [ + { + "__base64__": "AAKTZudMYWRtaW4vYWRtaW5AREVWLkVYQU1QTEUuQ09NAA==" + }, + { + "__base64__": "AAgBAA==" + } + ], + "krblastpwdchange": [ + "20101120061131Z" + ], + "krbpasswordexpiration": [ + "19700101000000Z" + ], + "krbprincipalname": [ + "host/dev.example.com@DEV.EXAMPLE.COM" + ], + "krbticketflags": [ + "0" + ], + "managedby_host": [ + "dev.example.com" + ], + "memberof_hostgroup": [ + "test" + ], + "objectclass": [ + "top", + "ipaobject", + "nshost", + "ipahost", + "ipaservice", + "pkiuser", + "krbprincipalaux", + "krbprincipal", + "krbticketpolicyaux" + ], + "serverhostname": [ + "dev" + ] + }, + "summary": null, + "value": "dev.example.com" + } + ] + } +} diff --git a/install/static/test/data/sudocmdgroup_member_sudocmd.json b/install/static/test/data/sudocmdgroup_member_sudocmd.json new file mode 100644 index 00000000..5f017f9c --- /dev/null +++ b/install/static/test/data/sudocmdgroup_member_sudocmd.json @@ -0,0 +1,57 @@ +{ + "error": null, + "id": 0, + "result": { + "count": 2, + "results": [ + { + "error": null, + "result": { + "description": [ + "more" + ], + "dn": "sudocmd=/usr/bin/more,cn=sudocmds,cn=accounts,dc=dev,dc=example,dc=com", + "ipauniqueid": [ + "a9138c9a-fc0c-11df-8584-00163e72f2d9" + ], + "memberof": [ + "cn=test,cn=sudocmdgroups,cn=accounts,dc=dev,dc=example,dc=com" + ], + "objectclass": [ + "ipaobject", + "ipasudocmd" + ], + "sudocmd": [ + "/usr/bin/more" + ] + }, + "summary": null, + "value": "/usr/bin/more" + }, + { + "error": null, + "result": { + "description": [ + "less" + ], + "dn": "sudocmd=/usr/bin/less,cn=sudocmds,cn=accounts,dc=dev,dc=example,dc=com", + "ipauniqueid": [ + "44ce29ee-fc38-11df-b995-00163e72f2d9" + ], + "memberof": [ + "cn=test,cn=sudocmdgroups,cn=accounts,dc=dev,dc=example,dc=com" + ], + "objectclass": [ + "ipaobject", + "ipasudocmd" + ], + "sudocmd": [ + "/usr/bin/less" + ] + }, + "summary": null, + "value": "/usr/bin/less" + } + ] + } +} diff --git a/install/static/test/data/user_memberof_group.json b/install/static/test/data/user_memberof_group.json new file mode 100644 index 00000000..e8f7a8fa --- /dev/null +++ b/install/static/test/data/user_memberof_group.json @@ -0,0 +1,64 @@ +{ + "error": null, + "id": 0, + "result": { + "count": 2, + "results": [ + { + "error": null, + "result": { + "cn": [ + "ipausers" + ], + "description": [ + "Default group for all users" + ], + "dn": "cn=ipausers,cn=groups,cn=accounts,dc=dev,dc=example,dc=com", + "gidnumber": [ + "1662072956" + ], + "member_user": [ + "test", + "admin" + ], + "objectclass": [ + "top", + "groupofnames", + "nestedgroup", + "ipausergroup", + "posixgroup" + ] + }, + "summary": null, + "value": "ipausers" + }, + { + "error": null, + "result": { + "cn": [ + "editors" + ], + "description": [ + "Limited admins who can edit other users" + ], + "dn": "cn=editors,cn=groups,cn=accounts,dc=dev,dc=example,dc=com", + "gidnumber": [ + "1662072957" + ], + "member_user": [ + "test" + ], + "objectclass": [ + "top", + "groupofnames", + "posixgroup", + "ipausergroup", + "nestedGroup" + ] + }, + "summary": null, + "value": "editors" + } + ] + } +} diff --git a/install/static/test/entity_tests.js b/install/static/test/entity_tests.js index 8f016efe..504775eb 100644 --- a/install/static/test/entity_tests.js +++ b/install/static/test/entity_tests.js @@ -83,57 +83,60 @@ test('Testing ipa_facet_setup_views().', function() { IPA.add_entity(entity); - entity.add_facet(ipa_search_facet({ + var facet = ipa_search_facet({ 'name': 'search', 'label': 'Search' - })); - - - var facet = ipa_association_facet({ - 'name': 'associate' }); entity.add_facet(facet); + entity.create_association_facets(); + var container = $('
    '); + entity.init(); + entity.setup(container); + var counter = 0; - IPA.switch_and_show_page = function(entity_name, facet_name, other_entity) { + IPA.switch_and_show_page = function(entity_name, facet_name, pkey) { counter++; }; - facet.create_action_panel(container); - //Container now has two divs, one for the action panel one for content - var list = container.children().last().children(); - var views = list.children(); + var action_panel = facet.get_action_panel(); + ok(action_panel.length, 'action panel exists'); + + var ul = $('ul', action_panel); + + var views = ul.children(); equals( - views.length, 5, + views.length, 6, 'Checking number of views' ); - facet = views.first(); - ok( facet.hasClass('entity-search', + var li = views.first(); + ok( li.hasClass('search-facet'), 'Checking the search facet' ); - facet = facet.next(); + li = li.next(); // skip action controls var attribute_members = IPA.metadata['user'].attribute_members; - for (attribute_member in attribute_members) { + for (var attribute_member in attribute_members) { var objects = attribute_members[attribute_member]; for (var i = 0; i < objects.length; i++) { var object = objects[i]; + var title = attribute_member+'_'+object; + + li = li.next(); + var value = li.attr('title'); equals( - facet.attr('title'), object, - 'Checking the '+object+' facet' + value, title, + 'Checking the '+title+' facet' ); - facet = facet.next(); } } - var action_panel = $('.action-panel', container); - ok(action_panel.length, 'action panel exists'); var pkey_input = $('input[name=pkey]', action_panel); ok(pkey_input.length,'pkey input exists'); var search_facets = $('li.search-facet', action_panel); @@ -148,7 +151,7 @@ test('Testing ipa_facet_setup_views().', function() { entity_facet.click(); } -// equals(4, counter,'four clicks'); + equals(counter, 0, 'links are disabled'); IPA.switch_and_show_page = orig_switch_and_show_page; }); diff --git a/install/static/widget.js b/install/static/widget.js index c2184c64..ea6821d1 100755 --- a/install/static/widget.js +++ b/install/static/widget.js @@ -422,47 +422,25 @@ function ipa_button_widget(spec) { } -function ipa_column_widget(spec) { +function ipa_column(spec) { spec = spec || {}; - // TODO: should not inherit from widget - var that = ipa_widget(spec); + var that = {}; + that.name = spec.name; + that.label = spec.label; that.primary_key = spec.primary_key; that.setup = spec.setup || setup; - that.link = spec.link; - that.other_entity = spec.other_entity; - - function setup(container, name, value, record) { - - var span = $('span[name="'+name+'"]', container); - - var param_info = ipa_get_param_info(that.entity_name, name); - var primary_key = that.primary_key || param_info && param_info['primary_key']; - - if (primary_key && that.link) { - var link = $('', { - 'href': '#'+value, - 'html': value, - 'click': function (value) { - return function() { - var target_entity = that.other_entity || - that.entity_name; - var state = IPA.tab_state(target_entity); - state[target_entity + '-facet'] = 'details'; - state[target_entity + '-pkey'] = value; - - $.bbq.pushState(state); - return false; - } - }(value) - }); - span.html(link); - } else { - span.html(value); - } + function setup(container, record) { + + container.empty(); + + var value = record[that.name]; + value = value ? value.toString() : ''; + + container.append(value); } return that; @@ -494,8 +472,20 @@ function ipa_table_widget(spec) { that.columns_by_name[column.name] = column; }; + that.set_columns = function(columns) { + that.clear_columns(); + for (var i=0; i', { 'style': 'float: left;', 'html': label @@ -656,8 +643,8 @@ function ipa_table_widget(spec) { for (var i=0; i').appendTo(that.container); that.filter_field = $('', { @@ -921,6 +934,8 @@ function ipa_adder_dialog(spec) { that.setup = function() { + // do not call that.dialog_setup(); + that.add_button.click(function(){ var values = $(':selected', that.available_list).detach(); values.each(function(i, selected){ @@ -946,7 +961,7 @@ function ipa_adder_dialog(spec) { 'Cancel': that.close }; - that.superior_open(container); + that.dialog_open(container); }; that.get_filter = function() { @@ -961,7 +976,12 @@ function ipa_adder_dialog(spec) { that.selected_list.html(''); }; - that.add_available_value = function(value) { + that.add_available_value = function(record) { + + var name = that.columns[0].name; + var value = record[name]; + value = value ? value.toString() : ''; + $('',{ 'value': value, 'html': value @@ -987,6 +1007,9 @@ function ipa_adder_dialog(spec) { that.container.dialog('close'); }; + that.adder_dialog_create = that.create; + that.adder_dialog_setup = that.setup; + return that; } @@ -1002,8 +1025,6 @@ function ipa_deleter_dialog(spec) { that.title = spec.title || IPA.messages.button.remove; that.remove = spec.remove; - that.superior_open = that.superior('open'); - that.values = spec.values || []; that.add_value = function(value) { @@ -1035,7 +1056,7 @@ function ipa_deleter_dialog(spec) { 'Cancel': that.close }; - that.superior_open(container); + that.dialog_open(container); }; return that; -- cgit