From 33887ca91d312fe957c89ddf13924bb080901072 Mon Sep 17 00:00:00 2001
From: Bruno Muniz Azevedo Filho <bruno@elixxir.io>
Date: Wed, 13 Jul 2022 20:33:17 -0300
Subject: [PATCH] Fixed issue w/ backup

---
 .../BackupFeature/Service/BackupService.swift | 19 +++---
 Sources/SFTPFeature/SFTPService.swift         | 66 ++++++++++++++-----
 2 files changed, 56 insertions(+), 29 deletions(-)

diff --git a/Sources/BackupFeature/Service/BackupService.swift b/Sources/BackupFeature/Service/BackupService.swift
index 54a3a5f6..ed3b5b53 100644
--- a/Sources/BackupFeature/Service/BackupService.swift
+++ b/Sources/BackupFeature/Service/BackupService.swift
@@ -296,8 +296,6 @@ extension BackupService {
                 case .failure(let error):
                     print(error.localizedDescription)
                 }
-
-                // try? FileManager.default.removeItem(at: url)
             }
         case .icloud:
             icloudService.uploadBackup(url) {
@@ -311,8 +309,6 @@ extension BackupService {
                 case .failure(let error):
                     print(error.localizedDescription)
                 }
-
-                // try? FileManager.default.removeItem(at: url)
             }
         case .dropbox:
             dropboxService.uploadBackup(url) {
@@ -326,15 +322,16 @@ extension BackupService {
                 case .failure(let error):
                     print(error.localizedDescription)
                 }
-
-                // try? FileManager.default.removeItem(at: url)
             }
         case .sftp:
-            do {
-                try sftpService.uploadBackup(url)
-            } catch {
-                print(error.localizedDescription)
-            }
+            sftpService.uploadBackup(url, {
+                switch $0 {
+                case .success(let backup):
+                    self.settings.value.backups[.sftp] = backup
+                case .failure(let error):
+                    print(error.localizedDescription)
+                }
+            })
         }
     }
 }
diff --git a/Sources/SFTPFeature/SFTPService.swift b/Sources/SFTPFeature/SFTPService.swift
index b751f396..b040668b 100644
--- a/Sources/SFTPFeature/SFTPService.swift
+++ b/Sources/SFTPFeature/SFTPService.swift
@@ -9,13 +9,14 @@ import Presentation
 import DependencyInjection
 
 public typealias SFTPDownloadResult = (Result<Data, Error>) -> Void
-public typealias SFTPAuthorizationParams = (UIViewController, () -> Void)
+public typealias SFTPUploadResult = (Result<Backup, Error>) -> Void
 public typealias SFTPFetchResult = (Result<RestoreSettings?, Error>) -> Void
+public typealias SFTPAuthorizationParams = (UIViewController, () -> Void)
 
 public struct SFTPService {
     public var isAuthorized: () -> Bool
-    public var uploadBackup: (URL) throws -> Void
     public var fetchMetadata: (SFTPFetchResult) -> Void
+    public var uploadBackup: (URL, SFTPUploadResult) -> Void
     public var authorizeFlow: (SFTPAuthorizationParams) -> Void
     public var authenticate: (String, String, String) throws -> Void
     public var downloadBackup: (String, SFTPDownloadResult) -> Void
@@ -27,14 +28,14 @@ public extension SFTPService {
             print("^^^ Requested auth status on sftp service")
             return true
         },
-        uploadBackup: { url in
-            print("^^^ Requested upload on sftp service")
-            print("^^^ URL path: \(url.path)")
-        },
         fetchMetadata: { completion in
             print("^^^ Requested backup metadata on sftp service.")
             completion(.success(nil))
         },
+        uploadBackup: { url, completion in
+            print("^^^ Requested upload on sftp service")
+            print("^^^ URL path: \(url.path)")
+        },
         authorizeFlow: { (_, completion) in
             print("^^^ Requested authorizing flow on sftp service.")
             completion()
@@ -62,18 +63,6 @@ public extension SFTPService {
 
             return false
         },
-        uploadBackup: { url 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()
-
-            try sftp.upload(localURL: url, remotePath: "backup/backup.xxm")
-        },
         fetchMetadata: { completion in
             do {
                 let keychain = try DependencyInjection.Container.shared.resolve() as KeychainHandling
@@ -117,6 +106,47 @@ public extension SFTPService {
                 completion(.failure(error))
             }
         },
+        uploadBackup: { url, 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 data = try Data(contentsOf: url)
+
+                if (try? sftp.listFiles(in: "backup")) == nil {
+                    try sftp.createDirectory("backup")
+                }
+
+                try sftp.upload(data: data, remotePath: "backup/backup.xxm")
+
+                completion(.success(.init(
+                    id: "backup/backup.xxm",
+                    date: Date(),
+                    size: Float(data.count)
+                )))
+            } 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))
+            }
+        },
         authorizeFlow: { controller, completion in
             var pushPresenter: Presenting = PushPresenter()
             pushPresenter.present(SFTPController(completion), from: controller)
-- 
GitLab