// // NCNetworkingSync.m // Nextcloud // // Created by Marino Faggiana on 29/10/17. // Copyright © 2017 TWS. All rights reserved. // #import "NCNetworkingSync.h" #import "CCUtility.h" #import "CCCertificate.h" #import "NCBridgeSwift.h" @implementation NCNetworkingSync + (NCNetworkingSync *)sharedManager { static NCNetworkingSync *sharedManager; @synchronized(self) { if (!sharedManager) { sharedManager = [NCNetworkingSync new]; } return sharedManager; } } #pragma -------------------------------------------------------------------------------------------- #pragma mark ============================ #pragma -------------------------------------------------------------------------------------------- - (NSError *)uploadFile:(NSString *)localFilePathName remoteFilePathName:(NSString *)remoteFilePathName user:(NSString *)user userID:(NSString *)userID password:(NSString *)password { OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication; __block NSError *returnError = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [communication setCredentialsWithUser:user andUserID:userID andPassword:password]; [communication setUserAgent:[CCUtility getUserAgent]]; [communication uploadFileSession:localFilePathName toDestiny:remoteFilePathName onCommunication:communication progress:^(NSProgress *progress) { // Progress } successRequest:^(NSURLResponse *response, NSString *redirectedServer) { dispatch_semaphore_signal(semaphore); } failureRequest:^(NSURLResponse *response, NSString *redirectedServer, NSError *error) { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:httpResponse.statusCode userInfo:[NSDictionary dictionaryWithObject:@"_error_upload_file_" forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); } failureBeforeRequest:^(NSError *error) { returnError = error; dispatch_semaphore_signal(semaphore); }]; while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]]; return returnError; } - (NSError *)checkServer:(NSString *)serverUrl user:(NSString *)user userID:(NSString *)userID password:(NSString *)password { OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication; __block NSError *returnError = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [communication setCredentialsWithUser:user andUserID:userID andPassword:password]; [communication setUserAgent:[CCUtility getUserAgent]]; [communication checkServer:serverUrl onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) { dispatch_semaphore_signal(semaphore); } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:@"_error_check_server_" forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]]; return returnError; } - (NSError *)readFile:(NSString *)filePathName user:(NSString *)user userID:(NSString *)userID password:(NSString *)password items:(NSArray **)items { OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication; __block NSError *returnError = nil; __block NSArray *returnItems = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [communication setCredentialsWithUser: user andUserID: userID andPassword: password]; [communication setUserAgent:[CCUtility getUserAgent]]; [communication readFile:filePathName onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer) { returnItems = items; dispatch_semaphore_signal(semaphore); } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:response.description forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]]; *items = returnItems; return returnError; } - (NSError *)readFolder:(NSString *)serverUrl user:(NSString *)user userID:(NSString *)userID password:(NSString *)password items:(NSArray **)items { OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication; __block NSError *returnError = nil; __block NSArray *returnItems = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [communication setCredentialsWithUser:user andUserID:userID andPassword:password]; [communication setUserAgent:[CCUtility getUserAgent]]; [communication readFolder:serverUrl depth:0 withUserSessionToken:nil onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer, NSString *token) { returnItems = items; dispatch_semaphore_signal(semaphore); } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:response.description forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]]; *items = returnItems; return returnError; } - (NSError *)createFolderAutomaticUpload:(NSString *)folderPathName user:(NSString *)user userID:(NSString *)userID password:(NSString *)password { OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication; __block NSError *returnError = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [communication setCredentialsWithUser:user andUserID:userID andPassword:password]; [communication setUserAgent:[CCUtility getUserAgent]]; [communication readFile:folderPathName onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer) { dispatch_semaphore_signal(semaphore); } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { [communication createFolder:folderPathName onCommunication:communication withForbiddenCharactersSupported:YES successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) { [[NCManageDatabase sharedInstance] clearDateReadWithServerUrl:[CCUtility deletingLastPathComponentFromServerUrl:folderPathName] directoryID:nil]; dispatch_semaphore_signal(semaphore); } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:response.description forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); } errorBeforeRequest:^(NSError *error) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:response.description forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; }]; while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]]; return returnError; } #pragma -------------------------------------------------------------------------------------------- #pragma mark ===== E2EE End-to-End Encryption ===== #pragma -------------------------------------------------------------------------------------------- // E2EE - (NSError *)markEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID serverUrl:(NSString *)serverUrl token:(NSString **)token { OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication; __block NSError *returnError = nil; __block NSString *returnToken = *token; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [communication setCredentialsWithUser:user andUserID:userID andPassword:password]; [communication setUserAgent:[CCUtility getUserAgent]]; // Read Folder [communication readFolder:serverUrl depth:@"1" withUserSessionToken:nil onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer, NSString *tokenReadFolder) { 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; } // LOCK [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:returnToken onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) { returnToken = token; [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithFileID:fileID token:returnToken]; // REMOVE METADATA [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) { NSLog(@"Found metadata and delete"); } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { NSLog(@"%@", [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:returnToken onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) { returnToken = nil; [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithFileID:fileID token:@""]; dispatch_semaphore_signal(semaphore); } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_unlock_", nil) forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_mark_folder_", nil) forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_lock_", nil) forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:response.description forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]]; *token = returnToken; return returnError; } - (NSError *)deletemarkEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID serverUrl:(NSString *)serverUrl token:(NSString **)token { OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication; __block NSError *returnError = nil; __block NSString *returnToken = *token; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [communication setCredentialsWithUser:user andUserID:userID andPassword:password]; [communication setUserAgent:[CCUtility getUserAgent]]; // Read Folder [communication readFolder:serverUrl depth:@"1" withUserSessionToken:nil onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer, NSString *tokenReadFolder) { 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; } // LOCK [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:returnToken onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) { returnToken = token; [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithFileID:fileID token:returnToken]; // DELETE METADATA [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) { NSLog(@"Found metadata and delete"); } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { NSLog(@"%@", [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:returnToken onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) { returnToken = nil; [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithFileID:fileID token:@""]; dispatch_semaphore_signal(semaphore); } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_unlock_", nil) forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_delete_mark_folder_", nil) forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_lock_", nil) forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:@"Read folder error" forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]]; *token = returnToken; return returnError; } - (NSError *)getEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID metadata:(NSString **)metadata { OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication; __block NSError *returnError = nil; __block NSString *returnMetadata = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [communication setCredentialsWithUser:user andUserID:userID andPassword:password]; [communication setUserAgent:[CCUtility getUserAgent]]; [communication getEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) { returnMetadata = encryptedMetadata; dispatch_semaphore_signal(semaphore); } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_get_metadata_", nil) forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]]; *metadata = returnMetadata; return returnError; } - (NSError *)deleteEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID { OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication; __block NSError *returnError = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [communication setCredentialsWithUser:user andUserID:userID andPassword:password]; [communication setUserAgent:[CCUtility getUserAgent]]; [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) { dispatch_semaphore_signal(semaphore); } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_delete_metadata_", nil) forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]]; return returnError; } - (NSError *)storeEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID metadata:(NSString *)metadata token:(NSString **)token { OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication; __block NSError *returnError = nil; __block NSString *returnToken = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [communication setCredentialsWithUser:user andUserID:userID andPassword:password]; [communication setUserAgent:[CCUtility getUserAgent]]; // LOCK [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:*token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) { returnToken = token; [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithFileID:fileID token:returnToken]; // STORE METADATA [communication storeEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID encryptedMetadata:metadata onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) { dispatch_semaphore_signal(semaphore); } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_store_metadata_", nil) forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_lock_", nil) forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]]; *token = returnToken; return returnError; } - (NSError *)updateEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID metadata:(NSString *)metadata token:(NSString **)token { OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication; __block NSError *returnError = nil; __block NSString *returnToken = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [communication setCredentialsWithUser:user andUserID:userID andPassword:password]; [communication setUserAgent:[CCUtility getUserAgent]]; // LOCK [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:*token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) { returnToken = token; [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithFileID:fileID token:returnToken]; // UPDATA METADATA [communication updateEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID encryptedMetadata:metadata token:returnToken onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) { dispatch_semaphore_signal(semaphore); } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_update_metadata_", nil) forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_lock_", nil) forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]]; *token = returnToken; return returnError; } - (NSError *)lockEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID token:(NSString **)token { OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication; __block NSError *returnError = nil; __block NSString *returnToken = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [communication setCredentialsWithUser:user andUserID:userID andPassword:password]; [communication setUserAgent:[CCUtility getUserAgent]]; // LOCK [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:*token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) { // Write DB token returnToken = token; [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithFileID:fileID token:returnToken]; dispatch_semaphore_signal(semaphore); } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_lock_", nil) forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]]; *token = returnToken; return returnError; } - (NSError *)unlockEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID token:(NSString *)token { OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication; __block NSError *returnError = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [communication setCredentialsWithUser:user andUserID:userID andPassword:password]; [communication setUserAgent:[CCUtility getUserAgent]]; // UNLOCK [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) { // Write DB token "" [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithFileID:fileID token:@""]; dispatch_semaphore_signal(semaphore); } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) { returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_unlock_", nil) forKey:NSLocalizedDescriptionKey]]; dispatch_semaphore_signal(semaphore); }]; while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]]; return returnError; } - (NSError *)sendEndToEndMetadataOnServerUrl:(NSString *)serverUrl account:(NSString *)account user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileNameRename:(NSString *)fileName fileNameNewRename:(NSString *)fileNameNew token:(NSString **)token { tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]]; *token = directory.e2eTokenLock; NSString *e2eTokenLock = *token; NSString *metadata; NSError *error; // Enabled E2E if ([CCUtility isEndToEndEnabled:account] == NO) return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_not_enabled_", nil) forKey:NSLocalizedDescriptionKey]]; // get Metadata for select updateEndToEndMetadata or storeEndToEndMetadata error = [[NCNetworkingSync sharedManager] getEndToEndMetadata:user userID:userID password:password url:url fileID:directory.fileID metadata:&metadata]; if (error.code != 404 && error != nil) { return error; } // Rename if (fileName && fileNameNew) [[NCManageDatabase sharedInstance] renameFileE2eEncryptionWithServerUrl:serverUrl fileNameIdentifier:fileName newFileName:fileNameNew newFileNamePath:[CCUtility returnFileNamePathFromFileName:fileNameNew serverUrl:serverUrl activeUrl:url]]; NSArray *tableE2eEncryption = [[NCManageDatabase sharedInstance] getE2eEncryptionsWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]]; if (!tableE2eEncryption) return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_record_not_found_", nil) forKey:NSLocalizedDescriptionKey]]; NSString *e2eMetadataJSON = [[NCEndToEndMetadata sharedInstance] encoderMetadata:tableE2eEncryption privateKey:[CCUtility getEndToEndPrivateKey:account] serverUrl:serverUrl]; if (!e2eMetadataJSON) return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_encode_metadata_", nil) forKey:NSLocalizedDescriptionKey]]; // send Metadata if (error == nil) error = [[NCNetworkingSync sharedManager] updateEndToEndMetadata:user userID:userID password:password url:url fileID:directory.fileID metadata:e2eMetadataJSON token:&e2eTokenLock]; else if (error.code == 404) error = [[NCNetworkingSync sharedManager] storeEndToEndMetadata:user userID:userID password:password url:url fileID:directory.fileID metadata:e2eMetadataJSON token:&e2eTokenLock]; *token = e2eTokenLock; return error; } - (NSError *)rebuildAndSendEndToEndMetadataOnServerUrl:(NSString *)serverUrl account:(NSString *)account user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url token:(NSString **)token { NSString *e2eTokenLock = *token; NSError *error; NSString *e2eMetadataJSON; tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]]; if (directory.e2eEncrypted == NO) return nil; NSArray *tableE2eEncryption = [[NCManageDatabase sharedInstance] getE2eEncryptionsWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]]; if (tableE2eEncryption) { e2eMetadataJSON = [[NCEndToEndMetadata sharedInstance] encoderMetadata:tableE2eEncryption privateKey:[CCUtility getEndToEndPrivateKey:account] serverUrl:serverUrl]; if (!e2eMetadataJSON) return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_encode_metadata_", nil) forKey:NSLocalizedDescriptionKey]]; error = [[NCNetworkingSync sharedManager] updateEndToEndMetadata:user userID:userID password:password url:url fileID:directory.fileID metadata:e2eMetadataJSON token:&e2eTokenLock]; } else { error = [[NCNetworkingSync sharedManager] deleteEndToEndMetadata:user userID:userID password:password url:url fileID:directory.fileID]; } *token = e2eTokenLock; return error; } @end