On 08/01/2016 11:57 PM, Fraser Tweedale wrote:
On Fri, Jul 29, 2016 at 11:13:16AM -0400, Ben Lipton wrote:
On 07/29/2016 09:39 AM, Petr Spacek wrote:
On 27.7.2016 19:06, Ben Lipton wrote:
Hi all,

I think the automatic CSR generation feature
(https://fedorahosted.org/freeipa/ticket/4899,
http://www.freeipa.org/page/V4/Automatic_Certificate_Request_Generation) is
stable enough to review now. The following are summaries of the attached 
patches:
0004: LDAP schema changes for the new feature
0005: Basic API for new objects and CSR generation
0006: Update install automation to create some default mapping rules
0007: Implement the lookups and text processing that generates the CSR config
0008 and 0009: Implement some actual transformation rules so that the feature
is usable
0010: Add a new cert profile for user certs, with mappings
0011: Implement import/export of cert profiles with mappings
0012: Tests for profile import/export

Generally speaking, later patches depend on earlier ones, but I don't
anticipate any problems from committing earlier patches without later ones.

If you prefer, you can also comment on the pull request version:
https://github.com/LiptonB/freeipa/pull/4. Note that I may force push on this
branch.

Allocation of OIDs for schema change also needs review:
https://code.engineering.redhat.com/gerrit/#/c/80061/

Known issues:
- When the requested principal does not have some of the requested data,
produces funny-looking configs with extra commas, empty sections, etc. They
are still accepted by my copies of openssl and certutil, but they look ugly.
- The new objects don't have any ACIs, so for the moment only admin can run
the new commands.
- Does not yet have support for prompting user for field values, so currently
all data must come from the database.
- All processing happens on the server side. As discussed in a previous
thread, it would be desirable to break this out into a library so it could be
used client-side.

Very excited to hear your thoughts!
Hi Ben,

I wanted to give it a try from user's point of view first, before diving into
implementation details. Here are some observations:
Thanks for giving it a try! This is great feedback.
0. Design pages are using term "helper" and it is used even as option in the
example with smartcards. Please fix either design page or the code so they are
consistent.
Good point. In a previous discussion, Alexander remarked that --helper
sounded too low-level, but I find that --use sounds very generic and
--format doesn't make a lot of sense for ipa cert-request, which never
actually gives you the config that's generated. So if they're all going to
be the same word, which is probably a good idea, I might be leaning towards
--helper, but I'm interested to hear opinions on this.
1. The "ipa cert-request" command is missing options --autofill and --use (aka
helper aka format :-) which are mentioned in the design pages.
Yeah, I haven't managed to implement much of the UI niceness suggested by
the design page. I probably should have mentioned that in the email - all
that I expect to be working at this point is 'ipa cert-get-requestdata' and
CRUD for the mapping rules/profiles themselves.
2. "ipa cert_get_requestdata" command passes even without --profile-id and
generates empty config. I think that this is not expected :-)
More expected than you might think :) I'm guessing what's happening is that
you're passing a user principal and it's defaulting to the caIPAserviceCert
profile, then failing to fill out any of the fields because the data it
needs is not there. I agree this isn't great. I was planning to address this
by having it throw an error if it can't generate at least the subject of the
request, and maybe suggest using a different profile.

I chose to have it default to caIPAserviceCert because that's what ipa
cert-request does, but maybe that's not as predictable as I thought.

In general use I think that 'caIPAserviceCert' is unlikely to be
used a majory of the time, and it is a new command so there are no
compatibility issues; therefore why not make the profile option
mandatory?
Fair enough. Ok, a modified patch that changes this (and fixes some label errors I noticed) is attached.

3. "ipa cert_get_requestdata --format=openssl" prints the text to stdout
including label "Configuration file contents:". This is hard to use because
simple redirection like "ipa cert_get_requestdata --format=openssl > config"
will not give you valid OpenSSL config file - it needs hand-editing.

It would be good to add --out parameter you envisioned in the design page.
Please ask jcholast for proper name and semantics :-) With --out option the
command can be used to generate valid config (or script if certutil was 
selected).
Agreed. Another example of the UI not being quite right yet. I've been
unsure how to handle this, because of certutil taking a command line and
openssl a config file. It actually gets even more complicated because, as
you point out in the next item, openssl also needs a command in addition to
the config file. I'm interested in thinking about how to handle this cleanly
from a user perspective. Generating a script, or providing the command lines
as hints, might be ways to get around these concerns.
4. "ipa cert_get_requestdata --format=openssl" could print hint what OpenSSL
command should be executed on the generated config file. For testing I've used
command "openssl req -new -out csr -text -config config" (stolen and modified
from smart card example). Also, as a second hint, it could print the IPA
command which needs to be used to sign the CSR generated by the helper.
Also agreed, the framework should be able to generate and (for purposes of
'ipa cert-request --autofill') even execute the command required to make the
CSR.

5. My naive attempt to get userCert for admin failed:
$ ipa cert_get_requestdata --format=openssl --principal=admin
--profile-id=userCert > usercert.conf
# remove the trailing label
$ openssl req -new -out csr -text -config usercert.conf
$ ipa cert-request --principal=admin --profile-id=userCert usercert.csr
ipa: ERROR: invalid 'csr': No Common Name was found in subject of request.

I'm attaching files generated by the commands above. I did not modify anything
in the templates or profiles, just tried to use the new profile added by
freeipa-blipton-0010-Add-a-new-cert-profile-for-users.patch .
Hah! This is what I get for thinking I know what the output has to look
like, and not testing all the way through to requesting the cert. I'll
change the profile to generate a subject with CN= instead of UID=. Updated
patch is attached. Unfortunately these rules are only updated at
ipa-server-install time, so if you'd like to fix it without reinstalling:

(Tangential commentary...) Yeah, currently cert-request demands the
CN.  There is a design to relax the requirement to handle empty
subject names (look at SAN only).  IMO it would make sense to accept
other "obvious" mappings in Subject DN like accepting UID instead of
CN for user subjects, but that would be a separate RFE.  Noone has
actually asked for it yet :)

Cheers,
Fraser

ipa certtransformationrule-mod dataUsernameCN dataUsernameCertutil
--template 
'CN={{ipa.datafield(subject.uid.0)|quote}},{{ipa.datafield(config.ipacertificatesubjectbase.0)|quote}}'
ipa certtransformationrule-mod dataUsernameCN dataUsernameOpenssl --template
'{{ipa.datafield(config.ipacertificatesubjectbase.0)}}
CN={{ipa.datafield(subject.uid.0)}}'
Yes, that must be an actual linebreak between the subjectbase and the CN in
the openssl one. I know :-/

Hopefully I will get to other things soon (but not this week).


Anyway, all this seems like (expected) initial problems. In general the first
touch with user interface seems reasonable and needs only small improvements.

Good work!


From b635e9af7c566e7627c3443376c4d58f4673fca1 Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Tue, 5 Jul 2016 14:19:49 -0400
Subject: [PATCH] Add plugin for CSR generation

This plugin will implement the cert-get-requestdata call that returns a
config that can be used to generate a CSR. This commit implements only
the very basic API of the plugin. Actual functionality will come in
later patches.

https://fedorahosted.org/freeipa/ticket/4899
---
 API.txt                          | 202 ++++++++++++++++++++++++++++++
 VERSION                          |   4 +-
 ipaclient/plugins/certmapping.py |  27 ++++
 ipaserver/plugins/certmapping.py | 261 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 492 insertions(+), 2 deletions(-)
 create mode 100644 ipaclient/plugins/certmapping.py
 create mode 100644 ipaserver/plugins/certmapping.py

diff --git a/API.txt b/API.txt
index 535d8ec9a4990395207e2455a09a8c1bdef5529a..7f31bbb7d95a720e6ee76df7bc5f528d8a68bcab 100644
--- a/API.txt
+++ b/API.txt
@@ -759,6 +759,13 @@ output: Output('count', type=[<type 'int'>])
 output: ListOfEntries('result')
 output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
 output: Output('truncated', type=[<type 'bool'>])
+command: cert_get_requestdata/1
+args: 0,4,1
+option: Str('format')
+option: Principal('principal')
+option: Str('profile_id')
+option: Str('version?')
+output: Output('result', type=[<type 'dict'>])
 command: cert_remove_hold/1
 args: 1,2,1
 arg: Int('serial_number')
@@ -808,6 +815,116 @@ option: Str('version?')
 output: Entry('result')
 output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
 output: PrimaryKey('value')
+command: certfieldmappingrule_add/1
+args: 2,7,3
+arg: Str('certprofilecn', cli_name='certprofile')
+arg: Str('cn', cli_name='id')
+option: Str('addattr*', cli_name='addattr')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: DNParam('ipacertdatamapping+', cli_name='datarule')
+option: DNParam('ipacertsyntaxmapping', cli_name='syntaxrule')
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Str('setattr*', cli_name='setattr')
+option: Str('version?')
+output: Entry('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: PrimaryKey('value')
+command: certfieldmappingrule_del/1
+args: 2,2,3
+arg: Str('certprofilecn', cli_name='certprofile')
+arg: Str('cn+', cli_name='id')
+option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?')
+output: Output('result', type=[<type 'dict'>])
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: ListOfPrimaryKeys('value')
+command: certfieldmappingrule_find/1
+args: 2,9,4
+arg: Str('certprofilecn', cli_name='certprofile')
+arg: Str('criteria?')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Str('cn?', autofill=False, cli_name='id')
+option: DNParam('ipacertdatamapping*', autofill=False, cli_name='datarule')
+option: DNParam('ipacertsyntaxmapping?', autofill=False, cli_name='syntaxrule')
+option: Flag('pkey_only?', autofill=True, default=False)
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Int('sizelimit?', autofill=False)
+option: Int('timelimit?', autofill=False)
+option: Str('version?')
+output: Output('count', type=[<type 'int'>])
+output: ListOfEntries('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: Output('truncated', type=[<type 'bool'>])
+command: certfieldmappingrule_show/1
+args: 2,4,3
+arg: Str('certprofilecn', cli_name='certprofile')
+arg: Str('cn', cli_name='id')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Flag('rights', autofill=True, default=False)
+option: Str('version?')
+output: Entry('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: PrimaryKey('value')
+command: certmappingrule_add/1
+args: 1,6,3
+arg: Str('cn', cli_name='id')
+option: Str('addattr*', cli_name='addattr')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Str('description', cli_name='description')
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Str('setattr*', cli_name='setattr')
+option: Str('version?')
+output: Entry('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: PrimaryKey('value')
+command: certmappingrule_del/1
+args: 1,2,3
+arg: Str('cn+', cli_name='id')
+option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?')
+output: Output('result', type=[<type 'dict'>])
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: ListOfPrimaryKeys('value')
+command: certmappingrule_find/1
+args: 1,8,4
+arg: Str('criteria?')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Str('cn?', autofill=False, cli_name='id')
+option: Str('description?', autofill=False, cli_name='description')
+option: Flag('pkey_only?', autofill=True, default=False)
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Int('sizelimit?', autofill=False)
+option: Int('timelimit?', autofill=False)
+option: Str('version?')
+output: Output('count', type=[<type 'int'>])
+output: ListOfEntries('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: Output('truncated', type=[<type 'bool'>])
+command: certmappingrule_mod/1
+args: 1,8,3
+arg: Str('cn', cli_name='id')
+option: Str('addattr*', cli_name='addattr')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Str('delattr*', cli_name='delattr')
+option: Str('description?', autofill=False, cli_name='description')
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Flag('rights', autofill=True, default=False)
+option: Str('setattr*', cli_name='setattr')
+option: Str('version?')
+output: Entry('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: PrimaryKey('value')
+command: certmappingrule_show/1
+args: 1,4,3
+arg: Str('cn', cli_name='id')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Flag('rights', autofill=True, default=False)
+option: Str('version?')
+output: Entry('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: PrimaryKey('value')
 command: certprofile_del/1
 args: 1,2,3
 arg: Str('cn+', cli_name='id')
@@ -871,6 +988,73 @@ option: Str('version?')
 output: Entry('result')
 output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
 output: PrimaryKey('value')
+command: certtransformationrule_add/1
+args: 2,7,3
+arg: Str('certmappingrulecn', cli_name='certmappingrule')
+arg: Str('cn', cli_name='id')
+option: Str('addattr*', cli_name='addattr')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Str('ipacerttransformationhelper+', cli_name='helper')
+option: Str('ipacerttransformationtemplate', cli_name='template')
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Str('setattr*', cli_name='setattr')
+option: Str('version?')
+output: Entry('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: PrimaryKey('value')
+command: certtransformationrule_del/1
+args: 2,2,3
+arg: Str('certmappingrulecn', cli_name='certmappingrule')
+arg: Str('cn+', cli_name='id')
+option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?')
+output: Output('result', type=[<type 'dict'>])
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: ListOfPrimaryKeys('value')
+command: certtransformationrule_find/1
+args: 2,9,4
+arg: Str('certmappingrulecn', cli_name='certmappingrule')
+arg: Str('criteria?')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Str('cn?', autofill=False, cli_name='id')
+option: Str('ipacerttransformationhelper*', autofill=False, cli_name='helper')
+option: Str('ipacerttransformationtemplate?', autofill=False, cli_name='template')
+option: Flag('pkey_only?', autofill=True, default=False)
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Int('sizelimit?', autofill=False)
+option: Int('timelimit?', autofill=False)
+option: Str('version?')
+output: Output('count', type=[<type 'int'>])
+output: ListOfEntries('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: Output('truncated', type=[<type 'bool'>])
+command: certtransformationrule_mod/1
+args: 2,9,3
+arg: Str('certmappingrulecn', cli_name='certmappingrule')
+arg: Str('cn', cli_name='id')
+option: Str('addattr*', cli_name='addattr')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Str('delattr*', cli_name='delattr')
+option: Str('ipacerttransformationhelper*', autofill=False, cli_name='helper')
+option: Str('ipacerttransformationtemplate?', autofill=False, cli_name='template')
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Flag('rights', autofill=True, default=False)
+option: Str('setattr*', cli_name='setattr')
+option: Str('version?')
+output: Entry('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: PrimaryKey('value')
+command: certtransformationrule_show/1
+args: 2,4,3
+arg: Str('certmappingrulecn', cli_name='certmappingrule')
+arg: Str('cn', cli_name='id')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Flag('rights', autofill=True, default=False)
+option: Str('version?')
+output: Entry('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: PrimaryKey('value')
 command: class_find/1
 args: 1,4,4
 arg: Str('criteria?')
@@ -6269,11 +6453,23 @@ default: caacl_remove_user/1
 default: caacl_show/1
 default: cert/1
 default: cert_find/1
+default: cert_get_requestdata/1
 default: cert_remove_hold/1
 default: cert_request/1
 default: cert_revoke/1
 default: cert_show/1
 default: cert_status/1
+default: certfieldmappingrule/1
+default: certfieldmappingrule_add/1
+default: certfieldmappingrule_del/1
+default: certfieldmappingrule_find/1
+default: certfieldmappingrule_show/1
+default: certmappingrule/1
+default: certmappingrule_add/1
+default: certmappingrule_del/1
+default: certmappingrule_find/1
+default: certmappingrule_mod/1
+default: certmappingrule_show/1
 default: certprofile/1
 default: certprofile_del/1
 default: certprofile_find/1
@@ -6281,6 +6477,12 @@ default: certprofile_import/1
 default: certprofile_mod/1
 default: certprofile_show/1
 default: certreq/1
+default: certtransformationrule/1
+default: certtransformationrule_add/1
+default: certtransformationrule_del/1
+default: certtransformationrule_find/1
+default: certtransformationrule_mod/1
+default: certtransformationrule_show/1
 default: class/1
 default: class_find/1
 default: class_show/1
diff --git a/VERSION b/VERSION
index ca489965050f32d2d8987dfd251ec2b2a0ba1768..17a8aeb2253bdf603a1f38bb1133cb3187f3d97b 100644
--- a/VERSION
+++ b/VERSION
@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
 #                                                      #
 ########################################################
 IPA_API_VERSION_MAJOR=2
-IPA_API_VERSION_MINOR=211
-# Last change: mbabinsk: allow 'value' output param in commands without primary key
+IPA_API_VERSION_MINOR=212
+# Last change: blipton - Add plugin for CSR generation
diff --git a/ipaclient/plugins/certmapping.py b/ipaclient/plugins/certmapping.py
new file mode 100644
index 0000000000000000000000000000000000000000..818bd940bbb979b21d7e804c23867bf8c5d16438
--- /dev/null
+++ b/ipaclient/plugins/certmapping.py
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2016  FreeIPA Contributors see COPYING for license
+#
+
+from ipaclient.frontend import CommandOverride, Str
+from ipalib.plugable import Registry
+from ipalib.text import _
+
+register = Registry()
+
+import six
+
+if six.PY3:
+    unicode = str
+
+__doc__ = _("""
+Temporary command override to display debug data generated by
+the server-side plugin
+""")
+
+@register(override=True, no_fail=True)
+class cert_get_requestdata(CommandOverride):
+    has_output_params = (
+        Str('debug_output',
+            label=_('Debug output'),
+        ),
+    )
diff --git a/ipaserver/plugins/certmapping.py b/ipaserver/plugins/certmapping.py
new file mode 100644
index 0000000000000000000000000000000000000000..2b4e22ae5d8404126863d31efffd9c62572e7beb
--- /dev/null
+++ b/ipaserver/plugins/certmapping.py
@@ -0,0 +1,261 @@
+
+from ipalib import api
+from ipalib import DNParam, Str, Command
+from ipalib import output
+from ipalib.parameters import Principal
+from ipalib.plugable import Registry
+from ipalib.text import _
+from .baseldap import (
+    LDAPCreate, LDAPObject, LDAPRetrieve, LDAPSearch, LDAPUpdate, LDAPDelete)
+from .certprofile import validate_profile_id
+
+
+__doc__ = _("""
+Mappings from FreeIPA data to Certificate Signing Requests.
+""")
+
+
+register = Registry()
+
+
+@register()
+class certfieldmappingrule(LDAPObject):
+    """
+    Certificate Field Mapping Rule object. Specifies how a particular cert
+    field should be constructed within this profile.
+    """
+    parent_object = 'certprofile'
+
+    object_name = _('Certificate Field Mapping Rule')
+    object_name_plural = _('Certificate Field Mapping Rules')
+    object_class = ['ipacertfieldmappingrule']
+    default_attributes = [
+        'cn', 'ipacertsyntaxmapping', 'ipacertdatamapping'
+    ]
+    search_attributes = [
+        'cn', 'ipacertsyntaxmapping', 'ipacertdatamapping'
+    ]
+    label = _('Certificate Field Mapping Rules')
+    label_singular = _('Certificate Field Mapping Rule')
+
+    takes_params = (
+        Str('cn',
+            primary_key=True,
+            cli_name='id',
+            label=_('Field Mapping Rule ID'),
+            doc=_('ID for referring to this field mapping rule'),
+        ),
+        DNParam('ipacertsyntaxmapping',
+            required=True,
+            cli_name='syntaxrule',
+            label=_('Mapping ruleset for field syntax'),
+            doc=_('Mapping ruleset for formatting entire field'),
+        ),
+        DNParam('ipacertdatamapping',
+            required=True,
+            multivalue=True,
+            cli_name='datarule',
+            label=_('Mapping ruleset for data items'),
+            doc=_('Mapping ruleset for formatting individual items of data'),
+        ),
+    )
+
+
+@register()
+class certfieldmappingrule_add(LDAPCreate):
+    NO_CLI = True
+
+    __doc__ = _("""Create a new Cert Field Mapping Rule""")
+
+
+@register()
+class certfieldmappingrule_find(LDAPSearch):
+    NO_CLI = True
+
+    __doc__ = _("""Search for Cert Field Mapping Rules""")
+
+
+@register()
+class certfieldmappingrule_show(LDAPRetrieve):
+    NO_CLI = True
+
+    __doc__ = _("""Retrieve a Cert Field Mapping Rule""")
+
+
+@register()
+class certfieldmappingrule_del(LDAPDelete):
+    NO_CLI = True
+
+    __doc__ = _("""Delete a Cert Field Mapping Rule""")
+
+
+@register()
+class certmappingrule(LDAPObject):
+    """
+    Certificate Mapping Rule object. Specifies how a particular cert
+    field should be constructed within this profile.
+    """
+    container_dn = api.env.container_certmappingruleset
+    object_name = _('Certificate Mapping Rule')
+    object_name_plural = _('Certificate Mapping Rules')
+    object_class = ['ipacertmappingruleset']
+    default_attributes = [
+        'cn', 'description'
+    ]
+    search_attributes = [
+        'cn', 'description'
+    ]
+    label = _('Certificate Mapping Rules')
+    label_singular = _('Certificate Mapping Rule')
+
+    takes_params = (
+        Str('cn',
+            primary_key=True,
+            cli_name='id',
+            label=_('Certificate Mapping Rule ID'),
+            doc=_('ID for referring to this mapping rule'),
+        ),
+        Str('description',
+            required=True,
+            cli_name='description',
+            label=_('Description of this mapping rule'),
+            doc=_('Description of this mapping rule'),
+        ),
+    )
+
+
+@register()
+class certmappingrule_add(LDAPCreate):
+    __doc__ = _("""Create a new Certificate Mapping Rule""")
+
+
+@register()
+class certmappingrule_mod(LDAPUpdate):
+    __doc__ = _("""Update a Certificate Mapping Rule""")
+
+
+@register()
+class certmappingrule_find(LDAPSearch):
+    __doc__ = _("""Search for Certificate Mapping Rules""")
+
+
+@register()
+class certmappingrule_show(LDAPRetrieve):
+    __doc__ = _("""Retrieve a Certificate Mapping Rule""")
+
+
+@register()
+class certmappingrule_del(LDAPDelete):
+    __doc__ = _("""Delete a Certificate Mapping Rule""")
+
+
+@register()
+class certtransformationrule(LDAPObject):
+    """
+    Certificate Transformation rule object. Specifies a particular data
+    transformation (comparable to a format string) that is used in converting
+    stored data to certificate requests.
+    """
+    parent_object = 'certmappingrule'
+
+    object_name = _('Certificate Transformation Rule')
+    object_name_plural = _('Certificate Transformation Rules')
+    object_class = ['ipacerttransformationrule']
+    default_attributes = [
+        'cn', 'ipacerttransformationtemplate', 'ipacerttransformationhelper'
+    ]
+    search_attributes = [
+        'cn', 'ipacerttransformationtemplate', 'ipacerttransformationhelper'
+    ]
+    label = _('Certificate Transformation Rules')
+    label_singular = _('Certificate Transformation Rule')
+
+    takes_params = (
+        Str('cn',
+            primary_key=True,
+            cli_name='id',
+            label=_('Certificate Transformation Rule ID'),
+            doc=_('ID for referring to this transformation rule'),
+        ),
+        Str('ipacerttransformationtemplate',
+            required=True,
+            cli_name='template',
+            label=_('String defining the transformation'),
+            doc=_('String that specifies how the input data should be'
+                  ' formatted and combined'),
+        ),
+        Str('ipacerttransformationhelper',
+            required=True,
+            multivalue=True,
+            cli_name='helper',
+            label=_('Name of CSR generation helper'),
+            doc=_('Name of the CSR generation helper to which the syntax of'
+                  ' this rule is targeted'),
+        ),
+    )
+
+
+@register()
+class certtransformationrule_add(LDAPCreate):
+    __doc__ = _("""Create a new Certificate Transformation Rule""")
+
+
+@register()
+class certtransformationrule_mod(LDAPUpdate):
+    __doc__ = _("""Update a Certificate Transformation Rule""")
+
+
+@register()
+class certtransformationrule_find(LDAPSearch):
+    __doc__ = _("""Search for Certificate Transformation Rules""")
+
+
+@register()
+class certtransformationrule_show(LDAPRetrieve):
+    __doc__ = _("""Retrieve a Certificate Transformation Rule""")
+
+
+@register()
+class certtransformationrule_del(LDAPDelete):
+    __doc__ = _("""Delete a Certificate Transformation Rule""")
+
+
+@register()
+class cert_get_requestdata(Command):
+    __doc__ = _('Gather data for a certificate signing request.')
+
+    takes_options = (
+        Principal('principal',
+            label=_('Principal'),
+            doc=_('Principal for this certificate (e.g.'
+                  ' HTTP/test.example.com)'),
+        ),
+        Str('profile_id',
+            validate_profile_id,
+            label=_('Profile ID'),
+            doc=_('Certificate Profile to use'),
+        ),
+        Str('format',
+            label=_('Name of CSR generation tool'),
+            doc=_('Name of tool (e.g. openssl, certutil) that will be used to'
+                  ' create CSR'),
+        ),
+    )
+
+    has_output = (
+        output.Output(
+            'result',
+            type=dict,
+            doc=_('Dictionary mapping variable name to value'),
+        ),
+    )
+
+    def execute(self, **kw):
+        principal = kw.get('principal')
+        profile_id = kw.get('profile_id')
+        helper = kw.get('format')
+
+        result = {'debug_output': u'test'}
+        return dict(
+            result=result
+        )
-- 
2.5.5

-- 
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