소스 검색

E2EE lock/unlock #511

Marino Faggiana 7 년 전
부모
커밋
43cb443ab8
5개의 변경된 파일293개의 추가작업 그리고 253개의 파일을 삭제
  1. 13 1
      iOSClient/Database/NCDatabase.swift
  2. 81 39
      iOSClient/Database/NCManageDatabase.swift
  3. 12 12
      iOSClient/Main/CCMain.m
  4. 3 3
      iOSClient/Networking/CCNetworking.m
  5. 184 198
      iOSClient/Networking/NCNetworkingSync.m

+ 13 - 1
iOSClient/Database/NCDatabase.swift

@@ -108,7 +108,6 @@ class tableDirectory: Object {
     @objc dynamic var favorite: Bool = false
     @objc dynamic var fileID = ""
     @objc dynamic var lock: Bool = false
-    @objc dynamic var e2eTokenLock = ""
     @objc dynamic var permissions = ""
     @objc dynamic var serverUrl = ""
     
@@ -137,6 +136,19 @@ class tableE2eEncryption: Object {
     }
 }
 
+class tableE2eEncryptionLock: Object {
+
+    @objc dynamic var account = ""
+    @objc dynamic var date = NSDate()
+    @objc dynamic var fileID = ""
+    @objc dynamic var serverUrl = ""
+    @objc dynamic var token = ""
+    
+    override static func primaryKey() -> String {
+        return "fileID"
+    }
+}
+
 class tableExternalSites: Object {
     
     @objc dynamic var account = ""

+ 81 - 39
iOSClient/Database/NCManageDatabase.swift

@@ -57,7 +57,7 @@ class NCManageDatabase: NSObject {
         let config = Realm.Configuration(
         
             fileURL: dirGroup?.appendingPathComponent("\(appDatabaseNextcloud)/\(k_databaseDefault)"),
-            schemaVersion: 16,
+            schemaVersion: 17,
             
             // 10 : Version 2.18.0
             // 11 : Version 2.18.2
@@ -66,6 +66,7 @@ class NCManageDatabase: NSObject {
             // 14 : Version 2.19.0.xx
             // 15 : Version 2.19.2
             // 16 : Version 2.20.2
+            // 17 : Version 2.20.4
             
             migrationBlock: { migration, oldSchemaVersion in
                 // We haven’t migrated anything yet, so oldSchemaVersion == 0
@@ -915,26 +916,6 @@ class NCManageDatabase: NSObject {
         return result.serverUrl
     }
     
-    @objc func getDirectoryE2ETokenLock(serverUrl: String, completion: @escaping (String?) -> Void) {
-        
-        DispatchQueue.main.async {
-    
-            guard let tableAccount = self.getAccountActive() else {
-                completion(nil)
-                return
-            }
-            
-            let realm = try! Realm()
-        
-            guard let result = realm.objects(tableDirectory.self).filter("account = %@ AND serverUrl = %@ AND e2eTokenLock != ''", tableAccount.account, serverUrl).first else {
-                completion(nil)
-                return
-            }
-        
-            completion(result.e2eTokenLock)
-        }
-    }
-    
     @objc func setDateReadDirectory(directoryID: String) {
         
         guard let tableAccount = self.getAccountActive() else {
@@ -1033,36 +1014,27 @@ class NCManageDatabase: NSObject {
         }
     }
 
-    @objc func setDirectoryE2ETokenLock(serverUrl: String, token: String?) {
+    /*
+    @objc func getDirectoryE2ETokenLock(serverUrl: String, completion: @escaping (String?) -> Void) {
         
         DispatchQueue.main.async {
             
             guard let tableAccount = self.getAccountActive() else {
+                completion(nil)
                 return
             }
             
             let realm = try! Realm()
-        
-            realm.beginWrite()
-        
-            guard let result = realm.objects(tableDirectory.self).filter("account = %@ AND serverUrl = %@", tableAccount.account, serverUrl).first else {
-                realm.cancelWrite()
+            
+            guard let result = realm.objects(tableDirectory.self).filter("account = %@ AND serverUrl = %@ AND e2eTokenLock != ''", tableAccount.account, serverUrl).first else {
+                completion(nil)
                 return
             }
-        
-            if (token == nil) {
-                result.e2eTokenLock = ""
-            } else {
-                result.e2eTokenLock = token!
-            }
-    
-            do {
-                try realm.commitWrite()
-            } catch let error {
-                print("[LOG] Could not write to database: ", error)
-            }
+            
+            completion(result.e2eTokenLock)
         }
     }
+    */
     
     //MARK: -
     //MARK: Table e2e Encryption
@@ -1175,6 +1147,76 @@ class NCManageDatabase: NSObject {
         return
     }
     
+    //MARK: -
+    //MARK: Table e2e Encryption Lock
+    
+    @objc func getE2ETokenLock(serverUrl: String) -> tableE2eEncryptionLock? {
+        
+        guard let tableAccount = self.getAccountActive() else {
+            return nil
+        }
+        
+        let realm = try! Realm()
+        realm.refresh()
+            
+        guard let result = realm.objects(tableE2eEncryptionLock.self).filter("account = %@ AND serverUrl = %@", tableAccount.account, serverUrl).first else {
+            return nil
+        }
+        
+        return tableE2eEncryptionLock.init(value: result)
+    }
+    
+    @objc func setE2ETokenLock(serverUrl: String, fileID: String, token: String) {
+        
+        guard let tableAccount = self.getAccountActive() else {
+            return
+        }
+            
+        let realm = try! Realm()
+        realm.refresh()
+
+        realm.beginWrite()
+        
+        let addObject = tableE2eEncryptionLock()
+                
+        addObject.account = tableAccount.account
+        addObject.fileID = fileID
+        addObject.serverUrl = serverUrl
+        addObject.token = token
+                
+        realm.add(addObject, update: true)
+        
+        do {
+            try realm.commitWrite()
+        } catch let error {
+            print("[LOG] Could not write to database: ", error)
+        }
+    }
+    
+    @objc func deteleE2ETokenLock(serverUrl: String) {
+        
+        guard let tableAccount = self.getAccountActive() else {
+            return
+        }
+            
+        let realm = try! Realm()
+        realm.refresh()
+
+        realm.beginWrite()
+
+        guard let result = realm.objects(tableE2eEncryptionLock.self).filter("account = %@ AND serverUrl = %@", tableAccount.account, serverUrl).first else {
+            return
+        }
+            
+        realm.delete(result)
+            
+        do {
+            try realm.commitWrite()
+        } catch let error {
+            print("[LOG] Could not write to database: ", error)
+        }
+    }
+
     //MARK: -
     //MARK: Table External Sites
     

+ 12 - 12
iOSClient/Main/CCMain.m

@@ -2134,19 +2134,19 @@
             }
                 
             // Unlock
-            [[NCManageDatabase sharedInstance] getDirectoryE2ETokenLockWithServerUrl:self.serverUrl completion:^(NSString * _Nullable token) {
-                if (token != nil) {
-                    NSError *error = [[NCNetworkingSync sharedManager] unlockEndToEndFolderEncrypted:appDelegate.activeUser userID:appDelegate.activeUserID password:appDelegate.activePassword url:appDelegate.activeUrl serverUrl:self.serverUrl fileID:_metadataFolder.fileID token:token];
-                    if (error) {
-                        dispatch_async(dispatch_get_main_queue(), ^{
-                            [appDelegate messageNotification:@"_e2e_error_unlock_" description:error.localizedDescription visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:error.code];
-                        });
-                    }
+            tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:self.serverUrl];
+
+            if (tableLock != nil) {
+                NSError *error = [[NCNetworkingSync sharedManager] unlockEndToEndFolderEncrypted:appDelegate.activeUser userID:appDelegate.activeUserID password:appDelegate.activePassword url:appDelegate.activeUrl serverUrl:self.serverUrl fileID:_metadataFolder.fileID token:tableLock.token];
+                if (error) {
+                    dispatch_async(dispatch_get_main_queue(), ^{
+                        [appDelegate messageNotification:@"_e2e_error_unlock_" description:error.localizedDescription visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:error.code];
+                    });
                 }
-                dispatch_async(dispatch_get_main_queue(), ^{
-                    [self reloadDatasource];
-                });
-            }];
+            }
+            dispatch_async(dispatch_get_main_queue(), ^{
+                [self reloadDatasource];
+            });
         });
         
     } else  {

+ 3 - 3
iOSClient/Networking/CCNetworking.m

@@ -1183,12 +1183,12 @@
     // E2EE : UNLOCK
     if ([CCUtility isFolderEncrypted:serverUrl account:_activeAccount] && [CCUtility isEndToEndEnabled:_activeAccount]) {
         
-        tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", _activeAccount, serverUrl]];
+        tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
 
         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
             
-            if (directory.e2eTokenLock.length > 0 && directory.e2eTokenLock) {
-                NSError *error = [[NCNetworkingSync sharedManager] unlockEndToEndFolderEncrypted:_activeUser userID:_activeUserID password:_activePassword url:_activeUrl serverUrl:serverUrl fileID:directory.fileID token:directory.e2eTokenLock];
+            if (tableLock) {
+                NSError *error = [[NCNetworkingSync sharedManager] unlockEndToEndFolderEncrypted:_activeUser userID:_activeUserID password:_activePassword url:_activeUrl serverUrl:serverUrl fileID:tableLock.fileID token:tableLock.token];
                 if (error) {
 #ifndef EXTENSION
                     dispatch_async(dispatch_get_main_queue(), ^{

+ 184 - 198
iOSClient/Networking/NCNetworkingSync.m

@@ -228,67 +228,66 @@
     [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
     [communication setUserAgent:[CCUtility getUserAgent]];
     
-    [[NCManageDatabase sharedInstance] getDirectoryE2ETokenLockWithServerUrl:serverUrl completion:^(NSString * _Nullable tokenDatabase) {
+    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) {
+    // Read Folder
+    [communication readFolder:serverUrl depth:@"1" withUserSessionToken:nil onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer, NSString *tokenReadFolder) {
     
-            if (items.count > 1) {
+        if (items.count > 1) {
             
-                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;
-            }
+            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 token:tokenDatabase onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
+        // LOCK
+        [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
         
-                [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:token];
+            [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
             
-                // REMOVE METADATA
-                [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                    NSLog(@"[LOG] Found metadata and delete");
-                } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-                    NSLog(@"[LOG] %@", [NSString stringWithFormat:@"Remove metadata error %d", (int)response.statusCode]);
-                }];
+            // REMOVE METADATA
+            [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
+                NSLog(@"[LOG] Found metadata and delete");
+            } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
+                NSLog(@"[LOG] %@", [NSString stringWithFormat:@"Remove metadata error %d", (int)response.statusCode]);
+            }];
         
-                // MARK
-                [communication markEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-            
-                    // UNLOCK
-                    [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                        [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:@""];
-                        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);
-                    }];
+            // MARK
+            [communication markEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
             
+                // UNLOCK
+                [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token 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);
+                }];
             
-                    returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_mark_folder_"];
+            } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
+            
+                returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_mark_folder_"];
 
-                    // UNLOCK
-                    [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                        [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:@""];
-                        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);
-                    }];
+                // UNLOCK
+                [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token 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_"];
-                dispatch_semaphore_signal(semaphore);
             }];
         
-        } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) {
+        } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
         
-            returnError = [self getError:response error:error descriptionDefault:@"_error_"];
+            returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
             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))
@@ -308,69 +307,68 @@
     [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
     [communication setUserAgent:[CCUtility getUserAgent]];
     
-    [[NCManageDatabase sharedInstance] getDirectoryE2ETokenLockWithServerUrl:serverUrl completion:^(NSString * _Nullable tokenDatabase) {
+    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) {
+    // Read Folder
+    [communication readFolder:serverUrl depth:@"1" withUserSessionToken:nil onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer, NSString *tokenReadFolder) {
         
-            if (items.count > 1) {
+        if (items.count > 1) {
             
-                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;
-            }
+            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 token:tokenDatabase onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
+        // LOCK
+        [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
         
-                [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:token];
+            [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
             
-                // DELETE METADATA
-                [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                    NSLog(@"[LOG] Found metadata and delete");
+            // DELETE METADATA
+            [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
+                NSLog(@"[LOG] Found metadata and delete");
+            } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
+                NSLog(@"[LOG] %@", [NSString stringWithFormat:@"Remove metadata error %d", (int)response.statusCode]);
+            }];
+        
+            // DELETE MARK
+            [communication deletemarkEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
+            
+                // UNLOCK
+                [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token 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);
                 }];
-        
-                // DELETE MARK
-                [communication deletemarkEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
             
-                    // UNLOCK
-                    [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                        [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:@""];
-                        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_delete_mark_folder_"];
+
+                // UNLOCK
+                [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token 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_delete_mark_folder_"];
-
-                    // UNLOCK
-                    [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                        [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:@""];
-                        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);
-                    }];
+                    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_lock_"];
-                dispatch_semaphore_signal(semaphore);
-            }];
-    
-        } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) {
-    
-            returnError = [self getError:response error:error descriptionDefault:@"_error_"];
+            returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
             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]];
     
@@ -418,50 +416,47 @@
     [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
     [communication setUserAgent:[CCUtility getUserAgent]];
     
-    [[NCManageDatabase sharedInstance] getDirectoryE2ETokenLockWithServerUrl:serverUrl completion:^(NSString * _Nullable tokenDatabase) {
-        
-        // LOCK
-        [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tokenDatabase onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
+    tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
+
+    // LOCK
+    [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
             
-            [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:token];
+        [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
             
-            // DELETE METADATA
-            [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                
-                // UNLOCK
-                if (unlock) {
-                    [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                        // Write DB token ""
-                        [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:@""];
-                        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);
-                    }];
-                } else {
-                    dispatch_semaphore_signal(semaphore);
-                }
-                
-            } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
+        // DELETE METADATA
+        [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
                 
-                returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_delete_metadata_"];
-
-                // UNLOCK
+            // UNLOCK
+            if (unlock) {
                 [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                    // Write DB token ""
-                    [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:@""];
+                    [[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);
                 }];
-            }];
-            
+            } else {
+                dispatch_semaphore_signal(semaphore);
+            }
+                
         } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-            
-            returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
-            dispatch_semaphore_signal(semaphore);
+                
+            returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_delete_metadata_"];
+
+            // UNLOCK
+            [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token 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_"];
+        dispatch_semaphore_signal(semaphore);
     }];
     
     while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
@@ -481,50 +476,47 @@
     [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
     [communication setUserAgent:[CCUtility getUserAgent]];
     
-    [[NCManageDatabase sharedInstance] getDirectoryE2ETokenLockWithServerUrl:serverUrl completion:^(NSString * _Nullable tokenDatabase) {
+    tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
 
-        // LOCK
-        [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tokenDatabase onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
+    // LOCK
+    [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
         
-            [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:token];
+        [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
         
-            // STORE METADATA
-            [communication storeEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID encryptedMetadata:metadata onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
+        // STORE METADATA
+        [communication storeEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID encryptedMetadata:metadata onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
             
-                // UNLOCK
-                if (unlock) {
-                    [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                        // Write DB token ""
-                        [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:@""];
-                        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);
-                    }];
-                } else {
-                    dispatch_semaphore_signal(semaphore);
-                }
-                
-            } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-            
-                returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_store_metadata_"];
-
-                // UNLOCK
+            // UNLOCK
+            if (unlock) {
                 [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                    // Write DB token ""
-                    [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:@""];
+                    [[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);
                 }];
+            } else {
+                dispatch_semaphore_signal(semaphore);
+            }
+                
+        } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
+            
+            returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_store_metadata_"];
+
+            // UNLOCK
+            [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token 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_lock_"];
-            dispatch_semaphore_signal(semaphore);
-        }];
+        returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
+        dispatch_semaphore_signal(semaphore);
     }];
 
     while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
@@ -544,50 +536,47 @@
     [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
     [communication setUserAgent:[CCUtility getUserAgent]];
     
-    [[NCManageDatabase sharedInstance] getDirectoryE2ETokenLockWithServerUrl:serverUrl completion:^(NSString * _Nullable tokenDatabase) {
+    tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
 
-        // LOCK
-        [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tokenDatabase onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
+    // LOCK
+    [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
         
-            [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:token];
+        [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
         
-            // UPDATA METADATA
-            [communication updateEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID encryptedMetadata:metadata token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
-            
-                // UNLOCK
-                if (unlock) {
-                    [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                        // Write DB token ""
-                        [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:@""];
-                        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);
-                    }];
-                } else {
-                    dispatch_semaphore_signal(semaphore);
-                }
-                
-            } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
+        // UPDATA METADATA
+        [communication updateEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID encryptedMetadata:metadata token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
             
-                returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_update_metadata_"];
-
-                // UNLOCK
+            // UNLOCK
+            if (unlock) {
                 [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                    // Write DB token ""
-                    [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:@""];
+                    [[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);
                 }];
-            }];
-        
+            } else {
+                dispatch_semaphore_signal(semaphore);
+            }
+                
         } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
         
-            returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
-            dispatch_semaphore_signal(semaphore);
+            returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_update_metadata_"];
+
+            // UNLOCK
+            [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token 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_"];
+        dispatch_semaphore_signal(semaphore);
     }];
 
     while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
@@ -607,20 +596,18 @@
     [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
     [communication setUserAgent:[CCUtility getUserAgent]];
     
-    [[NCManageDatabase sharedInstance] getDirectoryE2ETokenLockWithServerUrl:serverUrl completion:^(NSString * _Nullable tokenDatabase) {
-
-        // LOCK
-        [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tokenDatabase onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
+    tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
+    
+    // LOCK
+    [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
         
-            // Write DB token
-            [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:token];
-            dispatch_semaphore_signal(semaphore);
+        [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
+        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_lock_"];
-            dispatch_semaphore_signal(semaphore);
-        }];
+        returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
+        dispatch_semaphore_signal(semaphore);
     }];
 
     while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
@@ -643,8 +630,7 @@
     // UNLOCK
     [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
         
-        // Write DB token ""
-        [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithServerUrl:serverUrl token:@""];
+        [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
         dispatch_semaphore_signal(semaphore);
         
     } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {