marinofaggiana 5 лет назад
Родитель
Сommit
88383ad20f

+ 28 - 1
iOSClient/Database/NCManageDatabase.swift

@@ -2261,7 +2261,34 @@ class NCManageDatabase: NSObject {
         // Update Date Read Directory
         setDateReadDirectory(serverUrl: serverUrl, account: account)
     }
-    
+   
+    @objc func setMetadataEncrypted(ocId: String, encrypted: Bool) {
+           
+        let realm = try! Realm()
+
+        realm.beginWrite()
+
+        guard let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first else {
+            realm.cancelWrite()
+            return
+        }
+           
+        result.e2eEncrypted = encrypted
+
+        let account = result.account
+        let serverUrl = result.serverUrl
+           
+        do {
+            try realm.commitWrite()
+        } catch let error {
+            print("[LOG] Could not write to database: ", error)
+            return
+        }
+           
+        // Update Date Read Directory
+        setDateReadDirectory(serverUrl: serverUrl, account: account)
+    }
+       
     @objc func setMetadataFileNameView(serverUrl: String, fileName: String, newFileNameView: String, account: String) {
         
         let realm = try! Realm()

+ 6 - 3
iOSClient/Main/Menu/CCMain+Menu.swift

@@ -318,13 +318,16 @@ extension CCMain {
                         icon: CCGraphics.changeThemingColorImage(UIImage(named: "lock"), width: 50, height: 50, color: NCBrandColor.sharedInstance.icon),
                         action: { menuAction in
                             DispatchQueue.global(qos: .userInitiated).async {
-                                let error = NCNetworkingEndToEnd.sharedManager()?.markFolderEncrypted(onServerUrl: "\(self.serverUrl ?? "")/\(metadata.fileName)", fileId: metadata.fileId, user: appDelegate.activeUser, userID: appDelegate.activeUserID, password: appDelegate.activePassword, url: appDelegate.activeUrl)
+                                let serverUrl = self.serverUrl + "/" + metadata.fileName
+                                let error = NCNetworkingEndToEnd.sharedManager()?.markFolderEncrypted(onServerUrl: serverUrl, fileId: metadata.fileId, e2eToken: nil, user: appDelegate.activeUser, userID: appDelegate.activeUserID, password: appDelegate.activePassword, url: appDelegate.activeUrl)
                                 DispatchQueue.main.async {
                                     if (error != nil) {
                                         NCContentPresenter.shared.messageNotification(NSLocalizedString("_e2e_error_mark_folder_", comment: ""), description: error?.localizedDescription, delay: TimeInterval(k_dismissAfterSecond), type: .error, errorCode: (error! as NSError).code)
                                     } else {
-                                        NCManageDatabase.sharedInstance.deleteE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.activeAccount, "\(self.serverUrl ?? "")/\(metadata.fileName)"))
-                                        self.readFolder(self.serverUrl)
+                                        NCManageDatabase.sharedInstance.deleteE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.activeAccount, serverUrl))
+                                        NCManageDatabase.sharedInstance.setDirectory(serverUrl: serverUrl, serverUrlTo: nil, etag: nil, ocId: nil, fileId: nil, encrypted: true, richWorkspace: nil, account: metadata.account)
+                                        NCManageDatabase.sharedInstance.setMetadataEncrypted(ocId: metadata.ocId, encrypted: true)
+                                        NCMainCommon.sharedInstance.reloadDatasource(ServerUrl: self.serverUrl, ocId: metadata.ocId, action: k_action_MOD)
                                     }
                                 }
                             }

+ 63 - 56
iOSClient/Networking/NCNetworking.swift

@@ -286,72 +286,79 @@ import NCCommunication
             self.NotificationPost(name: k_notificationCenter_createFolder, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": Int(0)], errorDescription: "", completion: completion)
             return
         }
-        let isDirectoryEncrypted = CCUtility.isFolderEncrypted(serverUrl, e2eEncrypted: false, account: account)
-        if isDirectoryEncrypted {
-            fileNameIdentifier = CCUtility.generateRandomIdentifier()
-            fileNameFolderUrl = serverUrl + "/" + fileNameIdentifier
-        } else {
-            fileNameFolderUrl = serverUrl + "/" + fileNameFolder
-        }
-        
-        NCCommunication.sharedInstance.createFolder(fileNameFolderUrl, customUserAgent: nil, addCustomHeaders: nil, account: account) { (account, ocId, date, errorCode, errorDescription) in
-            if errorCode == 0 {
-                
-                self.readFile(serverUrlFileName: fileNameFolderUrl, account: account) { (account, metadataFolder, errorCode, errorDescription) in
-                    if errorCode == 0 {
-                        
-                        // Add folder
-                        NCManageDatabase.sharedInstance.addDirectory(encrypted: metadataFolder!.e2eEncrypted, favorite: metadataFolder!.favorite, ocId: metadataFolder!.ocId, fileId: metadataFolder!.fileId, etag: nil, permissions: metadataFolder!.permissions, serverUrl: fileNameFolderUrl, richWorkspace: metadataFolder!.richWorkspace, account: account)
-                        
-                        if isDirectoryEncrypted {
+        fileNameIdentifier = CCUtility.generateRandomIdentifier()
+        fileNameFolderUrl = serverUrl + "/" + fileNameIdentifier
+       
+        DispatchQueue.global().async {
+            
+            let directory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl))
+            if directory == nil {
+                self.NotificationPost(name: k_notificationCenter_createFolder, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": k_CCErrorInternalError], errorDescription: "Directory not found", completion: completion)
+                return
+            }
+            
+            if let error = NCNetworkingEndToEnd.sharedManager()?.lockFolderEncrypted(onServerUrl: serverUrl, fileId: directory?.ocId, user: user, userID: userID, password: password, url: url) as NSError? {
+                self.NotificationPost(name: k_notificationCenter_createFolder, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": error.code], errorDescription: error.localizedDescription, completion: completion)
+                return
+            }
+            
+            guard let lock = NCManageDatabase.sharedInstance.getE2ETokenLock(serverUrl: serverUrl) else {
+                self.NotificationPost(name: k_notificationCenter_createFolder, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": k_CCErrorInternalError], errorDescription: "Lock not found", completion: completion)
+                return
+            }
+            
+            NCCommunication.sharedInstance.createFolder(fileNameFolderUrl, customUserAgent: nil, addCustomHeaders: ["e2e-token" : lock.e2eToken], account: account) { (account, ocId, date, errorCode, errorDescription) in
+                if errorCode == 0 {
+                    self.readFile(serverUrlFileName: fileNameFolderUrl, account: account) { (account, metadataFolder, errorCode, errorDescription) in
+                        if errorCode == 0 {
+                            // Add Metadata
+                            NCManageDatabase.sharedInstance.addMetadata(metadataFolder!)
+                            // Add folder
+                            NCManageDatabase.sharedInstance.addDirectory(encrypted: metadataFolder!.e2eEncrypted, favorite: metadataFolder!.favorite, ocId: metadataFolder!.ocId, fileId: metadataFolder!.fileId, etag: nil, permissions: metadataFolder!.permissions, serverUrl: fileNameFolderUrl, richWorkspace: metadataFolder!.richWorkspace, account: account)
                             
-                            DispatchQueue.global().async {
-                                
-                                if let error = NCNetworkingEndToEnd.sharedManager()?.markFolderEncrypted(onServerUrl: fileNameFolderUrl, fileId: metadataFolder?.fileId, user: user, userID: userID, password: password, url: url) as NSError? {
-                                    self.NotificationPost(name: k_notificationCenter_createFolder, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": error.code], errorDescription: error.localizedDescription, completion: completion)
-                                    return
-                                }
-                                                                                                
-                                NCEndToEndEncryption.sharedManager()?.encryptkey(&key, initializationVector: &initializationVector)
-                                let metadataKey = NCEndToEndEncryption.sharedManager()?.generateKey(16)?.base64EncodedString(options: []) // AES_KEY_128_LENGTH
-                                
-                                object.account = account
-                                object.authenticationTag = nil
-                                object.fileName = fileNameFolder
-                                object.fileNameIdentifier = fileNameIdentifier
-                                object.fileNamePath = ""
-                                object.key = key! as String
-                                object.initializationVector = initializationVector! as String
-                                object.metadataKey = metadataKey!
-                                object.metadataKeyIndex = 0
-                                object.mimeType = "application/directory"
-                                object.serverUrl = serverUrl
-                                object.version = Int(NCManageDatabase.sharedInstance.getEndToEndEncryptionVersion(account: account))
-                                let _ = NCManageDatabase.sharedInstance.addE2eEncryption(object)
-                                
-                                // Send Metadata
-                                if let error = NCNetworkingEndToEnd.sharedManager()?.sendMetadata(onServerUrl: serverUrl, fileNameRename: nil, fileNameNewRename: nil, unlock: true, account: account, user: user, userID: userID, password: password, url: url) as NSError? {
-                                    self.NotificationPost(name: k_notificationCenter_createFolder, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": error.code], errorDescription: error.localizedDescription, completion: completion)
-                                    return
-                                }
-                                
-                                DispatchQueue.main.async {
-                                    self.NotificationPost(name: k_notificationCenter_createFolder, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": errorCode], errorDescription: errorDescription, completion: completion)
-                                }
+                            if let error = NCNetworkingEndToEnd.sharedManager()?.markFolderEncrypted(onServerUrl: fileNameFolderUrl, fileId: metadataFolder?.fileId, e2eToken: lock.e2eToken, user: user, userID: userID, password: password, url: url) as NSError? {
+                                self.NotificationPost(name: k_notificationCenter_createFolder, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": error.code], errorDescription: error.localizedDescription, completion: completion)
+                                return
+                            }
+
+                            NCEndToEndEncryption.sharedManager()?.encryptkey(&key, initializationVector: &initializationVector)
+                            let metadataKey = NCEndToEndEncryption.sharedManager()?.generateKey(16)?.base64EncodedString(options: []) // AES_KEY_128_LENGTH
+                            
+                            object.account = account
+                            object.authenticationTag = nil
+                            object.fileName = fileNameFolder
+                            object.fileNameIdentifier = fileNameIdentifier
+                            object.fileNamePath = ""
+                            object.key = key! as String
+                            object.initializationVector = initializationVector! as String
+                            object.metadataKey = metadataKey!
+                            object.metadataKeyIndex = 0
+                            object.mimeType = "application/directory"
+                            object.serverUrl = serverUrl
+                            object.version = Int(NCManageDatabase.sharedInstance.getEndToEndEncryptionVersion(account: account))
+                            let _ = NCManageDatabase.sharedInstance.addE2eEncryption(object)
+
+                            // Send Metadata
+                            if let error = NCNetworkingEndToEnd.sharedManager()?.sendMetadata(onServerUrl: serverUrl, fileNameRename: nil, fileNameNewRename: nil, unlock: true, account: account, user: user, userID: userID, password: password, url: url) as NSError? {
+                                self.NotificationPost(name: k_notificationCenter_createFolder, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": error.code], errorDescription: error.localizedDescription, completion: completion)
+                                return
                             }
+                            
+                            DispatchQueue.main.async {
+                                self.NotificationPost(name: k_notificationCenter_createFolder, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": errorCode], errorDescription: errorDescription, completion: completion)
+                            }
+                            
                         } else {
                             self.NotificationPost(name: k_notificationCenter_createFolder, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": errorCode], errorDescription: errorDescription, completion: completion)
                         }
-                    } else {
-                        self.NotificationPost(name: k_notificationCenter_createFolder, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": errorCode], errorDescription: errorDescription, completion: completion)
                     }
+                } else {
+                    self.NotificationPost(name: k_notificationCenter_createFolder, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": errorCode], errorDescription: errorDescription, completion: completion)
                 }
-            } else {
-                self.NotificationPost(name: k_notificationCenter_createFolder, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": errorCode], errorDescription: errorDescription, completion: completion)
             }
         }
     }
-    
+        
     //MARK: - WebDav Delete
 
     @objc func deleteMetadata(_ metadata: tableMetadata, user: String, userID: String, password: String, url: String, completion: @escaping (_ errorCode: Int, _ errorDescription: String)->()) {

+ 1 - 1
iOSClient/Networking/NCNetworkingEndToEnd.h

@@ -42,7 +42,7 @@
 
 // ===== End-to-End Encryption =====
 
-- (NSError *)markEndToEndFolderEncryptedOnServerUrl:(NSString *)serverUrl fileId:(NSString *)fileId user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url;
+- (NSError *)markEndToEndFolderEncryptedOnServerUrl:(NSString *)serverUrl fileId:(NSString *)fileId e2eToken:(NSString *)e2eToken user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url;
 - (NSError *)deletemarkEndToEndFolderEncryptedOnServerUrl:(NSString *)serverUrl fileId:(NSString *)fileId user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url;
 
 - (NSError *)getEndToEndMetadata:(NSString **)metadata fileId:(NSString *)fileId user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url;

+ 26 - 54
iOSClient/Networking/NCNetworkingEndToEnd.m

@@ -362,7 +362,7 @@
 #pragma --------------------------------------------------------------------------------------------
 // E2EE
 
-- (NSError *)markEndToEndFolderEncryptedOnServerUrl:(NSString *)serverUrl fileId:(NSString *)fileId user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url
+- (NSError *)markEndToEndFolderEncryptedOnServerUrl:(NSString *)serverUrl fileId:(NSString *)fileId e2eToken:(NSString *)e2eToken user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url
 {
     OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
 
@@ -373,68 +373,40 @@
     [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
     [communication setUserAgent:[CCUtility getUserAgent]];
     
-    tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
-
-    // Read Folder
-    [communication readFolder:serverUrl depth:@"1" withUserSessionToken:nil onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer, NSString *tokenReadFolder) {
-    
-        if (items.count > 1) {
+    // MARK
+    [communication markEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileId:fileId onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
             
-            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:999 userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_directory_not_empty_", nil) forKey:NSLocalizedDescriptionKey]];
-            dispatch_semaphore_signal(semaphore);
-            return;
-        }
-        
-        // LOCK
-        [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileId:fileId e2eToken:tableLock.e2eToken onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *e2eToken, NSString *redirectedServer) {
-        
-            [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileId:fileId e2eToken:e2eToken];
-            
-            // REMOVE METADATA
-            [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileId:fileId e2eToken:e2eToken onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                NSLog(@"[LOG] Found metadata and delete");
+        if (e2eToken) {
+            // UNLOCK
+            [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileId:fileId e2eToken:e2eToken onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
+                [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
+                dispatch_semaphore_signal(semaphore);
             } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-                NSLog(@"[LOG] %@", [NSString stringWithFormat:@"Remove metadata error %d", (int)response.statusCode]);
+                returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
+                dispatch_semaphore_signal(semaphore);
             }];
+        } else {
+            dispatch_semaphore_signal(semaphore);
+        }
         
-            // MARK
-            [communication markEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileId:fileId onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-            
-                // UNLOCK
-                [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileId:fileId e2eToken:e2eToken onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                    [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
-                    dispatch_semaphore_signal(semaphore);
-                } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-                    returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
-                    dispatch_semaphore_signal(semaphore);
-                }];
-            
-            } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
+    } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
             
-                returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_mark_folder_"];
+        returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_mark_folder_"];
 
-                // UNLOCK
-                [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileId:fileId e2eToken:e2eToken onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                    [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
-                    dispatch_semaphore_signal(semaphore);
-                } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-                    returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
-                    dispatch_semaphore_signal(semaphore);
-                }];
+        if (e2eToken) {
+            // UNLOCK
+            [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileId:fileId e2eToken:e2eToken onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
+                [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
+                dispatch_semaphore_signal(semaphore);
+            } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
+                returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
+                dispatch_semaphore_signal(semaphore);
             }];
-        
-        } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-        
-            returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
+        } else {
             dispatch_semaphore_signal(semaphore);
-        }];
-        
-    } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) {
-        
-        returnError = [self getError:response error:error descriptionDefault:@"_error_"];
-        dispatch_semaphore_signal(semaphore);
+        }
     }];
-    
+      
     while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
         [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];