>From 5ffe8835a710fb0d5b3fe1b5d353197e149ad702 Mon Sep 17 00:00:00 2001
From: Ade Lee <alee@redhat.com>
Date: Wed, 28 Aug 2013 13:01:44 -0400
Subject: [PATCH 147/147] Provide enrollment template per profile

This adds an API call to get a template which can be used to generate an
enrollment request which can be passed into the REST API.  The template
is simply a CertRequest with the relevant inputs for that profile added in.
---
 .../netscape/certsrv/profile/ProfileClient.java    |  5 ++
 .../netscape/certsrv/profile/ProfileResource.java  |  6 ++
 .../cms/servlet/profile/ProfileService.java        | 54 +++++++++++++++++
 .../com/netscape/cmstools/profile/ProfileCLI.java  | 50 ++++++++++++++++
 .../cmstools/profile/ProfileTemplateCLI.java       | 69 ++++++++++++++++++++++
 5 files changed, 184 insertions(+)
 create mode 100644 base/java-tools/src/com/netscape/cmstools/profile/ProfileTemplateCLI.java

diff --git a/base/common/src/com/netscape/certsrv/profile/ProfileClient.java b/base/common/src/com/netscape/certsrv/profile/ProfileClient.java
index c4ecf6bec170f61146ecbb4ba6726f54d46a5fdb..146b36bad1c290e6303ea414aab88c92f48d5cee 100644
--- a/base/common/src/com/netscape/certsrv/profile/ProfileClient.java
+++ b/base/common/src/com/netscape/certsrv/profile/ProfileClient.java
@@ -19,6 +19,7 @@ package com.netscape.certsrv.profile;
 
 import java.net.URISyntaxException;
 
+import com.netscape.certsrv.cert.CertEnrollmentRequest;
 import com.netscape.certsrv.client.Client;
 import com.netscape.certsrv.client.PKIClient;
 
@@ -50,6 +51,10 @@ public class ProfileClient extends Client {
         return profileClient.listProfiles();
     }
 
+    public CertEnrollmentRequest getEnrollmentTemplate(String id) {
+        return profileClient.getEnrollmentTemplate(id);
+    }
+
     public void enableProfile(String id) {
         profileClient.modifyProfileState(id, "enable");
     }
diff --git a/base/common/src/com/netscape/certsrv/profile/ProfileResource.java b/base/common/src/com/netscape/certsrv/profile/ProfileResource.java
index 5c733aa592ea4896637d9f6496140ee4259232e5..4e9b1eff964ee127bb788262c37c960546c89b6c 100644
--- a/base/common/src/com/netscape/certsrv/profile/ProfileResource.java
+++ b/base/common/src/com/netscape/certsrv/profile/ProfileResource.java
@@ -12,6 +12,7 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 
 import com.netscape.certsrv.authentication.AuthMethodMapping;
+import com.netscape.certsrv.cert.CertEnrollmentRequest;
 
 @Path("profiles")
 public interface ProfileResource {
@@ -25,6 +26,11 @@ public interface ProfileResource {
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     public ProfileData retrieveProfile(@PathParam("id") String id);
 
+    @GET
+    @Path("{id}/enrollment-template")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    public CertEnrollmentRequest getEnrollmentTemplate(@PathParam("id") String id);
+
     @POST
     @AuthMethodMapping("admin")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
diff --git a/base/common/src/com/netscape/cms/servlet/profile/ProfileService.java b/base/common/src/com/netscape/cms/servlet/profile/ProfileService.java
index 09a9a1c23d76d73d55ab8d60a45fc25b0c9b9241..0a9cd9895b35cdb6f84d991213d9ba1d062f835a 100644
--- a/base/common/src/com/netscape/cms/servlet/profile/ProfileService.java
+++ b/base/common/src/com/netscape/cms/servlet/profile/ProfileService.java
@@ -41,6 +41,7 @@ import com.netscape.certsrv.base.EBaseException;
 import com.netscape.certsrv.base.IConfigStore;
 import com.netscape.certsrv.base.PKIException;
 import com.netscape.certsrv.base.UnauthorizedException;
+import com.netscape.certsrv.cert.CertEnrollmentRequest;
 import com.netscape.certsrv.common.NameValuePairs;
 import com.netscape.certsrv.common.OpDef;
 import com.netscape.certsrv.common.ScopeDef;
@@ -55,6 +56,7 @@ import com.netscape.certsrv.profile.IProfileSubsystem;
 import com.netscape.certsrv.profile.PolicyConstraint;
 import com.netscape.certsrv.profile.PolicyConstraintValue;
 import com.netscape.certsrv.profile.PolicyDefault;
+import com.netscape.certsrv.profile.ProfileAttribute;
 import com.netscape.certsrv.profile.ProfileData;
 import com.netscape.certsrv.profile.ProfileDataInfo;
 import com.netscape.certsrv.profile.ProfileDataInfos;
@@ -927,4 +929,56 @@ public class ProfileService extends PKIService implements ProfileResource {
                 auditor.getParamString(scope, type, id, params));
         auditor.log(msg);
     }
+
+    @Override
+    public CertEnrollmentRequest getEnrollmentTemplate(String profileId) {
+        if (ps == null) {
+            CMS.debug("modifyProfileState: ps is null");
+            throw new PKIException("Error modifying profile state.  Profile Service not available");
+        }
+
+        if (profileId == null) {
+            CMS.debug("modifyProfileState: invalid request. profileId is null");
+            throw new BadRequestException("Invalid ProfileId");
+        }
+
+        IProfile profile = null;
+        try {
+            profile = ps.getProfile(profileId);
+            if (profile == null) {
+                throw new BadRequestException("Cannot provide enrollment template for profile `" + profileId +
+                        "`.  Profile not found");
+            }
+        } catch (EBaseException e) {
+            CMS.debug("getEnrollmentTemplate(): error obtaining profile `" + profileId + "`: " + e);
+            e.printStackTrace();
+            throw new PKIException("Error generating enrollment template.  Cannot obtain profile.");
+        }
+
+        CertEnrollmentRequest request = new CertEnrollmentRequest();
+        request.setProfileId(profileId);
+        request.setRenewal(Boolean.parseBoolean(profile.isRenewal()));
+        request.setRemoteAddr("");
+        request.setRemoteHost("");
+        request.setSerialNum("");
+
+        // populate inputs
+        Enumeration<String> inputIds = profile.getProfileInputIds();
+        while (inputIds.hasMoreElements()) {
+            String id = inputIds.nextElement();
+            try {
+                ProfileInput input = createProfileInput(profile, id);
+                for (ProfileAttribute attr: input.getAttrs()) {
+                    attr.setValue("");
+                }
+                request.addInput(input);
+            } catch (EBaseException e) {
+                CMS.debug("getEnrollmentTemplate(): Failed to add input " + id + " to request template: " + e);
+                e.printStackTrace();
+                throw new PKIException("Failed to add input" + id + "to request template");
+            }
+        }
+
+        return request;
+    }
 }
diff --git a/base/java-tools/src/com/netscape/cmstools/profile/ProfileCLI.java b/base/java-tools/src/com/netscape/cmstools/profile/ProfileCLI.java
index 59f63c7e9f2109a52978f6e11d8e6f534c576bdd..ef03fe48ac62f3be0b00e93d08d033dceb4acecb 100644
--- a/base/java-tools/src/com/netscape/cmstools/profile/ProfileCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/profile/ProfileCLI.java
@@ -12,6 +12,7 @@ import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
 
+import com.netscape.certsrv.cert.CertEnrollmentRequest;
 import com.netscape.certsrv.profile.ProfileAttribute;
 import com.netscape.certsrv.profile.ProfileClient;
 import com.netscape.certsrv.profile.ProfileData;
