diff --git a/app/src/main/java/com/kdt/mojangauth/InvalidateTokenTask.java b/app/src/main/java/com/kdt/mojangauth/InvalidateTokenTask.java new file mode 100644 index 000000000..663b48a46 --- /dev/null +++ b/app/src/main/java/com/kdt/mojangauth/InvalidateTokenTask.java @@ -0,0 +1,42 @@ +package com.kdt.mojangauth; + +import android.content.*; +import android.os.*; +import com.kdt.mojangauth.yggdrasil.*; +import java.io.*; +import java.util.*; +import net.kdt.pojavlaunch.*; + +public class InvalidateTokenTask extends AsyncTask { + private YggdrasilAuthenticator authenticator = new YggdrasilAuthenticator(); + //private Gson gson = new Gson(); + private MCProfile.Builder profilePath; + + private Context ctx; + private String path; + + public InvalidateTokenTask(Context ctx) { + this.ctx = ctx; + } + + @Override + public Throwable doInBackground(String... args) { + path = args[0]; + try { + this.profilePath = MCProfile.load(args[0]); + this.authenticator.invalidate(profilePath.getAccessToken(), UUID.fromString(profilePath.getClientID())); + return null; + } catch (Throwable e) { + return e; + } + } + + @Override + public void onPostExecute(Throwable result) { + if (result != null) { + Tools.showError(ctx, result); + } + new File(path).delete(); + } +} + diff --git a/app/src/main/java/com/kdt/mojangauth/RefreshTokenTask.java b/app/src/main/java/com/kdt/mojangauth/RefreshTokenTask.java index baccabdb1..ed1dbfc5b 100644 --- a/app/src/main/java/com/kdt/mojangauth/RefreshTokenTask.java +++ b/app/src/main/java/com/kdt/mojangauth/RefreshTokenTask.java @@ -37,7 +37,7 @@ public class RefreshTokenTask extends AsyncTask { 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())) { + if (204 != this.authenticator.validate(profilePath.getAccessToken()).statusCode) { RefreshResponse response = this.authenticator.refresh(profilePath.getAccessToken(), UUID.fromString(profilePath.getClientID())); if (response == null) { throw new NullPointerException("Response is null?"); diff --git a/app/src/main/java/com/kdt/mojangauth/yggdrasil/NetworkResponse.java b/app/src/main/java/com/kdt/mojangauth/yggdrasil/NetworkResponse.java new file mode 100644 index 000000000..9edecaec4 --- /dev/null +++ b/app/src/main/java/com/kdt/mojangauth/yggdrasil/NetworkResponse.java @@ -0,0 +1,23 @@ +package com.kdt.mojangauth.yggdrasil; + +import java.util.*; + +public class NetworkResponse +{ + public final int statusCode; + public final Object response; + public NetworkResponse(int statusCode, Object response) { + this.statusCode = statusCode; + this.response = response; + } + + public void throwExceptionIfNeed(String msg) { + if (statusCode >= 400) { + throw new RuntimeException(msg); + } + } + + public void throwExceptionIfNeed() { + throwExceptionIfNeed("Respone error, code: " + statusCode + ", message: " + response); + } +} 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 1eb7d8913..8695d321e 100644 --- a/app/src/main/java/com/kdt/mojangauth/yggdrasil/YggdrasilAuthenticator.java +++ b/app/src/main/java/com/kdt/mojangauth/yggdrasil/YggdrasilAuthenticator.java @@ -6,16 +6,16 @@ import java.net.*; import java.nio.charset.*; import java.util.*; import net.kdt.pojavlaunch.*; +import org.apache.commons.io.*; public class YggdrasilAuthenticator { private static final String API_URL = "https://authserver.mojang.com/"; private String clientName = "Minecraft"; private int clientVersion = 1; - private T makeRequest(String endpoint, Object inputObject, Class responseClass) throws IOException, Throwable { + private NetworkResponse makeRequest(String endpoint, Object inputObject, Class responseClass) throws IOException, Throwable { Throwable th; InputStream is = null; - byte[] buf = new byte[16384]; ByteArrayOutputStream bos = new ByteArrayOutputStream(); String requestJson = Tools.GLOBAL_GSON.toJson(inputObject); try { @@ -40,7 +40,7 @@ public class YggdrasilAuthenticator { } else { is = conn.getInputStream(); } - pipe(is, bos, buf); + IOUtils.copy(is, bos); if (is != null) { try { is.close(); @@ -52,14 +52,14 @@ public class YggdrasilAuthenticator { if (statusCode == 200 || statusCode == 204){ Log.i("Result", "Task " + endpoint + " successful"); - if (responseClass == null) { - return (T) Integer.valueOf(statusCode); - } else { - return Tools.GLOBAL_GSON.fromJson(outString, responseClass); + if (responseClass != null) { + return new NetworkResponse(statusCode, Tools.GLOBAL_GSON.fromJson(outString, responseClass)); } } else { Log.i("Result", "Task " + endpoint + " failure"); - return (T) Integer.valueOf(statusCode); + } + if (responseClass == null) { + return new NetworkResponse(statusCode, outString); } } catch (UnknownHostException e) { throw new RuntimeException("Can't connect to the server", e); @@ -82,37 +82,32 @@ public class YggdrasilAuthenticator { } throw th; } - } + return null; + } public AuthenticateResponse authenticate(String username, String password, UUID clientId) throws IOException, Throwable { - 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); + NetworkResponse obj = makeRequest("authenticate", new AuthenticateRequest(username, password, clientId, this.clientName, this.clientVersion), AuthenticateResponse.class); + /* + if (obj.statusCode != 200) { + throw new RuntimeException("Invalid username or password, status code: " + obj.statusCode); } - return (AuthenticateResponse) obj; + */ + obj.throwExceptionIfNeed(); + return (AuthenticateResponse) obj.response; } public RefreshResponse refresh(String authToken, UUID clientId) throws IOException, Throwable { - 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; + NetworkResponse obj = makeRequest("refresh", new RefreshRequest(authToken, clientId), RefreshResponse.class); + obj.throwExceptionIfNeed(); // "Invalid username or password, status code: " + obj.statusCode); + return (RefreshResponse) obj.response; } - public int validate(String authToken) throws Throwable { - return (Integer) makeRequest("validate", new RefreshRequest(authToken, null), null); + public NetworkResponse validate(String authToken) throws Throwable { + return makeRequest("validate", new RefreshRequest(authToken, null), null); } - - private void pipe(InputStream is, OutputStream out, byte[] buf) throws IOException { - while (true) { - int amt = is.read(buf); - if (amt >= 0) { - out.write(buf, 0, amt); - } else { - return; - } - } + + public NetworkResponse invalidate(String authToken, UUID clientId) throws Throwable { + return makeRequest("invalidate", new RefreshRequest(authToken, clientId), null); } } diff --git a/app/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java b/app/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java index 74ec3cf63..4d6fa1926 100644 --- a/app/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java +++ b/app/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java @@ -677,7 +677,7 @@ public class PojavLoginActivity extends BaseActivity @Override public void onClick(DialogInterface p1, int p2) { - file.delete(); + new InvalidateTokenTask(PojavLoginActivity.this).execute(file.getAbsolutePath()); flv.refreshPath(); } });