2121import com .google .auth .oauth2 .AccessToken ;
2222import com .google .auth .oauth2 .GoogleCredentials ;
2323import com .google .auth .oauth2 .ServiceAccountCredentials ;
24+ import com .google .common .collect .ImmutableSet ;
2425
2526import java .io .IOException ;
2627import java .io .InputStream ;
@@ -37,32 +38,42 @@ public abstract class AuthCredentials implements Restorable<AuthCredentials> {
3738
3839 private static class AppEngineAuthCredentials extends AuthCredentials {
3940
40- private static final AuthCredentials INSTANCE = new AppEngineAuthCredentials ();
41- private static final AppEngineAuthCredentialsState STATE = new AppEngineAuthCredentialsState ();
41+ private final Collection <String > scopes ;
4242
4343 private static class AppEngineCredentials extends GoogleCredentials {
4444
4545 private final Object appIdentityService ;
46+ private final Method getAccessToken ;
47+ private final Method getAccessTokenResult ;
4648 private final Collection <String > scopes ;
4749 private final boolean scopesRequired ;
4850
49- AppEngineCredentials () {
51+ AppEngineCredentials (Collection < String > scopes ) {
5052 try {
5153 Class <?> factoryClass =
5254 Class .forName ("com.google.appengine.api.appidentity.AppIdentityServiceFactory" );
5355 Method method = factoryClass .getMethod ("getAppIdentityService" );
5456 this .appIdentityService = method .invoke (null );
55- this .scopes = null ;
56- this .scopesRequired = true ;
57+ Class <?> serviceClass =
58+ Class .forName ("com.google.appengine.api.appidentity.AppIdentityService" );
59+ Class <?> tokenResultClass = Class .forName (
60+ "com.google.appengine.api.appidentity.AppIdentityService$GetAccessTokenResult" );
61+ this .getAccessTokenResult = serviceClass .getMethod ("getAccessToken" , Iterable .class );
62+ this .getAccessToken = tokenResultClass .getMethod ("getAccessToken" );
63+ this .scopes = scopes ;
64+ this .scopesRequired = (scopes == null || scopes .isEmpty ());
5765 } catch (Exception e ) {
5866 throw new RuntimeException ("Could not create AppEngineCredentials using reflection." );
5967 }
6068 }
6169
62- AppEngineCredentials (Collection <String > scopes , Object appIdentityService ) {
63- this .appIdentityService = appIdentityService ;
64- this .scopes = scopes ;
65- this .scopesRequired = (scopes == null || scopes .isEmpty ());
70+ AppEngineCredentials (Collection <String > scopes , Object appIdentityService ,
71+ Method getAccessToken , Method getAccessTokenResult ) {
72+ this .appIdentityService = appIdentityService ;
73+ this .getAccessToken = getAccessToken ;
74+ this .getAccessTokenResult = getAccessTokenResult ;
75+ this .scopes = scopes ;
76+ this .scopesRequired = (scopes == null || scopes .isEmpty ());
6677 }
6778
6879 /**
@@ -74,13 +85,7 @@ public AccessToken refreshAccessToken() throws IOException {
7485 throw new IOException ("AppEngineCredentials requires createScoped call before use." );
7586 }
7687 try {
77- Class <?> serviceClass =
78- Class .forName ("com.google.appengine.api.appidentity.AppIdentityService" );
79- Class <?> tokenResultClass = Class .forName (
80- "com.google.appengine.api.appidentity.AppIdentityService$GetAccessTokenResult" );
81- Method getAccessTokenResult = serviceClass .getMethod ("getAccessToken" , Iterable .class );
8288 Object accessTokenResult = getAccessTokenResult .invoke (appIdentityService , scopes );
83- Method getAccessToken = tokenResultClass .getMethod ("getAccessToken" );
8489 String accessToken = (String ) getAccessToken .invoke (accessTokenResult );
8590 return new AccessToken (accessToken , null );
8691 } catch (Exception e ) {
@@ -95,7 +100,8 @@ public boolean createScopedRequired() {
95100
96101 @ Override
97102 public GoogleCredentials createScoped (Collection <String > scopes ) {
98- return new AppEngineCredentials (scopes , appIdentityService );
103+ return new AppEngineCredentials (
104+ scopes , appIdentityService , getAccessToken , getAccessTokenResult );
99105 }
100106 }
101107
@@ -104,9 +110,15 @@ private static class AppEngineAuthCredentialsState
104110
105111 private static final long serialVersionUID = 3558563960848658928L ;
106112
113+ private final Collection <String > scopes ;
114+
115+ private AppEngineAuthCredentialsState (Collection <String > scopes ) {
116+ this .scopes = scopes ;
117+ }
118+
107119 @ Override
108120 public AuthCredentials restore () {
109- return INSTANCE ;
121+ return new AppEngineAuthCredentials ( scopes ) ;
110122 }
111123
112124 @ Override
@@ -120,14 +132,18 @@ public boolean equals(Object obj) {
120132 }
121133 }
122134
135+ AppEngineAuthCredentials (Collection <String > scopes ) {
136+ this .scopes = scopes != null ? ImmutableSet .copyOf (scopes ) : null ;
137+ }
138+
123139 @ Override
124- protected GoogleCredentials credentials () {
125- return new AppEngineCredentials ();
140+ public GoogleCredentials credentials () {
141+ return new AppEngineCredentials (null );
126142 }
127143
128144 @ Override
129145 public RestorableState <AuthCredentials > capture () {
130- return STATE ;
146+ return new AppEngineAuthCredentialsState ( scopes ) ;
131147 }
132148 }
133149
@@ -176,7 +192,7 @@ public boolean equals(Object obj) {
176192 }
177193
178194 @ Override
179- protected GoogleCredentials credentials () {
195+ public GoogleCredentials credentials () {
180196 return new ServiceAccountCredentials (null , account , privateKey , null , null );
181197 }
182198
@@ -232,29 +248,20 @@ public boolean equals(Object obj) {
232248 }
233249
234250 @ Override
235- protected GoogleCredentials credentials () {
251+ public GoogleCredentials credentials () {
236252 return googleCredentials ;
237253 }
238254
239- public ServiceAccountAuthCredentials toServiceAccountCredentials () {
240- if (googleCredentials instanceof ServiceAccountCredentials ) {
241- ServiceAccountCredentials credentials = (ServiceAccountCredentials ) googleCredentials ;
242- return new ServiceAccountAuthCredentials (credentials .getClientEmail (),
243- credentials .getPrivateKey ());
244- }
245- return null ;
246- }
247-
248255 @ Override
249256 public RestorableState <AuthCredentials > capture () {
250257 return STATE ;
251258 }
252259 }
253260
254- protected abstract GoogleCredentials credentials ();
261+ public abstract GoogleCredentials credentials ();
255262
256263 public static AuthCredentials createForAppEngine () {
257- return AppEngineAuthCredentials . INSTANCE ;
264+ return new AppEngineAuthCredentials ( null ) ;
258265 }
259266
260267 /**
@@ -297,11 +304,12 @@ public static ServiceAccountAuthCredentials createFor(String account, PrivateKey
297304 * Account Authentication</a>.
298305 * </p>
299306 *
300- * @param jsonCredentialStream stream for Service Account Credentials in JSON format
307+ * @param jsonCredentialStream stream for Service Account Credentials or User Credentials in JSON
308+ * format
301309 * @return the credentials instance.
302310 * @throws IOException if the credentials cannot be created from the stream.
303311 */
304- public static ServiceAccountAuthCredentials createForJson (InputStream jsonCredentialStream )
312+ public static AuthCredentials createForJson (InputStream jsonCredentialStream )
305313 throws IOException {
306314 GoogleCredentials tempCredentials = GoogleCredentials .fromStream (jsonCredentialStream );
307315 if (tempCredentials instanceof ServiceAccountCredentials ) {
@@ -310,9 +318,9 @@ public static ServiceAccountAuthCredentials createForJson(InputStream jsonCreden
310318 return new ServiceAccountAuthCredentials (
311319 tempServiceAccountCredentials .getClientEmail (),
312320 tempServiceAccountCredentials .getPrivateKey ());
313- } else {
314- throw new IOException (
315- "The given JSON Credentials Stream is not a service account credential." );
316321 }
322+ throw new IOException (
323+ "The given JSON credentials stream could not be parsed as service account credentials or"
324+ + " user credentials." );
317325 }
318326}
0 commit comments