From 2af418a99a2b5e09c89083cfcf45956eb5eeac18 Mon Sep 17 00:00:00 2001 From: khanhduytran0 Date: Mon, 7 Dec 2020 15:56:06 +0700 Subject: [PATCH] [Important change!] Do not refresh access token when it stills usable --- .../com/kdt/mojangauth/RefreshTokenTask.java | 102 +++++++++--------- .../yggdrasil/YggdrasilAuthenticator.java | 24 ++++- 2 files changed, 72 insertions(+), 54 deletions(-) diff --git a/app/src/main/java/com/kdt/mojangauth/RefreshTokenTask.java b/app/src/main/java/com/kdt/mojangauth/RefreshTokenTask.java index ec9499dac..baccabdb1 100644 --- a/app/src/main/java/com/kdt/mojangauth/RefreshTokenTask.java +++ b/app/src/main/java/com/kdt/mojangauth/RefreshTokenTask.java @@ -9,58 +9,62 @@ import com.kdt.mojangauth.yggdrasil.*; import android.app.*; public class RefreshTokenTask extends AsyncTask { - private YggdrasilAuthenticator authenticator = new YggdrasilAuthenticator(); - //private Gson gson = new Gson(); - private RefreshListener listener; - private MCProfile.Builder profilePath; + private YggdrasilAuthenticator authenticator = new YggdrasilAuthenticator(); + //private Gson gson = new Gson(); + private RefreshListener listener; + private MCProfile.Builder profilePath; - private Context ctx; - private ProgressDialog build; + private Context ctx; + private ProgressDialog build; - public RefreshTokenTask(Context ctx, RefreshListener listener) { - this.ctx = ctx; - this.listener = listener; - } + public RefreshTokenTask(Context ctx, RefreshListener listener) { + this.ctx = ctx; + this.listener = listener; + } - @Override - public void onPreExecute() { - build = new ProgressDialog(ctx); - build.setMessage("Refreshing"); - build.setProgressStyle(ProgressDialog.STYLE_SPINNER); - build.setCancelable(false); - build.show(); - } - - @Override - public Throwable doInBackground(String... args) { - try { - this.profilePath = MCProfile.load(args[0]); - RefreshResponse response = this.authenticator.refresh(profilePath.getAccessToken(), UUID.fromString(profilePath.getClientID())); - if (response == null) { - throw new NullPointerException("Response is null?"); - } - if (response.selectedProfile == null) { - throw new IllegalArgumentException("Can't refresh a demo account!"); - } - profilePath.setClientID(response.clientToken.toString()); - profilePath.setAccessToken(response.accessToken); - profilePath.setUsername(response.selectedProfile.name); - profilePath.setProfileID(response.selectedProfile.id); - MCProfile.build(profilePath); - return null; - } catch (Throwable e) { - return e; - } - } + @Override + public void onPreExecute() { + build = new ProgressDialog(ctx); + build.setMessage("Refreshing"); + build.setProgressStyle(ProgressDialog.STYLE_SPINNER); + build.setCancelable(false); + build.show(); + } - @Override - public void onPostExecute(Throwable result) { - build.dismiss(); - if (result == null) { - listener.onSuccess(); - } else { - listener.onFailed(result); - } - } + @Override + public Throwable doInBackground(String... args) { + try { + this.profilePath = MCProfile.load(args[0]); + // https://wiki.vg/Authentication + // Returns an empty payload (204 No Content) if successful, an error JSON with status 403 Forbidden otherwise. + if (204 != this.authenticator.validate(profilePath.getAccessToken())) { + RefreshResponse response = this.authenticator.refresh(profilePath.getAccessToken(), UUID.fromString(profilePath.getClientID())); + if (response == null) { + throw new NullPointerException("Response is null?"); + } + if (response.selectedProfile == null) { + throw new IllegalArgumentException("Can't refresh a demo account!"); + } + profilePath.setClientID(response.clientToken.toString()); + profilePath.setAccessToken(response.accessToken); + profilePath.setUsername(response.selectedProfile.name); + profilePath.setProfileID(response.selectedProfile.id); + MCProfile.build(profilePath); + } + return null; + } catch (Throwable e) { + return e; + } + } + + @Override + public void onPostExecute(Throwable result) { + build.dismiss(); + if (result == null) { + listener.onSuccess(); + } else { + listener.onFailed(result); + } + } } diff --git a/app/src/main/java/com/kdt/mojangauth/yggdrasil/YggdrasilAuthenticator.java b/app/src/main/java/com/kdt/mojangauth/yggdrasil/YggdrasilAuthenticator.java index 1c64ec890..1eb7d8913 100644 --- a/app/src/main/java/com/kdt/mojangauth/yggdrasil/YggdrasilAuthenticator.java +++ b/app/src/main/java/com/kdt/mojangauth/yggdrasil/YggdrasilAuthenticator.java @@ -49,12 +49,18 @@ public class YggdrasilAuthenticator { } } String outString = new String(bos.toByteArray(), Charset.forName("UTF-8")); - if (statusCode == 200){ + if (statusCode == 200 || statusCode == 204){ Log.i("Result", "Task " + endpoint + " successful"); - return Tools.GLOBAL_GSON.fromJson(outString, responseClass); + if (responseClass == null) { + return (T) Integer.valueOf(statusCode); + } else { + return Tools.GLOBAL_GSON.fromJson(outString, responseClass); + } + } else { + Log.i("Result", "Task " + endpoint + " failure"); + return (T) Integer.valueOf(statusCode); } - throw new RuntimeException("Invalid username or password, status code: " + statusCode); } catch (UnknownHostException e) { throw new RuntimeException("Can't connect to the server", e); } catch (Throwable th2) { @@ -79,11 +85,19 @@ public class YggdrasilAuthenticator { } public AuthenticateResponse authenticate(String username, String password, UUID clientId) throws IOException, Throwable { - return (AuthenticateResponse) makeRequest("authenticate", new AuthenticateRequest(username, password, clientId, this.clientName, this.clientVersion), AuthenticateResponse.class); + Object obj = makeRequest("authenticate", new AuthenticateRequest(username, password, clientId, this.clientName, this.clientVersion), AuthenticateResponse.class); + if (obj instanceof Integer) { + throw new RuntimeException("Invalid username or password, status code: " + (Integer) obj); + } + return (AuthenticateResponse) obj; } public RefreshResponse refresh(String authToken, UUID clientId) throws IOException, Throwable { - return (RefreshResponse) makeRequest("refresh", new RefreshRequest(authToken, clientId), RefreshResponse.class); + Object obj = makeRequest("refresh", new RefreshRequest(authToken, clientId), RefreshResponse.class); + if (obj instanceof Integer) { + throw new RuntimeException("Invalid username or password, status code: " + (Integer) obj); + } + return (RefreshResponse) obj; } public int validate(String authToken) throws Throwable {