summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEndi S. Dewata <edewata@redhat.com>2013-12-10 20:10:06 -0500
committerEndi S. Dewata <edewata@redhat.com>2013-12-16 19:15:43 -0500
commit017e14f93e376f7cbc20066f052a39c4552860d9 (patch)
treee7707f6cf39db3052261794b66a6934173b6104c
parent5952a82975063c4ec27303091a44e586d1386933 (diff)
downloadpki-017e14f93e376f7cbc20066f052a39c4552860d9.tar.gz
pki-017e14f93e376f7cbc20066f052a39c4552860d9.tar.xz
pki-017e14f93e376f7cbc20066f052a39c4552860d9.zip
Using PATCH method for modify operations.
Some modify operations have been modified to use HTTP PATCH method since the request only contains changes to the resource, not the entire resource. To replace the entire resource, separate replace operations using HTTP PUT method will be used instead. The Backbone library is using the same convention by default. Ticket #654
-rw-r--r--base/common/src/com/netscape/certsrv/base/PATCH.java35
-rw-r--r--base/common/src/com/netscape/certsrv/group/GroupResource.java3
-rw-r--r--base/common/src/com/netscape/certsrv/tps/token/TokenClient.java2
-rw-r--r--base/common/src/com/netscape/certsrv/tps/token/TokenModifyRequest.java152
-rw-r--r--base/common/src/com/netscape/certsrv/tps/token/TokenResource.java7
-rw-r--r--base/common/src/com/netscape/certsrv/user/UserResource.java11
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/admin/GroupService.java5
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/admin/UserService.java79
-rw-r--r--base/tps-tomcat/src/org/dogtagpki/server/tps/token/TokenService.java21
9 files changed, 148 insertions, 167 deletions
diff --git a/base/common/src/com/netscape/certsrv/base/PATCH.java b/base/common/src/com/netscape/certsrv/base/PATCH.java
new file mode 100644
index 000000000..9f2af17f1
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/PATCH.java
@@ -0,0 +1,35 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.certsrv.base;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.ws.rs.HttpMethod;
+
+/**
+ * http://brianoneill.blogspot.in/2011/11/patch-methods-on-jax-rs.html
+ */
+@Target({ ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@HttpMethod("PATCH")
+public @interface PATCH {
+}
diff --git a/base/common/src/com/netscape/certsrv/group/GroupResource.java b/base/common/src/com/netscape/certsrv/group/GroupResource.java
index 12c90228b..aa26bebb1 100644
--- a/base/common/src/com/netscape/certsrv/group/GroupResource.java
+++ b/base/common/src/com/netscape/certsrv/group/GroupResource.java
@@ -33,6 +33,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;
/**
* @author Endi S. Dewata
@@ -60,7 +61,7 @@ public interface GroupResource {
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public GroupData getGroup(@PathParam("groupID") String groupID);
- @POST
+ @PATCH
@Path("{groupID}")
@ClientResponseType(entityType=GroupData.class)
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
diff --git a/base/common/src/com/netscape/certsrv/tps/token/TokenClient.java b/base/common/src/com/netscape/certsrv/tps/token/TokenClient.java
index 602e8f966..e349acd1e 100644
--- a/base/common/src/com/netscape/certsrv/tps/token/TokenClient.java
+++ b/base/common/src/com/netscape/certsrv/tps/token/TokenClient.java
@@ -56,7 +56,7 @@ public class TokenClient extends Client {
public TokenData updateToken(String tokenID, TokenData tokenData) {
@SuppressWarnings("unchecked")
- ClientResponse<TokenData> response = (ClientResponse<TokenData>)resource.updateToken(tokenID, tokenData);
+ ClientResponse<TokenData> response = (ClientResponse<TokenData>)resource.replaceToken(tokenID, tokenData);
return client.getEntity(response);
}
diff --git a/base/common/src/com/netscape/certsrv/tps/token/TokenModifyRequest.java b/base/common/src/com/netscape/certsrv/tps/token/TokenModifyRequest.java
deleted file mode 100644
index b4168261f..000000000
--- a/base/common/src/com/netscape/certsrv/tps/token/TokenModifyRequest.java
+++ /dev/null
@@ -1,152 +0,0 @@
-// --- BEGIN COPYRIGHT BLOCK ---
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// (C) 2013 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-
-package com.netscape.certsrv.tps.token;
-
-import java.io.StringReader;
-import java.io.StringWriter;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-
-import org.jboss.resteasy.plugins.providers.atom.Link;
-
-/**
- * @author Endi S. Dewata
- */
-@XmlRootElement(name="TokenModifyRequest")
-public class TokenModifyRequest {
-
- public static Marshaller marshaller;
- public static Unmarshaller unmarshaller;
-
- static {
- try {
- marshaller = JAXBContext.newInstance(TokenModifyRequest.class).createMarshaller();
- marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
- unmarshaller = JAXBContext.newInstance(TokenModifyRequest.class).createUnmarshaller();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- String id;
- String userID;
-
- Link link;
-
- @XmlAttribute(name="id")
- public String getID() {
- return id;
- }
-
- public void setID(String id) {
- this.id = id;
- }
-
- @XmlElement(name="UserID")
- public String getUserID() {
- return userID;
- }
-
- public void setUserID(String userID) {
- this.userID = userID;
- }
-
- @XmlElement(name="Link")
- public Link getLink() {
- return link;
- }
-
- public void setLink(Link link) {
- this.link = link;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((id == null) ? 0 : id.hashCode());
- result = prime * result + ((link == null) ? 0 : link.hashCode());
- result = prime * result + ((userID == null) ? 0 : userID.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- TokenModifyRequest other = (TokenModifyRequest) obj;
- if (id == null) {
- if (other.id != null)
- return false;
- } else if (!id.equals(other.id))
- return false;
- if (link == null) {
- if (other.link != null)
- return false;
- } else if (!link.equals(other.link))
- return false;
- if (userID == null) {
- if (other.userID != null)
- return false;
- } else if (!userID.equals(other.userID))
- return false;
- return true;
- }
-
- public String toString() {
- try {
- StringWriter sw = new StringWriter();
- marshaller.marshal(this, sw);
- return sw.toString();
-
- } catch (Exception e) {
- return super.toString();
- }
- }
-
- public static TokenModifyRequest valueOf(String string) throws Exception {
- try {
- return (TokenModifyRequest)unmarshaller.unmarshal(new StringReader(string));
- } catch (Exception e) {
- return null;
- }
- }
-
- public static void main(String args[]) throws Exception {
-
- TokenModifyRequest before = new TokenModifyRequest();
- before.setID("token1");
- before.setUserID("user1");
-
- String string = before.toString();
- System.out.println(string);
-
- TokenModifyRequest after = TokenModifyRequest.valueOf(string);
- System.out.println(before.equals(after));
- }
-}
diff --git a/base/common/src/com/netscape/certsrv/tps/token/TokenResource.java b/base/common/src/com/netscape/certsrv/tps/token/TokenResource.java
index 000853623..529efe8c0 100644
--- a/base/common/src/com/netscape/certsrv/tps/token/TokenResource.java
+++ b/base/common/src/com/netscape/certsrv/tps/token/TokenResource.java
@@ -33,6 +33,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;
/**
@@ -67,11 +68,11 @@ public interface TokenResource {
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@ACLMapping("tokens.modify")
- public Response updateToken(
+ public Response replaceToken(
@PathParam("tokenID") String tokenID,
TokenData tokenData);
- @POST
+ @PATCH
@Path("{tokenID}")
@ClientResponseType(entityType=TokenData.class)
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@@ -79,7 +80,7 @@ public interface TokenResource {
@ACLMapping("tokens.modify")
public Response modifyToken(
@PathParam("tokenID") String tokenID,
- TokenModifyRequest request);
+ TokenData tokenData);
@DELETE
@Path("{tokenID}")
diff --git a/base/common/src/com/netscape/certsrv/user/UserResource.java b/base/common/src/com/netscape/certsrv/user/UserResource.java
index 19db939dd..90b46ef60 100644
--- a/base/common/src/com/netscape/certsrv/user/UserResource.java
+++ b/base/common/src/com/netscape/certsrv/user/UserResource.java
@@ -22,6 +22,7 @@ import javax.ws.rs.Consumes;
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.Produces;
@@ -33,6 +34,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;
/**
* @author Endi S. Dewata
@@ -63,7 +65,14 @@ public interface UserResource {
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public UserData getUser(@PathParam("userID") String userID);
- @POST
+ @PUT
+ @Path("{userID}")
+ @ClientResponseType(entityType=UserData.class)
+ @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ public Response replaceUser(@PathParam("userID") String userID, UserData userData);
+
+ @PATCH
@Path("{userID}")
@ClientResponseType(entityType=UserData.class)
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
diff --git a/base/server/cms/src/com/netscape/cms/servlet/admin/GroupService.java b/base/server/cms/src/com/netscape/cms/servlet/admin/GroupService.java
index 5f9a3b947..a20b548ad 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/admin/GroupService.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/admin/GroupService.java
@@ -267,7 +267,10 @@ public class GroupService extends PKIService implements GroupResource {
throw new ResourceNotFoundException("Group " + groupID + " not found.");
}
- group.set("description", groupData.getDescription());
+ String description = groupData.getDescription();
+ if (description != null) {
+ group.set("description", description);
+ }
// allow adding a group with no members, except "Certificate
// Server Administrators"
diff --git a/base/server/cms/src/com/netscape/cms/servlet/admin/UserService.java b/base/server/cms/src/com/netscape/cms/servlet/admin/UserService.java
index c24154094..63a461355 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/admin/UserService.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/admin/UserService.java
@@ -367,6 +367,85 @@ public class UserService extends PKIService implements UserResource {
}
/**
+ * Replaces an existing user in local scope.
+ * <P>
+ *
+ * Request/Response Syntax: http://warp.mcom.com/server/certificate/columbo/design/
+ * ui/admin-protocol-definition.html#user-admin
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CONFIG_ROLE used when configuring role information (anything under
+ * users/groups)
+ * </ul>
+ */
+ @Override
+ public Response replaceUser(String userID, UserData userData) {
+
+ if (userData == null) throw new BadRequestException("User data is null.");
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ IConfigStore cs = CMS.getConfigStore();
+ try {
+ if (userID == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID"));
+ throw new BadRequestException(getUserMessage("CMS_ADMIN_SRVLT_NULL_RS_ID", headers));
+ }
+
+ IUser user = userGroupManager.createUser(userID);
+
+ String fullName = userData.getFullName();
+ user.setFullName(fullName);
+
+ String email = userData.getEmail();
+ user.setEmail(email);
+
+ String pword = userData.getPassword();
+ IPasswordCheck passwdCheck = CMS.getPasswordChecker();
+
+ if (!passwdCheck.isGoodPassword(pword)) {
+ throw new EUsrGrpException(passwdCheck.getReason(pword));
+ }
+
+ user.setPassword(pword);
+
+ String phone = userData.getPhone();
+ user.setPhone(phone);
+
+ String state = userData.getState();
+ user.setState(state);
+
+ String csType = cs.getString("cs.type");
+ if (csType.equals("TPS")) {
+ String tpsProfiles = userData.getAttribute(ATTR_TPS_PROFILES);
+ String[] profiles = tpsProfiles.split(",");
+ user.setTpsProfiles(Arrays.asList(profiles));
+ }
+
+ userGroupManager.modifyUser(user);
+
+ auditModifyUser(userID, userData, ILogger.SUCCESS);
+
+ // read the data back
+ userData = getUser(userID);
+
+ return Response
+ .ok(userData)
+ .type(MediaType.APPLICATION_XML)
+ .build();
+
+ } catch (PKIException e) {
+ auditModifyUser(userID, userData, ILogger.FAILURE);
+ throw e;
+
+ } catch (EBaseException e) {
+ auditModifyUser(userID, userData, ILogger.FAILURE);
+ throw new PKIException(e.getMessage());
+ }
+ }
+
+ /**
* Modifies an existing user in local scope.
* <P>
*
diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/token/TokenService.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/token/TokenService.java
index 7991c8c20..4183ff6e2 100644
--- a/base/tps-tomcat/src/org/dogtagpki/server/tps/token/TokenService.java
+++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/token/TokenService.java
@@ -39,7 +39,6 @@ import com.netscape.certsrv.base.BadRequestException;
import com.netscape.certsrv.base.PKIException;
import com.netscape.certsrv.tps.token.TokenCollection;
import com.netscape.certsrv.tps.token.TokenData;
-import com.netscape.certsrv.tps.token.TokenModifyRequest;
import com.netscape.certsrv.tps.token.TokenResource;
import com.netscape.cms.servlet.base.PKIService;
@@ -200,12 +199,12 @@ public class TokenService extends PKIService implements TokenResource {
}
@Override
- public Response updateToken(String tokenID, TokenData tokenData) {
+ public Response replaceToken(String tokenID, TokenData tokenData) {
if (tokenID == null) throw new BadRequestException("Token ID is null.");
if (tokenData == null) throw new BadRequestException("Token data is null.");
- CMS.debug("TokenService.updateToken(\"" + tokenID + "\")");
+ CMS.debug("TokenService.replaceToken(\"" + tokenID + "\")");
try {
TPSSubsystem subsystem = (TPSSubsystem)CMS.getSubsystem(TPSSubsystem.ID);
@@ -229,21 +228,27 @@ public class TokenService extends PKIService implements TokenResource {
}
@Override
- public Response modifyToken(String tokenID, TokenModifyRequest request) {
+ public Response modifyToken(String tokenID, TokenData tokenData) {
if (tokenID == null) throw new BadRequestException("Token ID is null.");
- if (request == null) throw new BadRequestException("Token modification is null.");
+ if (tokenData == null) throw new BadRequestException("Token data is null.");
- CMS.debug("TokenService.modifyToken(\"" + tokenID + "\", request");
+ CMS.debug("TokenService.modifyToken(\"" + tokenID + "\")");
try {
TPSSubsystem subsystem = (TPSSubsystem)CMS.getSubsystem(TPSSubsystem.ID);
TokenDatabase database = subsystem.getTokenDatabase();
TokenRecord tokenRecord = database.getRecord(tokenID);
- // TODO: perform modification
- TokenData tokenData = createTokenData(tokenRecord);
+ String userID = tokenData.getUserID();
+ if (userID != null) {
+ tokenRecord.setUserID(userID);
+ }
+
+ database.updateRecord(tokenID, tokenRecord);
+
+ tokenData = createTokenData(database.getRecord(tokenID));
return Response
.ok(tokenData)