Sign out: Make sure there is a secure backup

This commit is contained in:
manuroe
2020-06-30 18:00:56 +02:00
parent 0acd723cce
commit 082d03be2e
4 changed files with 121 additions and 26 deletions
+116 -21
View File
@@ -150,7 +150,7 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(void);
@interface SettingsViewController () <DeactivateAccountViewControllerDelegate,
KeyBackupSetupCoordinatorBridgePresenterDelegate,
SecureBackupSetupCoordinatorBridgePresenterDelegate,
SignOutAlertPresenterDelegate,
SingleImagePickerPresenterDelegate,
SettingsDiscoveryTableViewSectionDelegate, SettingsDiscoveryViewModelCoordinatorDelegate,
@@ -233,8 +233,6 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
// The current pushed view controller
UIViewController *pushedViewController;
KeyBackupSetupCoordinatorBridgePresenter *keyBackupSetupCoordinatorBridgePresenter;
SettingsIdentityServerCoordinatorBridgePresenter *identityServerSettingsCoordinatorBridgePresenter;
}
@@ -257,6 +255,9 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
@property (nonatomic, strong) SettingsDiscoveryTableViewSection *settingsDiscoveryTableViewSection;
@property (nonatomic, strong) SettingsDiscoveryThreePidDetailsCoordinatorBridgePresenter *discoveryThreePidDetailsPresenter;
@property (nonatomic, strong) SecureBackupSetupCoordinatorBridgePresenter *secureBackupSetupCoordinatorBridgePresenter;
@property (nonatomic, strong) AuthenticatedSessionViewControllerFactory *authenticatedSessionViewControllerFactory;
@end
@implementation SettingsViewController
@@ -429,7 +430,7 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
[super destroy];
}
keyBackupSetupCoordinatorBridgePresenter = nil;
_secureBackupSetupCoordinatorBridgePresenter = nil;
identityServerSettingsCoordinatorBridgePresenter = nil;
}
@@ -4084,35 +4085,72 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
[deactivateAccountViewController dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - SecureBackupSetupCoordinatorBridgePresenter
#pragma mark - KeyBackupSetupCoordinatorBridgePresenter
- (void)showKeyBackupSetupFromSignOutFlow:(BOOL)showFromSignOutFlow
- (void)showSecureBackupSetupFromSignOutFlow
{
keyBackupSetupCoordinatorBridgePresenter = [[KeyBackupSetupCoordinatorBridgePresenter alloc] initWithSession:self.mainSession];
[keyBackupSetupCoordinatorBridgePresenter presentFrom:self
isStartedFromSignOut:showFromSignOutFlow
animated:true];
keyBackupSetupCoordinatorBridgePresenter.delegate = self;
if (self.canSetupSecureBackup)
{
[self setupSecureBackup2];
}
else
{
// Set up cross-signing first
[self setupCrossSigningWithTitle:NSLocalizedStringFromTable(@"secure_key_backup_setup_intro_title", @"Vector", nil)
message:NSLocalizedStringFromTable(@"security_settings_user_password_description", @"Vector", nil)
success:^{
[self setupSecureBackup2];
} failure:^(NSError *error) {
}];
}
}
- (void)keyBackupSetupCoordinatorBridgePresenterDelegateDidCancel:(KeyBackupSetupCoordinatorBridgePresenter *)bridgePresenter {
[keyBackupSetupCoordinatorBridgePresenter dismissWithAnimated:true];
keyBackupSetupCoordinatorBridgePresenter = nil;
- (void)setupSecureBackup2
{
SecureBackupSetupCoordinatorBridgePresenter *secureBackupSetupCoordinatorBridgePresenter = [[SecureBackupSetupCoordinatorBridgePresenter alloc] initWithSession:self.mainSession];
secureBackupSetupCoordinatorBridgePresenter.delegate = self;
[secureBackupSetupCoordinatorBridgePresenter presentFrom:self animated:YES];
self.secureBackupSetupCoordinatorBridgePresenter = secureBackupSetupCoordinatorBridgePresenter;
}
- (void)keyBackupSetupCoordinatorBridgePresenterDelegateDidSetupRecoveryKey:(KeyBackupSetupCoordinatorBridgePresenter *)bridgePresenter {
[keyBackupSetupCoordinatorBridgePresenter dismissWithAnimated:true];
keyBackupSetupCoordinatorBridgePresenter = nil;
- (BOOL)canSetupSecureBackup
{
// Accept to create a setup only if we have the 3 cross-signing keys
// This is the path to have a sane state
// TODO: What about missing MSK that was not gossiped before?
MXRecoveryService *recoveryService = self.mainSession.crypto.recoveryService;
NSArray *crossSigningServiceSecrets = @[
MXSecretId.crossSigningMaster,
MXSecretId.crossSigningSelfSigning,
MXSecretId.crossSigningUserSigning];
return ([recoveryService.secretsStoredLocally mx_intersectArray:crossSigningServiceSecrets].count
== crossSigningServiceSecrets.count);
}
#pragma mark - SecureBackupSetupCoordinatorBridgePresenterDelegate
- (void)secureBackupSetupCoordinatorBridgePresenterDelegateDidComplete:(SecureBackupSetupCoordinatorBridgePresenter *)coordinatorBridgePresenter
{
[self.secureBackupSetupCoordinatorBridgePresenter dismissWithAnimated:YES completion:nil];
self.secureBackupSetupCoordinatorBridgePresenter = nil;
}
- (void)secureBackupSetupCoordinatorBridgePresenterDelegateDidCancel:(SecureBackupSetupCoordinatorBridgePresenter *)coordinatorBridgePresenter
{
[self.secureBackupSetupCoordinatorBridgePresenter dismissWithAnimated:YES completion:nil];
self.secureBackupSetupCoordinatorBridgePresenter = nil;
}
#pragma mark - SignOutAlertPresenterDelegate
- (void)signOutAlertPresenterDidTapBackupAction:(SignOutAlertPresenter * _Nonnull)presenter
{
[self showKeyBackupSetupFromSignOutFlow:YES];
[self showSecureBackupSetupFromSignOutFlow];
}
- (void)signOutAlertPresenterDidTapSignOutAction:(SignOutAlertPresenter * _Nonnull)presenter
@@ -4136,6 +4174,63 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
}];
}
- (void)setupCrossSigningWithTitle:(NSString*)title
message:(NSString*)message
success:(void (^)(void))success
failure:(void (^)(NSError *error))failure
{
__block UIViewController *viewController;
[self startActivityIndicator];
// Get credentials to set up cross-signing
NSString *path = [NSString stringWithFormat:@"%@/keys/device_signing/upload", kMXAPIPrefixPathUnstable];
_authenticatedSessionViewControllerFactory = [[AuthenticatedSessionViewControllerFactory alloc] initWithSession:self.mainSession];
[_authenticatedSessionViewControllerFactory viewControllerForPath:path
httpMethod:@"POST"
title:title
message:message
onViewController:^(UIViewController * _Nonnull theViewController)
{
viewController = theViewController;
[self presentViewController:viewController animated:YES completion:nil];
} onAuthenticated:^(NSDictionary * _Nonnull authParams) {
[viewController dismissViewControllerAnimated:NO completion:nil];
viewController = nil;
MXCrossSigning *crossSigning = self.mainSession.crypto.crossSigning;
if (crossSigning)
{
[crossSigning setupWithAuthParams:authParams success:^{
[self stopActivityIndicator];
success();
} failure:^(NSError * _Nonnull error) {
[self stopActivityIndicator];
[[AppDelegate theDelegate] showErrorAsAlert:error];
failure(error);
}];
}
} onCancelled:^{
[self stopActivityIndicator];
[viewController dismissViewControllerAnimated:NO completion:nil];
viewController = nil;
failure(nil);
} onFailure:^(NSError * _Nonnull error) {
[self stopActivityIndicator];
[[AppDelegate theDelegate] showErrorAsAlert:error];
[viewController dismissViewControllerAnimated:NO completion:nil];
viewController = nil;
failure(error);
}];
}
#pragma mark - SingleImagePickerPresenterDelegate
- (void)singleImagePickerPresenterDidCancel:(SingleImagePickerPresenter *)presenter