Merge branch 'use-relative-documents-url'
This commit is contained in:
commit
bcd8032978
|
@ -59,7 +59,7 @@
|
||||||
"parsed_file.alerts.parsing.message" = "Unable to parse the provided configuration file (%@).";
|
"parsed_file.alerts.parsing.message" = "Unable to parse the provided configuration file (%@).";
|
||||||
"parsed_file.alerts.buttons.report" = "Report an issue";
|
"parsed_file.alerts.buttons.report" = "Report an issue";
|
||||||
|
|
||||||
"imported_hosts.title" = "Imported";
|
"imported_hosts.title" = "Imported hosts";
|
||||||
|
|
||||||
"service.welcome.message" = "Welcome to Passepartout!\n\nUse the organizer to add a new profile.";
|
"service.welcome.message" = "Welcome to Passepartout!\n\nUse the organizer to add a new profile.";
|
||||||
"service.sections.general.header" = "General";
|
"service.sections.general.header" = "General";
|
||||||
|
|
|
@ -54,13 +54,12 @@ extension ConnectionService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func targetConfigurationURL(for key: ProfileKey) -> URL {
|
private func targetConfigurationURL(for key: ProfileKey) -> URL {
|
||||||
let contextURL = key.contextURL(in: self)
|
return contextURL(key).appendingPathComponent(key.id).appendingPathExtension("ovpn")
|
||||||
return contextURL.appendingPathComponent(key.id).appendingPathExtension("ovpn")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func pendingConfigurationURLs() -> [URL] {
|
func pendingConfigurationURLs() -> [URL] {
|
||||||
do {
|
do {
|
||||||
let list = try FileManager.default.contentsOfDirectory(at: directory, includingPropertiesForKeys: nil, options: [])
|
let list = try FileManager.default.contentsOfDirectory(at: rootURL, includingPropertiesForKeys: nil, options: [])
|
||||||
return list.filter { $0.pathExtension == "ovpn" }
|
return list.filter { $0.pathExtension == "ovpn" }
|
||||||
} catch let e {
|
} catch let e {
|
||||||
log.error("Could not list imported configurations: \(e)")
|
log.error("Could not list imported configurations: \(e)")
|
||||||
|
|
|
@ -64,24 +64,6 @@ class ConnectionService: Codable {
|
||||||
id = profile.id
|
id = profile.id
|
||||||
}
|
}
|
||||||
|
|
||||||
func contextURL(in service: ConnectionService) -> URL {
|
|
||||||
switch context {
|
|
||||||
case .provider:
|
|
||||||
return service.providersURL
|
|
||||||
|
|
||||||
case .host:
|
|
||||||
return service.hostsURL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func profileURL(in service: ConnectionService) -> URL {
|
|
||||||
return ConnectionService.url(in: contextURL(in: service), forProfileId: id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func profileData(in service: ConnectionService) throws -> Data {
|
|
||||||
return try Data(contentsOf: profileURL(in: service))
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: RawRepresentable
|
// MARK: RawRepresentable
|
||||||
|
|
||||||
var rawValue: String {
|
var rawValue: String {
|
||||||
|
@ -101,14 +83,18 @@ class ConnectionService: Codable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy var directory = FileManager.default.userURL(for: .documentDirectory, appending: nil)
|
var directory: String? = nil
|
||||||
|
|
||||||
|
var rootURL: URL {
|
||||||
|
return FileManager.default.userURL(for: .documentDirectory, appending: directory)
|
||||||
|
}
|
||||||
|
|
||||||
private var providersURL: URL {
|
private var providersURL: URL {
|
||||||
return directory.appendingPathComponent(AppConstants.Store.providersDirectory)
|
return rootURL.appendingPathComponent(AppConstants.Store.providersDirectory)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var hostsURL: URL {
|
private var hostsURL: URL {
|
||||||
return directory.appendingPathComponent(AppConstants.Store.hostsDirectory)
|
return rootURL.appendingPathComponent(AppConstants.Store.hostsDirectory)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var build: Int
|
private var build: Int
|
||||||
|
@ -246,7 +232,7 @@ class ConnectionService: Codable {
|
||||||
try? fm.createDirectory(at: hostsURL, withIntermediateDirectories: false, attributes: nil)
|
try? fm.createDirectory(at: hostsURL, withIntermediateDirectories: false, attributes: nil)
|
||||||
|
|
||||||
for key in pendingRemoval {
|
for key in pendingRemoval {
|
||||||
let url = key.profileURL(in: self)
|
let url = profileURL(key)
|
||||||
try? fm.removeItem(at: url)
|
try? fm.removeItem(at: url)
|
||||||
if let cfg = configurationURL(for: key) {
|
if let cfg = configurationURL(for: key) {
|
||||||
try? fm.removeItem(at: cfg)
|
try? fm.removeItem(at: cfg)
|
||||||
|
@ -255,7 +241,7 @@ class ConnectionService: Codable {
|
||||||
for entry in cache.values {
|
for entry in cache.values {
|
||||||
if let profile = entry as? ProviderConnectionProfile {
|
if let profile = entry as? ProviderConnectionProfile {
|
||||||
do {
|
do {
|
||||||
let url = ConnectionService.url(in: providersURL, forProfileId: entry.id)
|
let url = profileURL(ProfileKey(.provider, entry.id))
|
||||||
let data = try encoder.encode(profile)
|
let data = try encoder.encode(profile)
|
||||||
try data.write(to: url)
|
try data.write(to: url)
|
||||||
log.debug("Saved provider '\(profile.id)'")
|
log.debug("Saved provider '\(profile.id)'")
|
||||||
|
@ -265,7 +251,7 @@ class ConnectionService: Codable {
|
||||||
}
|
}
|
||||||
} else if let profile = entry as? HostConnectionProfile {
|
} else if let profile = entry as? HostConnectionProfile {
|
||||||
do {
|
do {
|
||||||
let url = ConnectionService.url(in: hostsURL, forProfileId: entry.id)
|
let url = profileURL(ProfileKey(.host, entry.id))
|
||||||
let data = try encoder.encode(profile)
|
let data = try encoder.encode(profile)
|
||||||
try data.write(to: url)
|
try data.write(to: url)
|
||||||
log.debug("Saved host '\(profile.id)'")
|
log.debug("Saved host '\(profile.id)'")
|
||||||
|
@ -285,7 +271,7 @@ class ConnectionService: Codable {
|
||||||
if let _ = profile as? PlaceholderConnectionProfile {
|
if let _ = profile as? PlaceholderConnectionProfile {
|
||||||
let decoder = JSONDecoder()
|
let decoder = JSONDecoder()
|
||||||
do {
|
do {
|
||||||
let data = try key.profileData(in: self)
|
let data = try profileData(key)
|
||||||
switch context {
|
switch context {
|
||||||
case .provider:
|
case .provider:
|
||||||
profile = try decoder.decode(ProviderConnectionProfile.self, from: data)
|
profile = try decoder.decode(ProviderConnectionProfile.self, from: data)
|
||||||
|
@ -306,6 +292,24 @@ class ConnectionService: Codable {
|
||||||
return cache.keys.filter { $0.context == context }.map { $0.id }
|
return cache.keys.filter { $0.context == context }.map { $0.id }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func contextURL(_ key: ProfileKey) -> URL {
|
||||||
|
switch key.context {
|
||||||
|
case .provider:
|
||||||
|
return providersURL
|
||||||
|
|
||||||
|
case .host:
|
||||||
|
return hostsURL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func profileURL(_ key: ProfileKey) -> URL {
|
||||||
|
return contextURL(key).appendingPathComponent(key.id).appendingPathExtension("json")
|
||||||
|
}
|
||||||
|
|
||||||
|
func profileData(_ key: ProfileKey) throws -> Data {
|
||||||
|
return try Data(contentsOf: profileURL(key))
|
||||||
|
}
|
||||||
|
|
||||||
private static func profileId(fromURL url: URL) -> String? {
|
private static func profileId(fromURL url: URL) -> String? {
|
||||||
guard url.pathExtension == "json" else {
|
guard url.pathExtension == "json" else {
|
||||||
return nil
|
return nil
|
||||||
|
@ -313,10 +317,6 @@ class ConnectionService: Codable {
|
||||||
return url.deletingPathExtension().lastPathComponent
|
return url.deletingPathExtension().lastPathComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func url(in directory: URL, forProfileId profileId: String) -> URL {
|
|
||||||
return directory.appendingPathComponent(profileId).appendingPathExtension("json")
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Profiles
|
// MARK: Profiles
|
||||||
|
|
||||||
func addProfile(_ profile: ConnectionProfile, credentials: Credentials?) -> Bool {
|
func addProfile(_ profile: ConnectionProfile, credentials: Credentials?) -> Bool {
|
||||||
|
|
|
@ -35,9 +35,9 @@ class TransientStore {
|
||||||
|
|
||||||
static let shared = TransientStore()
|
static let shared = TransientStore()
|
||||||
|
|
||||||
private let rootURL: URL
|
private static var serviceURL: URL {
|
||||||
|
return FileManager.default.userURL(for: .documentDirectory, appending: AppConstants.Store.serviceFilename)
|
||||||
private let serviceURL: URL
|
}
|
||||||
|
|
||||||
let service: ConnectionService
|
let service: ConnectionService
|
||||||
|
|
||||||
|
@ -51,20 +51,16 @@ class TransientStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
private init() {
|
private init() {
|
||||||
rootURL = FileManager.default.userURL(for: .documentDirectory, appending: nil)
|
|
||||||
serviceURL = rootURL.appendingPathComponent(AppConstants.Store.serviceFilename)
|
|
||||||
|
|
||||||
let cfg = AppConstants.VPN.baseConfiguration()
|
let cfg = AppConstants.VPN.baseConfiguration()
|
||||||
do {
|
do {
|
||||||
ConnectionService.migrateJSON(at: serviceURL, to: serviceURL)
|
ConnectionService.migrateJSON(at: TransientStore.serviceURL, to: TransientStore.serviceURL)
|
||||||
|
|
||||||
let data = try Data(contentsOf: serviceURL)
|
let data = try Data(contentsOf: TransientStore.serviceURL)
|
||||||
if let content = String(data: data, encoding: .utf8) {
|
if let content = String(data: data, encoding: .utf8) {
|
||||||
log.verbose("Service JSON:")
|
log.verbose("Service JSON:")
|
||||||
log.verbose(content)
|
log.verbose(content)
|
||||||
}
|
}
|
||||||
service = try JSONDecoder().decode(ConnectionService.self, from: data)
|
service = try JSONDecoder().decode(ConnectionService.self, from: data)
|
||||||
service.directory = rootURL
|
|
||||||
service.baseConfiguration = cfg
|
service.baseConfiguration = cfg
|
||||||
service.loadProfiles()
|
service.loadProfiles()
|
||||||
} catch let e {
|
} catch let e {
|
||||||
|
@ -73,7 +69,6 @@ class TransientStore {
|
||||||
withAppGroup: GroupConstants.App.appGroup,
|
withAppGroup: GroupConstants.App.appGroup,
|
||||||
baseConfiguration: cfg
|
baseConfiguration: cfg
|
||||||
)
|
)
|
||||||
service.directory = rootURL
|
|
||||||
|
|
||||||
// // hardcoded loading
|
// // hardcoded loading
|
||||||
// _ = service.addProfile(ProviderConnectionProfile(name: .pia), credentials: nil)
|
// _ = service.addProfile(ProviderConnectionProfile(name: .pia), credentials: nil)
|
||||||
|
@ -83,7 +78,7 @@ class TransientStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
func serialize() {
|
func serialize() {
|
||||||
try? JSONEncoder().encode(service).write(to: serviceURL)
|
try? JSONEncoder().encode(service).write(to: TransientStore.serviceURL)
|
||||||
try? service.saveProfiles()
|
try? service.saveProfiles()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,7 +246,7 @@ internal enum L10n {
|
||||||
}
|
}
|
||||||
|
|
||||||
internal enum ImportedHosts {
|
internal enum ImportedHosts {
|
||||||
/// Imported
|
/// Imported hosts
|
||||||
internal static let title = L10n.tr("Localizable", "imported_hosts.title")
|
internal static let title = L10n.tr("Localizable", "imported_hosts.title")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue