URL: https://github.com/freeipa/freeipa/pull/400
Author: pvomacka
 Title: #400: WebUI: Certificate Mapping
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/400/head:pr400
git checkout pr400
From f93be59c887ee313ae6c8a5e0e963ee857fee2fb Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Mon, 16 Jan 2017 13:59:16 +0100
Subject: [PATCH 1/3] WebUI: Add possibility to set widget always writable

If widget will have set attribute 'always_writable' to true, then
'no_update' flag will be ingored. Used in command user-{add,remove}-certmap
which needs to be writable in WebUI and also needs to be omitted from
user-mod command.

Part of: https://fedorahosted.org/freeipa/ticket/6601
---
 install/ui/src/freeipa/field.js  | 11 ++++++++++-
 install/ui/src/freeipa/widget.js |  2 ++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/install/ui/src/freeipa/field.js b/install/ui/src/freeipa/field.js
index d70a778..2d05ab1 100644
--- a/install/ui/src/freeipa/field.js
+++ b/install/ui/src/freeipa/field.js
@@ -484,7 +484,16 @@ field.field = IPA.field = function(spec) {
                 writable = false;
             }
 
-            if (that.metadata.flags && array.indexOf(that.metadata.flags, 'no_update') > -1) {
+            // In case that widget has set always_writable attribute, then
+            // 'no_update' flag is ignored in WebUI. It is done because of
+            // commands like user-{add,remove}-certmap. They operate with user's
+            // attribute, which cannot be changed using user-mod, but only
+            // using command user-{add,remove}-certmap. Therefore it has set
+            // 'no_update' flag, but we need to show 'Add', 'Remove' buttons in
+            // WebUI.
+            if (that.metadata.flags &&
+                array.indexOf(that.metadata.flags, 'no_update') > -1 &&
+                that.widget && !that.widget.always_writable) {
                 writable = false;
             }
         }
diff --git a/install/ui/src/freeipa/widget.js b/install/ui/src/freeipa/widget.js
index 6ad8aad..e6dfef9 100644
--- a/install/ui/src/freeipa/widget.js
+++ b/install/ui/src/freeipa/widget.js
@@ -1516,6 +1516,8 @@ IPA.custom_command_multivalued_widget = function(spec) {
 
     var that = IPA.multivalued_widget(spec);
 
+    that.always_writable = spec.always_writable || true;
+
     that.item_name = spec.item_name || '';
 
     that.adder_dialog_spec = spec.adder_dialog_spec;

From 751c6ff6cf1118e1f1794e0f7b680809ecd2fe77 Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Mon, 16 Jan 2017 14:13:42 +0100
Subject: [PATCH 2/3] WebUI: Create non editable row widget for mutlivalued
 widget

Old krb-principal widget is changed to general one. And used also for
ipacertmapdata in user.

This widget make every line non-editable.

Part of: https://fedorahosted.org/freeipa/ticket/6601
---
 install/ui/src/freeipa/host.js    |  3 ++-
 install/ui/src/freeipa/service.js |  3 ++-
 install/ui/src/freeipa/user.js    |  3 ++-
 install/ui/src/freeipa/widget.js  | 29 +++++++++++++++++++----------
 4 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/install/ui/src/freeipa/host.js b/install/ui/src/freeipa/host.js
index 87cf264..023530a 100644
--- a/install/ui/src/freeipa/host.js
+++ b/install/ui/src/freeipa/host.js
@@ -93,7 +93,8 @@ return {
                             name: 'krbprincipalname',
                             item_name: 'principal',
                             child_spec: {
-                                $type: 'krb_principal'
+                                $type: 'non_editable_row',
+                                data_name: 'krb-principal'
                             }
                         },
                         {
diff --git a/install/ui/src/freeipa/service.js b/install/ui/src/freeipa/service.js
index a6607d2..adae347 100644
--- a/install/ui/src/freeipa/service.js
+++ b/install/ui/src/freeipa/service.js
@@ -81,7 +81,8 @@ return {
                             name: 'krbprincipalname',
                             item_name: 'principal',
                             child_spec: {
-                                $type: 'krb_principal'
+                                $type: 'non_editable_row',
+                                data_name: 'krb-principal'
                             }
                         },
                         {
diff --git a/install/ui/src/freeipa/user.js b/install/ui/src/freeipa/user.js
index 7a08151..a36b65a 100644
--- a/install/ui/src/freeipa/user.js
+++ b/install/ui/src/freeipa/user.js
@@ -192,7 +192,8 @@ return {
                             name: 'krbprincipalname',
                             item_name: 'principal',
                             child_spec: {
-                                $type: 'krb_principal'
+                                $type: 'non_editable_row',
+                                data_name: 'krb-principal'
                             }
                         },
                         {
diff --git a/install/ui/src/freeipa/widget.js b/install/ui/src/freeipa/widget.js
index e6dfef9..58d735c 100644
--- a/install/ui/src/freeipa/widget.js
+++ b/install/ui/src/freeipa/widget.js
@@ -1809,6 +1809,8 @@ IPA.custom_command_multivalued_widget = function(spec) {
 IPA.krb_principal_multivalued_widget = function (spec) {
 
     spec = spec || {};
+    spec.child_spec = spec.child_spec || {};
+    spec.child_spec.data_name = spec.child_spec.data_name || 'krb-principal';
 
     spec.adder_dialog_spec = spec.adder_dialog_spec || {
         title: '@i18n:krbaliases.adder_title',
@@ -1829,7 +1831,7 @@ IPA.krb_principal_multivalued_widget = function (spec) {
 
     that.create_remove_dialog_message = function(row) {
         var message = text.get('@i18n:krbaliases.remove_message');
-        message = message.replace('${alias}', row.widget.principal_name);
+        message = message.replace('${alias}', row.widget.new_value);
 
         return message;
     };
@@ -1837,7 +1839,7 @@ IPA.krb_principal_multivalued_widget = function (spec) {
 
     that.create_remove_args = function(row) {
         var pkey = that.facet.get_pkey();
-        var krbprincipalname = row.widget.principal_name;
+        var krbprincipalname = row.widget.new_value;
         krbprincipalname = [ krbprincipalname ];
 
         var args = [
@@ -1864,22 +1866,27 @@ IPA.krb_principal_multivalued_widget = function (spec) {
 };
 
 /**
- * Widget which is used as row in kerberos aliases multivalued widget.
- * It contains only string where is the principal alias name and delete button.
+ * Widget which is used as row in multivalued widget. Each row is just
+ * non-editable text field.
  *
  * @class
  * @extends IPA.input_widget
  */
-IPA.krb_principal_widget = function(spec) {
+ IPA.non_editable_row_widget = function(spec) {
     spec = spec || {};
 
     var that = IPA.input_widget();
 
+    /**
+     * Prefix of CSS class of each row.
+     */
+    that.data_name = spec.data_name || 'default';
+
     that.create = function(container) {
         that.widget_create(container);
 
-        that.principal_text = $('<span />', {
-            'class': 'krb-principal-name',
+        that.data_text = $('<span />', {
+            'class': that.data_name + '-data',
             text: ''
         }).appendTo(container);
 
@@ -1892,19 +1899,20 @@ IPA.krb_principal_widget = function(spec) {
 
     that.update = function(value) {
 
-        var principal_name = value[0] || '';
+        var single_value = value[0] || '';
 
-        that.principal_name = principal_name;
+        that.new_value = single_value;
         that.update_text();
     };
 
     that.update_text = function() {
-        that.principal_text.text(that.principal_name);
+        that.data_text.text(that.new_value);
     };
 
     return that;
 };
 
+
 /**
  * Option widget base
  *
@@ -7173,6 +7181,7 @@ exp.register = function() {
     w.register('html', IPA.html_widget);
     w.register('link', IPA.link_widget);
     w.register('multivalued', IPA.multivalued_widget);
+    w.register('non_editable_row', IPA.non_editable_row_widget);
     w.register('custom_command_multivalued',
         IPA.custom_command_multivalued_widget);
     w.register('krb_principal_multivalued',

From 65661ec8a7ff7ef4e081799654eb0d35399b7c87 Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Mon, 16 Jan 2017 14:16:47 +0100
Subject: [PATCH 3/3] WebUI: Add certmap module

Add facets for certmaprule and certmapconfigure entities.

https://fedorahosted.org/freeipa/ticket/6601
---
 install/ui/src/freeipa/app.js                  |   1 +
 install/ui/src/freeipa/navigation/menu_spec.js |  16 +-
 install/ui/src/freeipa/plugins/certmap.js      | 394 +++++++++++++++++++++++++
 install/ui/src/freeipa/stageuser.js            |   9 +
 install/ui/src/freeipa/user.js                 |   9 +
 install/ui/test/data/ipa_init.json             |  12 +
 ipaserver/plugins/internal.py                  |  12 +
 7 files changed, 452 insertions(+), 1 deletion(-)
 create mode 100644 install/ui/src/freeipa/plugins/certmap.js

diff --git a/install/ui/src/freeipa/app.js b/install/ui/src/freeipa/app.js
index 4eb045d..d262a64 100644
--- a/install/ui/src/freeipa/app.js
+++ b/install/ui/src/freeipa/app.js
@@ -32,6 +32,7 @@ define([
     './plugins/ca',
     './plugins/caacl',
     './plugins/certprofile',
+    './plugins/certmap',
     './dns',
     './group',
     './hbac',
diff --git a/install/ui/src/freeipa/navigation/menu_spec.js b/install/ui/src/freeipa/navigation/menu_spec.js
index 7d121d9..281bf22 100644
--- a/install/ui/src/freeipa/navigation/menu_spec.js
+++ b/install/ui/src/freeipa/navigation/menu_spec.js
@@ -151,7 +151,21 @@ var nav = {};
                     ]
                 },
                 { entity: 'otptoken' },
-                { entity: 'radiusproxy' }
+                { entity: 'radiusproxy' },
+                {
+                    entity: 'certmaprule',
+                    facet: 'search',
+                    children: [
+                        {
+                            entity: 'certmaprule',
+                            facet: 'search'
+                        },
+                        {
+                            entity: 'certmapconfig',
+                            facet: 'details'
+                        }
+                    ]
+                }
             ]
         },
         {
diff --git a/install/ui/src/freeipa/plugins/certmap.js b/install/ui/src/freeipa/plugins/certmap.js
new file mode 100644
index 0000000..0ca331b
--- /dev/null
+++ b/install/ui/src/freeipa/plugins/certmap.js
@@ -0,0 +1,394 @@
+//
+// Copyright (C) 2017  FreeIPA Contributors see COPYING for license
+//
+
+
+define([
+        'dojo/_base/lang',
+        'dojo/_base/declare',
+        'dojo/Evented',
+        'dojo/on',
+        '../navigation',
+        '../field',
+        '../ipa',
+        '../phases',
+        '../reg',
+        '../widget',
+        '../text',
+        '../util',
+        // plain imports
+        '../search',
+        '../entity'],
+            function(lang, declare, Evented, on, navigation, mod_field, IPA,
+                     phases, reg, widget_mod, text, util) {
+/**
+ * Certificate map module
+ * @class
+ */
+var certmap = IPA.certmap = {
+
+    search_facet_group: {
+        facets: {
+            certmaprule_search: 'certmaprule_search',
+            domainlevel: 'domainlevel_details'
+        }
+    }
+};
+
+var make_certmaprule_spec = function() {
+return {
+    name: 'certmaprule',
+    facets: [
+        {
+            $type: 'search',
+            always_request_members: true,
+            details_facet: 'details',
+            facet_groups: [certmap.search_facet_group],
+            facet_group: 'search',
+            row_enabled_attribute: 'ipaenabledflag',
+            columns: [
+                'cn',
+                {
+                    name: 'ipaenabledflag',
+                    label: '@i18n:status.label',
+                    formatter: 'boolean_status'
+                },
+                'description'
+            ],
+            actions: [
+                'batch_disable',
+                'batch_enable'
+            ],
+            control_buttons: [
+                {
+                    name: 'disable',
+                    label: '@i18n:buttons.disable',
+                    icon: 'fa-minus'
+                },
+                {
+                    name: 'enable',
+                    label: '@i18n:buttons.enable',
+                    icon: 'fa-check'
+                }
+            ]
+        },
+        {
+            $type: 'details',
+            disable_facet_tabs: true,
+            facet_groups: [certmap.search_facet_group],
+            facet_group: 'search',
+            actions: [
+                'enable',
+                'disable',
+                'delete'
+            ],
+            header_actions: ['enable', 'disable', 'delete'],
+            state: {
+                evaluators: [
+                    {
+                        $factory: IPA.enable_state_evaluator,
+                        field: 'ipaenabledflag'
+                    }
+                ]
+            },
+            sections: [
+                {
+                    name: 'details',
+                    fields: [
+                        'cn',
+                        {
+                            $type: 'textarea',
+                            name: 'description'
+                        },
+                        'ipacertmapissuer',
+                        'ipacertmapmaprule',
+                        'ipacertmapmatchrule',
+                        {
+                            $type: 'multivalued',
+                            name: 'associateddomain'
+                        },
+                        'ipacertmappriority'
+                    ]
+                }
+            ]
+        }
+    ],
+    adder_dialog: {
+        $factory: certmap.rule_adder_dialog,
+        fields: [
+            'cn',
+            'ipacertmapissuer',
+            'ipacertmapmaprule',
+            'ipacertmapmatchrule',
+            {
+                $type: 'multivalued',
+                name: 'associateddomain'
+            },
+            'ipacertmappriority',
+            {
+                $type: 'textarea',
+                name: 'description'
+            }
+        ]
+    }
+};};
+
+
+var make_certmapconfig_spec = function() {
+return {
+    name: 'certmapconfig',
+    defines_key: false,
+    facets: [
+        {
+            $type: 'details',
+            facet_groups: [certmap.search_facet_group],
+            facet_group: 'search',
+            sections: [
+                {
+                    name: 'details',
+                    fields: [
+                        {
+                            $type: 'checkbox',
+                            name: 'ipacertmappromptusername'
+                        }
+                    ]
+                }
+            ]
+        }
+    ]
+};};
+
+
+/**
+ * Custom adder dialog for adding cert map rules which automatically turns on
+ * the rule - to be consistent with HBAC rules etc.
+ */
+certmap.rule_adder_dialog = function (spec) {
+    spec = spec || {};
+
+    var that = IPA.entity_adder_dialog(spec);
+
+    that.create_add_command = function(record) {
+        var command = that.entity_adder_dialog_create_add_command(record);
+
+        command.set_option('ipaenabledflag', true);
+
+        return command;
+    };
+
+    return that;
+};
+
+/**
+ * Multivalued widget which is used for working with user's certmap.
+ *
+ * @class
+ * @extends IPA.custom_command_multivalued_widget
+ */
+certmap.certmap_multivalued_widget = function (spec) {
+
+    spec = spec || {};
+
+    var that = IPA.custom_command_multivalued_widget(spec);
+
+    that.create_adder_dialog = function() {
+        var spec = that.adder_dialog_spec || {
+            name: 'custom-add-dialog',
+            title: '@i18n:objects.certmap.adder_title',
+            policies: [
+                {
+                    $factory: IPA.multiple_choice_section_policy,
+                    widget: 'type'
+                }
+            ]
+        };
+
+        that.adder_dialog = certmap.custom_adder_dialog(spec);
+        that.adder_dialog.create_button({
+            name: 'add',
+            label: '@i18n:buttons.add',
+            click: function() {
+                that.add(that.adder_dialog);
+            }
+        });
+
+        that.adder_dialog.create_button({
+            name: 'cancel',
+            label: '@i18n:buttons.cancel',
+            click: function() {
+                that.adder_dialog.close();
+            }
+        });
+
+    };
+
+    that.create_remove_dialog_title = function(row) {
+        return text.get('@i18n:objects.certmap.deleter_title');
+    };
+
+    that.create_remove_dialog_message = function(row) {
+        var message = text.get('@i18n:objects.certmap.deleter_content');
+        message = message.replace('${data}', row.widget.new_value);
+
+        return message;
+    };
+
+    /**
+     * Compose options for add command.
+     * @return {Object} options
+     */
+    that.create_add_options = function() {
+        var options = {};
+        var widgets = that.adder_dialog.widgets.get_widgets();
+        var widget = widgets[0];
+        var inner_widgets = widget.widgets.get_widgets();
+
+        for (var i = 0, l = inner_widgets.length; i<l; i++) {
+            var w = inner_widgets[i];
+
+            if (w.enabled) {
+                var field = that.adder_dialog.fields.get_field(w.name);
+                var value = field.save();
+
+                if (field.name === 'issuer' || field.name === 'subject') {
+                    value = value[0];
+                }
+
+                if (!util.is_empty(value)) options[field.name] = value;
+            }
+        }
+
+        return options;
+    };
+
+
+    /**
+     * Compose options for remove command.
+     *
+     * @param {Object} row
+     * @return {Object} options
+     */
+    that.create_remove_options = function(row) {
+        var options = {};
+        var data = row.widget.new_value;
+
+        options['ipacertmapdata'] = data;
+
+        return options;
+    };
+
+    return that;
+};
+
+
+/**
+ * Adder dialog for adding certmapdata to user.
+ *
+ */
+certmap.custom_adder_dialog = function(spec) {
+    spec = spec || {};
+    spec.fields = [
+        {
+            $type: 'multivalued',
+            name: 'ipacertmapdata',
+            label: '@i18n:objects.certmap.data_label',
+            widget: 'type.ipacertmapdata'
+        },
+        {
+            $type: 'multivalued',
+            name: 'usercertificate',
+            label: '@i18n:objects.certmap.certificate',
+            widget: 'type.usercertificate',
+            child_spec: {
+                $type: 'textarea'
+            }
+        },
+        {
+            name: 'issuer',
+            label: '@i18n:objects.certmap.issuer',
+            widget: 'type.issuer'
+        },
+        {
+            name: 'subject',
+            label: '@i18n:objects.certmap.subject',
+            widget: 'type.subject'
+        }
+    ];
+
+    spec.widgets = [
+        {
+            $type: 'multiple_choice_section',
+            name: 'type',
+            choices: [
+                {
+                    name: 'data',
+                    label: '@i18n:objects.certmap.data_label',
+                    fields: ['ipacertmapdata', 'usercertificate'],
+                    required: [],
+                    enabled: true
+                },
+                {
+                    name: 'issuer_subj',
+                    label: '@i18n:objects.certmap.issuer_subject',
+                    fields: ['issuer', 'subject'],
+                    required: []
+                }
+            ],
+            widgets: [
+                {
+                    $type: 'multivalued',
+                    name: 'ipacertmapdata'
+                },
+                {
+                    $type: 'multivalued',
+                    name: 'usercertificate',
+                    child_spec: {
+                        $type: 'textarea'
+                    }
+                },
+                {
+                    name: 'issuer'
+                },
+                {
+                    name: 'subject'
+                }
+            ]
+        }
+    ];
+
+    var that = IPA.dialog(spec);
+
+    return that;
+};
+
+/**
+ * Certificat Mapping Rules entity specification object
+ * @member certmap
+ */
+certmap.certmaprule_spec = make_certmaprule_spec();
+
+/**
+ * Certificate Mapping Configuration entity specification object
+ * @member certmap
+ */
+certmap.certmapconfig_spec = make_certmapconfig_spec();
+
+
+/**
+ * Register entity
+ * @member cermap
+ */
+certmap.register = function() {
+    var e = reg.entity;
+    var w = reg.widget;
+
+    e.register({type: 'certmaprule', spec: certmap.certmaprule_spec});
+    e.register({type: 'certmapconfig', spec: certmap.certmapconfig_spec});
+    w.register('certmap_multivalued',
+                certmap.certmap_multivalued_widget);
+};
+
+phases.on('registration', certmap.register);
+
+return certmap;
+});
diff --git a/install/ui/src/freeipa/stageuser.js b/install/ui/src/freeipa/stageuser.js
index bf24491..f698fcc 100644
--- a/install/ui/src/freeipa/stageuser.js
+++ b/install/ui/src/freeipa/stageuser.js
@@ -147,6 +147,15 @@ return {
                             label: '@i18n:objects.sshkeystore.keys'
                         },
                         {
+                            $type: 'certmap_multivalued',
+                            name: 'ipacertmapdata',
+                            item_name: 'certmapdata',
+                            child_spec: {
+                                $type: 'non_editable_row',
+                                data_name: 'certmap'
+                            }
+                        },
+                        {
                             $type: 'checkboxes',
                             name: 'ipauserauthtype',
                             flags: ['w_if_no_aci'],
diff --git a/install/ui/src/freeipa/user.js b/install/ui/src/freeipa/user.js
index a36b65a..e92ef76 100644
--- a/install/ui/src/freeipa/user.js
+++ b/install/ui/src/freeipa/user.js
@@ -218,6 +218,15 @@ return {
                             label: '@i18n:objects.cert.certificates'
                         },
                         {
+                            $type: 'certmap_multivalued',
+                            name: 'ipacertmapdata',
+                            item_name: 'certmapdata',
+                            child_spec: {
+                                $type: 'non_editable_row',
+                                data_name: 'certmap'
+                            }
+                        },
+                        {
                             $type: 'checkboxes',
                             name: 'ipauserauthtype',
                             flags: ['w_if_no_aci'],
diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json
index 6d11e73..4483623 100644
--- a/install/ui/test/data/ipa_init.json
+++ b/install/ui/test/data/ipa_init.json
@@ -315,6 +315,18 @@
                             "view_certificate": "Certificate for ${entity} ${primary_key}",
                             "view_certificate_btn": "View Certificate"
                         },
+                        "certmap": {
+                            "adder_title": "Add Certificate Mapping Data",
+                            "data_label": "Certificate mapping data",
+                            "certificate": "Certificate",
+                            "conf_str": "Configuration string",
+                            "deleter_content": "Do you want to remove certificate mapping data ${data}?",
+                            "deleter_title": "Remove Certificate Mapping Data",
+                            "issuer": "Issuer",
+                            "issuer_subject": "Issuer and subject",
+                            "subject": "Subject",
+                            "version": "Version",
+                        },
                         "config": {
                             "group": "Group Options",
                             "search": "Search Options",
diff --git a/ipaserver/plugins/internal.py b/ipaserver/plugins/internal.py
index 0a8139e..31892c5 100644
--- a/ipaserver/plugins/internal.py
+++ b/ipaserver/plugins/internal.py
@@ -465,6 +465,18 @@ class i18n_messages(Command):
                 "view_certificate": _("Certificate for ${entity} ${primary_key}"),
                 "view_certificate_btn": _("View Certificate"),
             },
+            "certmap": {
+                "adder_title": _("Add Certificate Mapping Data"),
+                "data_label": _("Certificate mapping data"),
+                "certificate": _("Certificate"),
+                "conf_str": _("Configuration string"),
+                "deleter_content": _("Do you want to remove certificate mapping data ${data}?"),
+                "deleter_title": _("Remove Certificate Mapping Data"),
+                "issuer": _("Issuer"),
+                "issuer_subject": _("Issuer and subject"),
+                "subject": _("Subject"),
+                "version": _("Version"),
+            },
             "config": {
                 "group": _("Group Options"),
                 "search": _("Search Options"),
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to