mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Add certificate widget
The certificate widget is used for each certificate in certs_widget. It allows to view, get, download, revoke and restore certificate. https://fedorahosted.org/freeipa/ticket/5108 https://fedorahosted.org/freeipa/ticket/5381 Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
This commit is contained in:
parent
6d3622c600
commit
55a0baf1c3
@ -134,13 +134,31 @@
|
|||||||
// Certificate Widget
|
// Certificate Widget
|
||||||
|
|
||||||
.certificate-widget {
|
.certificate-widget {
|
||||||
|
padding: 5px 5px 5px 5px;
|
||||||
|
border: 1px dashed #DDD;
|
||||||
label {
|
label {
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
|
.cert-value {
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
.certificate {
|
.certificate {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
.dropdown {
|
||||||
|
float:right;
|
||||||
|
}
|
||||||
|
ul.dropdown-menu {
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
.watermark {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
opacity:0.5;
|
||||||
|
font-size: 150%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Working widget
|
// Working widget
|
||||||
|
@ -21,7 +21,9 @@
|
|||||||
|
|
||||||
define([
|
define([
|
||||||
'dojo/_base/lang',
|
'dojo/_base/lang',
|
||||||
|
'dojo/on',
|
||||||
'./builder',
|
'./builder',
|
||||||
|
'./datetime',
|
||||||
'./metadata',
|
'./metadata',
|
||||||
'./ipa',
|
'./ipa',
|
||||||
'./jquery',
|
'./jquery',
|
||||||
@ -31,10 +33,11 @@ define([
|
|||||||
'./rpc',
|
'./rpc',
|
||||||
'./text',
|
'./text',
|
||||||
'./widget',
|
'./widget',
|
||||||
|
'./widgets/DropdownWidget',
|
||||||
'./dialog'],
|
'./dialog'],
|
||||||
function(
|
function(
|
||||||
lang, builder, metadata_provider, IPA, $, menu,
|
lang, on, builder, datetime, metadata_provider, IPA, $, menu,
|
||||||
phases, reg, rpc, text, widget_mod) {
|
phases, reg, rpc, text, widget_mod, DropdownWidget) {
|
||||||
|
|
||||||
var exp = IPA.cert = {};
|
var exp = IPA.cert = {};
|
||||||
|
|
||||||
@ -1107,40 +1110,294 @@ IPA.cert.certs_widget = function(spec) {
|
|||||||
|
|
||||||
return that;
|
return that;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
if (!l) {
|
/**
|
||||||
that.content_el.append(that.create_status(
|
* certificate widget
|
||||||
'missing',
|
*
|
||||||
text.get('@i18n:objects.cert.missing'),
|
* @class
|
||||||
'fa fa-warning'));
|
* @extends IPA.input_widget
|
||||||
}
|
*/
|
||||||
|
IPA.cert.cert_widget = function(spec) {
|
||||||
|
|
||||||
if (l && !that.certs_visible) {
|
spec = spec || {};
|
||||||
|
|
||||||
var msg = text.get('@i18n:objects.cert.present');
|
var that = IPA.input_widget(spec);
|
||||||
msg = msg.replace('${count}', l);
|
IPA.table_mixin().apply(that);
|
||||||
that.content_el.append(
|
|
||||||
that.create_status('present', msg, 'fa fa-check'));
|
|
||||||
|
|
||||||
IPA.button({
|
that.certificate = null;
|
||||||
name: 'show',
|
|
||||||
label: '@i18n:buttons.show',
|
that.create = function(container) {
|
||||||
click: function() {
|
|
||||||
that.certs_visible = true;
|
that.widget_create(container);
|
||||||
that.create_certs();
|
|
||||||
|
that.container = container;
|
||||||
|
that.container.addClass('cert-container col-sm-12');
|
||||||
|
|
||||||
|
var spinner_spec = {
|
||||||
|
name: 'working-notification'
|
||||||
|
};
|
||||||
|
|
||||||
|
that.spinner = IPA.working_widget(spinner_spec);
|
||||||
|
that.spinner.create(that.container);
|
||||||
|
|
||||||
|
that.cert_subject = $('<div />', {
|
||||||
|
style: 'font-weight: bold;',
|
||||||
|
text: ''
|
||||||
|
}).appendTo(that.container);
|
||||||
|
|
||||||
|
that.table_layout = that.create_layout().appendTo(that.container);
|
||||||
|
|
||||||
|
var tr = that.create_row().appendTo(that.table_layout);
|
||||||
|
that.create_header_cell('@i18n:objects.cert.serial_number', ':')
|
||||||
|
.appendTo(tr);
|
||||||
|
that.cert_sn = that.create_cell('', '', 'cert-value').appendTo(tr);
|
||||||
|
|
||||||
|
tr = that.create_row().appendTo(that.table_layout);
|
||||||
|
that.create_header_cell('@i18n:objects.cert.issued_by', ':')
|
||||||
|
.appendTo(tr);
|
||||||
|
that.cert_issuer = that.create_cell('', '', 'cert-value').appendTo(tr);
|
||||||
|
|
||||||
|
tr = that.create_row().appendTo(that.table_layout);
|
||||||
|
that.create_header_cell('@i18n:objects.cert.valid_from', ':')
|
||||||
|
.appendTo(tr);
|
||||||
|
that.cert_valid_from = that.create_cell('', '', 'cert-value')
|
||||||
|
.appendTo(tr);
|
||||||
|
|
||||||
|
tr = that.create_row().appendTo(that.table_layout);
|
||||||
|
that.create_header_cell('@i18n:objects.cert.valid_to', ':')
|
||||||
|
.appendTo(tr);
|
||||||
|
that.cert_valid_to = that.create_cell('', '', 'cert-value')
|
||||||
|
.appendTo(tr);
|
||||||
|
|
||||||
|
that.dropdown = builder.build(null, {
|
||||||
|
$ctor: DropdownWidget,
|
||||||
|
toggle_text: text.get('@i18n:actions.title'),
|
||||||
|
toggle_class: 'btn btn-default dropdown-toggle',
|
||||||
|
toggle_icon: 'caret',
|
||||||
|
right_aligned: true,
|
||||||
|
name: 'cert-actions',
|
||||||
|
'class': 'dropdown cert-actions',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
name: 'view',
|
||||||
|
label: text.get('@i18n:buttons.view'),
|
||||||
|
handler: that.open_view_dialog
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'get',
|
||||||
|
label: text.get('@i18n:buttons.get'),
|
||||||
|
handler: that.open_get_dialog
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'download',
|
||||||
|
label: text.get('@i18n:buttons.download'),
|
||||||
|
handler: that.perform_download
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'revoke',
|
||||||
|
label: text.get('@i18n:buttons.revoke'),
|
||||||
|
disabled: true,
|
||||||
|
handler: that.open_revoke_dialog
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'remove_hold',
|
||||||
|
label: text.get('@i18n:buttons.remove_hold'),
|
||||||
|
disabled: true,
|
||||||
|
handler: that.perform_remove_hold
|
||||||
}
|
}
|
||||||
}).appendTo(that.content_el);
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
on(that.dropdown, 'item-click', function(item) {
|
||||||
|
if (!item.disabled && item.handler) {
|
||||||
|
item.handler();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
that.container.append(that.dropdown.render());
|
||||||
|
that.table_layout.appendTo(that.container);
|
||||||
|
|
||||||
|
that.create_error_link(that.container);
|
||||||
|
};
|
||||||
|
|
||||||
|
that.get_custom_actions = function() {
|
||||||
|
return that.dropdown;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.update_displayed_data = function() {
|
||||||
|
|
||||||
|
that.revoke_note = $('<div />', {
|
||||||
|
text: text.get('@i18n:objects.cert.revoked_status'),
|
||||||
|
style: 'display: none',
|
||||||
|
'class': 'watermark'
|
||||||
|
}).appendTo(that.container);
|
||||||
|
|
||||||
|
var cert = that.certificate;
|
||||||
|
|
||||||
|
if (cert) {
|
||||||
|
that.cert_subject.text(IPA.cert.parse_dn(cert.subject).cn);
|
||||||
|
that.cert_sn.text(cert.serial_number);
|
||||||
|
that.cert_issuer.text(IPA.cert.parse_dn(cert.issuer).cn);
|
||||||
|
that.cert_valid_from.text(cert.valid_not_before);
|
||||||
|
that.cert_valid_to.text(cert.valid_not_after);
|
||||||
|
}
|
||||||
|
|
||||||
|
that.handle_revocation_reason(cert.revocation_reason);
|
||||||
|
};
|
||||||
|
|
||||||
|
that.toggle_revoked_note = function(show) {
|
||||||
|
if (show) {
|
||||||
|
that.revoke_note.css('display', 'block');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
that.revoke_note.css('display', 'none');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
that.handle_revocation_reason = function(reason) {
|
||||||
|
// Skip certificates which are not issued by ipa's CA
|
||||||
|
if (that.certificate.revoked === undefined) return;
|
||||||
|
|
||||||
|
var dd_menu = that.get_custom_actions();
|
||||||
|
|
||||||
|
if (reason && reason === 6) {
|
||||||
|
dd_menu.enable_item('remove_hold');
|
||||||
|
dd_menu.disable_item('revoke');
|
||||||
|
that.toggle_revoked_note(true);
|
||||||
|
}
|
||||||
|
else if (reason === null || reason === undefined) {
|
||||||
|
dd_menu.enable_item('revoke');
|
||||||
|
dd_menu.disable_item('remove_hold');
|
||||||
|
}
|
||||||
|
else if (typeof reason === 'number' && reason >= 0 &&
|
||||||
|
reason < IPA.cert.CRL_REASON.length) {
|
||||||
|
dd_menu.disable_item('revoke');
|
||||||
|
that.toggle_revoked_note(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
that.update = function(values) {
|
that.update = function(values) {
|
||||||
that.certificates = values;
|
|
||||||
that.create_certs();
|
var certificate = values[0];
|
||||||
|
|
||||||
|
if (!certificate ) certificate = {};
|
||||||
|
|
||||||
|
that.certificate = certificate;
|
||||||
|
|
||||||
|
that.update_displayed_data();
|
||||||
};
|
};
|
||||||
|
|
||||||
that.clear = function() {
|
that.save = function() {
|
||||||
that.content_el.empty();
|
return that.certificate.certificate;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.compose_dialog_title = function() {
|
||||||
|
var cert = that.certificate;
|
||||||
|
var cn, o;
|
||||||
|
|
||||||
|
if (cert.subject) {
|
||||||
|
cn = IPA.cert.parse_dn(cert.subject).cn;
|
||||||
|
o = IPA.cert.parse_dn(cert.subject).o;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cn = o = text.get('@i18n:objects.cert.unspecified');
|
||||||
|
}
|
||||||
|
|
||||||
|
var r = text.get('@i18n:objects.cert.view_certificate');
|
||||||
|
r = r.replace('${entity}', cn);
|
||||||
|
r = r.replace('${primary_key}', o);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.open_view_dialog = function() {
|
||||||
|
|
||||||
|
var spec = {
|
||||||
|
title: that.compose_dialog_title(),
|
||||||
|
certificate: that.certificate
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialog = IPA.cert.view_dialog(spec);
|
||||||
|
dialog.open();
|
||||||
|
};
|
||||||
|
|
||||||
|
that.open_get_dialog = function() {
|
||||||
|
var spec = {
|
||||||
|
title: that.compose_dialog_title(),
|
||||||
|
certificate: that.certificate.certificate
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialog = IPA.cert.download_dialog(spec);
|
||||||
|
dialog.open();
|
||||||
|
};
|
||||||
|
|
||||||
|
that.perform_download = function() {
|
||||||
|
var data_uri = IPA.cert.create_data_uri(that.certificate.certificate);
|
||||||
|
IPA.cert.perform_download(data_uri);
|
||||||
|
};
|
||||||
|
|
||||||
|
that.open_revoke_dialog = function() {
|
||||||
|
var spec = {
|
||||||
|
title: that.compose_dialog_title(),
|
||||||
|
message: '@i18n:objects.cert.revoke_confirmation',
|
||||||
|
ok_label: '@i18n:buttons.revoke',
|
||||||
|
on_ok: function() {
|
||||||
|
|
||||||
|
var command_spec = {
|
||||||
|
hide_activity_icon: true,
|
||||||
|
notify_activity_end: function() {
|
||||||
|
that.spinner.emit('hide-spinner');
|
||||||
|
},
|
||||||
|
notify_activity_start: function() {
|
||||||
|
that.spinner.emit('display-spinner');
|
||||||
|
},
|
||||||
|
on_success: function() {
|
||||||
|
var reason = parseInt(dialog.get_reason(), 10);
|
||||||
|
that.handle_revocation_reason(reason);
|
||||||
|
that.facet.certificate_updated.notify();
|
||||||
|
IPA.notify_success('@i18n:objects.cert.revoked');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var sn = that.certificate.serial_number;
|
||||||
|
var revocation_reason = dialog.get_reason();
|
||||||
|
IPA.cert.perform_revoke(command_spec, sn, revocation_reason);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialog = IPA.cert.revoke_dialog(spec);
|
||||||
|
dialog.open();
|
||||||
|
};
|
||||||
|
|
||||||
|
that.perform_remove_hold = function() {
|
||||||
|
var spec = {
|
||||||
|
title: that.compose_dialog_title(),
|
||||||
|
message: '@i18n:objects.cert.remove_certificate_hold_confirmation',
|
||||||
|
ok_label: '@i18n:buttons.remove_hold',
|
||||||
|
on_ok: function () {
|
||||||
|
var command_spec = {
|
||||||
|
hide_activity_icon: true,
|
||||||
|
notify_activity_end: function() {
|
||||||
|
that.spinner.emit('hide-spinner');
|
||||||
|
},
|
||||||
|
notify_activity_start: function() {
|
||||||
|
that.spinner.emit('display-spinner');
|
||||||
|
},
|
||||||
|
on_success: function() {
|
||||||
|
that.toggle_revoked_note();
|
||||||
|
that.handle_revocation_reason();
|
||||||
|
that.facet.certificate_updated.notify();
|
||||||
|
IPA.notify_success('@i18n:objects.cert.hold_removed');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var sn = that.certificate.serial_number;
|
||||||
|
IPA.cert.perform_remove_hold(command_spec, sn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialog = IPA.confirm_dialog(spec);
|
||||||
|
dialog.open();
|
||||||
};
|
};
|
||||||
|
|
||||||
return that;
|
return that;
|
||||||
|
@ -69,6 +69,8 @@
|
|||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"close": "Close",
|
"close": "Close",
|
||||||
"disable": "Disable",
|
"disable": "Disable",
|
||||||
|
"download": "Download",
|
||||||
|
"download_title": "Download certificate as PEM formatted file.",
|
||||||
"edit": "Edit",
|
"edit": "Edit",
|
||||||
"enable": "Enable",
|
"enable": "Enable",
|
||||||
"filter": "Filter",
|
"filter": "Filter",
|
||||||
@ -268,6 +270,7 @@
|
|||||||
"md5_fingerprint": "MD5 Fingerprint",
|
"md5_fingerprint": "MD5 Fingerprint",
|
||||||
"missing": "No Valid Certificate",
|
"missing": "No Valid Certificate",
|
||||||
"new_certificate": "New Certificate",
|
"new_certificate": "New Certificate",
|
||||||
|
"new_cert_format": "Certificate in base64 or PEM format",
|
||||||
"note": "Note",
|
"note": "Note",
|
||||||
"organization": "Organization",
|
"organization": "Organization",
|
||||||
"organizational_unit": "Organizational Unit",
|
"organizational_unit": "Organizational Unit",
|
||||||
@ -287,6 +290,7 @@
|
|||||||
"revoke_certificate_simple": "Revoke Certificate",
|
"revoke_certificate_simple": "Revoke Certificate",
|
||||||
"revoke_confirmation": "To confirm your intention to revoke this certificate, select a reason from the pull-down list, and click the \"Revoke\" button.",
|
"revoke_confirmation": "To confirm your intention to revoke this certificate, select a reason from the pull-down list, and click the \"Revoke\" button.",
|
||||||
"revoked": "Certificate Revoked",
|
"revoked": "Certificate Revoked",
|
||||||
|
"revoked_status": "REVOKED",
|
||||||
"serial_number": "Serial Number",
|
"serial_number": "Serial Number",
|
||||||
"serial_number_hex": "Serial Number (hex)",
|
"serial_number_hex": "Serial Number (hex)",
|
||||||
"sha1_fingerprint": "SHA1 Fingerprint",
|
"sha1_fingerprint": "SHA1 Fingerprint",
|
||||||
@ -295,6 +299,8 @@
|
|||||||
"superseded": "Superseded",
|
"superseded": "Superseded",
|
||||||
"unspecified": "Unspecified",
|
"unspecified": "Unspecified",
|
||||||
"valid": "Valid Certificate Present",
|
"valid": "Valid Certificate Present",
|
||||||
|
"valid_from": "Valid from",
|
||||||
|
"valid_to": "Valid to",
|
||||||
"validity": "Validity",
|
"validity": "Validity",
|
||||||
"view_certificate": "Certificate for ${entity} ${primary_key}",
|
"view_certificate": "Certificate for ${entity} ${primary_key}",
|
||||||
"view_certificate_btn": "View Certificate"
|
"view_certificate_btn": "View Certificate"
|
||||||
|
@ -211,6 +211,8 @@ class i18n_messages(Command):
|
|||||||
"cancel": _("Cancel"),
|
"cancel": _("Cancel"),
|
||||||
"close": _("Close"),
|
"close": _("Close"),
|
||||||
"disable": _("Disable"),
|
"disable": _("Disable"),
|
||||||
|
"download": _("Download"),
|
||||||
|
"download_title": _("Download certificate as PEM formatted file."),
|
||||||
"edit": _("Edit"),
|
"edit": _("Edit"),
|
||||||
"enable": _("Enable"),
|
"enable": _("Enable"),
|
||||||
"filter": _("Filter"),
|
"filter": _("Filter"),
|
||||||
@ -411,6 +413,7 @@ class i18n_messages(Command):
|
|||||||
"md5_fingerprint": _("MD5 Fingerprint"),
|
"md5_fingerprint": _("MD5 Fingerprint"),
|
||||||
"missing": _("No Valid Certificate"),
|
"missing": _("No Valid Certificate"),
|
||||||
"new_certificate": _("New Certificate"),
|
"new_certificate": _("New Certificate"),
|
||||||
|
"new_cert_format": _("Certificate in base64 or PEM format"),
|
||||||
"note": _("Note"),
|
"note": _("Note"),
|
||||||
"organization": _("Organization"),
|
"organization": _("Organization"),
|
||||||
"organizational_unit": _("Organizational Unit"),
|
"organizational_unit": _("Organizational Unit"),
|
||||||
@ -430,6 +433,7 @@ class i18n_messages(Command):
|
|||||||
"revoke_certificate_simple": _("Revoke Certificate"),
|
"revoke_certificate_simple": _("Revoke Certificate"),
|
||||||
"revoke_confirmation": _("To confirm your intention to revoke this certificate, select a reason from the pull-down list, and click the \"Revoke\" button."),
|
"revoke_confirmation": _("To confirm your intention to revoke this certificate, select a reason from the pull-down list, and click the \"Revoke\" button."),
|
||||||
"revoked": _("Certificate Revoked"),
|
"revoked": _("Certificate Revoked"),
|
||||||
|
"revoked_status": _("REVOKED"),
|
||||||
"serial_number": _("Serial Number"),
|
"serial_number": _("Serial Number"),
|
||||||
"serial_number_hex": _("Serial Number (hex)"),
|
"serial_number_hex": _("Serial Number (hex)"),
|
||||||
"sha1_fingerprint": _("SHA1 Fingerprint"),
|
"sha1_fingerprint": _("SHA1 Fingerprint"),
|
||||||
@ -438,6 +442,8 @@ class i18n_messages(Command):
|
|||||||
"superseded": _("Superseded"),
|
"superseded": _("Superseded"),
|
||||||
"unspecified": _("Unspecified"),
|
"unspecified": _("Unspecified"),
|
||||||
"valid": _("Valid Certificate Present"),
|
"valid": _("Valid Certificate Present"),
|
||||||
|
"valid_from": _("Valid from"),
|
||||||
|
"valid_to": _("Valid to"),
|
||||||
"validity": _("Validity"),
|
"validity": _("Validity"),
|
||||||
"view_certificate": _("Certificate for ${entity} ${primary_key}"),
|
"view_certificate": _("Certificate for ${entity} ${primary_key}"),
|
||||||
"view_certificate_btn": _("View Certificate"),
|
"view_certificate_btn": _("View Certificate"),
|
||||||
|
Loading…
Reference in New Issue
Block a user