From 93c3f04cbba8a49eb8cf209ef549f5396f625f1e Mon Sep 17 00:00:00 2001 From: Henry Le Grys Date: Thu, 11 Feb 2021 18:01:13 +0000 Subject: [PATCH] Handle cancelled OAuth requests --- .../launcher/auth/MicrosoftLoginService.java | 10 +++++-- .../microsoft/MicrosoftWebAuthorizer.java | 4 +-- .../auth/microsoft/OauthHttpHandler.java | 10 +++++-- .../launcher/auth/microsoft/OauthResult.java | 28 +++++++++++++++++++ 4 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 launcher/src/main/java/com/skcraft/launcher/auth/microsoft/OauthResult.java diff --git a/launcher/src/main/java/com/skcraft/launcher/auth/MicrosoftLoginService.java b/launcher/src/main/java/com/skcraft/launcher/auth/MicrosoftLoginService.java index fb5beff..0982414 100644 --- a/launcher/src/main/java/com/skcraft/launcher/auth/MicrosoftLoginService.java +++ b/launcher/src/main/java/com/skcraft/launcher/auth/MicrosoftLoginService.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.skcraft.launcher.auth.microsoft.MicrosoftWebAuthorizer; import com.skcraft.launcher.auth.microsoft.MinecraftServicesAuthorizer; +import com.skcraft.launcher.auth.microsoft.OauthResult; import com.skcraft.launcher.auth.microsoft.XboxTokenAuthorizer; import com.skcraft.launcher.auth.microsoft.model.McAuthResponse; import com.skcraft.launcher.auth.microsoft.model.McProfileResponse; @@ -30,12 +31,17 @@ public class MicrosoftLoginService implements LoginService { public Session login() throws IOException, InterruptedException, AuthenticationException { MicrosoftWebAuthorizer authorizer = new MicrosoftWebAuthorizer(clientId); - String code = authorizer.authorize(); + OauthResult auth = authorizer.authorize(); + + if (auth.isError()) { + OauthResult.Error error = (OauthResult.Error) auth; + throw new AuthenticationException(error.getErrorMessage()); + } TokenResponse response = exchangeToken(form -> { form.add("grant_type", "authorization_code"); form.add("redirect_uri", authorizer.getRedirectUri()); - form.add("code", code); + form.add("code", ((OauthResult.Success) auth).getAuthCode()); }); Profile session = performLogin(response.getAccessToken(), null); diff --git a/launcher/src/main/java/com/skcraft/launcher/auth/microsoft/MicrosoftWebAuthorizer.java b/launcher/src/main/java/com/skcraft/launcher/auth/microsoft/MicrosoftWebAuthorizer.java index 5d46e91..5edeacb 100644 --- a/launcher/src/main/java/com/skcraft/launcher/auth/microsoft/MicrosoftWebAuthorizer.java +++ b/launcher/src/main/java/com/skcraft/launcher/auth/microsoft/MicrosoftWebAuthorizer.java @@ -18,7 +18,7 @@ public class MicrosoftWebAuthorizer { private final String clientId; @Getter private String redirectUri; - public String authorize() throws IOException, AuthenticationException, InterruptedException { + public OauthResult authorize() throws IOException, AuthenticationException, InterruptedException { if (Desktop.isDesktopSupported()) { // Interactive auth return authorizeInteractive(); @@ -28,7 +28,7 @@ public class MicrosoftWebAuthorizer { } } - private String authorizeInteractive() throws IOException, AuthenticationException, InterruptedException { + private OauthResult authorizeInteractive() throws IOException, AuthenticationException, InterruptedException { OauthHttpHandler httpHandler = new OauthHttpHandler(); Desktop.getDesktop().browse(generateInteractiveUrl(httpHandler.getPort())); diff --git a/launcher/src/main/java/com/skcraft/launcher/auth/microsoft/OauthHttpHandler.java b/launcher/src/main/java/com/skcraft/launcher/auth/microsoft/OauthHttpHandler.java index 59b0acf..b7b1e0f 100644 --- a/launcher/src/main/java/com/skcraft/launcher/auth/microsoft/OauthHttpHandler.java +++ b/launcher/src/main/java/com/skcraft/launcher/auth/microsoft/OauthHttpHandler.java @@ -17,7 +17,7 @@ import java.util.concurrent.Executors; public class OauthHttpHandler { private Executor executor = Executors.newCachedThreadPool(); private HttpServer server; - private String result; + private OauthResult result; public OauthHttpHandler() throws IOException { server = HttpServer.create(new InetSocketAddress("localhost", 0), 0); @@ -31,7 +31,7 @@ public class OauthHttpHandler { return server.getAddress().getPort(); } - public String await() throws InterruptedException { + public OauthResult await() throws InterruptedException { synchronized (this) { this.wait(); } @@ -46,7 +46,11 @@ public class OauthHttpHandler { public void handle(HttpExchange httpExchange) throws IOException { String query = httpExchange.getRequestURI().getQuery(); Map qs = Splitter.on('&').withKeyValueSeparator('=').split(query); - result = qs.get("code"); + if (qs.get("error") != null) { + result = new OauthResult.Error(qs.get("error_description")); + } else { + result = new OauthResult.Success(qs.get("code")); + } synchronized (OauthHttpHandler.this) { OauthHttpHandler.this.notifyAll(); diff --git a/launcher/src/main/java/com/skcraft/launcher/auth/microsoft/OauthResult.java b/launcher/src/main/java/com/skcraft/launcher/auth/microsoft/OauthResult.java new file mode 100644 index 0000000..28c8001 --- /dev/null +++ b/launcher/src/main/java/com/skcraft/launcher/auth/microsoft/OauthResult.java @@ -0,0 +1,28 @@ +package com.skcraft.launcher.auth.microsoft; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +public interface OauthResult { + boolean isError(); + + @RequiredArgsConstructor + class Success implements OauthResult { + @Getter private final String authCode; + + @Override + public boolean isError() { + return false; + } + } + + @RequiredArgsConstructor + class Error implements OauthResult { + @Getter private final String errorMessage; + + @Override + public boolean isError() { + return true; + } + } +}