summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Vomacka <pvomacka@redhat.com>2016-04-26 08:44:03 +0200
committerPetr Vobornik <pvoborni@redhat.com>2016-06-29 15:41:58 +0200
commit6d3622c600a82f889e77809c982d996974335e62 (patch)
tree68e0990b79d7df8c11688577c1391bdae8571a09
parent3056f349b94eb99deb665937a61204e0bfea6b78 (diff)
downloadfreeipa-6d3622c600a82f889e77809c982d996974335e62.tar.gz
freeipa-6d3622c600a82f889e77809c982d996974335e62.tar.xz
freeipa-6d3622c600a82f889e77809c982d996974335e62.zip
Add widget for showing multiple certificates
Certs widget is based on multivalued widget and adds ability to add new certificate and delete it. Each line is cert_widget. https://fedorahosted.org/freeipa/ticket/5108 https://fedorahosted.org/freeipa/ticket/5381 Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
-rwxr-xr-xinstall/ui/src/freeipa/certificate.js172
-rw-r--r--install/ui/src/freeipa/field.js1
-rw-r--r--install/ui/test/data/ipa_init.json1
-rw-r--r--ipaserver/plugins/internal.py1
4 files changed, 111 insertions, 64 deletions
diff --git a/install/ui/src/freeipa/certificate.js b/install/ui/src/freeipa/certificate.js
index 1ea4c1bac..0aa270039 100755
--- a/install/ui/src/freeipa/certificate.js
+++ b/install/ui/src/freeipa/certificate.js
@@ -113,6 +113,25 @@ IPA.cert.parse_dn = function(dn) {
return result;
};
+IPA.cert.get_base64 = function(text) {
+ /*
+ * Input is assumed to be base64 or PEM formatted certificate.
+ * The function just cuts the '-----BEGIN CERTIFICATE----' and
+ * '-----END CERTIFICATE-----' strings if they are present.
+ * Returns only base64 blob.
+ */
+
+ var match = IPA.cert.PEM_CERT_REGEXP.exec(text);
+
+ if (match) {
+ match = match[2].replace(/\s*/g, '');
+ return $.trim(match);
+ }
+
+ text = text.replace(/\s*/g, '');
+ return $.trim(text);
+};
+
IPA.cert.pem_format_base64 = function(text) {
/*
* Input is assumed to be base64 possibly with embedded whitespace.
@@ -547,31 +566,6 @@ IPA.cert.load_policy = function(spec) {
//store cert directly to facet. FIXME: introduce concept of models
that.container.certificate = certificate;
that.notify_loaded();
-
- // initialize another load of certificate because current entity
- // show commands don't contain revocation_reason so previous data
- // might be slightly incorrect
- if (!that.has_reason && certificate && certificate.certificate &&
- IPA.cert.is_enabled()) {
- that.load_revocation_reason(certificate.serial_number);
- }
- };
-
- that.load_revocation_reason = function(serial_number) {
- if (serial_number === null || serial_number === undefined) return;
-
- rpc.command({
- entity: 'cert',
- method: 'show',
- args: [serial_number],
- on_success: function(data, text_status, xhr) {
- // copy it so consumers can notice the difference
- that.container.certificate = lang.clone(that.container.certificate);
- var cert = that.container.certificate;
- cert.revocation_reason = data.result.result.revocation_reason;
- that.notify_loaded();
- }
- }).execute();
};
that.notify_loaded = function() {
@@ -1011,57 +1005,108 @@ IPA.cert.status_field = function(spec) {
return that;
};
-IPA.cert.cert_widget = function(spec) {
+
+/**
+ * Certificates widget
+ *
+ * Multivalued widget with certificate widget instead of text widget.
+ *
+ * @class
+ * @extends IPA.multivalued_widget
+ */
+IPA.cert.certs_widget = function(spec) {
spec = spec || {};
- spec.css_class = spec.css_class || 'certificate-widget';
+ spec.child_spec = spec.child_spec || {
+ $factory: IPA.cert.cert_widget,
+ css_class: 'certificate-widget',
+ facet: spec.facet
+ };
- var that = IPA.input_widget(spec);
- that.certs_visible = false;
+ spec.item_name = 'cert';
- that.create = function(container) {
+ spec.custom_actions = spec.custom_actions === undefined ? true :
+ spec.custom_actions;
- that.widget_create(container);
- that.content_el = $('<div>').appendTo(container);
+ spec.adder_dialog_spec = {
+ name: 'cert-add-dialog',
+ title: '@i18n:objects.cert.new_certificate',
+ sections: [
+ {
+ show_header: false,
+ fields: [
+ {
+ $type: 'textarea',
+ name: 'new_cert',
+ label: '@i18n:objects.cert.new_cert_format',
+ required: true,
+ rows: 15
+ }
+ ],
+ layout:
+ {
+ $factory: widget_mod.fluid_layout,
+ widget_cls: 'col-sm-12',
+ label_cls: 'col-sm-6 control-label'
+ }
+ }
+ ]
};
- that.create_status = function(name, text, icon) {
+ var that = IPA.custom_command_multivalued_widget(spec);
- var status = $('<label/>', {
- 'class': 'certificate-status'
- });
+ that.create_remove_options = function(row) {
+ var blob = row.widget.save();
+ var options = {
+ usercertificate: blob
+ };
- $('<i/>', {
- 'class': icon
- }).appendTo(status);
+ return options;
+ };
- status.append(" " + text);
+ /**
+ * Called on success of remove command. Override point.
+ */
+ that.on_success_remove = function(data, text_status, xhr) {
+ that.facet.refresh();
+ that.facet.certificate_updated.notify();
+ IPA.notify_success(data.result.summary);
+ };
+
+ that.create_add_options = function() {
+ var blob = that.adder_dialog.get_field('new_cert').get_value()[0];
+ blob = IPA.cert.get_base64(blob);
+ var options = {
+ usercertificate: blob
+ };
- return status;
+ return options;
};
- that.create_certs = function() {
+ that.on_success_add = function(data, text_status, xhr) {
+ that.facet.refresh();
+ that.facet.certificate_updated.notify();
+ IPA.notify_success(data.result.summary);
+ that.adder_dialog.close();
+ };
- that.content_el.empty();
- var l = that.certificates.length;
-
- if (l && that.certs_visible) {
- for (var i=0; i<l; i++) {
- $('<div/>', {
- 'class': 'certificate',
- text: that.certificates[i]
- }).appendTo(that.content_el);
- }
- $('<div/>').append(
- IPA.button({
- name: 'hide',
- label: '@i18n:buttons.hide',
- click: function() {
- that.certs_visible = false;
- that.create_certs();
- }
- })).
- appendTo(that.content_el);
+ that.create_remove_dialog_title = function(row) {
+ var title = row.widget.compose_dialog_title();
+
+ return title;
+ };
+
+ that.create_remove_dialog_message = function(row) {
+ var sn = row.widget.certificate.serial_number;
+ var message = text.get('@i18n:actions.delete_confirm');
+ message = message.replace('${object}',
+ text.get('@i18n:objects.cert.delete_cert_end') + sn);
+
+ return message;
+ };
+
+ return that;
+};
}
if (!l) {
@@ -1514,10 +1559,9 @@ exp.register = function() {
var f = reg.field;
var a = reg.action;
- w.register('certificate', IPA.cert.cert_widget);
+ w.register('certs', IPA.cert.certs_widget);
w.register('certificate_status', IPA.cert.status_widget);
f.register('certificate_status', IPA.cert.status_field);
-
f.register('revocation_reason', IPA.revocation_reason_field);
w.register('revocation_reason', IPA.text_widget);
diff --git a/install/ui/src/freeipa/field.js b/install/ui/src/freeipa/field.js
index 3f7e1d1b4..d8b957f5a 100644
--- a/install/ui/src/freeipa/field.js
+++ b/install/ui/src/freeipa/field.js
@@ -1553,6 +1553,7 @@ field.register = function() {
var v = reg.validator;
var l = reg.adapter;
+ f.register('certs', field.field);
f.register('checkbox', field.checkbox_field);
f.register('checkboxes', field.field);
f.register('combobox', field.field);
diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json
index 19fb1008e..cdb7bdbef 100644
--- a/install/ui/test/data/ipa_init.json
+++ b/install/ui/test/data/ipa_init.json
@@ -242,6 +242,7 @@
"cessation_of_operation": "Cessation of Operation",
"common_name": "Common Name",
"download": "Download",
+ "delete_cert_end": "the certificate with serial number ",
"expires_on": "Expires On",
"fingerprints": "Fingerprints",
"find_issuedon_from": "Issued on from",
diff --git a/ipaserver/plugins/internal.py b/ipaserver/plugins/internal.py
index fc437264e..8552f63d6 100644
--- a/ipaserver/plugins/internal.py
+++ b/ipaserver/plugins/internal.py
@@ -385,6 +385,7 @@ class i18n_messages(Command):
"cessation_of_operation": _("Cessation of Operation"),
"common_name": _("Common Name"),
"download": _("Download"),
+ "delete_cert_end": _("the certificate with serial number "),
"expires_on": _("Expires On"),
"find_issuedon_from": _("Issued on from"),
"find_issuedon_to": _("Issued on to"),