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.
This commit is contained in:
Endi S. Dewata
2010-11-16 18:10:40 -06:00
committed by Adam Young
parent b42271c47d
commit 5da8313b66
11 changed files with 787 additions and 351 deletions

View File

@@ -95,6 +95,7 @@ function ipa_add_dialog(spec) {
};
that.superior_init = that.superior('init');
that.add_dialog_init = that.init;
return that;
}

View File

@@ -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,46 +421,29 @@ function certificate_status_panel(spec) {
td.append('Valid Certificate Present:');
td = $('<td/>').appendTo(tr);
ipa_button({
'id': 'get_button',
'label': 'Get',
'click': function() {
ipa_cmd(that.entity_type+'_show', [pkey], {},
function(data, text_status, xhr) {
get_certificate(data.result.result);
}
);
}
$('<input/>', {
'type': 'button',
'name': 'get',
'value': 'Get'
}).appendTo(td);
ipa_button({
'id': 'revoke_button',
'label': 'Revoke',
'click': function() {
ipa_cmd(that.entity_type+'_show', [pkey], {},
function(data, text_status, xhr) {
revoke_certificate(data.result.result);
}
);
}
$('<input/>', {
'type': 'button',
'name': 'revoke',
'value': 'Revoke'
}).appendTo(td);
ipa_button({
'id': 'view_button',
'label': 'View',
'click': function() {
ipa_cmd(that.entity_type+'_show', [pkey], {},
function(data, text_status, xhr) {
view_certificate(data.result.result);
}
);
}
$('<input/>', {
'type': 'button',
'name': 'view',
'value': 'View'
}).appendTo(td);
tr = $('<tr/>').appendTo(table);
td = $('<td/>').appendTo(tr);
li2 = $('<li/>', {
$('<li/>', {
'class': 'certificate-status-revoked'
}).appendTo(td);
@@ -469,26 +452,20 @@ function certificate_status_panel(spec) {
td = $('<td/>').appendTo(tr);
td.append($('<span/>', {
'id': 'revocation_reason'
'name': 'revocation_reason'
}));
td.append(' ');
ipa_button({
'id': 'restore_button',
'label': 'Restore',
'click': function() {
ipa_cmd(that.entity_type+'_show', [pkey], {},
function(data, text_status, xhr) {
restore_certificate(data.result.result);
}
);
}
$('<input/>', {
'type': 'button',
'name': 'restore',
'value': 'Restore'
}).appendTo(td);
tr = $('<tr/>').appendTo(table);
td = $('<td/>').appendTo(tr);
li3 = $('<li/>', {
$('<li/>', {
'class': 'certificate-status-missing'
}).appendTo(td);
@@ -496,13 +473,89 @@ function certificate_status_panel(spec) {
td.append('No Valid Certificate:');
td = $('<td/>').appendTo(tr);
ipa_button({
'id': 'create_button',
$('<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_name+'_show', [that.pkey], {},
function(data, text_status, xhr) {
get_certificate(data.result.result);
}
);
}
});
button.replaceWith(that.get_button);
button = $('input[name=revoke]', that.container);
that.revoke_button = ipa_button({
'label': 'Revoke',
'click': function() {
ipa_cmd(that.entity_name+'_show', [that.pkey], {},
function(data, text_status, xhr) {
revoke_certificate(data.result.result);
}
);
}
});
button.replaceWith(that.revoke_button);
button = $('input[name=view]', that.container);
that.view_button = ipa_button({
'label': 'View',
'click': function() {
ipa_cmd(that.entity_name+'_show', [that.pkey], {},
function(data, text_status, xhr) {
view_certificate(data.result.result);
}
);
}
});
button.replaceWith(that.view_button);
that.revocation_reason = $('span[name=revocation_reason]', that.container);
button = $('input[name=restore]', that.container);
that.restore_button = ipa_button({
'label': 'Restore',
'click': function() {
ipa_cmd(that.entity_name+'_show', [that.pkey], {},
function(data, text_status, xhr) {
restore_certificate(data.result.result);
}
);
}
});
button.replaceWith(that.restore_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);
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);
$('#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.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;
}

View File

@@ -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;
$('<dt></dt>', {
id: that.name,
title: title,
html: label + ':'
}).appendTo(container);
}
function load(container, result) {
that.values = result[that.name];
/* 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,31 +803,35 @@ 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;
}
function _ipa_remove_on_click(obj)
{
var jobj = $(obj);

View File

@@ -142,6 +142,8 @@ function ipa_entity(spec) {
}
};
that.entity_init = that.init;
return that;
}

View File

@@ -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]
]);
function ipa_host() {
ipa_entity_set_add_definition('host', [
'dialog-add-host', 'Add New Host', [
['fqdn', 'Name', null]
]
]);
var that = ipa_entity({
'name': 'host'
});
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})
]);
that.init = function() {
ipa_entity_set_association_definition('host', {
'hostgroup': { associator: 'serial' },
'rolegroup': { associator: 'serial' }
});
that.create_association({
'name': 'hostgroup',
'associator': 'serial'
});
function host_enrollment_status_load(container, result) {
// skip enrollment_status
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;
}
function host_usercertificate_load(container, result) {
IPA.add_entity(ipa_host());
var dt = $('dt[title='+this.name+']', container);
if (!dt.length) return;
function ipa_host_add_dialog(spec) {
var panel = certificate_status_panel({
'entity_type': 'host',
'entity_label': 'Host',
'result': result,
'get_entity_pkey': function(result) {
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_certificate_status_widget(spec) {
spec = spec || {};
var that = certificate_status_widget(spec);
that.init = function() {
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;
}

View File

@@ -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;

View File

@@ -319,6 +319,8 @@ function ipa_search_facet(spec) {
}
}
that.search_facet_init = that.init;
return that;
}

View File

@@ -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) {
var dt = $('dt[title='+this.name+']', container);
if (!dt.length) return;
spec = spec || {};
var panel = certificate_status_panel({
'entity_type': 'service',
'entity_label': 'Service',
'result': result,
'get_entity_pkey': function(result) {
var that = certificate_status_widget(spec);
that.init = function() {
that.entity_label = IPA.metadata[that.entity_name].label;
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;
}

View File

@@ -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,22 +285,26 @@ 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(
span.length, 3,
'3 span'
);
same(
@@ -295,16 +313,13 @@ test("Testing ipa_details_section_setup again()",function(){
);
same(
dl[0].children[0].children[0].title, fields[0].name,
'title matches 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'
);
});

View File

@@ -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 dd = ipa_create_first_dd(this.name, select_temp);
dt.after(dd);
//var next = dt.next();
//next.css('clear', 'none');
//next.css('width', '70px');
var sel = dt.next().children().first();
var dd = ipa_create_first_dd(this.name);
dd.append(select_temp);
dd.appendTo(container);
var sel = dd.children().first();
for (var i = 0; i < states.length; ++i)
sel.append(option_temp.replace(/V/g, states[i]));

View File

@@ -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;