fix(shorebird_cli): send idToken via Authorization header (#250)
This commit is contained in:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user