From c056ae1937d8bbf4023f43f43c7f0331e9b6a35e Mon Sep 17 00:00:00 2001
From: Daniel Gerhardt <code@dgerhardt.net>
Date: Tue, 12 Jul 2016 17:25:07 +0200
Subject: [PATCH] Add proxy support for WebSocket connections

Configuration for Socket.IO has been refactored to support proxies and
replace ambiguous property names:
* Added API property `socketioPath` to `/configuration/`
* Added property `socketio.proxy-path`
* Removed property `security.ssl`
* Renamed properties:
  * `socketio.ip` -> `socketio.bind-address`
  * `security.keystore` -> `socketio.ssl.jks-file`
  * `security.storepass` -> `socketio.ssl.jks-password`

The default port to bind to has been changed from 10443 to 8090 since
SSL is not enabled by default. There is enough room (8081-8089) for
additional severs (e.g. `grunt run`) in development environments.
---
 .../de/thm/arsnova/config/ExtraConfig.java    | 19 +++++++++----------
 .../controller/ConfigurationController.java   |  7 +++++++
 src/main/resources/arsnova.properties.example | 17 ++++++++++-------
 src/test/resources/arsnova.properties.example | 17 ++++++++++-------
 src/test/resources/test-socketioconfig.xml    |  4 ++--
 5 files changed, 38 insertions(+), 26 deletions(-)

