summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2020-01-23 14:33:45 +0100
committerAndrej Mihajlov <and@mullvad.net>2020-01-23 14:33:45 +0100
commit8f9ac2d313f27d9cf9a3a9433de78619d2de44f1 (patch)
treef74ad2bacf82305295337e5617ba72da73a54d95
parent3a12e0aa8129b5385c08cf0b730e457c7234c0bc (diff)
parent6d1da2a4e7966b9d868d67f1d0b99be50e5f0172 (diff)
downloadmullvadvpn-8f9ac2d313f27d9cf9a3a9433de78619d2de44f1.tar.xz
mullvadvpn-8f9ac2d313f27d9cf9a3a9433de78619d2de44f1.zip
Merge branch 'remove-wg-key-on-logout-ios'
-rw-r--r--ios/MullvadVPN/AccountViewController.swift32
-rw-r--r--ios/MullvadVPN/MullvadAPI.swift9
-rw-r--r--ios/MullvadVPN/TunnelManager.swift52
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 {