@@ -35,6 +36,7 @@ public class ProfileCLI extends CLI {
         addModule(new ProfileRemoveCLI(this));
         addModule(new ProfileEnableCLI(this));
         addModule(new ProfileDisableCLI(this));
+        addModule(new ProfileTemplateCLI(this));
     }
 
     public String getFullName() {
@@ -144,4 +146,52 @@ public class ProfileCLI extends CLI {
         data = (ProfileData) unmarshaller.unmarshal(fis);
         return data;
     }
+
+    public static void saveEnrollmentTemplateToFile(String filename, CertEnrollmentRequest request)
+            throws JAXBException, FileNotFoundException {
+        JAXBContext context = JAXBContext.newInstance(CertEnrollmentRequest.class);
+        Marshaller marshaller = context.createMarshaller();
+        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+
+        FileOutputStream stream = new FileOutputStream(filename);
+        marshaller.marshal(request, stream);
+
+        MainCLI.printMessage("Saved enrollment template for " + request.getProfileId() + " to " + filename);
+    }
+
+    public static void printEnrollmentTemplate(CertEnrollmentRequest request) {
+        System.out.println("  Profile ID: " +  request.getProfileId());
+        System.out.println("  Renewal: " + request.getIsRenewal());
+
+        for (ProfileInput input: request.getInputs()) {
+            System.out.println();
+            System.out.println("  Input ID: " + input.getId());
+            System.out.println("  Name: " + input.getName());
+            System.out.println("  Class: " + input.getClassId());
+            for (ProfileAttribute attr: input.getAttrs()) {
+                System.out.println();
+                System.out.println("    Attribute Name: " + attr.getName());
+                System.out.println("    Attribute Description: " +
+                    attr.getDescriptor().getDescription(Locale.getDefault()));
+                System.out.println("    Attribute Syntax: " +
+                    attr.getDescriptor().getSyntax());
+            }
+        }
+
+        for (ProfileOutput output: request.getOutputs()) {
+            System.out.println();
+            System.out.println("  Output ID: " + output.getId());
+            System.out.println("  Name: " + output.getName());
+            System.out.println("  Class: " + output.getClassId());
+            for (ProfileAttribute attr: output.getAttrs()) {
+                System.out.println();
+                System.out.println("    Attribute Name: " + attr.getName());
+                System.out.println("    Attribute Description: " +
+                    attr.getDescriptor().getDescription(Locale.getDefault()));
+                System.out.println("    Attribute Syntax: " +
+                    attr.getDescriptor().getSyntax());
+            }
+        }
+
+    }
 }
diff --git a/base/java-tools/src/com/netscape/cmstools/profile/ProfileTemplateCLI.java b/base/java-tools/src/com/netscape/cmstools/profile/ProfileTemplateCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b1bb5b0f8ec12398f120a0ea1fc5d779c18d8da
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/profile/ProfileTemplateCLI.java
@@ -0,0 +1,69 @@
+package com.netscape.cmstools.profile;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.ParseException;
+
+import com.netscape.certsrv.cert.CertEnrollmentRequest;
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+
+public class ProfileTemplateCLI extends CLI {
+
+    public ProfileCLI profileCLI;
+
+    public ProfileTemplateCLI(ProfileCLI profileCLI) {
+        super("template", "Get Enrollment template", profileCLI);
+        this.profileCLI = profileCLI;
+    }
+
+    public void printHelp() {
+        formatter.printHelp(getFullName() + " <Profile ID>", options);
+    }
+
+    public void execute(String[] args) throws Exception {
+        CommandLine cmd = null;
+
+        Option option = new Option(null, "output", true, "Output filename");
+        option.setArgName("filename");
+        options.addOption(option);
+
+        try {
+            cmd = parser.parse(options, args);
+        } catch (ParseException e) {
+            System.err.println("Error: " + e.getMessage());
+            printHelp();
+            System.exit(-1);
+        }
+
+        String[] cLineArgs = cmd.getArgs();
+        if (cLineArgs.length < 1) {
+            System.err.println("Error: Missing profile ID.");
+            printHelp();
+            System.exit(-1);
+        }
+
+        String profileId = cLineArgs[0];
+
+        String filename = null;
+        if (cmd.hasOption("output")) {
+            filename = cmd.getOptionValue("output");
+
+            if (filename == null || filename.trim().length() == 0) {
+                System.err.println("Error: Missing output file name.");
+                printHelp();
+                System.exit(-1);
+            }
+        }
+
+        CertEnrollmentRequest request = profileCLI.profileClient.getEnrollmentTemplate(profileId);
+
+        MainCLI.printMessage("Enrollment Template for Profile \"" + profileId + "\"");
+
+        if (filename != null) {
+            ProfileCLI.saveEnrollmentTemplateToFile(filename, request);
+        } else {
+            ProfileCLI.printEnrollmentTemplate(request);
+        }
+    }
+}
-- 
1.8.1.4

