From 4be65eae04c0ed497bf404d43f9a11a4993a239d Mon Sep 17 00:00:00 2001
From: rsanchez <rsanchez@curisit.net>
Date: Mon, 29 Sep 2014 15:25:59 +0000
Subject: [PATCH] #2021 fix - Added HTTP client to connect to SeCuris server

---
 src/main/java/net/curisit/securis/beans/SignedLicenseBean.java |    3 
 src/main/java/net/curisit/securis/ConnectionManager.java       |  140 +++++++++++++++++++++++++++++++++++
 src/main/java/net/curisit/securis/LicenseManager.java          |   35 +++++---
 src/main/resources/securis-client.properties                   |    6 
 pom.xml                                                        |   12 +-
 src/main/java/net/curisit/securis/License.java                 |   17 +--
 src/main/java/net/curisit/securis/utils/SignatureHelper.java   |    2 
 7 files changed, 179 insertions(+), 36 deletions(-)

diff --git a/pom.xml b/pom.xml
index f4c8d55..eb68e1f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>net.curisit</groupId>
 	<artifactId>securis-client</artifactId>
-	<version>0.9.6-SNAPSHOT</version>
+	<version>0.9.7-SNAPSHOT</version>
 	<build>
 		<plugins>
 			<plugin>
@@ -47,11 +47,6 @@
 			<version>1.2</version>
 		</dependency>
 		<dependency>
-			<groupId>commons-net</groupId>
-			<artifactId>commons-net</artifactId>
-			<version>3.3</version>
-		</dependency>
-		<dependency>
 			<groupId>org.codehaus.jackson</groupId>
 			<artifactId>jackson-mapper-asl</artifactId>
 			<version>1.9.13</version>
@@ -61,6 +56,11 @@
 			<artifactId>log4j-core</artifactId>
 			<version>2.0.2</version>
 		</dependency>
+		<dependency>
+			<groupId>org.apache.httpcomponents</groupId>
+			<artifactId>httpclient</artifactId>
+			<version>4.4-beta1</version>
+		</dependency>
 	</dependencies>
 
 	<distributionManagement>
