fix(shorebird_cli): send idToken via Authorization header (#250)

This commit is contained in:
Felix Angelov
2023-04-06 17:48:46 -05:00
committed by GitHub
parent fa07e6f4d3
commit 6ecb5b8395
2 changed files with 40 additions and 4 deletions
+17 -2
View File
@@ -35,6 +35,20 @@ typedef ObtainAccessCredentials = Future<AccessCredentials> Function(
void Function(String) userPrompt,
);
class AuthenticatedClient extends http.BaseClient {
AuthenticatedClient({required this.token, required http.Client httpClient})
: _baseClient = httpClient;
final http.Client _baseClient;
final String token;
@override
Future<http.StreamedResponse> send(http.BaseRequest request) {
request.headers['Authorization'] = 'Bearer $token';
return _baseClient.send(request);
}
}
class Auth {
Auth({
http.Client? httpClient,
@@ -52,8 +66,9 @@ class Auth {
final credentialsFilePath = p.join(shorebirdConfigDir, _credentialsFileName);
http.Client get client {
if (_credentials == null) return _httpClient;
return autoRefreshingClient(_clientId, _credentials!, _httpClient);
final token = _credentials?.idToken;
if (token == null) return _httpClient;
return AuthenticatedClient(token: token, httpClient: _httpClient);
}
Future<void> login(void Function(String) prompt) async {
@@ -1,9 +1,13 @@
import 'dart:io';
import 'package:googleapis_auth/googleapis_auth.dart';
import 'package:http/http.dart' as http;
import 'package:mocktail/mocktail.dart';
import 'package:shorebird_cli/src/auth/auth.dart';
import 'package:test/test.dart';
class _FakeBaseRequest extends Fake implements http.BaseRequest {}
class _MockHttpClient extends Mock implements http.Client {}
class _MockAccessCredentials extends Mock implements AccessCredentials {}
@@ -24,6 +28,10 @@ void main() {
late AccessCredentials accessCredentials;
late Auth auth;
setUpAll(() {
registerFallbackValue(_FakeBaseRequest());
});
setUp(() {
httpClient = _MockHttpClient();
accessCredentials = _MockAccessCredentials();
@@ -37,12 +45,25 @@ void main() {
group('client', () {
test(
'returns an auto-refreshing client '
'returns an authenticated client '
'when credentials are present.', () async {
when(() => httpClient.send(any())).thenAnswer(
(_) async => http.StreamedResponse(
const Stream.empty(),
HttpStatus.ok,
),
);
await auth.login((_) {});
final client = auth.client;
expect(client, isA<http.Client>());
expect(client, isA<AutoRefreshingAuthClient>());
expect(client, isA<AuthenticatedClient>());
await client.get(Uri.parse('https://example.com'));
final captured = verify(() => httpClient.send(captureAny())).captured;
expect(captured, hasLength(1));
final request = captured.first as http.BaseRequest;
expect(request.headers['Authorization'], equals('Bearer $idToken'));
});
test(