Refactor AppFailurePage.

This commit is contained in:
Dain Nilsson 2022-05-20 17:19:39 +02:00
parent f33087fd0f
commit 9cce216e9f
No known key found for this signature in database
GPG Key ID: F04367096FBA95E8
5 changed files with 102 additions and 98 deletions

View File

@ -0,0 +1,83 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../desktop/models.dart';
import '../../desktop/state.dart';
import '../../theme.dart';
import '../message.dart';
import 'graphics.dart';
import 'message_page.dart';
class AppFailurePage extends ConsumerWidget {
final Widget? title;
final Object cause;
const AppFailurePage({this.title, required this.cause, super.key}) : super();
@override
Widget build(BuildContext context, WidgetRef ref) {
final reason = cause;
Widget? graphic = const Icon(Icons.error);
String? header = 'An error has occured';
String? message = reason.toString();
List<Widget> actions = [];
if (reason is RpcError) {
if (reason.status == 'connection-error') {
switch (reason.body['connection']) {
case 'ccid':
header = 'Failed to open smart card connection';
if (Platform.isMacOS) {
message = 'Try to remove and re-insert your YubiKey.';
} else if (Platform.isLinux) {
message = 'Make sure pcscd is running.';
} else {
message = 'Make sure your smart card service is functioning.';
}
break;
case 'fido':
if (Platform.isWindows &&
!ref.watch(rpcStateProvider.select((state) => state.isAdmin))) {
graphic = noPermission;
header = null;
message = 'WebAuthn management requires elevated privileges.';
actions = [
OutlinedButton.icon(
label: const Text('Unlock'),
icon: const Icon(Icons.lock_open),
style: AppTheme.primaryOutlinedButtonStyle(context),
onPressed: () async {
final controller = showMessage(
context, 'Elevating permissions...',
duration: const Duration(seconds: 30));
try {
if (await ref.read(rpcProvider).elevate()) {
ref.refresh(rpcProvider);
} else {
showMessage(context, 'Permission denied');
}
} finally {
controller.close();
}
}),
];
}
break;
default:
header = 'Failed to open connection';
message = 'Try to remove and re-insert your YubiKey.';
}
}
}
return MessagePage(
title: title,
graphic: graphic,
header: header,
message: message,
actions: actions,
);
}
}

View File

@ -1,50 +0,0 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:yubico_authenticator/desktop/models.dart';
class AppFailureScreen extends StatelessWidget {
final Object reason;
const AppFailureScreen(this.reason, {super.key}) : super();
@override
Widget build(BuildContext context) {
final cause = reason;
if (cause is RpcError) {
if (cause.status == 'connection-error' &&
cause.body['connection'] == 'ccid') {
var msg = 'Failed to open smart card connection';
if (Platform.isMacOS) {
msg += '\nTry to remove and re-insert your YubiKey to regain access.';
} else if (Platform.isLinux) {
msg += '\nMake sure pcscd is running.';
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
msg,
textAlign: TextAlign.center,
),
],
),
);
}
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
cause.toString(),
textAlign: TextAlign.center,
),
],
),
);
}
}

View File

@ -1,19 +1,12 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../app/message.dart';
import '../../app/models.dart';
import '../../app/views/app_failure_screen.dart';
import '../../app/views/app_failure_page.dart';
import '../../app/views/app_loading_screen.dart';
import '../../app/views/app_page.dart';
import '../../app/views/graphics.dart';
import '../../app/views/message_page.dart';
import '../../desktop/models.dart';
import '../../desktop/state.dart';
import '../../management/models.dart';
import '../../theme.dart';
import '../state.dart';
import 'locked_page.dart';
import 'unlocked_page.dart';
@ -53,41 +46,10 @@ class FidoScreen extends ConsumerWidget {
'WebAuthn requires the FIDO2 application to be enabled on your YubiKey',
);
}
if (Platform.isWindows && error is RpcError) {
if (error.status == 'connection-error' &&
!ref.watch(
rpcStateProvider.select((state) => state.isAdmin))) {
return MessagePage(
title: const Text('WebAuthn'),
graphic: noPermission,
message: 'WebAuthn management requires elevated privileges.',
actions: [
OutlinedButton.icon(
label: const Text('Unlock'),
icon: const Icon(Icons.lock_open),
style: AppTheme.primaryOutlinedButtonStyle(context),
onPressed: () async {
final controller = showMessage(
context, 'Elevating permissions...',
duration: const Duration(seconds: 30));
try {
if (await ref.read(rpcProvider).elevate()) {
ref.refresh(rpcProvider);
} else {
showMessage(context, 'Permission denied');
}
} finally {
controller.close();
}
}),
],
);
}
}
return AppPage(
return AppFailurePage(
title: const Text('WebAuthn'),
centered: true,
child: AppFailureScreen(error),
cause: error,
);
},
data: (fidoState) {

View File

@ -5,7 +5,6 @@ import 'package:collection/collection.dart';
import '../../app/message.dart';
import '../../app/models.dart';
import '../../app/state.dart';
import '../../app/views/app_failure_screen.dart';
import '../../app/views/app_loading_screen.dart';
import '../../core/models.dart';
import '../../widgets/responsive_dialog.dart';
@ -241,7 +240,18 @@ class _ManagementScreenState extends ConsumerState<ManagementScreen> {
final child =
ref.watch(managementStateProvider(widget.deviceData.node.path)).when(
loading: () => const AppLoadingScreen(),
error: (error, _) => AppFailureScreen(error),
error: (error, _) => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
error.toString(),
textAlign: TextAlign.center,
),
],
),
),
data: (info) {
bool hasConfig = info.version.major > 4;
if (hasConfig) {

View File

@ -6,7 +6,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../app/message.dart';
import '../../app/models.dart';
import '../../app/views/app_failure_screen.dart';
import '../../app/views/app_failure_page.dart';
import '../../app/views/app_loading_screen.dart';
import '../../app/views/app_page.dart';
import '../../app/views/graphics.dart';
@ -31,10 +31,9 @@ class OathScreen extends ConsumerWidget {
centered: true,
child: const AppLoadingScreen(),
),
error: (error, _) => AppPage(
error: (error, _) => AppFailurePage(
title: const Text('Authenticator'),
centered: true,
child: AppFailureScreen(error),
cause: error,
),
data: (oathState) => oathState.locked
? _LockedView(devicePath, oathState)