From 1435d31d363444d1785046a14929fda4db362e41 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 27 Nov 2018 10:25:21 -0500 Subject: [PATCH] Implemented guest BLOCK and ALLOW options #25 --- .../java/net/simon987/server/GameServer.java | 2 - .../net/simon987/server/web/GuestPolicy.java | 16 +++ .../net/simon987/server/web/WebServer.java | 21 ++- .../server/websocket/SocketServer.java | 120 +++++++++++------- Server/src/main/resources/config.properties | 2 + Server/src/main/resources/static/js/mar.js | 9 +- Server/src/main/typescript/GameClient.ts | 5 +- 7 files changed, 117 insertions(+), 58 deletions(-) create mode 100644 Server/src/main/java/net/simon987/server/web/GuestPolicy.java diff --git a/Server/src/main/java/net/simon987/server/GameServer.java b/Server/src/main/java/net/simon987/server/GameServer.java index aafd128..9112c44 100644 --- a/Server/src/main/java/net/simon987/server/GameServer.java +++ b/Server/src/main/java/net/simon987/server/GameServer.java @@ -160,8 +160,6 @@ public class GameServer implements Runnable { uTime = System.currentTimeMillis() - startTime; waitTime = config.getInt("tick_length") - uTime; -// LogManager.LOGGER.info("Wait time : " + waitTime + "ms | Update time: " + uTime + "ms | " + (int) (((double) uTime / waitTime) * 100) + "% load"); - try { if (waitTime >= 0) { Thread.sleep(waitTime); diff --git a/Server/src/main/java/net/simon987/server/web/GuestPolicy.java b/Server/src/main/java/net/simon987/server/web/GuestPolicy.java new file mode 100644 index 0000000..4c4f3a8 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/web/GuestPolicy.java @@ -0,0 +1,16 @@ +package net.simon987.server.web; + +public enum GuestPolicy { + /** + * Allow guests, must login to have Cubot + */ + ALLOW, + /** + * Block guests completely + */ + BLOCK, + /** + * Allow guests, can have Cubot, but it is not saved in database + */ + TEMPORARY +} diff --git a/Server/src/main/java/net/simon987/server/web/WebServer.java b/Server/src/main/java/net/simon987/server/web/WebServer.java index c8c2c76..e1d59f3 100644 --- a/Server/src/main/java/net/simon987/server/web/WebServer.java +++ b/Server/src/main/java/net/simon987/server/web/WebServer.java @@ -12,6 +12,7 @@ import java.util.Properties; public class WebServer { private SocketServer socketServer; + private GuestPolicy guestPolicy; public WebServer(ServerConfiguration config) { @@ -30,15 +31,16 @@ public class WebServer { * * Certificates generated from Let's Encrypt are usually in /etc/letsencrypt/live/www.site.com */ - Spark.secure( config.getString("keyStore_path"), config.getString("keyStore_password"), null, null); LogManager.LOGGER.info("(Web) Enabled ssl"); } + initGuestPolicy(config); + + socketServer = new SocketServer(guestPolicy); - socketServer = new SocketServer(); Spark.webSocket("/socket", socketServer); Spark.get("/", new HomePage(), templateEngine); @@ -57,7 +59,22 @@ public class WebServer { Spark.after((request, response) -> response.header("Content-Encoding", "gzip")); } + /** + * Load guest policy from config. + * If no valid policy is specified in the config, the default GuestPolicy.ALLOW is used + */ + private void initGuestPolicy(ServerConfiguration config) { + String guestPolicyStr = config.getString("guest_policy"); + try { + this.guestPolicy = GuestPolicy.valueOf(guestPolicyStr); + } catch (IllegalArgumentException | NullPointerException e) { + System.err.println("Invalid argument for guest policy: " + guestPolicyStr); + this.guestPolicy = GuestPolicy.ALLOW; + } + } + public SocketServer getSocketServer() { return socketServer; } + } diff --git a/Server/src/main/java/net/simon987/server/websocket/SocketServer.java b/Server/src/main/java/net/simon987/server/websocket/SocketServer.java index 90f5032..aea4015 100644 --- a/Server/src/main/java/net/simon987/server/websocket/SocketServer.java +++ b/Server/src/main/java/net/simon987/server/websocket/SocketServer.java @@ -4,6 +4,7 @@ import net.simon987.server.GameServer; import net.simon987.server.game.objects.ControllableUnit; import net.simon987.server.logging.LogManager; import net.simon987.server.user.User; +import net.simon987.server.web.GuestPolicy; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; @@ -24,8 +25,14 @@ public class SocketServer { private MessageDispatcher messageDispatcher = new MessageDispatcher(); private static final String AUTH_OK_MESSAGE = "{\"t\":\"auth\", \"m\":\"ok\"}"; + private static final String FORBIDDEN_MESSAGE = "{\"t\":\"auth\", \"m\":\"forbidden\"}"; + private static final int AUTH_TOKEN_LEN = 128; - public SocketServer() { + private GuestPolicy guestPolicy; + + public SocketServer(GuestPolicy guestPolicy) { + + this.guestPolicy = guestPolicy; messageDispatcher.addHandler(new UserInfoRequestHandler()); messageDispatcher.addHandler(new TerrainRequestHandler()); @@ -34,6 +41,7 @@ public class SocketServer { messageDispatcher.addHandler(new CodeRequestHandler()); messageDispatcher.addHandler(new KeypressHandler()); messageDispatcher.addHandler(new DebugCommandHandler()); + } @OnWebSocketConnect @@ -52,55 +60,62 @@ public class SocketServer { public void onMessage(Session session, String message) { OnlineUser onlineUser = onlineUserManager.getUser(session); - if (onlineUser != null) { - - if (onlineUser.isAuthenticated()) { - - messageDispatcher.dispatch(onlineUser, message); - - } else { - - LogManager.LOGGER.info("(WS) Received message from unauthenticated user " + session.getRemoteAddress().getAddress()); - if (message.length() == 128) { - - User user = GameServer.INSTANCE.getUserManager().validateAuthToken(message); - - if (user != null) { - - LogManager.LOGGER.info("(WS) User was successfully authenticated: " + user.getUsername()); - - onlineUser.setUser(user); - onlineUser.setAuthenticated(true); - - try { - session.getRemote().sendString(AUTH_OK_MESSAGE); - } catch (IOException e) { - e.printStackTrace(); - } - - } else { - - User guestUser = GameServer.INSTANCE.getGameUniverse().getOrCreateUser(GameServer.INSTANCE.getGameUniverse().getGuestUsername(), false); - onlineUser.setUser(guestUser); - onlineUser.setAuthenticated(true); - onlineUser.getUser().setGuest(true); - - LogManager.LOGGER.info("(WS) Created guest user " + - onlineUser.getUser().getUsername() + session.getRemoteAddress().getAddress()); - - try { - session.getRemote().sendString(AUTH_OK_MESSAGE); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } - - } else { - + //Shouldn't happen + if (onlineUser == null) { LogManager.LOGGER.severe("(WS) FIXME: SocketServer:onMessage"); + return; } + + //Authenticated user + if (onlineUser.isAuthenticated()) { + messageDispatcher.dispatch(onlineUser, message); + return; + } + + //Handle auth request + if (message.length() == AUTH_TOKEN_LEN) { + LogManager.LOGGER.info("(WS) Received message from unauthenticated user " + session.getRemoteAddress().getAddress()); + + User user = GameServer.INSTANCE.getUserManager().validateAuthToken(message); + + if (user != null) { + doPostAuthUser(session, onlineUser, user); + } else if (this.guestPolicy != GuestPolicy.BLOCK) { + doPostAuthGuest(session, onlineUser); + } else { + LogManager.LOGGER.info("(WS) Blocked guest user " + session.getRemoteAddress().getAddress()); + kickOnlineUser(session, onlineUser); + } + } + + //Ignore other cases + } + + private void kickOnlineUser(Session session, OnlineUser onlineUser) { + sendString(session, FORBIDDEN_MESSAGE); + session.close(); + } + + private void doPostAuthGuest(Session session, OnlineUser onlineUser) { + User guestUser = GameServer.INSTANCE.getGameUniverse().getOrCreateUser(GameServer.INSTANCE.getGameUniverse().getGuestUsername(), false); + onlineUser.setUser(guestUser); + onlineUser.setAuthenticated(true); + onlineUser.getUser().setGuest(true); + + LogManager.LOGGER.info("(WS) Created guest user " + + onlineUser.getUser().getUsername() + session.getRemoteAddress().getAddress()); + + sendString(session, AUTH_OK_MESSAGE); + } + + + private void doPostAuthUser(Session session, OnlineUser onlineUser, User user) { + LogManager.LOGGER.info("(WS) User was successfully authenticated: " + user.getUsername()); + + onlineUser.setUser(user); + onlineUser.setAuthenticated(true); + + sendString(session, AUTH_OK_MESSAGE); } /** @@ -134,6 +149,14 @@ public class SocketServer { } } + private void sendString(Session session, String message) { + try { + session.getRemote().sendString(message); + } catch (IOException e) { + e.printStackTrace(); + } + } + private void sendJSONObject(OnlineUser user, JSONObject json) { try { user.getWebSocket().getRemote().sendString((json.toJSONString())); @@ -158,7 +181,6 @@ public class SocketServer { private JSONArray intListToJSON(List ints) { JSONArray jsonInts = new JSONArray(); - jsonInts.addAll(ints); return jsonInts; diff --git a/Server/src/main/resources/config.properties b/Server/src/main/resources/config.properties index 17598c4..781ead3 100644 --- a/Server/src/main/resources/config.properties +++ b/Server/src/main/resources/config.properties @@ -9,6 +9,8 @@ keyStore_password= #Server mar_address=ws://localhost:4567/socket server_name=MAR dev +# ALLOW | TEMPORARY | BLOCK +guest_policy=ALLOW #Database mongo_dbname=mar_beta diff --git a/Server/src/main/resources/static/js/mar.js b/Server/src/main/resources/static/js/mar.js index bda0f9b..4f2ce8e 100644 --- a/Server/src/main/resources/static/js/mar.js +++ b/Server/src/main/resources/static/js/mar.js @@ -555,8 +555,9 @@ var AuthListener = (function () { console.log("[MAR] Auth successful"); } mar.client.requestUserInfo(); - } - else { + } else if (message.m == "forbidden") { + alert("Authentication failed. Guest accounts are blocked on this server"); + } else { alert("Authentication failed. Please make sure you are logged in and reload the page."); } }; @@ -712,7 +713,9 @@ var GameClient = (function () { if (DEBUG) { console.log("[MAR] Received server info " + xhr.responseText); } - setTimeout(self.connectToGameServer(JSON.parse(xhr.responseText)), 100); + setTimeout(function () { + return self.connectToGameServer(JSON.parse(xhr.responseText)); + }, 100); } }; xhr.send(null); diff --git a/Server/src/main/typescript/GameClient.ts b/Server/src/main/typescript/GameClient.ts index 5968a1c..a2f140f 100644 --- a/Server/src/main/typescript/GameClient.ts +++ b/Server/src/main/typescript/GameClient.ts @@ -134,6 +134,8 @@ class AuthListener implements MessageListener { } mar.client.requestUserInfo(); + } else if (message.m == "forbidden") { + alert("Authentication failed. Guest accounts are blocked on this server") } else { alert("Authentication failed. Please make sure you are logged in and reload the page."); } @@ -343,7 +345,6 @@ class GameClient { this.socket.send(JSON.stringify(json)); } - /** * Get server info from game website */ @@ -364,7 +365,7 @@ class GameClient { console.log("[MAR] Received server info " + xhr.responseText); } - setTimeout(self.connectToGameServer(JSON.parse(xhr.responseText)), 100); + setTimeout(() => self.connectToGameServer(JSON.parse(xhr.responseText)), 100); } }; xhr.send(null);