diff --git a/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java b/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java index 9ce4860..fdca85f 100644 --- a/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java +++ b/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java @@ -14,6 +14,7 @@ import org.samo_lego.simpleauth.commands.*; import org.samo_lego.simpleauth.event.AuthEventHandler; import org.samo_lego.simpleauth.event.entity.player.ChatCallback; import org.samo_lego.simpleauth.event.entity.player.PlayerJoinServerCallback; +import org.samo_lego.simpleauth.event.entity.player.PlayerLeaveServerCallback; import org.samo_lego.simpleauth.event.entity.player.PlayerMoveCallback; import org.samo_lego.simpleauth.event.item.DropItemCallback; import org.samo_lego.simpleauth.event.item.TakeItemCallback; @@ -38,7 +39,8 @@ public class SimpleAuth implements DedicatedServerModInitializer { // Boolean for easier checking if player is authenticated public static boolean isAuthenticated(ServerPlayerEntity player) { - return !deauthenticatedUsers.containsKey(player.getUuidAsString()); + String uuid = player.getUuidAsString(); + return !deauthenticatedUsers.containsKey(uuid); } // Getting game directory @@ -75,10 +77,12 @@ public class SimpleAuth implements DedicatedServerModInitializer { // Registering the events PlayerJoinServerCallback.EVENT.register(AuthEventHandler::onPlayerJoin); + PlayerLeaveServerCallback.EVENT.register(AuthEventHandler::onPlayerLeave); DropItemCallback.EVENT.register(AuthEventHandler::onDropItem); TakeItemCallback.EVENT.register(AuthEventHandler::onTakeItem); ChatCallback.EVENT.register(AuthEventHandler::onPlayerChat); PlayerMoveCallback.EVENT.register(AuthEventHandler::onPlayerMove); + // From Fabric API AttackBlockCallback.EVENT.register((playerEntity, world, hand, blockPos, direction) -> AuthEventHandler.onAttackBlock(playerEntity)); UseBlockCallback.EVENT.register((player, world, hand, blockHitResult) -> AuthEventHandler.onUseBlock(player)); @@ -93,6 +97,14 @@ public class SimpleAuth implements DedicatedServerModInitializer { db.close(); } + // Getting some config options + private static Text notAuthenticated() { + if(SimpleAuth.config.main.enableGlobalPassword) { + return new LiteralText(SimpleAuth.config.lang.loginRequired); + } + return new LiteralText(SimpleAuth.config.lang.notAuthenticated); + } + // Authenticates player and sends the message public static void authenticatePlayer(ServerPlayerEntity player, Text msg) { deauthenticatedUsers.remove(player.getUuidAsString()); @@ -102,19 +114,11 @@ public class SimpleAuth implements DedicatedServerModInitializer { player.sendMessage(msg); } - // Getting some config options - private static Text notAuthenticated() { - if(SimpleAuth.config.main.enableGlobalPassword) { - return new LiteralText(SimpleAuth.config.lang.loginRequired); - } - return new LiteralText(SimpleAuth.config.lang.notAuthenticated); - } - // De-authenticates player public static void deauthenticatePlayer(ServerPlayerEntity player) { // Marking player as not authenticated, (re)setting login tries to zero String uuid = player.getUuidAsString(); - SimpleAuth.deauthenticatedUsers.put(uuid, new PlayerCache(uuid)); + SimpleAuth.deauthenticatedUsers.put(uuid, new PlayerCache(uuid, player.getIp())); // Player is now not authenticated player.sendMessage(notAuthenticated()); diff --git a/src/main/java/org/samo_lego/simpleauth/commands/AuthCommand.java b/src/main/java/org/samo_lego/simpleauth/commands/AuthCommand.java index 21fa8b1..9e9db89 100644 --- a/src/main/java/org/samo_lego/simpleauth/commands/AuthCommand.java +++ b/src/main/java/org/samo_lego/simpleauth/commands/AuthCommand.java @@ -1,5 +1,6 @@ package org.samo_lego.simpleauth.commands; +import com.google.gson.JsonObject; import com.mojang.brigadier.CommandDispatcher; import net.minecraft.entity.Entity; import net.minecraft.server.command.ServerCommandSource; @@ -9,6 +10,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.samo_lego.simpleauth.SimpleAuth; import org.samo_lego.simpleauth.storage.AuthConfig; +import org.samo_lego.simpleauth.storage.PlayerCache; import org.samo_lego.simpleauth.utils.AuthHelper; import java.io.File; @@ -106,8 +108,7 @@ public class AuthCommand { private static int removeAccount(ServerCommandSource source, String uuid) { Entity sender = source.getEntity(); SimpleAuth.db.deleteUserData(uuid); - - // TODO -> Kick player that was unregistered? + SimpleAuth.deauthenticatedUsers.put(uuid, new PlayerCache(uuid, "")); if(sender != null) sender.sendMessage(userdataDeleted); @@ -121,10 +122,12 @@ public class AuthCommand { // Getting the player who send the command Entity sender = source.getEntity(); - if(SimpleAuth.db.registerUser( - uuid, - AuthHelper.hashPass(password.toCharArray()) - )) { + // JSON object holding password (may hold some other info in the future) + JsonObject playerdata = new JsonObject(); + String hash = AuthHelper.hashPass(password.toCharArray()); + playerdata.addProperty("password", hash); + + if(SimpleAuth.db.registerUser(uuid, playerdata.toString())) { if(sender != null) sender.sendMessage(userdataUpdated); else @@ -139,10 +142,12 @@ public class AuthCommand { // Getting the player who send the command Entity sender = source.getEntity(); - SimpleAuth.db.updateUserData( - uuid, - AuthHelper.hashPass(password.toCharArray()) - ); + // JSON object holding password (may hold some other info in the future) + JsonObject playerdata = new JsonObject(); + String hash = AuthHelper.hashPass(password.toCharArray()); + playerdata.addProperty("password", hash); + + SimpleAuth.db.updateUserData(uuid, playerdata.toString()); if(sender != null) sender.sendMessage(userdataUpdated); else diff --git a/src/main/java/org/samo_lego/simpleauth/commands/ChangepwCommand.java b/src/main/java/org/samo_lego/simpleauth/commands/ChangepwCommand.java index 41c7ba3..0f1d17d 100644 --- a/src/main/java/org/samo_lego/simpleauth/commands/ChangepwCommand.java +++ b/src/main/java/org/samo_lego/simpleauth/commands/ChangepwCommand.java @@ -1,5 +1,6 @@ package org.samo_lego.simpleauth.commands; +import com.google.gson.JsonObject; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.server.command.ServerCommandSource; @@ -67,10 +68,12 @@ public class ChangepwCommand { )); return 0; } - SimpleAuth.db.updateUserData( - player.getUuidAsString(), - AuthHelper.hashPass(newPass.toCharArray()) - ); + // JSON object holding password (may hold some other info in the future) + JsonObject playerdata = new JsonObject(); + String hash = AuthHelper.hashPass(newPass.toCharArray()); + playerdata.addProperty("password", hash); + + SimpleAuth.db.updateUserData(player.getUuidAsString(), playerdata.toString()); player.sendMessage(passwordUpdated); return 1; } diff --git a/src/main/java/org/samo_lego/simpleauth/commands/LoginCommand.java b/src/main/java/org/samo_lego/simpleauth/commands/LoginCommand.java index 5b7b58d..96a7ce7 100644 --- a/src/main/java/org/samo_lego/simpleauth/commands/LoginCommand.java +++ b/src/main/java/org/samo_lego/simpleauth/commands/LoginCommand.java @@ -7,7 +7,6 @@ import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.LiteralText; import net.minecraft.text.Text; import org.samo_lego.simpleauth.SimpleAuth; -import org.samo_lego.simpleauth.storage.PlayerCache; import org.samo_lego.simpleauth.utils.AuthHelper; import static com.mojang.brigadier.arguments.StringArgumentType.getString; @@ -41,6 +40,7 @@ public class LoginCommand { // Getting the player who send the command ServerPlayerEntity player = source.getPlayer(); String uuid = player.getUuidAsString(); + int passwordResult = AuthHelper.checkPass(uuid, pass.toCharArray()); if(SimpleAuth.isAuthenticated(player)) { player.sendMessage(alreadyAuthenticated); @@ -50,11 +50,11 @@ public class LoginCommand { player.networkHandler.disconnect(loginTriesExceeded); return 0; } - else if (AuthHelper.checkPass(uuid, pass.toCharArray()) == 1) { + else if(passwordResult == 1) { SimpleAuth.authenticatePlayer(player, successfullyAuthenticated); return 1; } - else if(AuthHelper.checkPass(uuid, pass.toCharArray()) == -1) { + else if(passwordResult == -1) { player.sendMessage(notRegistered); return 0; } @@ -66,7 +66,7 @@ public class LoginCommand { // Sending wrong pass message player.sendMessage(wrongPassword); // ++ the login tries - SimpleAuth.deauthenticatedUsers.getOrDefault(uuid, new PlayerCache(uuid)).loginTries += 1; + SimpleAuth.deauthenticatedUsers.get(uuid).loginTries += 1; return 0; } } diff --git a/src/main/java/org/samo_lego/simpleauth/commands/RegisterCommand.java b/src/main/java/org/samo_lego/simpleauth/commands/RegisterCommand.java index a55f798..1b55a45 100644 --- a/src/main/java/org/samo_lego/simpleauth/commands/RegisterCommand.java +++ b/src/main/java/org/samo_lego/simpleauth/commands/RegisterCommand.java @@ -1,5 +1,6 @@ package org.samo_lego.simpleauth.commands; +import com.google.gson.JsonObject; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.server.command.ServerCommandSource; @@ -62,7 +63,11 @@ public class RegisterCommand { return 0; } String hash = AuthHelper.hashPass(pass1.toCharArray()); - if (SimpleAuth.db.registerUser(player.getUuidAsString(), hash)) { + // JSON object holding password (may hold some other info in the future) + JsonObject playerdata = new JsonObject(); + playerdata.addProperty("password", hash); + + if (SimpleAuth.db.registerUser(player.getUuidAsString(), playerdata.toString())) { SimpleAuth.authenticatePlayer(player, registerSuccess); return 1; } diff --git a/src/main/java/org/samo_lego/simpleauth/storage/PlayerCache.java b/src/main/java/org/samo_lego/simpleauth/storage/PlayerCache.java index 04aba4e..a3b5a29 100644 --- a/src/main/java/org/samo_lego/simpleauth/storage/PlayerCache.java +++ b/src/main/java/org/samo_lego/simpleauth/storage/PlayerCache.java @@ -1,21 +1,29 @@ package org.samo_lego.simpleauth.storage; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import org.samo_lego.simpleauth.SimpleAuth; public class PlayerCache { public boolean isRegistered; - public boolean isAuthenticated; + public boolean wasAuthenticated; public String password; public int loginTries; + public String lastIp; + private static final JsonParser parser = new JsonParser(); - public PlayerCache(String uuid) { + + public PlayerCache(String uuid, String ip) { SimpleAuthDatabase db = SimpleAuth.db; - this.isAuthenticated = false; + this.wasAuthenticated = false; this.loginTries = 0; + this.lastIp = ip; + if(db.isUserRegistered(uuid)) { this.isRegistered = true; - this.password = db.getPassword(uuid); + JsonObject json = parser.parse(db.getData(uuid)).getAsJsonObject(); + this.password = json.get("password").getAsString(); } else { this.isRegistered = false; diff --git a/src/main/java/org/samo_lego/simpleauth/storage/SimpleAuthDatabase.java b/src/main/java/org/samo_lego/simpleauth/storage/SimpleAuthDatabase.java index fd9c300..c90f2a6 100644 --- a/src/main/java/org/samo_lego/simpleauth/storage/SimpleAuthDatabase.java +++ b/src/main/java/org/samo_lego/simpleauth/storage/SimpleAuthDatabase.java @@ -40,10 +40,10 @@ public class SimpleAuthDatabase { } // When player registers, we insert the data into DB - public boolean registerUser(String uuid, String password) { + public boolean registerUser(String uuid, String data) { try { if(!this.isUserRegistered(uuid)) { - levelDBStore.put(bytes("UUID:" + uuid), bytes("password:" + password)); + levelDBStore.put(bytes("UUID:" + uuid), bytes("data:" + data)); return true; } return false; @@ -75,17 +75,17 @@ public class SimpleAuthDatabase { // Updates the password of the user public void updateUserData(String uuid, String password) { try { - levelDBStore.put(bytes("UUID:" + uuid),bytes("password:" + password)); + levelDBStore.put(bytes("UUID:" + uuid),bytes("data:" + password)); } catch (Error e) { LOGGER.error("[SimpleAuth] " + e.getMessage()); } } // Gets the hashed password from DB - public String getPassword(String uuid){ + public String getData(String uuid){ try { if(this.isUserRegistered(uuid)) // Gets password from db and removes "password:" prefix from it - return new String(levelDBStore.get(bytes("UUID:" + uuid))).substring(9); + return new String(levelDBStore.get(bytes("UUID:" + uuid))).substring(5); } catch (Error e) { LOGGER.error("[SimpleAuth] Error getting password: " + e.getMessage()); } diff --git a/src/main/java/org/samo_lego/simpleauth/utils/AuthHelper.java b/src/main/java/org/samo_lego/simpleauth/utils/AuthHelper.java index 4d28e38..4553369 100644 --- a/src/main/java/org/samo_lego/simpleauth/utils/AuthHelper.java +++ b/src/main/java/org/samo_lego/simpleauth/utils/AuthHelper.java @@ -1,5 +1,7 @@ package org.samo_lego.simpleauth.utils; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import de.mkammerer.argon2.Argon2; import de.mkammerer.argon2.Argon2Factory; import org.apache.logging.log4j.LogManager; @@ -12,6 +14,9 @@ public class AuthHelper { // Creating the instance private static final Argon2 argon2 = Argon2Factory.create(); + // Json parser + private static final JsonParser parser = new JsonParser(); + // Returns 1 if password is correct, 0 if not // and -1 if user is not registered yet public static int checkPass(String uuid, char[] pass) { @@ -35,8 +40,11 @@ public class AuthHelper { if(SimpleAuth.deauthenticatedUsers.containsKey(uuid)) hashed = SimpleAuth.deauthenticatedUsers.get(uuid).password; // Hashed password from DB - else - hashed = SimpleAuth.db.getPassword(uuid); + else { + JsonObject json = parser.parse(SimpleAuth.db.getData(uuid)).getAsJsonObject(); + hashed = json.get("password").getAsString(); + } + if(hashed.equals("")) return -1; // User is not yet registered // Verify password