Commit 04d9613f authored by KingRainbow44's avatar KingRainbow44
Browse files

External authentication

parent 5d7edc38
...@@ -35,7 +35,6 @@ import emu.grasscutter.utils.Language; ...@@ -35,7 +35,6 @@ import emu.grasscutter.utils.Language;
import emu.grasscutter.server.game.GameServer; import emu.grasscutter.server.game.GameServer;
import emu.grasscutter.tools.Tools; import emu.grasscutter.tools.Tools;
import emu.grasscutter.utils.Crypto; import emu.grasscutter.utils.Crypto;
import emu.grasscutter.BuildConfig;
import javax.annotation.Nullable; import javax.annotation.Nullable;
...@@ -129,7 +128,6 @@ public final class Grasscutter { ...@@ -129,7 +128,6 @@ public final class Grasscutter {
httpServer.addRouter(GenericHandler.class); httpServer.addRouter(GenericHandler.class);
httpServer.addRouter(AnnouncementsHandler.class); httpServer.addRouter(AnnouncementsHandler.class);
httpServer.addRouter(DispatchHandler.class); httpServer.addRouter(DispatchHandler.class);
httpServer.addRouter(LegacyAuthHandler.class);
httpServer.addRouter(GachaHandler.class); httpServer.addRouter(GachaHandler.class);
// TODO: find a better place? // TODO: find a better place?
......
...@@ -2,6 +2,7 @@ package emu.grasscutter.auth; ...@@ -2,6 +2,7 @@ package emu.grasscutter.auth;
import emu.grasscutter.server.http.objects.*; import emu.grasscutter.server.http.objects.*;
import express.http.Request; import express.http.Request;
import express.http.Response;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Getter; import lombok.Getter;
...@@ -52,12 +53,20 @@ public interface AuthenticationSystem { ...@@ -52,12 +53,20 @@ public interface AuthenticationSystem {
*/ */
Authenticator<ComboTokenResJson> getSessionKeyAuthenticator(); Authenticator<ComboTokenResJson> getSessionKeyAuthenticator();
/**
* This is the authenticator used for handling external authentication requests.
* @return An authenticator.
*/
ExternalAuthenticator getExternalAuthenticator();
/** /**
* A data container that holds relevant data for authenticating a client. * A data container that holds relevant data for authenticating a client.
*/ */
@Builder @AllArgsConstructor @Getter @Builder @AllArgsConstructor @Getter
class AuthenticationRequest { class AuthenticationRequest {
private final Request request; private final Request request;
@Nullable private final Response response;
@Nullable private final LoginAccountRequestJson passwordRequest; @Nullable private final LoginAccountRequestJson passwordRequest;
@Nullable private final LoginTokenRequestJson tokenRequest; @Nullable private final LoginTokenRequestJson tokenRequest;
@Nullable private final ComboTokenReqJson sessionKeyRequest; @Nullable private final ComboTokenReqJson sessionKeyRequest;
...@@ -104,4 +113,15 @@ public interface AuthenticationSystem { ...@@ -104,4 +113,15 @@ public interface AuthenticationSystem {
.sessionKeyData(tokenData) .sessionKeyData(tokenData)
.build(); .build();
} }
/**
* Generates an authentication request from a {@link Response} object.
* @param request The Express request.
* @param response the Express response.
* @return An authentication request.
*/
static AuthenticationRequest fromExternalRequest(Request request, Response response) {
return AuthenticationRequest.builder().request(request)
.response(response).build();
}
} }
...@@ -15,6 +15,7 @@ public final class DefaultAuthentication implements AuthenticationSystem { ...@@ -15,6 +15,7 @@ public final class DefaultAuthentication implements AuthenticationSystem {
private final Authenticator<LoginResultJson> passwordAuthenticator = new PasswordAuthenticator(); private final Authenticator<LoginResultJson> passwordAuthenticator = new PasswordAuthenticator();
private final Authenticator<LoginResultJson> tokenAuthenticator = new TokenAuthenticator(); private final Authenticator<LoginResultJson> tokenAuthenticator = new TokenAuthenticator();
private final Authenticator<ComboTokenResJson> sessionKeyAuthenticator = new SessionKeyAuthenticator(); private final Authenticator<ComboTokenResJson> sessionKeyAuthenticator = new SessionKeyAuthenticator();
private final ExternalAuthenticator externalAuthenticator = new ExternalAuthentication();
@Override @Override
public void createAccount(String username, String password) { public void createAccount(String username, String password) {
...@@ -46,4 +47,9 @@ public final class DefaultAuthentication implements AuthenticationSystem { ...@@ -46,4 +47,9 @@ public final class DefaultAuthentication implements AuthenticationSystem {
public Authenticator<ComboTokenResJson> getSessionKeyAuthenticator() { public Authenticator<ComboTokenResJson> getSessionKeyAuthenticator() {
return this.sessionKeyAuthenticator; return this.sessionKeyAuthenticator;
} }
@Override
public ExternalAuthenticator getExternalAuthenticator() {
return this.externalAuthenticator;
}
} }
...@@ -158,4 +158,24 @@ public final class DefaultAuthenticators { ...@@ -158,4 +158,24 @@ public final class DefaultAuthenticators {
return response; return response;
} }
} }
/**
* Handles authentication requests from external sources.
*/
public static class ExternalAuthentication implements ExternalAuthenticator {
@Override public void handleLogin(AuthenticationRequest request) {
assert request.getResponse() != null;
request.getResponse().send("Authentication is not available with the default authentication method.");
}
@Override public void handleAccountCreation(AuthenticationRequest request) {
assert request.getResponse() != null;
request.getResponse().send("Authentication is not available with the default authentication method.");
}
@Override public void handlePasswordReset(AuthenticationRequest request) {
assert request.getResponse() != null;
request.getResponse().send("Authentication is not available with the default authentication method.");
}
}
} }
package emu.grasscutter.auth;
import emu.grasscutter.auth.AuthenticationSystem.AuthenticationRequest;
/**
* Handles authentication via external routes.
*/
public interface ExternalAuthenticator {
/**
* Called when an external login request is made.
* @param request The authentication request.
*/
void handleLogin(AuthenticationRequest request);
/**
* Called when an external account creation request is made.
* @param request The authentication request.
*
* For developers: Use {@link AuthenticationRequest#getRequest()} to get the request body.
* Use {@link AuthenticationRequest#getResponse()} to get the response body.
*/
void handleAccountCreation(AuthenticationRequest request);
/**
* Called when an external password reset request is made.
* @param request The authentication request.
*
* For developers: Use {@link AuthenticationRequest#getRequest()} to get the request body.
* Use {@link AuthenticationRequest#getResponse()} to get the response body.
*/
void handlePasswordReset(AuthenticationRequest request);
}
...@@ -24,6 +24,12 @@ public final class DispatchHandler implements Router { ...@@ -24,6 +24,12 @@ public final class DispatchHandler implements Router {
express.post("/hk4e_global/mdk/shield/api/verify", DispatchHandler::tokenLogin); express.post("/hk4e_global/mdk/shield/api/verify", DispatchHandler::tokenLogin);
// Combo token login (from session key). // Combo token login (from session key).
express.post("/hk4e_global/combo/granter/login/v2/login", DispatchHandler::sessionKeyLogin); express.post("/hk4e_global/combo/granter/login/v2/login", DispatchHandler::sessionKeyLogin);
// External login (from other clients).
express.get("/authentication/type", (request, response) -> response.send(Grasscutter.getAuthenticationSystem().getClass().getSimpleName()));
express.post("/authentication/login", (request, response) -> response.status(500).send("{\"notice\":\"This API is deprecated.\"}"));
express.post("/authentication/register", (request, response) -> response.status(500).send("{\"notice\":\"This API is deprecated.\"}"));
express.post("/authentication/change_password", (request, response) -> response.status(500).send("{\"notice\":\"This API is deprecated.\"}"));
} }
/** /**
......
package emu.grasscutter.server.http.handlers;
import emu.grasscutter.server.http.Router;
import express.Express;
import io.javalin.Javalin;
/**
* Handles the legacy authentication system routes.
*/
public final class LegacyAuthHandler implements Router {
@Override public void applyRoutes(Express express, Javalin handle) {
express.get("/authentication/type", (request, response) -> response.status(500).send("{\"notice\":\"This API is deprecated.\"}"));
express.post("/authentication/login", (request, response) -> response.status(500).send("{\"notice\":\"This API is deprecated.\"}"));
express.post("/authentication/register", (request, response) -> response.status(500).send("{\"notice\":\"This API is deprecated.\"}"));
express.post("/authentication/change_password", (request, response) -> response.status(500).send("{\"notice\":\"This API is deprecated.\"}"));
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment