From e529c7e724fdeb4abf1fba551ea0e57f05fd4ed9 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Thu, 27 Mar 2014 21:42:38 -0400
Subject: [PATCH] Refactored TPS authenticators.

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

Ticket #654
---
 .../tps/authenticator/AuthenticatorData.java       | 29 +++---------
 .../tps/authenticator/AuthenticatorResource.java   |  4 +-
 .../tps/authenticator/AuthenticatorCLI.java        |  8 ++--
 .../shared/webapps/tps/js/authenticator.js         | 53 +++++++++++-----------
 .../server/tps/rest/AuthenticatorService.java      | 32 +++++++++----
 5 files changed, 62 insertions(+), 64 deletions(-)

diff --git a/base/common/src/com/netscape/certsrv/tps/authenticator/AuthenticatorData.java b/base/common/src/com/netscape/certsrv/tps/authenticator/AuthenticatorData.java
index d55dde126a465d1b6452d40efb3a687d81832e8b..2984d66ebc933de67541d07440144bcdfb380d15 100644
--- a/base/common/src/com/netscape/certsrv/tps/authenticator/AuthenticatorData.java
+++ b/base/common/src/com/netscape/certsrv/tps/authenticator/AuthenticatorData.java
@@ -21,7 +21,6 @@ package com.netscape.certsrv.tps.authenticator;
 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 AuthenticatorData {
 
     String id;
     String status;
-    Map<String, String> properties = new LinkedHashMap<String, String>();
+    Map<String, String> properties;
 
     Link link;
 
@@ -91,24 +90,7 @@ public class AuthenticatorData {
     }
 
     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 AuthenticatorData {
         AuthenticatorData before = new AuthenticatorData();
         before.setID("authenticator1");
         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/authenticator/AuthenticatorResource.java b/base/common/src/com/netscape/certsrv/tps/authenticator/AuthenticatorResource.java
index 457549ecace2bdb9beabbb3b524c9271a80b66b5..d21ad552c9692cd1790feb46ad40a5363fdab5b9 100644
--- a/base/common/src/com/netscape/certsrv/tps/authenticator/AuthenticatorResource.java
+++ b/base/common/src/com/netscape/certsrv/tps/authenticator/AuthenticatorResource.java
@@ -20,7 +20,6 @@ package com.netscape.certsrv.tps.authenticator;
 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 AuthenticatorResource {
     @ClientResponseType(entityType=AuthenticatorData.class)
     public Response addAuthenticator(AuthenticatorData authenticatorData);
 
-    @PUT
+    @PATCH
     @Path("{authenticatorID}")
     @ACLMapping("authenticators.modify")
     @ClientResponseType(entityType=AuthenticatorData.class)
diff --git a/base/java-tools/src/com/netscape/cmstools/tps/authenticator/AuthenticatorCLI.java b/base/java-tools/src/com/netscape/cmstools/tps/authenticator/AuthenticatorCLI.java
index ebdf808900230b55b87908e31e017449df41a52d..8f802f57b681dca5fba491249636282d2b726a20 100644
--- a/base/java-tools/src/com/netscape/cmstools/tps/authenticator/AuthenticatorCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/tps/authenticator/AuthenticatorCLI.java
@@ -59,9 +59,11 @@ public class AuthenticatorCLI extends CLI {
         if (showProperties) {
             System.out.println("  Properties:");
             Map<String, String> properties = authenticatorData.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/authenticator.js b/base/tps-tomcat/shared/webapps/tps/js/authenticator.js
index 6ad9d7555ad3e8a3f8815331885d3ab9a97924ee..059aa9eb60cdd7fe37f7c789f4358a8c8e6d5988 100644
--- a/base/tps-tomcat/shared/webapps/tps/js/authenticator.js
+++ b/base/tps-tomcat/shared/webapps/tps/js/authenticator.js
@@ -24,46 +24,45 @@ var AuthenticatorModel = Model.extend({
     parseResponse: function(response) {
         return {
             id: response.id,
+            authenticatorID: response.id,
             status: response.Status,
             properties: response.Properties.Property
         };
     },
-    parseXML: function(data) {
-        var xml = $(data);
-        var entry = $("Authenticator", 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/AuthenticatorService.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/rest/AuthenticatorService.java
index 2daffd55107044ca17d54ca0daf33e7fe927e29a..6a66e9ec55cbc91d84587a04079b9247f0c39a89 100644
--- a/base/tps-tomcat/src/org/dogtagpki/server/tps/rest/AuthenticatorService.java
+++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/rest/AuthenticatorService.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 AuthenticatorService extends PKIService implements AuthenticatorRes
 
             AuthenticatorRecord record = database.getRecord(authenticatorID);
 
-            String status = record.getStatus();
-            if (!"Disabled".equals(status)) {
+            // only disabled authenticator can be updated
+            if (!"Disabled".equals(record.getStatus())) {
                 throw new ForbiddenException("Unable to update authenticator " + authenticatorID);
             }
 
-            status = authenticatorData.getStatus();
-            if (!"Enabled".equals(status)) {
-                throw new ForbiddenException("Invalid authenticator status: " + status);
+            // update status if specified
+            String status = authenticatorData.getStatus();
+            if (status != null && !"Disabled".equals(status)) {
+                if (!"Enabled".equals(status)) {
+                    throw new ForbiddenException("Invalid authenticator 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 authenticator
+                record.setStatus(status);
             }
 
-            Principal principal = servletRequest.getUserPrincipal();
-            if (database.requiresApproval() && !database.canApprove(principal)) {
-                status = "Pending_Approval";
+            // update properties if specified
+            Map<String, String> properties = authenticatorData.getProperties();
+            if (properties != null) {
+                record.setProperties(authenticatorData.getProperties());
             }
 
-            record.setStatus(status);
-            record.setProperties(authenticatorData.getProperties());
             database.updateRecord(authenticatorID, record);
 
             authenticatorData = createAuthenticatorData(database.getRecord(authenticatorID));
-- 
1.8.4.2

