NCNetworkingSync.m 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. //
  2. // NCNetworkingSync.m
  3. // Nextcloud
  4. //
  5. // Created by Marino Faggiana on 29/10/17.
  6. // Copyright © 2017 TWS. All rights reserved.
  7. //
  8. #import "NCNetworkingSync.h"
  9. #import "CCUtility.h"
  10. #import "CCCertificate.h"
  11. #import "NCBridgeSwift.h"
  12. /*********************************************************************************
  13. Netwok call synchronous mode, use this only from :
  14. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  15. });
  16. *********************************************************************************/
  17. @implementation NCNetworkingSync
  18. + (NCNetworkingSync *)sharedManager {
  19. static NCNetworkingSync *sharedManager;
  20. @synchronized(self)
  21. {
  22. if (!sharedManager) {
  23. sharedManager = [NCNetworkingSync new];
  24. }
  25. return sharedManager;
  26. }
  27. }
  28. #pragma --------------------------------------------------------------------------------------------
  29. #pragma mark ============================
  30. #pragma --------------------------------------------------------------------------------------------
  31. - (NSError *)readFile:(NSString *)filePathName user:(NSString *)user userID:(NSString *)userID password:(NSString *)password items:(NSArray **)items
  32. {
  33. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  34. __block NSError *returnError = nil;
  35. __block NSArray *returnItems = nil;
  36. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  37. [communication setCredentialsWithUser: user andUserID: userID andPassword: password];
  38. [communication setUserAgent:[CCUtility getUserAgent]];
  39. [communication readFile:filePathName onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer) {
  40. returnItems = items;
  41. dispatch_semaphore_signal(semaphore);
  42. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  43. returnError = [self getError:response error:error descriptionDefault:@"_error_"];
  44. dispatch_semaphore_signal(semaphore);
  45. }];
  46. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  47. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  48. *items = returnItems;
  49. return returnError;
  50. }
  51. - (NSError *)readFolder:(NSString *)serverUrl user:(NSString *)user userID:(NSString *)userID password:(NSString *)password items:(NSArray **)items
  52. {
  53. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  54. __block NSError *returnError = nil;
  55. __block NSArray *returnItems = nil;
  56. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  57. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  58. [communication setUserAgent:[CCUtility getUserAgent]];
  59. [communication readFolder:serverUrl depth:0 withUserSessionToken:nil onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer, NSString *token) {
  60. returnItems = items;
  61. dispatch_semaphore_signal(semaphore);
  62. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) {
  63. returnError = [self getError:response error:error descriptionDefault:@"_error_"];
  64. dispatch_semaphore_signal(semaphore);
  65. }];
  66. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  67. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  68. *items = returnItems;
  69. return returnError;
  70. }
  71. - (NSError *)createFolder:(NSString *)folderPathName user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url encrypted:(BOOL)encrypted fileID:(NSString **)fileID
  72. {
  73. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  74. __block NSError *returnError = nil;
  75. __block NSString *returnFileID = nil;
  76. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  77. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  78. [communication setUserAgent:[CCUtility getUserAgent]];
  79. [communication readFile:folderPathName onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer) {
  80. dispatch_semaphore_signal(semaphore);
  81. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  82. [communication createFolder:folderPathName onCommunication:communication withForbiddenCharactersSupported:YES successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  83. NSDictionary *fields = [response allHeaderFields];
  84. returnFileID = [CCUtility removeForbiddenCharactersFileSystem:[fields objectForKey:@"OC-FileId"]];
  85. if (encrypted) {
  86. // MARK
  87. [communication markEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:returnFileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  88. [[NCManageDatabase sharedInstance] clearDateReadWithServerUrl:[CCUtility deletingLastPathComponentFromServerUrl:folderPathName] directoryID:nil];
  89. dispatch_semaphore_signal(semaphore);
  90. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  91. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_mark_folder_"];
  92. dispatch_semaphore_signal(semaphore);
  93. }];
  94. } else {
  95. [[NCManageDatabase sharedInstance] clearDateReadWithServerUrl:[CCUtility deletingLastPathComponentFromServerUrl:folderPathName] directoryID:nil];
  96. dispatch_semaphore_signal(semaphore);
  97. }
  98. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  99. returnError = [self getError:response error:error descriptionDefault:@"_error_"];
  100. dispatch_semaphore_signal(semaphore);
  101. } errorBeforeRequest:^(NSError *error) {
  102. returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:response.description forKey:NSLocalizedDescriptionKey]];
  103. dispatch_semaphore_signal(semaphore);
  104. }];
  105. }];
  106. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  107. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  108. *fileID = returnFileID;
  109. return returnError;
  110. }
  111. #pragma --------------------------------------------------------------------------------------------
  112. #pragma mark ===== E2EE End-to-End Encryption =====
  113. #pragma --------------------------------------------------------------------------------------------
  114. // E2EE
  115. - (NSError *)markEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID serverUrl:(NSString *)serverUrl
  116. {
  117. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  118. __block NSError *returnError = nil;
  119. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  120. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  121. [communication setUserAgent:[CCUtility getUserAgent]];
  122. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  123. // Read Folder
  124. [communication readFolder:serverUrl depth:@"1" withUserSessionToken:nil onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer, NSString *tokenReadFolder) {
  125. if (items.count > 1) {
  126. returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:999 userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_directory_not_empty_", nil) forKey:NSLocalizedDescriptionKey]];
  127. dispatch_semaphore_signal(semaphore);
  128. return;
  129. }
  130. // LOCK
  131. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  132. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
  133. // REMOVE METADATA
  134. [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  135. NSLog(@"[LOG] Found metadata and delete");
  136. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  137. NSLog(@"[LOG] %@", [NSString stringWithFormat:@"Remove metadata error %d", (int)response.statusCode]);
  138. }];
  139. // MARK
  140. [communication markEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  141. // UNLOCK
  142. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  143. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  144. dispatch_semaphore_signal(semaphore);
  145. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  146. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  147. dispatch_semaphore_signal(semaphore);
  148. }];
  149. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  150. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_mark_folder_"];
  151. // UNLOCK
  152. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  153. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  154. dispatch_semaphore_signal(semaphore);
  155. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  156. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  157. dispatch_semaphore_signal(semaphore);
  158. }];
  159. }];
  160. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  161. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  162. dispatch_semaphore_signal(semaphore);
  163. }];
  164. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) {
  165. returnError = [self getError:response error:error descriptionDefault:@"_error_"];
  166. dispatch_semaphore_signal(semaphore);
  167. }];
  168. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  169. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  170. return returnError;
  171. }
  172. - (NSError *)deletemarkEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID serverUrl:(NSString *)serverUrl
  173. {
  174. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  175. __block NSError *returnError = nil;
  176. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  177. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  178. [communication setUserAgent:[CCUtility getUserAgent]];
  179. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  180. // Read Folder
  181. [communication readFolder:serverUrl depth:@"1" withUserSessionToken:nil onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer, NSString *tokenReadFolder) {
  182. if (items.count > 1) {
  183. returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:999 userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_directory_not_empty_", nil) forKey:NSLocalizedDescriptionKey]];
  184. dispatch_semaphore_signal(semaphore);
  185. return;
  186. }
  187. // LOCK
  188. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  189. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
  190. // DELETE METADATA
  191. [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  192. NSLog(@"[LOG] Found metadata and delete");
  193. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  194. NSLog(@"[LOG] %@", [NSString stringWithFormat:@"Remove metadata error %d", (int)response.statusCode]);
  195. }];
  196. // DELETE MARK
  197. [communication deletemarkEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  198. // UNLOCK
  199. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  200. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  201. dispatch_semaphore_signal(semaphore);
  202. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  203. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  204. dispatch_semaphore_signal(semaphore);
  205. }];
  206. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  207. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_delete_mark_folder_"];
  208. // UNLOCK
  209. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  210. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  211. dispatch_semaphore_signal(semaphore);
  212. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  213. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  214. dispatch_semaphore_signal(semaphore);
  215. }];
  216. }];
  217. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  218. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  219. dispatch_semaphore_signal(semaphore);
  220. }];
  221. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) {
  222. returnError = [self getError:response error:error descriptionDefault:@"_error_"];
  223. dispatch_semaphore_signal(semaphore);
  224. }];
  225. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  226. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  227. return returnError;
  228. }
  229. - (NSError *)getEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID metadata:(NSString **)metadata
  230. {
  231. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  232. __block NSError *returnError = nil;
  233. __block NSString *returnMetadata = nil;
  234. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  235. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  236. [communication setUserAgent:[CCUtility getUserAgent]];
  237. [communication getEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
  238. returnMetadata = encryptedMetadata;
  239. dispatch_semaphore_signal(semaphore);
  240. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  241. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_get_metadata_"];
  242. dispatch_semaphore_signal(semaphore);
  243. }];
  244. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  245. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  246. *metadata = returnMetadata;
  247. return returnError;
  248. }
  249. - (NSError *)deleteEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url serverUrl:(NSString *)serverUrl fileID:(NSString *)fileID unlock:(BOOL)unlock
  250. {
  251. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  252. __block NSError *returnError = nil;
  253. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  254. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  255. [communication setUserAgent:[CCUtility getUserAgent]];
  256. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  257. // LOCK
  258. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  259. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
  260. // DELETE METADATA
  261. [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  262. // UNLOCK
  263. if (unlock) {
  264. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  265. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  266. dispatch_semaphore_signal(semaphore);
  267. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  268. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  269. dispatch_semaphore_signal(semaphore);
  270. }];
  271. } else {
  272. dispatch_semaphore_signal(semaphore);
  273. }
  274. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  275. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_delete_metadata_"];
  276. // UNLOCK
  277. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  278. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  279. dispatch_semaphore_signal(semaphore);
  280. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  281. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  282. dispatch_semaphore_signal(semaphore);
  283. }];
  284. }];
  285. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  286. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  287. dispatch_semaphore_signal(semaphore);
  288. }];
  289. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  290. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  291. return returnError;
  292. }
  293. - (NSError *)storeEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url serverUrl:(NSString *)serverUrl fileID:(NSString *)fileID metadata:(NSString *)metadata unlock:(BOOL)unlock
  294. {
  295. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  296. __block NSError *returnError = nil;
  297. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  298. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  299. [communication setUserAgent:[CCUtility getUserAgent]];
  300. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  301. // LOCK
  302. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  303. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
  304. // STORE METADATA
  305. [communication storeEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID encryptedMetadata:metadata onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
  306. // UNLOCK
  307. if (unlock) {
  308. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  309. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  310. dispatch_semaphore_signal(semaphore);
  311. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  312. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  313. dispatch_semaphore_signal(semaphore);
  314. }];
  315. } else {
  316. dispatch_semaphore_signal(semaphore);
  317. }
  318. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  319. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_store_metadata_"];
  320. // UNLOCK
  321. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  322. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  323. dispatch_semaphore_signal(semaphore);
  324. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  325. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  326. dispatch_semaphore_signal(semaphore);
  327. }];
  328. }];
  329. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  330. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  331. dispatch_semaphore_signal(semaphore);
  332. }];
  333. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  334. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  335. return returnError;
  336. }
  337. - (NSError *)updateEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url serverUrl:(NSString *)serverUrl fileID:(NSString *)fileID metadata:(NSString *)metadata unlock:(BOOL)unlock
  338. {
  339. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  340. __block NSError *returnError = nil;
  341. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  342. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  343. [communication setUserAgent:[CCUtility getUserAgent]];
  344. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  345. // LOCK
  346. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  347. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
  348. // UPDATA METADATA
  349. [communication updateEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID encryptedMetadata:metadata token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
  350. // UNLOCK
  351. if (unlock) {
  352. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  353. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  354. dispatch_semaphore_signal(semaphore);
  355. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  356. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  357. dispatch_semaphore_signal(semaphore);
  358. }];
  359. } else {
  360. dispatch_semaphore_signal(semaphore);
  361. }
  362. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  363. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_update_metadata_"];
  364. // UNLOCK
  365. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  366. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  367. dispatch_semaphore_signal(semaphore);
  368. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  369. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  370. dispatch_semaphore_signal(semaphore);
  371. }];
  372. }];
  373. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  374. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  375. dispatch_semaphore_signal(semaphore);
  376. }];
  377. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  378. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  379. return returnError;
  380. }
  381. - (NSError *)lockEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url serverUrl:(NSString *)serverUrl fileID:(NSString *)fileID
  382. {
  383. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  384. __block NSError *returnError = nil;
  385. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  386. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  387. [communication setUserAgent:[CCUtility getUserAgent]];
  388. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  389. // LOCK
  390. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  391. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
  392. dispatch_semaphore_signal(semaphore);
  393. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  394. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  395. dispatch_semaphore_signal(semaphore);
  396. }];
  397. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  398. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  399. return returnError;
  400. }
  401. - (NSError *)unlockEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url serverUrl:(NSString *)serverUrl fileID:(NSString *)fileID token:(NSString *)token
  402. {
  403. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  404. __block NSError *returnError = nil;
  405. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  406. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  407. [communication setUserAgent:[CCUtility getUserAgent]];
  408. // UNLOCK
  409. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  410. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  411. dispatch_semaphore_signal(semaphore);
  412. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  413. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  414. dispatch_semaphore_signal(semaphore);
  415. }];
  416. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  417. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  418. return returnError;
  419. }
  420. - (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
  421. {
  422. tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]];
  423. NSString *metadata;
  424. NSError *error;
  425. // Enabled E2E
  426. if ([CCUtility isEndToEndEnabled:account] == NO)
  427. return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_not_enabled_", nil) forKey:NSLocalizedDescriptionKey]];
  428. // get Metadata for select updateEndToEndMetadata or storeEndToEndMetadata
  429. error = [[NCNetworkingSync sharedManager] getEndToEndMetadata:user userID:userID password:password url:url fileID:directory.fileID metadata:&metadata];
  430. if (error.code != 404 && error != nil) {
  431. return error;
  432. }
  433. // Rename
  434. if (fileName && fileNameNew)
  435. [[NCManageDatabase sharedInstance] renameFileE2eEncryptionWithServerUrl:serverUrl fileNameIdentifier:fileName newFileName:fileNameNew newFileNamePath:[CCUtility returnFileNamePathFromFileName:fileNameNew serverUrl:serverUrl activeUrl:url]];
  436. NSArray *tableE2eEncryption = [[NCManageDatabase sharedInstance] getE2eEncryptionsWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]];
  437. if (!tableE2eEncryption)
  438. return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_record_not_found_", nil) forKey:NSLocalizedDescriptionKey]];
  439. NSString *e2eMetadataJSON = [[NCEndToEndMetadata sharedInstance] encoderMetadata:tableE2eEncryption privateKey:[CCUtility getEndToEndPrivateKey:account] serverUrl:serverUrl];
  440. if (!e2eMetadataJSON)
  441. return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_encode_metadata_", nil) forKey:NSLocalizedDescriptionKey]];
  442. // send Metadata
  443. if (error == nil)
  444. error = [[NCNetworkingSync sharedManager] updateEndToEndMetadata:user userID:userID password:password url:url serverUrl:serverUrl fileID:directory.fileID metadata:e2eMetadataJSON unlock:NO];
  445. else if (error.code == 404)
  446. error = [[NCNetworkingSync sharedManager] storeEndToEndMetadata:user userID:userID password:password url:url serverUrl:serverUrl fileID:directory.fileID metadata:e2eMetadataJSON unlock:NO];
  447. return error;
  448. }
  449. - (NSError *)rebuildAndSendEndToEndMetadataOnServerUrl:(NSString *)serverUrl account:(NSString *)account user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url
  450. {
  451. NSError *error;
  452. NSString *e2eMetadataJSON;
  453. tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]];
  454. if (directory.e2eEncrypted == NO)
  455. return nil;
  456. NSArray *tableE2eEncryption = [[NCManageDatabase sharedInstance] getE2eEncryptionsWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]];
  457. if (tableE2eEncryption) {
  458. e2eMetadataJSON = [[NCEndToEndMetadata sharedInstance] encoderMetadata:tableE2eEncryption privateKey:[CCUtility getEndToEndPrivateKey:account] serverUrl:serverUrl];
  459. if (!e2eMetadataJSON)
  460. return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_encode_metadata_", nil) forKey:NSLocalizedDescriptionKey]];
  461. error = [[NCNetworkingSync sharedManager] updateEndToEndMetadata:user userID:userID password:password url:url serverUrl:serverUrl fileID:directory.fileID metadata:e2eMetadataJSON unlock:YES];
  462. } else {
  463. [[NCNetworkingSync sharedManager] deleteEndToEndMetadata:user userID:userID password:password url:url serverUrl:serverUrl fileID:directory.fileID unlock:YES];
  464. }
  465. return error;
  466. }
  467. - (NSError *)getError:(NSHTTPURLResponse *)response error:(NSError *)error descriptionDefault:(NSString *)descriptionDefault
  468. {
  469. NSInteger errorCode = response.statusCode;
  470. NSString *errorDescription = response.description;
  471. if (errorDescription == nil || errorCode == 0) {
  472. errorCode = error.code;
  473. errorDescription = error.description;
  474. if (errorDescription == nil) errorDescription = NSLocalizedString(descriptionDefault, @"");
  475. }
  476. errorDescription = [NSString stringWithFormat:@"%@ [%ld] - %@", NSLocalizedString(descriptionDefault, @""), (long)errorCode, errorDescription];
  477. if (errorDescription.length >= 250) {
  478. errorDescription = [errorDescription substringToIndex:250];
  479. errorDescription = [errorDescription stringByAppendingString:@" ..."];
  480. }
  481. return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:errorCode userInfo:[NSDictionary dictionaryWithObject:errorDescription forKey:NSLocalizedDescriptionKey]];
  482. }
  483. @end