Commit fa80be39 authored by David Jean's avatar David Jean Committed by Commit Bot

[ios] Refactor reauthentication module for re-use

Move from /ios/chrome/browser/settings/ui/password
to /ios/chrome/common/reauthenticaton

Moved metrics out of it and into (non test) callers.
Changed result from BOOL to 3 states enum for success,
failure and skipped.

The goal is to be able to use it in the credential extension.

Bug: 1045455
Change-Id: I94104044c82b637b9d183f07fc6d8ce291e5b7a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2089864
Commit-Queue: David Jean <djean@chromium.org>
Reviewed-by: default avatarSylvain Defresne <sdefresne@chromium.org>
Reviewed-by: default avatarOlivier Robin <olivierrobin@chromium.org>
Reviewed-by: default avatarGauthier Ambard <gambard@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748269}
parent 8851a2cf
......@@ -189,7 +189,6 @@ source_set("settings") {
allow_circular_includes_from = [ "//ios/chrome/browser/ui/authentication" ]
libs = [
"CoreLocation.framework",
"LocalAuthentication.framework",
"UIKit.framework",
]
}
......
......@@ -12,9 +12,6 @@ source_set("password") {
"password_exporter.mm",
"passwords_table_view_controller.h",
"passwords_table_view_controller.mm",
"reauthentication_module.h",
"reauthentication_module.mm",
"reauthentication_protocol.h",
]
deps = [
":password_constants",
......@@ -44,6 +41,7 @@ source_set("password") {
"//ios/chrome/browser/ui/table_view/cells:cells_constants",
"//ios/chrome/browser/ui/util",
"//ios/chrome/common/ui/colors",
"//ios/chrome/common/ui/reauthentication",
"//ios/chrome/common/ui/util",
"//ios/third_party/material_components_ios",
"//ui/base",
......@@ -66,7 +64,6 @@ source_set("test_support") {
sources = [
"password_details_table_view_controller+testing.h",
"password_exporter_for_testing.h",
"reauthentication_module_for_testing.h",
]
deps = [ ":password" ]
}
......@@ -78,7 +75,6 @@ source_set("unit_tests") {
"password_details_table_view_controller_unittest.mm",
"password_exporter_unittest.mm",
"passwords_table_view_controller_unittest.mm",
"reauthentication_module_unittest.mm",
]
deps = [
":password",
......@@ -100,6 +96,7 @@ source_set("unit_tests") {
"//ios/chrome/browser/ui/util",
"//ios/chrome/browser/web:test_support",
"//ios/chrome/common/ui/colors",
"//ios/chrome/common/ui/reauthentication",
"//ios/chrome/test/app:test_support",
"//ios/web/public/test",
"//ios/web/public/test",
......@@ -131,6 +128,7 @@ source_set("eg_test_support") {
"//components/prefs",
"//ios/chrome/browser/browser_state",
"//ios/chrome/browser/passwords",
"//ios/chrome/common/ui/reauthentication",
"//ios/chrome/test/app:test_support",
"//ios/third_party/material_components_ios",
"//url",
......@@ -156,6 +154,7 @@ source_set("eg_tests") {
"//ios/chrome/browser/ui/table_view/cells",
"//ios/chrome/browser/ui/table_view/cells:cells_constants",
"//ios/chrome/browser/ui/util",
"//ios/chrome/common/ui/reauthentication",
"//ios/chrome/test/earl_grey:test_support",
"//ios/testing/earl_grey:earl_grey_support",
"//ios/third_party/material_components_ios",
......@@ -192,6 +191,7 @@ source_set("eg_app_support+eg2") {
"//ios/chrome/app/strings:ios_strings_grit",
"//ios/chrome/browser/browser_state",
"//ios/chrome/browser/passwords",
"//ios/chrome/common/ui/reauthentication",
"//ios/chrome/test/app:test_support",
"//ios/testing/earl_grey:eg_app_support+eg2",
"//ios/third_party/material_components_ios",
......@@ -208,6 +208,8 @@ source_set("eg_test_support+eg2") {
testonly = true
sources = [ "passwords_settings_app_interface.h" ]
deps = [ "//ios/chrome/common/ui/reauthentication" ]
}
source_set("eg2_tests") {
......@@ -228,6 +230,7 @@ source_set("eg2_tests") {
"//ios/chrome/browser/ui/settings:settings_root_constants",
"//ios/chrome/browser/ui/table_view/cells:cells_constants",
"//ios/chrome/browser/ui/util",
"//ios/chrome/common/ui/reauthentication",
"//ios/chrome/test/earl_grey:eg_test_support+eg2",
"//ios/testing/earl_grey:eg_test_support+eg2",
"//ios/third_party/earl_grey2:test_lib",
......
......@@ -19,7 +19,6 @@
#import "ios/chrome/browser/ui/commands/browser_commands.h"
#import "ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h"
#import "ios/chrome/browser/ui/settings/password/passwords_table_view_controller.h"
#import "ios/chrome/browser/ui/settings/password/reauthentication_module.h"
#import "ios/chrome/browser/ui/settings/utils/settings_utils.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.h"
......@@ -28,6 +27,7 @@
#include "ios/chrome/browser/ui/ui_feature_flags.h"
#include "ios/chrome/browser/ui/util/uikit_ui_util.h"
#import "ios/chrome/common/ui/colors/semantic_color_names.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
#include "ios/chrome/grit/ios_strings.h"
#import "ios/third_party/material_components_ios/src/components/Snackbar/src/MaterialSnackbar.h"
#include "ui/base/l10n/l10n_util_mac.h"
......@@ -36,6 +36,9 @@
#error "This file requires ARC support."
#endif
using password_manager::metrics_util::LogPasswordSettingsReauthResult;
using password_manager::metrics_util::ReauthResult;
namespace {
typedef NS_ENUM(NSInteger, SectionIdentifier) {
......@@ -345,9 +348,13 @@ typedef NS_ENUM(NSInteger, ItemType) {
if ([_weakReauthenticationModule canAttemptReauth]) {
__weak PasswordDetailsTableViewController* weakSelf = self;
void (^showPasswordHandler)(BOOL) = ^(BOOL success) {
void (^showPasswordHandler)(ReauthenticationResult) = ^(
ReauthenticationResult result) {
PasswordDetailsTableViewController* strongSelf = weakSelf;
if (!strongSelf || !success)
if (!strongSelf)
return;
[strongSelf logPasswordSettingsReauthResult:result];
if (result == ReauthenticationResult::kFailure)
return;
TableViewTextItem* passwordItem = strongSelf->_passwordItem;
passwordItem.masked = NO;
......@@ -401,11 +408,13 @@ typedef NS_ENUM(NSInteger, ItemType) {
password_manager::metrics_util::ReauthResult::kSkipped);
} else if ([_weakReauthenticationModule canAttemptReauth]) {
__weak PasswordDetailsTableViewController* weakSelf = self;
void (^copyPasswordHandler)(BOOL) = ^(BOOL success) {
void (^copyPasswordHandler)(ReauthenticationResult) = ^(
ReauthenticationResult result) {
PasswordDetailsTableViewController* strongSelf = weakSelf;
if (!strongSelf)
return;
if (success) {
[strongSelf logPasswordSettingsReauthResult:result];
if (result != ReauthenticationResult::kFailure) {
UIPasteboard* generalPasteboard = [UIPasteboard generalPasteboard];
generalPasteboard.string = strongSelf->_password;
[strongSelf showToast:l10n_util::GetNSString(
......@@ -619,6 +628,24 @@ typedef NS_ENUM(NSInteger, ItemType) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
#pragma mark - Metrics
// Logs metrics for the given reauthentication result (success, failure or
// skipped).
- (void)logPasswordSettingsReauthResult:(ReauthenticationResult)result {
switch (result) {
case ReauthenticationResult::kSuccess:
LogPasswordSettingsReauthResult(ReauthResult::kSuccess);
break;
case ReauthenticationResult::kFailure:
LogPasswordSettingsReauthResult(ReauthResult::kFailure);
break;
case ReauthenticationResult::kSkipped:
LogPasswordSettingsReauthResult(ReauthResult::kSkipped);
break;
}
}
#pragma mark - ForTesting
- (void)setReauthenticationModule:
......
......@@ -7,10 +7,10 @@
#include "base/mac/foundation_util.h"
#include "base/strings/sys_string_conversions.h"
#include "components/autofill/core/common/password_form.h"
#import "ios/chrome/browser/ui/settings/password/reauthentication_module.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h"
#import "ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h"
#import "ios/chrome/browser/web/chrome_web_test.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
#include "ios/chrome/grit/ios_strings.h"
#include "ios/chrome/test/app/password_test_util.h"
#include "ios/web/public/test/web_task_environment.h"
......@@ -61,7 +61,7 @@ class PasswordDetailsTableViewControllerTest
void SetUp() override {
ChromeTableViewControllerTest::SetUp();
reauthentication_module_ = [[MockReauthenticationModule alloc] init];
reauthentication_module_.shouldSucceed = YES;
reauthentication_module_.expectedResult = ReauthenticationResult::kSuccess;
}
ChromeTableViewController* InstantiateController() override {
......
......@@ -18,7 +18,7 @@
#include "components/password_manager/core/browser/password_manager_metrics_util.h"
#include "components/password_manager/core/common/passwords_directory_util_ios.h"
#include "components/strings/grit/components_strings.h"
#import "ios/chrome/browser/ui/settings/password/reauthentication_module.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
#include "ios/chrome/grit/ios_strings.h"
#include "ui/base/l10n/l10n_util_mac.h"
......@@ -26,6 +26,9 @@
#error "This file requires ARC support."
#endif
using password_manager::metrics_util::LogPasswordSettingsReauthResult;
using password_manager::metrics_util::ReauthResult;
namespace {
enum class ReauthenticationStatus {
......@@ -206,14 +209,19 @@ enum class ReauthenticationStatus {
- (void)startReauthentication {
__weak PasswordExporter* weakSelf = self;
void (^onReauthenticationFinished)(BOOL) = ^(BOOL success) {
void (^onReauthenticationFinished)(ReauthenticationResult) =
^(ReauthenticationResult result) {
DCHECK(result != ReauthenticationResult::kSkipped);
PasswordExporter* strongSelf = weakSelf;
if (!strongSelf)
return;
if (success) {
strongSelf.reauthenticationStatus = ReauthenticationStatus::SUCCESSFUL;
if (result == ReauthenticationResult::kSuccess) {
LogPasswordSettingsReauthResult(ReauthResult::kSuccess);
strongSelf.reauthenticationStatus =
ReauthenticationStatus::SUCCESSFUL;
[strongSelf showPreparingPasswordsAlert];
} else {
LogPasswordSettingsReauthResult(ReauthResult::kFailure);
strongSelf.reauthenticationStatus = ReauthenticationStatus::FAILED;
}
[strongSelf tryExporting];
......
......@@ -127,7 +127,8 @@ class PasswordExporterTest : public PlatformTest {
// Tests that when reauthentication is successful, writing the passwords file
// is attempted and a call to show the activity view is made.
TEST_F(PasswordExporterTest, PasswordFileWriteReauthSucceeded) {
mock_reauthentication_module_.shouldSucceed = YES;
mock_reauthentication_module_.expectedResult =
ReauthenticationResult::kSuccess;
FakePasswordFileWriter* fake_password_file_writer =
[[FakePasswordFileWriter alloc] init];
fake_password_file_writer.writingStatus = WriteToURLStatus::SUCCESS;
......@@ -154,7 +155,8 @@ TEST_F(PasswordExporterTest, PasswordFileWriteReauthSucceeded) {
// the appropriate error is displayed and the export operation
// is interrupted.
TEST_F(PasswordExporterTest, WritingFailedOutOfDiskSpace) {
mock_reauthentication_module_.shouldSucceed = YES;
mock_reauthentication_module_.expectedResult =
ReauthenticationResult::kSuccess;
FakePasswordFileWriter* fake_password_file_writer =
[[FakePasswordFileWriter alloc] init];
fake_password_file_writer.writingStatus =
......@@ -192,7 +194,8 @@ TEST_F(PasswordExporterTest, WritingFailedOutOfDiskSpace) {
// enough disk space, the appropriate error is displayed and the export
// operation is interrupted.
TEST_F(PasswordExporterTest, WritingFailedUnknownError) {
mock_reauthentication_module_.shouldSucceed = YES;
mock_reauthentication_module_.expectedResult =
ReauthenticationResult::kSuccess;
FakePasswordFileWriter* fake_password_file_writer =
[[FakePasswordFileWriter alloc] init];
fake_password_file_writer.writingStatus = WriteToURLStatus::UNKNOWN_ERROR;
......@@ -227,7 +230,8 @@ TEST_F(PasswordExporterTest, WritingFailedUnknownError) {
// Tests that when reauthentication fails the export flow is interrupted.
TEST_F(PasswordExporterTest, ExportInterruptedWhenReauthFails) {
mock_reauthentication_module_.shouldSucceed = NO;
mock_reauthentication_module_.expectedResult =
ReauthenticationResult::kFailure;
FakePasswordSerialzerBridge* fake_password_serializer_bridge =
[[FakePasswordSerialzerBridge alloc] init];
[password_exporter_
......@@ -272,7 +276,8 @@ TEST_F(PasswordExporterTest, ExportInterruptedWhenReauthFails) {
// Tests that cancelling the export while serialization is still ongoing
// waits for it to finish before cleaning up.
TEST_F(PasswordExporterTest, CancelWaitsForSerializationFinished) {
mock_reauthentication_module_.shouldSucceed = YES;
mock_reauthentication_module_.expectedResult =
ReauthenticationResult::kSuccess;
FakePasswordSerialzerBridge* fake_password_serializer_bridge =
[[FakePasswordSerialzerBridge alloc] init];
[password_exporter_
......@@ -309,7 +314,8 @@ TEST_F(PasswordExporterTest, CancelWaitsForSerializationFinished) {
// Tests that if the export is cancelled before writing to file finishes
// successfully the request to show the activity controller isn't made.
TEST_F(PasswordExporterTest, CancelledBeforeWriteToFileFinishesSuccessfully) {
mock_reauthentication_module_.shouldSucceed = YES;
mock_reauthentication_module_.expectedResult =
ReauthenticationResult::kSuccess;
FakePasswordFileWriter* fake_password_file_writer =
[[FakePasswordFileWriter alloc] init];
fake_password_file_writer.writingStatus = WriteToURLStatus::SUCCESS;
......@@ -341,7 +347,8 @@ TEST_F(PasswordExporterTest, CancelledBeforeWriteToFileFinishesSuccessfully) {
// Tests that if the export is cancelled before writing to file fails
// with an error, the request to show the error alert isn't made.
TEST_F(PasswordExporterTest, CancelledBeforeWriteToFileFails) {
mock_reauthentication_module_.shouldSucceed = YES;
mock_reauthentication_module_.expectedResult =
ReauthenticationResult::kSuccess;
FakePasswordFileWriter* fake_password_file_writer =
[[FakePasswordFileWriter alloc] init];
fake_password_file_writer.writingStatus = WriteToURLStatus::UNKNOWN_ERROR;
......
......@@ -7,6 +7,8 @@
#import <UIKit/UIKit.h>
#import "ios/chrome/common/ui/reauthentication/reauthentication_protocol.h"
// EarlGreyScopedBlockSwizzlerAppInterface contains the app-side
// implementation for helpers. These helpers are compiled into
// the app binary and can be called from either app or test code.
......@@ -16,7 +18,8 @@
// view password) and its options for next test.
+ (void)setUpMockReauthenticationModule;
+ (void)setUpMockReauthenticationModuleForExport;
+ (void)mockReauthenticationModuleShouldSucceed:(BOOL)shouldSucceed;
+ (void)mockReauthenticationModuleExpectedResult:
(ReauthenticationResult)expectedResult;
+ (void)mockReauthenticationModuleCanAttempt:(BOOL)canAttempt;
// Dismisses snack bar. Used before next test.
......
......@@ -151,8 +151,9 @@ static MockReauthenticationModule* _mockReauthenticationModule;
SetUpAndReturnMockReauthenticationModuleForExport();
}
+ (void)mockReauthenticationModuleShouldSucceed:(BOOL)shouldSucceed {
_mockReauthenticationModule.shouldSucceed = shouldSucceed;
+ (void)mockReauthenticationModuleExpectedResult:
(ReauthenticationResult)expectedResult {
_mockReauthenticationModule.expectedResult = expectedResult;
}
+ (void)mockReauthenticationModuleCanAttempt:(BOOL)canAttempt {
......
......@@ -14,6 +14,7 @@
#import "ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h"
#import "ios/chrome/browser/ui/settings/settings_root_table_constants.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_protocol.h"
#include "ios/chrome/grit/ios_strings.h"
#import "ios/chrome/test/earl_grey/chrome_actions.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
......@@ -406,7 +407,8 @@ void TapEdit() {
performAction:grey_tap()];
[PasswordSettingsAppInterface setUpMockReauthenticationModule];
[PasswordSettingsAppInterface mockReauthenticationModuleShouldSucceed:YES];
[PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
ReauthenticationResult::kSuccess];
// Check the snackbar in case of successful reauthentication.
[GetInteractionForPasswordDetailItem(CopyPasswordButton())
......@@ -419,7 +421,8 @@ void TapEdit() {
performAction:grey_tap()];
// Check the snackbar in case of failed reauthentication.
[PasswordSettingsAppInterface mockReauthenticationModuleShouldSucceed:NO];
[PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
ReauthenticationResult::kFailure];
[GetInteractionForPasswordDetailItem(CopyPasswordButton())
performAction:grey_tap()];
......@@ -449,7 +452,8 @@ void TapEdit() {
performAction:grey_tap()];
[PasswordSettingsAppInterface setUpMockReauthenticationModule];
[PasswordSettingsAppInterface mockReauthenticationModuleShouldSucceed:YES];
[PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
ReauthenticationResult::kSuccess];
// Check the snackbar in case of successful reauthentication.
[GetInteractionForPasswordDetailItem(ShowPasswordButton())
......@@ -480,7 +484,8 @@ void TapEdit() {
performAction:grey_tap()];
[PasswordSettingsAppInterface setUpMockReauthenticationModule];
[PasswordSettingsAppInterface mockReauthenticationModuleShouldSucceed:NO];
[PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
ReauthenticationResult::kFailure];
// Check the snackbar in case of failed reauthentication.
[GetInteractionForPasswordDetailItem(ShowPasswordButton())
......@@ -882,7 +887,8 @@ void TapEdit() {
// end of the test, otherwise it might get deleted too soon and break the
// functionality of copying and viewing passwords.
[PasswordSettingsAppInterface setUpMockReauthenticationModule];
[PasswordSettingsAppInterface mockReauthenticationModuleShouldSucceed:YES];
[PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
ReauthenticationResult::kSuccess];
// Tap the context menu item for copying.
[[EarlGrey
......@@ -924,7 +930,8 @@ void TapEdit() {
// end of the test, otherwise it might get deleted too soon and break the
// functionality of copying and viewing passwords.
[PasswordSettingsAppInterface setUpMockReauthenticationModule];
[PasswordSettingsAppInterface mockReauthenticationModuleShouldSucceed:YES];
[PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
ReauthenticationResult::kSuccess];
// Tap the context menu item for showing.
[[EarlGrey
......@@ -1400,7 +1407,8 @@ void TapEdit() {
OpenPasswordSettings();
[PasswordSettingsAppInterface setUpMockReauthenticationModuleForExport];
[PasswordSettingsAppInterface mockReauthenticationModuleShouldSucceed:YES];
[PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
ReauthenticationResult::kSuccess];
[[EarlGrey
selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId(
......
......@@ -41,7 +41,6 @@
#import "ios/chrome/browser/ui/settings/password/password_details_table_view_controller_delegate.h"
#import "ios/chrome/browser/ui/settings/password/password_exporter.h"
#import "ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h"
#import "ios/chrome/browser/ui/settings/password/reauthentication_module.h"
#import "ios/chrome/browser/ui/settings/utils/pref_backed_boolean.h"
#import "ios/chrome/browser/ui/settings/utils/settings_utils.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
......@@ -55,6 +54,7 @@
#import "ios/chrome/browser/ui/util/uikit_ui_util.h"
#import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h"
#import "ios/chrome/common/ui/colors/semantic_color_names.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
#import "ios/chrome/common/ui/util/constraints_ui_util.h"
#include "ios/chrome/grit/ios_strings.h"
#include "ui/base/l10n/l10n_util_mac.h"
......
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
source_set("reauthentication") {
configs += [ "//build/config/compiler:enable_arc" ]
sources = [
"reauthentication_module.h",
"reauthentication_module.mm",
"reauthentication_protocol.h",
]
deps = [ "//base" ]
frameworks = [ "LocalAuthentication.framework" ]
}
source_set("test_support") {
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
sources = [ "reauthentication_module_for_testing.h" ]
deps = [ ":reauthentication" ]
}
source_set("unit_tests") {
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
sources = [ "reauthentication_module_unittest.mm" ]
deps = [
":reauthentication",
":test_support",
"//base",
"//base/test:test_support",
"//testing/gmock",
"//testing/gtest",
"//testing/gtest",
"//third_party/ocmock",
]
}
......@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_REAUTHENTICATION_MODULE_H_
#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_REAUTHENTICATION_MODULE_H_
#ifndef IOS_CHROME_COMMON_UI_REAUTHENTICATION_REAUTHENTICATION_MODULE_H_
#define IOS_CHROME_COMMON_UI_REAUTHENTICATION_REAUTHENTICATION_MODULE_H_
#import <Foundation/Foundation.h>
#import "ios/chrome/browser/ui/settings/password/reauthentication_protocol.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_protocol.h"
// A help article on how to set up a passcode.
extern const char kPasscodeArticleURL[];
......@@ -39,4 +39,4 @@ extern const char kPasscodeArticleURL[];
@end
#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_REAUTHENTICATION_MODULE_H_
#endif // IOS_CHROME_COMMON_UI_REAUTHENTICATION_REAUTHENTICATION_MODULE_H_
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/settings/password/reauthentication_module.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
#import <LocalAuthentication/LocalAuthentication.h>
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "components/password_manager/core/browser/password_manager_metrics_util.h"
#import "base/logging.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
......@@ -15,9 +13,6 @@
constexpr char kPasscodeArticleURL[] = "https://support.apple.com/HT204060";
using password_manager::metrics_util::LogPasswordSettingsReauthResult;
using password_manager::metrics_util::ReauthResult;
@implementation ReauthenticationModule {
// Block that creates a new |LAContext| object everytime one is required,
// meant to make testing with a mock object possible.
......@@ -51,10 +46,11 @@ using password_manager::metrics_util::ReauthResult;
- (void)attemptReauthWithLocalizedReason:(NSString*)localizedReason
canReusePreviousAuth:(BOOL)canReusePreviousAuth
handler:(void (^)(BOOL success))handler {
handler:
(void (^)(ReauthenticationResult success))
handler {
if (canReusePreviousAuth && [self isPreviousAuthValid]) {
handler(YES);
LogPasswordSettingsReauthResult(ReauthResult::kSkipped);
handler(ReauthenticationResult::kSkipped);
return;
}
......@@ -69,10 +65,8 @@ using password_manager::metrics_util::ReauthResult;
if (success) {
[strongSelf->_successfulReauthTimeAccessor updateSuccessfulReauthTime];
}
handler(success);
LogPasswordSettingsReauthResult(success ? ReauthResult::kSuccess
: ReauthResult::kFailure);
handler(success ? ReauthenticationResult::kSuccess
: ReauthenticationResult::kFailure);
});
};
......
......@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_REAUTHENTICATION_MODULE_FOR_TESTING_H_
#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_REAUTHENTICATION_MODULE_FOR_TESTING_H_
#ifndef IOS_CHROME_COMMON_UI_REAUTHENTICATION_REAUTHENTICATION_MODULE_FOR_TESTING_H_
#define IOS_CHROME_COMMON_UI_REAUTHENTICATION_REAUTHENTICATION_MODULE_FOR_TESTING_H_
#import "ios/chrome/browser/ui/settings/password/reauthentication_module.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
#import <LocalAuthentication/LocalAuthentication.h>
......@@ -17,4 +17,4 @@
@end
#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_REAUTHENTICATION_MODULE_FOR_TESTING_H
#endif // IOS_CHROME_COMMON_UI_REAUTHENTICATION_REAUTHENTICATION_MODULE_FOR_TESTING_H_
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/settings/password/reauthentication_module_for_testing.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_module_for_testing.h"
#import <LocalAuthentication/LocalAuthentication.h>
......@@ -79,9 +79,10 @@ TEST_F(ReauthenticationModuleTest, ReauthReuseNotPermitted) {
OCMExpect([auth_context_ evaluatePolicy:LAPolicyDeviceOwnerAuthentication
localizedReason:[OCMArg any]
reply:[OCMArg any]]);
[reauthentication_module_ attemptReauthWithLocalizedReason:@"Test"
[reauthentication_module_
attemptReauthWithLocalizedReason:@"Test"
canReusePreviousAuth:NO
handler:^(BOOL success){
handler:^(ReauthenticationResult success){
}];
EXPECT_OCMOCK_VERIFY(auth_context_);
......@@ -106,9 +107,10 @@ TEST_F(ReauthenticationModuleTest, ReauthReusePermittedLessThanSixtySeconds) {
// Use @try/@catch as -reject raises an exception.
@try {
[reauthentication_module_ attemptReauthWithLocalizedReason:@"Test"
[reauthentication_module_
attemptReauthWithLocalizedReason:@"Test"
canReusePreviousAuth:YES
handler:^(BOOL success){
handler:^(ReauthenticationResult success){
}];
EXPECT_OCMOCK_VERIFY(auth_context_);
} @catch (NSException* exception) {
......@@ -136,9 +138,10 @@ TEST_F(ReauthenticationModuleTest, ReauthReusePermittedMoreThanSixtySeconds) {
OCMExpect([auth_context_ evaluatePolicy:LAPolicyDeviceOwnerAuthentication
localizedReason:[OCMArg any]
reply:[OCMArg any]]);
[reauthentication_module_ attemptReauthWithLocalizedReason:@"Test"
[reauthentication_module_
attemptReauthWithLocalizedReason:@"Test"
canReusePreviousAuth:YES
handler:^(BOOL success){
handler:^(ReauthenticationResult success){
}];
EXPECT_OCMOCK_VERIFY(auth_context_);
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_REAUTHENTICATION_PROTOCOL_H_
#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_REAUTHENTICATION_PROTOCOL_H_
#ifndef IOS_CHROME_COMMON_UI_REAUTHENTICATION_REAUTHENTICATION_PROTOCOL_H_
#define IOS_CHROME_COMMON_UI_REAUTHENTICATION_REAUTHENTICATION_PROTOCOL_H_
#import <Foundation/Foundation.h>
// Indicates the result of the Reauthentication attempt.
enum class ReauthenticationResult {
kSuccess = 0,
kFailure = 1,
kSkipped = 2,
kMaxValue = kSkipped,
};
// Protocol for implementor of hardware reauthentication check.
@protocol ReauthenticationProtocol <NSObject>
// Checks whether Touch ID and/or passcode is enabled for the device.
- (BOOL)canAttemptReauth;
// Attempts to reauthenticate the user with Touch ID or passcode if Touch ID is
// not available. If |canReusePreviousAuth| is YES, a previous successful
// reauthentication can be taken into consideration, otherwise a new
// Attempts to reauthenticate the user with Touch ID or Face ID, or passcode if
// such hardware is not available. If |canReusePreviousAuth| is YES, a previous
// successful reauthentication can be taken into consideration, otherwise a new
// reauth attempt must be made. |handler| will take action depending on the
// result of the reauth attempt.
- (void)attemptReauthWithLocalizedReason:(NSString*)localizedReason
canReusePreviousAuth:(BOOL)canReusePreviousAuth
handler:(void (^)(BOOL success))handler;
handler:
(void (^)(ReauthenticationResult success))
handler;
@end
#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_REAUTHENTICATION_PROTOCOL_H_
#endif // IOS_CHROME_COMMON_UI_REAUTHENTICATION_REAUTHENTICATION_PROTOCOL_H_
......@@ -313,6 +313,7 @@ test("ios_chrome_unittests") {
"//ios/chrome/browser/web_state_list/web_usage_enabler:unit_tests",
"//ios/chrome/browser/webui:unit_tests",
"//ios/chrome/common:unit_tests",
"//ios/chrome/common/ui/reauthentication:unit_tests",
"//ios/chrome/common/ui/util:unit_tests",
"//ios/chrome/content_widget_extension:unit_tests",
"//ios/chrome/search_widget_extension:unit_tests",
......
......@@ -82,6 +82,7 @@ source_set("test_support") {
"//ios/chrome/browser/url_loading",
"//ios/chrome/browser/web_state_list",
"//ios/chrome/browser/web_state_list/web_usage_enabler",
"//ios/chrome/common/ui/reauthentication",
"//ios/public/provider/chrome/browser",
"//ios/public/provider/chrome/browser/signin:fake_chrome_identity",
"//ios/public/provider/chrome/browser/signin:test_support",
......
......@@ -5,7 +5,7 @@
#ifndef IOS_CHROME_TEST_APP_PASSWORD_TEST_UTIL_H_
#define IOS_CHROME_TEST_APP_PASSWORD_TEST_UTIL_H_
#import "ios/chrome/browser/ui/settings/password/reauthentication_module.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
@interface MockReauthenticationModule : NSObject<ReauthenticationProtocol>
......@@ -17,7 +17,7 @@
// Indicates whether (mock) authentication should succeed or not. Setting
// |shouldSucceed| to any value sets |canAttempt| to YES.
@property(nonatomic, assign) BOOL shouldSucceed;
@property(nonatomic, assign) ReauthenticationResult expectedResult;
@end
......
......@@ -18,12 +18,12 @@
@synthesize localizedReasonForAuthentication =
_localizedReasonForAuthentication;
@synthesize shouldSucceed = _shouldSucceed;
@synthesize expectedResult = _expectedResult;
@synthesize canAttempt = _canAttempt;
- (void)setShouldSucceed:(BOOL)shouldSucceed {
- (void)setExpectedResult:(ReauthenticationResult)expectedResult {
_canAttempt = YES;
_shouldSucceed = shouldSucceed;
_expectedResult = expectedResult;
}
- (BOOL)canAttemptReauth {
......@@ -32,10 +32,11 @@
- (void)attemptReauthWithLocalizedReason:(NSString*)localizedReason
canReusePreviousAuth:(BOOL)canReusePreviousAuth
handler:(void (^)(BOOL success))
handler:
(void (^)(ReauthenticationResult success))
showCopyPasswordsHandler {
self.localizedReasonForAuthentication = localizedReason;
showCopyPasswordsHandler(_shouldSucceed);
showCopyPasswordsHandler(_expectedResult);
}
@end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment