Saving changes, password results now in enum

This commit is contained in:
samo_lego 2020-11-07 17:55:21 +01:00
parent d198a67346
commit 48dd9ce00b
8 changed files with 53 additions and 93 deletions

View File

@ -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)

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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
);
}

View File

@ -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 = "";
public static PlayerCache fromJson(ServerPlayerEntity player, String fakeUuid) {
if(config.experimental.debugMode)
logInfo("New player cache created.");
}
logInfo("Creating cache for " + Objects.requireNonNull(player).getGameProfile().getName());
public static PlayerCache fromJson(ServerPlayerEntity player, String json) {
if(config.experimental.debugMode)
logInfo("Creating cache for " + Objects.requireNonNull(player).getName());
PlayerCache playerCache = new PlayerCache(player);;
String json = DB.getUserData(fakeUuid);
if(!json.isEmpty()) {
// Parsing data from DB
PlayerCache playerCache = gson.fromJson(json, PlayerCache.class);
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;
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);
}
}

View File

@ -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

View File

@ -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
}
}