71 lines
2.3 KiB
Dart
71 lines
2.3 KiB
Dart
|
|
import 'package:halkyon_app/src/auth/model/session_grant.dart';
|
||
|
|
import 'package:halkyon_app/src/base/base_client.dart';
|
||
|
|
import 'package:halkyon_base_client/halkyon_base_client.dart' as protocol;
|
||
|
|
import 'package:http/http.dart' as http;
|
||
|
|
import 'package:serverpod_auth_idp_flutter/serverpod_auth_idp_flutter.dart';
|
||
|
|
|
||
|
|
/// The calls a gateway makes on an instance's halkyon_base for someone
|
||
|
|
/// other than the device's person: without a session, through a client of
|
||
|
|
/// halkyon_base holding none (Serverpod issues no session for another
|
||
|
|
/// person inside a signed-in call), and with a session granted but not yet
|
||
|
|
/// the device's, through a client holding that one. Each client is the
|
||
|
|
/// call's own, closed after.
|
||
|
|
final class BaseCalls(
|
||
|
|
final ServerpodClientShared _client, {
|
||
|
|
|
||
|
|
/// The module's endpoints on the app's client, as the device's person.
|
||
|
|
required final protocol.Caller _base,
|
||
|
|
|
||
|
|
/// What the clients it makes for itself send through; tests give a fake.
|
||
|
|
final http.Client Function()? _httpClient,
|
||
|
|
}) {
|
||
|
|
/// What [call] gives on a client of halkyon_base without a session.
|
||
|
|
Future<T> signedOut<T>(Future<T> Function(BaseClient base) call) async {
|
||
|
|
final client = BaseClient(
|
||
|
|
_client.host,
|
||
|
|
httpClientOverride: _httpClient?.call(),
|
||
|
|
);
|
||
|
|
try {
|
||
|
|
return await call(client);
|
||
|
|
} finally {
|
||
|
|
client.close();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// What [call] gives on the device's session, or on [grant]'s, kept in
|
||
|
|
/// memory by a client of its own.
|
||
|
|
Future<T> asGrant<T>(
|
||
|
|
SessionGrant? grant,
|
||
|
|
Future<T> Function(protocol.Caller base) call,
|
||
|
|
) async {
|
||
|
|
if (grant == null) {
|
||
|
|
return await call(_base);
|
||
|
|
}
|
||
|
|
final sessionManager = FlutterAuthSessionManager(
|
||
|
|
storage: _MemorySessionStorage(),
|
||
|
|
);
|
||
|
|
final client = BaseClient(
|
||
|
|
_client.host,
|
||
|
|
httpClientOverride: _httpClient?.call(),
|
||
|
|
)..authSessionManager = sessionManager;
|
||
|
|
try {
|
||
|
|
await sessionManager.updateSignedInUser(grant.session as AuthSuccess);
|
||
|
|
return await call(client.modules);
|
||
|
|
} finally {
|
||
|
|
client.close();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Keeps one session in memory, for a client used once.
|
||
|
|
final class _MemorySessionStorage() implements ClientAuthSuccessStorage {
|
||
|
|
AuthSuccess? _session;
|
||
|
|
|
||
|
|
@override
|
||
|
|
Future<AuthSuccess?> get() async => _session;
|
||
|
|
|
||
|
|
@override
|
||
|
|
Future<void> set(AuthSuccess? data) async {
|
||
|
|
_session = data;
|
||
|
|
}
|
||
|
|
}
|