From 1ebf280dcbd06d23bfccc8ec481047b602352866 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Thu, 27 Mar 2014 18:52:54 -0400
Subject: [PATCH] Refactored TPS connections.

The TPS connections has been modified to use PATCH for update operation
as required by Backbone. The ConnectionData class has been modified to
accept null properties to indicate that the properties are not being
updated. The ConnectionModel class has been modified to use JSON data
type for enable and disable operations.

Ticket #654
---
 .../certsrv/tps/connection/ConnectionData.java     | 29 +++---------
 .../certsrv/tps/connection/ConnectionResource.java |  4 +-
 .../cmstools/tps/connection/ConnectionCLI.java     |  8 ++--
 .../tps-tomcat/shared/webapps/tps/js/connection.js | 53 +++++++++++-----------
 .../server/tps/rest/ConnectionService.java         | 32 +++++++++----
 5 files changed, 62 insertions(+), 64 deletions(-)

diff --git a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionData.java b/base/common/src/com/netscape/certsrv/tps/connection/ConnectionData.java
index 3ab71c75d458af06637701fdb8f3abb26378742e..0d1224d3c7e58408bf31c619c4e0bfb8b86be481 100644
--- a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionData.java
+++ b/base/common/src/com/netscape/certsrv/tps/connection/ConnectionData.java
@@ -21,7 +21,6 @@ package com.netscape.certsrv.tps.connection;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -62,7 +61,7 @@ public class ConnectionData {
 
     String id;
     String status;
-    Map<String, String> properties = new LinkedHashMap<String, String>();
+    Map<String, String> properties;
 
     Link link;
 
@@ -91,24 +90,7 @@ public class ConnectionData {
     }
 
     public void setProperties(Map<String, String> properties) {
-        this.properties.clear();
-        this.properties.putAll(properties);
-    }
-
-    public Collection<String> getPropertyNames() {
-        return properties.keySet();
-    }
-
-    public String getProperty(String name) {
-        return properties.get(name);
-    }
-
-    public void setProperty(String name, String value) {
-        properties.put(name, value);
-    }
-
-    public String removeProperty(String name) {
-        return properties.remove(name);
+        this.properties = properties;
     }
 
     public static class MapAdapter extends XmlAdapter<PropertyList, Map<String, String>> {
@@ -223,8 +205,11 @@ public class ConnectionData {
         ConnectionData before = new ConnectionData();
         before.setID("connection1");
         before.setStatus("ENABLED");
-        before.setProperty("param1", "value1");
-        before.setProperty("param2", "value2");
+
+        Map<String, String> properties = new LinkedHashMap<String, String>();
+        properties.put("param1", "value1");
+        properties.put("param2", "value2");
+        before.setProperties(properties);
 
         String string = before.toString();
         System.out.println(string);
diff --git a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionResource.java b/base/common/src/com/netscape/certsrv/tps/connection/ConnectionResource.java
index e161350633f997d478f360055f49c2a1fd637073..216e3793b267f2c10322baea62e5545737260d1d 100644
--- a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionResource.java
+++ b/base/common/src/com/netscape/certsrv/tps/connection/ConnectionResource.java
@@ -20,7 +20,6 @@ package com.netscape.certsrv.tps.connection;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.QueryParam;
@@ -30,6 +29,7 @@ import org.jboss.resteasy.annotations.ClientResponseType;
 
 import com.netscape.certsrv.acls.ACLMapping;
 import com.netscape.certsrv.authentication.AuthMethodMapping;
+import com.netscape.certsrv.base.PATCH;
 
 
 /**
@@ -57,7 +57,7 @@ public interface ConnectionResource {
     @ClientResponseType(entityType=ConnectionData.class)
     public Response addConnection(ConnectionData connectionData);
 
-    @PUT
+    @PATCH
     @Path("{connectionID}")
     @ACLMapping("connections.modify")
     @ClientResponseType(entityType=ConnectionData.class)
diff --git a/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionCLI.java b/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionCLI.java
index 1159a20128471f07fe3cba4a8f9b726080eb3f4a..c0802ba13a05d6e410759ee6c29ac5081d0131db 100644
--- a/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionCLI.java
@@ -59,9 +59,11 @@ public class ConnectionCLI extends CLI {
         if (showProperties) {
             System.out.println("  Properties:");
             Map<String, String> properties = connectionData.getProperties();
-            for (String name : properties.keySet()) {
-                String value = properties.get(name);
-                System.out.println("    " + name + ": " + value);
+            if (properties != null) {
+                for (String name : properties.keySet()) {
+                    String value = properties.get(name);
+                    System.out.println("    " + name + ": " + value);
+                }
             }
         }
 
diff --git a/base/tps-tomcat/shared/webapps/tps/js/connection.js b/base/tps-tomcat/shared/webapps/tps/js/connection.js
index adf7a3c2963b2b683ad4b3a8e4a2220a6884feee..7c3743d45d68985ab4d7331cec05798fd2a7624d 100644
--- a/base/tps-tomcat/shared/webapps/tps/js/connection.js
+++ b/base/tps-tomcat/shared/webapps/tps/js/connection.js
@@ -24,46 +24,45 @@ var ConnectionModel = Model.extend({
     parseResponse: function(response) {
         return {
             id: response.id,
+            connectionID: response.id,
             status: response.Status,
             properties: response.Properties.Property
         };
     },
-    parseXML: function(data) {
-        var xml = $(data);
-        var entry = $("Connection", xml);
-        var status = $("Status", entry);
-        return {
-            id: entry.attr("id"),
-            status: status.text()
-        };
-    },
     createRequest: function(attributes) {
         return {
-            id: attributes.id,
-            Status: attributes.status
+            id: attributes.profileID,
+            Status: attributes.status,
+            Properties: {
+                Property: attributes.properties
+            }
         };
     },
     enable: function(options) {
         var self = this;
-        $.post(self.url() + "?action=enable")
-            .done(function(data, textStatus, jqXHR) {
-                self.set(self.parseXML(data));
-                options.success.call(self, data, textStatus, jqXHR);
-            })
-            .fail(function(jqXHR, textStatus, errorThrown) {
-                options.error.call(self, jqXHR, textStatus, errorThrown);
-            });
+        $.ajax({
+            type: "POST",
+            url: self.url() + "?action=enable",
+            dataType: "json"
+        }).done(function(data, textStatus, jqXHR) {
+            self.set(self.parseResponse(data));
+            if (options.success) options.success.call(self, data, textStatus, jqXHR);
+        }).fail(function(jqXHR, textStatus, errorThrown) {
+            if (options.error) options.error.call(self, jqXHR, textStatus, errorThrown);
+        });
     },
     disable: function(options) {
         var self = this;
-        $.post(self.url() + "?action=disable")
-            .done(function(data, textStatus, jqXHR) {
-                self.set(self.parseXML(data));
-                options.success.call(self, data, textStatus, jqXHR);
-            })
-            .fail(function(jqXHR, textStatus, errorThrown) {
-                options.error.call(self, jqXHR, textStatus, errorThrown);
-            });
+        $.ajax({
+            type: "POST",
+            url: self.url() + "?action=disable",
+            dataType: "json"
+        }).done(function(data, textStatus, jqXHR) {
+            self.set(self.parseResponse(data));
+            if (options.success) options.success.call(self, data, textStatus, jqXHR);
+        }).fail(function(jqXHR, textStatus, errorThrown) {
+            if (options.error) options.error.call(self, jqXHR, textStatus, errorThrown);
+        });
     }
 });
 
diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/rest/ConnectionService.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/rest/ConnectionService.java
index 8e0b69dcf85f332850b269ba561bc89688078d0a..daa9fb003bc11a05ad05fc9293012aedbe38bfd1 100644
--- a/base/tps-tomcat/src/org/dogtagpki/server/tps/rest/ConnectionService.java
+++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/rest/ConnectionService.java
@@ -23,6 +23,7 @@ import java.net.URI;
 import java.net.URLEncoder;
 import java.security.Principal;
 import java.util.Iterator;
+import java.util.Map;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.core.Context;
@@ -205,23 +206,34 @@ public class ConnectionService extends PKIService implements ConnectionResource
 
             ConnectionRecord record = database.getRecord(connectionID);
 
-            String status = record.getStatus();
-            if (!"Disabled".equals(status)) {
+            // only disabled connection can be updated
+            if (!"Disabled".equals(record.getStatus())) {
                 throw new ForbiddenException("Unable to update connection " + connectionID);
             }
 
-            status = connectionData.getStatus();
-            if (!"Enabled".equals(status)) {
-                throw new ForbiddenException("Invalid connection status: " + status);
+            // update status if specified
+            String status = connectionData.getStatus();
+            if (status != null && !"Disabled".equals(status)) {
+                if (!"Enabled".equals(status)) {
+                    throw new ForbiddenException("Invalid connection status: " + status);
+                }
+
+                // if user doesn't have rights, set to pending
+                Principal principal = servletRequest.getUserPrincipal();
+                if (database.requiresApproval() && !database.canApprove(principal)) {
+                    status = "Pending_Approval";
+                }
+
+                // enable connection
+                record.setStatus(status);
             }
 
-            Principal principal = servletRequest.getUserPrincipal();
-            if (database.requiresApproval() && !database.canApprove(principal)) {
-                status = "Pending_Approval";
+            // update properties if specified
+            Map<String, String> properties = connectionData.getProperties();
+            if (properties != null) {
+                record.setProperties(properties);
             }
 
-            record.setStatus(status);
-            record.setProperties(connectionData.getProperties());
             database.updateRecord(connectionID, record);
 
             connectionData = createConnectionData(database.getRecord(connectionID));
-- 
1.8.4.2

