From 6c2bc7b0f502531e86b8a7af789c7d81b3bbff09 Mon Sep 17 00:00:00 2001
From: Endi Sukma Dewata <edewata@redhat.com>
Date: Wed, 30 Jan 2013 17:57:17 -0500
Subject: [PATCH] Merged cert-request-review/approve commands.

The cert-request-approve has been merged into cert-request-review
to ensure that these operations are executed in the same session.

Ticket #474
---
 .../src/com/netscape/certsrv/cert/CertClient.java  |  24 ++++
 base/java-tools/man/man1/pki.1                     |  10 +-
 .../src/com/netscape/cmstools/cert/CertCLI.java    |  11 +-
 .../cmstools/cert/CertRequestApproveCLI.java       |  58 ---------
 .../cmstools/cert/CertRequestReviewCLI.java        | 138 +++++++++++++++------
 5 files changed, 142 insertions(+), 99 deletions(-)
 delete mode 100644 base/java-tools/src/com/netscape/cmstools/cert/CertRequestApproveCLI.java

diff --git a/base/common/src/com/netscape/certsrv/cert/CertClient.java b/base/common/src/com/netscape/certsrv/cert/CertClient.java
index c209bf9b8c805634b8c977e4599f7e690e397d12..53118aba1c4a7122a37189fa9d8b5d0ac6eddf5e 100644
--- a/base/common/src/com/netscape/certsrv/cert/CertClient.java
+++ b/base/common/src/com/netscape/certsrv/cert/CertClient.java
@@ -84,6 +84,30 @@ public class CertClient extends PKIClient {
         certRequestResource.approveRequest(id, data);
     }
 
