18
18
19
19
import static com .google .common .base .Preconditions .checkNotNull ;
20
20
21
- import com .google .api .client .googleapis .auth .oauth2 .GoogleCredential ;
22
- import com .google .api .client .googleapis .extensions .appengine .auth .oauth2 .AppIdentityCredential ;
23
- import com .google .api .client .http .HttpRequestInitializer ;
24
- import com .google .api .client .http .HttpTransport ;
25
- import com .google .api .client .json .jackson .JacksonFactory ;
26
- import com .google .auth .http .HttpCredentialsAdapter ;
21
+ import com .google .auth .oauth2 .AccessToken ;
27
22
import com .google .auth .oauth2 .GoogleCredentials ;
28
23
import com .google .auth .oauth2 .ServiceAccountCredentials ;
29
24
30
25
import java .io .IOException ;
31
26
import java .io .InputStream ;
32
27
import java .io .Serializable ;
28
+ import java .lang .reflect .Method ;
33
29
import java .security .PrivateKey ;
30
+ import java .util .Collection ;
34
31
import java .util .Objects ;
35
- import java .util .Set ;
36
32
37
33
/**
38
34
* Credentials for accessing Google Cloud services.
@@ -42,8 +38,67 @@ public abstract class AuthCredentials implements Restorable<AuthCredentials> {
42
38
private static class AppEngineAuthCredentials extends AuthCredentials {
43
39
44
40
private static final AuthCredentials INSTANCE = new AppEngineAuthCredentials ();
45
- private static final AppEngineAuthCredentialsState STATE =
46
- new AppEngineAuthCredentialsState ();
41
+ private static final AppEngineAuthCredentialsState STATE = new AppEngineAuthCredentialsState ();
42
+
43
+ private static class AppEngineCredentials extends GoogleCredentials {
44
+
45
+ private final Object appIdentityService ;
46
+ private final Method getAccessToken ;
47
+ private final Method getAccessTokenResult ;
48
+ private final Collection <String > scopes ;
49
+
50
+ AppEngineCredentials () {
51
+ try {
52
+ Class <?> factoryClass =
53
+ Class .forName ("com.google.appengine.api.appidentity.AppIdentityServiceFactory" );
54
+ Method method = factoryClass .getMethod ("getAppIdentityService" );
55
+ this .appIdentityService = method .invoke (null );
56
+ Class <?> serviceClass =
57
+ Class .forName ("com.google.appengine.api.appidentity.AppIdentityService" );
58
+ Class <?> tokenResultClass = Class .forName (
59
+ "com.google.appengine.api.appidentity.AppIdentityService$GetAccessTokenResult" );
60
+ this .getAccessTokenResult = serviceClass .getMethod ("getAccessToken" , Iterable .class );
61
+ this .getAccessToken = tokenResultClass .getMethod ("getAccessToken" );
62
+ this .scopes = null ;
63
+ } catch (Exception e ) {
64
+ throw new RuntimeException ("Could not create AppEngineCredentials." , e );
65
+ }
66
+ }
67
+
68
+ AppEngineCredentials (Collection <String > scopes , AppEngineCredentials unscoped ) {
69
+ this .appIdentityService = unscoped .appIdentityService ;
70
+ this .getAccessToken = unscoped .getAccessToken ;
71
+ this .getAccessTokenResult = unscoped .getAccessTokenResult ;
72
+ this .scopes = scopes ;
73
+ }
74
+
75
+ /**
76
+ * Refresh the access token by getting it from the App Identity service
77
+ */
78
+ @ Override
79
+ public AccessToken refreshAccessToken () throws IOException {
80
+ if (createScopedRequired ()) {
81
+ throw new IOException ("AppEngineCredentials requires createScoped call before use." );
82
+ }
83
+ try {
84
+ Object accessTokenResult = getAccessTokenResult .invoke (appIdentityService , scopes );
85
+ String accessToken = (String ) getAccessToken .invoke (accessTokenResult );
86
+ return new AccessToken (accessToken , null );
87
+ } catch (Exception e ) {
88
+ throw new IOException ("Could not get the access token." , e );
89
+ }
90
+ }
91
+
92
+ @ Override
93
+ public boolean createScopedRequired () {
94
+ return scopes == null || scopes .isEmpty ();
95
+ }
96
+
97
+ @ Override
98
+ public GoogleCredentials createScoped (Collection <String > scopes ) {
99
+ return new AppEngineCredentials (scopes , this );
100
+ }
101
+ }
47
102
48
103
private static class AppEngineAuthCredentialsState
49
104
implements RestorableState <AuthCredentials >, Serializable {
@@ -67,9 +122,8 @@ public boolean equals(Object obj) {
67
122
}
68
123
69
124
@ Override
70
- protected HttpRequestInitializer httpRequestInitializer (HttpTransport transport ,
71
- Set <String > scopes ) {
72
- return new AppIdentityCredential (scopes );
125
+ public GoogleCredentials credentials () {
126
+ return new AppEngineCredentials ();
73
127
}
74
128
75
129
@ Override
@@ -83,8 +137,6 @@ public static class ServiceAccountAuthCredentials extends AuthCredentials {
83
137
private final String account ;
84
138
private final PrivateKey privateKey ;
85
139
86
- private static final AuthCredentials NO_CREDENTIALS = new ServiceAccountAuthCredentials ();
87
-
88
140
private static class ServiceAccountAuthCredentialsState
89
141
implements RestorableState <AuthCredentials >, Serializable {
90
142
@@ -100,9 +152,6 @@ private ServiceAccountAuthCredentialsState(String account, PrivateKey privateKey
100
152
101
153
@ Override
102
154
public AuthCredentials restore () {
103
- if (account == null && privateKey == null ) {
104
- return NO_CREDENTIALS ;
105
- }
106
155
return new ServiceAccountAuthCredentials (account , privateKey );
107
156
}
108
157
@@ -127,23 +176,9 @@ public boolean equals(Object obj) {
127
176
this .privateKey = checkNotNull (privateKey );
128
177
}
129
178
130
- ServiceAccountAuthCredentials () {
131
- account = null ;
132
- privateKey = null ;
133
- }
134
-
135
179
@ Override
136
- protected HttpRequestInitializer httpRequestInitializer (
137
- HttpTransport transport , Set <String > scopes ) {
138
- GoogleCredential .Builder builder = new GoogleCredential .Builder ()
139
- .setTransport (transport )
140
- .setJsonFactory (new JacksonFactory ());
141
- if (privateKey != null ) {
142
- builder .setServiceAccountPrivateKey (privateKey );
143
- builder .setServiceAccountId (account );
144
- builder .setServiceAccountScopes (scopes );
145
- }
146
- return builder .build ();
180
+ public ServiceAccountCredentials credentials () {
181
+ return new ServiceAccountCredentials (null , account , privateKey , null , null );
147
182
}
148
183
149
184
public String account () {
@@ -198,18 +233,8 @@ public boolean equals(Object obj) {
198
233
}
199
234
200
235
@ Override
201
- protected HttpRequestInitializer httpRequestInitializer (HttpTransport transport ,
202
- Set <String > scopes ) {
203
- return new HttpCredentialsAdapter (googleCredentials .createScoped (scopes ));
204
- }
205
-
206
- public ServiceAccountAuthCredentials toServiceAccountCredentials () {
207
- if (googleCredentials instanceof ServiceAccountCredentials ) {
208
- ServiceAccountCredentials credentials = (ServiceAccountCredentials ) googleCredentials ;
209
- return new ServiceAccountAuthCredentials (credentials .getClientEmail (),
210
- credentials .getPrivateKey ());
211
- }
212
- return null ;
236
+ public GoogleCredentials credentials () {
237
+ return googleCredentials ;
213
238
}
214
239
215
240
@ Override
@@ -218,8 +243,7 @@ public RestorableState<AuthCredentials> capture() {
218
243
}
219
244
}
220
245
221
- protected abstract HttpRequestInitializer httpRequestInitializer (HttpTransport transport ,
222
- Set <String > scopes );
246
+ public abstract GoogleCredentials credentials ();
223
247
224
248
public static AuthCredentials createForAppEngine () {
225
249
return AppEngineAuthCredentials .INSTANCE ;
@@ -271,12 +295,15 @@ public static ServiceAccountAuthCredentials createFor(String account, PrivateKey
271
295
*/
272
296
public static ServiceAccountAuthCredentials createForJson (InputStream jsonCredentialStream )
273
297
throws IOException {
274
- GoogleCredential tempCredentials = GoogleCredential .fromStream (jsonCredentialStream );
275
- return new ServiceAccountAuthCredentials (tempCredentials .getServiceAccountId (),
276
- tempCredentials .getServiceAccountPrivateKey ());
277
- }
278
-
279
- public static AuthCredentials noCredentials () {
280
- return ServiceAccountAuthCredentials .NO_CREDENTIALS ;
298
+ GoogleCredentials tempCredentials = GoogleCredentials .fromStream (jsonCredentialStream );
299
+ if (tempCredentials instanceof ServiceAccountCredentials ) {
300
+ ServiceAccountCredentials tempServiceAccountCredentials =
301
+ (ServiceAccountCredentials ) tempCredentials ;
302
+ return new ServiceAccountAuthCredentials (
303
+ tempServiceAccountCredentials .getClientEmail (),
304
+ tempServiceAccountCredentials .getPrivateKey ());
305
+ }
306
+ throw new IOException (
307
+ "The given JSON Credentials Stream is not for a service account credential." );
281
308
}
282
309
}
0 commit comments