diff --git a/integration_test/piv_test.dart b/integration_test/piv_test.dart index d31dac6e..85c6ba48 100644 --- a/integration_test/piv_test.dart +++ b/integration_test/piv_test.dart @@ -34,87 +34,121 @@ void main() { group('PIV Settings', skip: isAndroid, () { const factoryPin = '123456'; const factoryPuk = '12345678'; - appTest('Reset PIV (settings-init)', (WidgetTester tester) async { + const uno = 'abcdabcd'; + const due = 'bcdabcda'; + const tre = 'cdabcdab'; + + appTest('reset PIV (settings-init)', (WidgetTester tester) async { await tester.resetPiv(); await tester.shortWait(); }); - appTest('Lock PIN, unlock with PUK', (WidgetTester tester) async { - await tester.configurePiv(); - await tester.shortWait(); - await tester.tap(find.byKey(managePinAction).hitTestable()); - await tester.shortWait(); - await tester.lockPinPuk(); - await tester.shortWait(); - await tester.tap(find.byKey(actionsIconButtonKey).hitTestable()); - /// TODO: This expect needs to verify that Pin subtitle is 'Blocked' - /// expect(find.byKey(managePinAction), find.byTooltip('Blocked')); + appTest('pin lock-unlock', (WidgetTester tester) async { + await tester.resetPiv(); await tester.shortWait(); + + await tester.pinView(); + await tester.pivFirst(); + + await tester.longWait(); + await tester.pinView(); + await tester.longWait(); + + await tester.pivLockTest(); + + await tester.sendKeyEvent(LogicalKeyboardKey.escape); + await tester.shortWait(); + + await tester.tap(find.byKey(actionsIconButtonKey).hitTestable()); + await tester.longWait(); + + expect(find.text('Blocked, use PUK to reset'), findsOne); + await tester.tap(find.byKey(managePinAction).hitTestable()); await tester.shortWait(); - await tester.enterText(find.byKey(pinPukField).hitTestable(), factoryPuk); - await tester.shortWait(); - await tester.enterText( - find.byKey(newPinPukField).hitTestable(), factoryPin); - await tester.shortWait(); - await tester.enterText( - find.byKey(confirmPinPukField).hitTestable(), factoryPin); - await tester.shortWait(); - await tester.tap(find.byKey(saveButton).hitTestable()); - await tester.shortWait(); - await tester.sendKeyEvent(LogicalKeyboardKey.escape); + + // PUK field is pre-filled + await tester.pivFirst(); + await tester.tap(find.byKey(actionsIconButtonKey).hitTestable()); await tester.longWait(); - await tester.resetPiv(); + + expect(find.text('Blocked, use PUK to reset'), findsNothing); }); - appTest('Lock PUK, lock PIN, factory reset', (WidgetTester tester) async { - await tester.configurePiv(); - await tester.shortWait(); - await tester.tap(find.byKey(managePukAction).hitTestable()); - await tester.shortWait(); - await tester.lockPinPuk(); - await tester.shortWait(); - await tester.tap(find.byKey(actionsIconButtonKey).hitTestable()); - /// TODO: This expect needs to verify that PUK underline is 'Blocked' - /// expect(find.byKey(managePukAction), find.byTooltip('Blocked')); - - await tester.shortWait(); - await tester.tap(find.byKey(managePinAction).hitTestable()); - await tester.shortWait(); - await tester.lockPinPuk(); - await tester.shortWait(); - await tester.tap(find.byKey(actionsIconButtonKey).hitTestable()); - - /// TODO: This expect needs to verify that Pin underline is 'Blocked' - /// expect(find.byKey(managePinAction), find.byTooltip('Blocked')); - - await tester.shortWait(); - await tester.tap(find.byKey(managePinAction).hitTestable()); - await tester.shortWait(); - await tester.tap(find.byKey(managePukAction).hitTestable()); - await tester.shortWait(); - await tester.sendKeyEvent(LogicalKeyboardKey.escape); - await tester.longWait(); + appTest('lock PUK, lock PIN, factory reset', (WidgetTester tester) async { await tester.resetPiv(); + await tester.shortWait(); + + // set first pin/puk + await tester.pinView(); + await tester.pivFirst(); + await tester.pukView(); + await tester.pivFirst(); + + // lock pin and puk + await tester.pinView(); + await tester.pivLockTest(); + await tester.sendKeyEvent(LogicalKeyboardKey.escape); + await tester.shortWait(); + await tester.pukView(); + await tester.pivLockTest(); + await tester.sendKeyEvent(LogicalKeyboardKey.escape); + await tester.shortWait(); + + // verify blockedness + + await tester.tap(find.byKey(actionsIconButtonKey).hitTestable()); + await tester.shortWait(); + + expect(find.text('Blocked, factory reset needed'), findsAny); + + await tester.sendKeyEvent(LogicalKeyboardKey.escape); + await tester.shortWait(); }); appTest('Change PIN', (WidgetTester tester) async { - const newpin = '123123'; - await tester.configurePiv(); - await tester.tap(find.byKey(managePinAction).hitTestable()); + await tester.resetPiv(); await tester.shortWait(); - await tester.enterText(find.byKey(pinPukField).hitTestable(), factoryPin); + + //reset factorypin + await tester.pinView(); + await tester.pivFirst(); + + // onepin + await tester.pinView(); + await tester.enterText(find.byKey(pinPukField).hitTestable(), 'firstpin'); await tester.shortWait(); - await tester.enterText(find.byKey(newPinPukField).hitTestable(), newpin); + await tester.enterText(find.byKey(newPinPukField).hitTestable(), uno); await tester.shortWait(); - await tester.enterText( - find.byKey(confirmPinPukField).hitTestable(), newpin); + await tester.enterText(find.byKey(confirmPinPukField).hitTestable(), uno); await tester.shortWait(); await tester.tap(find.byKey(saveButton).hitTestable()); - await tester.longWait(); - await tester.configurePiv(); - await tester.tap(find.byKey(managePinAction).hitTestable()); await tester.shortWait(); - await tester.enterText(find.byKey(pinPukField).hitTestable(), newpin); + + // onepin + await tester.pinView(); + await tester.enterText(find.byKey(pinPukField).hitTestable(), uno); + await tester.shortWait(); + await tester.enterText(find.byKey(newPinPukField).hitTestable(), due); + await tester.shortWait(); + await tester.enterText(find.byKey(confirmPinPukField).hitTestable(), due); + await tester.shortWait(); + await tester.tap(find.byKey(saveButton).hitTestable()); + await tester.shortWait(); + + // onepin + await tester.pinView(); + await tester.enterText(find.byKey(pinPukField).hitTestable(), due); + await tester.shortWait(); + await tester.enterText(find.byKey(newPinPukField).hitTestable(), tre); + await tester.shortWait(); + await tester.enterText(find.byKey(confirmPinPukField).hitTestable(), tre); + await tester.shortWait(); + await tester.tap(find.byKey(saveButton).hitTestable()); + await tester.shortWait(); + + // factorpin + await tester.pinView(); + await tester.enterText(find.byKey(pinPukField).hitTestable(), tre); await tester.shortWait(); await tester.enterText( find.byKey(newPinPukField).hitTestable(), factoryPin); @@ -123,26 +157,52 @@ void main() { find.byKey(confirmPinPukField).hitTestable(), factoryPin); await tester.shortWait(); await tester.tap(find.byKey(saveButton).hitTestable()); - await tester.longWait(); + await tester.shortWait(); }); appTest('Change PUK', (WidgetTester tester) async { - const newpuk = '12341234'; - await tester.configurePiv(); - await tester.tap(find.byKey(managePukAction).hitTestable()); + await tester.resetPiv(); await tester.shortWait(); - await tester.enterText(find.byKey(pinPukField).hitTestable(), factoryPuk); + + //reset factorypuk + await tester.pinView(); + await tester.pivFirst(); + + // onepin + await tester.pinView(); + await tester.enterText(find.byKey(pinPukField).hitTestable(), 'firstpin'); await tester.shortWait(); - await tester.enterText(find.byKey(newPinPukField).hitTestable(), newpuk); + await tester.enterText(find.byKey(newPinPukField).hitTestable(), uno); await tester.shortWait(); - await tester.enterText( - find.byKey(confirmPinPukField).hitTestable(), newpuk); + await tester.enterText(find.byKey(confirmPinPukField).hitTestable(), uno); await tester.shortWait(); await tester.tap(find.byKey(saveButton).hitTestable()); - await tester.longWait(); - await tester.configurePiv(); - await tester.tap(find.byKey(managePukAction).hitTestable()); await tester.shortWait(); - await tester.enterText(find.byKey(pinPukField).hitTestable(), newpuk); + + // onepin + await tester.pinView(); + await tester.enterText(find.byKey(pinPukField).hitTestable(), uno); + await tester.shortWait(); + await tester.enterText(find.byKey(newPinPukField).hitTestable(), due); + await tester.shortWait(); + await tester.enterText(find.byKey(confirmPinPukField).hitTestable(), due); + await tester.shortWait(); + await tester.tap(find.byKey(saveButton).hitTestable()); + await tester.shortWait(); + + // onepin + await tester.pinView(); + await tester.enterText(find.byKey(pinPukField).hitTestable(), due); + await tester.shortWait(); + await tester.enterText(find.byKey(newPinPukField).hitTestable(), tre); + await tester.shortWait(); + await tester.enterText(find.byKey(confirmPinPukField).hitTestable(), tre); + await tester.shortWait(); + await tester.tap(find.byKey(saveButton).hitTestable()); + await tester.shortWait(); + + // factorpuk + await tester.pinView(); + await tester.enterText(find.byKey(pinPukField).hitTestable(), tre); await tester.shortWait(); await tester.enterText( find.byKey(newPinPukField).hitTestable(), factoryPuk); @@ -151,7 +211,7 @@ void main() { find.byKey(confirmPinPukField).hitTestable(), factoryPuk); await tester.shortWait(); await tester.tap(find.byKey(saveButton).hitTestable()); - await tester.longWait(); + await tester.shortWait(); }); group('PIV Management Key', () { const newmanagementkey = @@ -162,6 +222,9 @@ void main() { 'aaaabbbbccccaaaabbbbccccaaaabbbbccccaaaabbbbccc'; appTest('Out of bounds managementkey key', (WidgetTester tester) async { + await tester.resetPiv(); + await tester.shortWait(); + await tester.configurePiv(); await tester.shortWait(); await tester.tap(find.byKey(manageManagementKeyAction).hitTestable()); diff --git a/integration_test/utils/piv_test_util.dart b/integration_test/utils/piv_test_util.dart index 7b636da5..e58cce94 100644 --- a/integration_test/utils/piv_test_util.dart +++ b/integration_test/utils/piv_test_util.dart @@ -22,30 +22,112 @@ import 'package:yubico_authenticator/piv/keys.dart'; import 'test_util.dart'; extension PIVFunctions on WidgetTester { + static const ett = 'firstpin'; + static const lock1 = 'lockpinn1'; + static const lock2 = 'lockpinn2'; + static const lock3 = 'lockpinn3'; + /// Open the PIV Configuration Future configurePiv() async { - // 1. open PIV view - var pivDrawerButton = find.byKey(pivAppDrawer).hitTestable(); - await tap(pivDrawerButton); - await longWait(); + await tap(find.byKey(pivAppDrawer).hitTestable()); + await shortWait(); await tap(find.byKey(actionsIconButtonKey).hitTestable()); + await shortWait(); + } + + Future pinView() async { + await tap(find.byKey(pivAppDrawer).hitTestable()); + await shortWait(); + await tap(find.byKey(actionsIconButtonKey).hitTestable()); + await shortWait(); + await tap(find.byKey(managePinAction)); + await shortWait(); + } + + Future pukView() async { + await tap(find.byKey(pivAppDrawer).hitTestable()); + await shortWait(); + await tap(find.byKey(actionsIconButtonKey).hitTestable()); + await shortWait(); + await tap(find.byKey(managePukAction)); + await shortWait(); + } + + Future managementKeyView() async { + await tap(find.byKey(pivAppDrawer).hitTestable()); + await shortWait(); + await tap(find.byKey(actionsIconButtonKey).hitTestable()); + await shortWait(); + await tap(find.byKey(manageManagementKeyAction)); + await shortWait(); + } + + Future pivFirst() async { + // when in pin or puk view, remove factorypin/puk + await enterText(find.byKey(newPinPukField), ett); + await shortWait(); + await enterText(find.byKey(confirmPinPukField), ett); + await shortWait(); + await tap(find.byKey(saveButton).hitTestable()); + await shortWait(); + } + + Future pivLockTest() async { + // when in pin or puk view this will lock it + var pintext1 = 'lockpin1'; + await enterText(find.byKey(pinPukField), pintext1); + await shortWait(); + await enterText(find.byKey(newPinPukField), pintext1); + await shortWait(); + await enterText(find.byKey(confirmPinPukField), pintext1); + await shortWait(); + await tap(find.byKey(saveButton).hitTestable()); + await shortWait(); + + var pintext2 = 'lockpin2'; + await enterText(find.byKey(pinPukField), pintext2); + await shortWait(); + await enterText(find.byKey(newPinPukField), pintext2); + await shortWait(); + await enterText(find.byKey(confirmPinPukField), pintext2); + await shortWait(); + await tap(find.byKey(saveButton).hitTestable()); + await shortWait(); + + var pintext3 = 'lockpin3'; + await enterText(find.byKey(pinPukField), pintext3); + await shortWait(); + await enterText(find.byKey(newPinPukField), pintext3); + await shortWait(); + await enterText(find.byKey(confirmPinPukField), pintext3); + await shortWait(); + await tap(find.byKey(saveButton).hitTestable()); await longWait(); } - /// Locks PIN or PUK - Future lockPinPuk() async { - for (var i = 0; i < 3; i += 1) { - var wrongpin = '123456$i'; - await enterText(find.byKey(pinPukField).hitTestable(), wrongpin); - await shortWait(); - await enterText(find.byKey(newPinPukField).hitTestable(), wrongpin); - await shortWait(); - await enterText(find.byKey(confirmPinPukField).hitTestable(), wrongpin); - await shortWait(); - await tap(find.byKey(saveButton).hitTestable()); - await longWait(); - } + Future pivLock() async { + // when in pin or puk view this will lock it + // for (var i = 0; i < 3; i += 1) { + + await enterText(find.byKey(pinPukField), 'skrivhär'); + await shortWait(); + await enterText(find.byKey(newPinPukField), lock1); + await shortWait(); + await enterText(find.byKey(confirmPinPukField), lock1); + await shortWait(); + await tap(find.byKey(saveButton).hitTestable()); + await shortWait(); + await enterText(find.byKey(pinPukField), lock2); + await shortWait(); + await enterText(find.byKey(newPinPukField), lock2); + await shortWait(); + await enterText(find.byKey(confirmPinPukField), lock2); + await shortWait(); + await tap(find.byKey(saveButton).hitTestable()); + await shortWait(); + // } await sendKeyEvent(LogicalKeyboardKey.escape); + await shortWait(); } /// Factory reset Piv application @@ -56,19 +138,23 @@ extension PIVFunctions on WidgetTester { await switchToKey(targetKey); await shortWait(); - /// 2. open the key menu - await tapPopupMenu(targetKey); + /// 2. open the home view + await tap(find.byKey(homeDrawer).hitTestable()); await shortWait(); - await tap(find.byKey(yubikeyFactoryResetMenuButton).hitTestable()); - await longWait(); - /// 3. then toggle 'Piv' in the 'Factory reset' reset_dialog.dart + /// 3. open menu + await tap(find.byKey(actionsIconButtonKey).hitTestable()); + await shortWait(); + await tap(find.byKey(yubikeyFactoryResetMenuButton)); + await shortWait(); + + /// 4. then toggle 'Piv' in the 'Factory reset' reset_dialog.dart await tap(find.byKey(factoryResetPickResetPiv)); await longWait(); - /// 4. Click reset TextButton: done + /// 5. Click reset TextButton: done await tap(find.byKey(factoryResetReset)); - await shortWait(); + await ultraLongWait(); // 5. Verify Resetedness // /// TODO: this expect algorithm is flaky diff --git a/lib/home/views/key_actions.dart b/lib/home/views/key_actions.dart index b0c13e30..de19cf56 100644 --- a/lib/home/views/key_actions.dart +++ b/lib/home/views/key_actions.dart @@ -58,6 +58,7 @@ Widget homeBuildActions( title: deviceData.info.version.major > 4 ? l10n.s_toggle_applications : l10n.s_toggle_interfaces, + key: yubikeyApplicationToggleMenuButton, subtitle: interfacesLocked ? l10n.l_factory_reset_required : (deviceData.info.version.major > 4 @@ -83,6 +84,7 @@ Widget homeBuildActions( ActionListItem( icon: const Icon(Symbols.delete_forever), title: l10n.s_factory_reset, + key: yubikeyFactoryResetMenuButton, subtitle: l10n.l_factory_reset_desc, actionStyle: ActionStyle.primary, onTap: (context) { diff --git a/lib/piv/views/manage_key_dialog.dart b/lib/piv/views/manage_key_dialog.dart index c6fac2c9..f310eb76 100644 --- a/lib/piv/views/manage_key_dialog.dart +++ b/lib/piv/views/manage_key_dialog.dart @@ -292,7 +292,7 @@ class _ManageKeyDialogState extends ConsumerState { }, ).init(), AppTextField( - key: keys.newPinPukField, + //key: keys.newPinPukField, autofocus: _defaultKeyUsed, autofillHints: const [AutofillHints.newPassword], maxLength: hexLength,