// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/credential_provider_extension/reauthentication_handler.h"
#import "base/logging.h"
#import "base/strings/sys_string_conversions.h"
#import "ios/chrome/common/app_group/app_group_command.h"
#import "ios/chrome/common/app_group/app_group_constants.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
@implementation ReauthenticationHandler {
// Module containing the reauthentication mechanism used accessing passwords.
__weak id<ReauthenticationProtocol> _weakReauthenticationModule;
}
- (instancetype)initWithReauthenticationModule:
(id<ReauthenticationProtocol>)reauthenticationModule {
DCHECK(reauthenticationModule);
self = [super init];
if (self) {
_weakReauthenticationModule = reauthenticationModule;
}
return self;
}
- (void)verifyUserWithCompletionHandler:
(void (^)(ReauthenticationResult))completionHandler
presentReminderOnViewController:(UIViewController*)viewController {
if ([_weakReauthenticationModule canAttemptReauth]) {
[_weakReauthenticationModule
attemptReauthWithLocalizedReason:
NSLocalizedString(@"IDS_IOS_CREDENTIAL_PROVIDER_SCREENLOCK_REASON",
@"Access Passwords...")
canReusePreviousAuth:YES
handler:completionHandler];
} else {
[self showSetPasscodeDialogOnViewController:viewController
completionHandler:completionHandler];
}
}
- (void)showSetPasscodeDialogOnViewController:(UIViewController*)viewController
completionHandler:(void (^)(ReauthenticationResult))
completionHandler {
UIAlertController* alertController = [UIAlertController
alertControllerWithTitle:
NSLocalizedString(
@"IDS_IOS_CREDENTIAL_PROVIDER_SET_UP_SCREENLOCK_TITLE",
@"Set A Passcode")
message:NSLocalizedString(
@"IDS_IOS_CREDENTIAL_PROVIDER_SET_UP_"
@"SCREENLOCK_CONTENT",
@"To use passwords, you must first set a "
@"passcode on your device.")
preferredStyle:UIAlertControllerStyleAlert];
__weak UIResponder* opener = [self openerFromViewController:viewController];
UIAlertAction* learnAction = [UIAlertAction
actionWithTitle:
NSLocalizedString(
@"IDS_IOS_CREDENTIAL_PROVIDER_SET_UP_SCREENLOCK_LEARN_HOW",
@"Learn How")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction*) {
[self openAppWithURL:[NSURL
URLWithString:base::SysUTF8ToNSString(
kPasscodeArticleURL)]
opener:opener];
completionHandler(ReauthenticationResult::kFailure);
}];
[alertController addAction:learnAction];
UIAlertAction* okAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"IDS_IOS_CREDENTIAL_PROVIDER_OK",
@"OK")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction*) {
completionHandler(ReauthenticationResult::kFailure);
}];
[alertController addAction:okAction];
alertController.preferredAction = okAction;
[viewController presentViewController:alertController
animated:YES
completion:nil];
}
#pragma mark - Private
// Returns first responder up the chain that can open a URL.
- (UIResponder*)openerFromViewController:(UIViewController*)viewController {
UIResponder* responder = viewController;
while (responder) {
if ([responder respondsToSelector:@selector(openURL:)]) {
return responder;
}
responder = responder.nextResponder;
}
return nil;
}
// Open URL through app group commands.
- (void)openAppWithURL:(NSURL*)URL opener:(UIResponder*)opener {
AppGroupCommand* command = [[AppGroupCommand alloc]
initWithSourceApp:app_group::kOpenCommandSourceCredentialsExtension
URLOpenerBlock:^(NSURL* openURL) {
if ([opener respondsToSelector:@selector(openURL:)]) {
[opener performSelector:@selector(openURL:)
withObject:openURL
afterDelay:0];
}
}];
[command prepareToOpenURL:URL];
[command executeInApp];
}
@end