diff --git a/src/main/java/de/thm/arsnova/config/ExtraConfig.java b/src/main/java/de/thm/arsnova/config/ExtraConfig.java
index 367a29e5..d61e4a8f 100644
--- a/src/main/java/de/thm/arsnova/config/ExtraConfig.java
+++ b/src/main/java/de/thm/arsnova/config/ExtraConfig.java
@@ -59,11 +59,10 @@ public class ExtraConfig extends WebMvcConfigurerAdapter {
 	@Value(value = "${connector.username}") private String connectorUsername;
 	@Value(value = "${connector.password}") private String connectorPassword;
 
-	@Value(value = "${socketio.ip}") private String socketIp;
+	@Value(value = "${socketio.bind-address}") private String socketAddress;
 	@Value(value = "${socketio.port}") private int socketPort;
-	@Value(value = "${security.ssl}") private boolean socketUseSll;
-	@Value(value = "${security.keystore}") private String socketKeystore;
-	@Value(value = "${security.storepass}") private String socketStorepass;
+	@Value(value = "${socketio.ssl.jks-file:}") private String socketKeystore;
+	@Value(value = "${socketio.ssl.jks-password:}") private String socketKeystorePassword;
 	@Value(value = "${security.cors.origins:}") private String[] corsOrigins;
 
 	private static int testPortOffset = 0;
@@ -110,11 +109,11 @@ public class ExtraConfig extends WebMvcConfigurerAdapter {
 	@Bean(name = "socketServer", initMethod = "startServer", destroyMethod = "stopServer")
 	public ARSnovaSocket socketServer() {
 		final ARSnovaSocketIOServer socketServer = new ARSnovaSocketIOServer();
-		socketServer.setHostIp(socketIp);
+		socketServer.setHostIp(socketAddress);
 		socketServer.setPortNumber(socketPort);
-		socketServer.setUseSSL(socketUseSll);
+		socketServer.setUseSSL(!socketKeystore.isEmpty());
 		socketServer.setKeystore(socketKeystore);
-		socketServer.setStorepass(socketStorepass);
+		socketServer.setStorepass(socketKeystorePassword);
 		return socketServer;
 	}
 
@@ -123,11 +122,11 @@ public class ExtraConfig extends WebMvcConfigurerAdapter {
 	public ARSnovaSocket socketTestServer() {
 		final int testSocketPort = 1234 + testPortOffset++ % 10;
 		final ARSnovaSocketIOServer socketServer = new ARSnovaSocketIOServer();
-		socketServer.setHostIp(socketIp);
+		socketServer.setHostIp(socketAddress);
 		socketServer.setPortNumber(socketPort + testSocketPort);
-		socketServer.setUseSSL(socketUseSll);
+		socketServer.setUseSSL(!socketKeystore.isEmpty());
 		socketServer.setKeystore(socketKeystore);
-		socketServer.setStorepass(socketStorepass);
+		socketServer.setStorepass(socketKeystorePassword);
 		return socketServer;
 	}
 
diff --git a/src/main/java/de/thm/arsnova/controller/ConfigurationController.java b/src/main/java/de/thm/arsnova/controller/ConfigurationController.java
index 0783751b..0c35ae6a 100644
--- a/src/main/java/de/thm/arsnova/controller/ConfigurationController.java
+++ b/src/main/java/de/thm/arsnova/controller/ConfigurationController.java
@@ -42,6 +42,9 @@ public class ConfigurationController extends AbstractController {
 	@Value("${api.path:}")
 	private String apiPath;
 
+	@Value("${socketio.proxy-path:}")
+	private String socketioPath;
+
 	@Value("${customization.path}")
 	private String customizationPath;
 
@@ -167,6 +170,10 @@ public class ConfigurationController extends AbstractController {
 		}
 		config.put("apiPath", apiPath);
 
+
+		if (!"".equals(socketioPath)) {
+			config.put("socketioPath", socketioPath);
+		}
 		if (!"".equals(customizationPath)) {
 			config.put("customizationPath", customizationPath);
 		}
diff --git a/src/main/resources/arsnova.properties.example b/src/main/resources/arsnova.properties.example
index 7e735899..12d799d6 100644
--- a/src/main/resources/arsnova.properties.example
+++ b/src/main/resources/arsnova.properties.example
@@ -15,14 +15,17 @@ customization.path=/customization
 mobile.path=/mobile
 presenter.path=/presenter
 
-# SSL configuration
-security.ssl=false
-security.keystore=/etc/arsnova/arsnova.jks
-security.storepass=arsnova
-
 # WebSockets server
-socketio.ip=0.0.0.0
-socketio.port=10443
+socketio.bind-address=localhost
+socketio.port=8090
+# SSL/TLS configuration
+# To enable SSL for Socket.IO you have to import your key and certificate files into a Java Key Store. If you tunnel
+# WebSocket connections through a proxy server, you can skip this configuration.
+# See https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html
+#
+#socketio.ssl.jks-file=/etc/arsnova/arsnova.jks
+#socketio.ssl.jks-password=arsnova
+#socketio.proxy-path=/socket.io
 
 # Admin accounts
 # Usernames of the accounts which are allowed to manage global messages of the
diff --git a/src/test/resources/arsnova.properties.example b/src/test/resources/arsnova.properties.example
index 7e735899..12d799d6 100644
--- a/src/test/resources/arsnova.properties.example
+++ b/src/test/resources/arsnova.properties.example
@@ -15,14 +15,17 @@ customization.path=/customization
 mobile.path=/mobile
 presenter.path=/presenter
 
-# SSL configuration
-security.ssl=false
-security.keystore=/etc/arsnova/arsnova.jks
-security.storepass=arsnova
-
 # WebSockets server
-socketio.ip=0.0.0.0
-socketio.port=10443
+socketio.bind-address=localhost
+socketio.port=8090
+# SSL/TLS configuration
+# To enable SSL for Socket.IO you have to import your key and certificate files into a Java Key Store. If you tunnel
+# WebSocket connections through a proxy server, you can skip this configuration.
+# See https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html
+#
+#socketio.ssl.jks-file=/etc/arsnova/arsnova.jks
+#socketio.ssl.jks-password=arsnova
+#socketio.proxy-path=/socket.io
 
 # Admin accounts
 # Usernames of the accounts which are allowed to manage global messages of the
diff --git a/src/test/resources/test-socketioconfig.xml b/src/test/resources/test-socketioconfig.xml
index 27d91124..00a2df36 100644
--- a/src/test/resources/test-socketioconfig.xml
+++ b/src/test/resources/test-socketioconfig.xml
@@ -6,6 +6,6 @@
 
 	<bean id="socketServer" class="de.thm.arsnova.socket.ARSnovaSocketIOServer"
 		init-method="startServer" destroy-method="stopServer" scope="singleton"
-		p:portNumber="11443" p:hostIp="${socketio.ip}" p:useSSL="${security.ssl}" p:keystore="${security.keystore}"
-		p:storepass="${security.storepass}" />
+		p:portNumber="11443" p:hostIp="localhost" p:useSSL="false" p:keystore=""
+		p:storepass="" />
 </beans>
-- 
GitLab