blob: 69aac72fa2b5c8d472a17a9e5ec9e777d532fdaf [file] [log] [blame]
import 'package:http/http.dart';
import '../access_credentials.dart';
import '../auth_client.dart';
import '../auth_functions.dart';
import '../auth_http_utils.dart';
import '../http_client_base.dart';
/// Base class for "Flows" that provide [AccessCredentials].
abstract class BaseFlow {
Future<AccessCredentials> run();
}
Future<AutoRefreshingAuthClient> clientFromFlow(
BaseFlow Function(Client client) flowFactory, {
Client? baseClient,
}) async {
if (baseClient == null) {
baseClient = Client();
} else {
baseClient = nonClosingClient(baseClient);
}
final flow = flowFactory(baseClient);
try {
final credentials = await flow.run();
return _FlowClient(baseClient, credentials, flow);
} catch (e) {
baseClient.close();
rethrow;
}
}
// Will close the underlying `http.Client`.
class _FlowClient extends AutoRefreshDelegatingClient {
final BaseFlow _flow;
@override
AccessCredentials credentials;
Client _authClient;
_FlowClient(super.client, this.credentials, this._flow)
: _authClient = authenticatedClient(client, credentials);
@override
Future<StreamedResponse> send(BaseRequest request) async {
if (credentials.accessToken.hasExpired) {
final newCredentials = await _flow.run();
notifyAboutNewCredentials(newCredentials);
credentials = newCredentials;
_authClient = authenticatedClient(baseClient, credentials);
}
return _authClient.send(request);
}
}