+    public void rejectRequest(RequestId id, CertReviewResponse data) {
+        certRequestResource.rejectRequest(id, data);
+    }
+
+    public void cancelRequest(RequestId id, CertReviewResponse data) {
+        certRequestResource.cancelRequest(id, data);
+    }
+
+    public void updateRequest(RequestId id, CertReviewResponse data) {
+        certRequestResource.updateRequest(id, data);
+    }
+
+    public void validateRequest(RequestId id, CertReviewResponse data) {
+        certRequestResource.validateRequest(id, data);
+    }
+
+    public void assignRequest(RequestId id, CertReviewResponse data) {
+        certRequestResource.assignRequest(id, data);
+    }
+
+    public void unassignRequest(RequestId id, CertReviewResponse data) {
+        certRequestResource.unassignRequest(id, data);
+    }
+
     public CertRequestInfos listRequests(String requestState, String requestType, RequestId start, Integer pageSize,
             Integer maxResults, Integer maxTime) {
         return certRequestResource.listRequests(requestState, requestType, start, pageSize, maxResults, maxTime);
diff --git a/base/java-tools/man/man1/pki.1 b/base/java-tools/man/man1/pki.1
index 5729861e8968369919a4d3066ff836dce9fa5552..a18117bba5efe892784a5f9a35022762553fc81e 100644
--- a/base/java-tools/man/man1/pki.1
+++ b/base/java-tools/man/man1/pki.1
@@ -163,13 +163,17 @@ Then submit the request for review.  This can be done without authentication.
 
 .B pki cert-request-submit <request file>
 
-Then, an agent needs to review the request.
+Then, an agent needs to review the request by running the following command:
 
 .B pki <agent authentication> cert-request-review <request ID> --output <request review file>
 
-The output file contains details about the request, as well as the defaults and constraints of the enrollment profile.  It contains all the values that can be overridden by the agent.  To approve a request, run the following command as an agent:
+The request, as well as the defaults and constraints of the enrollment profile, will be stored in the output file.  The agent can examine the file and override any values if necessary.  To process the request, enter the appropriate action when prompted:
 
-.B pki <agent authentication> cert-request-approve <request review file>
+.B Action (approve/reject/cancel/update/validate/assign/unassign):
+
+Alternatively, the agent can process the request in a single step with the following command:
+
+.B pki <agent authentication> cert-request-review <request ID> --action <action>
 
 .SS Group Management Commands
 All group commands must be executed as an administrator. Some representative commands are shown below.  Type \fBpki group\fP to get a list of additional commands.
diff --git a/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java b/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java
index d3bf51e3232477ecedffc049a73cb516dff0c330..b9122531c77e9e96ffe378dd063bfe64b7dc7d90 100644
--- a/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java
@@ -27,6 +27,7 @@ import com.netscape.certsrv.cert.CertClient;
 import com.netscape.certsrv.cert.CertData;
 import com.netscape.certsrv.cert.CertDataInfo;
 import com.netscape.certsrv.cert.CertRequestInfo;
+import com.netscape.certsrv.cert.CertReviewResponse;
 import com.netscape.cmstools.cli.CLI;
 import com.netscape.cmstools.cli.MainCLI;
 
@@ -51,7 +52,6 @@ public class CertCLI extends CLI {
         addModule(new CertRequestFindCLI(this));
         addModule(new CertRequestSubmitCLI(this));
         addModule(new CertRequestReviewCLI(this));
-        addModule(new CertRequestApproveCLI(this));
     }
 
     public void printHelp() {
@@ -146,7 +146,14 @@ public class CertCLI extends CLI {
 
     public static void printCertRequestInfo(CertRequestInfo info) {
         System.out.println("  Request ID: " + info.getRequestId());
-        System.out.println("  Status: " + info.getRequestStatus());
         System.out.println("  Type: " + info.getRequestType());
+        System.out.println("  Status: " + info.getRequestStatus());
+    }
+
+    public static void printCertReviewResponse(CertReviewResponse response) {
+        System.out.println("  Request ID: " + response.getRequestId());
+        System.out.println("  Profile: " + response.getProfileName());
+        System.out.println("  Type: " + response.getRequestType());
+        System.out.println("  Status: " + response.getRequestStatus());
     }
 }
diff --git a/base/java-tools/src/com/netscape/cmstools/cert/CertRequestApproveCLI.java b/base/java-tools/src/com/netscape/cmstools/cert/CertRequestApproveCLI.java
deleted file mode 100644
index 0c6db8a9034c910abc22add1f9f4de76c0cd9237..0000000000000000000000000000000000000000
--- a/base/java-tools/src/com/netscape/cmstools/cert/CertRequestApproveCLI.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.netscape.cmstools.cert;
-
-import java.io.FileInputStream;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Unmarshaller;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.ParseException;
-
-import com.netscape.certsrv.cert.CertReviewResponse;
-import com.netscape.cmstools.cli.CLI;
-import com.netscape.cmstools.cli.MainCLI;
-
-public class CertRequestApproveCLI extends CLI {
-    CertCLI parent;
-
-    public CertRequestApproveCLI(CertCLI parent) {
-        super("request-approve", "Approve certificate request");
-        this.parent = parent;
-    }
-
-    @Override
-    public void execute(String[] args) throws Exception {
-        CommandLine cmd = null;
-
-        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: No file name specified.");
-            printHelp();
-            System.exit(-1);
-        }
-
-        FileInputStream fis = new FileInputStream(cLineArgs[0].trim());
-
-        JAXBContext context = JAXBContext.newInstance(CertReviewResponse.class);
-        Unmarshaller unmarshaller = context.createUnmarshaller();
-        CertReviewResponse reviewInfo = (CertReviewResponse) unmarshaller.unmarshal(fis);
-
-        parent.client.approveRequest(reviewInfo.getRequestId(), reviewInfo);
-
-        MainCLI.printMessage("Approved certificate request " + reviewInfo.getRequestId().toString());
-    }
-
-    @Override
-    public void printHelp() {
-        formatter.printHelp(parent.name + "-" + name + " <file name>", options);
-    }
-}
diff --git a/base/java-tools/src/com/netscape/cmstools/cert/CertRequestReviewCLI.java b/base/java-tools/src/com/netscape/cmstools/cert/CertRequestReviewCLI.java
index 682314b2545161285220fd4fe85089e97d6d9f6f..3891508bd99baf231bd107154add691dcadba3c6 100644
--- a/base/java-tools/src/com/netscape/cmstools/cert/CertRequestReviewCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cert/CertRequestReviewCLI.java
@@ -1,15 +1,20 @@
 package com.netscape.cmstools.cert;
 
-import java.io.FileNotFoundException;
+import java.io.BufferedReader;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.List;
 
 import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.ParseException;
+import org.apache.commons.lang.StringUtils;
 
 import com.netscape.certsrv.base.PKIException;
 import com.netscape.certsrv.cert.CertReviewResponse;
@@ -20,6 +25,9 @@ import com.netscape.cmstools.cli.MainCLI;
 public class CertRequestReviewCLI extends CLI {
 
     CertCLI parent;
+    List<String> actions = Arrays.asList(
+        "approve", "reject", "cancel", "update", "validate", "assign", "unassign"
+    );
 
     public CertRequestReviewCLI(CertCLI parent) {
         super("request-review", "Review certificate request");
@@ -27,11 +35,21 @@ public class CertRequestReviewCLI extends CLI {
     }
 
     @Override
-    public void execute(String[] args) {
+    public void printHelp() {
+        formatter.printHelp(parent.name + "-" + name + " <Request ID> [OPTIONS...]", options);
+    }
+
+    @Override
+    public void execute(String[] args) throws Exception {
         CommandLine cmd = null;
 
-        Option output = new Option(null, "output", true, "Output Filename");
-        options.addOption(output);
+        Option option = new Option(null, "action", true, "Action: " + StringUtils.join(actions, ", "));
+        option.setArgName("action");
+        options.addOption(option);
+
+        option = new Option(null, "output", true, "Output filename");
+        option.setArgName("filename");
+        options.addOption(option);
 
         try {
             cmd = parser.parse(options, args);
@@ -42,62 +60,110 @@ public class CertRequestReviewCLI extends CLI {
         }
 
         String[] cLineArgs = cmd.getArgs();
-
         if (cLineArgs.length < 1) {
-            System.err.println("Error: No request id specified.");
-            printHelp();
-            System.exit(-1);
-        }
-        String filename = null;
-        if (cmd.hasOption("output")) {
-            filename = cmd.getOptionValue("output");
-        } else {
-            System.err.println("No output option specified.");
-            printHelp();
-            System.exit(-1);
-        }
-
-        if (filename == null || filename.trim().length() == 0) {
-            System.err.println("Specify the filename to write the request information");
+            System.err.println("Error: Missing certificate request ID.");
             printHelp();
             System.exit(-1);
         }
 
-        RequestId reqId = null;
+        RequestId requestId = null;
         try {
-            reqId = new RequestId(cLineArgs[0]);
+            requestId = new RequestId(cLineArgs[0]);
         } catch (NumberFormatException e) {
-            System.err.println("Error: Invalid RequestID: " + cLineArgs[0]);
+            System.err.println("Error: Invalid certificate request ID " + cLineArgs[0] + ".");
             System.exit(-1);
         }
 
+        String action = cmd.getOptionValue("action");
+        String filename = null;
+
+        if (action == null) {
+            if (cmd.hasOption("output")) {
+                filename = cmd.getOptionValue("output");
+            } else {
+                System.err.println("Error: Missing output file name.");
+                printHelp();
+                System.exit(-1);
+            }
+
+            if (filename == null || filename.trim().length() == 0) {
+                System.err.println("Error: Missing output file name.");
+                printHelp();
+                System.exit(-1);
+            }
+        }
+
+        // Retrieve certificate request.
         CertReviewResponse reviewInfo = null;
         try {
-            reviewInfo = parent.client.reviewRequest(reqId);
+            reviewInfo = parent.client.reviewRequest(requestId);
         } catch (PKIException e) {
             System.err.println(e.getMessage());
             System.exit(-1);
         }
 
-        try {
+        if (action == null) {
+            // Store certificate request in a file.
             JAXBContext context = JAXBContext.newInstance(CertReviewResponse.class);
             Marshaller marshaller = context.createMarshaller();
             marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
 
             FileOutputStream stream = new FileOutputStream(filename);
-
             marshaller.marshal(reviewInfo, stream);
-            MainCLI.printMessage("Downloaded certificate request " + cLineArgs[0]);
-        } catch (JAXBException e) {
-            System.err.println("Cannot write to the file. " + e);
-        } catch (FileNotFoundException e) {
-            System.err.println("File not found at " + filename);
+
+            MainCLI.printMessage("Retrieved certificate request " + requestId);
+            CertCLI.printCertReviewResponse(reviewInfo);
+            System.out.println("  Filename: " + filename);
+            if (verbose) System.out.println("  Nonce: " + reviewInfo.getNonce());
+            System.out.println();
+
+            while (true) {
+                // Prompt for action.
+                System.out.print("Action (" + StringUtils.join(actions, "/") + "): ");
+                System.out.flush();
+
+                BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+                action = reader.readLine().trim().toLowerCase();
+
+                if (actions.contains(action)) break;
+            }
+
+            // Read certificate request file.
+            Unmarshaller unmarshaller = context.createUnmarshaller();
+            FileInputStream fis = new FileInputStream(filename);
+            reviewInfo = (CertReviewResponse) unmarshaller.unmarshal(fis);
         }
 
-    }
+        if (action.equalsIgnoreCase("approve")) {
+            parent.client.approveRequest(reviewInfo.getRequestId(), reviewInfo);
+            MainCLI.printMessage("Approved certificate request " + requestId);
+
+        } else if (action.equalsIgnoreCase("reject")) {
+            parent.client.rejectRequest(reviewInfo.getRequestId(), reviewInfo);
+            MainCLI.printMessage("Rejected certificate request " + requestId);
 
-    @Override
-    public void printHelp() {
-        formatter.printHelp(parent.name + "-" + name + " <request id>", options);
+        } else if (action.equalsIgnoreCase("cancel")) {
+            parent.client.cancelRequest(reviewInfo.getRequestId(), reviewInfo);
+            MainCLI.printMessage("Canceled certificate request " + requestId);
+
+        } else if (action.equalsIgnoreCase("update")) {
+            parent.client.updateRequest(reviewInfo.getRequestId(), reviewInfo);
+            MainCLI.printMessage("Updated certificate request " + requestId);
+
+        } else if (action.equalsIgnoreCase("validate")) {
+            parent.client.validateRequest(reviewInfo.getRequestId(), reviewInfo);
+            MainCLI.printMessage("Validated certificate request " + requestId);
+
+        } else if (action.equalsIgnoreCase("assign")) {
+            parent.client.assignRequest(reviewInfo.getRequestId(), reviewInfo);
+            MainCLI.printMessage("Assigned certificate request " + requestId);
+
+        } else if (action.equalsIgnoreCase("unassign")) {
+            parent.client.unassignRequest(reviewInfo.getRequestId(), reviewInfo);
+            MainCLI.printMessage("Unassigned certificate request " + requestId);
+
+        } else {
+            throw new Error("Invalid action: " + action);
+        }
     }
 }
-- 
1.7.12.1

