Skip to content

Commit 3ebe7d1

Browse files
authored
Move signBlob to a function, remove IAMSigner class (#717)
Also readme cleanup
1 parent e6d0a9c commit 3ebe7d1

15 files changed

+163
-300
lines changed

googleapis_auth/CHANGELOG.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
## 2.1.0-wip
1+
## 2.1.0
22

3-
- `AuthClient`
4-
- Added `serviceAccountCredentials` getter.
5-
- Added `sign()` method via `AuthClientSigningExtension`.
3+
- `AuthClientSigningExtension`: Added `sign()` which accepts an optional `serviceAccountCredentials` argument, and `getServiceAccountEmail()` which accepts an optional `email` argument.
64
- `ServiceAccountCredentials`
75
- Added parsing for `projectId` and `universeDomain` properties.
86
- Added `sign()` method for RSA-SHA256 signing.
9-
- `IAMSigner`
10-
- Now uses the unified metadata cache from `package:google_cloud`.
7+
- Added `signBlob()` function for signing via IAM Credentials API.
118
- `MetadataServerAuthorizationFlow`
129
- Now uses `getMetadataValue` (caching) and `fetchMetadataValue`
1310
(non-caching) from `package:google_cloud`.

googleapis_auth/README.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ This package also provides convenience functionality for:
55
- obtaining authenticated HTTP clients
66
- automatically refreshing OAuth2 credentials
77

8+
> [!WARNING]
89
> Do _**NOT**_ use this package (`package:googleapis_auth`) with a
910
> [Flutter](https://flutter.dev/) application.
1011
>
@@ -47,11 +48,12 @@ After the Client ID has been created, you can obtain access credentials via
4748
```dart
4849
import 'package:googleapis_auth/auth_browser.dart';
4950
50-
// Initialize the browser oauth2 flow functionality then use it to obtain credentials.
51+
// Initialize the browser oauth2 flow functionality then use it to obtain
52+
// credentials.
5153
Future<AccessCredentials> obtainCredentials() => requestAccessCredentials(
52-
clientId: '....apps.googleusercontent.com',
53-
scopes: ['scope1', 'scope2'],
54-
);
54+
clientId: '....apps.googleusercontent.com',
55+
scopes: ['scope1', 'scope2'],
56+
);
5557
```
5658

5759
or obtain an authenticated HTTP client via
@@ -207,7 +209,7 @@ Here is an example of getting an HTTP client which uses an API key for making
207209
HTTP requests.
208210

209211
```dart
210-
import "package:googleapis_auth/auth_io.dart";
212+
import 'package:googleapis_auth/auth_io.dart';
211213
212214
var client = clientViaApiKey('<api-key-from-devconsole>');
213215
// [client] can now be used to make REST calls to Google APIs.
@@ -240,11 +242,16 @@ class MicrosoftAuthEndpoints extends AuthEndpoints {
240242
This can then be used to obtain credentials:
241243

242244
```dart
245+
final clientId = ClientId('my-client-id', 'my-client-secret');
243246
final credentials = await obtainAccessCredentialsViaUserConsent(
244247
clientId,
245248
['scope1', 'scope2'],
246249
client,
247-
prompt,
250+
(url) {
251+
print('Please go to the following URL and grant access:');
252+
print(' => $url');
253+
print('');
254+
},
248255
authEndpoints: MicrosoftAuthEndpoints(),
249256
);
250257
```

googleapis_auth/lib/googleapis_auth.dart

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
///
99
/// In most cases, you'll want to import either
1010
/// [auth_io] or [auth_browser] depending on your platform.
11+
///
1112
/// {@canonicalFor access_credentials.AccessCredentials}
1213
/// {@canonicalFor access_token.AccessToken}
1314
/// {@canonicalFor auth_client.AuthClient}
@@ -19,10 +20,23 @@
1920
/// {@canonicalFor client_id.ClientId}
2021
/// {@canonicalFor exceptions.AccessDeniedException}
2122
/// {@canonicalFor exceptions.ServerRequestFailedException}
22-
/// {@canonicalFor exceptions.RefreshFailedException}
2323
/// {@canonicalFor exceptions.UserConsentException}
2424
/// {@canonicalFor response_type.ResponseType}
2525
/// {@canonicalFor service_account_credentials.ServiceAccountCredentials}
26+
///
27+
/// {@template googleapis_auth_returned_auto_refresh_client}
28+
/// Returns an [AutoRefreshingAuthClient] that will automatically refresh the
29+
/// [AccessCredentials] before they expire.
30+
/// {@endtemplate}
31+
///
32+
/// {@template googleapis_auth_user_consent_return}
33+
/// Returns the [AccessCredentials] containing the access token.
34+
/// {@endtemplate}
35+
///
36+
/// {@template googleapis_auth_client_for_creds}
37+
/// The provided `client` will be used for making the HTTP requests needed to
38+
/// create the returned [AccessCredentials].
39+
/// {@endtemplate}
2640
library;
2741

2842
export 'src/auth_client.dart';

googleapis_auth/lib/src/auth_client.dart

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,6 @@ import '../auth_io.dart';
1010
abstract class AuthClient implements Client {
1111
/// The credentials currently used for making HTTP requests.
1212
AccessCredentials get credentials;
13-
14-
/// The service account credentials used to create this client, if any.
15-
///
16-
/// Returns `null` if this client was not created via
17-
/// [clientViaServiceAccount] or if the underlying credentials are not
18-
/// service account credentials.
19-
ServiceAccountCredentials? get serviceAccountCredentials;
2013
}
2114

2215
/// A auto-refreshing, authenticated HTTP client.

googleapis_auth/lib/src/auth_client_signing_extension.dart

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ library;
77

88
import 'dart:convert';
99

10+
import 'package:google_cloud/general.dart';
1011
import 'iam_signer.dart';
1112
import 'impersonated_auth_client.dart';
1213
import 'service_account_credentials.dart';
13-
import 'utils.dart';
1414

1515
/// Extension providing smart signing capabilities for [AuthClient].
1616
///
@@ -41,21 +41,17 @@ import 'utils.dart';
4141
/// final signature = await client.sign(utf8.encode('data to sign'));
4242
/// ```
4343
extension AuthClientSigningExtension on AuthClient {
44-
/// Returns the service account email associated with this client.
45-
///
46-
/// If the client was created with explicit [ServiceAccountCredentials],
47-
/// returns the email from those credentials.
48-
///
49-
/// Otherwise, queries the GCE metadata server to retrieve the default
44+
/// Queries the GCE metadata server to retrieve the default
5045
/// service account email.
5146
///
52-
/// The result is cached for the lifetime of the Dart process by the
53-
/// underlying [IAMSigner].
47+
/// The result is cached for the lifetime of the Dart process.
5448
///
5549
/// If [refresh] is `true`, the cache is cleared and the value is re-computed.
5650
Future<String> getServiceAccountEmail({bool refresh = false}) async =>
57-
serviceAccountCredentials?.email ??
58-
await IAMSigner(this).getServiceAccountEmail(refresh: refresh);
51+
await serviceAccountEmailFromMetadataServer(
52+
client: this,
53+
refresh: refresh,
54+
);
5955

6056
/// Signs some bytes using the credentials from this auth client.
6157
///
@@ -67,7 +63,8 @@ extension AuthClientSigningExtension on AuthClient {
6763
/// - Other auth clients: Uses IAM signBlob API with the default service
6864
/// account.
6965
///
70-
/// [data] is the bytes to be signed.
66+
/// [serviceAccountCredentials] can be provided to sign the data locally
67+
/// using RSA-SHA256 if the credentials have a private key.
7168
///
7269
/// [endpoint] is an optional custom IAM Credentials API endpoint. This is
7370
/// useful when working with different universe domains. If not provided,
@@ -83,28 +80,28 @@ extension AuthClientSigningExtension on AuthClient {
8380
///
8481
/// final client = await clientViaServiceAccount(credentials, scopes);
8582
/// final data = utf8.encode('data to sign');
86-
/// final signature = await client.sign(data);
83+
/// final signature = await client.sign(
84+
/// data,
85+
/// serviceAccountCredentials: credentials,
86+
/// );
8787
/// print('Signature (base64): ${signature.signedBlob}');
8888
/// ```
89-
Future<String> sign(List<int> data, {String? endpoint}) async {
89+
Future<String> sign(
90+
List<int> data, {
91+
ServiceAccountCredentials? serviceAccountCredentials,
92+
String? endpoint,
93+
}) async {
9094
// Check if this is an impersonated client
9195
if (this is ImpersonatedAuthClient) {
9296
final impersonated = this as ImpersonatedAuthClient;
9397
return (await impersonated.sign(data)).signedBlob;
9498
}
9599

96-
// Check if we have service account credentials for local signing
97-
final serviceAccountCreds = serviceAccountCredentials;
98-
99-
if (serviceAccountCreds != null) {
100+
if (serviceAccountCredentials != null) {
100101
// Use local signing with service account credentials
101-
return base64Encode(serviceAccountCreds.sign(data));
102+
return base64Encode(serviceAccountCredentials.sign(data));
102103
}
103104

104-
// If we're NOT using local signing, use IAM API signing
105-
final universeDomain =
106-
serviceAccountCreds?.universeDomain ?? defaultUniverseDomain;
107-
endpoint ??= 'https://iamcredentials.$universeDomain';
108-
return (await IAMSigner(this, endpoint: endpoint).sign(data)).signedBlob;
105+
return (await signBlob(this, data, endpoint: endpoint)).signedBlob;
109106
}
110107
}

googleapis_auth/lib/src/auth_http_utils.dart

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ class AuthenticatedClient extends DelegatingClient implements AuthClient {
2424
super.closeUnderlyingClient = false,
2525
});
2626

27-
@override
28-
ServiceAccountCredentials? get serviceAccountCredentials => null;
29-
3027
@override
3128
Future<StreamedResponse> send(BaseRequest request) async {
3229
// Make new request object and perform the authenticated request.
@@ -113,9 +110,6 @@ class AutoRefreshingClient extends AutoRefreshDelegatingClient {
113110
);
114111
}
115112

116-
@override
117-
ServiceAccountCredentials? get serviceAccountCredentials => null;
118-
119113
@override
120114
Future<StreamedResponse> send(BaseRequest request) async {
121115
if (!credentials.accessToken.hasExpired) {

0 commit comments

Comments
 (0)