]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-6984: Adding support for SSL connections to Shared Authority server.
authorremillet <remillet@yahoo.com>
Fri, 8 Jul 2016 23:01:47 +0000 (16:01 -0700)
committerremillet <remillet@yahoo.com>
Fri, 8 Jul 2016 23:01:47 +0000 (16:01 -0700)
services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityServiceUtils.java
services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java
services/client/src/main/java/org/collectionspace/services/client/AbstractServiceClientImpl.java
services/client/src/main/java/org/collectionspace/services/client/AuthorityClient.java
services/client/src/main/java/org/collectionspace/services/client/AuthorityClientImpl.java
services/client/src/main/java/org/collectionspace/services/client/AuthorityProxy.java
services/client/src/main/java/org/collectionspace/services/client/CollectionSpaceClient.java
services/common/src/main/java/org/collectionspace/services/common/ServiceMessages.java

index d1d10e173f91d823b67b4ade4a26367f41fb01a9..5c81fa9fc1aebd60c95e60bfce25f194fbce08b7 100644 (file)
@@ -22,7 +22,10 @@ import org.collectionspace.services.config.tenant.RemoteClientConfigurations;
 import org.collectionspace.services.config.tenant.TenantBindingType;
 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
-import org.dom4j.DocumentException;
+import org.collectionspace.services.common.document.DocumentException;
+
+//import org.dom4j.DocumentException;
+import org.eclipse.jetty.http.HttpStatus;
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -121,14 +124,16 @@ public class AuthorityServiceUtils {
         Response res = client.read(specifier.getURNValue());
         try {
                int statusCode = res.getStatus();
-       
-               // Check the status code of the response: does it match
-               // the expected response(s)?
-               if (logger.isDebugEnabled()) {
-                   logger.debug(client.getClass().getCanonicalName() + ": status = " + statusCode);
+               if (statusCode == HttpStatus.OK_200) {
+                   result = new PoxPayloadIn((String)res.readEntity(responseType)); // Get the entire response!                                        
+               } else {
+                       String errMsg = String.format("Could not retrieve authority information for '%s' on remote server '%s'.  Server returned status code %d",
+                                       specifier.getURNValue(), remoteClientConfig.getUrl(), statusCode);
+                       if (logger.isDebugEnabled()) {
+                           logger.debug(errMsg);
+                       }
+                       throw new DocumentException(statusCode, errMsg);
                }
-               
-            result = new PoxPayloadIn((String)res.readEntity(responseType)); // Get the entire response!               
         } finally {
                res.close();
         }
@@ -155,14 +160,16 @@ public class AuthorityServiceUtils {
         
         try {
                int statusCode = res.getStatus();
-       
-               // Check the status code of the response: does it match
-               // the expected response(s)?
-               if (logger.isDebugEnabled()) {
-                   logger.debug(client.getClass().getCanonicalName() + ": status = " + statusCode);
-               }
-               
-            result = new PoxPayloadIn((String)res.readEntity(responseType)); // Get the entire response!               
+               if (statusCode == HttpStatus.OK_200) {
+                   result = new PoxPayloadIn((String)res.readEntity(responseType)); // Get the entire response.
+               } else {
+                       String errMsg = String.format("Could not retrieve authority item information for '%s:%s' on remote server '%s'.  Server returned status code %d",
+                                       specifier.getParentSpecifier().getURNValue(), specifier.getItemSpecifier().getURNValue(), remoteClientConfig.getUrl(), statusCode);
+                       if (logger.isDebugEnabled()) {
+                           logger.debug(errMsg);
+                       }
+                       throw new DocumentException(statusCode, errMsg);
+               }               
         } finally {
                res.close();
         }
@@ -188,7 +195,7 @@ public class AuthorityServiceUtils {
      * refnames with the correct domain name
      */
        static public PoxPayloadIn filterRefnameDomains(ServiceContext ctx,
-                       PoxPayloadIn payload) throws DocumentException {
+                       PoxPayloadIn payload) throws org.dom4j.DocumentException {
                PoxPayloadIn result = null;
 
                
index 87b6720f49f0b9132c87352cc353effa05df8782..30016a37983a5328a600c5d96c97c31e6ff1b22e 100644 (file)
@@ -63,8 +63,8 @@ import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler;
 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
 import org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
-
 import org.dom4j.Element;
+import org.eclipse.jetty.http.HttpStatus;
 import org.nuxeo.ecm.core.api.ClientException;
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.slf4j.Logger;
@@ -144,7 +144,7 @@ public abstract class AuthorityDocumentModelHandler<AuthCommon>
                //
                //
                Long sasRev = getRevision(sasPayloadIn);
-               if (sasRev > localRev) {
+               if (sasRev > localRev || true) { // FIXME: Along with the revision number, we need to use other meta information to determine if a sync should happen -for now, alway sync
                        //
                        // First, sync all the authority items
                        //
@@ -492,7 +492,18 @@ public abstract class AuthorityDocumentModelHandler<AuthCommon>
        return result; // -1 = no sync needed/possible, 0 = sync'd, 1 = created new item
        
        
-    }    
+    }
+    
+    private void assertStatusCode(Response res, Specifier specifier, AuthorityClient client) throws Exception {
+        int statusCode = res.getStatus();
+
+       if (statusCode != HttpStatus.OK_200) {
+               String errMsg = String.format("Could not retrieve authority information for '%s' on remote server '%s'.  Server returned status code %d",
+                               specifier.getURNValue(), client.getBaseURL(), statusCode);
+               res.close();
+               throw new DocumentException(statusCode, errMsg);
+       }
+    }
     
     /**
      * Request an authority item list payload from the SAS server.
@@ -504,22 +515,32 @@ public abstract class AuthorityDocumentModelHandler<AuthCommon>
      */
     private PoxPayloadIn requestPayloadInItemList(ServiceContext ctx, Specifier specifier) throws Exception {
        PoxPayloadIn result = null;
-       
         AuthorityClient client = (AuthorityClient) ctx.getClient();
+       //
+       // First find out how many items exist
         Response res = client.readItemList(specifier.getURNValue(),
                        null,   // partial term string
-                       null    // keyword string
+                       null,   // keyword string
+                       0,              // page size
+                       0               // page number
                        );
+        assertStatusCode(res, specifier, client);
+        AbstractCommonList commonList = res.readEntity(AbstractCommonList.class);
+        res.close();
+        long numOfItems = commonList.getTotalItems();        
+        
+        //
+        // Next, request a payload list with all the items
+        res = client.readItemList(specifier.getURNValue(),
+                       null,           // partial term string
+                       null,           // keyword string
+                       numOfItems,     // page size
+                       0                       // page number
+                       );        
+        assertStatusCode(res, specifier, client);
+
         try {
-               int statusCode = res.getStatus();
-       
-               // Check the status code of the response: does it match
-               // the expected response(s)?
-               if (logger.isDebugEnabled()) {
-                   logger.debug(client.getClass().getCanonicalName() + ": status = " + statusCode);
-               }
-               
-            result = new PoxPayloadIn((String)res.readEntity(getEntityResponseType())); // Get the entire response!            
+            result = new PoxPayloadIn((String)res.readEntity(getEntityResponseType())); // Get the entire response.
         } finally {
                res.close();
         }
index 1b1665b7fe6fb545c698ed238b733bdfe5890aea..010cf33ebf215a807abc0e1dc6ac6ed2b05dc1ae 100644 (file)
@@ -47,10 +47,44 @@ import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+
 // FIXME: Deprecated classes that need to be updated
 import org.jboss.resteasy.client.ProxyFactory;
 import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.conn.ssl.SSLContexts;
+
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
 
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * Private class for SSL support
+ */
+class HttpsTrustManager implements X509TrustManager {
+
+       @Override
+       public void checkClientTrusted(X509Certificate[] arg0, String arg1)
+                       throws CertificateException {
+               // TODO Auto-generated method stub
+
+       }
+
+       @Override
+       public void checkServerTrusted(X509Certificate[] arg0, String arg1)
+                       throws CertificateException {
+               // TODO Auto-generated method stub
+
+       }
+
+       @Override
+       public X509Certificate[] getAcceptedIssuers() {
+               return new X509Certificate[]{};
+       }
+
+}
 
 /**
  * Private class for JAX-RS authentication
@@ -498,17 +532,23 @@ public abstract class AbstractServiceClientImpl<CLT, REQUEST_PT, RESPONSE_PT, P
      * allow to reset proxy as per security needs
      */
     @Override
-       public void setProxy() {
+       public void setProxy() throws Exception {
        ResteasyClient client = null;
         String urlString = url.toString();
        Class<P> proxyClass = this.getProxyClass();
        
+       if (useSSL()) {
+               SSLContext sslcontext = SSLContexts.custom().useSSL().build();
+            sslcontext.init(null, new X509TrustManager[]{new HttpsTrustManager()}, new SecureRandom());
+            client = (ResteasyClient)ClientBuilder.newBuilder().sslContext(sslcontext).build();
+       } else {
+               client = (ResteasyClient)ClientBuilder.newClient();
+       }
+       
         if (useAuth()) {
             String user = properties.getProperty(USER_PROPERTY);
             String password = properties.getProperty(PASSWORD_PROPERTY);
-               client = (ResteasyClient)ClientBuilder.newClient().register(new Authenticator(user, password));
-        } else {
-               client = (ResteasyClient)ClientBuilder.newClient();
+               client = client.register(new Authenticator(user, password));
         }
         
         proxy = client.target(urlString).proxy(proxyClass);
@@ -532,7 +572,7 @@ public abstract class AbstractServiceClientImpl<CLT, REQUEST_PT, RESPONSE_PT, P
     @Override
        public void setAuth(boolean useAuth,
             String user, boolean useUser,
-            String password, boolean usePassword) {
+            String password, boolean usePassword) throws Exception {
         if (useAuth == true) {
             setProperty(CollectionSpaceClient.AUTH_PROPERTY, "true");
             if (useUser) {
index a1fe2043b260618ff8cfec2f88e01811e23885c7..e4a5f7a0e9cc166cc116f7a261e2db65ac18723e 100644 (file)
@@ -153,9 +153,14 @@ public interface AuthorityClient<AUTHORITY_COMMON_TYPE, AUTHORITY_ITEM_TYPE, P e
      * @return the client response
      */
     public Response readItemList(String inAuthority, String partialTerm, String keywords);
-    
+
+    public Response readItemList(String inAuthority, String partialTerm, String keywords, long pageSize, long pageNum);
+
     public Response readItemList(String inAuthority, String partialTerm, String keywords, Boolean includeDeleted);
     
+    public Response readItemList(String inAuthority, String partialTerm, String keywords, Boolean includeDeleted,
+               long pageSize, long pageNum);
+
     /**
      * Read item list for named vocabulary, filtering by partial term match, or keywords. Only one of
      * partialTerm or keywords should be specified. If both are specified, keywords
index 0f720b839a55c65587cb75a83b7b23b2345958d3..d4cb867778d0e03f15299cf17507b92fba7a370a 100644 (file)
@@ -209,10 +209,22 @@ public abstract class AuthorityClientImpl<AUTHORITY_COMMON_TYPE, AUTHORITY_ITEM_
         return getProxy().readItemList(inAuthority, partialTerm, keywords, INCLUDE_DELETE_TRUE);
     }
 
+    @Override
+    public Response readItemList(String inAuthority, String partialTerm, String keywords, long pageSize, long pageNum) {
+        return getProxy().readItemList(inAuthority, partialTerm, keywords, INCLUDE_DELETE_TRUE, pageSize, pageNum);
+    }
+
     @Override
     public Response readItemList(String inAuthority, String partialTerm, String keywords, Boolean includeDeleted) {
         return getProxy().readItemList(inAuthority, partialTerm, keywords, includeDeleted.toString());
     }
+    
+    @Override
+    public Response readItemList(String inAuthority, String partialTerm, String keywords, Boolean includeDeleted,
+               long pageSize, long pageNum) {
+        return getProxy().readItemList(inAuthority, partialTerm, keywords, includeDeleted.toString(), pageSize, pageNum);
+    }
+    
 
     /**
      * Read item list for named vocabulary, filtering by partial term match, or keywords. Only one of
index 0648c0ea71808e53356bdac9093d1c9ab088e8b5..1b12114e85fa4b5d454f5c35ec825f708cfe55dd 100644 (file)
@@ -153,6 +153,17 @@ public interface AuthorityProxy extends CollectionSpaceCommonListPoxProxy {
             @QueryParam(IQueryManager.SEARCH_TYPE_KEYWORDS_KW) String keywords,
             @QueryParam(WorkflowClient.WORKFLOWSTATE_QUERY) String workflowState);
     
+    @GET
+    @Produces({"application/xml"})
+    @Path("/{csid}/items/")
+    Response readItemList(
+               @PathParam("csid") String vcsid,
+            @QueryParam (IQueryManager.SEARCH_TYPE_PARTIALTERM) String partialTerm,
+            @QueryParam(IQueryManager.SEARCH_TYPE_KEYWORDS_KW) String keywords,
+            @QueryParam(WorkflowClient.WORKFLOWSTATE_QUERY) String workflowState,
+            @QueryParam(IClientQueryParams.PAGE_SIZE_PARAM) long pageSize,
+            @QueryParam(IClientQueryParams.START_PAGE_PARAM) long pageNum);
+    
     // List Items for a named authority matching a partial term or keywords.
     @GET
     @Produces({"application/xml"})
index 7b97f0f912fecda025433d0a58188685cfdd72b8..63b8cd26d5c30f5d96c6c395ae895971a1579c5a 100644 (file)
@@ -150,8 +150,9 @@ public interface CollectionSpaceClient<CLT, REQUEST_TYPE, RESPONSE_TYPE, P exten
      * setProxy for the client
      * might be useful to reset proxy (based on auth requirements) that is usually created at the time of
      * constructing a client
+     * @throws Exception 
      */
-    void setProxy();
+    void setProxy() throws Exception;
 
     /**
      * setAuth sets up authentication properties based on given parameters
@@ -160,10 +161,11 @@ public interface CollectionSpaceClient<CLT, REQUEST_TYPE, RESPONSE_TYPE, P exten
      * @param useUser indicates using user name
      * @param password
      * @param usePassword indicates using password
+     * @throws Exception 
      */
     void setAuth(boolean useAuth,
             String user, boolean useUser,
-            String password, boolean usePassword);
+            String password, boolean usePassword) throws Exception;
 
     /**
      * Use auth.
index bc167db96072ba890adffeb401104937ff3b6ad2..3df268caf942078323d3330ca993005a2b4662bd 100644 (file)
@@ -60,7 +60,7 @@ public class ServiceMessages {
     public static final String VALIDATION_FAILURE = "Validation failure ";
     public static final String MISSING_CSID = "missing csid";
     public static final String MISSING_INVALID_CSID = "missing/invalid csid=";
-       public static final String SYNC_FAILED = "Synchonization failed.";
+       public static final String SYNC_FAILED = "Synchonization failed";
 
     public static String resourceNotFoundMsg(String csid) {
         return String.format("The resource identified by CSID '%s' was not found.", csid);