diff --git a/src/main/java/net/curisit/securis/ConnectionManager.java b/src/main/java/net/curisit/securis/ConnectionManager.java
new file mode 100644
index 0000000..1312390
--- /dev/null
+++ b/src/main/java/net/curisit/securis/ConnectionManager.java
@@ -0,0 +1,140 @@
+package net.curisit.securis;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import net.curisit.securis.beans.RequestBean;
+import net.curisit.securis.utils.JsonUtils;
+import net.curisit.securis.utils.Params;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.apache.http.ssl.TrustStrategy;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+/**
+ * Manage all server connections
+ * 
+ * @author roberto <roberto.sanchez@curisit.net>
+ */
+public class ConnectionManager {
+
+	private static final Logger LOG = LogManager.getLogger(ConnectionManager.class);
+
+	private static ConnectionManager singleton;
+
+	private final String serverUrl;
+	private final CloseableHttpClient httpClient;
+	
+	private ConnectionManager() throws SeCurisException {
+		String aux = Params.get(Params.KEYS.LICENSE_SERVER_URL, "https://securis.curistec.com/api");
+		if (aux.endsWith("/")) {
+		    serverUrl = aux.substring(0, aux.length()-2);
+		} else {
+		    serverUrl = aux;
+		}
+		httpClient = createHttpClient();
+	}
+	
+	private CloseableHttpClient createHttpClient() throws SeCurisException {
+	       SSLContextBuilder builder = new SSLContextBuilder();
+	        SSLConnectionSocketFactory sslsf = null; 
+	        try {
+	            builder.loadTrustMaterial((KeyStore)null, new TrustStrategy() {
+	                @Override
+	                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+	                    return true;
+	                }
+	            });
+	            sslsf = new SSLConnectionSocketFactory(builder.build());
+	        } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e1) {
+	            LOG.error(e1);
+	            throw new SeCurisException("Error creating SSL socket factory");
+	        }
+	        return HttpClientBuilder.create().setSSLSocketFactory(sslsf).build();
+	}
+
+	public synchronized static ConnectionManager getInstance() throws SeCurisException {
+	    if (singleton == null) {
+	        singleton = new ConnectionManager();
+	    }
+		return singleton;
+	}
+
+
+	public <T> T executePost(String command, Class<T> returnType, RequestBean req) throws SeCurisException {
+        HttpPost postRequest = new HttpPost(String.format("%s/%s", serverUrl, command));
+        postRequest.addHeader("accept", "application/json");
+        postRequest.addHeader("content-type", "application/json");
+        try {
+            postRequest.setEntity(new StringEntity(JsonUtils.toJSON(req)));
+        } catch (UnsupportedEncodingException | SeCurisException e1) {
+            throw new SeCurisException("Error preparing POST command", e1);
+        }
+        HttpResponse response;
+        try {
+            response = httpClient.execute(postRequest);
+            if (response.getStatusLine().getStatusCode() != 200) {
+                throw new SeCurisException("Error executing command " + command + ", status: " + response.getStatusLine().getStatusCode());
+            }
+            String jsonLic = IOUtils.toString(response.getEntity().getContent());
+            LOG.info("License read OK: {}", jsonLic);
+            T responseBean = JsonUtils.json2object(jsonLic, returnType);
+
+            LOG.info("Response bean read OK: {}", responseBean);
+            LOG.info("JSON to write in file: {}", JsonUtils.toJSON(responseBean));
+            
+            return responseBean;
+        } catch (IOException e) {
+            LOG.error("Error acessing SeCuris server", e);
+            throw new SeCurisException("Error accessing SeCuris server");
+        }
+ 	}
+
+
+    public <T> T executeGet(String command, Class<T> returnType) throws SeCurisException {
+        HttpGet getRequest = new HttpGet(String.format("%s/%s", serverUrl, command));
+        getRequest.addHeader("accept", "application/json");
+
+        HttpResponse response;
+        try {
+            response = httpClient.execute(getRequest);
+            if (response.getStatusLine().getStatusCode() != 200) {
+                throw new SeCurisException("Error executing command " + command + ", status: " + response.getStatusLine().getStatusCode());
+            }
+            String jsonLic = IOUtils.toString(response.getEntity().getContent());
+            LOG.info("License read OK: {}", jsonLic);
+            T responseBean = JsonUtils.json2object(jsonLic, returnType);
+
+            LOG.info("Response bean read OK: {}", responseBean);
+            LOG.info("JSON to write in file: {}", JsonUtils.toJSON(responseBean));
+            
+            return responseBean;
+        } catch (IOException e) {
+            LOG.error("Error acessing SeCuris server", e);
+            throw new SeCurisException("Error accessing SeCuris server");
+        }
+    }
+     
+	public static class Command {
+        public static final String TEST = "ping";
+        public static final String CREATE_LIC = "request";
+        public static final String RENEW_LIC = "renew";
+	}
+
+
+}
diff --git a/src/main/java/net/curisit/securis/License.java b/src/main/java/net/curisit/securis/License.java
index 1d49af8..1f2a210 100644
--- a/src/main/java/net/curisit/securis/License.java
+++ b/src/main/java/net/curisit/securis/License.java
@@ -33,8 +33,6 @@
  *                                     file. --server parameter is mandatory.
  *  -s,--server <url_license_server>   License server url.
  *  -t,--test_lc                       Test if License Server (LC) is
- *                                     available. --server parameter is
- *                                     mandatory.
  * </pre>
  * 
  * @author roberto <roberto.sanchez@curisit.net>
