Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ targetCompatibility = 1.7

repositories {
mavenCentral()
maven { url "https://jitpack.io" }
}

sourceSets {
Expand Down Expand Up @@ -95,6 +96,7 @@ checkstyleMain.doLast {
}

dependencies {
compile 'com.github.svarzee:gpsoauth-java:v0.2.0'
compile 'com.squareup.okio:okio:1.9.0'
compile 'com.squareup.moshi:moshi:1.2.0'
compile 'com.annimon:stream:1.1.1'
Expand Down
99 changes: 99 additions & 0 deletions src/main/java/com/pokegoapi/auth/GoogleAutoCredentialProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package com.pokegoapi.auth;

import POGOProtos.Networking.Envelopes.RequestEnvelopeOuterClass.RequestEnvelope.AuthInfo;
import com.pokegoapi.exceptions.LoginFailedException;
import com.pokegoapi.exceptions.RemoteServerException;
import okhttp3.OkHttpClient;
import svarzee.gps.gpsoauth.AuthToken;
import svarzee.gps.gpsoauth.Gpsoauth;

import java.io.IOException;

/**
* Use to login with google username and password
*/
public class GoogleAutoCredentialProvider extends CredentialProvider {

// from https://github.com/tejado/pgoapi/blob/master/pgoapi/auth_google.py
private static String GOOGLE_LOGIN_ANDROID_ID = "9774d56d682e549c";
private static String GOOGLE_LOGIN_SERVICE =
"audience:server:client_id:848232511240-7so421jotr2609rmqakceuu1luuq0ptb.apps.googleusercontent.com";
private static String GOOGLE_LOGIN_APP = "com.nianticlabs.pokemongo";
private static String GOOGLE_LOGIN_CLIENT_SIG = "321187995bc7cdc2b5fc91b11a96e2baa8602c62";

private final Gpsoauth gpsoauth;
private final String username;
private TokenInfo tokenInfo;


/**
* Constructs credential provider using username and password
*
* @param username - google username
* @param password - google password
* @throws LoginFailedException - login failed possibly due to invalid credentials
* @throws RemoteServerException - some server/network failure
*/
public GoogleAutoCredentialProvider(OkHttpClient httpClient, String username, String password)
throws LoginFailedException, RemoteServerException {
this.gpsoauth = new Gpsoauth(httpClient);
this.username = username;
this.tokenInfo = login(username, password);
}

private TokenInfo login(String username, String password) throws RemoteServerException, LoginFailedException {
try {
String masterToken = gpsoauth.performMasterLoginForToken(username, password, GOOGLE_LOGIN_ANDROID_ID);
AuthToken authToken = gpsoauth.performOAuthForToken(username, masterToken, GOOGLE_LOGIN_ANDROID_ID,
GOOGLE_LOGIN_SERVICE, GOOGLE_LOGIN_APP, GOOGLE_LOGIN_CLIENT_SIG);
return new TokenInfo(authToken, masterToken);
} catch (IOException e) {
throw new RemoteServerException(e);
} catch (Gpsoauth.TokenRequestFailed e) {
throw new LoginFailedException(e);
}
}

private TokenInfo refreshToken(String username, String refreshToken) throws RemoteServerException, LoginFailedException {
try {
AuthToken authToken = gpsoauth.performOAuthForToken(username, refreshToken, GOOGLE_LOGIN_ANDROID_ID,
GOOGLE_LOGIN_SERVICE, GOOGLE_LOGIN_APP, GOOGLE_LOGIN_CLIENT_SIG);
return new TokenInfo(authToken, refreshToken);
} catch (IOException e) {
throw new RemoteServerException(e);
} catch (Gpsoauth.TokenRequestFailed e) {
throw new LoginFailedException(e);
}
}

@Override
public String getTokenId() throws LoginFailedException, RemoteServerException {
if (isTokenIdExpired()) {
this.tokenInfo = refreshToken(username, tokenInfo.refreshToken);
}
return tokenInfo.authToken.getToken();
}

@Override
public AuthInfo getAuthInfo() throws LoginFailedException, RemoteServerException {
AuthInfo.Builder builder = AuthInfo.newBuilder();
builder.setProvider("google");
builder.setToken(AuthInfo.JWT.newBuilder().setContents(tokenInfo.authToken.getToken()).setUnknown2(59).build());
return builder.build();
}

@Override
public boolean isTokenIdExpired() {
return tokenInfo.authToken.getExpiry() > System.currentTimeMillis() / 1000 - 60;
}

private static class TokenInfo {
final AuthToken authToken;
final String refreshToken;

TokenInfo(AuthToken authToken, String refreshToken) {
this.authToken = authToken;
this.refreshToken = refreshToken;
}
}
}