Note: static json files for testing and such will be updated soon (there were several patch which changes API. I rather want to do one mass regeneration than several minor ones in a short period of time.


1) [PATCH] Web UI:Certificate pages

Following pages were added to Web UI:
 * certificated details
 * certificate search

Certificate is not regular object so it gets no metadata. Therefore artificial metadata were created for it to allow usage of search and details facet.

Search and details facet were modified to allow removing of add/remove/update/reset buttons - certificates have no mod operation and they are not added by standard means.

User can revoke and restore certificated in details facet.

https://fedorahosted.org/freeipa/ticket/3419

2) [PATCH] Web UI:Choose different search option for cert-find

This extends certificate search page by search option select. Therefore
the search is not restricted to 'subject'.

It should be replaced by https://fedorahosted.org/freeipa/ticket/191 in a future.

https://fedorahosted.org/freeipa/ticket/3419
--
Petr Vobornik
From 868040b866e6180f81fae2d8c7f50482e09824e4 Mon Sep 17 00:00:00 2001
From: Petr Vobornik <pvobo...@redhat.com>
Date: Fri, 22 Feb 2013 17:22:30 +0100
Subject: [PATCH] Web UI:Certificate pages

Following pages were added to Web UI:
 * certificated details
 * certificate search

Certificate is not regular object so it gets no metadata. Therefore artificial
metadata were created for it to allow usage of search and details facet.

Search and details facet were modified to allow removing of add/remove/update/
reset buttons - certificates have no mod operation and they are not added by
standard means.

User can revoke and restore certificated in details facet.

https://fedorahosted.org/freeipa/ticket/3419
---
 install/ui/src/freeipa/certificate.js | 255 ++++++++++++++++++++++++++++++++--
 install/ui/src/freeipa/details.js     |  24 ++--
 install/ui/src/freeipa/facet.js       |   1 +
 install/ui/src/freeipa/search.js      |  24 ++--
 install/ui/src/freeipa/webui.js       |   3 +-
 install/ui/src/freeipa/widget.js      |   3 +
 install/ui/test/data/ipa_init.json    |   7 +
 ipalib/plugins/internal.py            |   7 +
 8 files changed, 294 insertions(+), 30 deletions(-)

diff --git a/install/ui/src/freeipa/certificate.js b/install/ui/src/freeipa/certificate.js
index f7bc843590ee621a071c764131dcf9ed9f5e75f6..1b6a129c3afeebd65182f8addf2884be66abffa5 100755
--- a/install/ui/src/freeipa/certificate.js
+++ b/install/ui/src/freeipa/certificate.js
@@ -19,7 +19,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-define(['./ipa', './jquery', './dialog'], function(IPA, $) {
+define(['./ipa', './jquery','dojo/_base/lang', './dialog'], function(IPA, $, lang) {
 
 IPA.cert = {};
 
@@ -486,6 +486,7 @@ IPA.cert.load_policy = function(spec) {
 
     var that = IPA.facet_policy();
     that.loader = IPA.build(spec.loader);
+    that.has_reason = spec.has_reason;
 
     that.post_load = function(data) {
 
@@ -499,7 +500,8 @@ IPA.cert.load_policy = function(spec) {
         // initialize another load of certificate because current entity
         // show commands don't contain revocation_reason so previous data
         // might be slightly incorrect
-        if (certificate && certificate.certificate && !IPA.cert.is_selfsign()) {
+        if (!that.has_reason && certificate && certificate.certificate &&
+                !IPA.cert.is_selfsign()) {
             that.load_revocation_reason(certificate.serial_number);
         }
     };
@@ -672,9 +674,12 @@ IPA.cert.revoke_action = function(spec) {
         var entity_label = that.entity_label || facet.entity.metadata.label_singular;
         var entity_name = certificate.entity_info.name;
 
-        var title = IPA.messages.objects.cert.revoke_certificate;
-        title = title.replace('${entity}', entity_label);
-        title = title.replace('${primary_key}', entity_name);
+        var title = IPA.messages.objects.cert.revoke_certificate_simple;
+        if (entity_name && entity_label) {
+            title = IPA.messages.objects.cert.revoke_certificate;
+            title = title.replace('${entity}', entity_label);
+            title = title.replace('${primary_key}', entity_name);
+        }
 
         that.dialog.title = title;
         that.dialog.message = that.get_confirm_message(facet);
@@ -725,9 +730,12 @@ IPA.cert.restore_action = function(spec) {
         var entity_label = that.entity_label || facet.entity.metadata.label_singular;
         var entity_name = certificate.entity_info.name;
 
-        var title = IPA.messages.objects.cert.restore_certificate;
-        title = title.replace('${entity}', entity_label);
-        title = title.replace('${primary_key}', entity_name);
+        var title = IPA.messages.objects.cert.restore_certificate_simple;
+        if (entity_name && entity_label) {
+            title = IPA.messages.objects.cert.restore_certificate;
+            title = title.replace('${entity}', entity_label);
+            title = title.replace('${primary_key}', entity_name);
+        }
 
         that.dialog.title = title;
         that.dialog.message = that.get_confirm_message(facet);
@@ -923,5 +931,234 @@ IPA.cert.status_field = function(spec) {
 IPA.widget_factories['certificate_status'] = IPA.cert.status_widget;
 IPA.field_factories['certificate_status'] = IPA.cert.status_field;
 
+IPA.cert.entity = function(spec) {
+
+    var that = IPA.entity(spec);
+
+    that.get_default_metadata = function() {
+
+        var add_param = function(name, label, doc,  primary_key) {
+            entity.takes_params.push({
+                name: name,
+                label: label,
+                doc: doc,
+                primary_key: !!primary_key,
+                flags: ['no_update']
+            });
+        };
+
+        var get_param = function(params, name) {
+
+            for (var i=0;i<params.length;i++) {
+                if (params[i].name === name) return params[i];
+            }
+            return null;
+        };
+
+        var cmd = IPA.metadata.commands['cert_find'];
+        var entity = lang.clone(cmd);
+        entity.attribute_members = {};
+        entity.label = IPA.messages.objects.cert.certificates;
+        entity.label_singular = IPA.messages.objects.cert.certificate;
+        entity.methods = [
+            'find',
+            'remove-hold',
+            'request',
+            'revoke',
+            'show',
+            'status'
+        ];
+        entity.name = "certificate";
+        entity.object_name = "certificate";
+        entity.object_name_plural = "certificates";
+        entity.parent_object = "";
+        entity.primary_key = "serial_number";
+        entity.rdn_attribute = "";
+        entity.relationships = {};
+        entity.takes_params = lang.clone(entity.takes_options);
+
+        get_param(entity.takes_params, 'subject').flags = ['no_update'];
+        var reason = get_param(entity.takes_params, 'revocation_reason');
+        reason.flags = ['no_update'];
+        reason.label = IPA.messages.objects.cert.revocation_reason;
+
+        add_param('serial_number',
+                  IPA.messages.objects.cert.serial_number,
+                  IPA.messages.objects.cert.serial_number,
+                  true);
+        add_param('serial_number_hex',
+                  IPA.messages.objects.cert.serial_number_hex,
+                  IPA.messages.objects.cert.serial_number_hex);
+        add_param('issuer',
+                  IPA.messages.objects.cert.issued_by,
+                  IPA.messages.objects.cert.issued_by);
+        add_param('status',
+                  IPA.messages.objects.cert.status,
+                  IPA.messages.objects.cert.status);
+        add_param('valid_not_before',
+                  IPA.messages.objects.cert.issued_on,
+                  IPA.messages.objects.cert.issued_on);
+        add_param('valid_not_after',
+                  IPA.messages.objects.cert.expires_on,
+                  IPA.messages.objects.cert.expires_on);
+        add_param('md5_fingerprint',
+                  IPA.messages.objects.cert.md5_fingerprint,
+                  IPA.messages.objects.cert.md5_fingerprint);
+        add_param('sha1_fingerprint',
+                  IPA.messages.objects.cert.sha1_fingerprint,
+                  IPA.messages.objects.cert.sha1_fingerprint);
+        add_param('certificate',
+                  IPA.messages.objects.cert.certificate,
+                  IPA.messages.objects.cert.certificate);
+
+
+        IPA.metadata.objects.cert = entity;
+        return entity;
+    };
+
+    that.init = function() {
+        that.entity_init();
+
+        that.builder.search_facet({
+            factory: IPA.cert.search_facet,
+            label: IPA.messages.objects.cert.label,
+            pagination: false,
+            no_update: true,
+            columns: [
+                {
+                    name: 'serial_number',
+                    primary_key: true,
+                    width: '90px'
+                },
+                'subject',
+                {
+                    name: 'status',
+                    width: '120px'
+                }
+            ]
+        }).
+        details_facet({
+            factory: IPA.cert.details_facet,
+            no_update: true,
+            actions: [
+                IPA.cert.revoke_action,
+                IPA.cert.restore_action
+            ],
+            state: {
+                evaluators: [
+                    IPA.cert.certificate_evaluator
+                ]
+            },
+            sections: [
+                {
+                    name: 'details',
+                    label: IPA.messages.objects.cert.certificate,
+                    action_panel: {
+                        factory: IPA.action_panel,
+                        name: 'cert_actions',
+                        actions: [
+                            'revoke_cert', 'restore_cert'
+                        ]
+                    },
+                    fields: [
+                        'serial_number',
+                        'serial_number_hex',
+                        'subject',
+                        'issuer',
+                        'valid_not_before',
+                        'valid_not_after',
+                        'md5_fingerprint',
+                        'sha1_fingerprint',
+                        {
+                            type: 'revocation_reason',
+                            name: 'revocation_reason'
+                        },
+                        {
+                            type: 'textarea',
+                            name: 'certificate',
+                            style: {
+                                width: '550px',
+                                height: '350px'
+                            }
+                        }
+                    ]
+                }
+            ],
+            policies: [
+                IPA.cert.load_policy({ has_reason: true})
+            ]
+        });
+    };
+
+    return that;
+};
+
+IPA.cert.search_facet = function(spec) {
+
+    spec = spec || {};
+
+    var that = IPA.search_facet(spec);
+
+
+    that.create_refresh_command = function() {
+
+        var command = that.search_facet_create_refresh_command();
+        var arg = command.args.pop();
+
+        if (arg) {
+            command.set_option('subject', arg);
+        }
+
+        return command;
+    };
+
+    return that;
+};
+
+IPA.cert.details_facet = function(spec, no_init) {
+
+    spec = spec || {};
+
+    var that = IPA.details_facet(spec, true);
+    that.certificate_loaded = IPA.observer();
+
+    that.create_refresh_command = function() {
+
+        var command = that.details_facet_create_refresh_command();
+        delete command.options.all;
+        delete command.options.rights;
+        return command;
+    };
+
+    if (!no_init) that.init_details_facet();
+
+    return that;
+};
+
+IPA.revocation_reason_field = function(spec) {
+
+    spec = spec || {};
+
+    var that = IPA.field(spec);
+
+    that.load = function(record) {
+
+        that.field_load(record);
+
+        var reason = record.revocation_reason;
+        var text = IPA.cert.CRL_REASON[reason] || '';
+        that.values = [text];
+
+        that.reset();
+    };
+
+    return that;
+};
+
+IPA.field_factories['revocation_reason'] = IPA.revocation_reason_field;
+IPA.widget_factories['revocation_reason'] = IPA.text_widget;
+
+IPA.register('cert', IPA.cert.entity);
+
 return {};
-});
+});
\ No newline at end of file
diff --git a/install/ui/src/freeipa/details.js b/install/ui/src/freeipa/details.js
index e8f1e86d9be52af65ddc8065663059a799f1211e..bd23e564e3bed0144f587a7b23a77308874ec35d 100644
--- a/install/ui/src/freeipa/details.js
+++ b/install/ui/src/freeipa/details.js
@@ -238,21 +238,25 @@ IPA.details_facet = function(spec, no_init) {
         IPA.update_action);
 
     spec.control_buttons = spec.control_buttons || [];
+
+    if (!spec.no_update) {
+        spec.control_buttons.unshift(
+            {
+                name: 'reset',
+                label: IPA.messages.buttons.reset,
+                icon: 'reset-icon'
+            },
+            {
+                name: 'update',
+                label: IPA.messages.buttons.update,
+                icon: 'update-icon'
+            });
+    }
     spec.control_buttons.unshift(
         {
             name: 'refresh',
             label: IPA.messages.buttons.refresh,
             icon: 'reset-icon'
-        },
-        {
-            name: 'reset',
-            label: IPA.messages.buttons.reset,
-            icon: 'reset-icon'
-        },
-        {
-            name: 'update',
-            label: IPA.messages.buttons.update,
-            icon: 'update-icon'
         });
 
     spec.state = spec.state || {};
diff --git a/install/ui/src/freeipa/facet.js b/install/ui/src/freeipa/facet.js
index 77e05cab67ccdac234b8ea267fa582ab30d0b50f..3ad868e84d6678d89239bde3c6ef0e7899580c9f 100644
--- a/install/ui/src/freeipa/facet.js
+++ b/install/ui/src/freeipa/facet.js
@@ -38,6 +38,7 @@ IPA.facet = function(spec, no_init) {
     that.title = spec.title || that.label;
     that.tab_label = spec.tab_label || that.label;
     that.display_class = spec.display_class;
+    that.no_update = spec.no_update;
 
     that.disable_breadcrumb = spec.disable_breadcrumb;
     that.disable_facet_tabs = spec.disable_facet_tabs;
diff --git a/install/ui/src/freeipa/search.js b/install/ui/src/freeipa/search.js
index a3f35b5e9034761ad4980b8745ebcdb5173e35e5..d57c40126c98ae99a49c5559a3ca79b56005ec9c 100644
--- a/install/ui/src/freeipa/search.js
+++ b/install/ui/src/freeipa/search.js
@@ -42,21 +42,25 @@ IPA.search_facet = function(spec, no_init) {
         IPA.add_action);
 
     spec.control_buttons = spec.control_buttons || [];
+
+    if (!spec.no_update) {
+        spec.control_buttons.unshift(
+            {
+                name: 'remove',
+                label: IPA.messages.buttons.remove,
+                icon: 'remove-icon'
+            },
+            {
+                name: 'add',
+                label: IPA.messages.buttons.add,
+                icon: 'add-icon'
+            });
+    }
     spec.control_buttons.unshift(
         {
             name: 'refresh',
             label: IPA.messages.buttons.refresh,
             icon: 'reset-icon'
-        },
-        {
-            name: 'remove',
-            label: IPA.messages.buttons.remove,
-            icon: 'remove-icon'
-        },
-        {
-            name: 'add',
-            label: IPA.messages.buttons.add,
-            icon: 'add-icon'
         });
 
     spec.state = spec.state || {};
diff --git a/install/ui/src/freeipa/webui.js b/install/ui/src/freeipa/webui.js
index f6c3339ec4b5d3fb8a4cb547407eebf2a19b45af..2bc3bdd47a94551cac7d16d260868e7f78c7c91a 100644
--- a/install/ui/src/freeipa/webui.js
+++ b/install/ui/src/freeipa/webui.js
@@ -42,7 +42,8 @@ IPA.admin_navigation = function(spec) {
                  {entity: 'dnsconfig'},
                  {entity: 'dnsrecord', hidden:true}
              ]
-            }
+            },
+            {entity: 'cert', label: IPA.messages.tabs.cert }
         ]},
         {name: 'policy', label: IPA.messages.tabs.policy, children: [
             {name: 'hbac', label: IPA.messages.tabs.hbac, children: [
diff --git a/install/ui/src/freeipa/widget.js b/install/ui/src/freeipa/widget.js
index dc39c7ecd74fd1bce4d992b286a96cf19ba38aca..9527696fb79c2154733f430b2578324dedddc62d 100644
--- a/install/ui/src/freeipa/widget.js
+++ b/install/ui/src/freeipa/widget.js
@@ -960,6 +960,7 @@ IPA.textarea_widget = function (spec) {
 
     that.rows = spec.rows || 5;
     that.cols = spec.cols || 40;
+    that.style = spec.style;
 
     that.create = function(container) {
 
@@ -978,6 +979,8 @@ IPA.textarea_widget = function (spec) {
             }
         }).appendTo(container);
 
+        if (that.style) that.input.css(that.style);
+
         that.input.bind('input', function() {
             that.on_value_changed();
         });
diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json
index 44484a9aaa4b04c2730cacd1adcbe682e507d736..32b1e17707d2a64a938840bf580f0492730ce633 100644
--- a/install/ui/test/data/ipa_init.json
+++ b/install/ui/test/data/ipa_init.json
@@ -176,6 +176,8 @@
                             "aa_compromise": "AA Compromise",
                             "affiliation_changed": "Affiliation Changed",
                             "ca_compromise": "CA Compromise",
+                            "certificate": "Certificate",
+                            "certificates": "Certificates",
                             "certificate_hold": "Certificate Hold",
                             "cessation_of_operation": "Cessation of Operation",
                             "common_name": "Common Name",
@@ -198,14 +200,18 @@
                             "request_message": "<ol> <li>Create a certificate database or use an existing one. To create a new database:<br/> <code># certutil -N -d &lt;database path&gt;</code> </li> <li>Create a CSR with subject <em>CN=&lt;hostname&gt;,O=&lt;realm&gt;</em>, for example:<br/> <code># certutil -R -d &lt;database path&gt; -a -g &lt;key size&gt; -s 'CN=${hostname},O=${realm}'</code> </li> <li> Copy and paste the CSR (from <em>-----BEGIN NEW CERTIFICATE REQUEST-----</em> to <em>-----END NEW CERTIFICATE REQUEST-----</em>) into the text area below: </li> </ol>",
                             "requested": "Certificate requested",
                             "restore_certificate": "Restore Certificate for ${entity} ${primary_key}",
+                            "restore_certificate_simple": "Restore Certificate",
                             "restore_confirmation": "To confirm your intention to restore this certificate, click the \"Restore\" button.",
                             "restored": "Certificate restored",
+                            "revocation_reason": "Revocation reason",
                             "revoke_certificate": "Revoke Certificate for ${entity} ${primary_key}",
+                            "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.",
                             "revoked": "Certificate Revoked",
                             "serial_number": "Serial Number",
                             "serial_number_hex": "Serial Number (hex)",
                             "sha1_fingerprint": "SHA1 Fingerprint",
+                            "status": "Status",
                             "superseded": "Superseded",
                             "unspecified": "Unspecified",
                             "valid": "Valid Certificate Present",
@@ -509,6 +515,7 @@
                         "audit": "Audit",
                         "automember": "Automember",
                         "automount": "Automount",
+                        "cert": "Certificates",
                         "dns": "DNS",
                         "hbac": "Host Based Access Control",
                         "identity": "Identity",
diff --git a/ipalib/plugins/internal.py b/ipalib/plugins/internal.py
index cfb5d60f9f8a9f748b58dd8364a8690bf6724755..853cd6ee84c8a0885e568245434920f332e39d06 100644
--- a/ipalib/plugins/internal.py
+++ b/ipalib/plugins/internal.py
@@ -312,6 +312,8 @@ class i18n_messages(Command):
                 "aa_compromise": _("AA Compromise"),
                 "affiliation_changed": _("Affiliation Changed"),
                 "ca_compromise": _("CA Compromise"),
+                "certificate": _("Certificate"),
+                "certificates": _("Certificates"),
                 "certificate_hold": _("Certificate Hold"),
                 "cessation_of_operation": _("Cessation of Operation"),
                 "common_name": _("Common Name"),
@@ -334,14 +336,18 @@ class i18n_messages(Command):
                 "request_message": _("<ol> <li>Create a certificate database or use an existing one. To create a new database:<br/> <code># certutil -N -d &lt;database path&gt;</code> </li> <li>Create a CSR with subject <em>CN=&lt;hostname&gt;,O=&lt;realm&gt;</em>, for example:<br/> <code># certutil -R -d &lt;database path&gt; -a -g &lt;key size&gt; -s 'CN=${hostname},O=${realm}'</code> </li> <li> Copy and paste the CSR (from <em>-----BEGIN NEW CERTIFICATE REQUEST-----</em> to <em>-----END NEW CERTIFICATE REQUEST-----</em>) into the text area below: </li> </ol>"),
                 "requested": _("Certificate requested"),
                 "restore_certificate": _("Restore Certificate for ${entity} ${primary_key}"),
+                "restore_certificate_simple": _("Restore Certificate"),
                 "restore_confirmation": _("To confirm your intention to restore this certificate, click the \"Restore\" button."),
                 "restored": _("Certificate restored"),
+                "revocation_reason": _("Revocation reason"),
                 "revoke_certificate": _("Revoke Certificate for ${entity} ${primary_key}"),
+                "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."),
                 "revoked": _("Certificate Revoked"),
                 "serial_number": _("Serial Number"),
                 "serial_number_hex": _("Serial Number (hex)"),
                 "sha1_fingerprint": _("SHA1 Fingerprint"),
+                "status": _("Status"),
                 "superseded": _("Superseded"),
                 "unspecified": _("Unspecified"),
                 "valid": _("Valid Certificate Present"),
@@ -648,6 +654,7 @@ class i18n_messages(Command):
             "audit": _("Audit"),
             "automember": _("Automember"),
             "automount": _("Automount"),
+            "cert": _("Certificates"),
             "dns": _("DNS"),
             "hbac": _("Host Based Access Control"),
             "identity": _("Identity"),
-- 
1.7.11.7

From d77131d5796693e47da0b4b6b340626c1246d982 Mon Sep 17 00:00:00 2001
From: Petr Vobornik <pvobo...@redhat.com>
Date: Fri, 22 Feb 2013 17:12:53 +0100
Subject: [PATCH] Web UI:Choose different search option for cert-find

This extends certificate search page by search option select. Therefore
the search is not restricted to 'subject'.

It should be replaced by https://fedorahosted.org/freeipa/ticket/191 in a
future.

https://fedorahosted.org/freeipa/ticket/3419
---
 install/ui/ipa.css                    |   9 +++
 install/ui/src/freeipa/certificate.js | 103 +++++++++++++++++++++++++++++++++-
 install/ui/src/freeipa/search.js      |   8 ++-
 install/ui/test/data/ipa_init.json    |  12 ++++
 ipalib/plugins/internal.py            |  12 ++++
 5 files changed, 140 insertions(+), 4 deletions(-)

diff --git a/install/ui/ipa.css b/install/ui/ipa.css
index 4e51c3051e75846f386910c8998f73db7afbddaa..71cad4206fd0780d6578846827922ec4edb56458 100644
--- a/install/ui/ipa.css
+++ b/install/ui/ipa.css
@@ -727,6 +727,15 @@ div[name=settings].facet-group li a {
     color: gray;
 }
 
+.search-option {
+    border: 1px solid #9f9e9e;
+    background: url(images/search-background.png);
+    border-radius: 15px !important;
+    height: 22px;
+    line-height: 22px;
+    padding: 0 8px 0;
+}
+
 .search-filter {
     width: 215px;
     -moz-border-radius: 15px !important;
diff --git a/install/ui/src/freeipa/certificate.js b/install/ui/src/freeipa/certificate.js
index 1b6a129c3afeebd65182f8addf2884be66abffa5..fc9f22c9cd5e2b0006680857eaf4887280ff1bcf 100755
--- a/install/ui/src/freeipa/certificate.js
+++ b/install/ui/src/freeipa/certificate.js
@@ -1035,6 +1035,56 @@ IPA.cert.entity = function(spec) {
                     name: 'status',
                     width: '120px'
                 }
+            ],
+            search_options:  [
+                {
+                    value: 'subject',
+                    label: IPA.messages.objects.cert.find_subject
+                },
+                {
+                    value: 'revocation_reason',
+                    label: IPA.messages.objects.cert.find_revocation_reason
+                },
+                {
+                    value: 'min_serial_number',
+                    label: IPA.messages.objects.cert.find_min_serial_number
+                },
+                {
+                    value: 'max_serial_number',
+                    label: IPA.messages.objects.cert.find_max_serial_number
+                },
+                {
+                    value: 'validnotafter_from',
+                    label: IPA.messages.objects.cert.find_validnotafter_from
+                },
+                {
+                    value: 'validnotafter_to',
+                    label: IPA.messages.objects.cert.find_validnotafter_to
+                },
+                {
+                    value: 'validnotbefore_from',
+                    label: IPA.messages.objects.cert.find_validnotbefore_from
+                },
+                {
+                    value: 'validnotbefore_to',
+                    label: IPA.messages.objects.cert.find_validnotbefore_to
+                },
+                {
+                    value: 'issuedon_from',
+                    label: IPA.messages.objects.cert.find_issuedon_from
+                },
+                {
+                    value: 'issuedon_to',
+                    label: IPA.messages.objects.cert.find_issuedon_to
+                },
+                {
+                    value: 'revokedon_from',
+                    label: IPA.messages.objects.cert.find_revokedon_from
+                },
+                {
+                    value: 'revokedon_to',
+                    label: IPA.messages.objects.cert.find_revokedon_to
+                }
             ]
         }).
         details_facet({
@@ -1099,19 +1149,70 @@ IPA.cert.search_facet = function(spec) {
 
     var that = IPA.search_facet(spec);
 
+    that.search_options = spec.search_options || [];
+
+    that.create_header = function(container) {
+        that.search_facet_create_header(container);
+
+        that.search_option = $('<select/>', {
+            name: 'search_option',
+            'class': 'search-option'
+        });
+
+        that.filter_container.before(that.search_option);
+
+        for (var i=0; i<that.search_options.length; i++) {
+            var option = that.search_options[i];
+
+            var metadata = IPA.get_command_option('cert_find', option.value);
+            var doc = metadata.doc || '';
+
+            $('<option/>', {
+                text: option.label,
+                value: option.value,
+                title: doc
+            }).appendTo(that.search_option);
+        }
+    };
 
     that.create_refresh_command = function() {
 
         var command = that.search_facet_create_refresh_command();
         var arg = command.args.pop();
 
+        var option = that.search_option.val();
+
         if (arg) {
-            command.set_option('subject', arg);
+            command.set_option(option, arg);
         }
 
         return command;
     };
 
+    // parent method only sets expired flag when filter change, it doesn't
+    // expect that option can change -> set expire flag for every search
+    that.find = function() {
+        var filter = that.filter.val();
+        var search_opt = that.search_option.val();
+        var old_filter = IPA.nav.get_state(that.managed_entity.name+'-filter');
+        var state = {};
+        state[that.managed_entity.name + '-filter'] = filter;
+        state[that.managed_entity.name + '-search-option'] = search_opt;
+
+        that.set_expired_flag();
+
+        IPA.nav.push_state(state);
+    };
+
+    that.show = function() {
+        that.search_facet_show();
+
+        if (that.search_option) {
+            var search_opt = IPA.nav.get_state(that.entity.name+'-search-option');
+            that.search_option.val(search_opt);
+        }
+    };
+
     return that;
 };
 
diff --git a/install/ui/src/freeipa/search.js b/install/ui/src/freeipa/search.js
index d57c40126c98ae99a49c5559a3ca79b56005ec9c..be37f88b7f863721bb06d8070bee0f8a87869ac4 100644
--- a/install/ui/src/freeipa/search.js
+++ b/install/ui/src/freeipa/search.js
@@ -83,14 +83,14 @@ IPA.search_facet = function(spec, no_init) {
 
         div.append(IPA.create_network_spinner());
 
-        var filter_container = $('<div/>', {
+        that.filter_container = $('<div/>', {
             'class': 'search-filter'
         }).appendTo(div);
 
         that.filter = $('<input/>', {
             type: 'text',
             name: 'filter'
-        }).appendTo(filter_container);
+        }).appendTo(that.filter_container);
 
         that.filter.keypress(function(e) {
             /* if the key pressed is the enter key */
@@ -106,7 +106,7 @@ IPA.search_facet = function(spec, no_init) {
                 that.find();
                 return false;
             }
-        }).appendTo(filter_container);
+        }).appendTo(that.filter_container);
 
         that.create_control_buttons(that.controls);
     };
@@ -258,6 +258,8 @@ IPA.search_facet = function(spec, no_init) {
     // methods that should be invoked by subclasses
     that.search_facet_refresh = that.refresh;
     that.search_facet_create_refresh_command = that.create_refresh_command;
+    that.search_facet_create_header = that.create_header;
+    that.search_facet_show = that.show;
 
     return that;
 };
diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json
index 32b1e17707d2a64a938840bf580f0492730ce633..5dc6afb56a8259255c442af329fecd3cf85cf1f2 100644
--- a/install/ui/test/data/ipa_init.json
+++ b/install/ui/test/data/ipa_init.json
@@ -183,6 +183,18 @@
                             "common_name": "Common Name",
                             "expires_on": "Expires On",
                             "fingerprints": "Fingerprints",
+                            "find_issuedon_from": "Issued on from",
+                            "find_issuedon_to": "Issued on to",
+                            "find_max_serial_number": "Maximum serial number",
+                            "find_min_serial_number": "Minimum serial number",
+                            "find_revocation_reason": "Revocation reason",
+                            "find_revokedon_from": "Revoked on from",
+                            "find_revokedon_to": "Revoked on to",
+                            "find_subject": "Subject",
+                            "find_validnotafter_from": "Valid not after from",
+                            "find_validnotafter_to": "Valid not after to",
+                            "find_validnotbefore_from": "Valid not before from",
+                            "find_validnotbefore_to": "Valid not before to",
                             "issue_certificate": "Issue New Certificate for ${entity} ${primary_key}",
                             "issued_by": "Issued By",
                             "issued_on": "Issued On",
diff --git a/ipalib/plugins/internal.py b/ipalib/plugins/internal.py
index 853cd6ee84c8a0885e568245434920f332e39d06..dd81f6f94bfb53f28f741cf6e69afdf9fd1572c7 100644
--- a/ipalib/plugins/internal.py
+++ b/ipalib/plugins/internal.py
@@ -318,6 +318,18 @@ class i18n_messages(Command):
                 "cessation_of_operation": _("Cessation of Operation"),
                 "common_name": _("Common Name"),
                 "expires_on": _("Expires On"),
+                "find_issuedon_from": _("Issued on from"),
+                "find_issuedon_to": _("Issued on to"),
+                "find_max_serial_number": _("Maximum serial number"),
+                "find_min_serial_number": _("Minimum serial number"),
+                "find_revocation_reason": _("Revocation reason"),
+                "find_revokedon_from": _("Revoked on from"),
+                "find_revokedon_to": _("Revoked on to"),
+                "find_subject": _("Subject"),
+                "find_validnotafter_from": _("Valid not after from"),
+                "find_validnotafter_to": _("Valid not after to"),
+                "find_validnotbefore_from": _("Valid not before from"),
+                "find_validnotbefore_to": _("Valid not before to"),
                 "fingerprints": _("Fingerprints"),
                 "issue_certificate": _("Issue New Certificate for ${entity} ${primary_key}"),
                 "issued_by": _("Issued By"),
-- 
1.7.11.7

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to