NCNetworkingEndToEnd.m 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876
  1. //
  2. // NCNetworkingEndToEnd.m
  3. // Nextcloud
  4. //
  5. // Created by Marino Faggiana on 29/10/17.
  6. // Copyright (c) 2017 Marino Faggiana. All rights reserved.
  7. //
  8. // Author Marino Faggiana <marino.faggiana@nextcloud.com>
  9. //
  10. // This program is free software: you can redistribute it and/or modify
  11. // it under the terms of the GNU General Public License as published by
  12. // the Free Software Foundation, either version 3 of the License, or
  13. // (at your option) any later version.
  14. //
  15. // This program is distributed in the hope that it will be useful,
  16. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. // GNU General Public License for more details.
  19. //
  20. // You should have received a copy of the GNU General Public License
  21. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. //
  23. #import "NCNetworkingEndToEnd.h"
  24. #import "OCNetworking.h"
  25. #import "CCUtility.h"
  26. #import "CCCertificate.h"
  27. #import "NCBridgeSwift.h"
  28. /*********************************************************************************
  29. Netwok call synchronous mode, use this only from :
  30. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  31. });
  32. *********************************************************************************/
  33. @implementation NCNetworkingEndToEnd
  34. + (NCNetworkingEndToEnd *)sharedManager {
  35. static NCNetworkingEndToEnd *sharedManager;
  36. @synchronized(self)
  37. {
  38. if (!sharedManager) {
  39. sharedManager = [NCNetworkingEndToEnd new];
  40. }
  41. return sharedManager;
  42. }
  43. }
  44. #pragma --------------------------------------------------------------------------------------------
  45. #pragma mark ===== End-to-End Encryption NETWORKING =====
  46. #pragma --------------------------------------------------------------------------------------------
  47. - (void)getEndToEndPublicKeyWithAccount:(NSString *)account completion:(void (^)(NSString *account, NSString *publicKey, NSString *message, NSInteger errorCode))completion
  48. {
  49. tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountWithPredicate:[NSPredicate predicateWithFormat:@"account == %@", account]];
  50. if (tableAccount == nil) {
  51. completion(account, nil, NSLocalizedString(@"_error_user_not_available_", nil), k_CCErrorUserNotAvailble);
  52. }
  53. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  54. [communication setCredentialsWithUser:tableAccount.user andUserID:tableAccount.userID andPassword:[CCUtility getPassword:account]];
  55. [communication setUserAgent:[CCUtility getUserAgent]];
  56. [communication getEndToEndPublicKeys:[tableAccount.url stringByAppendingString:@"/"] onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *publicKey, NSString *redirectedServer) {
  57. completion(account, publicKey, nil, 0);
  58. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  59. NSString *message = @"";
  60. NSInteger errorCode = response.statusCode;
  61. if (errorCode == 0 || (errorCode >= 200 && errorCode < 300))
  62. errorCode = error.code;
  63. // Error
  64. if (errorCode == 503) {
  65. message = NSLocalizedString(@"_server_error_retry_", nil);
  66. } else {
  67. message = [error.userInfo valueForKey:@"NSLocalizedDescription"];
  68. }
  69. completion(account, nil, message, errorCode);
  70. }];
  71. }
  72. - (void)getEndToEndPrivateKeyCipherWithAccount:(NSString *)account completion:(void (^)(NSString *account, NSString *privateKeyChiper, NSString *message, NSInteger errorCode))completion
  73. {
  74. tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountWithPredicate:[NSPredicate predicateWithFormat:@"account == %@", account]];
  75. if (tableAccount == nil) {
  76. completion(account, nil, NSLocalizedString(@"_error_user_not_available_", nil), k_CCErrorUserNotAvailble);
  77. }
  78. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  79. [communication setCredentialsWithUser:tableAccount.user andUserID:tableAccount.userID andPassword:[CCUtility getPassword:account]];
  80. [communication setUserAgent:[CCUtility getUserAgent]];
  81. [communication getEndToEndPrivateKeyCipher:[tableAccount.url stringByAppendingString:@"/"] onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *privateKeyChiper, NSString *redirectedServer) {
  82. completion(account, privateKeyChiper, nil, 0);
  83. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  84. NSString *message = @"";
  85. NSInteger errorCode = response.statusCode;
  86. if (errorCode == 0 || (errorCode >= 200 && errorCode < 300))
  87. errorCode = error.code;
  88. // Error
  89. if (errorCode == 503) {
  90. message = NSLocalizedString(@"_server_error_retry_", nil);
  91. } else {
  92. message = [error.userInfo valueForKey:@"NSLocalizedDescription"];
  93. }
  94. completion(account, nil, message, errorCode);
  95. }];
  96. }
  97. - (void)signEndToEndPublicKeyWithAccount:(NSString *)account publicKey:(NSString *)publicKey completion:(void (^)(NSString *account, NSString *publicKey, NSString *message, NSInteger errorCode))completion
  98. {
  99. tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountWithPredicate:[NSPredicate predicateWithFormat:@"account == %@", account]];
  100. if (tableAccount == nil) {
  101. completion(account, nil, NSLocalizedString(@"_error_user_not_available_", nil), k_CCErrorUserNotAvailble);
  102. }
  103. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  104. [communication setCredentialsWithUser:tableAccount.user andUserID:tableAccount.userID andPassword:[CCUtility getPassword:account]];
  105. [communication setUserAgent:[CCUtility getUserAgent]];
  106. [communication signEndToEndPublicKey:[tableAccount.url stringByAppendingString:@"/"] publicKey:[CCUtility URLEncodeStringFromString:publicKey] onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *publicKey, NSString *redirectedServer) {
  107. completion(account, publicKey, nil, 0);
  108. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  109. NSString *message = @"";
  110. NSInteger errorCode = response.statusCode;
  111. if (errorCode == 0 || (errorCode >= 200 && errorCode < 300))
  112. errorCode = error.code;
  113. // Error
  114. if (errorCode == 503) {
  115. message = NSLocalizedString(@"_server_error_retry_", nil);
  116. } else {
  117. message = [error.userInfo valueForKey:@"NSLocalizedDescription"];
  118. }
  119. completion(account, nil, message, errorCode);
  120. }];
  121. }
  122. - (void)storeEndToEndPrivateKeyCipherWithAccount:(NSString *)account privateKeyString:(NSString *)privateKeyString privateKeyChiper:(NSString *)privateKeyChiper completion:(void (^)(NSString *account, NSString *privateKeyString, NSString *privateKey, NSString *message, NSInteger errorCode))completion
  123. {
  124. tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountWithPredicate:[NSPredicate predicateWithFormat:@"account == %@", account]];
  125. if (tableAccount == nil) {
  126. completion(account, nil, nil, NSLocalizedString(@"_error_user_not_available_", nil), k_CCErrorUserNotAvailble);
  127. }
  128. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  129. [communication setCredentialsWithUser:tableAccount.user andUserID:tableAccount.userID andPassword:[CCUtility getPassword:account]];
  130. [communication setUserAgent:[CCUtility getUserAgent]];
  131. [communication storeEndToEndPrivateKeyCipher:[tableAccount.url stringByAppendingString:@"/"] privateKeyChiper:[CCUtility URLEncodeStringFromString:privateKeyChiper] onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *privateKey, NSString *redirectedServer) {
  132. completion(account, privateKeyString, privateKeyChiper, nil, 0);
  133. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  134. NSString *message = @"";
  135. NSInteger errorCode = response.statusCode;
  136. if (errorCode == 0 || (errorCode >= 200 && errorCode < 300))
  137. errorCode = error.code;
  138. // Error
  139. if (errorCode == 503) {
  140. message = NSLocalizedString(@"_server_error_retry_", nil);
  141. } else {
  142. message = [error.userInfo valueForKey:@"NSLocalizedDescription"];
  143. }
  144. completion(account, nil, nil, message, errorCode);
  145. }];
  146. }
  147. - (void)deleteEndToEndPublicKeyWithAccount:(NSString *)account completion:(void (^)(NSString *account, NSString *message, NSInteger errorCode))completion
  148. {
  149. tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountWithPredicate:[NSPredicate predicateWithFormat:@"account == %@", account]];
  150. if (tableAccount == nil) {
  151. completion(account, NSLocalizedString(@"_error_user_not_available_", nil), k_CCErrorUserNotAvailble);
  152. }
  153. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  154. [communication setCredentialsWithUser:tableAccount.user andUserID:tableAccount.userID andPassword:[CCUtility getPassword:account]];
  155. [communication setUserAgent:[CCUtility getUserAgent]];
  156. [communication deleteEndToEndPublicKey:[tableAccount.url stringByAppendingString:@"/"] onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  157. completion(account, nil ,0);
  158. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  159. NSString *message = @"";
  160. NSInteger errorCode = response.statusCode;
  161. if (errorCode == 0 || (errorCode >= 200 && errorCode < 300))
  162. errorCode = error.code;
  163. // Error
  164. if (errorCode == 503) {
  165. message = NSLocalizedString(@"_server_error_retry_", nil);
  166. } else {
  167. message = [error.userInfo valueForKey:@"NSLocalizedDescription"];
  168. }
  169. completion(account, message, errorCode);
  170. }];
  171. }
  172. - (void)deleteEndToEndPrivateKeyWithAccount:(NSString *)account completion:(void (^)(NSString *account, NSString *message, NSInteger errorCode))completion
  173. {
  174. tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountWithPredicate:[NSPredicate predicateWithFormat:@"account == %@", account]];
  175. if (tableAccount == nil) {
  176. completion(account, NSLocalizedString(@"_error_user_not_available_", nil), k_CCErrorUserNotAvailble);
  177. }
  178. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  179. [communication setCredentialsWithUser:tableAccount.user andUserID:tableAccount.userID andPassword:[CCUtility getPassword:account]];
  180. [communication setUserAgent:[CCUtility getUserAgent]];
  181. [communication deleteEndToEndPrivateKey:[tableAccount.url stringByAppendingString:@"/"] onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  182. completion(account, nil, 0);
  183. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  184. NSString *message = @"";
  185. NSInteger errorCode = response.statusCode;
  186. if (errorCode == 0 || (errorCode >= 200 && errorCode < 300))
  187. errorCode = error.code;
  188. // Error
  189. if (errorCode == 503) {
  190. message = NSLocalizedString(@"_server_error_retry_", nil);
  191. } else {
  192. message = [error.userInfo valueForKey:@"NSLocalizedDescription"];
  193. }
  194. completion(account, message, errorCode);
  195. }];
  196. }
  197. - (void)getEndToEndServerPublicKeyWithAccount:(NSString *)account completion:(void (^)(NSString *account, NSString *publicKey, NSString *message, NSInteger errorCode))completion
  198. {
  199. tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountWithPredicate:[NSPredicate predicateWithFormat:@"account == %@", account]];
  200. if (tableAccount == nil) {
  201. completion(account, nil, NSLocalizedString(@"_error_user_not_available_", nil), k_CCErrorUserNotAvailble);
  202. }
  203. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  204. [communication setCredentialsWithUser:tableAccount.user andUserID:tableAccount.userID andPassword:[CCUtility getPassword:account]];
  205. [communication setUserAgent:[CCUtility getUserAgent]];
  206. [communication getEndToEndServerPublicKey:[tableAccount.url stringByAppendingString:@"/"] onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *publicKey, NSString *redirectedServer) {
  207. completion(account, publicKey, nil, 0);
  208. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  209. NSString *message = @"";
  210. NSInteger errorCode = response.statusCode;
  211. if (errorCode == 0 || (errorCode >= 200 && errorCode < 300))
  212. errorCode = error.code;
  213. // Error
  214. if (errorCode == 503) {
  215. message = NSLocalizedString(@"_server_error_retry_", nil);
  216. } else {
  217. message = [error.userInfo valueForKey:@"NSLocalizedDescription"];
  218. }
  219. completion(account, nil, message, errorCode);
  220. }];
  221. }
  222. - (void)createEndToEndFolder:(NSString *)folderPathName account:(NSString *)account user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url encrypted:(BOOL)encrypted ocId:(NSString **)ocId error:(NSError **)error
  223. {
  224. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  225. __block NSError *returnError = nil;
  226. __block NSString *returnocId = nil;
  227. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  228. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  229. [communication setUserAgent:[CCUtility getUserAgent]];
  230. [communication readFile:folderPathName onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer) {
  231. dispatch_semaphore_signal(semaphore);
  232. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  233. [communication createFolder:folderPathName onCommunication:communication withForbiddenCharactersSupported:YES successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  234. NSDictionary *fields = [response allHeaderFields];
  235. returnocId = [CCUtility removeForbiddenCharactersFileSystem:[fields objectForKey:@"OC-FileId"]];
  236. if (encrypted) {
  237. // MARK
  238. [communication markEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:returnocId onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  239. [[NCManageDatabase sharedInstance] clearDateReadWithServerUrl:[CCUtility deletingLastPathComponentFromServerUrl:folderPathName] account:account];
  240. dispatch_semaphore_signal(semaphore);
  241. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  242. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_mark_folder_"];
  243. dispatch_semaphore_signal(semaphore);
  244. }];
  245. } else {
  246. [[NCManageDatabase sharedInstance] clearDateReadWithServerUrl:[CCUtility deletingLastPathComponentFromServerUrl:folderPathName] account:account];
  247. dispatch_semaphore_signal(semaphore);
  248. }
  249. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  250. returnError = [self getError:response error:error descriptionDefault:@"_error_"];
  251. dispatch_semaphore_signal(semaphore);
  252. } errorBeforeRequest:^(NSError *error) {
  253. returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:response.description forKey:NSLocalizedDescriptionKey]];
  254. dispatch_semaphore_signal(semaphore);
  255. }];
  256. }];
  257. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  258. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  259. *ocId = returnocId;
  260. *error = returnError;
  261. }
  262. #pragma --------------------------------------------------------------------------------------------
  263. #pragma mark ===== E2EE End-to-End Encryption =====
  264. #pragma --------------------------------------------------------------------------------------------
  265. // E2EE
  266. - (NSError *)markEndToEndFolderEncryptedOnServerUrl:(NSString *)serverUrl ocId:(NSString *)ocId user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url
  267. {
  268. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  269. __block NSError *returnError = nil;
  270. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  271. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  272. [communication setUserAgent:[CCUtility getUserAgent]];
  273. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  274. // Read Folder
  275. [communication readFolder:serverUrl depth:@"1" withUserSessionToken:nil onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer, NSString *tokenReadFolder) {
  276. if (items.count > 1) {
  277. returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:999 userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_directory_not_empty_", nil) forKey:NSLocalizedDescriptionKey]];
  278. dispatch_semaphore_signal(semaphore);
  279. return;
  280. }
  281. // LOCK
  282. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  283. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl ocId:ocId token:token];
  284. // REMOVE METADATA
  285. [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] ocId:ocId onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  286. NSLog(@"[LOG] Found metadata and delete");
  287. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  288. NSLog(@"[LOG] %@", [NSString stringWithFormat:@"Remove metadata error %d", (int)response.statusCode]);
  289. }];
  290. // MARK
  291. [communication markEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  292. // UNLOCK
  293. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  294. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  295. dispatch_semaphore_signal(semaphore);
  296. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  297. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  298. dispatch_semaphore_signal(semaphore);
  299. }];
  300. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  301. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_mark_folder_"];
  302. // UNLOCK
  303. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  304. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  305. dispatch_semaphore_signal(semaphore);
  306. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  307. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  308. dispatch_semaphore_signal(semaphore);
  309. }];
  310. }];
  311. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  312. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  313. dispatch_semaphore_signal(semaphore);
  314. }];
  315. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) {
  316. returnError = [self getError:response error:error descriptionDefault:@"_error_"];
  317. dispatch_semaphore_signal(semaphore);
  318. }];
  319. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  320. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  321. return returnError;
  322. }
  323. - (NSError *)deletemarkEndToEndFolderEncryptedOnServerUrl:(NSString *)serverUrl ocId:(NSString *)ocId user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url
  324. {
  325. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  326. __block NSError *returnError = nil;
  327. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  328. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  329. [communication setUserAgent:[CCUtility getUserAgent]];
  330. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  331. // Read Folder
  332. [communication readFolder:serverUrl depth:@"1" withUserSessionToken:nil onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer, NSString *tokenReadFolder) {
  333. if (items.count > 1) {
  334. returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:999 userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_directory_not_empty_", nil) forKey:NSLocalizedDescriptionKey]];
  335. dispatch_semaphore_signal(semaphore);
  336. return;
  337. }
  338. // LOCK
  339. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  340. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl ocId:ocId token:token];
  341. // DELETE METADATA
  342. [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] ocId:ocId onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  343. NSLog(@"[LOG] Found metadata and delete");
  344. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  345. NSLog(@"[LOG] %@", [NSString stringWithFormat:@"Remove metadata error %d", (int)response.statusCode]);
  346. }];
  347. // DELETE MARK
  348. [communication deletemarkEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  349. // UNLOCK
  350. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  351. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  352. dispatch_semaphore_signal(semaphore);
  353. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  354. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  355. dispatch_semaphore_signal(semaphore);
  356. }];
  357. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  358. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_delete_mark_folder_"];
  359. // UNLOCK
  360. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  361. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  362. dispatch_semaphore_signal(semaphore);
  363. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  364. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  365. dispatch_semaphore_signal(semaphore);
  366. }];
  367. }];
  368. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  369. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  370. dispatch_semaphore_signal(semaphore);
  371. }];
  372. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) {
  373. returnError = [self getError:response error:error descriptionDefault:@"_error_"];
  374. dispatch_semaphore_signal(semaphore);
  375. }];
  376. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  377. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  378. return returnError;
  379. }
  380. - (NSError *)getEndToEndMetadata:(NSString **)metadata ocId:(NSString *)ocId user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url
  381. {
  382. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  383. __block NSError *returnError = nil;
  384. __block NSString *returnMetadata = nil;
  385. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  386. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  387. [communication setUserAgent:[CCUtility getUserAgent]];
  388. [communication getEndToEndMetadata:[url stringByAppendingString:@"/"] ocId:ocId onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
  389. returnMetadata = encryptedMetadata;
  390. dispatch_semaphore_signal(semaphore);
  391. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  392. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_get_metadata_"];
  393. dispatch_semaphore_signal(semaphore);
  394. }];
  395. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  396. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  397. *metadata = returnMetadata;
  398. return returnError;
  399. }
  400. - (NSError *)deleteEndToEndMetadataOnServerUrl:(NSString *)serverUrl ocId:(NSString *)ocId unlock:(BOOL)unlock user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url
  401. {
  402. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  403. __block NSError *returnError = nil;
  404. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  405. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  406. [communication setUserAgent:[CCUtility getUserAgent]];
  407. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  408. // LOCK
  409. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  410. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl ocId:ocId token:token];
  411. // DELETE METADATA
  412. [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] ocId:ocId onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  413. // UNLOCK
  414. if (unlock) {
  415. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  416. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  417. dispatch_semaphore_signal(semaphore);
  418. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  419. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  420. dispatch_semaphore_signal(semaphore);
  421. }];
  422. } else {
  423. dispatch_semaphore_signal(semaphore);
  424. }
  425. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  426. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_delete_metadata_"];
  427. // UNLOCK
  428. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  429. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  430. dispatch_semaphore_signal(semaphore);
  431. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  432. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  433. dispatch_semaphore_signal(semaphore);
  434. }];
  435. }];
  436. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  437. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  438. dispatch_semaphore_signal(semaphore);
  439. }];
  440. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  441. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  442. return returnError;
  443. }
  444. - (NSError *)storeEndToEndMetadata:(NSString *)metadata serverUrl:(NSString *)serverUrl ocId:(NSString *)ocId unlock:(BOOL)unlock user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url
  445. {
  446. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  447. __block NSError *returnError = nil;
  448. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  449. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  450. [communication setUserAgent:[CCUtility getUserAgent]];
  451. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  452. // LOCK
  453. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  454. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl ocId:ocId token:token];
  455. // STORE METADATA
  456. [communication storeEndToEndMetadata:[url stringByAppendingString:@"/"] ocId:ocId encryptedMetadata:metadata onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
  457. // UNLOCK
  458. if (unlock) {
  459. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  460. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  461. dispatch_semaphore_signal(semaphore);
  462. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  463. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  464. dispatch_semaphore_signal(semaphore);
  465. }];
  466. } else {
  467. dispatch_semaphore_signal(semaphore);
  468. }
  469. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  470. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_store_metadata_"];
  471. // UNLOCK
  472. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  473. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  474. dispatch_semaphore_signal(semaphore);
  475. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  476. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  477. dispatch_semaphore_signal(semaphore);
  478. }];
  479. }];
  480. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  481. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  482. dispatch_semaphore_signal(semaphore);
  483. }];
  484. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  485. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  486. return returnError;
  487. }
  488. - (NSError *)updateEndToEndMetadata:(NSString *)metadata serverUrl:(NSString *)serverUrl ocId:(NSString *)ocId unlock:(BOOL)unlock user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url
  489. {
  490. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  491. __block NSError *returnError = nil;
  492. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  493. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  494. [communication setUserAgent:[CCUtility getUserAgent]];
  495. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  496. // LOCK
  497. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  498. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl ocId:ocId token:token];
  499. // UPDATA METADATA
  500. [communication updateEndToEndMetadata:[url stringByAppendingString:@"/"] ocId:ocId encryptedMetadata:metadata token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
  501. // UNLOCK
  502. if (unlock) {
  503. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  504. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  505. dispatch_semaphore_signal(semaphore);
  506. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  507. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  508. dispatch_semaphore_signal(semaphore);
  509. }];
  510. } else {
  511. dispatch_semaphore_signal(semaphore);
  512. }
  513. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  514. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_update_metadata_"];
  515. // UNLOCK
  516. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  517. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  518. dispatch_semaphore_signal(semaphore);
  519. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  520. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  521. dispatch_semaphore_signal(semaphore);
  522. }];
  523. }];
  524. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  525. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  526. dispatch_semaphore_signal(semaphore);
  527. }];
  528. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  529. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  530. return returnError;
  531. }
  532. - (NSError *)lockEndToEndFolderEncryptedOnServerUrl:(NSString *)serverUrl ocId:(NSString *)ocId user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url
  533. {
  534. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  535. __block NSError *returnError = nil;
  536. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  537. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  538. [communication setUserAgent:[CCUtility getUserAgent]];
  539. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  540. // LOCK
  541. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  542. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl ocId:ocId token:token];
  543. dispatch_semaphore_signal(semaphore);
  544. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  545. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  546. dispatch_semaphore_signal(semaphore);
  547. }];
  548. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  549. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  550. return returnError;
  551. }
  552. - (NSError *)unlockEndToEndFolderEncryptedOnServerUrl:(NSString *)serverUrl ocId:(NSString *)ocId token:(NSString *)token user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url
  553. {
  554. OCCommunication *communication = [OCNetworking sharedManager].sharedOCCommunication;
  555. __block NSError *returnError = nil;
  556. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  557. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  558. [communication setUserAgent:[CCUtility getUserAgent]];
  559. // UNLOCK
  560. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] ocId:ocId token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  561. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  562. dispatch_semaphore_signal(semaphore);
  563. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  564. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  565. dispatch_semaphore_signal(semaphore);
  566. }];
  567. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  568. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  569. return returnError;
  570. }
  571. - (NSError *)sendEndToEndMetadataOnServerUrl:(NSString *)serverUrl fileNameRename:(NSString *)fileName fileNameNewRename:(NSString *)fileNameNew account:(NSString *)account user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url
  572. {
  573. tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", account, serverUrl]];
  574. NSString *metadata;
  575. NSError *error;
  576. // Enabled E2E
  577. if ([CCUtility isEndToEndEnabled:account] == NO)
  578. return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_not_enabled_", nil) forKey:NSLocalizedDescriptionKey]];
  579. // get Metadata for select updateEndToEndMetadata or storeEndToEndMetadata
  580. error = [self getEndToEndMetadata:&metadata ocId:directory.ocId user:user userID:userID password:password url:url];
  581. if (error.code != kOCErrorServerPathNotFound && error != nil) {
  582. return error;
  583. }
  584. // Rename
  585. if (fileName && fileNameNew)
  586. [[NCManageDatabase sharedInstance] renameFileE2eEncryptionWithServerUrl:serverUrl fileNameIdentifier:fileName newFileName:fileNameNew newFileNamePath:[CCUtility returnFileNamePathFromFileName:fileNameNew serverUrl:serverUrl activeUrl:url]];
  587. NSArray *tableE2eEncryption = [[NCManageDatabase sharedInstance] getE2eEncryptionsWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", account, serverUrl]];
  588. if (!tableE2eEncryption)
  589. return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_record_not_found_", nil) forKey:NSLocalizedDescriptionKey]];
  590. NSString *e2eMetadataJSON = [[NCEndToEndMetadata sharedInstance] encoderMetadata:tableE2eEncryption privateKey:[CCUtility getEndToEndPrivateKey:account] serverUrl:serverUrl];
  591. if (!e2eMetadataJSON)
  592. return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_encode_metadata_", nil) forKey:NSLocalizedDescriptionKey]];
  593. // send Metadata
  594. if (error == nil)
  595. error = [self updateEndToEndMetadata:e2eMetadataJSON serverUrl:serverUrl ocId:directory.ocId unlock:NO user:user userID:userID password:password url:url];
  596. else if (error.code == kOCErrorServerPathNotFound)
  597. error = [self storeEndToEndMetadata:e2eMetadataJSON serverUrl:serverUrl ocId:directory.ocId unlock:NO user:user userID:userID password:password url:url];
  598. return error;
  599. }
  600. - (NSError *)rebuildAndSendEndToEndMetadataOnServerUrl:(NSString *)serverUrl account:(NSString *)account user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url
  601. {
  602. NSError *error;
  603. NSString *e2eMetadataJSON;
  604. tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", account, serverUrl]];
  605. if (directory.e2eEncrypted == NO)
  606. return nil;
  607. NSArray *tableE2eEncryption = [[NCManageDatabase sharedInstance] getE2eEncryptionsWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", account, serverUrl]];
  608. if (tableE2eEncryption) {
  609. e2eMetadataJSON = [[NCEndToEndMetadata sharedInstance] encoderMetadata:tableE2eEncryption privateKey:[CCUtility getEndToEndPrivateKey:account] serverUrl:serverUrl];
  610. if (!e2eMetadataJSON)
  611. return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_encode_metadata_", nil) forKey:NSLocalizedDescriptionKey]];
  612. error = [self updateEndToEndMetadata:e2eMetadataJSON serverUrl:serverUrl ocId:directory.ocId unlock:YES user:user userID:userID password:password url:url];
  613. } else {
  614. [self deleteEndToEndMetadataOnServerUrl:serverUrl ocId:directory.ocId unlock:YES user:user userID:userID password:password url:url];
  615. }
  616. return error;
  617. }
  618. - (NSError *)getError:(NSHTTPURLResponse *)response error:(NSError *)error descriptionDefault:(NSString *)descriptionDefault
  619. {
  620. NSInteger errorCode = response.statusCode;
  621. NSString *errorDescription = response.description;
  622. if (errorDescription == nil || errorCode == 0) {
  623. errorCode = error.code;
  624. errorDescription = error.description;
  625. if (errorDescription == nil) errorDescription = NSLocalizedString(descriptionDefault, @"");
  626. }
  627. errorDescription = [NSString stringWithFormat:@"%@ [%ld] - %@", NSLocalizedString(descriptionDefault, @""), (long)errorCode, errorDescription];
  628. if (errorDescription.length >= 250) {
  629. errorDescription = [errorDescription substringToIndex:250];
  630. errorDescription = [errorDescription stringByAppendingString:@" ..."];
  631. }
  632. return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:errorCode userInfo:[NSDictionary dictionaryWithObject:errorDescription forKey:NSLocalizedDescriptionKey]];
  633. }
  634. @end