Skip to content

Commit 6e72591

Browse files
committed
Add tracking of whether an account exists to TunnelManager; activate/deactivate key rotation appropriately.
1 parent a302326 commit 6e72591

File tree

4 files changed

+30
-7
lines changed

4 files changed

+30
-7
lines changed

ios/MullvadVPN/TunnelManager/SetAccountOperation.swift

+8
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ enum SetAccountAction {
3535
case .delete: "Delete account"
3636
}
3737
}
38+
39+
// true if this action results in an account being set if successful
40+
var isConstructive: Bool {
41+
switch self {
42+
case .unset, .delete: false
43+
default: true
44+
}
45+
}
3846
}
3947

4048
class SetAccountOperation: ResultOperation<StoredAccountData?> {

ios/MullvadVPN/TunnelManager/TunnelManager.swift

+18-1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ final class TunnelManager: StorePaymentObserver {
6060
private let observerList = ObserverList<TunnelObserver>()
6161
private var networkMonitor: NWPathMonitor?
6262

63+
private var hasAccount = false {
64+
didSet(previous) {
65+
if hasAccount != previous {
66+
startOrStopPeriodicPrivateKeyRotation()
67+
}
68+
}
69+
}
70+
6371
private var privateKeyRotationTimer: DispatchSourceTimer?
6472
public private(set) var isRunningPeriodicPrivateKeyRotation = false
6573
public private(set) var nextKeyRotationDate: Date? = nil
@@ -112,7 +120,7 @@ final class TunnelManager: StorePaymentObserver {
112120
nslock.lock()
113121
defer { nslock.unlock() }
114122

115-
guard !isRunningPeriodicPrivateKeyRotation else { return }
123+
guard !isRunningPeriodicPrivateKeyRotation, hasAccount else { return }
116124

117125
logger.debug("Start periodic private key rotation.")
118126

@@ -132,6 +140,14 @@ final class TunnelManager: StorePaymentObserver {
132140
updatePrivateKeyRotationTimer()
133141
}
134142

143+
func startOrStopPeriodicPrivateKeyRotation() {
144+
if hasAccount {
145+
startPeriodicPrivateKeyRotation()
146+
} else {
147+
stopPeriodicPrivateKeyRotation()
148+
}
149+
}
150+
135151
func getNextKeyRotationDate() -> Date? {
136152
nslock.lock()
137153
defer { nslock.unlock() }
@@ -337,6 +353,7 @@ final class TunnelManager: StorePaymentObserver {
337353

338354
operation.completionQueue = .main
339355
operation.completionHandler = { [weak self] result in
356+
self?.hasAccount = action.isConstructive
340357
self?.updatePrivateKeyRotationTimer()
341358

342359
completionHandler(result)

ios/MullvadVPNTests/DevicesProxy+Stubs.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ struct DevicesProxyStub: DeviceHandling {
5454
retryStrategy: REST.RetryStrategy,
5555
completion: @escaping ProxyCompletionHandler<Bool>
5656
) -> Cancellable {
57-
AnyCancellable()
57+
completion(.success(true))
58+
return AnyCancellable()
5859
}
5960

6061
func rotateDeviceKey(

ios/MullvadVPNTests/TunnelManagerTests.swift

+2-5
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,8 @@ final class TunnelManagerTests: XCTestCase {
5959
apiProxy: apiProxy,
6060
accessTokenManager: accessTokenManager
6161
)
62-
tunnelManager.startPeriodicPrivateKeyRotation()
63-
let previousTimer = tunnelManager.nextKeyRotationDate
6462
_ = try await tunnelManager.setNewAccount()
65-
XCTAssertNotEqual(previousTimer, tunnelManager.nextKeyRotationDate)
63+
XCTAssertEqual(tunnelManager.isRunningPeriodicPrivateKeyRotation, true)
6664
}
6765

6866
func testLogOutStopsKeyRotations() async throws {
@@ -83,9 +81,8 @@ final class TunnelManagerTests: XCTestCase {
8381
apiProxy: apiProxy,
8482
accessTokenManager: accessTokenManager
8583
)
86-
tunnelManager.startPeriodicPrivateKeyRotation()
84+
_ = try await tunnelManager.setNewAccount()
8785
await tunnelManager.unsetAccount()
88-
// This currently fails, as isRunningPeriodicPrivateKeyRotation is not changed.
8986
XCTAssertEqual(tunnelManager.isRunningPeriodicPrivateKeyRotation, false)
9087
}
9188
}

0 commit comments

Comments
 (0)