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

[ios] Add reauthentication handler to credential extension

Bug: 1045455
Change-Id: I8e72c9466ae00d87141c4fcea30ee817a1fbfb55
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2106166
Commit-Queue: David Jean <djean@chromium.org>
Reviewed-by: default avatarJavier Ernesto Flores Robles <javierrobles@chromium.org>
Cr-Commit-Position: refs/heads/master@{#751973}
parent 8f35d4cf
......@@ -42,13 +42,17 @@ ios_appex_bundle("credential_provider_extension") {
sources = [
"credential_provider_view_controller.h",
"credential_provider_view_controller.mm",
"reauthentication_handler.h",
"reauthentication_handler.mm",
]
configs += [ "//build/config/compiler:enable_arc" ]
deps = [
":system_strings",
"//base",
"//ios/chrome/common/ui/colors",
"//ios/chrome/common/ui/reauthentication",
"//ios/chrome/credential_provider_extension/resources",
"//ios/chrome/credential_provider_extension/ui",
ios_account_verification_provider_target,
......
......@@ -21,6 +21,11 @@
<string>IDS_IOS_CREDENTIAL_PROVIDER_EXTENSION_CANCEL</string>
<string>IDS_IOS_CREDENTIAL_PROVIDER_STALE_CREDENTIALS_SUBTITLE</string>
<string>IDS_IOS_CREDENTIAL_PROVIDER_STALE_CREDENTIALS_TITLE</string>
<string>IDS_IOS_CREDENTIAL_PROVIDER_SCREENLOCK_REASON</string>
<string>IDS_IOS_CREDENTIAL_PROVIDER_SET_UP_SCREENLOCK_CONTENT</string>
<string>IDS_IOS_CREDENTIAL_PROVIDER_SET_UP_SCREENLOCK_TITLE</string>
<string>IDS_IOS_CREDENTIAL_PROVIDER_SET_UP_SCREENLOCK_LEARN_HOW</string>
<string>IDS_IOS_CREDENTIAL_PROVIDER_OK</string>
</array>
</dict>
</array>
......
......@@ -4,17 +4,29 @@
#import "ios/chrome/credential_provider_extension/credential_provider_view_controller.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
#import "ios/chrome/credential_provider_extension/reauthentication_handler.h"
#import "ios/chrome/credential_provider_extension/ui/credential_list_coordinator.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface CredentialProviderViewController ()
@interface CredentialProviderViewController () <SuccessfulReauthTimeAccessor>
// List coordinator that shows the list of passwords when started.
@property(nonatomic, strong) CredentialListCoordinator* listCoordinator;
// Date kept for ReauthenticationModule.
@property(nonatomic, strong) NSDate* lastSuccessfulReauthTime;
// Reauthentication Module used for reauthentication.
@property(nonatomic, strong) ReauthenticationModule* reauthenticationModule;
// Interface for |reauthenticationModule|, handling mostly the case when no
// hardware for authentication is available.
@property(nonatomic, strong) ReauthenticationHandler* reauthenticationHandler;
@end
@implementation CredentialProviderViewController
......@@ -28,4 +40,47 @@
[self.listCoordinator start];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// TODO(crbug.com/1045455): Remove, this is for testing purpose only.
[self reauthenticateIfNeededWithCompletionHandler:^(
ReauthenticationResult result) {
// TODO(crbug.com/1045455): Check result before cancelling.
[self.extensionContext
cancelRequestWithError:
[[NSError alloc]
initWithDomain:ASExtensionErrorDomain
code:ASExtensionErrorCode::ASExtensionErrorCodeFailed
userInfo:nil]];
}];
}
#pragma mark - Properties
- (ReauthenticationHandler*)reauthenticationHandler {
if (!self.reauthenticationModule) {
self.reauthenticationModule = [[ReauthenticationModule alloc]
initWithSuccessfulReauthTimeAccessor:self];
self.reauthenticationHandler = [[ReauthenticationHandler alloc]
initWithReauthenticationModule:self.reauthenticationModule];
}
return _reauthenticationHandler;
}
#pragma mark - Private
- (void)reauthenticateIfNeededWithCompletionHandler:
(void (^)(ReauthenticationResult))completionHandler {
[self.reauthenticationHandler
verifyUserWithCompletionHandler:completionHandler
presentReminderOnViewController:self];
}
#pragma mark - SuccessfulReauthTimeAccessor
- (void)updateSuccessfulReauthTime {
self.lastSuccessfulReauthTime = [[NSDate alloc] init];
}
@end
// 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_CREDENTIAL_PROVIDER_EXTENSION_REAUTHENTICATION_HANDLER_H_
#define IOS_CHROME_CREDENTIAL_PROVIDER_EXTENSION_REAUTHENTICATION_HANDLER_H_
#import "ios/chrome/common/ui/reauthentication/reauthentication_protocol.h"
#import <UIKit/UIKit.h>
// Handler for showing the hardwarde reauthentication input to user, or
// a dialog about setting a passcode if nothing else is available.
@interface ReauthenticationHandler : NSObject
// Creates a handler with the given |ReauthenticationProtocol| module.
// A test instance can be passed in.
- (instancetype)initWithReauthenticationModule:
(id<ReauthenticationProtocol>)reauthenticationModule;
// Starts reauthentication flow, which will call |completionHandler| with
// the result status, or present an alert reminding user to set a passcode
// if no hardware for reauthentication is available.
- (void)verifyUserWithCompletionHandler:
(void (^)(ReauthenticationResult))completionHandler
presentReminderOnViewController:(UIViewController*)viewController;
@end
#endif // IOS_CHROME_CREDENTIAL_PROVIDER_EXTENSION_REAUTHENTICATION_HANDLER_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.
#import "ios/chrome/credential_provider_extension/reauthentication_handler.h"
#import "base/logging.h"
#include "base/strings/sys_string_conversions.h"
#import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@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 {
DCHECK(viewController.extensionContext);
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];
UIAlertAction* learnAction = [UIAlertAction
actionWithTitle:
NSLocalizedString(
@"IDS_IOS_CREDENTIAL_PROVIDER_SET_UP_SCREENLOCK_LEARN_HOW",
@"Learn How")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction*) {
UIResponder* responder = viewController;
while (responder) {
if ([responder respondsToSelector:@selector(openURL:)]) {
[responder
performSelector:@selector(openURL:)
withObject:
[NSURL URLWithString:base::SysUTF8ToNSString(
kPasscodeArticleURL)]
afterDelay:0];
break;
}
responder = responder.nextResponder;
}
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];
}
@end
......@@ -181,6 +181,21 @@ all other OS specific variables will be false.
<message name="IDS_IOS_CREDENTIAL_PROVIDER_STALE_CREDENTIALS_TITLE" desc="Title for stale credentials screen." meaning="Title to show when a user signs out, and the credentials are no longer available.">
No Chrome Passwords
</message>
<message name="IDS_IOS_CREDENTIAL_PROVIDER_SCREENLOCK_REASON" desc="Reason given to user by iOS hardware unlock module." meaning="Used by iOS as the reason given to user for re-unlocking their device.">
Access Passwords...
</message>
<message name="IDS_IOS_CREDENTIAL_PROVIDER_SET_UP_SCREENLOCK_CONTENT" desc="Message informing the user that to use passwords, a screen lock needs to be set up on the device." meaning="This is shown as an alert message after the user tries to use passwords from chrome. [Length: about two lines]">
To use passwords, you must first set a passcode on your device.
</message>
<message name="IDS_IOS_CREDENTIAL_PROVIDER_SET_UP_SCREENLOCK_TITLE" desc="Title of the alert informing the user that in order to use passwords." meaning="Title of alert when a screen lock needs to be set up on the device. [Length: one line]">
Set A Passcode
</message>
<message name="IDS_IOS_CREDENTIAL_PROVIDER_SET_UP_SCREENLOCK_LEARN_HOW" desc="The label of the 'Learn how' button" meaning="'Learn how' button of the alert informing the user that in order to use passwords, a screen lock needs to be set up on the device. The button leads to a help article on how to set up a device lock.">
Learn How
</message>
<message name="IDS_IOS_CREDENTIAL_PROVIDER_OK" desc="Used for OK on buttons">
OK
</message>
</messages>
</release>
</grit>
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