Skip to content

Commit

Permalink
feat(#661): make auth cancelable
Browse files Browse the repository at this point in the history
  • Loading branch information
tamslo committed Nov 14, 2024
1 parent d8a8f87 commit b970407
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 17 deletions.
20 changes: 15 additions & 5 deletions app/lib/login/cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ class LoginCubit extends Cubit<LoginState> {
// signInAndLoadUserData authenticates a user with a Lab and fetches their
// genomic data from it's endpoint.
Future<void> signInAndLoadUserData(BuildContext context, Lab lab) async {
emit(LoginState.loadingUserData(null));
emit(LoginState.loadingUserData(
lab.authLoadingMessage(),
cancelable: lab.cancelAuthInApp,
));
try {
await lab.authenticate();
} on LabAuthenticationCanceled {
} on LabProcessCanceled {
revertToInitialState();
return;
} on LabAuthenticationError {
Expand All @@ -29,13 +32,18 @@ class LoginCubit extends Cubit<LoginState> {
return;
}

if (lab.authenticationWasCanceled) {
lab.authenticationWasCanceled = false;
return;
}

try {
final loadingMessage = shouldFetchDiplotypes()
// ignore: use_build_context_synchronously
? context.l10n.auth_loading_data
// ignore: use_build_context_synchronously
: context.l10n.auth_updating_data;
emit(LoginState.loadingUserData(loadingMessage));
emit(LoginState.loadingUserData(loadingMessage, ));
if (shouldFetchDiplotypes()) {
final (labData, activeDrugList) = await lab.loadData();
await saveDiplotypesAndActiveDrugs(
Expand All @@ -59,8 +67,10 @@ class LoginCubit extends Cubit<LoginState> {
@freezed
class LoginState with _$LoginState {
const factory LoginState.initial() = _InitialState;
const factory LoginState.loadingUserData(String? loadingMessage) =
_LoadingUserDataState;
const factory LoginState.loadingUserData(
String? loadingMessage,
{bool? cancelable}
) = _LoadingUserDataState;
const factory LoginState.loadedUserData() = _LoadedUserDataState;
const factory LoginState.error(String string) = _ErrorState;
}
20 changes: 16 additions & 4 deletions app/lib/login/models/app_share_flow_lab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,29 @@ class AppShareFlowLab extends Lab {
late Uri publishUrl;
late Map<String, String>? publishHeaders;

@override
// ignore: overridden_fields
bool cancelAuthInApp = true;

@override
String? authLoadingMessage() =>
'Please open the $shareAppName and share your data with PharMe';

@override
Future<void> authenticate() async {
// THIS IS FOR TESTING, SHOULD WAIT UNTIL A DEEP LINK IS RECEIVED
// (if possible like this but could set metadata field when deep link
// caught and wait here until it was set)
await Future.delayed(Duration(seconds: 7));
}

@override
Future<(List<LabResult>, List<String>)> loadData() async {
// THIS IS FOR TESTING, SHOULD GET FROM DWA
publishUrl = Uri.parse(
'https://hpi-datastore.duckdns.org/userdata?id=1e006a69-b693-43d2-a318-22904e305b5c',
);
publishHeaders = null;
}

@override
Future<(List<LabResult>, List<String>)> loadData() async {
return fetchData(
publishUrl,
headers: publishHeaders,
Expand Down
8 changes: 6 additions & 2 deletions app/lib/login/models/lab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import 'package:http/http.dart' as http;

import '../../common/module.dart';

class LabAuthenticationCanceled implements Exception {
LabAuthenticationCanceled();
class LabProcessCanceled implements Exception {
LabProcessCanceled();
}

class LabAuthenticationError implements Exception {
Expand All @@ -18,6 +18,10 @@ class Lab {
});

String name;
bool cancelAuthInApp = false;
bool authenticationWasCanceled = false;

String? authLoadingMessage() => null;

Future<void> authenticate() async {}
Future<(List<LabResult>, List<String>)> loadData() async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class OAuthAuthorizationCodeFlowLab extends Lab {
token = jsonDecode(response.body)['access_token'] as String;
} on PlatformException catch (e) {
if (e.code == 'CANCELED') {
throw LabAuthenticationCanceled();
throw LabProcessCanceled();
}
}
if (token == null) {
Expand Down
25 changes: 20 additions & 5 deletions app/lib/login/pages/login.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
import '../../../common/module.dart';
import '../cubit.dart';
import '../models/app_share_flow_lab.dart';
import '../models/lab.dart';
import '../models/oauth_authorization_code_flow_lab.dart';

final labs = [
Expand All @@ -28,6 +29,10 @@ class LoginPage extends HookWidget {

final LoginCubit? cubit;

Lab _getSelectedLab(ValueNotifier<String> dropdownValue) => labs.firstWhere(
(lab) => lab.name == dropdownValue.value,
);

@override
Widget build(BuildContext context) {
final dropdownValue = useState(labs.first.name);
Expand All @@ -41,7 +46,7 @@ class LoginPage extends HookWidget {
child: state.when(
initial: () =>
_buildInitialScreen(context, dropdownValue),
loadingUserData: (loadingMessage) => Padding(
loadingUserData: (loadingMessage, cancelable) => Padding(
padding: EdgeInsets.all(PharMeTheme.largeSpace),
child: Column(
children: [
Expand All @@ -54,6 +59,19 @@ class LoginPage extends HookWidget {
textAlign: TextAlign.center,
),
],
if (cancelable ?? false) ...[
SizedBox(height: PharMeTheme.largeSpace),
FullWidthButton(
context.l10n.action_cancel,
() {
final selectedLab = _getSelectedLab(dropdownValue);
selectedLab.authenticationWasCanceled = true;
context
.read<LoginCubit>()
.revertToInitialState();
}
)
],
],
),
),
Expand All @@ -73,12 +91,9 @@ class LoginPage extends HookWidget {
ValueNotifier<String> dropdownValue,
) {
Future<void> action() async {
final selectedLab = labs.firstWhere(
(el) => el.name == dropdownValue.value,
);
await context
.read<LoginCubit>()
.signInAndLoadUserData(context, selectedLab);
.signInAndLoadUserData(context, _getSelectedLab(dropdownValue));
}

return _buildColumnWrapper(
Expand Down

0 comments on commit b970407

Please sign in to comment.