Skip to content

Commit 4b166d0

Browse files
authored
Added new oauth for google user interaction to supercede GoogleCredentialProvider (example included) added a new hasLure method to Pokestops that is more reliable. Undeprecrated constructors that construct time objects by default (#316)
1 parent 338ebc5 commit 4b166d0

File tree

7 files changed

+311
-3
lines changed

7 files changed

+311
-3
lines changed

src/main/java/com/pokegoapi/api/PokemonGo.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ public PokemonGo(CredentialProvider credentialProvider, OkHttpClient client, Tim
102102
* @throws LoginFailedException When login fails
103103
* @throws RemoteServerException When server fails
104104
*/
105-
@Deprecated
106105
public PokemonGo(CredentialProvider credentialProvider, OkHttpClient client)
107106
throws LoginFailedException, RemoteServerException {
108107
this(credentialProvider, client, new SystemTimeImpl());

src/main/java/com/pokegoapi/api/map/fort/Pokestop.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import POGOProtos.Inventory.Item.ItemIdOuterClass;
1919
import POGOProtos.Map.Fort.FortDataOuterClass;
20+
import POGOProtos.Map.Fort.FortModifierOuterClass;
2021
import POGOProtos.Networking.Requests.Messages.AddFortModifierMessageOuterClass.AddFortModifierMessage;
2122
import POGOProtos.Networking.Requests.Messages.FortDetailsMessageOuterClass.FortDetailsMessage;
2223
import POGOProtos.Networking.Requests.Messages.FortSearchMessageOuterClass.FortSearchMessage;
@@ -32,6 +33,8 @@
3233
import com.pokegoapi.main.ServerRequest;
3334
import lombok.Getter;
3435

36+
import java.util.List;
37+
3538
/**
3639
* Created by mjmfighter on 7/20/2016.
3740
*/
@@ -183,7 +186,25 @@ public FortDetails getDetails() throws LoginFailedException, RemoteServerExcepti
183186
* Returns whether this pokestop has an active lure.
184187
* @return lure status
185188
*/
189+
@Deprecated
186190
public boolean hasLurePokemon() {
187191
return fortData.hasLureInfo() && fortData.getLureInfo().getLureExpiresTimestampMs() < api.currentTimeMillis();
188192
}
193+
194+
/**
195+
* Returns whether this pokestop has an active lure.
196+
* @return lure status
197+
*/
198+
public boolean hasLure() throws LoginFailedException, RemoteServerException {
199+
200+
201+
List<FortModifierOuterClass.FortModifier> modifiers = getDetails().getModifier();
202+
for (FortModifierOuterClass.FortModifier mod : modifiers) {
203+
if (mod.getItemId() == ItemIdOuterClass.ItemId.ITEM_TROY_DISK) {
204+
return true;
205+
}
206+
}
207+
208+
return false;
209+
}
189210
}

src/main/java/com/pokegoapi/auth/GoogleAutoCredentialProvider.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ public class GoogleAutoCredentialProvider extends CredentialProvider {
3636
* @throws LoginFailedException - login failed possibly due to invalid credentials
3737
* @throws RemoteServerException - some server/network failure
3838
*/
39-
@Deprecated
4039
public GoogleAutoCredentialProvider(OkHttpClient httpClient, String username, String password)
4140
throws LoginFailedException, RemoteServerException {
4241
this.gpsoauth = new Gpsoauth(httpClient);

src/main/java/com/pokegoapi/auth/GoogleCredentialProvider.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public class GoogleCredentialProvider extends CredentialProvider {
6464
* @throws LoginFailedException When login fails
6565
* @throws RemoteServerException When server fails
6666
*/
67+
@Deprecated
6768
public GoogleCredentialProvider(OkHttpClient client, String refreshToken, Time time)
6869
throws LoginFailedException, RemoteServerException {
6970
this.time = time;
@@ -98,6 +99,7 @@ public GoogleCredentialProvider(OkHttpClient client, String refreshToken)
9899
* @throws LoginFailedException When login fails
99100
* @throws RemoteServerException When server fails
100101
*/
102+
@Deprecated
101103
public GoogleCredentialProvider(OkHttpClient client,
102104
OnGoogleLoginOAuthCompleteListener onGoogleLoginOAuthCompleteListener, Time time)
103105
throws LoginFailedException, RemoteServerException {
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
/*
2+
* This program is free software: you can redistribute it and/or modify
3+
* it under the terms of the GNU General Public License as published by
4+
* the Free Software Foundation, either version 3 of the License, or
5+
* (at your option) any later version.
6+
*
7+
* This program is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
* GNU General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU General Public License
13+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
14+
*/
15+
16+
package com.pokegoapi.auth;
17+
18+
import POGOProtos.Networking.Envelopes.RequestEnvelopeOuterClass.RequestEnvelope.AuthInfo;
19+
import com.pokegoapi.exceptions.LoginFailedException;
20+
import com.pokegoapi.exceptions.RemoteServerException;
21+
import com.pokegoapi.util.Log;
22+
import com.pokegoapi.util.SystemTimeImpl;
23+
import com.pokegoapi.util.Time;
24+
import com.squareup.moshi.Moshi;
25+
import lombok.Getter;
26+
import okhttp3.*;
27+
28+
import java.io.IOException;
29+
30+
public class GoogleUserCredentialProvider extends CredentialProvider {
31+
32+
public static final String SECRET = "NCjF1TLi2CcY6t5mt0ZveuL7";
33+
public static final String CLIENT_ID = "848232511240-73ri3t7plvk96pj4f85uj8otdat2alem.apps.googleusercontent.com";
34+
public static final String OAUTH_TOKEN_ENDPOINT = "https://www.googleapis.com/oauth2/v4/token";
35+
public static final String LOGIN_URL = "https://accounts.google.com/o/oauth2/auth?client_id=848232511240-73ri3t7plvk96pj4f85uj8otdat2alem.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=openid%20email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email";
36+
private static final String TAG = GoogleUserCredentialProvider.class.getSimpleName();
37+
//We try and refresh token 5 minutes before it actually expires
38+
private static final long REFRESH_TOKEN_BUFFER_TIME = 5 * 60 * 1000;
39+
private final OkHttpClient client;
40+
41+
42+
private final Time time;
43+
44+
private long expiresTimestamp;
45+
46+
private String tokenId;
47+
48+
@Getter
49+
private String refreshToken;
50+
51+
private AuthInfo.Builder authbuilder;
52+
53+
/**
54+
* Used for logging in when one has a persisted refreshToken.
55+
*
56+
* @param client OkHttp client
57+
* @param refreshToken Refresh Token Persisted by user
58+
* @param time a Time implementation
59+
* @throws LoginFailedException When login fails
60+
* @throws RemoteServerException When server fails
61+
*/
62+
public GoogleUserCredentialProvider(OkHttpClient client, String refreshToken, Time time)
63+
throws LoginFailedException, RemoteServerException {
64+
this.time = time;
65+
this.client = client;
66+
this.refreshToken = refreshToken;
67+
68+
refreshToken(refreshToken);
69+
authbuilder = AuthInfo.newBuilder();
70+
}
71+
72+
/**
73+
* Used for logging in when you dont have a persisted refresh token.
74+
*
75+
* @param client OkHttp client
76+
* @param time a Time implementation
77+
* @throws LoginFailedException When login fails
78+
* @throws RemoteServerException When server fails
79+
*/
80+
public GoogleUserCredentialProvider(OkHttpClient client, Time time)
81+
throws LoginFailedException, RemoteServerException {
82+
this.time = time;
83+
this.client = client;
84+
85+
authbuilder = AuthInfo.newBuilder();
86+
}
87+
88+
/**
89+
* Used for logging in when you dont have a persisted refresh token.
90+
*
91+
* @param client OkHttp client
92+
* @throws LoginFailedException When login fails
93+
* @throws RemoteServerException When server fails
94+
*/
95+
public GoogleUserCredentialProvider(OkHttpClient client)
96+
throws LoginFailedException, RemoteServerException {
97+
this.time = new SystemTimeImpl();
98+
this.client = client;
99+
100+
authbuilder = AuthInfo.newBuilder();
101+
}
102+
103+
104+
/**
105+
* Given the refresh token fetches a new access token and returns AuthInfo.
106+
*
107+
* @param refreshToken Refresh token persisted by the user after initial login
108+
* @throws LoginFailedException If we fail to get tokenId
109+
*/
110+
public void refreshToken(String refreshToken) throws LoginFailedException, RemoteServerException {
111+
HttpUrl url = HttpUrl.parse(OAUTH_TOKEN_ENDPOINT).newBuilder()
112+
.addQueryParameter("client_id", CLIENT_ID)
113+
.addQueryParameter("client_secret", SECRET)
114+
.addQueryParameter("refresh_token", refreshToken)
115+
.addQueryParameter("grant_type", "refresh_token")
116+
.build();
117+
//Empty request body
118+
RequestBody reqBody = RequestBody.create(null, new byte[0]);
119+
Request request = new Request.Builder()
120+
.url(url)
121+
.method("POST", reqBody)
122+
.build();
123+
124+
Response response = null;
125+
try {
126+
response = client.newCall(request).execute();
127+
128+
} catch (IOException e) {
129+
throw new RemoteServerException("Network Request failed to fetch refreshed tokenId", e);
130+
}
131+
Moshi moshi = new Moshi.Builder().build();
132+
GoogleAuthTokenJson googleAuthTokenJson = null;
133+
try {
134+
googleAuthTokenJson = moshi.adapter(GoogleAuthTokenJson.class).fromJson(response.body().string());
135+
Log.d(TAG, "" + googleAuthTokenJson.getExpiresIn());
136+
} catch (IOException e) {
137+
throw new RemoteServerException("Failed to unmarshal the Json response to fetch refreshed tokenId", e);
138+
}
139+
if (googleAuthTokenJson.getError() != null) {
140+
throw new LoginFailedException(googleAuthTokenJson.getError());
141+
} else {
142+
Log.d(TAG, "Refreshed Token " + googleAuthTokenJson.getIdToken());
143+
expiresTimestamp = time.currentTimeMillis()
144+
+ (googleAuthTokenJson.getExpiresIn() * 1000 - REFRESH_TOKEN_BUFFER_TIME);
145+
tokenId = googleAuthTokenJson.getIdToken();
146+
}
147+
}
148+
149+
150+
151+
152+
/**
153+
* Uses an access code to login and get tokens
154+
*/
155+
public void login(String authcode) throws LoginFailedException, RemoteServerException {
156+
157+
HttpUrl url = HttpUrl.parse(OAUTH_TOKEN_ENDPOINT).newBuilder()
158+
.addQueryParameter("code", authcode)
159+
.addQueryParameter("client_id", CLIENT_ID)
160+
.addQueryParameter("client_secret", SECRET)
161+
.addQueryParameter("grant_type", "authorization_code")
162+
.addQueryParameter("scope", "openid email https://www.googleapis.com/auth/userinfo.email")
163+
.addQueryParameter("redirect_uri", "urn:ietf:wg:oauth:2.0:oob")
164+
.build();
165+
166+
//Create empty body
167+
RequestBody reqBody = RequestBody.create(null, new byte[0]);
168+
169+
Request request = new Request.Builder()
170+
.url(url)
171+
.method("POST", reqBody)
172+
.build();
173+
Response response = null;
174+
try {
175+
response = client.newCall(request).execute();
176+
} catch (IOException e) {
177+
throw new RemoteServerException("Network Request failed to fetch tokenId", e);
178+
}
179+
180+
Moshi moshi = new Moshi.Builder().build();
181+
182+
GoogleAuthTokenJson googleAuth = null;
183+
try {
184+
googleAuth = moshi.adapter(GoogleAuthTokenJson.class).fromJson(response.body().string());
185+
Log.d(TAG, "" + googleAuth.getExpiresIn());
186+
} catch (IOException e) {
187+
throw new RemoteServerException("Failed to unmarshell the Json response to fetch tokenId", e);
188+
}
189+
;
190+
191+
192+
193+
194+
195+
196+
Log.d(TAG, "Got token: " + googleAuth.getAccessToken());
197+
198+
expiresTimestamp = time.currentTimeMillis()
199+
+ (googleAuth.getExpiresIn() * 1000 - REFRESH_TOKEN_BUFFER_TIME);
200+
tokenId = googleAuth.getIdToken();
201+
refreshToken = googleAuth.getRefreshToken();
202+
}
203+
204+
205+
206+
207+
@Override
208+
public String getTokenId() throws LoginFailedException, RemoteServerException {
209+
if (isTokenIdExpired()) {
210+
refreshToken(refreshToken);
211+
}
212+
return tokenId;
213+
}
214+
215+
/**
216+
* Refreshes tokenId if it has expired
217+
*
218+
* @return AuthInfo object
219+
* @throws LoginFailedException When login fails
220+
*/
221+
@Override
222+
public AuthInfo getAuthInfo() throws LoginFailedException, RemoteServerException {
223+
if (isTokenIdExpired()) {
224+
refreshToken(refreshToken);
225+
}
226+
authbuilder.setProvider("google");
227+
authbuilder.setToken(AuthInfo.JWT.newBuilder().setContents(tokenId).setUnknown2(59).build());
228+
return authbuilder.build();
229+
}
230+
231+
@Override
232+
public boolean isTokenIdExpired() {
233+
if (time.currentTimeMillis() > expiresTimestamp) {
234+
return true;
235+
} else {
236+
return false;
237+
}
238+
}
239+
240+
241+
}

src/main/java/com/pokegoapi/auth/PtcCredentialProvider.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ public Response intercept(Chain chain) throws IOException {
116116
* @param username Username
117117
* @param password password
118118
*/
119-
@Deprecated
120119
public PtcCredentialProvider(OkHttpClient client, String username, String password)
121120
throws LoginFailedException, RemoteServerException {
122121
this(client, username, password, new SystemTimeImpl());
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* This program is free software: you can redistribute it and/or modify
3+
* it under the terms of the GNU General Public License as published by
4+
* the Free Software Foundation, either version 3 of the License, or
5+
* (at your option) any later version.
6+
*
7+
* This program is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
* GNU General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU General Public License
13+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
14+
*/
15+
16+
package com.pokegoapi.examples;
17+
18+
19+
import com.pokegoapi.auth.GoogleUserCredentialProvider;
20+
import com.pokegoapi.exceptions.LoginFailedException;
21+
import com.pokegoapi.exceptions.RemoteServerException;
22+
import okhttp3.OkHttpClient;
23+
24+
25+
import java.util.Scanner;
26+
27+
public class GoogleUserInteractionExample {
28+
29+
30+
public static void main(String[] args) {
31+
OkHttpClient http = new OkHttpClient();
32+
GoogleUserCredentialProvider provider = null;
33+
try {
34+
35+
provider = new GoogleUserCredentialProvider(http);
36+
System.out.println("Please go to " + provider.LOGIN_URL);
37+
System.out.println("Enter authorisation code:");
38+
Scanner sc = new Scanner(System.in);
39+
String access = sc.nextLine();
40+
provider.login(access);
41+
System.out.println("Refresh token:" + provider.getRefreshToken());
42+
} catch (LoginFailedException | RemoteServerException e) {
43+
e.printStackTrace();
44+
}
45+
46+
}
47+
}

0 commit comments

Comments
 (0)