Starting with password caching.

This commit is contained in:
samo_lego 2020-04-12 17:54:52 +02:00
parent 9ec2e4478c
commit ef301883b7
9 changed files with 53 additions and 22 deletions

View File

@ -5,21 +5,21 @@ import net.fabricmc.fabric.api.event.player.*;
import net.fabricmc.fabric.api.event.server.ServerStopCallback; import net.fabricmc.fabric.api.event.server.ServerStopCallback;
import net.fabricmc.fabric.api.registry.CommandRegistry; import net.fabricmc.fabric.api.registry.CommandRegistry;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.samo_lego.simpleauth.commands.*; import org.samo_lego.simpleauth.commands.*;
import org.samo_lego.simpleauth.database.SimpleAuthDatabase;
import org.samo_lego.simpleauth.event.AuthEventHandler; import org.samo_lego.simpleauth.event.AuthEventHandler;
import org.samo_lego.simpleauth.event.entity.player.ChatCallback; 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.PlayerJoinServerCallback;
import org.samo_lego.simpleauth.event.entity.player.PlayerMoveCallback; import org.samo_lego.simpleauth.event.entity.player.PlayerMoveCallback;
import org.samo_lego.simpleauth.event.item.DropItemCallback; import org.samo_lego.simpleauth.event.item.DropItemCallback;
import org.samo_lego.simpleauth.event.item.TakeItemCallback; import org.samo_lego.simpleauth.event.item.TakeItemCallback;
import org.samo_lego.simpleauth.utils.AuthConfig; import org.samo_lego.simpleauth.storage.AuthConfig;
import org.samo_lego.simpleauth.storage.PlayerCache;
import org.samo_lego.simpleauth.storage.SimpleAuthDatabase;
import java.io.File; import java.io.File;
import java.util.HashMap; import java.util.HashMap;
@ -33,11 +33,12 @@ public class SimpleAuth implements DedicatedServerModInitializer {
// HashMap of players that are not authenticated // HashMap of players that are not authenticated
// Rather than storing all the authenticated players, we just store ones that are not authenticated // Rather than storing all the authenticated players, we just store ones that are not authenticated
public static HashMap<PlayerEntity, Integer> deauthenticatedUsers = new HashMap<>(); // It stores some data as well, e.g. login tries and user password
public static HashMap<String, PlayerCache> deauthenticatedUsers = new HashMap<>();
// Boolean for easier checking if player is authenticated // Boolean for easier checking if player is authenticated
public static boolean isAuthenticated(ServerPlayerEntity player) { public static boolean isAuthenticated(ServerPlayerEntity player) {
return !deauthenticatedUsers.containsKey(player); return !deauthenticatedUsers.containsKey(player.getUuidAsString());
} }
// Getting game directory // Getting game directory
@ -94,7 +95,7 @@ public class SimpleAuth implements DedicatedServerModInitializer {
// Authenticates player and sends the message // Authenticates player and sends the message
public static void authenticatePlayer(ServerPlayerEntity player, Text msg) { public static void authenticatePlayer(ServerPlayerEntity player, Text msg) {
deauthenticatedUsers.remove(player); deauthenticatedUsers.remove(player.getUuidAsString());
// Player no longer needs to be invisible and invulnerable // Player no longer needs to be invisible and invulnerable
player.setInvulnerable(false); player.setInvulnerable(false);
player.setInvisible(false); player.setInvisible(false);
@ -112,7 +113,8 @@ public class SimpleAuth implements DedicatedServerModInitializer {
// De-authenticates player // De-authenticates player
public static void deauthenticatePlayer(ServerPlayerEntity player) { public static void deauthenticatePlayer(ServerPlayerEntity player) {
// Marking player as not authenticated, (re)setting login tries to zero // Marking player as not authenticated, (re)setting login tries to zero
SimpleAuth.deauthenticatedUsers.put(player, 0); String uuid = player.getUuidAsString();
SimpleAuth.deauthenticatedUsers.put(uuid, new PlayerCache(uuid));
// Player is now not authenticated // Player is now not authenticated
player.sendMessage(notAuthenticated()); player.sendMessage(notAuthenticated());

View File

@ -8,7 +8,7 @@ import net.minecraft.text.Text;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.samo_lego.simpleauth.SimpleAuth; import org.samo_lego.simpleauth.SimpleAuth;
import org.samo_lego.simpleauth.utils.AuthConfig; import org.samo_lego.simpleauth.storage.AuthConfig;
import org.samo_lego.simpleauth.utils.AuthHelper; import org.samo_lego.simpleauth.utils.AuthHelper;
import java.io.File; import java.io.File;

View File

@ -67,7 +67,7 @@ public class ChangepwCommand {
)); ));
return 0; return 0;
} }
SimpleAuth.db.update( SimpleAuth.db.updateUserData(
player.getUuidAsString(), player.getUuidAsString(),
AuthHelper.hashPass(newPass.toCharArray()) AuthHelper.hashPass(newPass.toCharArray())
); );

View File

@ -7,6 +7,7 @@ import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.samo_lego.simpleauth.SimpleAuth; import org.samo_lego.simpleauth.SimpleAuth;
import org.samo_lego.simpleauth.storage.PlayerCache;
import org.samo_lego.simpleauth.utils.AuthHelper; import org.samo_lego.simpleauth.utils.AuthHelper;
import static com.mojang.brigadier.arguments.StringArgumentType.getString; import static com.mojang.brigadier.arguments.StringArgumentType.getString;
@ -39,20 +40,21 @@ public class LoginCommand {
private static int login(ServerCommandSource source, String pass) throws CommandSyntaxException { private static int login(ServerCommandSource source, String pass) throws CommandSyntaxException {
// Getting the player who send the command // Getting the player who send the command
ServerPlayerEntity player = source.getPlayer(); ServerPlayerEntity player = source.getPlayer();
String uuid = player.getUuidAsString();
if(SimpleAuth.isAuthenticated(player)) { if(SimpleAuth.isAuthenticated(player)) {
player.sendMessage(alreadyAuthenticated); player.sendMessage(alreadyAuthenticated);
return 0; return 0;
} }
else if(SimpleAuth.deauthenticatedUsers.get(player) >= maxLoginTries && maxLoginTries != -1) { else if(SimpleAuth.deauthenticatedUsers.get(uuid).loginTries >= maxLoginTries && maxLoginTries != -1) {
player.networkHandler.disconnect(loginTriesExceeded); player.networkHandler.disconnect(loginTriesExceeded);
return 0; return 0;
} }
else if (AuthHelper.checkPass(player.getUuidAsString(), pass.toCharArray()) == 1) { else if (AuthHelper.checkPass(uuid, pass.toCharArray()) == 1) {
SimpleAuth.authenticatePlayer(player, successfullyAuthenticated); SimpleAuth.authenticatePlayer(player, successfullyAuthenticated);
return 1; return 1;
} }
else if(AuthHelper.checkPass(player.getUuidAsString(), pass.toCharArray()) == -1) { else if(AuthHelper.checkPass(uuid, pass.toCharArray()) == -1) {
player.sendMessage(notRegistered); player.sendMessage(notRegistered);
return 0; return 0;
} }
@ -64,10 +66,7 @@ public class LoginCommand {
// Sending wrong pass message // Sending wrong pass message
player.sendMessage(wrongPassword); player.sendMessage(wrongPassword);
// ++ the login tries // ++ the login tries
SimpleAuth.deauthenticatedUsers.replace( SimpleAuth.deauthenticatedUsers.getOrDefault(uuid, new PlayerCache(uuid)).loginTries += 1;
player,
SimpleAuth.deauthenticatedUsers.getOrDefault(player, 0) + 1
);
return 0; return 0;
} }
} }

View File

@ -47,7 +47,7 @@ public class UnregisterCommand {
} }
else if (AuthHelper.checkPass(player.getUuidAsString(), pass.toCharArray()) == 1) { else if (AuthHelper.checkPass(player.getUuidAsString(), pass.toCharArray()) == 1) {
SimpleAuth.deauthenticatePlayer(player); SimpleAuth.deauthenticatePlayer(player);
SimpleAuth.db.delete(player.getUuidAsString()); SimpleAuth.db.deleteUserData(player.getUuidAsString());
player.sendMessage(accountDeleted); player.sendMessage(accountDeleted);
return 1; return 1;
} }

View File

@ -15,7 +15,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.samo_lego.simpleauth.utils; package org.samo_lego.simpleauth.storage;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;

View File

@ -0,0 +1,25 @@
package org.samo_lego.simpleauth.storage;
import org.samo_lego.simpleauth.SimpleAuth;
public class PlayerCache {
public boolean isRegistered;
public boolean isAuthenticated;
public String password;
public int loginTries;
public PlayerCache(String uuid) {
SimpleAuthDatabase db = SimpleAuth.db;
this.isAuthenticated = false;
this.loginTries = 0;
if(db.isUserRegistered(uuid)) {
this.isRegistered = true;
this.password = db.getPassword(uuid);
}
else {
this.isRegistered = false;
this.password = "";
}
}
}

View File

@ -1,4 +1,4 @@
package org.samo_lego.simpleauth.database; package org.samo_lego.simpleauth.storage;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -54,7 +54,7 @@ public class SimpleAuthDatabase {
} }
// Checks if user is registered // Checks if user is registered
private boolean isUserRegistered(String uuid) { public boolean isUserRegistered(String uuid) {
try { try {
return levelDBStore.get(bytes("UUID:" + uuid)) != null; return levelDBStore.get(bytes("UUID:" + uuid)) != null;
} catch (DBException e) { } catch (DBException e) {

View File

@ -10,7 +10,7 @@ public class AuthHelper {
private static final Logger LOGGER = LogManager.getLogger(); private static final Logger LOGGER = LogManager.getLogger();
// Creating the instance // Creating the instance
private static Argon2 argon2 = Argon2Factory.create(); private static final Argon2 argon2 = Argon2Factory.create();
// Returns 1 if password is correct, 0 if not // Returns 1 if password is correct, 0 if not
// and -1 if user is not registered yet // and -1 if user is not registered yet
@ -30,8 +30,13 @@ public class AuthHelper {
} }
else { else {
try { try {
String hashed;
// Password from cache
if(SimpleAuth.deauthenticatedUsers.containsKey(uuid))
hashed = SimpleAuth.deauthenticatedUsers.get(uuid).password;
// Hashed password from DB // Hashed password from DB
String hashed = SimpleAuth.db.getPassword(uuid); else
hashed = SimpleAuth.db.getPassword(uuid);
if(hashed.equals("")) if(hashed.equals(""))
return -1; // User is not yet registered return -1; // User is not yet registered
// Verify password // Verify password