@@ -85,16 +83,13 @@
 			}
 
 			if (cmd.hasOption('c')) {
-				String reqFilename = cmd.getOptionValue("rfile");
-				checkMandatoryParameter(reqFilename, "rfile");
-
-				LOG.warn("This command is not yet implemented");
-				System.exit(0);
+				LicenseManager.getInstance().requestLicense();
+                System.exit(0);
 			}
 
 			if (cmd.hasOption('t')) {
-				LOG.warn("This command is not yet implemented");
-				System.exit(0);
+                LicenseManager.getInstance().testServer();
+                System.exit(0);
 			}
 
 			if (cmd.hasOption('r')) {
@@ -168,8 +163,8 @@
 		options.addOption(OptionBuilder.withArgName("lic_file").withLongOpt("validate").withDescription("Validate lic file.").hasArg(true).create('l'));
 
 		options.addOption("g", "gen_request", false, "Generate request file. If --rfile parameter is missing then It is generated in current directory.");
-		options.addOption(OptionBuilder.withArgName("lic_file").withLongOpt("create").withDescription("Request a license file from server.").hasArg(true).create('c'));
-		options.addOption("t", "test_lc", false, "Test if License Server (LC) is available. --server parameter is mandatory.");
+		options.addOption(OptionBuilder.withLongOpt("create").withDescription("Request a license file to server.").hasArg(false).create('c'));
+		options.addOption("t", "test_lc", false, "Test if License Server (LC) is available. ");
 		options.addOption(OptionBuilder.withArgName("lic_file").withLongOpt("renew").withDescription("Synchronize/renew the current license file.").hasArg(true).create('r'));
 
 		return options;
diff --git a/src/main/java/net/curisit/securis/LicenseManager.java b/src/main/java/net/curisit/securis/LicenseManager.java
index c754def..ecec7a5 100644
--- a/src/main/java/net/curisit/securis/LicenseManager.java
+++ b/src/main/java/net/curisit/securis/LicenseManager.java
@@ -7,6 +7,7 @@
 import java.nio.file.Paths;
 import java.nio.file.StandardOpenOption;
 
+import net.curisit.securis.ConnectionManager.Command;
 import net.curisit.securis.beans.LicenseBean;
 import net.curisit.securis.beans.RequestBean;
 import net.curisit.securis.beans.SignedLicenseBean;
@@ -29,10 +30,9 @@
 
 	private static LicenseManager singleton = new LicenseManager();
 
-	String serverUrl = null;
-
+	public static final String PING_MESSAGE = "SeCuris API OK";	
+	
 	private LicenseManager() {
-		serverUrl = Params.get(Params.KEYS.LICENSE_SERVER_URL);
 	}
 
 	public static LicenseManager getInstance() {
@@ -88,9 +88,7 @@
 	 */
 	public LicenseBean requestLicense() throws SeCurisException {
 		RequestBean req = ReqGenerator.getInstance().createRequest(Params.get(Params.KEYS.APPLICATION_CODE), Params.get(Params.KEYS.CUSTOMER_CODE));
-		if (true) {
-			throw new SeCurisException("Action not implemented yet");
-		}
+
 		LicenseBean lic = requestLicenseToServer(req);
 		return lic;
 	}
@@ -120,9 +118,10 @@
 
 	}
 
-	private LicenseBean requestLicenseToServer(RequestBean req) {
-		// TODO Prepare call to server sending the request bean to get a valid license
-		return null;
+	private SignedLicenseBean requestLicenseToServer(RequestBean req) throws SeCurisException {
+	    SignedLicenseBean lic = ConnectionManager.getInstance().executePost(Command.CREATE_LIC, SignedLicenseBean.class, req);
+ 
+ 		return lic;
 	}
 
 	/**
@@ -149,13 +148,19 @@
 	 * @return New license bean if server creates a new one, otherwise the same current License bean will be returned
 	 * @throws SeCurisException
 	 */
-	public LicenseBean renew(File licenseFile) throws SeCurisException {
+	public SignedLicenseBean renew(File licenseFile) throws SeCurisException {
 		LicenseBean lic = validateLicense(licenseFile);
-		if (true) {
-			throw new SeCurisException("Action not implemented yet");
-		}
-		// TODO: Send the current LicenseBean to server to check if a new one is prepared.
-		return lic;
+
+        SignedLicenseBean newLic = ConnectionManager.getInstance().executePost(Command.RENEW_LIC, SignedLicenseBean.class, lic);
+
+		return newLic;
 	}
 
+    public void testServer() throws SeCurisException {
+        String pingMsg = ConnectionManager.getInstance().executeGet(Command.RENEW_LIC, String.class);
+        if (!PING_MESSAGE.equals(pingMsg)) {
+            throw new SeCurisException("SeCuris Server is not running in given URL");
+        }
+    }
+
 }
diff --git a/src/main/java/net/curisit/securis/beans/SignedLicenseBean.java b/src/main/java/net/curisit/securis/beans/SignedLicenseBean.java
index d6841ae..bcfcf83 100644
--- a/src/main/java/net/curisit/securis/beans/SignedLicenseBean.java
+++ b/src/main/java/net/curisit/securis/beans/SignedLicenseBean.java
@@ -10,6 +10,9 @@
 	public String getCurrentSignature() {
 		return super.getSignature();
 	}
+	
+	public SignedLicenseBean() {
+	}
 
 	public SignedLicenseBean(LicenseBean lb) {
 		super(lb);
diff --git a/src/main/java/net/curisit/securis/utils/SignatureHelper.java b/src/main/java/net/curisit/securis/utils/SignatureHelper.java
index a701a64..a23586b 100644
--- a/src/main/java/net/curisit/securis/utils/SignatureHelper.java
+++ b/src/main/java/net/curisit/securis/utils/SignatureHelper.java
@@ -18,9 +18,9 @@
 import net.curisit.securis.SeCurisException;
 import net.curisit.securis.beans.LicenseBean;
 
+import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.net.util.Base64;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
diff --git a/src/main/resources/securis-client.properties b/src/main/resources/securis-client.properties
index 87c09f2..11910d7 100644
--- a/src/main/resources/securis-client.properties
+++ b/src/main/resources/securis-client.properties
@@ -1,3 +1,3 @@
-license.server.url = https://securis.curistec.com/securis/api
-app.code = XXXX
-customer.code = XX01
+license.server.url = https://securis.curistec.com/api
+app.code = CI01
+customer.code = CT01

--
Gitblit v1.3.2