2018-12-28 20:06:46 +00:00
|
|
|
// SPDX-License-Identifier: MIT
|
2020-12-04 11:15:29 +00:00
|
|
|
// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved.
|
2018-12-28 20:06:46 +00:00
|
|
|
|
|
|
|
import Foundation
|
|
|
|
|
|
|
|
class TunnelImporter {
|
2019-02-25 10:52:52 +00:00
|
|
|
static func importFromFile(urls: [URL], into tunnelsManager: TunnelsManager, sourceVC: AnyObject?, errorPresenterType: ErrorPresenterProtocol.Type, completionHandler: (() -> Void)? = nil) {
|
|
|
|
guard !urls.isEmpty else {
|
|
|
|
completionHandler?()
|
|
|
|
return
|
|
|
|
}
|
2019-03-04 08:20:06 +00:00
|
|
|
let dispatchGroup = DispatchGroup()
|
|
|
|
var configs = [TunnelConfiguration?]()
|
|
|
|
var lastFileImportErrorText: (title: String, message: String)?
|
|
|
|
for url in urls {
|
|
|
|
if url.pathExtension.lowercased() == "zip" {
|
|
|
|
dispatchGroup.enter()
|
|
|
|
ZipImporter.importConfigFiles(from: url) { result in
|
2019-04-08 07:52:06 +00:00
|
|
|
switch result {
|
|
|
|
case .failure(let error):
|
2019-03-04 08:20:06 +00:00
|
|
|
lastFileImportErrorText = error.alertText
|
2019-04-08 07:52:06 +00:00
|
|
|
case .success(let configsInZip):
|
2019-03-04 08:20:06 +00:00
|
|
|
configs.append(contentsOf: configsInZip)
|
|
|
|
}
|
|
|
|
dispatchGroup.leave()
|
2019-02-25 10:52:52 +00:00
|
|
|
}
|
2019-03-04 08:20:06 +00:00
|
|
|
} else { /* if it is not a zip, we assume it is a conf */
|
|
|
|
let fileName = url.lastPathComponent
|
|
|
|
let fileBaseName = url.deletingPathExtension().lastPathComponent.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
|
|
dispatchGroup.enter()
|
|
|
|
DispatchQueue.global(qos: .userInitiated).async {
|
|
|
|
let fileContents: String
|
|
|
|
do {
|
|
|
|
fileContents = try String(contentsOf: url)
|
|
|
|
} catch let error {
|
|
|
|
DispatchQueue.main.async {
|
2019-03-05 10:27:11 +00:00
|
|
|
if let cocoaError = error as? CocoaError, cocoaError.isFileError {
|
|
|
|
lastFileImportErrorText = (title: tr("alertCantOpenInputConfFileTitle"), message: error.localizedDescription)
|
|
|
|
} else {
|
|
|
|
lastFileImportErrorText = (title: tr("alertCantOpenInputConfFileTitle"), message: tr(format: "alertCantOpenInputConfFileMessage (%@)", fileName))
|
|
|
|
}
|
2019-03-04 08:20:06 +00:00
|
|
|
configs.append(nil)
|
|
|
|
dispatchGroup.leave()
|
|
|
|
}
|
2019-02-25 10:52:52 +00:00
|
|
|
return
|
|
|
|
}
|
2019-06-28 10:06:58 +00:00
|
|
|
var parseError: Error?
|
|
|
|
var tunnelConfiguration: TunnelConfiguration?
|
|
|
|
do {
|
|
|
|
tunnelConfiguration = try TunnelConfiguration(fromWgQuickConfig: fileContents, called: fileBaseName)
|
|
|
|
} catch let error {
|
|
|
|
parseError = error
|
|
|
|
}
|
2019-03-04 08:20:06 +00:00
|
|
|
DispatchQueue.main.async {
|
2019-06-28 10:06:58 +00:00
|
|
|
if parseError != nil {
|
|
|
|
if let parseError = parseError as? WireGuardAppError {
|
|
|
|
lastFileImportErrorText = parseError.alertText
|
|
|
|
} else {
|
|
|
|
lastFileImportErrorText = (title: tr("alertBadConfigImportTitle"), message: tr(format: "alertBadConfigImportMessage (%@)", fileName))
|
|
|
|
}
|
2019-03-05 10:27:11 +00:00
|
|
|
}
|
2019-03-04 08:20:06 +00:00
|
|
|
configs.append(tunnelConfiguration)
|
|
|
|
dispatchGroup.leave()
|
|
|
|
}
|
2019-02-25 10:52:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-03-04 08:20:06 +00:00
|
|
|
dispatchGroup.notify(queue: .main) {
|
2019-03-05 10:20:50 +00:00
|
|
|
tunnelsManager.addMultiple(tunnelConfigurations: configs.compactMap { $0 }) { numberSuccessful, lastAddError in
|
2019-03-04 08:20:06 +00:00
|
|
|
if !configs.isEmpty && numberSuccessful == configs.count {
|
|
|
|
completionHandler?()
|
2018-12-28 20:06:46 +00:00
|
|
|
return
|
|
|
|
}
|
2019-03-05 10:20:50 +00:00
|
|
|
let alertText: (title: String, message: String)?
|
2019-03-04 08:20:06 +00:00
|
|
|
if urls.count == 1 {
|
|
|
|
if urls.first!.pathExtension.lowercased() == "zip" && !configs.isEmpty {
|
2019-03-05 10:20:50 +00:00
|
|
|
alertText = (title: tr(format: "alertImportedFromZipTitle (%d)", numberSuccessful),
|
|
|
|
message: tr(format: "alertImportedFromZipMessage (%1$d of %2$d)", numberSuccessful, configs.count))
|
2018-12-28 20:06:46 +00:00
|
|
|
} else {
|
2019-03-05 10:20:50 +00:00
|
|
|
alertText = lastFileImportErrorText ?? lastAddError?.alertText
|
2018-12-28 20:06:46 +00:00
|
|
|
}
|
2019-03-04 08:20:06 +00:00
|
|
|
} else {
|
2019-03-05 10:20:50 +00:00
|
|
|
alertText = (title: tr(format: "alertImportedFromMultipleFilesTitle (%d)", numberSuccessful),
|
|
|
|
message: tr(format: "alertImportedFromMultipleFilesMessage (%1$d of %2$d)", numberSuccessful, configs.count))
|
|
|
|
}
|
|
|
|
if let alertText = alertText {
|
|
|
|
errorPresenterType.showErrorAlert(title: alertText.title, message: alertText.message, from: sourceVC, onPresented: completionHandler)
|
|
|
|
} else {
|
|
|
|
completionHandler?()
|
2018-12-28 20:06:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|