diff --git a/packages/shorebird_cli/lib/src/auth/auth.dart b/packages/shorebird_cli/lib/src/auth/auth.dart index 75f68373..45120398 100644 --- a/packages/shorebird_cli/lib/src/auth/auth.dart +++ b/packages/shorebird_cli/lib/src/auth/auth.dart @@ -35,6 +35,20 @@ typedef ObtainAccessCredentials = Future 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 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 login(void Function(String) prompt) async { diff --git a/packages/shorebird_cli/test/src/auth/auth_test.dart b/packages/shorebird_cli/test/src/auth/auth_test.dart index 9c78f172..bc176d3e 100644 --- a/packages/shorebird_cli/test/src/auth/auth_test.dart +++ b/packages/shorebird_cli/test/src/auth/auth_test.dart @@ -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()); - expect(client, isA()); + expect(client, isA()); + + 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(