From 081f7960edca025f6da08833ba208d356c55651a Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Thu, 25 Mar 2021 20:14:49 -0400
Subject: [PATCH] Add ability to search on certificate revocation status

This can be used to narrow the candidate list of
certificates when deleting objects like hosts and
service.

Related: https://pagure.io/freeipa/issue/7835

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
---
 API.txt                     |  3 ++-
 VERSION.m4                  |  4 ++--
 ipaserver/plugins/cert.py   | 13 +++++++++++--
 ipaserver/plugins/dogtag.py |  4 ++++
 4 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/API.txt b/API.txt
index 2193f3a84d6..212ef807c77 100644
--- a/API.txt
+++ b/API.txt
@@ -754,7 +754,7 @@ output: Entry('result')
 output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
 output: PrimaryKey('value')
 command: cert_find/1
-args: 1,29,4
+args: 1,30,4
 arg: Str('criteria?')
 option: Flag('all', autofill=True, cli_name='all', default=False)
 option: Str('cacn?', cli_name='ca')
@@ -777,6 +777,7 @@ option: DateTime('revokedon_from?', autofill=False)
 option: DateTime('revokedon_to?', autofill=False)
 option: Principal('service*', cli_name='services')
 option: Int('sizelimit?')
+option: StrEnum('status?', values=[u'VALID', u'INVALID', u'REVOKED', u'EXPIRED', u'REVOKED_EXPIRED'])
 option: Str('subject?', autofill=False)
 option: Int('timelimit?')
 option: Str('user*', cli_name='users')
diff --git a/VERSION.m4 b/VERSION.m4
index f4412c5b995..059446726a1 100644
--- a/VERSION.m4
+++ b/VERSION.m4
@@ -86,8 +86,8 @@ define(IPA_DATA_VERSION, 20100614120000)
 #                                                      #
 ########################################################
 define(IPA_API_VERSION_MAJOR, 2)
-define(IPA_API_VERSION_MINOR, 241)
-# Last change: add auto-private-groups option to idrange
+define(IPA_API_VERSION_MINOR, 242)
+# Last change: add status options for cert-find
 
 
 ########################################################
diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
index 9ba4834a20d..93ed9fa3307 100644
--- a/ipaserver/plugins/cert.py
+++ b/ipaserver/plugins/cert.py
@@ -31,7 +31,7 @@
 from dns import resolver, reversename
 import six
 
-from ipalib import Command, Str, Int, Flag
+from ipalib import Command, Str, Int, Flag, StrEnum
 from ipalib import api
 from ipalib import errors, messages
 from ipalib import x509
@@ -1559,6 +1559,12 @@ class cert_find(Search, CertMethod):
             normalizer=normalize_pkidate,
             autofill=False,
         ),
+        StrEnum(
+            'status?',
+            doc=_("Status of the certificate"),
+            values=(u'VALID', u'INVALID', u'REVOKED', u'EXPIRED',
+                    u'REVOKED_EXPIRED'),
+        ),
         Flag('pkey_only?',
             label=_("Primary key only"),
             doc=_("Results should contain primary key attribute only "
@@ -1644,7 +1650,8 @@ def _ca_search(self, raw, pkey_only, exactly, **options):
                      'validnotafter_from', 'validnotafter_to',
                      'validnotbefore_from', 'validnotbefore_to',
                      'issuedon_from', 'issuedon_to',
-                     'revokedon_from', 'revokedon_to'):
+                     'revokedon_from', 'revokedon_to',
+                     'status'):
             try:
                 value = options[name]
             except KeyError:
@@ -1680,6 +1687,8 @@ def _ca_search(self, raw, pkey_only, exactly, **options):
                 ra_options['subject'] = hosts[0]
             elif len(users) == 1 and not services and not hosts:
                 ra_options['subject'] = users[0]
+        if 'status' in options:
+            ra_options['status'] = options.get('status')
 
         try:
             ca_enabled_check(self.api)
diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py
index 974a48f0a10..f2dc6e4ab09 100644
--- a/ipaserver/plugins/dogtag.py
+++ b/ipaserver/plugins/dogtag.py
@@ -1785,6 +1785,10 @@ def convert_time(value):
             node = etree.SubElement(page, 'serialTo')
             node.text = unicode(options['max_serial_number'])
 
+        if 'status' in options:
+            node = etree.SubElement(page, 'status')
+            node.text = unicode(options['status'])
+
         # date_types is a tuple that consists of:
         #   1. attribute name passed from IPA API
         #   2. attribute name used by REST API
