diff options
author | Endi S. Dewata <edewata@redhat.com> | 2010-11-16 18:10:40 -0600 |
---|---|---|
committer | Adam Young <ayoung@redhat.com> | 2010-11-18 10:12:18 -0500 |
commit | 5da8313b668340494f06afe6d3459f368948588f (patch) | |
tree | c19b19cf32bd8487cf42f21348a1ca97f8fe2f6c /install/static | |
parent | b42271c47d0e672f1a88585f5a87f5db8522f634 (diff) | |
download | freeipa-5da8313b668340494f06afe6d3459f368948588f.tar.gz freeipa-5da8313b668340494f06afe6d3459f368948588f.tar.xz freeipa-5da8313b668340494f06afe6d3459f368948588f.zip |
Service and Host Provisioning
The service and host details pages have been modified to display Kerberos
key provisioning status and to provide a way to unprovision. The host
enrollment via OTP has not been implemented yet.
The ipa_details_field has been modified to remove any old <dd> tags it
created in the previous load operation. This is to support other widgets
that need to perform load operation without removing <dd> tags.
The certificate_status_panel has been converted into a widget. The host
entity has been rewritten using the new framework.
The unit tests has been updated.
Diffstat (limited to 'install/static')
-rw-r--r-- | install/static/add.js | 1 | ||||
-rwxr-xr-x | install/static/certificate.js | 183 | ||||
-rw-r--r-- | install/static/details.js | 229 | ||||
-rw-r--r-- | install/static/entity.js | 2 | ||||
-rw-r--r-- | install/static/host.js | 367 | ||||
-rw-r--r-- | install/static/ipa.css | 14 | ||||
-rw-r--r-- | install/static/search.js | 2 | ||||
-rw-r--r-- | install/static/service.js | 220 | ||||
-rw-r--r-- | install/static/test/details_tests.js | 69 | ||||
-rw-r--r-- | install/static/user.js | 56 | ||||
-rwxr-xr-x | install/static/widget.js | 1 |
11 files changed, 790 insertions, 354 deletions
diff --git a/install/static/add.js b/install/static/add.js index 6b31a6ed..1ebd2888 100644 --- a/install/static/add.js +++ b/install/static/add.js @@ -95,6 +95,7 @@ function ipa_add_dialog(spec) { }; that.superior_init = that.superior('init'); + that.add_dialog_init = that.init; return that; } diff --git a/install/static/certificate.js b/install/static/certificate.js index affc58aa..265568a0 100755 --- a/install/static/certificate.js +++ b/install/static/certificate.js @@ -389,12 +389,13 @@ function certificate_request_dialog(spec) { return that; } -function certificate_status_panel(spec) { - var that = $('<div/>'); +function certificate_status_widget(spec) { + spec = spec || {}; - that.entity_type = spec.entity_type; - that.entity_label = spec.entity_label || that.entity_type; + var that = ipa_widget(spec); + + that.entity_label = spec.entity_label || that.entity_name; that.result = spec.result; @@ -403,17 +404,16 @@ function certificate_status_panel(spec) { that.get_entity_principal = spec.get_entity_principal; that.get_entity_certificate = spec.get_entity_certificate; - var li1, li2, li3; + that.create = function(container) { - function init() { - var pkey = that.get_entity_pkey(that.result); + that.widget_create(container); - var table = $('<table/>').appendTo(that); + var table = $('<table/>').appendTo(container); var tr = $('<tr/>').appendTo(table); var td = $('<td/>').appendTo(tr); - li1 = $('<li/>', { + $('<li/>', { 'class': 'certificate-status-valid' }).appendTo(td); @@ -421,88 +421,141 @@ function certificate_status_panel(spec) { td.append('Valid Certificate Present:'); td = $('<td/>').appendTo(tr); - ipa_button({ - 'id': 'get_button', + + $('<input/>', { + 'type': 'button', + 'name': 'get', + 'value': 'Get' + }).appendTo(td); + + $('<input/>', { + 'type': 'button', + 'name': 'revoke', + 'value': 'Revoke' + }).appendTo(td); + + $('<input/>', { + 'type': 'button', + 'name': 'view', + 'value': 'View' + }).appendTo(td); + + tr = $('<tr/>').appendTo(table); + + td = $('<td/>').appendTo(tr); + $('<li/>', { + 'class': 'certificate-status-revoked' + }).appendTo(td); + + td = $('<td/>').appendTo(tr); + td.append('Certificate Revoked:'); + + td = $('<td/>').appendTo(tr); + td.append($('<span/>', { + 'name': 'revocation_reason' + })); + td.append(' '); + + $('<input/>', { + 'type': 'button', + 'name': 'restore', + 'value': 'Restore' + }).appendTo(td); + + tr = $('<tr/>').appendTo(table); + + td = $('<td/>').appendTo(tr); + $('<li/>', { + 'class': 'certificate-status-missing' + }).appendTo(td); + + td = $('<td/>').appendTo(tr); + td.append('No Valid Certificate:'); + + td = $('<td/>').appendTo(tr); + $('<input/>', { + 'type': 'button', + 'name': 'create', + 'value': 'New Certificate' + }).appendTo(td); + }; + + that.setup = function(container) { + + that.container = container; + + that.valid = $('li.certificate-status-valid', that.container); + that.revoked = $('li.certificate-status-revoked', that.container); + that.missing = $('li.certificate-status-missing', that.container); + + var button = $('input[name=get]', that.container); + that.get_button = ipa_button({ 'label': 'Get', 'click': function() { - ipa_cmd(that.entity_type+'_show', [pkey], {}, + ipa_cmd(that.entity_name+'_show', [that.pkey], {}, function(data, text_status, xhr) { get_certificate(data.result.result); } ); } - }).appendTo(td); + }); + button.replaceWith(that.get_button); - ipa_button({ - 'id': 'revoke_button', + button = $('input[name=revoke]', that.container); + that.revoke_button = ipa_button({ 'label': 'Revoke', 'click': function() { - ipa_cmd(that.entity_type+'_show', [pkey], {}, + ipa_cmd(that.entity_name+'_show', [that.pkey], {}, function(data, text_status, xhr) { revoke_certificate(data.result.result); } ); } - }).appendTo(td); + }); + button.replaceWith(that.revoke_button); - ipa_button({ - 'id': 'view_button', + button = $('input[name=view]', that.container); + that.view_button = ipa_button({ 'label': 'View', 'click': function() { - ipa_cmd(that.entity_type+'_show', [pkey], {}, + ipa_cmd(that.entity_name+'_show', [that.pkey], {}, function(data, text_status, xhr) { view_certificate(data.result.result); } ); } - }).appendTo(td); - - tr = $('<tr/>').appendTo(table); - - td = $('<td/>').appendTo(tr); - li2 = $('<li/>', { - 'class': 'certificate-status-revoked' - }).appendTo(td); - - td = $('<td/>').appendTo(tr); - td.append('Certificate Revoked:'); + }); + button.replaceWith(that.view_button); - td = $('<td/>').appendTo(tr); - td.append($('<span/>', { - 'id': 'revocation_reason' - })); - td.append(' '); + that.revocation_reason = $('span[name=revocation_reason]', that.container); - ipa_button({ - 'id': 'restore_button', + button = $('input[name=restore]', that.container); + that.restore_button = ipa_button({ 'label': 'Restore', 'click': function() { - ipa_cmd(that.entity_type+'_show', [pkey], {}, + ipa_cmd(that.entity_name+'_show', [that.pkey], {}, function(data, text_status, xhr) { restore_certificate(data.result.result); } ); } - }).appendTo(td); - - tr = $('<tr/>').appendTo(table); - - td = $('<td/>').appendTo(tr); - li3 = $('<li/>', { - 'class': 'certificate-status-missing' - }).appendTo(td); - - td = $('<td/>').appendTo(tr); - td.append('No Valid Certificate:'); + }); + button.replaceWith(that.restore_button); - td = $('<td/>').appendTo(tr); - ipa_button({ - 'id': 'create_button', + button = $('input[name=create]', that.container); + that.create_button = ipa_button({ 'label': 'New Certificate', 'click': function() { request_certificate(that.result); } - }).appendTo(td); + }); + button.replaceWith(that.create_button); + }; + + that.load = function(container, result) { + + that.result = result; + that.pkey = that.get_entity_pkey(that.result); var entity_certificate = that.get_entity_certificate(that.result); if (entity_certificate) { @@ -510,18 +563,18 @@ function certificate_status_panel(spec) { } else { set_status(CERTIFICATE_STATUS_MISSING); } - } + }; function set_status(status, revocation_reason) { - li1.toggleClass('certificate-status-active', status == CERTIFICATE_STATUS_VALID); - li2.toggleClass('certificate-status-active', status == CERTIFICATE_STATUS_REVOKED); - li3.toggleClass('certificate-status-active', status == CERTIFICATE_STATUS_MISSING); - - $('#get_button', that).css('visibility', status == CERTIFICATE_STATUS_VALID ? 'visible' : 'hidden'); - $('#revoke_button', that).css('visibility', status == CERTIFICATE_STATUS_VALID ? 'visible' : 'hidden'); - $('#view_button', that).css('visibility', status == CERTIFICATE_STATUS_VALID ? 'visible' : 'hidden'); - $('#revocation_reason', that).html(revocation_reason == undefined ? '' : CRL_REASON[revocation_reason]); - $('#restore_button', that).css('visibility', revocation_reason == 6 ? 'visible' : 'hidden'); + that.valid.toggleClass('certificate-status-active', status == CERTIFICATE_STATUS_VALID); + that.revoked.toggleClass('certificate-status-active', status == CERTIFICATE_STATUS_REVOKED); + that.missing.toggleClass('certificate-status-active', status == CERTIFICATE_STATUS_MISSING); + + that.get_button.css('visibility', status == CERTIFICATE_STATUS_VALID ? 'visible' : 'hidden'); + that.revoke_button.css('visibility', status == CERTIFICATE_STATUS_VALID ? 'visible' : 'hidden'); + that.view_button.css('visibility', status == CERTIFICATE_STATUS_VALID ? 'visible' : 'hidden'); + that.revocation_reason.html(revocation_reason == undefined ? '' : CRL_REASON[revocation_reason]); + that.restore_button.css('visibility', revocation_reason == 6 ? 'visible' : 'hidden'); } function check_status(serial_number) { @@ -668,7 +721,5 @@ function certificate_status_panel(spec) { dialog.open(); } - init(); - return that; } diff --git a/install/static/details.js b/install/static/details.js index ee61f0cf..f7afcece 100644 --- a/install/static/details.js +++ b/install/static/details.js @@ -39,38 +39,20 @@ function ipa_details_field(spec) { var that = ipa_widget(spec); - that.create = spec.create || create; that.load = spec.load || load; that.save = spec.save || save; - function create(container) { - - var title = that.name; - var label = ''; - - var param_info = ipa_get_param_info(that.entity_name, that.name); - if (param_info) - label = param_info['label']; - - if (!label) - label = that.label; + function load(container, result) { - $('<dt></dt>', { - id: that.name, - title: title, - html: label + ':' - }).appendTo(container); - } + that.values = result[that.name]; - function load(container, result) { + /* remove all <dd> tags i.e. all attribute values */ + $('dd', that.container).remove(); var multivalue = false; var hint_span = null; var dd; - var dt = $('dt[title='+that.name+']', container); - if (!dt.length) return; - var param_info = ipa_get_param_info(that.entity_name, that.name); if (param_info) { if (param_info['multivalue'] || param_info['class'] == 'List') @@ -83,44 +65,39 @@ function ipa_details_field(spec) { } } - var value = result[that.name]; var rights = 'rsc'; + if (result.attributelevelrights){ rights = result.attributelevelrights[this.name] || rights ; } - if (value) { - dd = ipa_create_first_dd( - that.name,ipa_create_input( - that.entity_name, that.name, value[0],hint_span,rights) - ); - dt.after(dd); - var last_dd = dd; - for (var i = 1; i < value.length; ++i) { - dd = ipa_create_other_dd( - that.name, ipa_create_input(that.entity_name, that.name, - value[i],hint_span,rights) - ); - last_dd.after(dd); - last_dd = dd; + + if (that.values) { + dd = ipa_create_first_dd(that.name); + dd.append(ipa_details_field_create_input.call(that, that.values[0], hint_span, rights, 0)); + dd.appendTo(that.container); + + for (var i = 1; i < that.values.length; ++i) { + dd = ipa_create_other_dd(that.name); + dd.append(ipa_details_field_create_input.call(that, that.values[i], hint_span, rights, i)); + dd.appendTo(that.container); } + if (multivalue && IPA.is_field_writable(rights) ) { - dd = ipa_create_other_dd( - that.name, _ipa_a_add_template.replace('A', that.name) - ); - last_dd.after(dd); + dd = ipa_create_other_dd(that.name); + dd.append(ipa_details_field_create_add_link.call(that, that.name, rights, that.values.length)); + dd.appendTo(that.container); } + } else { if (multivalue && IPA.is_field_writable(rights)) { - dd = ipa_create_first_dd( - that.name, _ipa_a_add_template.replace('A', that.name) - ); - dt.after(dd); + dd = ipa_create_first_dd(that.name); + dd.append(ipa_details_field_create_add_link.call(that, that.name, rights, 0)); + dd.appendTo(that.container); + } else { - dd = ipa_create_first_dd( - that.name, ipa_create_input( - that.entity_name, that.name,'',hint_span,rights) - ); - dt.after(dd); + dd = ipa_create_first_dd(that.name); + dd.append(ipa_details_field_create_input.call(that, '', hint_span, rights, 0)); + dd.appendTo(that.container); } } } @@ -128,8 +105,8 @@ function ipa_details_field(spec) { function save(container) { var values = []; - var dd = $('dd[title='+that.name+']', container); - dd.each(function () { + $('dd', that.container).each(function () { + var input = $('input', $(this)); if (!input.length) return; @@ -298,6 +275,30 @@ function ipa_details_section(spec){ return that; } +/** + * This class creates a details section formatted as a list of + * attributes names and values. The list is defined using <dl> tag. + * The attribute name is defined inside a <dt> tag. The attribute + * value is defined using a <dd> tag inside a <span> tag. If the + * attribute has multiple values the content inside <span> will + * be duplicated to display each value. + * + * Example: + * <dl class="entryattrs"> + * + * <dt title="givenname">First Name:</dt> + * <span name="givenname"> + * <dd><input type="text" size="20"/></dd> + * </span> + * + * <dt title="telephonenumber">Telephone Number:</dt> + * <span name="telephonenumber"> + * <dd><input type="text" size="20"/></dd> + * <dd><input type="text" size="20"/></dd> + * </span> + * + * </dl> + */ function ipa_details_list_section(spec){ spec = spec || {}; @@ -319,34 +320,20 @@ function ipa_details_list_section(spec){ for (var i = 0; i < fields.length; ++i) { var field = fields[i]; + var label = field.label; + + var param_info = ipa_get_param_info(that.entity_name, field.name); + if (param_info && param_info['label']) label = param_info['label']; + + $('<dt/>', { + html: label + ':' + }).appendTo(dl); + var span = $('<span/>', { 'name': field.name }).appendTo(dl); field.create(span); } }; - /* populate definition lists with the class 'entryattrs' with entry attributes - * - * The list has to be specially crafted for this function to work properly: - * <dt> tags should have the 'title' attribute set to an LDAP attribute name - * OR to a javascript function name prefixed with 'call_', which will be given - * the <dt> object and entry_attrs as arguments. - * Example: - * <dl class="entryattrs"> - * <dt title="givenname">First Name:</dt> - * <dt title="call_some_callback">Some Attribute:</dt> - * </dl> - * - * arguments: - * result - 'result' field as returned by ipa *-show commnads - * (basically an associative array with attr:value pairs) */ - that.load = function(result) { - /* remove all <dd> tags i.e. all attribute values */ - $('dd', that.container).remove(); - - /* go through all <dt> tags and pair them with newly created <dd>s */ - that.section_load(result); - }; - // Deprecated: Used for backward compatibility only. function input(spec){ that.create_field(spec); @@ -415,6 +402,8 @@ function ipa_details_facet(spec) { } }; + that.details_facet_init = that.init; + return that; } @@ -621,8 +610,6 @@ function ipa_details_update(container, pkey, on_win, on_fail) /* HTML templates for ipa_details_display() */ -var _ipa_a_add_template = - '<a href="jslink" onclick="return (_ipa_add_on_click(this))" title="A">Add</a>'; var _ipa_span_doc_template = '<span class="attrhint">Hint: D</span>'; var _ipa_span_hint_template = '<span class="attrhint">Hint: D</span>'; @@ -641,10 +628,12 @@ function ipa_details_display(result) function ipa_create_first_dd(field_name, content){ - return $('<dd/>', { + var dd = $('<dd/>', { 'class': 'first', 'title': field_name - }).append(content); + }); + if (content) dd.append(content); + return dd; } function ipa_create_other_dd(field_name, content){ @@ -678,13 +667,15 @@ var _ipa_param_type_2_handler_map = { * arguments: * attr - LDAP attribute name * value - the attributes value */ -function ipa_create_input(entity_name, attr, value,hint,rights) +function ipa_details_field_create_input(value,hint,rights, index) { + var that = this; + var input = $("<label>",{html:value.toString()}); - var param_info = ipa_get_param_info(entity_name, attr); + var param_info = ipa_get_param_info(that.entity_name, that.name); if (!param_info) { /* no information about the param is available, default to text input */ - input = _ipa_create_text_input(attr, value, null,rights); + input = _ipa_create_text_input.call(that, value, null, rights, index); if (hint){ input.after(hint); } @@ -697,11 +688,11 @@ function ipa_create_input(entity_name, attr, value,hint,rights) /* call handler by param class */ var handler = _ipa_param_type_2_handler_map[param_info['class']]; if (handler) { - input = handler(attr, value, param_info,rights); + input = handler.call(that, value, param_info, rights, index); if ((param_info['multivalue'] || param_info['class'] == 'List') && IPA.is_field_writable(rights)){ - input.append( _ipa_create_remove_link(attr, param_info)); + input.append( _ipa_create_remove_link(that.name, param_info)); } if (hint){ input.after(hint); @@ -733,22 +724,10 @@ function _ipa_create_remove_link(attr, param_info) /* creates a input box for editing a string attribute */ -function _ipa_create_text_input(attr, value, param_info, rights) +function _ipa_create_text_input(value, param_info, rights, index) { - - function calculate_dd_index(jobj){ - var index = 0; - var dd = jobj.parents('dd').slice(0, 1)[0]; - dd = dd.previousElementSibling; - - while(dd.nodeName.toUpperCase() === 'DD'){ - dd = dd.previousElementSibling; - index += 1; - if (index > 100 ) - break; - } - return index; - } + var that = this; + index = index || 0; function validate_input(text, param_info,error_link){ if(param_info && param_info.pattern){ @@ -766,9 +745,9 @@ function _ipa_create_text_input(attr, value, param_info, rights) var span = $("<Span />"); var input = $("<input/>",{ - type:"text", - name:attr, - value:value.toString(), + type: "text", + name: that.name, + value: value.toString(), keyup: function(){ var undo_link=this.nextElementSibling; undo_link.style.display ="inline"; @@ -788,13 +767,7 @@ function _ipa_create_text_input(attr, value, param_info, rights) "class":"ui-state-highlight ui-corner-all", style:"display:none", click: function(){ - var key = this.previousElementSibling.name; - var entity_divs = $(this).parents('.entity-container'); - var entry_attrs = ipa_details_cache[entity_divs[0].id]; - - index = calculate_dd_index($(this)); - - var previous_value = entry_attrs[key] || ""; + var previous_value = that.values || ''; if (index >= previous_value.length){ previous_value = ''; }else{ @@ -830,28 +803,32 @@ function ipa_details_reset(container) } } -/* Event handlers */ +function ipa_details_field_create_add_link(title, rights, index) { -function _ipa_add_on_click(obj) -{ - var jobj = $(obj); - var attr = jobj.attr('title'); - var par = jobj.parent(); - var obj_name = jobj.closest('.entity-container').attr('title'); + var that = this; - var param_info = ipa_get_param_info(obj_name, ''); - //TODO rights need to be inherited - //And used to control presnece of the add link - var input = _ipa_create_text_input(attr, '', param_info, 'rswco'); + var link = $('<a/>', { + 'href': 'jslink', + 'title': title, + 'html': 'Add', + 'click': function () { - par.prepend(input); - jobj.next('input').focus(); - jobj.remove(); - par.after( ipa_create_other_dd(attr,_ipa_a_add_template.replace('A', attr))); + var param_info = ipa_get_param_info(that.entity_name, ''); + var input = _ipa_create_text_input.call(that, '', param_info, rights, index); - return (false); -} + link.replaceWith(input); + input.focus(); + + var dd = ipa_create_other_dd(that.name); + dd.append(ipa_details_field_create_add_link.call(that, that.name, rights, index+1)); + dd.appendTo(that.container); + return false; + } + }); + + return link; +} diff --git a/install/static/entity.js b/install/static/entity.js index e68ed3f2..3c0f1bba 100644 --- a/install/static/entity.js +++ b/install/static/entity.js @@ -142,6 +142,8 @@ function ipa_entity(spec) { } }; + that.entity_init = that.init; + return that; } diff --git a/install/static/host.js b/install/static/host.js index bd9deda3..a721dd21 100644 --- a/install/static/host.js +++ b/install/static/host.js @@ -20,67 +20,332 @@ /* REQUIRES: ipa.js, details.js, search.js, add.js, entity.js */ -ipa_entity_set_search_definition('host', [ - ['fqdn', 'Name', null], - ['description', 'Description', null], - ['enrolled', 'Enrolled?', null], - ['manages', 'Manages?', null] -]); - -ipa_entity_set_add_definition('host', [ - 'dialog-add-host', 'Add New Host', [ - ['fqdn', 'Name', null] - ] -]); - -ipa_entity_set_details_definition('host', [ - ipa_stanza({name:'details', label:'Host Details'}). - input({name:'fqdn', label:'Fully Qualified Domain Name'}). - input({name:'krbprincipalname', label:'Kerberos Principal'}). - input({name:'serverhostname', label:'Server Host Name'}), - ipa_stanza({name:'enrollment', label:'Enrollment'}). - input({name:'enrollment_status', label:'Status', - load:host_enrollment_status_load}), - ipa_stanza({name:'certificate', label:'Host Certificate'}). - input({name:'certificate_status', label:'Status', - load:host_usercertificate_load}) -]); - -ipa_entity_set_association_definition('host', { - 'hostgroup': { associator: 'serial' }, - 'rolegroup': { associator: 'serial' } -}); - -function host_enrollment_status_load(container, result) { - // skip enrollment_status +function ipa_host() { + + var that = ipa_entity({ + 'name': 'host' + }); + + that.init = function() { + + that.create_association({ + 'name': 'hostgroup', + 'associator': 'serial' + }); + + that.create_association({ + 'name': 'rolegroup', + 'associator': 'serial' + }); + + var dialog = ipa_host_add_dialog({ + 'name': 'add', + 'title': 'Add New Host' + }); + that.add_dialog(dialog); + dialog.init(); + + var facet = ipa_host_search_facet({ + 'name': 'search', + 'label': 'Search' + }); + that.add_facet(facet); + + facet = ipa_host_details_facet({ + 'name': 'details', + 'label': 'Details' + }); + that.add_facet(facet); + + facet = ipa_association_facet({ + 'name': 'associate' + }); + that.add_facet(facet); + + that.entity_init(); + }; + + return that; +} + +IPA.add_entity(ipa_host()); + +function ipa_host_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': 'fqdn', + 'label': 'Name', + 'size': 40, + 'undo': false + })); + }; + + return that; +} + +function ipa_host_search_facet(spec) { + + spec = spec || {}; + + var that = ipa_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.search_facet_init(); + }; + + return that; +} + +function ipa_host_details_facet(spec) { + + spec = spec || {}; + + var that = ipa_details_facet(spec); + + that.init = function() { + + var section = ipa_details_list_section({ + name: 'details', + label: 'Host Details' + }); + that.add_section(section); + + section.create_field({ + name: 'fqdn', + label: 'Fully Qualified Domain Name' + }); + + section.create_field({ + name: 'krbprincipalname', + label: 'Kerberos Principal' + }); + + section.create_field({ + name: 'serverhostname', + label: 'Server Host Name' + }); + + section = ipa_details_list_section({ + name: 'enrollment', + label: 'Enrollment' + }); + that.add_section(section); + + section.add_field(host_provisioning_status_widget({ + name: 'provisioning_status', + label: 'Status' + })); + + section = ipa_details_list_section({ + name:'certificate', + label:'Host Certificate' + }); + that.add_section(section); + + section.add_field(host_certificate_status_widget({ + name: 'certificate_status', + label: 'Status' + })); + + that.details_facet_init(); + }; + + return that; +} + +function host_provisioning_status_widget(spec) { + + spec = spec || {}; + + var that = ipa_widget(spec); + + that.create = function(container) { + + that.widget_create(container); + + var table = $('<table/>').appendTo(container); + + var tr = $('<tr/>').appendTo(table); + + var td = $('<td/>').appendTo(tr); + var li = $('<li/>', { + 'class': 'key-status-valid' + }).appendTo(td); + + td = $('<td/>').appendTo(tr); + td.append('Kerberos Key Present, Host Provisioned:'); + + td = $('<td/>').appendTo(tr); + + $('<input/>', { + 'type': 'button', + 'name': 'unprovision', + 'value': 'Delete Key, Unprovision' + }).appendTo(td); + + tr = $('<tr/>').appendTo(table); + + td = $('<td/>').appendTo(tr); + li = $('<li/>', { + 'class': 'key-status-missing' + }).appendTo(td); + + td = $('<td/>').appendTo(tr); + td.append('Kerberos Key Not Present'); + + td = $('<td/>').appendTo(tr); + + tr = $('<tr/>').appendTo(table); + + td = $('<td/>').appendTo(tr); + + td = $('<td/>').appendTo(tr); + td.append('Enroll via One-Time-Password:'); + + td = $('<td/>').appendTo(tr); + + $('<input/>', { + 'type': 'text', + 'name': 'otp', + 'size': 10 + }).appendTo(td); + + $('<input/>', { + 'type': 'button', + 'name': 'enroll', + 'value': 'Set OTP' + }).appendTo(td); + }; + + that.setup = function(container) { + + that.container = container; + + that.valid = $('li.key-status-valid', that.container); + that.missing = $('li.key-status-missing', that.container); + + var button = $('input[name=unprovision]', that.container); + that.unprovision_button = ipa_button({ + 'label': 'Delete Key, Unprovision', + 'click': that.unprovision + }); + button.replaceWith(that.unprovision_button); + + that.otp_input = $('input[name=otp]', that.container); + + that.enroll_button = $('input[name=enroll]', that.container); + button = ipa_button({ + 'label': 'Set OTP', + 'click': that.set_otp + }); + + that.enroll_button.replaceWith(button); + that.enroll_button = button; + }; + + that.unprovision = function() { + + var label = IPA.metadata[that.entity_name].label; + var dialog = ipa_dialog({ + 'title': 'Unprovisioning '+label + }); + + dialog.create = function() { + dialog.container.append( + 'To confirm your intention to unprovision this host, '+ + 'click the "Unprovision" button.'); + }; + + dialog.add_button('Unprovision', function() { + var pkey = that.result['fqdn'][0]; + ipa_cmd(that.entity_name+'_disable', [pkey], {}, + function(data, text_status, xhr) { + set_status('missing'); + dialog.close(); + }, + function(xhr, text_status, error_thrown) { + dialog.close(); + } + ); + }); + + dialog.add_button('Cancel', function() { + dialog.close(); + }); + + dialog.init(); + + dialog.open(that.container); + + return false; + }; + + that.set_otp = function() { + // TODO: enroll via OTP + alert(that.otp.val()); + }; + + that.load = function(container, result) { + that.result = result; + var krblastpwdchange = result['krblastpwdchange']; + set_status(krblastpwdchange ? 'valid' : 'missing'); + }; + + function set_status(status) { + that.valid.toggleClass('key-status-active', status == 'valid'); + that.missing.toggleClass('key-status-active', status == 'missing'); + + that.unprovision_button.css('visibility', status == 'valid' ? 'visible' : 'hidden'); + that.otp_input.css('visibility', status == 'missing' ? 'visible' : 'hidden'); + that.enroll_button.css('visibility', status == 'missing' ? 'visible' : 'hidden'); + } + + return that; } -function host_usercertificate_load(container, result) { +function host_certificate_status_widget(spec) { + + spec = spec || {}; + + var that = certificate_status_widget(spec); - var dt = $('dt[title='+this.name+']', container); - if (!dt.length) return; + that.init = function() { - var panel = certificate_status_panel({ - 'entity_type': 'host', - 'entity_label': 'Host', - 'result': result, - 'get_entity_pkey': function(result) { + that.entity_label = IPA.metadata[that.entity_name].label; + + that.get_entity_pkey = function(result) { var values = result['fqdn']; return values ? values[0] : null; - }, - 'get_entity_name': function(result) { - return this.get_entity_pkey(result); - }, - 'get_entity_principal': function(result) { + }; + + that.get_entity_name = function(result) { + return that.get_entity_pkey(result); + }; + + that.get_entity_principal = function(result) { var values = result['krbprincipalname']; return values ? values[0] : null; - }, - 'get_entity_certificate': function(result) { + }; + + that.get_entity_certificate = function(result) { var values = result['usercertificate']; return values ? values[0].__base64__ : null; } - }); + }; - var dd = ipa_create_first_dd(this.name, panel); - dt.after(dd); + return that; } diff --git a/install/static/ipa.css b/install/static/ipa.css index f7817f19..9183b9f9 100644 --- a/install/static/ipa.css +++ b/install/static/ipa.css @@ -411,6 +411,20 @@ span.main-separator{ .strikethrough { text-decoration: line-through; } +.key-status-valid { + list-style-type: circle; + color: #008000; +} + +.key-status-missing { + list-style-type: circle; + color: #daa520; +} + +.key-status-active { + list-style-type: disc; +} + .certificate-status-valid { list-style-type: circle; color: #008000; diff --git a/install/static/search.js b/install/static/search.js index a107209b..8d0fc55c 100644 --- a/install/static/search.js +++ b/install/static/search.js @@ -319,6 +319,8 @@ function ipa_search_facet(spec) { } } + that.search_facet_init = that.init; + return that; } diff --git a/install/static/service.js b/install/static/service.js index 0b0adb82..cf8d2cea 100644 --- a/install/static/service.js +++ b/install/static/service.js @@ -26,8 +26,6 @@ function ipa_service() { 'name': 'service' }); - that.superior_init = that.superior('init'); - that.init = function() { that.create_association({ @@ -60,7 +58,7 @@ function ipa_service() { }); that.add_facet(facet); - that.superior_init(); + that.entity_init(); }; return that; @@ -74,24 +72,22 @@ function ipa_service_add_dialog(spec) { var that = ipa_add_dialog(spec); - that.superior_init = that.superior('init'); - that.init = function() { - this.superior_init(); + that.add_dialog_init(); - this.add_field(ipa_widget({ + that.add_field(ipa_widget({ name: 'krbprincipalname', label: 'Principal' })); - this.add_field(ipa_text_widget({ + that.add_field(ipa_text_widget({ 'name': 'service', 'label': 'Service', 'size': 20, 'undo': false })); - this.add_field(ipa_text_widget({ + that.add_field(ipa_text_widget({ 'name': 'host', 'label': 'Host Name', 'size': 40, @@ -159,12 +155,10 @@ function ipa_service_search_facet(spec) { var that = ipa_search_facet(spec); - that.superior_init = that.superior('init'); - that.init = function() { this.create_column({name:'krbprincipalname', label:'Principal'}); - that.superior_init(); + that.search_facet_init(); }; return that; @@ -176,13 +170,11 @@ function ipa_service_details_facet(spec) { var that = ipa_details_facet(spec); - that.superior_init = that.superior('init'); - that.init = function() { var section = ipa_details_list_section({ - name:'details', - label:'Service Details' + name: 'details', + label: 'Service Details' }); that.add_section(section); @@ -204,85 +196,195 @@ function ipa_service_details_facet(spec) { }); section = ipa_details_list_section({ - name:'provisioning', - label:'Provisioning' + name: 'provisioning', + label: 'Provisioning' }); that.add_section(section); - section.create_field({ + section.add_field(service_provisioning_status_widget({ name: 'provisioning_status', - label: 'Status', - load: service_provisioning_status_load - }); + label: 'Status' + })); section = ipa_details_list_section({ - name:'certificate', - label:'Service Certificate' + name: 'certificate', + label: 'Service Certificate' }); that.add_section(section); - section.create_field({ + section.add_field(service_certificate_status_widget({ name: 'certificate_status', - label: 'Status', - load: service_usercertificate_load - }); + label: 'Status' + })); - that.superior_init(); + that.details_facet_init(); }; return that; } function service_service_load(container, result) { - var dt = $('dt[title='+this.name+']', container); - if (!dt.length) return; + + $('dd', container).remove(); + + var dd = ipa_create_first_dd(this.name); + dd.appendTo(container); var krbprincipalname = result['krbprincipalname'][0]; var service = krbprincipalname.replace(/\/.*$/, ''); - var dd = ipa_create_first_dd(this.name, service); - dt.after(dd); + dd.append(service); } function service_host_load(container, result) { - var dt = $('dt[title='+this.name+']', container); - if (!dt.length) return; + + $('dd', container).remove(); + + var dd = ipa_create_first_dd(this.name); + dd.appendTo(container); var krbprincipalname = result['krbprincipalname'][0]; var host = krbprincipalname.replace(/^.*\//, '').replace(/@.*$/, ''); - var dd = ipa_create_first_dd(this.name, host); - dt.after(dd); + dd.append(host); } -function service_provisioning_status_load(container, result) { - // skip provisioning_status +function service_provisioning_status_widget(spec) { + + spec = spec || {}; + + var that = ipa_widget(spec); + + that.create = function(container) { + + that.widget_create(container); + + var table = $('<table/>').appendTo(container); + + var tr = $('<tr/>').appendTo(table); + + var td = $('<td/>').appendTo(tr); + var li = $('<li/>', { + 'class': 'key-status-valid' + }).appendTo(td); + + td = $('<td/>').appendTo(tr); + td.append('Kerberos Key Present, Service Provisioned:'); + + td = $('<td/>').appendTo(tr); + + $('<input/>', { + 'type': 'button', + 'name': 'unprovision', + 'value': 'Delete Key, Unprovision' + }).appendTo(td); + + tr = $('<tr/>').appendTo(table); + + td = $('<td/>').appendTo(tr); + li = $('<li/>', { + 'class': 'key-status-missing' + }).appendTo(td); + + td = $('<td/>').appendTo(tr); + td.append('Kerberos Key Not Present'); + }; + + that.setup = function(container) { + + that.container = container; + + that.valid = $('li.key-status-valid', that.container); + that.missing = $('li.key-status-missing', that.container); + + var button = $('input[name=unprovision]', that.container); + that.unprovision_button = ipa_button({ + 'label': 'Delete Key, Unprovision', + 'click': that.unprovision + }); + button.replaceWith(that.unprovision_button); + }; + + that.unprovision = function() { + + var label = IPA.metadata[that.entity_name].label; + var dialog = ipa_dialog({ + 'title': 'Unprovisioning '+label + }); + + dialog.create = function() { + dialog.container.append( + 'To confirm your intention to unprovision this service, '+ + 'click the "Unprovision" button.'); + }; + + dialog.add_button('Unprovision', function() { + var pkey = that.result['krbprincipalname'][0]; + ipa_cmd(that.entity_name+'_disable', [pkey], {}, + function(data, text_status, xhr) { + set_status('missing'); + dialog.close(); + }, + function(xhr, text_status, error_thrown) { + dialog.close(); + } + ); + }); + + dialog.add_button('Cancel', function() { + dialog.close(); + }); + + dialog.init(); + + dialog.open(that.container); + + return false; + }; + + that.load = function(container, result) { + that.result = result; + var krblastpwdchange = result['krblastpwdchange']; + set_status(krblastpwdchange ? 'valid' : 'missing'); + }; + + function set_status(status) { + that.valid.toggleClass('key-status-active', status == 'valid'); + that.missing.toggleClass('key-status-active', status == 'missing'); + + that.unprovision_button.css('visibility', status == 'valid' ? 'visible' : 'hidden'); + } + + return that; } -function service_usercertificate_load(container, result) { +function service_certificate_status_widget(spec) { + + spec = spec || {}; + + var that = certificate_status_widget(spec); - var dt = $('dt[title='+this.name+']', container); - if (!dt.length) return; + that.init = function() { + + that.entity_label = IPA.metadata[that.entity_name].label; - var panel = certificate_status_panel({ - 'entity_type': 'service', - 'entity_label': 'Service', - 'result': result, - 'get_entity_pkey': function(result) { + that.get_entity_pkey = function(result) { var values = result['krbprincipalname']; return values ? values[0] : null; - }, - 'get_entity_name': function(result) { - var value = this.get_entity_pkey(result); + }; + + that.get_entity_name = function(result) { + var value = that.get_entity_pkey(result); return value ? value.replace(/@.*$/, '') : null; - }, - 'get_entity_principal': function(result) { - return this.get_entity_pkey(result); - }, - 'get_entity_certificate': function(result) { + }; + + that.get_entity_principal = function(result) { + return that.get_entity_pkey(result); + }; + + that.get_entity_certificate = function(result) { var values = result['usercertificate']; return values ? values[0].__base64__ : null; - } - }); + }; + }; - var dd = ipa_create_first_dd(this.name, panel); - dt.after(dd); + return that; } diff --git a/install/static/test/details_tests.js b/install/static/test/details_tests.js index 2bb9b9c6..04738143 100644 --- a/install/static/test/details_tests.js +++ b/install/static/test/details_tests.js @@ -44,7 +44,7 @@ test("Testing ipa_details_section.create().", function() { var container = $("<div/>"); section.create(container); - var dl = container.find('dl'); + var dl = $('dl', container); same( dl.length, 1, @@ -63,15 +63,26 @@ test("Testing ipa_details_section.create().", function() { ); for (var i=0; i<fields.length; i++) { + var field = fields[i]; + var dt = dts.get(i); same( - dt.title, fields[i].name, - 'Checking field '+i+'\'s title' + dt.innerHTML, field.label+':', + 'Checking field '+field.name+'\'s label' ); - same( - dt.innerHTML, fields[i].label+':', - 'Checking field '+i+'\'s label' + var span = $('span[name='+field.name+']', dl); + + ok( + span.length, + 'Checking span tag for field '+field.name + ); + + var dd = $('dd', span); + + ok( + dd.length == 0, + 'Checking dd tag for field '+field.name ); } }); @@ -184,18 +195,13 @@ test("Testing details lifecycle: create, setup, load.", function(){ 'dl tag for identity is created' ); - var dts= identity.find('dt'); + var dts = identity.find('dt'); same( dts.length, 6, 'Checking dt tags for identity' ); - same( - dts[5].title, facet.sections[0].fields[5].name, - 'Checking dt title' - ); - container.attr('id','user'); ok ( @@ -219,10 +225,14 @@ test("Testing details lifecycle: create, setup, load.", function(){ test("Testing _ipa_create_text_input().", function(){ + var field = ipa_details_field({ + 'name': "name" + }); + var name = "name"; var value="value"; var rights = 'rscwo' - var input = _ipa_create_text_input(name, value, null,rights); + var input = _ipa_create_text_input.call(field, value, null,rights); ok(input,"input not null"); var text = input.find('input'); @@ -235,10 +245,14 @@ test("Testing _ipa_create_text_input().", function(){ test("Testing _ipa_create_text_input() read only .", function(){ + var field = ipa_details_field({ + 'name': "name" + }); + var name = "name"; var value="value"; var rights = 'rsc' - var input = _ipa_create_text_input(name, value, null,rights); + var input = _ipa_create_text_input.call(field, value, null,rights); ok(input,"input not null"); var text = input.find('input'); @@ -271,40 +285,41 @@ test("Testing ipa_details_section_setup again()",function(){ section.setup(container); section.load(result); - ok(container.find('hr'),'hr'); - //var h2= container.find('h2'); //ok(h2); //ok(h2[0].innerHTML.indexOf(section.label) > 1,"find name in html"); - var dl = container.find('dl'); - + var dl = $('dl', container); ok( dl.length, 'dl is created' ); + var dt = $('dt', dl); same( - dl[0].children.length, 3, - '3 spans' + dt.length, 3, + '3 dt' ); + var span = dt.next(); same( - dl[0].id, section.name, - 'checking section name' + span.length, 3, + '3 span' ); same( - dl[0].children[0].children[0].title, fields[0].name, - 'title matches name' + dl[0].id, section.name, + 'checking section name' ); same( - dl[0].children[0].children[0].innerHTML, fields[0].label+":", + dt[0].innerHTML, fields[0].label+":", 'inner HTML matches label' ); + + var dd = $('dd', span[0]); same( - dl[0].children[2].children[0].title, fields[2].name, - 'title matches fields[2] name' + dd.length, 1, + '1 dd' ); }); diff --git a/install/static/user.js b/install/static/user.js index 74c003e5..2a9bc7d0 100644 --- a/install/static/user.js +++ b/install/static/user.js @@ -26,7 +26,7 @@ ipa_entity_set_search_definition('user', [ ['uidnumber', 'UID', null], ['mail', 'EMAIL', null], ['telephonenumber', 'Phone', null], - ['title', 'Job Title', null], + ['title', 'Job Title', null] ]); ipa_entity_set_add_definition('user', [ @@ -89,10 +89,13 @@ ipa_entity_set_association_definition('user', { function user_status_load(container, result) { - var lock_field = 'nsaccountlock'; - var dt = $('dt[title='+this.name+']', container); - if (!dt.length) return; + $('dd', container).remove(); + + var dd = ipa_create_first_dd(this.name); + dd.appendTo(container); + + var lock_field = 'nsaccountlock'; var locked = result[lock_field] && result[lock_field][0].toLowerCase() === 'true'; @@ -134,8 +137,7 @@ function user_status_load(container, result) { return (false); } }); - - dt.after(ipa_create_first_dd(this.name, status_field)); + status_field.appendTo(dd); } @@ -191,17 +193,20 @@ function resetpwd_on_click(){ } function user_password_load(container, result) { - var dt = $('dt[title='+this.name+']', container); - if (!dt.length) return; - - dt.after(ipa_create_first_dd( - this.name, - $('<a/>',{ - href:"jslink", - click:resetpwd_on_click, - title:'userpassword', - text: 'reset password' - }))); + + $('dd', container).remove(); + + var dd = ipa_create_first_dd(this.name); + dd.appendTo(container); + + var link = $('<a/>',{ + href:"jslink", + click:resetpwd_on_click, + title:'userpassword', + text: 'reset password' + }); + link.appendTo(dd); + } var select_temp = '<select title="st"></select>'; @@ -215,17 +220,18 @@ var states = [ 'WA', 'WV', 'WI', 'WY', '' ]; function user_state_load(container, result) { - var dt = $('dt[title='+this.name+']', container); - if (!dt.length) return; - var next = dt.next(); - next.css('clear', 'none'); - next.css('width', '70px'); + $('dd', container).remove(); + + //var next = dt.next(); + //next.css('clear', 'none'); + //next.css('width', '70px'); - var dd = ipa_create_first_dd(this.name, select_temp); - dt.after(dd); + var dd = ipa_create_first_dd(this.name); + dd.append(select_temp); + dd.appendTo(container); - var sel = dt.next().children().first(); + var sel = dd.children().first(); for (var i = 0; i < states.length; ++i) sel.append(option_temp.replace(/V/g, states[i])); diff --git a/install/static/widget.js b/install/static/widget.js index 1b99831e..6ed27dec 100755 --- a/install/static/widget.js +++ b/install/static/widget.js @@ -109,6 +109,7 @@ function ipa_widget(spec) { }; // methods that should be invoked by subclasses + that.widget_create = that.create; that.widget_setup = that.setup; return that; |