Skip to content

Commit

Permalink
Merge pull request Grover-c13#165 from rajulbhatnagar/googleauth_refresh
Browse files Browse the repository at this point in the history
Refresh the OAuth token when it expires
  • Loading branch information
Grover-c13 authored Jul 24, 2016
2 parents 2e14fab + 7ccf228 commit 0db0742
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 19 deletions.
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Sun Jul 17 19:51:46 PDT 2016
#Sat Jul 23 04:51:41 PDT 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-all.zip
74 changes: 60 additions & 14 deletions src/main/java/com/pokegoapi/auth/GoogleLogin.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
package com.pokegoapi.auth;

import POGOProtos.Networking.Envelopes.RequestEnvelopeOuterClass.RequestEnvelope.AuthInfo;

import com.pokegoapi.exceptions.LoginFailedException;
import com.pokegoapi.util.Log;
import com.squareup.moshi.Moshi;

import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
Expand All @@ -29,10 +31,7 @@
import java.net.URISyntaxException;

public class GoogleLogin extends Login {
public static final String SECRET = "NCjF1TLi2CcY6t5mt0ZveuL7";
public static final String CLIENT_ID = "848232511240-73ri3t7plvk96pj4f85uj8otdat2alem.apps.googleusercontent.com";
public static final String OAUTH_ENDPOINT = "https://accounts.google.com/o/oauth2/device/code";
public static final String OAUTH_TOKEN_ENDPOINT = "https://www.googleapis.com/oauth2/v4/token";

private static final String TAG = GoogleLogin.class.getSimpleName();

private final OkHttpClient client;
Expand All @@ -41,6 +40,41 @@ public GoogleLogin(OkHttpClient client) {
this.client = client;
}

/**
* Given the refresh token fetches a new access token and returns AuthInfo.
*
* @param refreshToken Refresh token returned during initial login
* @return Refreshed AuthInfo object
* @throws IOException If the network call fails
*/
public AuthInfo refreshToken(String refreshToken) throws IOException {
HttpUrl url = HttpUrl.parse(GoogleLoginSecrets.OAUTH_TOKEN_ENDPOINT).newBuilder()
.addQueryParameter("client_id", GoogleLoginSecrets.CLIENT_ID)
.addQueryParameter("client_secret", GoogleLoginSecrets.SECRET)
.addQueryParameter("refresh_token", refreshToken)
.addQueryParameter("grant_type", "refresh_token")
.build();
//Empty request body
RequestBody reqBody = RequestBody.create(null, new byte[0]);
Request request = new Request.Builder()
.url(url)
.method("POST", reqBody)
.build();

Response response = client.newCall(request).execute();
Moshi moshi = new Moshi.Builder().build();
GoogleAuthTokenJson token = moshi.adapter(GoogleAuthTokenJson.class).fromJson(response.body().string());
if (token.getError() != null) {
return null;
} else {
Log.d(TAG, "Refreshed Token " + token.getIdToken());
AuthInfo.Builder builder = AuthInfo.newBuilder();
builder.setProvider("google");
builder.setToken(AuthInfo.JWT.newBuilder().setContents(token.getIdToken()).setUnknown2(59).build());
return builder.build();
}
}

/**
* Returns an AuthInfo object given a token, this should not be an access token but rather an id_token
*
Expand All @@ -54,18 +88,31 @@ public AuthInfo login(String token) {
return builder.build();
}

/**
* Returns an AuthInfo object given a token, this should not be an access token but rather an id_token.
*
* @param token the id_token stored from a previous oauth attempt.
* @param refreshToken Let app provide refresh token if they have persisted it
* @return AuthInfo a AuthInfo proto structure to be encapsulated in server requests
*/
public AuthInfo login(String token, String refreshToken) {
GoogleLoginSecrets.refresh_token = refreshToken;
AuthInfo.Builder builder = AuthInfo.newBuilder();
builder.setProvider("google");
builder.setToken(AuthInfo.JWT.newBuilder().setContents(token).setUnknown2(59).build());
return builder.build();
}

/**
* Starts a login flow for google using a username and password, this uses googles device oauth endpoint,
* a URL and code is displayed, not really ideal right now.
*
* @param username Google username
* @param password Google password
* @return AuthInfo a AuthInfo proto structure to be encapsulated in server requests
*/
public AuthInfo login(String username, String password) throws LoginFailedException {
public AuthInfo login() throws LoginFailedException {
try {
HttpUrl url = HttpUrl.parse(OAUTH_ENDPOINT).newBuilder()
.addQueryParameter("client_id", CLIENT_ID)
HttpUrl url = HttpUrl.parse(GoogleLoginSecrets.OAUTH_ENDPOINT).newBuilder()
.addQueryParameter("client_id", GoogleLoginSecrets.CLIENT_ID)
.addQueryParameter("scope", "openid email https://www.googleapis.com/auth/userinfo.email")
.build();

Expand All @@ -91,9 +138,8 @@ public AuthInfo login(String username, String password) throws LoginFailedExcept
Thread.sleep(googleAuth.getInterval() * 1000);
}


Log.d(TAG, "Got token: " + token.getIdToken());

GoogleLoginSecrets.refresh_token = token.getRefreshToken();
AuthInfo.Builder authbuilder = AuthInfo.newBuilder();
authbuilder.setProvider("google");
authbuilder.setToken(AuthInfo.JWT.newBuilder().setContents(token.getIdToken()).setUnknown2(59).build());
Expand All @@ -107,9 +153,9 @@ public AuthInfo login(String username, String password) throws LoginFailedExcept


private GoogleAuthTokenJson poll(GoogleAuthJson json) throws URISyntaxException, IOException {
HttpUrl url = HttpUrl.parse(OAUTH_TOKEN_ENDPOINT).newBuilder()
.addQueryParameter("client_id", CLIENT_ID)
.addQueryParameter("client_secret", SECRET)
HttpUrl url = HttpUrl.parse(GoogleLoginSecrets.OAUTH_TOKEN_ENDPOINT).newBuilder()
.addQueryParameter("client_id", GoogleLoginSecrets.CLIENT_ID)
.addQueryParameter("client_secret", GoogleLoginSecrets.SECRET)
.addQueryParameter("code", json.getDeviceCode())
.addQueryParameter("grant_type", "http://oauth.net/grant_type/device/1.0")
.addQueryParameter("scope", "openid email https://www.googleapis.com/auth/userinfo.email")
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/com/pokegoapi/auth/GoogleLoginSecrets.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.pokegoapi.auth;

/**
* Created by RajulB on 7/23/2016.
*/

public class GoogleLoginSecrets {
public static final String SECRET = "NCjF1TLi2CcY6t5mt0ZveuL7";
public static final String CLIENT_ID = "848232511240-73ri3t7plvk96pj4f85uj8otdat2alem.apps.googleusercontent.com";
public static final String OAUTH_ENDPOINT = "https://accounts.google.com/o/oauth2/device/code";
public static final String OAUTH_TOKEN_ENDPOINT = "https://www.googleapis.com/oauth2/v4/token";

public static String refresh_token = null;
}
2 changes: 1 addition & 1 deletion src/main/java/com/pokegoapi/auth/PtcLogin.java
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public AuthInfo login(String username, String password) throws LoginFailedExcept
.addQueryParameter("client_id", CLIENT_ID)
.addQueryParameter("redirect_uri", REDIRECT_URI)
.addQueryParameter("client_secret", CLIENT_SECRET)
.addQueryParameter("grant_type", "refresh_token")
.addQueryParameter("grant_type", "refreshToken")
.addQueryParameter("code", ticket)
.build();

Expand Down
21 changes: 19 additions & 2 deletions src/main/java/com/pokegoapi/main/RequestHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@
import POGOProtos.Networking.Envelopes.RequestEnvelopeOuterClass;
import POGOProtos.Networking.Envelopes.RequestEnvelopeOuterClass.RequestEnvelope.AuthInfo;
import POGOProtos.Networking.Envelopes.ResponseEnvelopeOuterClass;

import com.google.protobuf.ByteString;
import com.pokegoapi.api.PokemonGo;
import com.pokegoapi.auth.GoogleLogin;
import com.pokegoapi.auth.GoogleLoginSecrets;
import com.pokegoapi.exceptions.LoginFailedException;
import com.pokegoapi.exceptions.RemoteServerException;
import com.pokegoapi.util.Log;

import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.Response;
Expand Down Expand Up @@ -129,8 +133,21 @@ public void sendServerRequests(ServerRequest... serverRequests) throws RemoteSer
lastAuth = responseEnvelop.getAuthTicket();
}

if (responseEnvelop.getStatusCode() == 102) {
throw new LoginFailedException();
if (responseEnvelop.getStatusCode() == 102 && GoogleLoginSecrets.refresh_token != null) {
Log.d(TAG,"Refreshing Token");
GoogleLogin login = new GoogleLogin(client);
final AuthInfo refreshedAuth = login.refreshToken(GoogleLoginSecrets.refresh_token);
if (refreshedAuth == null) {
throw new LoginFailedException(String.format("Refreshing token failed Error %s in API Url %s",
responseEnvelop.getApiUrl(), responseEnvelop.getError()));
} else {
this.auth = refreshedAuth;
sendServerRequests(serverRequests);
return;
}
} else if (responseEnvelop.getStatusCode() == 102) {
throw new LoginFailedException(String.format("Error %s in API Url %s",
responseEnvelop.getApiUrl(), responseEnvelop.getError()));
} else if (responseEnvelop.getStatusCode() == 53) {
// 53 means that the api_endpoint was not correctly set, should be at this point, though, so redo the request
sendServerRequests(serverRequests);
Expand Down

0 comments on commit 0db0742

Please sign in to comment.