diff options
12 files changed, 175 insertions, 1 deletions
diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/CAApplication.java b/base/ca/src/org/dogtagpki/server/ca/rest/CAApplication.java index 78f3da941..2e193d5e1 100644 --- a/base/ca/src/org/dogtagpki/server/ca/rest/CAApplication.java +++ b/base/ca/src/org/dogtagpki/server/ca/rest/CAApplication.java @@ -10,6 +10,7 @@ import org.dogtagpki.server.rest.AccountService; import org.dogtagpki.server.rest.AuditService; import org.dogtagpki.server.rest.AuthMethodInterceptor; import org.dogtagpki.server.rest.GroupService; +import org.dogtagpki.server.rest.MessageFormatInterceptor; import org.dogtagpki.server.rest.SecurityDomainService; import org.dogtagpki.server.rest.SelfTestService; import org.dogtagpki.server.rest.SystemCertService; @@ -91,6 +92,7 @@ public class CAApplication extends Application { // interceptors singletons.add(new AuthMethodInterceptor()); singletons.add(new ACLInterceptor()); + singletons.add(new MessageFormatInterceptor()); } public Set<Class<?>> getClasses() { diff --git a/base/common/src/com/netscape/certsrv/base/PKIException.java b/base/common/src/com/netscape/certsrv/base/PKIException.java index ad55d139e..f89c1b18c 100644 --- a/base/common/src/com/netscape/certsrv/base/PKIException.java +++ b/base/common/src/com/netscape/certsrv/base/PKIException.java @@ -31,6 +31,11 @@ public class PKIException extends RuntimeException { public int code; + public PKIException(Response.Status status) { + super(status.getReasonPhrase()); + code = status.getStatusCode(); + } + public PKIException(String message) { super(message); code = Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(); diff --git a/base/common/src/com/netscape/certsrv/client/ClientConfig.java b/base/common/src/com/netscape/certsrv/client/ClientConfig.java index c85db52d3..da4e3d780 100644 --- a/base/common/src/com/netscape/certsrv/client/ClientConfig.java +++ b/base/common/src/com/netscape/certsrv/client/ClientConfig.java @@ -55,6 +55,7 @@ public class ClientConfig { String certPassword; String username; String password; + String messageFormat; @XmlElement(name="ServerURI") public URI getServerURI() { @@ -123,6 +124,15 @@ public class ClientConfig { this.password = password; } + @XmlElement(name="MessageFormat") + public String getMessageFormat() { + return messageFormat; + } + + public void setMessageFormat(String messageFormat) { + this.messageFormat = messageFormat; + } + @Override public int hashCode() { final int prime = 31; @@ -130,6 +140,7 @@ public class ClientConfig { result = prime * result + ((certDatabase == null) ? 0 : certDatabase.hashCode()); result = prime * result + ((certNickname == null) ? 0 : certNickname.hashCode()); result = prime * result + ((certPassword == null) ? 0 : certPassword.hashCode()); + result = prime * result + ((messageFormat == null) ? 0 : messageFormat.hashCode()); result = prime * result + ((password == null) ? 0 : password.hashCode()); result = prime * result + ((serverURI == null) ? 0 : serverURI.hashCode()); result = prime * result + ((username == null) ? 0 : username.hashCode()); @@ -160,6 +171,11 @@ public class ClientConfig { return false; } else if (!certPassword.equals(other.certPassword)) return false; + if (messageFormat == null) { + if (other.messageFormat != null) + return false; + } else if (!messageFormat.equals(other.messageFormat)) + return false; if (password == null) { if (other.password != null) return false; diff --git a/base/common/src/com/netscape/certsrv/client/PKIClient.java b/base/common/src/com/netscape/certsrv/client/PKIClient.java index 2b455fa8c..4f5a98d25 100644 --- a/base/common/src/com/netscape/certsrv/client/PKIClient.java +++ b/base/common/src/com/netscape/certsrv/client/PKIClient.java @@ -33,6 +33,8 @@ import com.netscape.cmsutil.util.Utils; public class PKIClient { + public final static String[] MESSAGE_FORMATS = { "xml", "json" }; + public ClientConfig config; public PKIConnection connection; diff --git a/base/common/src/com/netscape/certsrv/client/PKIConnection.java b/base/common/src/com/netscape/certsrv/client/PKIConnection.java index 1c3e58a1b..06c51aaad 100644 --- a/base/common/src/com/netscape/certsrv/client/PKIConnection.java +++ b/base/common/src/com/netscape/certsrv/client/PKIConnection.java @@ -17,12 +17,14 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.UnknownHostException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import javax.ws.rs.client.Entity; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; @@ -511,7 +513,20 @@ public class PKIConnection { public <T> T createProxy(URI uri, Class<T> clazz) throws URISyntaxException { ResteasyWebTarget target = resteasyClient.target(uri); - return ProxyBuilder.builder(clazz, target).build(); + ProxyBuilder<T> builder = ProxyBuilder.builder(clazz, target); + + String messageFormat = config.getMessageFormat(); + if (messageFormat == null) messageFormat = PKIClient.MESSAGE_FORMATS[0]; + + if (!Arrays.asList(PKIClient.MESSAGE_FORMATS).contains(messageFormat)) { + throw new Error("Unsupported message format: " + messageFormat); + } + + MediaType contentType = MediaType.valueOf("application/" + messageFormat); + builder.defaultConsumes(contentType); + builder.defaultProduces(contentType); + + return builder.build(); } public <T> T getEntity(Response response, Class<T> clazz) { diff --git a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java index 082c8140b..3527238d2 100644 --- a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java @@ -185,6 +185,10 @@ public class MainCLI extends CLI { option.setArgName("list"); options.addOption(option); + option = new Option(null, "message-format", true, "Message format: xml (default), json"); + option.setArgName("format"); + options.addOption(option); + options.addOption("v", false, "Verbose"); options.addOption(null, "help", false, "Help"); options.addOption(null, "version", false, "Version"); @@ -252,6 +256,10 @@ public class MainCLI extends CLI { } if (verbose) System.out.println("Security database: "+this.certDatabase.getAbsolutePath()); + + String messageFormat = cmd.getOptionValue("message-format"); + config.setMessageFormat(messageFormat); + if (verbose) System.out.println("Message format: " + messageFormat); } public void convertCertStatusList(String list, Collection<Integer> statuses) throws Exception { diff --git a/base/kra/src/org/dogtagpki/server/kra/rest/KRAApplication.java b/base/kra/src/org/dogtagpki/server/kra/rest/KRAApplication.java index ea8a6c038..c8dc553e2 100644 --- a/base/kra/src/org/dogtagpki/server/kra/rest/KRAApplication.java +++ b/base/kra/src/org/dogtagpki/server/kra/rest/KRAApplication.java @@ -10,6 +10,7 @@ import org.dogtagpki.server.rest.AccountService; import org.dogtagpki.server.rest.AuditService; import org.dogtagpki.server.rest.AuthMethodInterceptor; import org.dogtagpki.server.rest.GroupService; +import org.dogtagpki.server.rest.MessageFormatInterceptor; import org.dogtagpki.server.rest.SecurityDomainService; import org.dogtagpki.server.rest.SelfTestService; import org.dogtagpki.server.rest.SystemCertService; @@ -69,6 +70,7 @@ public class KRAApplication extends Application { // interceptors singletons.add(new AuthMethodInterceptor()); singletons.add(new ACLInterceptor()); + singletons.add(new MessageFormatInterceptor()); } public Set<Class<?>> getClasses() { diff --git a/base/ocsp/src/org/dogtagpki/server/ocsp/rest/OCSPApplication.java b/base/ocsp/src/org/dogtagpki/server/ocsp/rest/OCSPApplication.java index 1be534978..688fec772 100644 --- a/base/ocsp/src/org/dogtagpki/server/ocsp/rest/OCSPApplication.java +++ b/base/ocsp/src/org/dogtagpki/server/ocsp/rest/OCSPApplication.java @@ -10,6 +10,7 @@ import org.dogtagpki.server.rest.AccountService; import org.dogtagpki.server.rest.AuditService; import org.dogtagpki.server.rest.AuthMethodInterceptor; import org.dogtagpki.server.rest.GroupService; +import org.dogtagpki.server.rest.MessageFormatInterceptor; import org.dogtagpki.server.rest.SecurityDomainService; import org.dogtagpki.server.rest.SelfTestService; import org.dogtagpki.server.rest.SystemCertService; @@ -65,6 +66,7 @@ public class OCSPApplication extends Application { // interceptors singletons.add(new AuthMethodInterceptor()); singletons.add(new ACLInterceptor()); + singletons.add(new MessageFormatInterceptor()); } public Set<Class<?>> getClasses() { diff --git a/base/server/cms/src/com/netscape/cms/servlet/base/PKIService.java b/base/server/cms/src/com/netscape/cms/servlet/base/PKIService.java index 6550715f5..27dea60db 100644 --- a/base/server/cms/src/com/netscape/cms/servlet/base/PKIService.java +++ b/base/server/cms/src/com/netscape/cms/servlet/base/PKIService.java @@ -20,6 +20,7 @@ package com.netscape.cms.servlet.base; import java.lang.reflect.Method; import java.net.URI; import java.security.cert.CertificateEncodingException; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -27,13 +28,16 @@ import java.util.Map; import javax.ws.rs.FormParam; import javax.ws.rs.core.CacheControl; +import javax.ws.rs.core.Context; import javax.ws.rs.core.EntityTag; import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.PKIException; import com.netscape.certsrv.cert.CertData; import com.netscape.certsrv.logging.IAuditor; import com.netscape.certsrv.logging.ILogger; @@ -52,18 +56,53 @@ public class PKIService { // caching parameters public static final int DEFAULT_LONG_CACHE_LIFETIME = 1000; + public static List<MediaType> MESSAGE_FORMATS = Arrays.asList( + MediaType.APPLICATION_XML_TYPE, + MediaType.APPLICATION_JSON_TYPE + ); + + @Context + private HttpHeaders headers; + public ILogger logger = CMS.getLogger(); public IAuditor auditor = CMS.getAuditor(); + public static MediaType resolveFormat(MediaType format) { + + for (MediaType supportedFormat : MESSAGE_FORMATS) { + if (format.isCompatible(supportedFormat)) return supportedFormat; + } + + return null; + } + + public static MediaType resolveFormat(List<MediaType> formats) { + + for (MediaType acceptableFormat : formats) { + MediaType supportedFormat = resolveFormat(acceptableFormat); + if (supportedFormat != null) return supportedFormat; + } + + return null; + } + + public MediaType getResponseFormat() { + MediaType responseFormat = resolveFormat(headers.getAcceptableMediaTypes()); + if (responseFormat == null) throw new PKIException(Response.Status.NOT_ACCEPTABLE); + return responseFormat; + } + public Response createOKResponse() { return Response .ok() + .type(getResponseFormat()) .build(); } public Response createOKResponse(Object entity) { return Response .ok(entity) + .type(getResponseFormat()) .build(); } @@ -71,12 +110,14 @@ public class PKIService { return Response .created(link) .entity(entity) + .type(getResponseFormat()) .build(); } public Response createNoContentResponse() { return Response .noContent() + .type(getResponseFormat()) .build(); } diff --git a/base/server/cms/src/org/dogtagpki/server/rest/MessageFormatInterceptor.java b/base/server/cms/src/org/dogtagpki/server/rest/MessageFormatInterceptor.java new file mode 100644 index 000000000..6734efe1d --- /dev/null +++ b/base/server/cms/src/org/dogtagpki/server/rest/MessageFormatInterceptor.java @@ -0,0 +1,77 @@ +//--- 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) 2014 Red Hat, Inc. +//All rights reserved. +//--- END COPYRIGHT BLOCK --- +package org.dogtagpki.server.rest; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.List; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.Provider; + +import org.jboss.resteasy.core.ResourceMethodInvoker; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.cms.servlet.base.PKIService; + +/** + * @author Endi S. Dewata + */ +@Provider +public class MessageFormatInterceptor implements ContainerRequestFilter { + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) requestContext + .getProperty("org.jboss.resteasy.core.ResourceMethodInvoker"); + Method method = methodInvoker.getMethod(); + Class<?> clazz = methodInvoker.getResourceClass(); + + CMS.debug("MessageFormatInterceptor: " + clazz.getSimpleName() + "." + method.getName() + "()"); + + MediaType contentType = requestContext.getMediaType(); + CMS.debug("MessageFormatInterceptor: content-type: " + contentType); + + if (contentType != null) { + MediaType requestFormat = PKIService.resolveFormat(contentType); + + if (requestFormat == null) { + throw new WebApplicationException(Response.Status.UNSUPPORTED_MEDIA_TYPE); + } + + CMS.debug("MessageFormatInterceptor: request format: " + requestFormat); + } + + List<MediaType> acceptableFormats = requestContext.getAcceptableMediaTypes(); + CMS.debug("MessageFormatInterceptor: acceptable formats: " + acceptableFormats); + + if (acceptableFormats != null) { + MediaType responseFormat = PKIService.resolveFormat(acceptableFormats); + + if (responseFormat == null) { + throw new WebApplicationException(Response.Status.NOT_ACCEPTABLE); + } + + CMS.debug("MessageFormatInterceptor: response format: " + responseFormat); + } + } +} diff --git a/base/tks/src/org/dogtagpki/server/tks/rest/TKSApplication.java b/base/tks/src/org/dogtagpki/server/tks/rest/TKSApplication.java index 976b9bd9f..f824f9088 100644 --- a/base/tks/src/org/dogtagpki/server/tks/rest/TKSApplication.java +++ b/base/tks/src/org/dogtagpki/server/tks/rest/TKSApplication.java @@ -10,6 +10,7 @@ import org.dogtagpki.server.rest.AccountService; import org.dogtagpki.server.rest.AuditService; import org.dogtagpki.server.rest.AuthMethodInterceptor; import org.dogtagpki.server.rest.GroupService; +import org.dogtagpki.server.rest.MessageFormatInterceptor; import org.dogtagpki.server.rest.SelfTestService; import org.dogtagpki.server.rest.SystemCertService; import org.dogtagpki.server.rest.SystemConfigService; @@ -52,6 +53,7 @@ public class TKSApplication extends Application { // interceptors singletons.add(new AuthMethodInterceptor()); singletons.add(new ACLInterceptor()); + singletons.add(new MessageFormatInterceptor()); } public Set<Class<?>> getClasses() { diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/rest/TPSApplication.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/rest/TPSApplication.java index 0dfd2b7c0..7ecadb5a7 100644 --- a/base/tps-tomcat/src/org/dogtagpki/server/tps/rest/TPSApplication.java +++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/rest/TPSApplication.java @@ -27,6 +27,7 @@ import org.dogtagpki.server.rest.AccountService; import org.dogtagpki.server.rest.AuditService; import org.dogtagpki.server.rest.AuthMethodInterceptor; import org.dogtagpki.server.rest.GroupService; +import org.dogtagpki.server.rest.MessageFormatInterceptor; import org.dogtagpki.server.rest.SelfTestService; import org.dogtagpki.server.rest.SystemCertService; import org.dogtagpki.server.rest.SystemConfigService; @@ -92,6 +93,7 @@ public class TPSApplication extends Application { // interceptors singletons.add(new AuthMethodInterceptor()); singletons.add(new ACLInterceptor()); + singletons.add(new MessageFormatInterceptor()); } public Set<Class<?>> getClasses() { |