From 48dd9ce00b45073699104cfe1d45e3a8ff2d2edc Mon Sep 17 00:00:00 2001 From: samo_lego <34912839+samolego@users.noreply.github.com> Date: Sat, 7 Nov 2020 17:55:21 +0100 Subject: [PATCH] Saving changes, password results now in enum --- .../simpleauth/commands/AccountCommand.java | 4 +- .../simpleauth/commands/AuthCommand.java | 14 ++-- .../simpleauth/commands/LoginCommand.java | 6 +- .../simpleauth/commands/RegisterCommand.java | 3 +- .../mixin/MixinServerPlayerEntity.java | 12 ++- .../simpleauth/storage/PlayerCache.java | 80 ++++++------------- .../simpleauth/storage/database/LevelDB.java | 5 +- .../simpleauth/utils/AuthHelper.java | 22 ++--- 8 files changed, 53 insertions(+), 93 deletions(-) diff --git a/src/main/java/org/samo_lego/simpleauth/commands/AccountCommand.java b/src/main/java/org/samo_lego/simpleauth/commands/AccountCommand.java index 37b1903..c5ed294 100644 --- a/src/main/java/org/samo_lego/simpleauth/commands/AccountCommand.java +++ b/src/main/java/org/samo_lego/simpleauth/commands/AccountCommand.java @@ -71,7 +71,7 @@ public class AccountCommand { // Different thread to avoid lag spikes THREADPOOL.submit(() -> { - if (AuthHelper.checkPassword(((PlayerAuth) player).getFakeUuid(), pass.toCharArray()) == 1) { + if (AuthHelper.checkPassword(((PlayerAuth) player).getFakeUuid(), pass.toCharArray()) == AuthHelper.PasswordOptions.CORRECT) { DB.deleteUserData(((PlayerAuth) player).getFakeUuid()); player.sendMessage(new LiteralText(config.lang.accountDeleted), false); ((PlayerAuth) player).setAuthenticated(false); @@ -99,7 +99,7 @@ public class AccountCommand { } // Different thread to avoid lag spikes THREADPOOL.submit(() -> { - if (AuthHelper.checkPassword(((PlayerAuth) player).getFakeUuid(), oldPass.toCharArray()) == 1) { + if (AuthHelper.checkPassword(((PlayerAuth) player).getFakeUuid(), oldPass.toCharArray()) == AuthHelper.PasswordOptions.CORRECT) { if (newPass.length() < config.main.minPasswordChars) { player.sendMessage(new LiteralText( String.format(config.lang.minPasswordChars, config.main.minPasswordChars) 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 25b9cd0..ee83666 100644 --- a/src/main/java/org/samo_lego/simpleauth/commands/AuthCommand.java +++ b/src/main/java/org/samo_lego/simpleauth/commands/AuthCommand.java @@ -9,7 +9,6 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.LiteralText; import net.minecraft.util.Identifier; -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; @@ -93,7 +92,7 @@ public class AuthCommand { .then(literal("update") .then(argument("uuid", word()) .then(argument("password", word()) - .executes( ctx -> updatePass( + .executes( ctx -> updatePassword( ctx.getSource(), getString(ctx, "uuid"), getString(ctx, "password") @@ -188,7 +187,7 @@ public class AuthCommand { Entity sender = source.getEntity(); THREADPOOL.submit(() -> { DB.deleteUserData(uuid); - SimpleAuth.playerCacheMap.put(uuid, new PlayerCache(null)); + playerCacheMap.put(uuid, null); }); if(sender != null) @@ -216,12 +215,11 @@ public class AuthCommand { playerCache = playerCacheMap.get(uuid); } else { - playerCache = new PlayerCache(null); + playerCache = PlayerCache.fromJson(null, uuid); } playerCacheMap.put(uuid, playerCache); playerCacheMap.get(uuid).password = AuthHelper.hashPassword(password.toCharArray()); - playerCacheMap.get(uuid).isRegistered = true; if (sender != null) ((PlayerEntity) sender).sendMessage(new LiteralText(config.lang.userdataUpdated), false); @@ -239,7 +237,7 @@ public class AuthCommand { * @param password new password for the player * @return 0 */ - private static int updatePass(ServerCommandSource source, String uuid, String password) { + private static int updatePassword(ServerCommandSource source, String uuid, String password) { // Getting the player who send the command Entity sender = source.getEntity(); @@ -249,11 +247,11 @@ public class AuthCommand { playerCache = playerCacheMap.get(uuid); } else { - playerCache = new PlayerCache(null); + playerCache = PlayerCache.fromJson(null, uuid); } playerCacheMap.put(uuid, playerCache); - if(!playerCacheMap.get(uuid).isRegistered) { + if(!playerCacheMap.get(uuid).password.isEmpty()) { if (sender != null) ((PlayerEntity) sender).sendMessage(new LiteralText(config.lang.userNotRegistered), false); else 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 3374865..5571c2a 100644 --- a/src/main/java/org/samo_lego/simpleauth/commands/LoginCommand.java +++ b/src/main/java/org/samo_lego/simpleauth/commands/LoginCommand.java @@ -40,18 +40,18 @@ public class LoginCommand { // Putting rest of the command in different thread to avoid lag spikes THREADPOOL.submit(() -> { int maxLoginTries = config.main.maxLoginTries; - int passwordResult = AuthHelper.checkPassword(uuid, pass.toCharArray()); + AuthHelper.PasswordOptions passwordResult = AuthHelper.checkPassword(uuid, pass.toCharArray()); if(playerCacheMap.get(uuid).loginTries >= maxLoginTries && maxLoginTries != -1) { player.networkHandler.disconnect(new LiteralText(config.lang.loginTriesExceeded)); return; } - else if(passwordResult == 1) { + else if(passwordResult == AuthHelper.PasswordOptions.CORRECT) { player.sendMessage(new LiteralText(config.lang.successfullyAuthenticated), false); ((PlayerAuth) player).setAuthenticated(true); return; } - else if(passwordResult == -1) { + else if(passwordResult == AuthHelper.PasswordOptions.NOT_REGISTERED) { player.sendMessage(new LiteralText(config.lang.registerRequired), false); return; } 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 dd293c9..0ff9373 100644 --- a/src/main/java/org/samo_lego/simpleauth/commands/RegisterCommand.java +++ b/src/main/java/org/samo_lego/simpleauth/commands/RegisterCommand.java @@ -63,12 +63,11 @@ public class RegisterCommand { } PlayerCache playerCache = playerCacheMap.get(((PlayerAuth) player).getFakeUuid()); - if (!playerCache.isRegistered) { + if (playerCache.password.isEmpty()) { ((PlayerAuth) player).setAuthenticated(true); player.sendMessage(new LiteralText(config.lang.registerSuccess), false); playerCache.password = hashPassword(pass1.toCharArray()); - playerCache.isRegistered = true; return; } player.sendMessage(new LiteralText(config.lang.alreadyRegistered), false); diff --git a/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerPlayerEntity.java b/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerPlayerEntity.java index 753db51..2117ee2 100644 --- a/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerPlayerEntity.java +++ b/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerPlayerEntity.java @@ -11,7 +11,6 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.RegistryKey; import net.minecraft.world.World; -import org.samo_lego.simpleauth.SimpleAuth; import org.samo_lego.simpleauth.storage.PlayerCache; import org.samo_lego.simpleauth.utils.PlayerAuth; import org.spongepowered.asm.mixin.Final; @@ -92,14 +91,13 @@ public class MixinServerPlayerEntity implements PlayerAuth { public String getFakeUuid() { // If server is in online mode online-mode UUIDs should be used assert server != null; - if(server.isOnlineMode() && this.isUsingMojangAccount()) + if(server.isOnlineMode() && this.isUsingMojangAccount() && !config.experimental.forceoOfflineUuids) return player.getUuidAsString(); /* Lower case is used for Player and PlAyEr to get same UUID (for password storing) Mimicking Mojang behaviour, where players cannot set their name to ExAmple if Example is already taken. */ - // Getting player+s name via GameProfile, in order to be compatible with Drogtor mod String playername = player.getGameProfile().getName().toLowerCase(); return PlayerEntity.getOfflinePlayerUuid(playername).toString(); @@ -116,7 +114,7 @@ public class MixinServerPlayerEntity implements PlayerAuth { if(!playerCacheMap.containsKey(this.getFakeUuid())) { // First join - playerCache = new PlayerCache(this.getFakeUuid(), player); + playerCache = PlayerCache.fromJson(player, this.getFakeUuid()); playerCacheMap.put(this.getFakeUuid(), playerCache); } else { @@ -157,12 +155,12 @@ public class MixinServerPlayerEntity implements PlayerAuth { @Override public Text getAuthMessage() { final PlayerCache cache = playerCacheMap.get(((PlayerAuth) player).getFakeUuid()); - if(SimpleAuth.config.main.enableGlobalPassword || cache.isRegistered) + if(!config.main.enableGlobalPassword && cache.password.isEmpty()) return new LiteralText( - SimpleAuth.config.lang.notAuthenticated + "\n" + SimpleAuth.config.lang.loginRequired + config.lang.notAuthenticated+ "\n" + config.lang.registerRequired ); return new LiteralText( - SimpleAuth.config.lang.notAuthenticated+ "\n" + SimpleAuth.config.lang.registerRequired + config.lang.notAuthenticated + "\n" + config.lang.loginRequired ); } 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 b489a27..e792e82 100644 --- a/src/main/java/org/samo_lego/simpleauth/storage/PlayerCache.java +++ b/src/main/java/org/samo_lego/simpleauth/storage/PlayerCache.java @@ -1,7 +1,8 @@ package org.samo_lego.simpleauth.storage; import com.google.gson.Gson; -import com.google.gson.JsonObject; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.Expose; import net.minecraft.block.Blocks; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; @@ -9,6 +10,7 @@ import net.minecraft.util.math.Vec3d; import java.util.Objects; +import static org.samo_lego.simpleauth.SimpleAuth.DB; import static org.samo_lego.simpleauth.SimpleAuth.config; import static org.samo_lego.simpleauth.utils.SimpleLogger.logInfo; @@ -16,37 +18,37 @@ import static org.samo_lego.simpleauth.utils.SimpleLogger.logInfo; * Class used for storing the non-authenticated player's cache */ public class PlayerCache { - /** - * Whether player is registered. - */ - public boolean isRegistered; /** * Whether player is authenticated. * Used for {@link org.samo_lego.simpleauth.event.AuthEventHandler#onPlayerJoin(ServerPlayerEntity) session validation}. */ - public boolean isAuthenticated; + @Expose + public boolean isAuthenticated = false; /** * Hashed password of player. */ - public String password; + @Expose + public String password = ""; /** * Stores how many times player has tried to login. */ - public int loginTries; + public int loginTries = 0; /** * Last recorded IP of player. * Used for {@link org.samo_lego.simpleauth.event.AuthEventHandler#onPlayerJoin(ServerPlayerEntity) sessions}. */ + @Expose public String lastIp; /** * Time until session is valid. */ + @Expose public long validUntil; /** * Player stats before de-authentication. */ - public boolean wasInPortal; + public boolean wasInPortal = false; /** * Last recorded position before de-authentication. @@ -61,7 +63,9 @@ public class PlayerCache { public final PlayerCache.LastLocation lastLocation = new PlayerCache.LastLocation(); - private static final Gson gson = new Gson(); + private static final Gson gson = new GsonBuilder() + .excludeFieldsWithoutExposeAnnotation() + .create(); /** * Creates an empty cache for player (when player doesn't exist in DB). @@ -69,11 +73,6 @@ public class PlayerCache { * @param player player to create cache for */ public PlayerCache(ServerPlayerEntity player) { - if(config.experimental.debugMode) - logInfo("Creating cache for " + Objects.requireNonNull(player).getName()); - this.isAuthenticated = false; - this.loginTries = 0; - if(player != null) { this.lastIp = player.getIp(); @@ -85,57 +84,24 @@ public class PlayerCache { this.wasInPortal = player.getBlockState().getBlock().equals(Blocks.NETHER_PORTAL); } - else { - this.wasInPortal = false; - } - - this.isRegistered = false; - this.password = ""; - - if(config.experimental.debugMode) - logInfo("New player cache created."); } - public static PlayerCache fromJson(ServerPlayerEntity player, String json) { + public static PlayerCache fromJson(ServerPlayerEntity player, String fakeUuid) { if(config.experimental.debugMode) - logInfo("Creating cache for " + Objects.requireNonNull(player).getName()); + logInfo("Creating cache for " + Objects.requireNonNull(player).getGameProfile().getName()); - // Parsing data from DB - PlayerCache playerCache = gson.fromJson(json, PlayerCache.class); + PlayerCache playerCache = new PlayerCache(player);; - playerCache.loginTries = 0; - playerCache.isAuthenticated = false; - - if(playerCache.password != null && !playerCache.password.isEmpty()) { - playerCache.isRegistered = true; - } - else { - // Not registered - playerCache.isRegistered = false; - playerCache.password = ""; - } - if(player != null) { - playerCache.lastIp = player.getIp(); - - playerCache.wasInPortal = player.getBlockState().getBlock().equals(Blocks.NETHER_PORTAL); - - // Setting position cache - playerCache.lastLocation.dimension = player.getServerWorld(); - playerCache.lastLocation.position = player.getPos(); - playerCache.lastLocation.yaw = player.yaw; - playerCache.lastLocation.pitch = player.pitch; - } - else { - playerCache.wasInPortal = false; + String json = DB.getUserData(fakeUuid); + if(!json.isEmpty()) { + // Parsing data from DB + playerCache = gson.fromJson(json, PlayerCache.class); } return playerCache; } - public JsonObject toJson() { - JsonObject cacheJson = new JsonObject(); - cacheJson.addProperty("password", this.password); - - return cacheJson; + public String toJson() { + return gson.toJson(this); } } diff --git a/src/main/java/org/samo_lego/simpleauth/storage/database/LevelDB.java b/src/main/java/org/samo_lego/simpleauth/storage/database/LevelDB.java index b0cbc06..7430bc2 100644 --- a/src/main/java/org/samo_lego/simpleauth/storage/database/LevelDB.java +++ b/src/main/java/org/samo_lego/simpleauth/storage/database/LevelDB.java @@ -1,6 +1,5 @@ package org.samo_lego.simpleauth.storage.database; -import com.google.gson.JsonObject; import org.iq80.leveldb.DB; import org.iq80.leveldb.DBException; import org.iq80.leveldb.Options; @@ -140,8 +139,8 @@ public class LevelDB { WriteBatch batch = levelDBStore.createWriteBatch(); // Updating player data. playerCacheMap.forEach((uuid, playerCache) -> { - JsonObject data = playerCache.toJson(); - batch.put(bytes("UUID:" + uuid), bytes("data:" + data.toString())); + String data = playerCache.toJson(); + batch.put(bytes("UUID:" + uuid), bytes("data:" + data)); }); try { // Writing and closing batch 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 1eaa013..301f786 100644 --- a/src/main/java/org/samo_lego/simpleauth/utils/AuthHelper.java +++ b/src/main/java/org/samo_lego/simpleauth/utils/AuthHelper.java @@ -14,24 +14,18 @@ public class AuthHelper { * @param password password that needs to be checked * @return 1 for pass, 0 if password is false, -1 if user is not yet registered */ - public static int checkPassword(String uuid, char[] password) { + public static PasswordOptions checkPassword(String uuid, char[] password) { if(config.main.enableGlobalPassword) { // We have global password enabled - return verifyPassword(password, config.main.globalPassword) ? 1 : 0; + return verifyPassword(password, config.main.globalPassword) ? PasswordOptions.CORRECT : PasswordOptions.WRONG; } else { - String hashed; - // Password from cache - if(playerCacheMap.get(uuid).isRegistered) - hashed = playerCacheMap.get(uuid).password; - else - return -1; - + String hashed = playerCacheMap.get(uuid).password; if(hashed.isEmpty()) - return -1; // User is not yet registered + return PasswordOptions.NOT_REGISTERED; // Verify password - return verifyPassword(password, hashed) ? 1 : 0; + return verifyPassword(password, hashed) ? PasswordOptions.CORRECT : PasswordOptions.WRONG; } } @@ -54,4 +48,10 @@ public class AuthHelper { else return HasherArgon2.verify(pass, hashed); } + + public enum PasswordOptions { + CORRECT, + WRONG, + NOT_REGISTERED + } }