Skip to content
Snippets Groups Projects
Commit 753d61fe authored by Spotlight Deveaux's avatar Spotlight Deveaux :fox:
Browse files

Rearrange auth manager

parent c360018d
No related branches found
No related tags found
No related merge requests found
...@@ -2,12 +2,16 @@ package io.github.packserver.Cedar; ...@@ -2,12 +2,16 @@ package io.github.packserver.Cedar;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.time.Instant; import java.time.Instant;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.Objects; import java.util.Objects;
import java.util.UUID;
import static io.github.packserver.Cedar.ErrorsAndTheirMeanings.*;
/** /**
* Handles authentication via QR code. * Handles authentication via QR code.
...@@ -15,11 +19,7 @@ import java.util.Objects; ...@@ -15,11 +19,7 @@ import java.util.Objects;
*/ */
class AuthenticationManager { class AuthenticationManager {
private final Player p; private final Main plugin = Main.plugin;
AuthenticationManager(Player p) {
this.p = p;
}
// This is the format that the data is stored in the Redis. // This is the format that the data is stored in the Redis.
class StorageFormat { class StorageFormat {
...@@ -33,7 +33,7 @@ class AuthenticationManager { ...@@ -33,7 +33,7 @@ class AuthenticationManager {
/** /**
* Send authentication data to player * Send authentication data to player
*/ */
Integer generateAuthString() { Integer generateAuthString(Player p) {
StorageFormat toBeStored = new StorageFormat(); StorageFormat toBeStored = new StorageFormat();
// Generate random number // Generate random number
toBeStored.code = 100000 + new SecureRandom().nextInt(900000); toBeStored.code = 100000 + new SecureRandom().nextInt(900000);
...@@ -53,16 +53,40 @@ class AuthenticationManager { ...@@ -53,16 +53,40 @@ class AuthenticationManager {
return toBeStored.code; return toBeStored.code;
} }
String continueAuth(WebsocketServer.ParseWithCode jsonResult) {
String potentialPlayerUUID = jsonResult.uuid;
if (Main.DEBUG) {
Main.plugin.getLogger().info("I found " + potentialPlayerUUID + " as the player's UUID.");
}
// Check if it's an actual UUID.
UUID playerUUID;
try {
playerUUID = UUID.fromString(potentialPlayerUUID);
} catch (IllegalArgumentException e) {
return returnJSON(USER_UUID_INVALID);
}
// Check UUID and such
String result = checkPlayer(playerUUID);
if (!(result.equals(returnJSON(SUCCESS)))) {
return result;
}
// It appears to be valid. Validate the code.
result = checkCode(jsonResult.code, playerUUID);
return result;
// TODO: add more checking
}
/** /**
* Verify code. * Verify code.
* @param givenCode Code recieved from client * @param givenCode Code received from client
* @return Status * @return Status
*/ */
Integer checkCode(Integer givenCode) { private String checkCode(Integer givenCode, UUID playerUUID) {
Main.plugin.getLogger().info("I ran! xdxdxdxdxd");
// Get data // Get data
String jsonFromStorage = new RedisFactory().getString("app_code_" + p.getUniqueId()); String jsonFromStorage = new RedisFactory().getString("app_code_" + playerUUID.toString());
Main.plugin.getLogger().info("Retrived " + jsonFromStorage); Main.plugin.getLogger().info("Retrieved " + jsonFromStorage);
Gson gson = new Gson(); Gson gson = new Gson();
StorageFormat storedData = gson.fromJson(jsonFromStorage, StorageFormat.class); StorageFormat storedData = gson.fromJson(jsonFromStorage, StorageFormat.class);
Main.plugin.getLogger().info("Given code: " + givenCode + ", and we have " + storedData.code + "."); Main.plugin.getLogger().info("Given code: " + givenCode + ", and we have " + storedData.code + ".");
...@@ -70,16 +94,43 @@ class AuthenticationManager { ...@@ -70,16 +94,43 @@ class AuthenticationManager {
// We can check this by subtracting 30 minutes from right now. // We can check this by subtracting 30 minutes from right now.
// If that time is after the saved time, it's too late. // If that time is after the saved time, it's too late.
Instant savedTime = storedData.time; Instant savedTime = storedData.time;
Instant thirtyMinutesBefore = Instant.now().plus(30, ChronoUnit.MINUTES); // Go 30 minutes from then
if (savedTime.isAfter(thirtyMinutesBefore)) { Instant thirtyMinutesAfter = savedTime.plus(30, ChronoUnit.MINUTES);
return ErrorsAndTheirMeanings.CODE_EXPIRED.getId(); // Check if we're past that time
if (Instant.now().isAfter(thirtyMinutesAfter)) {
return returnJSON(CODE_EXPIRED);
} }
// Now that time has been verified, we can check the code. // Now that time has been verified, we can check the code.
if (Objects.equals(givenCode, storedData.code)) { if (Objects.equals(givenCode, storedData.code)) {
return ErrorsAndTheirMeanings.SUCCESS.getId(); return returnJSON(SUCCESS);
} else { } else {
return ErrorsAndTheirMeanings.CODE_INCORRECT.getId(); return returnJSON(CODE_INCORRECT);
} }
} }
/**
* Validate the UUID/player
*
* @param playerUUID The UUID to check
* @return The errors encountered, or success
*/
private String checkPlayer(UUID playerUUID) {
OfflinePlayer possiblePlayer = plugin.getServer().getOfflinePlayer(playerUUID);
if (possiblePlayer.hasPlayedBefore()) {
if (possiblePlayer.isOnline()) {
Player p = possiblePlayer.getPlayer();
return returnJSON(SUCCESS);
} else return returnJSON(USER_NOT_ONLINE);
} else return returnJSON(USER_NEVER_JOINED);
}
/**
* A method to get JSON to return for errors.
*
* @param error The ErrorsAndTheirMeanings error you want
* @return JSON result with error
*/
private String returnJSON(ErrorsAndTheirMeanings error) {
return "{\"result\":" + error.getId() + "}";
}
} }
...@@ -87,13 +87,13 @@ class ImageRenderer extends MapRenderer { ...@@ -87,13 +87,13 @@ class ImageRenderer extends MapRenderer {
Gson gson = new Gson(); Gson gson = new Gson();
QRString toDisplay = new QRString(); QRString toDisplay = new QRString();
toDisplay.playerUUID = player.getUniqueId(); toDisplay.playerUUID = player.getUniqueId();
toDisplay.code = new AuthenticationManager(player).generateAuthString(); toDisplay.code = new AuthenticationManager().generateAuthString(player);
File qrFile = QRCode.from(gson.toJson(toDisplay)).to(ImageType.PNG).file(); File qrFile = QRCode.from(gson.toJson(toDisplay)).to(ImageType.PNG).file();
try { try {
canvas.drawImage(0, 0, ImageIO.read(qrFile)); canvas.drawImage(0, 0, ImageIO.read(qrFile));
} catch (IOException e) { } catch (IOException e) {
player.sendMessage("Looks like I just done messed up lol"); player.sendMessage(ChatColor.RED + "I couldn't grab the QR code for you to scan! This is an error.");
e.printStackTrace(); e.printStackTrace();
} }
this.hasRendered = true; this.hasRendered = true;
......
...@@ -9,6 +9,7 @@ enum ErrorsAndTheirMeanings { ...@@ -9,6 +9,7 @@ enum ErrorsAndTheirMeanings {
// Chapter 1: your basic username issues. // Chapter 1: your basic username issues.
USER_NEVER_JOINED(1), USER_NEVER_JOINED(1),
USER_NOT_ONLINE(2), USER_NOT_ONLINE(2),
USER_UUID_INVALID(3),
// Chapter 2: authentication related stuff. // Chapter 2: authentication related stuff.
CODE_EXPIRED(100), CODE_EXPIRED(100),
......
package io.github.packserver.Cedar; package io.github.packserver.Cedar;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.util.UUID;
import static io.github.packserver.Cedar.ErrorsAndTheirMeanings.*;
/** /**
* @author spotlight * Various utilities
*
* @author Spotlight
*/ */
class Utils { class Utils {
private UUID playerUUID;
private final Main plugin = Main.plugin;
/**
* Be warned, we want to use UUIDs though.
*
* @param playerUUID UUID of player
*/
Utils(UUID playerUUID) {
this.playerUUID = playerUUID;
}
private Boolean checkHasJoined() {
//noinspection deprecation
OfflinePlayer p = plugin.getServer().getOfflinePlayer(playerUUID);
// Actual checking
return p.hasPlayedBefore();
}
Integer authenticateCheck(Integer code) {
Main.plugin.getLogger().info("I ran! xdxd");
if (checkHasJoined()) {
Main.plugin.getLogger().info("I ran! xdxdxd");
//noinspection deprecation
OfflinePlayer possiblePlayer = plugin.getServer().getOfflinePlayer(playerUUID);
if (possiblePlayer.isOnline()) {
Main.plugin.getLogger().info("I ran! xdxdxdxd");
Player p = possiblePlayer.getPlayer();
return new AuthenticationManager(p).checkCode(code);
} else return USER_NOT_ONLINE.getId();
} else return USER_NEVER_JOINED.getId();
}
} }
...@@ -6,7 +6,6 @@ import com.google.gson.JsonSyntaxException; ...@@ -6,7 +6,6 @@ import com.google.gson.JsonSyntaxException;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Collection; import java.util.Collection;
import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
...@@ -43,28 +42,13 @@ public class WebsocketServer extends WebSocketServer { ...@@ -43,28 +42,13 @@ public class WebsocketServer extends WebSocketServer {
private Integer action; private Integer action;
} }
class ParseWithUsername {
@SerializedName("action")
private Integer action;
@SerializedName("username")
private String username;
}
// We want to use the UUID from now on.
class ParseWithUUID {
@SerializedName("action")
private Integer action;
@SerializedName("uuid")
private UUID playerUUID;
}
class ParseWithCode { class ParseWithCode {
@SerializedName("action") @SerializedName("action")
private Integer action; Integer action;
@SerializedName("uuid") @SerializedName("uuid")
private UUID playerUUID; String uuid;
@SerializedName("code") @SerializedName("code")
private Integer code; Integer code;
} }
@Override @Override
...@@ -87,11 +71,13 @@ public class WebsocketServer extends WebSocketServer { ...@@ -87,11 +71,13 @@ public class WebsocketServer extends WebSocketServer {
switch (action) { switch (action) {
case 105: case 105:
// Sends back success or nah. // Sends back success or nah.
// "Well, uh, technically, uh, nah"
Main.plugin.getLogger().info("I did something useful!"); Main.plugin.getLogger().info("I did something useful!");
ParseWithCode jsonRequest = gson.fromJson(json, ParseWithCode.class); ParseWithCode jsonRequest = gson.fromJson(json, ParseWithCode.class);
Main.plugin.getLogger().info("Code recieved in onMessage: " + jsonRequest.code); Main.plugin.getLogger().info(jsonRequest.toString());
conn.send("{\"result\": " + new Utils(jsonRequest.playerUUID).authenticateCheck(jsonRequest.code) + "}");
Main.plugin.getLogger().info("Code received in onMessage: " + jsonRequest.code);
Main.plugin.getLogger().info("I found the following: " + jsonRequest.uuid);
conn.send(new AuthenticationManager().continueAuth(jsonRequest));
conn.close(); conn.close();
break; break;
default: default:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment