Skip to content
Snippets Groups Projects
Commit b1250380 authored by Bruno Muniz's avatar Bruno Muniz :apple:
Browse files

Fixing sftp download

parent 8fa61fa0
No related branches found
No related tags found
2 merge requests!54Releasing 1.1.4,!42Adding SFTP as a service to backup/restore
...@@ -24,6 +24,7 @@ public final class OutlinedInputField: UIView { ...@@ -24,6 +24,7 @@ public final class OutlinedInputField: UIView {
textField.delegate = self textField.delegate = self
textField.backgroundColor = .clear textField.backgroundColor = .clear
textField.textColor = Asset.neutralDark.color
placeholderLabel.textColor = Asset.neutralWeak.color placeholderLabel.textColor = Asset.neutralWeak.color
placeholderLabel.font = Fonts.Mulish.regular.font(size: 16.0) placeholderLabel.font = Fonts.Mulish.regular.font(size: 16.0)
......
...@@ -5,6 +5,7 @@ import Models ...@@ -5,6 +5,7 @@ import Models
import Combine import Combine
import Defaults import Defaults
import XXModels import XXModels
import Keychain
import Foundation import Foundation
import Integration import Integration
import Permissions import Permissions
...@@ -31,6 +32,7 @@ final class LaunchViewModel { ...@@ -31,6 +32,7 @@ final class LaunchViewModel {
@Dependency private var network: XXNetworking @Dependency private var network: XXNetworking
@Dependency private var versionChecker: VersionChecker @Dependency private var versionChecker: VersionChecker
@Dependency private var dropboxService: DropboxInterface @Dependency private var dropboxService: DropboxInterface
@Dependency private var keychainHandler: KeychainHandling
@Dependency private var permissionHandler: PermissionHandling @Dependency private var permissionHandler: PermissionHandling
@KeyObject(.username, defaultValue: nil) var username: String? @KeyObject(.username, defaultValue: nil) var username: String?
...@@ -90,6 +92,7 @@ final class LaunchViewModel { ...@@ -90,6 +92,7 @@ final class LaunchViewModel {
self.hudSubject.send(.none) self.hudSubject.send(.none)
self.routeSubject.send(.onboarding(ndf)) self.routeSubject.send(.onboarding(ndf))
self.dropboxService.unlink() self.dropboxService.unlink()
try? self.keychainHandler.clear()
return return
} }
...@@ -98,6 +101,7 @@ final class LaunchViewModel { ...@@ -98,6 +101,7 @@ final class LaunchViewModel {
self.hudSubject.send(.none) self.hudSubject.send(.none)
self.routeSubject.send(.onboarding(ndf)) self.routeSubject.send(.onboarding(ndf))
self.dropboxService.unlink() self.dropboxService.unlink()
try? self.keychainHandler.clear()
return return
} }
......
...@@ -90,11 +90,17 @@ final class RestoreViewModel { ...@@ -90,11 +90,17 @@ final class RestoreViewModel {
} }
private func downloadBackupForSFTP(_ backup: Backup) { private func downloadBackupForSFTP(_ backup: Backup) {
do { sftpService.downloadBackup(backup.id, { [weak self] in
try sftpService.downloadBackup(backup.id) guard let self = self else { return }
} catch { self.stepRelay.send(.downloading(backup.size, backup.size))
print(error.localizedDescription)
} switch $0 {
case .success(let data):
self.continueRestoring(data: data)
case .failure(let error):
self.stepRelay.send(.failDownload(error))
}
})
} }
private func downloadBackupForDropbox(_ backup: Backup) { private func downloadBackupForDropbox(_ backup: Backup) {
......
import UIKit import UIKit
import Shout import Shout
import Socket
import Models import Models
import Combine import Combine
import Keychain import Keychain
...@@ -7,16 +8,17 @@ import Foundation ...@@ -7,16 +8,17 @@ import Foundation
import Presentation import Presentation
import DependencyInjection import DependencyInjection
public typealias SFTPFetchResult = (Result<RestoreSettings?, Error>) -> Void public typealias SFTPDownloadResult = (Result<Data, Error>) -> Void
public typealias SFTPAuthorizationParams = (UIViewController, () -> Void) public typealias SFTPAuthorizationParams = (UIViewController, () -> Void)
public typealias SFTPFetchResult = (Result<RestoreSettings?, Error>) -> Void
public struct SFTPService { public struct SFTPService {
public var isAuthorized: () -> Bool public var isAuthorized: () -> Bool
public var uploadBackup: (URL) throws -> Void public var uploadBackup: (URL) throws -> Void
public var downloadBackup: (String) throws -> Void
public var fetchMetadata: (SFTPFetchResult) -> Void public var fetchMetadata: (SFTPFetchResult) -> Void
public var authenticate: (String, String, String) throws -> Void
public var authorizeFlow: (SFTPAuthorizationParams) -> Void public var authorizeFlow: (SFTPAuthorizationParams) -> Void
public var authenticate: (String, String, String) throws -> Void
public var downloadBackup: (String, SFTPDownloadResult) -> Void
} }
public extension SFTPService { public extension SFTPService {
...@@ -29,23 +31,23 @@ public extension SFTPService { ...@@ -29,23 +31,23 @@ public extension SFTPService {
print("^^^ Requested upload on sftp service") print("^^^ Requested upload on sftp service")
print("^^^ URL path: \(url.path)") print("^^^ URL path: \(url.path)")
}, },
downloadBackup: { path in
print("^^^ Requested backup download on sftp service.")
print("^^^ Path: \(path)")
},
fetchMetadata: { completion in fetchMetadata: { completion in
print("^^^ Requested backup metadata on sftp service.") print("^^^ Requested backup metadata on sftp service.")
completion(.success(nil)) completion(.success(nil))
}, },
authorizeFlow: { (_, completion) in
print("^^^ Requested authorizing flow on sftp service.")
completion()
},
authenticate: { host, username, password in authenticate: { host, username, password in
print("^^^ Requested authentication on sftp service.") print("^^^ Requested authentication on sftp service.")
print("^^^ Host: \(host)") print("^^^ Host: \(host)")
print("^^^ Username: \(username)") print("^^^ Username: \(username)")
print("^^^ Password: \(password)") print("^^^ Password: \(password)")
}, },
authorizeFlow: { (_, completion) in downloadBackup: { path, completion in
print("^^^ Requested authorizing flow on sftp service.") print("^^^ Requested backup download on sftp service.")
completion() print("^^^ Path: \(path)")
} }
) )
...@@ -72,20 +74,6 @@ public extension SFTPService { ...@@ -72,20 +74,6 @@ public extension SFTPService {
try sftp.upload(localURL: url, remotePath: "backup/backup.xxm") try sftp.upload(localURL: url, remotePath: "backup/backup.xxm")
}, },
downloadBackup: { path in
let keychain = try DependencyInjection.Container.shared.resolve() as KeychainHandling
let host = try keychain.get(key: .host)
let password = try keychain.get(key: .pwd)
let username = try keychain.get(key: .username)
let ssh = try SSH(host: host!, port: 22)
try ssh.authenticate(username: username!, password: password!)
let sftp = try ssh.openSftp()
let temp = NSTemporaryDirectory()
try sftp.download(remotePath: path, localURL: URL(string: temp)!)
print(FileManager.default.fileExists(atPath: temp))
},
fetchMetadata: { completion in fetchMetadata: { completion in
do { do {
let keychain = try DependencyInjection.Container.shared.resolve() as KeychainHandling let keychain = try DependencyInjection.Container.shared.resolve() as KeychainHandling
...@@ -113,22 +101,87 @@ public extension SFTPService { ...@@ -113,22 +101,87 @@ public extension SFTPService {
completion(.success(nil)) completion(.success(nil))
} catch { } catch {
if let error = error as? SSHError {
print(error.kind)
print(error.message)
print(error.description)
} else if let error = error as? Socket.Error {
print(error.errorCode)
print(error.description)
print(error.errorReason)
print(error.localizedDescription)
} else {
print(error.localizedDescription)
}
completion(.failure(error)) completion(.failure(error))
} }
}, },
authenticate: { host, username, password in
let ssh = try SSH(host: host, port: 22)
try ssh.authenticate(username: username, password: password)
let sftp = try ssh.openSftp()
let keychain = try DependencyInjection.Container.shared.resolve() as KeychainHandling
try keychain.store(key: .host, value: host)
try keychain.store(key: .pwd, value: password)
try keychain.store(key: .username, value: username)
},
authorizeFlow: { controller, completion in authorizeFlow: { controller, completion in
var pushPresenter: Presenting = PushPresenter() var pushPresenter: Presenting = PushPresenter()
pushPresenter.present(SFTPController(completion), from: controller) pushPresenter.present(SFTPController(completion), from: controller)
},
authenticate: { host, username, password in
do {
try SSH.connect(
host: host,
port: 22,
username: username,
authMethod: SSHPassword(password)) { ssh in
_ = try ssh.openSftp()
let keychain = try DependencyInjection.Container.shared.resolve() as KeychainHandling
try keychain.store(key: .host, value: host)
try keychain.store(key: .pwd, value: password)
try keychain.store(key: .username, value: username)
}
} catch {
if let error = error as? SSHError {
print(error.kind)
print(error.message)
print(error.description)
} else if let error = error as? Socket.Error {
print(error.errorCode)
print(error.description)
print(error.errorReason)
print(error.localizedDescription)
} else {
print(error.localizedDescription)
}
throw error
}
},
downloadBackup: { path, completion in
do {
let keychain = try DependencyInjection.Container.shared.resolve() as KeychainHandling
let host = try keychain.get(key: .host)
let password = try keychain.get(key: .pwd)
let username = try keychain.get(key: .username)
let ssh = try SSH(host: host!, port: 22)
try ssh.authenticate(username: username!, password: password!)
let sftp = try ssh.openSftp()
let localURL = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.elixxir.messenger")!
.appendingPathComponent("sftp")
try sftp.download(remotePath: path, localURL: localURL)
let data = try Data(contentsOf: localURL)
completion(.success(data))
} catch {
completion(.failure(error))
if var error = error as? SSHError {
print(error.kind)
print(error.message)
print(error.description)
} else {
print(error.localizedDescription)
}
}
} }
) )
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment