diff --git a/Riot/Modules/CrossSigning/Setup/CrossSigningSetupCoordinator.swift b/Riot/Modules/CrossSigning/Setup/CrossSigningSetupCoordinator.swift new file mode 100644 index 000000000..05d5f1d4c --- /dev/null +++ b/Riot/Modules/CrossSigning/Setup/CrossSigningSetupCoordinator.swift @@ -0,0 +1,107 @@ +// File created from FlowTemplate +// $ createRootCoordinator.sh CrossSigning CrossSigningSetup +/* + Copyright 2021 New Vector Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +import UIKit + +@objcMembers +final class CrossSigningSetupCoordinator: CrossSigningSetupCoordinatorType { + + // MARK: - Properties + + // MARK: Private + + private let parameters: CrossSigningSetupCoordinatorParameters + private let crossSigningService: CrossSigningService + + // MARK: Public + + // Must be used only internally + var childCoordinators: [Coordinator] = [] + + weak var delegate: CrossSigningSetupCoordinatorDelegate? + + // MARK: - Setup + + init(parameters: CrossSigningSetupCoordinatorParameters) { + self.parameters = parameters + self.crossSigningService = CrossSigningService() + } + + // MARK: - Public methods + + func start() { + self.showReauthentication() + } + + func toPresentable() -> UIViewController { + return self.parameters.presenter.toPresentable() + } + + // MARK: - Private methods + + private func showReauthentication() { + + let authenticationSessionParameters = self.crossSigningService.setupCrossSigningAuthenticationSessionParameters() + + let reauthenticationParameters = ReauthenticationCoordinatorParameters(session: parameters.session, + presenter: parameters.presenter, + title: parameters.title, + message: parameters.message, + authenticationSessionParameters: authenticationSessionParameters) + + let coordinator = ReauthenticationCoordinator(parameters: reauthenticationParameters) + coordinator.delegate = self + self.add(childCoordinator: coordinator) + + coordinator.start() + } + + private func setupCrossSigning(with authenticationParameters: [String: Any]) { + guard let crossSigning = self.parameters.session.crypto.crossSigning else { + return + } + + crossSigning.setup(withAuthParams: authenticationParameters) { [weak self] in + guard let self = self else { + return + } + self.delegate?.crossSigningSetupCoordinatorDidComplete(self) + } failure: { [weak self] error in + guard let self = self else { + return + } + self.delegate?.crossSigningSetupCoordinator(self, didFailWithError: error) + } + } +} + +// MARK: - ReauthenticationCoordinatorDelegate +extension CrossSigningSetupCoordinator: ReauthenticationCoordinatorDelegate { + + func reauthenticationCoordinatorDidComplete(_ coordinator: ReauthenticationCoordinatorType, withAuthenticationParameters authenticationParameters: [String: Any]?) { + self.setupCrossSigning(with: authenticationParameters ?? [:]) + } + + func reauthenticationCoordinatorDidCancel(_ coordinator: ReauthenticationCoordinatorType) { + self.delegate?.crossSigningSetupCoordinatorDidCancel(self) + } + + func reauthenticationCoordinator(_ coordinator: ReauthenticationCoordinatorType, didFailWithError error: Error) { + self.delegate?.crossSigningSetupCoordinator(self, didFailWithError: error) + } +} diff --git a/Riot/Modules/CrossSigning/Setup/CrossSigningSetupCoordinatorBridgePresenter.swift b/Riot/Modules/CrossSigning/Setup/CrossSigningSetupCoordinatorBridgePresenter.swift new file mode 100644 index 000000000..b334c9c40 --- /dev/null +++ b/Riot/Modules/CrossSigning/Setup/CrossSigningSetupCoordinatorBridgePresenter.swift @@ -0,0 +1,105 @@ +// File created from FlowTemplate +// $ createRootCoordinator.sh CrossSigning CrossSigningSetup +/* + Copyright 2021 New Vector Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +import Foundation + +/// CrossSigningSetupCoordinatorBridgePresenter enables to start CrossSigningSetupCoordinator from a view controller. +/// This bridge is used while waiting for global usage of coordinator pattern. +/// It breaks the Coordinator abstraction and it has been introduced for Objective-C compatibility (mainly for integration in legacy view controllers). +/// Each bridge should be removed once the underlying Coordinator has been integrated by another Coordinator. +@objcMembers +final class CrossSigningSetupCoordinatorBridgePresenter: NSObject { + + // MARK: - Properties + + // MARK: Private + + private let session: MXSession + private var coordinator: CrossSigningSetupCoordinator? + + private var didComplete: (() -> Void)? + private var didCancel: (() -> Void)? + private var didFail: ((Error) -> Void)? + + // MARK: - Setup + + init(session: MXSession) { + self.session = session + super.init() + } + + // MARK: - Public + + func present(with title: String, + message: String, + from viewController: UIViewController, + animated: Bool, + success: @escaping () -> Void, + cancel: @escaping () -> Void, + failure: @escaping (Error) -> Void) { + + self.didComplete = success + self.didCancel = cancel + self.didFail = failure + + let parameters = CrossSigningSetupCoordinatorParameters(session: self.session, presenter: viewController, title: title, message: message) + + let crossSigningSetupCoordinator = CrossSigningSetupCoordinator(parameters: parameters) + crossSigningSetupCoordinator.delegate = self + crossSigningSetupCoordinator.start() + + self.coordinator = crossSigningSetupCoordinator + } + + func dismiss(animated: Bool, completion: (() -> Void)?) { + + self.resetCompletions() + + guard let coordinator = self.coordinator else { + return + } + coordinator.toPresentable().dismiss(animated: animated) { + self.coordinator = nil + + if let completion = completion { + completion() + } + } + } + + private func resetCompletions() { + self.didComplete = nil + self.didCancel = nil + self.didFail = nil + } +} + +// MARK: - CrossSigningSetupCoordinatorDelegate +extension CrossSigningSetupCoordinatorBridgePresenter: CrossSigningSetupCoordinatorDelegate { + func crossSigningSetupCoordinatorDidComplete(_ coordinator: CrossSigningSetupCoordinatorType) { + self.didComplete?() + } + + func crossSigningSetupCoordinatorDidCancel(_ coordinator: CrossSigningSetupCoordinatorType) { + self.didCancel?() + } + + func crossSigningSetupCoordinator(_ coordinator: CrossSigningSetupCoordinatorType, didFailWithError error: Error) { + self.didFail?(error) + } +} diff --git a/Riot/Modules/CrossSigning/Setup/CrossSigningSetupCoordinatorParameters.swift b/Riot/Modules/CrossSigning/Setup/CrossSigningSetupCoordinatorParameters.swift new file mode 100644 index 000000000..65b50f2d9 --- /dev/null +++ b/Riot/Modules/CrossSigning/Setup/CrossSigningSetupCoordinatorParameters.swift @@ -0,0 +1,46 @@ +// +// Copyright 2020 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// CrossSigningSetupCoordinator input parameters +@objcMembers +class CrossSigningSetupCoordinatorParameters: NSObject { + + /// The Matrix session + let session: MXSession + + /// The presenter used to show authentication screen(s) + let presenter: Presentable + + /// The title to use in the authentication screen if present. + let title: String? + + /// The message to use in the authentication screen if present. + let message: String? + + init(session: MXSession, + presenter: Presentable, + title: String?, + message: String?) { + self.session = session + self.presenter = presenter + self.title = title + self.message = message + + super.init() + } +} diff --git a/Riot/Modules/CrossSigning/Setup/CrossSigningSetupCoordinatorType.swift b/Riot/Modules/CrossSigning/Setup/CrossSigningSetupCoordinatorType.swift new file mode 100644 index 000000000..1dc620d3f --- /dev/null +++ b/Riot/Modules/CrossSigning/Setup/CrossSigningSetupCoordinatorType.swift @@ -0,0 +1,30 @@ +// File created from FlowTemplate +// $ createRootCoordinator.sh CrossSigning CrossSigningSetup +/* + Copyright 2020 New Vector Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +import Foundation + +protocol CrossSigningSetupCoordinatorDelegate: class { + func crossSigningSetupCoordinatorDidComplete(_ coordinator: CrossSigningSetupCoordinatorType) + func crossSigningSetupCoordinatorDidCancel(_ coordinator: CrossSigningSetupCoordinatorType) + func crossSigningSetupCoordinator(_ coordinator: CrossSigningSetupCoordinatorType, didFailWithError error: Error) +} + +/// `CrossSigningSetupCoordinatorType` is a protocol describing a Coordinator that handles cross signing setup navigation flow. +protocol CrossSigningSetupCoordinatorType: Coordinator, Presentable { + var delegate: CrossSigningSetupCoordinatorDelegate? { get } +}