Commit ea3298ee authored by Viktor Semeniuk's avatar Viktor Semeniuk Committed by Commit Bot

[iOS][Password Check] Reauthentication before revealing the password

This change adds reauthentication mechanism before revealing password on
Password Details Screen. Reauth will be requested before showing,
editing or copying password. Password editing and copying to be done in
the future CLs.

Bug: 1075494
Change-Id: Idbebddb9dcdb0928af16e115d69c6fe28860c872
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2302753
Commit-Queue: Viktor Semeniuk <vsemeniuk@google.com>
Reviewed-by: default avatarGauthier Ambard <gambard@chromium.org>
Cr-Commit-Position: refs/heads/master@{#791791}
parent 1fb788ce
...@@ -38,6 +38,7 @@ source_set("password") { ...@@ -38,6 +38,7 @@ source_set("password") {
"//ios/chrome/browser", "//ios/chrome/browser",
"//ios/chrome/browser", "//ios/chrome/browser",
"//ios/chrome/browser/browser_state", "//ios/chrome/browser/browser_state",
"//ios/chrome/browser/main:public",
"//ios/chrome/browser/passwords", "//ios/chrome/browser/passwords",
"//ios/chrome/browser/signin", "//ios/chrome/browser/signin",
"//ios/chrome/browser/sync", "//ios/chrome/browser/sync",
...@@ -138,6 +139,7 @@ source_set("unit_tests") { ...@@ -138,6 +139,7 @@ source_set("unit_tests") {
"//ios/chrome/app/strings", "//ios/chrome/app/strings",
"//ios/chrome/app/strings", "//ios/chrome/app/strings",
"//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/browser_state:test_support",
"//ios/chrome/browser/main:test_support",
"//ios/chrome/browser/passwords", "//ios/chrome/browser/passwords",
"//ios/chrome/browser/ui/settings/cells", "//ios/chrome/browser/ui/settings/cells",
"//ios/chrome/browser/ui/table_view:test_support", "//ios/chrome/browser/ui/table_view:test_support",
......
...@@ -19,12 +19,15 @@ source_set("password_details") { ...@@ -19,12 +19,15 @@ source_set("password_details") {
"//components/url_formatter", "//components/url_formatter",
"//ios/chrome/app/strings", "//ios/chrome/app/strings",
"//ios/chrome/browser", "//ios/chrome/browser",
"//ios/chrome/browser/main:public",
"//ios/chrome/browser/passwords", "//ios/chrome/browser/passwords",
"//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/browser/ui/alert_coordinator",
"//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/commands",
"//ios/chrome/browser/ui/coordinators:chrome_coordinators", "//ios/chrome/browser/ui/coordinators:chrome_coordinators",
"//ios/chrome/browser/ui/table_view", "//ios/chrome/browser/ui/table_view",
"//ios/chrome/common/ui/colors", "//ios/chrome/common/ui/colors",
"//ios/chrome/common/ui/reauthentication",
"//ios/chrome/common/ui/util", "//ios/chrome/common/ui/util",
"//ios/web", "//ios/web",
"//ui/base", "//ui/base",
...@@ -63,6 +66,7 @@ source_set("password_details_ui") { ...@@ -63,6 +66,7 @@ source_set("password_details_ui") {
"//ios/chrome/browser/ui/table_view/cells:cells_constants", "//ios/chrome/browser/ui/table_view/cells:cells_constants",
"//ios/chrome/browser/ui/util", "//ios/chrome/browser/ui/util",
"//ios/chrome/common/ui/colors", "//ios/chrome/common/ui/colors",
"//ios/chrome/common/ui/reauthentication",
"//ios/chrome/common/ui/util", "//ios/chrome/common/ui/util",
"//ui/base", "//ui/base",
] ]
...@@ -85,6 +89,7 @@ source_set("unit_tests") { ...@@ -85,6 +89,7 @@ source_set("unit_tests") {
"//ios/chrome/app/strings:ios_chromium_strings_grit", "//ios/chrome/app/strings:ios_chromium_strings_grit",
"//ios/chrome/app/strings:ios_strings_grit", "//ios/chrome/app/strings:ios_strings_grit",
"//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/browser_state:test_support",
"//ios/chrome/browser/main:test_support",
"//ios/chrome/browser/passwords", "//ios/chrome/browser/passwords",
"//ios/chrome/browser/ui/settings/cells", "//ios/chrome/browser/ui/settings/cells",
"//ios/chrome/browser/ui/table_view:test_support", "//ios/chrome/browser/ui/table_view:test_support",
...@@ -92,6 +97,7 @@ source_set("unit_tests") { ...@@ -92,6 +97,7 @@ source_set("unit_tests") {
"//ios/chrome/browser/ui/table_view/cells:cells_constants", "//ios/chrome/browser/ui/table_view/cells:cells_constants",
"//ios/chrome/browser/ui/util", "//ios/chrome/browser/ui/util",
"//ios/chrome/common/ui/colors", "//ios/chrome/common/ui/colors",
"//ios/chrome/common/ui/reauthentication",
"//ios/chrome/test/app:test_support", "//ios/chrome/test/app:test_support",
"//ios/web/public/test", "//ios/web/public/test",
"//testing/gmock", "//testing/gmock",
......
...@@ -8,8 +8,10 @@ ...@@ -8,8 +8,10 @@
#import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h" #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
@protocol ApplicationCommands; @protocol ApplicationCommands;
class Browser;
class IOSChromePasswordCheckManager; class IOSChromePasswordCheckManager;
@protocol PasswordDetailsCoordinatorDelegate; @protocol PasswordDetailsCoordinatorDelegate;
@class ReauthenticationModule;
namespace autofill { namespace autofill {
struct PasswordForm; struct PasswordForm;
...@@ -21,9 +23,10 @@ struct PasswordForm; ...@@ -21,9 +23,10 @@ struct PasswordForm;
- (instancetype) - (instancetype)
initWithBaseNavigationController: initWithBaseNavigationController:
(UINavigationController*)navigationController (UINavigationController*)navigationController
browser:(Browser*)browser
password:(const autofill::PasswordForm&)password password:(const autofill::PasswordForm&)password
reauthModule:(ReauthenticationModule*)reauthModule
passwordCheckManager:(IOSChromePasswordCheckManager*)manager passwordCheckManager:(IOSChromePasswordCheckManager*)manager
dispatcher:(id<ApplicationCommands>)dispatcher
NS_DESIGNATED_INITIALIZER; NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithBaseViewController:(UIViewController*)viewController - (instancetype)initWithBaseViewController:(UIViewController*)viewController
...@@ -32,6 +35,9 @@ struct PasswordForm; ...@@ -32,6 +35,9 @@ struct PasswordForm;
// Delegate. // Delegate.
@property(nonatomic, weak) id<PasswordDetailsCoordinatorDelegate> delegate; @property(nonatomic, weak) id<PasswordDetailsCoordinatorDelegate> delegate;
// Dispatcher.
@property(nonatomic, weak) id<ApplicationCommands> dispatcher;
@end @end
#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_COORDINATOR_H_ #endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_COORDINATOR_H_
...@@ -6,12 +6,19 @@ ...@@ -6,12 +6,19 @@
#include "base/mac/foundation_util.h" #include "base/mac/foundation_util.h"
#include "components/autofill/core/common/password_form.h" #include "components/autofill/core/common/password_form.h"
#include "components/strings/grit/components_strings.h"
#import "ios/chrome/browser/main/browser.h"
#import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h"
#import "ios/chrome/browser/ui/commands/application_commands.h"
#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
#import "ios/chrome/browser/ui/settings/password/password_details/password_details_consumer.h" #import "ios/chrome/browser/ui/settings/password/password_details/password_details_consumer.h"
#import "ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h" #import "ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h"
#import "ios/chrome/browser/ui/settings/password/password_details/password_details_handler.h" #import "ios/chrome/browser/ui/settings/password/password_details/password_details_handler.h"
#import "ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h" #import "ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h"
#import "ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller.h" #import "ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller.h"
#include "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/browser/ui/ui_feature_flags.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
#include "ios/chrome/grit/ios_strings.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
...@@ -31,8 +38,12 @@ ...@@ -31,8 +38,12 @@
// Main mediator for this coordinator. // Main mediator for this coordinator.
@property(nonatomic, strong) PasswordDetailsMediator* mediator; @property(nonatomic, strong) PasswordDetailsMediator* mediator;
// Dispatcher. // Module containing the reauthentication mechanism for viewing and copying
@property(nonatomic, weak) id<ApplicationCommands> dispatcher; // passwords.
@property(nonatomic, weak) ReauthenticationModule* reauthenticationModule;
// Modal alert for interactions with password.
@property(nonatomic, strong) AlertCoordinator* alertCoordinator;
@end @end
...@@ -43,19 +54,20 @@ ...@@ -43,19 +54,20 @@
- (instancetype) - (instancetype)
initWithBaseNavigationController: initWithBaseNavigationController:
(UINavigationController*)navigationController (UINavigationController*)navigationController
browser:(Browser*)browser
password:(const autofill::PasswordForm&)password password:(const autofill::PasswordForm&)password
passwordCheckManager:(IOSChromePasswordCheckManager*)manager reauthModule:(ReauthenticationModule*)reauthModule
dispatcher:(id<ApplicationCommands>)dispatcher { passwordCheckManager:(IOSChromePasswordCheckManager*)manager {
self = [super initWithBaseViewController:navigationController browser:nil]; self = [super initWithBaseViewController:navigationController
browser:browser];
if (self) { if (self) {
DCHECK(navigationController); DCHECK(navigationController);
DCHECK(manager); DCHECK(manager);
DCHECK(dispatcher);
_baseNavigationController = navigationController; _baseNavigationController = navigationController;
_password = password; _password = password;
_manager = manager; _manager = manager;
_dispatcher = dispatcher; _reauthenticationModule = reauthModule;
} }
return self; return self;
} }
...@@ -73,6 +85,7 @@ ...@@ -73,6 +85,7 @@
self.mediator.consumer = self.viewController; self.mediator.consumer = self.viewController;
self.viewController.handler = self; self.viewController.handler = self;
self.viewController.commandsDispatcher = self.dispatcher; self.viewController.commandsDispatcher = self.dispatcher;
self.viewController.reauthModule = self.reauthenticationModule;
[self.baseNavigationController pushViewController:self.viewController [self.baseNavigationController pushViewController:self.viewController
animated:YES]; animated:YES];
...@@ -90,4 +103,34 @@ ...@@ -90,4 +103,34 @@
[self.delegate passwordDetailsCoordinatorDidRemove:self]; [self.delegate passwordDetailsCoordinatorDidRemove:self];
} }
- (void)showPasscodeDialog {
NSString* title =
l10n_util::GetNSString(IDS_IOS_SETTINGS_SET_UP_SCREENLOCK_TITLE);
NSString* message =
l10n_util::GetNSString(IDS_IOS_SETTINGS_SET_UP_SCREENLOCK_CONTENT);
self.alertCoordinator = [[AlertCoordinator alloc]
initWithBaseViewController:self.baseViewController
browser:self.browser
title:title
message:message];
__weak __typeof(self) weakSelf = self;
OpenNewTabCommand* command =
[OpenNewTabCommand commandWithURLFromChrome:GURL(kPasscodeArticleURL)];
[self.alertCoordinator addItemWithTitle:l10n_util::GetNSString(IDS_OK)
action:nil
style:UIAlertActionStyleCancel];
[self.alertCoordinator
addItemWithTitle:l10n_util::GetNSString(
IDS_IOS_SETTINGS_SET_UP_SCREENLOCK_LEARN_HOW)
action:^{
[weakSelf.dispatcher closeSettingsUIAndOpenURL:command];
}
style:UIAlertActionStyleDefault];
[self.alertCoordinator start];
}
@end @end
...@@ -11,6 +11,10 @@ ...@@ -11,6 +11,10 @@
// Called when the view controller was dismissed. // Called when the view controller was dismissed.
- (void)passwordDetailsViewControllerDidDisappear; - (void)passwordDetailsViewControllerDidDisappear;
// Shows a dialog offering the user to set a passcode in order to see the
// password.
- (void)showPasscodeDialog;
@end @end
#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_HANDLER_H_ #endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_HANDLER_H_
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
@protocol ApplicationCommands; @protocol ApplicationCommands;
@protocol PasswordDetailsHandler; @protocol PasswordDetailsHandler;
@protocol PasswordDetailsViewControllerDelegate; @protocol PasswordDetailsViewControllerDelegate;
@protocol ReauthenticationProtocol;
// Screen which shows password details and allows to edit it. // Screen which shows password details and allows to edit it.
@interface PasswordDetailsViewController @interface PasswordDetailsViewController
...@@ -25,6 +26,10 @@ ...@@ -25,6 +26,10 @@
// Dispatcher for this ViewController. // Dispatcher for this ViewController.
@property(nonatomic, weak) id<ApplicationCommands> commandsDispatcher; @property(nonatomic, weak) id<ApplicationCommands> commandsDispatcher;
// Module containing the reauthentication mechanism for interections
// with password.
@property(nonatomic, weak) id<ReauthenticationProtocol> reauthModule;
@end @end
#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_VIEW_CONTROLLER_H_ #endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_VIEW_CONTROLLER_H_
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
#import "ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller.h" #import "ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller.h"
#include "base/mac/foundation_util.h" #include "base/mac/foundation_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "components/password_manager/core/browser/password_manager_metrics_util.h"
#import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/commands/application_commands.h"
#import "ios/chrome/browser/ui/commands/open_new_tab_command.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
#import "ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.h"
...@@ -19,6 +21,7 @@ ...@@ -19,6 +21,7 @@
#import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h"
#import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.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/colors/semantic_color_names.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
#include "ios/chrome/grit/ios_chromium_strings.h" #include "ios/chrome/grit/ios_chromium_strings.h"
#include "ios/chrome/grit/ios_strings.h" #include "ios/chrome/grit/ios_strings.h"
#include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/l10n/l10n_util_mac.h"
...@@ -29,6 +32,9 @@ ...@@ -29,6 +32,9 @@
namespace { namespace {
using password_manager::metrics_util::LogPasswordSettingsReauthResult;
using password_manager::metrics_util::ReauthResult;
// Padding used between the image and the text labels. // Padding used between the image and the text labels.
const CGFloat kWarningIconSize = 20; const CGFloat kWarningIconSize = 20;
...@@ -45,6 +51,12 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -45,6 +51,12 @@ typedef NS_ENUM(NSInteger, ItemType) {
ItemTypeChangePasswordRecommendation, ItemTypeChangePasswordRecommendation,
}; };
typedef NS_ENUM(NSInteger, ReauthenticationReason) {
ReauthenticationReasonShow = 0,
ReauthenticationReasonCopy,
ReauthenticationReasonEdit,
};
} // namespace } // namespace
@interface PasswordDetailsViewController () @interface PasswordDetailsViewController ()
...@@ -78,8 +90,13 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -78,8 +90,13 @@ typedef NS_ENUM(NSInteger, ItemType) {
#pragma mark - ChromeTableViewController #pragma mark - ChromeTableViewController
- (void)editButtonPressed { - (void)editButtonPressed {
// TODO:(crbug.com/1075494) - Request reauth if user clicked edit and password // Request reauthentication before revealing password during editing.
// was not shown. // Editing mode will be entered on successful reauth.
if (!self.tableView.editing && !self.isPasswordShown) {
[self attemptToShowPasswordFor:ReauthenticationReasonEdit];
return;
}
[super editButtonPressed]; [super editButtonPressed];
if (!self.tableView.editing) { if (!self.tableView.editing) {
...@@ -88,13 +105,7 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -88,13 +105,7 @@ typedef NS_ENUM(NSInteger, ItemType) {
didEditPasswordDetails:self.password]; didEditPasswordDetails:self.password];
} }
[self loadModel]; [self reloadData];
[self reconfigureCellsForItems:
[self.tableViewModel
itemsInSectionWithIdentifier:SectionIdentifierPassword]];
[self reconfigureCellsForItems:
[self.tableViewModel
itemsInSectionWithIdentifier:SectionIdentifierCompromisedInfo]];
} }
- (void)loadModel { - (void)loadModel {
...@@ -314,20 +325,134 @@ typedef NS_ENUM(NSInteger, ItemType) { ...@@ -314,20 +325,134 @@ typedef NS_ENUM(NSInteger, ItemType) {
return newImage; return newImage;
} }
// Shows reauthentication dialog if needed. If the reauthentication is
// successful reveals the password.
- (void)attemptToShowPasswordFor:(ReauthenticationReason)reason {
// If password was already shown (before editing or copying) we don't need to
// request reauth again.
if (self.isPasswordShown) {
[self showPasswordFor:reason];
return;
}
if ([self.reauthModule canAttemptReauth]) {
__weak __typeof(self) weakSelf = self;
void (^showPasswordHandler)(ReauthenticationResult) =
^(ReauthenticationResult result) {
PasswordDetailsViewController* strongSelf = weakSelf;
if (!strongSelf)
return;
[strongSelf logPasswordSettingsReauthResult:result];
if (result == ReauthenticationResult::kFailure)
return;
[strongSelf showPasswordFor:reason];
};
[self.reauthModule
attemptReauthWithLocalizedReason:[self getLocalizedStringFor:reason]
canReusePreviousAuth:YES
handler:showPasswordHandler];
} else {
[self.handler showPasscodeDialog];
}
}
// Reveals password to the user.
- (void)showPasswordFor:(ReauthenticationReason)reason {
switch (reason) {
case ReauthenticationReasonShow:
self.passwordShown = YES;
self.passwordTextItem.textFieldValue = self.password.password;
self.passwordTextItem.identifyingIcon =
[[UIImage imageNamed:@"infobar_hide_password_icon"]
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[self reconfigureCellsForItems:@[ self.passwordTextItem ]];
break;
case ReauthenticationReasonCopy:
// TODO:(crbug.com/1075494) - Implement copy password functionality.
break;
case ReauthenticationReasonEdit:
// Called super because we want to update only |tableView.editing|.
[super editButtonPressed];
[self reloadData];
break;
}
[self logPasswordAccessWith:reason];
}
// Returns localized reason for reauthentication dialog.
- (NSString*)getLocalizedStringFor:(ReauthenticationReason)reason {
switch (reason) {
case ReauthenticationReasonShow:
return l10n_util::GetNSString(
IDS_IOS_SETTINGS_PASSWORD_REAUTH_REASON_SHOW);
case ReauthenticationReasonCopy:
return l10n_util::GetNSString(
IDS_IOS_SETTINGS_PASSWORD_REAUTH_REASON_COPY);
case ReauthenticationReasonEdit:
// TODO:(crbug.com/1075494) - Add custom string for edit.
return l10n_util::GetNSString(
IDS_IOS_SETTINGS_PASSWORD_REAUTH_REASON_SHOW);
}
}
#pragma mark - Actions #pragma mark - Actions
// Called when the user tapped on the show/hide button near password. // Called when the user tapped on the show/hide button near password.
- (void)didTapShowHideButton:(UIButton*)buttonView { - (void)didTapShowHideButton:(UIButton*)buttonView {
// TODO:(crbug.com/1075494) - Request reauth before revealing the password. if (self.isPasswordShown) {
self.passwordShown = !self.passwordShown; self.passwordShown = NO;
self.passwordTextItem.textFieldValue = self.passwordTextItem.textFieldValue = kMaskedPassword;
[self isPasswordShown] ? self.password.password : kMaskedPassword; self.passwordTextItem.identifyingIcon =
NSString* image = self.isPasswordShown ? @"infobar_hide_password_icon" [[UIImage imageNamed:@"infobar_reveal_password_icon"]
: @"infobar_reveal_password_icon"; imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
self.passwordTextItem.identifyingIcon = [[UIImage imageNamed:image] [self reconfigureCellsForItems:@[ self.passwordTextItem ]];
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; } else {
[self attemptToShowPasswordFor:ReauthenticationReasonShow];
[self reconfigureCellsForItems:@[ self.passwordTextItem ]]; }
}
#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;
}
}
- (void)logPasswordAccessWith:(ReauthenticationReason)reason {
switch (reason) {
case ReauthenticationReasonShow:
UMA_HISTOGRAM_ENUMERATION(
"PasswordManager.AccessPasswordInSettings",
password_manager::metrics_util::ACCESS_PASSWORD_VIEWED,
password_manager::metrics_util::ACCESS_PASSWORD_COUNT);
break;
case ReauthenticationReasonCopy:
UMA_HISTOGRAM_ENUMERATION(
"PasswordManager.AccessPasswordInSettings",
password_manager::metrics_util::ACCESS_PASSWORD_COPIED,
password_manager::metrics_util::ACCESS_PASSWORD_COUNT);
break;
case ReauthenticationReasonEdit:
UMA_HISTOGRAM_ENUMERATION(
"PasswordManager.AccessPasswordInSettings",
password_manager::metrics_util::ACCESS_PASSWORD_EDITED,
password_manager::metrics_util::ACCESS_PASSWORD_COUNT);
break;
}
} }
@end @end
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <memory> #include <memory>
#include "base/mac/foundation_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/common/password_form.h" #include "components/autofill/core/common/password_form.h"
#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
...@@ -17,8 +18,10 @@ ...@@ -17,8 +18,10 @@
#import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_text_edit_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_text_edit_item.h"
#import "ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
#include "ios/chrome/grit/ios_chromium_strings.h" #include "ios/chrome/grit/ios_chromium_strings.h"
#include "ios/chrome/grit/ios_strings.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" #include "ios/web/public/test/web_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h" #include "testing/gtest_mac.h"
...@@ -39,6 +42,9 @@ ...@@ -39,6 +42,9 @@
- (void)passwordDetailsViewControllerDidDisappear { - (void)passwordDetailsViewControllerDidDisappear {
} }
- (void)showPasscodeDialog {
}
@end @end
// Test class that conforms to PasswordDetailsViewControllerDelegate in order to // Test class that conforms to PasswordDetailsViewControllerDelegate in order to
...@@ -62,6 +68,8 @@ class PasswordDetailsViewControllerTest : public ChromeTableViewControllerTest { ...@@ -62,6 +68,8 @@ class PasswordDetailsViewControllerTest : public ChromeTableViewControllerTest {
PasswordDetailsViewControllerTest() { PasswordDetailsViewControllerTest() {
handler_ = [[FakePasswordDetailsHandler alloc] init]; handler_ = [[FakePasswordDetailsHandler alloc] init];
delegate_ = [[FakePasswordDetailsDelegate alloc] init]; delegate_ = [[FakePasswordDetailsDelegate alloc] init];
reauthentication_module_ = [[MockReauthenticationModule alloc] init];
reauthentication_module_.expectedResult = ReauthenticationResult::kSuccess;
} }
ChromeTableViewController* InstantiateController() override { ChromeTableViewController* InstantiateController() override {
...@@ -70,10 +78,11 @@ class PasswordDetailsViewControllerTest : public ChromeTableViewControllerTest { ...@@ -70,10 +78,11 @@ class PasswordDetailsViewControllerTest : public ChromeTableViewControllerTest {
initWithStyle:UITableViewStylePlain]; initWithStyle:UITableViewStylePlain];
controller.handler = handler_; controller.handler = handler_;
controller.delegate = delegate_; controller.delegate = delegate_;
controller.reauthModule = reauthentication_module_;
return controller; return controller;
} }
void ShowPassword(bool isCompromised = false) { void SetPassword(bool isCompromised = false) {
auto form = autofill::PasswordForm(); auto form = autofill::PasswordForm();
form.url = GURL("http://www.example.com/"); form.url = GURL("http://www.example.com/");
form.action = GURL("http://www.example.com/accounts/Login"); form.action = GURL("http://www.example.com/accounts/Login");
...@@ -111,10 +120,12 @@ class PasswordDetailsViewControllerTest : public ChromeTableViewControllerTest { ...@@ -111,10 +120,12 @@ class PasswordDetailsViewControllerTest : public ChromeTableViewControllerTest {
FakePasswordDetailsHandler* handler() { return handler_; } FakePasswordDetailsHandler* handler() { return handler_; }
FakePasswordDetailsDelegate* delegate() { return delegate_; } FakePasswordDetailsDelegate* delegate() { return delegate_; }
MockReauthenticationModule* reauth() { return reauthentication_module_; }
private: private:
FakePasswordDetailsHandler* handler_; FakePasswordDetailsHandler* handler_;
FakePasswordDetailsDelegate* delegate_; FakePasswordDetailsDelegate* delegate_;
MockReauthenticationModule* reauthentication_module_;
}; };
// Tests PasswordDetailsViewController is set up with appropriate items // Tests PasswordDetailsViewController is set up with appropriate items
...@@ -129,7 +140,7 @@ TEST_F(PasswordDetailsViewControllerTest, TestModel) { ...@@ -129,7 +140,7 @@ TEST_F(PasswordDetailsViewControllerTest, TestModel) {
// Tests that password is displayed properly. // Tests that password is displayed properly.
TEST_F(PasswordDetailsViewControllerTest, TestPassword) { TEST_F(PasswordDetailsViewControllerTest, TestPassword) {
ShowPassword(); SetPassword();
EXPECT_EQ(1, NumberOfSections()); EXPECT_EQ(1, NumberOfSections());
EXPECT_EQ(3, NumberOfItemsInSection(0)); EXPECT_EQ(3, NumberOfItemsInSection(0));
...@@ -141,7 +152,7 @@ TEST_F(PasswordDetailsViewControllerTest, TestPassword) { ...@@ -141,7 +152,7 @@ TEST_F(PasswordDetailsViewControllerTest, TestPassword) {
// Tests that compromised password is displayed properly. // Tests that compromised password is displayed properly.
TEST_F(PasswordDetailsViewControllerTest, TestCompromisedPassword) { TEST_F(PasswordDetailsViewControllerTest, TestCompromisedPassword) {
ShowPassword(true); SetPassword(true);
EXPECT_EQ(2, NumberOfSections()); EXPECT_EQ(2, NumberOfSections());
EXPECT_EQ(3, NumberOfItemsInSection(0)); EXPECT_EQ(3, NumberOfItemsInSection(0));
EXPECT_EQ(2, NumberOfItemsInSection(1)); EXPECT_EQ(2, NumberOfItemsInSection(1));
...@@ -155,3 +166,72 @@ TEST_F(PasswordDetailsViewControllerTest, TestCompromisedPassword) { ...@@ -155,3 +166,72 @@ TEST_F(PasswordDetailsViewControllerTest, TestCompromisedPassword) {
CheckDetailItemTextWithId(IDS_IOS_CHANGE_COMPROMISED_PASSWORD_DESCRIPTION, 1, CheckDetailItemTextWithId(IDS_IOS_CHANGE_COMPROMISED_PASSWORD_DESCRIPTION, 1,
1); 1);
} }
// Tests that password is shown/hidden.
TEST_F(PasswordDetailsViewControllerTest, TestShowHidePassword) {
SetPassword();
CheckEditCellText(kMaskedPassword, 0, 2);
NSIndexPath* indexOfPassword = [NSIndexPath indexPathForRow:2 inSection:0];
TableViewTextEditCell* textFieldCell =
base::mac::ObjCCastStrict<TableViewTextEditCell>(
[controller().tableView cellForRowAtIndexPath:indexOfPassword]);
[textFieldCell.identifyingIconButton
sendActionsForControlEvents:UIControlEventTouchUpInside];
CheckEditCellText(@"test", 0, 2);
EXPECT_NSEQ(
l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_REAUTH_REASON_SHOW),
reauth().localizedReasonForAuthentication);
[textFieldCell.identifyingIconButton
sendActionsForControlEvents:UIControlEventTouchUpInside];
CheckEditCellText(kMaskedPassword, 0, 2);
}
// Tests that passwords was not shown in case reauth failed.
TEST_F(PasswordDetailsViewControllerTest, TestShowPasswordReauthFailed) {
SetPassword();
CheckEditCellText(kMaskedPassword, 0, 2);
reauth().expectedResult = ReauthenticationResult::kFailure;
NSIndexPath* indexOfPassword = [NSIndexPath indexPathForRow:2 inSection:0];
TableViewTextEditCell* textFieldCell =
base::mac::ObjCCastStrict<TableViewTextEditCell>(
[controller().tableView cellForRowAtIndexPath:indexOfPassword]);
[textFieldCell.identifyingIconButton
sendActionsForControlEvents:UIControlEventTouchUpInside];
CheckEditCellText(kMaskedPassword, 0, 2);
}
// Tests that password was revealed during editing.
TEST_F(PasswordDetailsViewControllerTest, TestPasswordShownDuringEditing) {
SetPassword();
CheckEditCellText(kMaskedPassword, 0, 2);
PasswordDetailsViewController* passwordDetails =
base::mac::ObjCCastStrict<PasswordDetailsViewController>(controller());
[passwordDetails editButtonPressed];
EXPECT_TRUE(passwordDetails.tableView.editing);
CheckEditCellText(@"test", 0, 2);
[passwordDetails editButtonPressed];
EXPECT_FALSE(passwordDetails.tableView.editing);
CheckEditCellText(kMaskedPassword, 0, 2);
}
// Tests that editing mode was not entered because reauth failed.
TEST_F(PasswordDetailsViewControllerTest, TestEditingReauthFailed) {
SetPassword();
CheckEditCellText(kMaskedPassword, 0, 2);
reauth().expectedResult = ReauthenticationResult::kFailure;
PasswordDetailsViewController* passwordDetails =
base::mac::ObjCCastStrict<PasswordDetailsViewController>(controller());
[passwordDetails editButtonPressed];
EXPECT_FALSE(passwordDetails.tableView.editing);
CheckEditCellText(kMaskedPassword, 0, 2);
}
...@@ -8,8 +8,10 @@ ...@@ -8,8 +8,10 @@
#import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h" #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
@protocol ApplicationCommands; @protocol ApplicationCommands;
class Browser;
class IOSChromePasswordCheckManager; class IOSChromePasswordCheckManager;
@class PasswordIssuesCoordinator; @class PasswordIssuesCoordinator;
@class ReauthenticationModule;
// Delegate for PasswordIssuesCoordinator. // Delegate for PasswordIssuesCoordinator.
@protocol PasswordIssuesCoordinatorDelegate @protocol PasswordIssuesCoordinatorDelegate
...@@ -25,6 +27,7 @@ class IOSChromePasswordCheckManager; ...@@ -25,6 +27,7 @@ class IOSChromePasswordCheckManager;
- (instancetype)initWithBaseNavigationController: - (instancetype)initWithBaseNavigationController:
(UINavigationController*)navigationController (UINavigationController*)navigationController
browser:(Browser*)browser
passwordCheckManager: passwordCheckManager:
(IOSChromePasswordCheckManager*)manager (IOSChromePasswordCheckManager*)manager
NS_DESIGNATED_INITIALIZER; NS_DESIGNATED_INITIALIZER;
...@@ -32,6 +35,9 @@ class IOSChromePasswordCheckManager; ...@@ -32,6 +35,9 @@ class IOSChromePasswordCheckManager;
- (instancetype)initWithBaseViewController:(UIViewController*)viewController - (instancetype)initWithBaseViewController:(UIViewController*)viewController
browser:(Browser*)browser NS_UNAVAILABLE; browser:(Browser*)browser NS_UNAVAILABLE;
// Reauthentication module used by password details coordinator.
@property(nonatomic, strong) ReauthenticationModule* reauthModule;
@property(nonatomic, weak) id<PasswordIssuesCoordinatorDelegate> delegate; @property(nonatomic, weak) id<PasswordIssuesCoordinatorDelegate> delegate;
@property(nonatomic, weak) id<ApplicationCommands> dispatcher; @property(nonatomic, weak) id<ApplicationCommands> dispatcher;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#import "ios/chrome/browser/ui/settings/password/password_issues_coordinator.h" #import "ios/chrome/browser/ui/settings/password/password_issues_coordinator.h"
#include "base/mac/foundation_util.h" #include "base/mac/foundation_util.h"
#import "ios/chrome/browser/main/browser.h"
#import "ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.h" #import "ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.h"
#import "ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h" #import "ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h"
#import "ios/chrome/browser/ui/settings/password/password_issue_with_form.h" #import "ios/chrome/browser/ui/settings/password/password_issue_with_form.h"
...@@ -13,6 +14,7 @@ ...@@ -13,6 +14,7 @@
#import "ios/chrome/browser/ui/settings/password/password_issues_presenter.h" #import "ios/chrome/browser/ui/settings/password/password_issues_presenter.h"
#import "ios/chrome/browser/ui/settings/password/password_issues_table_view_controller.h" #import "ios/chrome/browser/ui/settings/password/password_issues_table_view_controller.h"
#include "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/browser/ui/ui_feature_flags.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
...@@ -42,9 +44,11 @@ ...@@ -42,9 +44,11 @@
- (instancetype)initWithBaseNavigationController: - (instancetype)initWithBaseNavigationController:
(UINavigationController*)navigationController (UINavigationController*)navigationController
browser:(Browser*)browser
passwordCheckManager: passwordCheckManager:
(IOSChromePasswordCheckManager*)manager { (IOSChromePasswordCheckManager*)manager {
self = [super initWithBaseViewController:navigationController browser:nil]; self = [super initWithBaseViewController:navigationController
browser:browser];
if (self) { if (self) {
_baseNavigationController = navigationController; _baseNavigationController = navigationController;
_manager = manager; _manager = manager;
...@@ -66,6 +70,13 @@ ...@@ -66,6 +70,13 @@
self.mediator = self.mediator =
[[PasswordIssuesMediator alloc] initWithPasswordCheckManager:_manager]; [[PasswordIssuesMediator alloc] initWithPasswordCheckManager:_manager];
// If reauthentication module was not provided, coordinator will create its
// own.
if (!self.reauthModule) {
self.reauthModule = [[ReauthenticationModule alloc]
initWithSuccessfulReauthTimeAccessor:self.mediator];
}
self.mediator.consumer = self.viewController; self.mediator.consumer = self.viewController;
self.viewController.presenter = self; self.viewController.presenter = self;
...@@ -95,9 +106,11 @@ ...@@ -95,9 +106,11 @@
DCHECK(!self.passwordDetails); DCHECK(!self.passwordDetails);
self.passwordDetails = [[PasswordDetailsCoordinator alloc] self.passwordDetails = [[PasswordDetailsCoordinator alloc]
initWithBaseNavigationController:self.baseNavigationController initWithBaseNavigationController:self.baseNavigationController
browser:self.browser
password:form password:form
passwordCheckManager:_manager reauthModule:self.reauthModule
dispatcher:self.dispatcher]; passwordCheckManager:_manager];
self.passwordDetails.dispatcher = self.dispatcher;
self.passwordDetails.delegate = self; self.passwordDetails.delegate = self;
[self.passwordDetails start]; [self.passwordDetails start];
} }
......
...@@ -7,11 +7,13 @@ ...@@ -7,11 +7,13 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
class IOSChromePasswordCheckManager; class IOSChromePasswordCheckManager;
@protocol PasswordIssuesConsumer; @protocol PasswordIssuesConsumer;
// This mediator fetches and organises the credentials for its consumer. // This mediator fetches and organises the credentials for its consumer.
@interface PasswordIssuesMediator : NSObject @interface PasswordIssuesMediator : NSObject <SuccessfulReauthTimeAccessor>
- (instancetype)initWithPasswordCheckManager: - (instancetype)initWithPasswordCheckManager:
(IOSChromePasswordCheckManager*)manager NS_DESIGNATED_INITIALIZER; (IOSChromePasswordCheckManager*)manager NS_DESIGNATED_INITIALIZER;
......
...@@ -20,6 +20,12 @@ ...@@ -20,6 +20,12 @@
std::vector<password_manager::CredentialWithPassword> _compromisedCredentials; std::vector<password_manager::CredentialWithPassword> _compromisedCredentials;
} }
// Object storing the time of the previous successful re-authentication.
// This is meant to be used by the |ReauthenticationModule| for keeping
// re-authentications valid for a certain time interval within the scope
// of the Password Issues Screen.
@property(nonatomic, strong, readonly) NSDate* successfulReauthTime;
@end @end
@implementation PasswordIssuesMediator @implementation PasswordIssuesMediator
...@@ -69,4 +75,14 @@ ...@@ -69,4 +75,14 @@
[self.consumer setPasswordIssues:passwords]; [self.consumer setPasswordIssues:passwords];
} }
#pragma mark SuccessfulReauthTimeAccessor
- (void)updateSuccessfulReauthTime {
_successfulReauthTime = [[NSDate alloc] init];
}
- (NSDate*)lastSuccessfulReauthTime {
return [self successfulReauthTime];
}
@end @end
...@@ -10,16 +10,15 @@ ...@@ -10,16 +10,15 @@
#import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
#import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h" #import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h"
class ChromeBrowserState; class Browser;
@protocol ReauthenticationProtocol; @protocol ReauthenticationProtocol;
@class PasswordExporter; @class PasswordExporter;
@interface PasswordsTableViewController @interface PasswordsTableViewController
: SettingsRootTableViewController <SettingsControllerProtocol> : SettingsRootTableViewController <SettingsControllerProtocol>
// The designated initializer. |browserState| must not be nil. // The designated initializer. |browser| must not be nil.
- (instancetype)initWithBrowserState:(ChromeBrowserState*)browserState - (instancetype)initWithBrowser:(Browser*)browser NS_DESIGNATED_INITIALIZER;
NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithStyle:(UITableViewStyle)style NS_UNAVAILABLE; - (instancetype)initWithStyle:(UITableViewStyle)style NS_UNAVAILABLE;
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "components/url_formatter/url_formatter.h" #include "components/url_formatter/url_formatter.h"
#include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/application_context.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#import "ios/chrome/browser/main/browser.h"
#include "ios/chrome/browser/passwords/ios_chrome_password_check_manager.h" #include "ios/chrome/browser/passwords/ios_chrome_password_check_manager.h"
#include "ios/chrome/browser/passwords/ios_chrome_password_check_manager_factory.h" #include "ios/chrome/browser/passwords/ios_chrome_password_check_manager_factory.h"
#include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h" #include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h"
...@@ -213,6 +214,8 @@ std::vector<std::unique_ptr<autofill::PasswordForm>> CopyOf( ...@@ -213,6 +214,8 @@ std::vector<std::unique_ptr<autofill::PasswordForm>> CopyOf(
password_manager::DuplicatesMap _savedPasswordDuplicates; password_manager::DuplicatesMap _savedPasswordDuplicates;
// Map containing duplicates of blocked passwords. // Map containing duplicates of blocked passwords.
password_manager::DuplicatesMap _blockedPasswordDuplicates; password_manager::DuplicatesMap _blockedPasswordDuplicates;
// The browser where the screen is being displayed.
Browser* _browser;
// The current Chrome browser state. // The current Chrome browser state.
ChromeBrowserState* _browserState; ChromeBrowserState* _browserState;
// Authentication Service Observer. // Authentication Service Observer.
...@@ -252,14 +255,15 @@ std::vector<std::unique_ptr<autofill::PasswordForm>> CopyOf( ...@@ -252,14 +255,15 @@ std::vector<std::unique_ptr<autofill::PasswordForm>> CopyOf(
#pragma mark - Initialization #pragma mark - Initialization
- (instancetype)initWithBrowserState:(ChromeBrowserState*)browserState { - (instancetype)initWithBrowser:(Browser*)browser {
DCHECK(browserState); DCHECK(browser);
UITableViewStyle style = base::FeatureList::IsEnabled(kSettingsRefresh) UITableViewStyle style = base::FeatureList::IsEnabled(kSettingsRefresh)
? UITableViewStylePlain ? UITableViewStylePlain
: UITableViewStyleGrouped; : UITableViewStyleGrouped;
self = [super initWithStyle:style]; self = [super initWithStyle:style];
if (self) { if (self) {
_browserState = browserState; _browser = browser;
_browserState = browser->GetBrowserState();
_reauthenticationModule = [[ReauthenticationModule alloc] _reauthenticationModule = [[ReauthenticationModule alloc]
initWithSuccessfulReauthTimeAccessor:self]; initWithSuccessfulReauthTimeAccessor:self];
_passwordExporter = [[PasswordExporter alloc] _passwordExporter = [[PasswordExporter alloc]
...@@ -1197,9 +1201,11 @@ std::vector<std::unique_ptr<autofill::PasswordForm>> CopyOf( ...@@ -1197,9 +1201,11 @@ std::vector<std::unique_ptr<autofill::PasswordForm>> CopyOf(
DCHECK(!_passwordIssuesCoordinator); DCHECK(!_passwordIssuesCoordinator);
_passwordIssuesCoordinator = [[PasswordIssuesCoordinator alloc] _passwordIssuesCoordinator = [[PasswordIssuesCoordinator alloc]
initWithBaseNavigationController:self.navigationController initWithBaseNavigationController:self.navigationController
browser:_browser
passwordCheckManager:_passwordCheck.get()]; passwordCheckManager:_passwordCheck.get()];
_passwordIssuesCoordinator.delegate = self; _passwordIssuesCoordinator.delegate = self;
_passwordIssuesCoordinator.dispatcher = self.dispatcher; _passwordIssuesCoordinator.dispatcher = self.dispatcher;
_passwordIssuesCoordinator.reauthModule = _reauthenticationModule;
[_passwordIssuesCoordinator start]; [_passwordIssuesCoordinator start];
} }
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include "components/password_manager/core/browser/password_manager_test_utils.h" #include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/password_manager/core/browser/test_password_store.h" #include "components/password_manager/core/browser/test_password_store.h"
#include "components/password_manager/core/common/password_manager_features.h" #include "components/password_manager/core/common/password_manager_features.h"
#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #include "ios/chrome/browser/main/test_browser.h"
#include "ios/chrome/browser/passwords/ios_chrome_bulk_leak_check_service_factory.h" #include "ios/chrome/browser/passwords/ios_chrome_bulk_leak_check_service_factory.h"
#include "ios/chrome/browser/passwords/ios_chrome_password_check_manager.h" #include "ios/chrome/browser/passwords/ios_chrome_password_check_manager.h"
#include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h" #include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h"
...@@ -90,18 +90,17 @@ class PasswordsTableViewControllerTest ...@@ -90,18 +90,17 @@ class PasswordsTableViewControllerTest
password_manager::features::kPasswordCheck); password_manager::features::kPasswordCheck);
} }
TestChromeBrowserState::Builder test_cbs_builder; browser_ = std::make_unique<TestBrowser>();
chrome_browser_state_ = test_cbs_builder.Build();
ChromeTableViewControllerTest::SetUp(); ChromeTableViewControllerTest::SetUp();
IOSChromePasswordStoreFactory::GetInstance()->SetTestingFactory( IOSChromePasswordStoreFactory::GetInstance()->SetTestingFactory(
chrome_browser_state_.get(), browser_->GetBrowserState(),
base::BindRepeating( base::BindRepeating(
&password_manager::BuildPasswordStore<web::BrowserState, &password_manager::BuildPasswordStore<web::BrowserState,
TestPasswordStore>)); TestPasswordStore>));
IOSChromeBulkLeakCheckServiceFactory::GetInstance() IOSChromeBulkLeakCheckServiceFactory::GetInstance()
->SetTestingFactoryAndUse( ->SetTestingFactoryAndUse(
chrome_browser_state_.get(), browser_->GetBrowserState(),
base::BindLambdaForTesting([](web::BrowserState*) { base::BindLambdaForTesting([](web::BrowserState*) {
return std::unique_ptr<KeyedService>( return std::unique_ptr<KeyedService>(
std::make_unique<MockBulkLeakCheckService>()); std::make_unique<MockBulkLeakCheckService>());
...@@ -129,19 +128,19 @@ class PasswordsTableViewControllerTest ...@@ -129,19 +128,19 @@ class PasswordsTableViewControllerTest
TestPasswordStore& GetTestStore() { TestPasswordStore& GetTestStore() {
return *static_cast<TestPasswordStore*>( return *static_cast<TestPasswordStore*>(
IOSChromePasswordStoreFactory::GetForBrowserState( IOSChromePasswordStoreFactory::GetForBrowserState(
chrome_browser_state_.get(), ServiceAccessType::EXPLICIT_ACCESS) browser_->GetBrowserState(), ServiceAccessType::EXPLICIT_ACCESS)
.get()); .get());
} }
MockBulkLeakCheckService& GetMockPasswordCheckService() { MockBulkLeakCheckService& GetMockPasswordCheckService() {
return *static_cast<MockBulkLeakCheckService*>( return *static_cast<MockBulkLeakCheckService*>(
IOSChromeBulkLeakCheckServiceFactory::GetForBrowserState( IOSChromeBulkLeakCheckServiceFactory::GetForBrowserState(
chrome_browser_state_.get())); browser_->GetBrowserState()));
} }
ChromeTableViewController* InstantiateController() override { ChromeTableViewController* InstantiateController() override {
return [[PasswordsTableViewController alloc] return
initWithBrowserState:chrome_browser_state_.get()]; [[PasswordsTableViewController alloc] initWithBrowser:browser_.get()];
} }
void ChangePasswordCheckState(PasswordCheckUIState state) { void ChangePasswordCheckState(PasswordCheckUIState state) {
...@@ -275,7 +274,7 @@ class PasswordsTableViewControllerTest ...@@ -275,7 +274,7 @@ class PasswordsTableViewControllerTest
void RunUntilIdle() { task_environment_.RunUntilIdle(); } void RunUntilIdle() { task_environment_.RunUntilIdle(); }
web::WebTaskEnvironment task_environment_; web::WebTaskEnvironment task_environment_;
std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; std::unique_ptr<TestBrowser> browser_;
base::test::ScopedFeatureList scoped_feature_list_; base::test::ScopedFeatureList scoped_feature_list_;
}; };
......
...@@ -143,8 +143,7 @@ NSString* const kSettingsDoneButtonId = @"kSettingsDoneButtonId"; ...@@ -143,8 +143,7 @@ NSString* const kSettingsDoneButtonId = @"kSettingsDoneButtonId";
delegate { delegate {
DCHECK(browser); DCHECK(browser);
PasswordsTableViewController* controller = PasswordsTableViewController* controller =
[[PasswordsTableViewController alloc] [[PasswordsTableViewController alloc] initWithBrowser:browser];
initWithBrowserState:browser->GetBrowserState()];
controller.dispatcher = [delegate handlerForSettings]; controller.dispatcher = [delegate handlerForSettings];
SettingsNavigationController* nc = [[SettingsNavigationController alloc] SettingsNavigationController* nc = [[SettingsNavigationController alloc]
...@@ -522,8 +521,7 @@ NSString* const kSettingsDoneButtonId = @"kSettingsDoneButtonId"; ...@@ -522,8 +521,7 @@ NSString* const kSettingsDoneButtonId = @"kSettingsDoneButtonId";
- (void)showSavedPasswordsSettingsFromViewController: - (void)showSavedPasswordsSettingsFromViewController:
(UIViewController*)baseViewController { (UIViewController*)baseViewController {
PasswordsTableViewController* controller = PasswordsTableViewController* controller =
[[PasswordsTableViewController alloc] [[PasswordsTableViewController alloc] initWithBrowser:self.browser];
initWithBrowserState:self.browser->GetBrowserState()];
controller.dispatcher = [self.settingsNavigationDelegate handlerForSettings]; controller.dispatcher = [self.settingsNavigationDelegate handlerForSettings];
[self pushViewController:controller animated:YES]; [self pushViewController:controller animated:YES];
} }
......
...@@ -886,8 +886,8 @@ NSString* kDevViewSourceKey = @"DevViewSource"; ...@@ -886,8 +886,8 @@ NSString* kDevViewSourceKey = @"DevViewSource";
case ItemTypePasswords: case ItemTypePasswords:
base::RecordAction( base::RecordAction(
base::UserMetricsAction("Options_ShowPasswordManager")); base::UserMetricsAction("Options_ShowPasswordManager"));
controller = [[PasswordsTableViewController alloc] controller =
initWithBrowserState:_browserState]; [[PasswordsTableViewController alloc] initWithBrowser:_browser];
break; break;
case ItemTypeAutofillCreditCard: case ItemTypeAutofillCreditCard:
base::RecordAction(base::UserMetricsAction("AutofillCreditCardsViewed")); base::RecordAction(base::UserMetricsAction("AutofillCreditCardsViewed"));
......
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