diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2020-01-23 14:33:45 +0100 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2020-01-23 14:33:45 +0100 |
| commit | 8f9ac2d313f27d9cf9a3a9433de78619d2de44f1 (patch) | |
| tree | f74ad2bacf82305295337e5617ba72da73a54d95 | |
| parent | 3a12e0aa8129b5385c08cf0b730e457c7234c0bc (diff) | |
| parent | 6d1da2a4e7966b9d868d67f1d0b99be50e5f0172 (diff) | |
| download | mullvadvpn-8f9ac2d313f27d9cf9a3a9433de78619d2de44f1.tar.xz mullvadvpn-8f9ac2d313f27d9cf9a3a9433de78619d2de44f1.zip | |
Merge branch 'remove-wg-key-on-logout-ios'
| -rw-r--r-- | ios/MullvadVPN/AccountViewController.swift | 32 | ||||
| -rw-r--r-- | ios/MullvadVPN/MullvadAPI.swift | 9 | ||||
| -rw-r--r-- | ios/MullvadVPN/TunnelManager.swift | 52 |
3 files changed, 80 insertions, 13 deletions
diff --git a/ios/MullvadVPN/AccountViewController.swift b/ios/MullvadVPN/AccountViewController.swift index 6a423e2b9a..a4d0f8a959 100644 --- a/ios/MullvadVPN/AccountViewController.swift +++ b/ios/MullvadVPN/AccountViewController.swift @@ -42,17 +42,29 @@ class AccountViewController: UIViewController { } @IBAction func doLogout() { - logoutSubscriber = Account.shared.logout() - .receive(on: DispatchQueue.main) - .sink(receiveCompletion: { (completion) in - switch completion { - case .failure(let error): - self.presentError(error, preferredStyle: .alert) + let message = NSLocalizedString("Logging out. Please wait...", + comment: "A modal message displayed during log out") - case .finished: - self.performSegue(withIdentifier: SegueIdentifier.Account.logout.rawValue, sender: self) - } - }) + let alertController = UIAlertController( + title: nil, + message: message, + preferredStyle: .alert) + + present(alertController, animated: true) { + self.logoutSubscriber = Account.shared.logout() + .delay(for: .seconds(1), scheduler: DispatchQueue.main) + .sink(receiveCompletion: { (completion) in + switch completion { + case .failure(let error): + alertController.dismiss(animated: true) { + self.presentError(error, preferredStyle: .alert) + } + + case .finished: + self.performSegue(withIdentifier: SegueIdentifier.Account.logout.rawValue, sender: self) + } + }) + } } @IBAction func copyAccountToken() { diff --git a/ios/MullvadVPN/MullvadAPI.swift b/ios/MullvadVPN/MullvadAPI.swift index 055b55e078..0a09018818 100644 --- a/ios/MullvadVPN/MullvadAPI.swift +++ b/ios/MullvadVPN/MullvadAPI.swift @@ -163,6 +163,15 @@ class MullvadAPI { return MullvadAPI.makeDataTaskPublisher(request: request) } + func removeWireguardKey(accountToken: String, publicKey: Data) -> AnyPublisher<Response<Bool>, MullvadAPI.Error> { + let request = JsonRpcRequest(method: "remove_wg_key", params: [ + AnyEncodable(accountToken), + AnyEncodable(publicKey) + ]) + + return MullvadAPI.makeDataTaskPublisher(request: request) + } + private static func makeDataTaskPublisher<T: Decodable>(request: JsonRpcRequest) -> AnyPublisher<Response<T>, MullvadAPI.Error> { return Just(request) .encode(encoder: makeJSONEncoder()) diff --git a/ios/MullvadVPN/TunnelManager.swift b/ios/MullvadVPN/TunnelManager.swift index 3019fd2343..4b0f455e7e 100644 --- a/ios/MullvadVPN/TunnelManager.swift +++ b/ios/MullvadVPN/TunnelManager.swift @@ -431,9 +431,55 @@ class TunnelManager { .flatMap { (accountToken, tunnelProvider) -> AnyPublisher<(), TunnelManagerError> in let removeKeychainConfigPublisher = Deferred { - TunnelConfigurationManager.remove(account: accountToken) - .mapError { UnsetAccountError.removeTunnelConfiguration($0) } - .publisher + () -> AnyPublisher<(), UnsetAccountError> in + // Load existing configuration + switch TunnelConfigurationManager.load(account: accountToken) { + case .success(let tunnelConfig): + let publicKey = tunnelConfig.interface + .privateKey + .publicKey + .rawRepresentation + + // Remove configuration from Keychain + return TunnelConfigurationManager.remove(account: accountToken) + .mapError { UnsetAccountError.removeTunnelConfiguration($0) } + .publisher + .flatMap { + // Remove WireGuard key from master + self.apiClient.removeWireguardKey( + accountToken: accountToken, + publicKey: publicKey + ) + .retry(1) + .map({ (response) -> () in + switch response.result { + case .success(let isRemoved): + os_log(.debug, "Removed the WireGuard key from server: %{public}s", "\(isRemoved)") + + case .failure(let error): + os_log(.error, "Failed to remove the WireGuard key from server. Server error: %{public}s", error.localizedDescription) + } + + // Suppress server errors + return () + }).catch({ (error) -> Result<(), UnsetAccountError>.Publisher in + os_log(.error, "Failed to remove the Wireguard key from server. Network error: %{public}s", error.localizedDescription) + + // Suppress network errors + return Result.Publisher(()) + }) + }.eraseToAnyPublisher() + + case .failure(let error): + // Ignore Keychain errors because that normally means that the Keychain + // configuration was already removed and we shouldn't be blocking the + // user from logging out + os_log(.error, "Failed to read the tunnel configuration from Keychain: %{public}s", error.localizedDescription) + + return Just(()) + .setFailureType(to: UnsetAccountError.self) + .eraseToAnyPublisher() + } } let removeTunnelPublisher = Deferred { |
