mirror of
https://github.com/simon987/Much-Assembly-Required.git
synced 2025-04-18 18:26:42 +00:00
Websocket auth up and running
This commit is contained in:
parent
dc034d1437
commit
113aa50d87
@ -6,6 +6,7 @@ import net.simon987.server.web.AlertMessage;
|
||||
import net.simon987.server.web.AlertType;
|
||||
import net.simon987.server.websocket.SocketServer;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.json.simple.JSONObject;
|
||||
import spark.ModelAndView;
|
||||
import spark.Spark;
|
||||
import spark.template.velocity.VelocityTemplateEngine;
|
||||
@ -153,11 +154,52 @@ public class Main {
|
||||
request.session().attribute("messages", messages);
|
||||
}
|
||||
|
||||
|
||||
response.redirect("/account");
|
||||
return null;
|
||||
});
|
||||
|
||||
Spark.get("/server_info", (request, response) -> {
|
||||
|
||||
//TODO put that in a constructor somewhere
|
||||
String address;
|
||||
if (GameServer.INSTANCE.getConfig().getInt("use_ssl") == 0) {
|
||||
address = "ws://" +
|
||||
GameServer.INSTANCE.getConfig().getString("mar_address") + ":" +
|
||||
GameServer.INSTANCE.getConfig().getString("mar_port") + "/socket";
|
||||
} else {
|
||||
address = "wss://" +
|
||||
GameServer.INSTANCE.getConfig().getString("mar_address") + ":" +
|
||||
GameServer.INSTANCE.getConfig().getString("mar_port") + "/socket";
|
||||
}
|
||||
String serverName = GameServer.INSTANCE.getConfig().getString("server_name");
|
||||
int tickLength = GameServer.INSTANCE.getConfig().getInt("tick_length");
|
||||
|
||||
JSONObject json = new JSONObject();
|
||||
|
||||
String username = request.session().attribute("username");
|
||||
|
||||
if (username != null) {
|
||||
String token = GameServer.INSTANCE.getUserManager().generateAndGetToken(username);
|
||||
|
||||
json.put("token", token);
|
||||
json.put("username", username);
|
||||
|
||||
} else {
|
||||
|
||||
json.put("token", "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
|
||||
json.put("username", "guest");
|
||||
}
|
||||
|
||||
json.put("address", address);
|
||||
json.put("serverName", serverName);
|
||||
json.put("tickLength", tickLength);
|
||||
|
||||
response.header("Content-Type", "application/json");
|
||||
|
||||
return json.toJSONString();
|
||||
|
||||
});
|
||||
|
||||
Spark.after((request, response) -> response.header("Content-Encoding", "gzip"));
|
||||
}
|
||||
|
||||
|
@ -23,10 +23,10 @@ public class RandomStringGenerator {
|
||||
return new String(buf);
|
||||
}
|
||||
|
||||
public static final String UPPER_ALPHA_CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
public static final String LOWER_ALPHA_CHARSET = UPPER_ALPHA_CHARSET.toLowerCase(Locale.ROOT);
|
||||
public static final String NUMERIC_CHARSET = "0123456789";
|
||||
public static final String ALPHANUMERIC_CHARSET = UPPER_ALPHA_CHARSET + LOWER_ALPHA_CHARSET + NUMERIC_CHARSET;
|
||||
static final String UPPER_ALPHA_CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
static final String LOWER_ALPHA_CHARSET = UPPER_ALPHA_CHARSET.toLowerCase(Locale.ROOT);
|
||||
static final String NUMERIC_CHARSET = "0123456789";
|
||||
static final String ALPHANUMERIC_CHARSET = UPPER_ALPHA_CHARSET + LOWER_ALPHA_CHARSET + NUMERIC_CHARSET;
|
||||
|
||||
private final Random random;
|
||||
|
||||
|
@ -19,12 +19,14 @@ public class User implements MongoSerialisable {
|
||||
|
||||
private String userCode;
|
||||
private String password;
|
||||
private String accessToken;
|
||||
|
||||
private CPU cpu;
|
||||
|
||||
private ControllableUnit controlledUnit;
|
||||
|
||||
private boolean guest;
|
||||
private boolean guest = false;
|
||||
private boolean moderator = false;
|
||||
|
||||
public User() throws CancelledException {
|
||||
GameEvent event = new UserCreationEvent(this);
|
||||
@ -33,7 +35,6 @@ public class User implements MongoSerialisable {
|
||||
throw new CancelledException();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public User(ControllableUnit unit) {
|
||||
@ -51,6 +52,7 @@ public class User implements MongoSerialisable {
|
||||
dbObject.put("controlledUnit", controlledUnit.getObjectId());
|
||||
dbObject.put("cpu", cpu.mongoSerialise());
|
||||
dbObject.put("password", password);
|
||||
dbObject.put("moderator", moderator);
|
||||
|
||||
return dbObject;
|
||||
|
||||
@ -62,6 +64,7 @@ public class User implements MongoSerialisable {
|
||||
user.username = (String) obj.get("username");
|
||||
user.userCode = (String) obj.get("code");
|
||||
user.password = (String) obj.get("password");
|
||||
user.moderator = (boolean) obj.get("moderator");
|
||||
|
||||
user.getControlledUnit().setParent(user);
|
||||
|
||||
@ -114,4 +117,20 @@ public class User implements MongoSerialisable {
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public boolean isModerator() {
|
||||
return moderator;
|
||||
}
|
||||
|
||||
public void setModerator(boolean moderator) {
|
||||
this.moderator = moderator;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package net.simon987.server.user;
|
||||
import com.mongodb.*;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.exception.CancelledException;
|
||||
import net.simon987.server.crypto.RandomStringGenerator;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import org.springframework.security.crypto.bcrypt.BCrypt;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -91,4 +93,42 @@ public class UserManager {
|
||||
|
||||
userCollection.save(user.mongoSerialise()); //Save new password immediately
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and save a access token for websocket auth
|
||||
*
|
||||
* @param username Username
|
||||
* @return The generated token
|
||||
*/
|
||||
public String generateAndGetToken(String username) {
|
||||
|
||||
User user = GameServer.INSTANCE.getGameUniverse().getUser(username);
|
||||
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
RandomStringGenerator generator = new RandomStringGenerator(128);
|
||||
String token = generator.nextString();
|
||||
|
||||
user.setAccessToken(token);
|
||||
|
||||
LogManager.LOGGER.fine("(Web) Generated access token for " + username);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
public User validateAuthToken(String token) {
|
||||
|
||||
for (User user : GameServer.INSTANCE.getGameUniverse().getUsers()) {
|
||||
|
||||
if (user.getAccessToken().equals(token)) {
|
||||
user.setAccessToken("");
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ public class CodeRequestHandler implements MessageHandler {
|
||||
|
||||
LogManager.LOGGER.fine("(WS) Code request from " + user.getUser().getUsername());
|
||||
|
||||
if (user.isGuest()) {
|
||||
if (user.getUser().isGuest()) {
|
||||
|
||||
JSONObject response = new JSONObject();
|
||||
|
||||
|
@ -16,7 +16,7 @@ public class CodeUploadHandler implements MessageHandler {
|
||||
|
||||
LogManager.LOGGER.fine("(WS) Code upload from " + user.getUser().getUsername());
|
||||
|
||||
if (user.isGuest()) {
|
||||
if (user.getUser().isGuest()) {
|
||||
//Ignore
|
||||
|
||||
} else {
|
||||
|
@ -10,7 +10,7 @@ public class DebugCommandHandler implements MessageHandler {
|
||||
public void handle(OnlineUser user, JSONObject json) {
|
||||
|
||||
|
||||
if (json.get("t").equals("debug") && user.isModerator()) {
|
||||
if (json.get("t").equals("debug") && user.getUser().isModerator()) {
|
||||
|
||||
DebugCommandEvent e = new DebugCommandEvent(json, user);
|
||||
GameServer.INSTANCE.getEventDispatcher().dispatch(e); //Ignore cancellation
|
||||
|
@ -15,7 +15,7 @@ public class FloppyHandler implements MessageHandler {
|
||||
|
||||
LogManager.LOGGER.fine("(WS) Floppy download request from " + user.getUser().getUsername());
|
||||
|
||||
if (user.isGuest()) {
|
||||
if (user.getUser().isGuest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ public class KeypressHandler implements MessageHandler {
|
||||
@Override
|
||||
public void handle(OnlineUser user, JSONObject json) {
|
||||
|
||||
if (!user.isGuest()) {
|
||||
if (!user.getUser().isGuest()) {
|
||||
if (json.get("t").equals("k")) {
|
||||
|
||||
//LogManager.LOGGER.fine("(WS) Received keypress");
|
||||
|
@ -10,10 +10,6 @@ public class OnlineUser {
|
||||
|
||||
private Session webSocket;
|
||||
|
||||
private boolean guest;
|
||||
|
||||
private boolean moderator;
|
||||
|
||||
/**
|
||||
* Associated game user (if authenticated)
|
||||
*/
|
||||
@ -44,20 +40,4 @@ public class OnlineUser {
|
||||
this.authenticated = authenticated;
|
||||
}
|
||||
|
||||
public void setGuest(boolean guest) {
|
||||
this.guest = guest;
|
||||
user.setGuest(guest);
|
||||
}
|
||||
|
||||
public boolean isGuest() {
|
||||
return guest;
|
||||
}
|
||||
|
||||
public boolean isModerator() {
|
||||
return moderator;
|
||||
}
|
||||
|
||||
public void setModerator(boolean moderator) {
|
||||
this.moderator = moderator;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
package net.simon987.server.websocket;
|
||||
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.game.ControllableUnit;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.user.User;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
|
||||
@ -57,14 +59,46 @@ public class SocketServer {
|
||||
} else {
|
||||
|
||||
LogManager.LOGGER.info("(WS) Received message from unauthenticated user " + session.getRemoteAddress());
|
||||
//todo
|
||||
|
||||
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("{\"t\":\"auth\", \"m\":\"ok\"}");
|
||||
} 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());
|
||||
|
||||
try {
|
||||
session.getRemote().sendString("{\"t\":\"auth\", \"m\":\"ok\"}");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
LogManager.LOGGER.severe("(WS) FIXME: SocketServer:onMessage");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,7 +115,7 @@ public class SocketServer {
|
||||
|
||||
if (user.getWebSocket().isOpen()) {
|
||||
|
||||
if (user.isGuest()) {
|
||||
if (user.getUser().isGuest()) {
|
||||
|
||||
json.remove("c");
|
||||
try {
|
||||
|
@ -18,7 +18,7 @@ public class UserInfoRequestHandler implements MessageHandler {
|
||||
LogManager.LOGGER.fine("(WS) User info request from " + user.getUser().getUsername());
|
||||
JSONObject json = new JSONObject();
|
||||
|
||||
if (user.isGuest()) {
|
||||
if (user.getUser().isGuest()) {
|
||||
json.put("worldX", GameServer.INSTANCE.getConfig().getInt("new_user_worldX"));
|
||||
json.put("worldY", GameServer.INSTANCE.getConfig().getInt("new_user_worldY"));
|
||||
json.put("dimension", GameServer.INSTANCE.getConfig().getString("new_user_dimension"));
|
||||
|
@ -8,12 +8,11 @@ mysql_url=jdbc:mysql://localhost:3306/mar?useSSL=false
|
||||
save_interval=5
|
||||
log_limit=2000000
|
||||
log_count=10
|
||||
# Web server port
|
||||
webSocket_port=8887
|
||||
webSocket_host=0.0.0.0
|
||||
|
||||
use_secure_webSocket=0
|
||||
use_ssl=0
|
||||
cert_path=certificates
|
||||
mar_port=4567
|
||||
mar_address=localhost
|
||||
server_name=Official MAR server
|
||||
# ----------------------------------------------
|
||||
|
||||
# Length of a tick in ms
|
||||
@ -86,7 +85,6 @@ wg_minCopperCount=0
|
||||
# Maximum copper tile count for the WorldGenerator
|
||||
wg_maxCopperCount=2
|
||||
|
||||
|
||||
# ----------------------------------------------
|
||||
# Maximum execution time of user code in ms
|
||||
user_timeout=100
|
||||
|
@ -695,7 +695,7 @@ var GameClient = (function () {
|
||||
console.log("[MAR] Getting server info... ");
|
||||
}
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "./getServerInfo.php", true);
|
||||
xhr.open("GET", "./server_info", true);
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
if (DEBUG) {
|
||||
|
@ -374,7 +374,7 @@ class GameClient {
|
||||
}
|
||||
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "./getServerInfo.php", true);
|
||||
xhr.open("GET", "./server_info", true);
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user