diff --git a/build.gradle b/build.gradle index ac3a21e..29187ab 100644 --- a/build.gradle +++ b/build.gradle @@ -10,14 +10,14 @@ sourceCompatibility = 17 targetCompatibility = 17 group 'me.exzork.gcauth' -version '2.1.6' +version '2.2.0' repositories { mavenCentral() } dependencies { - implementation files('lib/grasscutter-1.1.1-dev.jar') + implementation files('lib/grasscutter-1.1.2-dev.jar') implementation 'org.springframework.security:spring-security-crypto:5.6.3' implementation 'commons-logging:commons-logging:1.2' implementation 'com.auth0:java-jwt:3.19.1' diff --git a/src/main/java/me/exzork/gcauth/GCAuth.java b/src/main/java/me/exzork/gcauth/GCAuth.java index 2ef1905..ea15a85 100644 --- a/src/main/java/me/exzork/gcauth/GCAuth.java +++ b/src/main/java/me/exzork/gcauth/GCAuth.java @@ -5,6 +5,7 @@ import com.google.gson.GsonBuilder; import emu.grasscutter.Grasscutter; import emu.grasscutter.plugin.Plugin; import me.exzork.gcauth.handler.*; +import me.exzork.gcauth.router.GCAuthRouter; import me.exzork.gcauth.utils.Authentication; import java.io.File; @@ -21,7 +22,7 @@ public class GCAuth extends Plugin { @Override public void onEnable() { - configFile = new File(getDataFolder().toPath()+ "/config.json"); + configFile = new File(getDataFolder().toPath() + "/config.json"); if (!configFile.exists()) { try { Files.createDirectories(configFile.toPath().getParent()); @@ -30,28 +31,24 @@ public class GCAuth extends Plugin { } } loadConfig(); - if(Grasscutter.getDispatchServer().registerAuthHandler(new GCAuthAuthenticationHandler())) { - Grasscutter.getLogger().info("[GCAuth] GCAuth Enabled!"); - config.jwtSecret = Authentication.generateRandomString(32); - saveConfig(); - if(Grasscutter.getConfig().account.autoCreate) { - Grasscutter.getLogger().warn("[GCAuth] GCAuth does not support automatic account creation. Please disable in the server's config.json or just ignore this warning."); - } - } else { - Grasscutter.getLogger().error("[GCAuth] GCAuth could not be enabled"); + Grasscutter.setAuthenticationSystem(new GCAuthAuthenticationHandler()); + //Grasscutter.getHttpServer().addRouter(GCAuthRouter.class); + Grasscutter.getLogger().info("[GCAuth] GCAuth Enabled!"); + config.jwtSecret = Authentication.generateRandomString(32); + saveConfig(); + if (Grasscutter.getConfig().account.autoCreate) { + Grasscutter.getLogger().warn("[GCAuth] GCAuth does not support automatic account creation. Please disable in the server's config.json or just ignore this warning."); } } @Override public void onDisable() { - if(Grasscutter.getDispatchServer().getAuthHandler().getClass().equals(GCAuthAuthenticationHandler.class)) { - Grasscutter.getDispatchServer().resetAuthHandler(); - } + } - public void loadConfig() { + public void loadConfig() { try (FileReader file = new FileReader(configFile)) { - config = gson.fromJson(file,Config.class); + config = gson.fromJson(file, Config.class); saveConfig(); } catch (Exception e) { config = new Config(); @@ -66,6 +63,12 @@ public class GCAuth extends Plugin { Grasscutter.getLogger().error("[GCAuth] Unable to save config file."); } } - public static Config getConfigStatic() {return config;} - public Config getConfig() {return config;} + + public static Config getConfigStatic() { + return config; + } + + public Config getConfig() { + return config; + } } diff --git a/src/main/java/me/exzork/gcauth/handler/GCAuthAuthenticationHandler.java b/src/main/java/me/exzork/gcauth/handler/GCAuthAuthenticationHandler.java index 19ab1c6..b85e591 100644 --- a/src/main/java/me/exzork/gcauth/handler/GCAuthAuthenticationHandler.java +++ b/src/main/java/me/exzork/gcauth/handler/GCAuthAuthenticationHandler.java @@ -1,75 +1,38 @@ package me.exzork.gcauth.handler; +import emu.grasscutter.auth.AuthenticationSystem; +import emu.grasscutter.auth.Authenticator; +import emu.grasscutter.auth.DefaultAuthenticators; +import emu.grasscutter.server.http.objects.ComboTokenResJson; +import emu.grasscutter.server.http.objects.LoginResultJson; -import emu.grasscutter.Grasscutter; -import emu.grasscutter.game.Account; -import emu.grasscutter.server.dispatch.authentication.AuthenticationHandler; -import emu.grasscutter.server.dispatch.json.LoginAccountRequestJson; -import emu.grasscutter.server.dispatch.json.LoginResultJson; -import express.http.Request; -import express.http.Response; -import me.exzork.gcauth.utils.Authentication; - -import java.io.IOException; - -public class GCAuthAuthenticationHandler implements AuthenticationHandler { +public class GCAuthAuthenticationHandler implements AuthenticationSystem { + private final Authenticator gcAuthAuthenticator = new GCAuthenticators.GCAuthAuthenticator(); + private final Authenticator tokenAuthenticator = new DefaultAuthenticators.TokenAuthenticator(); + private final Authenticator sessionKeyAuthenticator = new DefaultAuthenticators.SessionKeyAuthenticator(); @Override - public void handleLogin(Request req, Response res) { - try { - new LoginHandler().handle(req, res); - } catch (IOException e) { - Grasscutter.getLogger().warn("[GCAuth] Unable to handle login request"); - e.printStackTrace(); - } + public void createAccount(String username, String password) { + } @Override - public void handleRegister(Request req, Response res) { - try { - new RegisterHandler().handle(req, res); - } catch (IOException e) { - Grasscutter.getLogger().warn("[GCAuth] Unable to handle register request"); - e.printStackTrace(); - } + public void resetPassword(String s) { + } @Override - public void handleChangePassword(Request req, Response res) { - try { - new ChangePasswordHandler().handle(req, res); - } catch (IOException e) { - Grasscutter.getLogger().warn("[GCAuth] Unable to handle change password request"); - e.printStackTrace(); - } + public Authenticator getPasswordAuthenticator() { + return gcAuthAuthenticator; } @Override - public boolean verifyUser(String details) { - return false; + public Authenticator getTokenAuthenticator() { + return tokenAuthenticator; } @Override - public LoginResultJson handleGameLogin(Request request, LoginAccountRequestJson requestData) { - LoginResultJson responseData = new LoginResultJson(); - - // Login - Account account = Authentication.getAccountByOneTimeToken(requestData.account); - if(account == null) { - Grasscutter.getLogger().info("[GCAuth] Client " + request.ip() + " failed to log in"); - responseData.retcode = -201; - responseData.message = "Token is invalid"; - return responseData; - } - - // Account was found, log the player in - responseData.message = "OK"; - responseData.data.account.uid = account.getId(); - responseData.data.account.token = account.generateSessionKey(); - responseData.data.account.email = account.getEmail(); - - Grasscutter.getLogger().info(String.format("[GCAuth] Client %s logged in as %s", request.ip(), responseData.data.account.uid)); - - return responseData; + public Authenticator getSessionKeyAuthenticator() { + return sessionKeyAuthenticator; } } diff --git a/src/main/java/me/exzork/gcauth/handler/GCAuthenticators.java b/src/main/java/me/exzork/gcauth/handler/GCAuthenticators.java new file mode 100644 index 0000000..bcc6809 --- /dev/null +++ b/src/main/java/me/exzork/gcauth/handler/GCAuthenticators.java @@ -0,0 +1,39 @@ +package me.exzork.gcauth.handler; + +import emu.grasscutter.Grasscutter; +import emu.grasscutter.auth.AuthenticationSystem; +import emu.grasscutter.auth.Authenticator; +import emu.grasscutter.database.DatabaseHelper; +import emu.grasscutter.game.Account; +import emu.grasscutter.server.http.objects.LoginResultJson; +import me.exzork.gcauth.utils.Authentication; + +public class GCAuthenticators { + + public static class GCAuthAuthenticator implements Authenticator { + + @Override + public LoginResultJson authenticate(AuthenticationSystem.AuthenticationRequest authenticationRequest) { + var response = new LoginResultJson(); + + var requestData = authenticationRequest.getPasswordRequest(); + assert requestData != null; + Account account = Authentication.getAccountByOneTimeToken(requestData.account); + if(account == null) { + Grasscutter.getLogger().info("[GCAuth] Client " + requestData.account + " tried to login with invalid one time token."); + response.retcode = -201; + response.message = "Token is invalid"; + return response; + } + + // Account was found, log the player in + response.message = "OK"; + response.data.account.uid = account.getId(); + response.data.account.token = account.generateSessionKey(); + response.data.account.email = account.getEmail(); + + Grasscutter.getLogger().info("[GCAuth] Client " + requestData.account + " logged in"); + return response; + } + } +} diff --git a/src/main/java/me/exzork/gcauth/handler/LoginHandler.java b/src/main/java/me/exzork/gcauth/handler/LoginHandler.java index 77b2aab..1121a1e 100644 --- a/src/main/java/me/exzork/gcauth/handler/LoginHandler.java +++ b/src/main/java/me/exzork/gcauth/handler/LoginHandler.java @@ -17,8 +17,6 @@ public class LoginHandler implements HttpContextHandler { @Override public void handle(Request request, Response response) throws IOException { AuthResponseJson authResponse = new AuthResponseJson(); - - try { String requestBody = request.ctx().body(); if (requestBody.isEmpty()) { diff --git a/src/main/java/me/exzork/gcauth/router/GCAuthRouter.java b/src/main/java/me/exzork/gcauth/router/GCAuthRouter.java new file mode 100644 index 0000000..0c679ad --- /dev/null +++ b/src/main/java/me/exzork/gcauth/router/GCAuthRouter.java @@ -0,0 +1,17 @@ +package me.exzork.gcauth.router; + +import emu.grasscutter.server.http.Router; +import express.Express; +import io.javalin.Javalin; +import me.exzork.gcauth.handler.ChangePasswordHandler; +import me.exzork.gcauth.handler.LoginHandler; +import me.exzork.gcauth.handler.RegisterHandler; + +public class GCAuthRouter implements Router { + @Override + public void applyRoutes(Express express, Javalin javalin) { + express.post("/authentication/login", new LoginHandler()); + express.post("/authentication/register", new RegisterHandler()); + express.post("/authentication/change_password", new ChangePasswordHandler()); + } +}