-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PIA-1173: Add Bootstrapper and monitoring for vpn and auth status
- Loading branch information
1 parent
11c9e89
commit 68e240a
Showing
15 changed files
with
676 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// | ||
// BootstraperFactory.swift | ||
// PIA VPN-tvOS | ||
// | ||
// Created by Said Rehouni on 18/1/24. | ||
// Copyright © 2024 Private Internet Access Inc. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import PIALibrary | ||
import SwiftyBeaver | ||
|
||
class BootstraperFactory { | ||
static func makeBootstrapper() -> BootstraperType { | ||
Bootstrapper(setupDebugginConsole: setupDebugginConsole, | ||
loadDataBase: loadDataBase, | ||
cleanCurrentAccount: cleanCurrentAccount, | ||
migrateNMT: migrateNMT, | ||
setupLatestRegionList: setupLatestRegionList, | ||
setupConfiguration: setupConfiguration, | ||
setupPreferences: setupPreferences, | ||
acceptDataSharing: acceptDataSharing, | ||
dependencyBootstrap: Client.bootstrap, | ||
renewalDIPToken: renewalDIPToken, | ||
setupExceptionHandler: setupExceptionHandler) | ||
} | ||
|
||
private static func setupDebugginConsole() { | ||
let console = ConsoleDestination() | ||
#if PIA_DEV | ||
console.minLevel = .debug | ||
#else | ||
console.minLevel = .info | ||
#endif | ||
SwiftyBeaver.addDestination(console) | ||
} | ||
|
||
private static func migrateNMT() { | ||
AppPreferences.shared.migrateNMT() | ||
} | ||
|
||
private static func loadDataBase() { | ||
Client.database = Client.Database(group: AppConstants.appGroup) | ||
} | ||
|
||
private static func setupPreferences() { | ||
let defaults = Client.preferences.defaults | ||
defaults.isPersistentConnection = true | ||
defaults.mace = false | ||
defaults.vpnType = IKEv2Profile.vpnType | ||
} | ||
|
||
private static func cleanCurrentAccount() { | ||
// Check if should clean the account after delete the app and install again | ||
if Client.providers.accountProvider.shouldCleanAccount { | ||
//If first install, we need to ensure we don't have data from previous sessions in the Secure Keychain | ||
Client.providers.accountProvider.cleanDatabase() | ||
} | ||
} | ||
|
||
private static func setupLatestRegionList() { | ||
// TODO: Fix Build Phase script to download the latest Regions list on building | ||
/* | ||
guard let bundledRegionsURL = AppConstants.RegionsGEN4.bundleURL else { | ||
fatalError("Could not find bundled regions file") | ||
} | ||
do { | ||
let bundledServersJSON = try Data(contentsOf: bundledRegionsURL) | ||
Client.configuration.bundledServersJSON = bundledServersJSON | ||
} catch let e { | ||
fatalError("Could not parse bundled regions file: \(e)") | ||
} | ||
*/ | ||
} | ||
|
||
private static func renewalDIPToken() { | ||
// Check the DIP token for renewal | ||
if AppPreferences.shared.checksDipExpirationRequest, let dipToken = Client.providers.serverProvider.dipTokens?.first { | ||
Client.providers.serverProvider.handleDIPTokenExpiration(dipToken: dipToken, nil) | ||
} | ||
} | ||
|
||
private static func setupConfiguration() { | ||
Client.configuration.enablesConnectivityUpdates = true | ||
Client.configuration.enablesServerUpdates = true | ||
Client.configuration.enablesServerPings = true | ||
Client.configuration.webTimeout = AppConfiguration.ClientConfiguration.webTimeout | ||
Client.configuration.vpnProfileName = AppConfiguration.VPN.profileName | ||
} | ||
|
||
private static func acceptDataSharing() { | ||
if Client.preferences.shareServiceQualityData { | ||
ServiceQualityManager.shared.start() | ||
} else { | ||
ServiceQualityManager.shared.stop() | ||
} | ||
} | ||
|
||
private static func setupExceptionHandler() { | ||
NSSetUncaughtExceptionHandler { exception in | ||
Client.preferences.lastKnownException = "$exception,\n\(exception.callStackSymbols.joined(separator: "\n"))" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// | ||
// Bootstrapper.swift | ||
// PIA VPN-tvOS | ||
// | ||
// Created by Said Rehouni on 17/1/24. | ||
// Copyright © 2024 Private Internet Access Inc. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
protocol BootstraperType { | ||
func callAsFunction() | ||
} | ||
|
||
class Bootstrapper: BootstraperType { | ||
var setupDebugginConsole: (() -> Void) | ||
var loadDataBase: (() -> Void) | ||
var cleanCurrentAccount: (() -> Void) | ||
var migrateNMT: (() -> Void) | ||
var setupLatestRegionList: (() -> Void) | ||
var setupConfiguration: (() -> Void) | ||
var setupPreferences: (() -> Void) | ||
var acceptDataSharing: (() -> Void) | ||
var dependencyBootstrap: (() -> Void) | ||
var renewalDIPToken: (() -> Void) | ||
var setupExceptionHandler: (() -> Void) | ||
|
||
init(setupDebugginConsole: @escaping () -> Void, loadDataBase: @escaping () -> Void, cleanCurrentAccount: @escaping () -> Void, migrateNMT: @escaping () -> Void, setupLatestRegionList: @escaping () -> Void, setupConfiguration: @escaping () -> Void, setupPreferences: @escaping () -> Void, acceptDataSharing: @escaping () -> Void, dependencyBootstrap: @escaping () -> Void, renewalDIPToken: @escaping () -> Void, setupExceptionHandler: @escaping () -> Void) { | ||
self.setupDebugginConsole = setupDebugginConsole | ||
self.loadDataBase = loadDataBase | ||
self.cleanCurrentAccount = cleanCurrentAccount | ||
self.migrateNMT = migrateNMT | ||
self.setupLatestRegionList = setupLatestRegionList | ||
self.setupConfiguration = setupConfiguration | ||
self.setupPreferences = setupPreferences | ||
self.acceptDataSharing = acceptDataSharing | ||
self.dependencyBootstrap = dependencyBootstrap | ||
self.renewalDIPToken = renewalDIPToken | ||
self.setupExceptionHandler = setupExceptionHandler | ||
} | ||
|
||
func callAsFunction() { | ||
setupDebugginConsole() | ||
loadDataBase() | ||
cleanCurrentAccount() | ||
migrateNMT() | ||
setupLatestRegionList() | ||
setupConfiguration() | ||
setupPreferences() | ||
acceptDataSharing() | ||
dependencyBootstrap() | ||
renewalDIPToken() | ||
setupExceptionHandler() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
PIA VPN-tvOS/Shared/StateMonitors/StateMonitorsFactory.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// | ||
// StateMonitorsFactory.swift | ||
// PIA VPN-tvOS | ||
// | ||
// Created by Said Rehouni on 19/1/24. | ||
// Copyright © 2024 Private Internet Access Inc. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import PIALibrary | ||
|
||
class StateMonitorsFactory { | ||
static func makeUserAuthenticationStatusMonitor() -> UserAuthenticationStatusMonitorType { | ||
UserAuthenticationStatusMonitor(currentStatus: Client.providers.accountProvider.isLoggedIn ? .loggedIn : .loggedOut, | ||
notificationCenter: NotificationCenter.default) | ||
} | ||
|
||
static func makeVPNStatusMonitor() -> VPNStatusMonitorType { | ||
guard let defaultVPNProvider = Client.providers.vpnProvider as? DefaultVPNProvider else { | ||
fatalError("Incorrect vpn provider type") | ||
} | ||
|
||
return VPNStatusMonitor(vpnStatusProvider: defaultVPNProvider, | ||
notificationCenter: NotificationCenter.default) | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
PIA VPN-tvOS/Shared/StateMonitors/UserAuthenticationStatusMonitor.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// | ||
// UserAuthenticationStatusMonitor.swift | ||
// PIA VPN-tvOS | ||
// | ||
// Created by Said Rehouni on 18/1/24. | ||
// Copyright © 2024 Private Internet Access Inc. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import Combine | ||
|
||
protocol UserAuthenticationStatusMonitorType { | ||
func getStatus() -> AnyPublisher<UserAuthenticationStatus, Never> | ||
} | ||
|
||
enum UserAuthenticationStatus { | ||
case loggedIn | ||
case loggedOut | ||
} | ||
|
||
class UserAuthenticationStatusMonitor: UserAuthenticationStatusMonitorType { | ||
private var status: CurrentValueSubject<UserAuthenticationStatus, Never> | ||
private let notificationCenter: NotificationCenterType | ||
|
||
init(currentStatus: UserAuthenticationStatus, notificationCenter: NotificationCenterType) { | ||
self.notificationCenter = notificationCenter | ||
self.status = CurrentValueSubject<UserAuthenticationStatus, Never>(currentStatus) | ||
|
||
addObservers() | ||
} | ||
|
||
private func addObservers() { | ||
notificationCenter.addObserver(self, selector: #selector(handleAccountDidLogin), name: .PIAAccountDidLogin, object: nil) | ||
|
||
notificationCenter.addObserver(self, selector: #selector(handleAccountDidLogout), name: .PIAAccountDidLogout, object: nil) | ||
} | ||
|
||
@objc func handleAccountDidLogin() { | ||
if status.value != .loggedIn { | ||
status.send(.loggedIn) | ||
} | ||
} | ||
|
||
@objc func handleAccountDidLogout() { | ||
if status.value != .loggedOut { | ||
status.send(.loggedOut) | ||
} | ||
} | ||
|
||
func getStatus() -> AnyPublisher<UserAuthenticationStatus, Never> { | ||
return status.eraseToAnyPublisher() | ||
} | ||
|
||
deinit { | ||
notificationCenter.removeObserver(self) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// | ||
// VPNStatusMonitor.swift | ||
// PIA VPN-tvOS | ||
// | ||
// Created by Said Rehouni on 18/1/24. | ||
// Copyright © 2024 Private Internet Access Inc. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import Combine | ||
import PIALibrary | ||
|
||
protocol VPNStatusMonitorType { | ||
func getStatus() -> AnyPublisher<VPNStatus, Never> | ||
} | ||
|
||
class VPNStatusMonitor: VPNStatusMonitorType { | ||
private var status: CurrentValueSubject<VPNStatus, Never> | ||
private let vpnStatusProvider: VPNStatusProviderType | ||
private let notificationCenter: NotificationCenterType | ||
|
||
init(vpnStatusProvider: VPNStatusProviderType, notificationCenter: NotificationCenterType) { | ||
self.vpnStatusProvider = vpnStatusProvider | ||
self.notificationCenter = notificationCenter | ||
self.status = CurrentValueSubject<VPNStatus, Never>(vpnStatusProvider.vpnStatus) | ||
} | ||
|
||
private func addObservers() { | ||
notificationCenter.addObserver(self, | ||
selector: #selector(vpnStatusDidChange(notification:)), | ||
name: .PIADaemonsDidUpdateVPNStatus, | ||
object: nil) | ||
} | ||
|
||
@objc func vpnStatusDidChange(notification: Notification) { | ||
if vpnStatusProvider.vpnStatus != status.value { | ||
status.send(vpnStatusProvider.vpnStatus) | ||
} | ||
} | ||
|
||
func getStatus() -> AnyPublisher<VPNStatus, Never> { | ||
return status.eraseToAnyPublisher() | ||
} | ||
|
||
deinit { | ||
notificationCenter.removeObserver(self) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
PIA VPN-tvOSTests/RootContainer/Mocks/BootstraperMock.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// | ||
// BootstraperMock.swift | ||
// PIA VPN-tvOSTests | ||
// | ||
// Created by Said Rehouni on 20/1/24. | ||
// Copyright © 2024 Private Internet Access Inc. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
@testable import PIA_VPN_tvOS | ||
|
||
class BootstraperMock: BootstraperType { | ||
var callAsFunctionTimesCalled = 0 | ||
|
||
func callAsFunction() { | ||
callAsFunctionTimesCalled += 1 | ||
} | ||
} |
Oops, something went wrong.