CCMove.m 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. //
  2. // CCMove.m
  3. // Crypto Cloud Technology Nextcloud
  4. //
  5. // Created by Marino Faggiana on 04/09/14.
  6. // Copyright (c) 2014 TWS. All rights reserved.
  7. //
  8. // Author Marino Faggiana <m.faggiana@twsweb.it>
  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 "CCMove.h"
  24. #ifndef EXTENSION
  25. #import "AppDelegate.h"
  26. #ifdef CUSTOM_BUILD
  27. #import "CustomSwift.h"
  28. #else
  29. #import "Nextcloud-Swift.h"
  30. #endif
  31. #else
  32. #ifdef CUSTOM_BUILD
  33. #import "CustomSwiftShare.h"
  34. #else
  35. #import "Share-Swift.h"
  36. #endif
  37. #endif
  38. @interface CCMove ()
  39. {
  40. NSString *activeAccount;
  41. NSString *activePassword;
  42. NSString *activeUrl;
  43. NSString *activeUser;
  44. NSString *directoryUser;
  45. CCHud *_hud;
  46. BOOL _isCryptoCloudMode;
  47. }
  48. @end
  49. @implementation CCMove
  50. // MARK: - View
  51. - (void)viewDidLoad
  52. {
  53. [super viewDidLoad];
  54. TableAccount *recordAccount = [CCCoreData getActiveAccount];
  55. if (recordAccount) {
  56. activeAccount = recordAccount.account;
  57. activePassword = recordAccount.password;
  58. activeUrl = recordAccount.url;
  59. activeUser = recordAccount.user;
  60. directoryUser = [CCUtility getDirectoryActiveUser:activeUser activeUrl:activeUrl];
  61. // Crypto Mode
  62. if ([[CCUtility getKeyChainPasscodeForUUID:[CCUtility getUUID]] length] == 0) {
  63. _isCryptoCloudMode = NO;
  64. } else {
  65. _isCryptoCloudMode = YES;
  66. }
  67. } else {
  68. UIAlertController * alert= [UIAlertController alertControllerWithTitle:nil message:NSLocalizedString(@"_no_active_account_", nil) preferredStyle:UIAlertControllerStyleAlert];
  69. UIAlertAction* ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
  70. [alert dismissViewControllerAnimated:YES completion:nil];
  71. }];
  72. [alert addAction:ok];
  73. [self presentViewController:alert animated:YES completion:nil];
  74. }
  75. _hud = [[CCHud alloc] initWithView:self.view];
  76. // TableView : at the end of rows nothing
  77. self.tableView.tableFooterView = [UIView new];
  78. self.tableView.separatorColor = NCBrandColor.sharedInstance.seperator;
  79. [self.cancel setTitle:NSLocalizedString(@"_cancel_", nil)];
  80. [self.create setTitle:NSLocalizedString(@"_create_folder_", nil)];
  81. if (![_serverUrl length]) {
  82. _serverUrl = [CCUtility getHomeServerUrlActiveUrl:activeUrl];
  83. UIImageView *image = [[UIImageView alloc] initWithImage:[UIImage imageNamed: NCBrandImages.sharedInstance.navigationLogo]];
  84. [self.navigationController.navigationBar.topItem setTitleView:image];
  85. self.title = @"Home";
  86. } else {
  87. UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0,0, self.navigationItem.titleView.frame.size.width, 40)];
  88. label.text = self.passMetadata.fileNamePrint;
  89. if (self.passMetadata.cryptated) label.textColor = NCBrandColor.sharedInstance.cryptocloud;
  90. else label.textColor = self.tintColorTitle;
  91. label.backgroundColor =[UIColor clearColor];
  92. label.textAlignment = NSTextAlignmentCenter;
  93. self.navigationItem.titleView=label;
  94. }
  95. // Toolbar Color
  96. self.navigationController.navigationBar.barTintColor = NCBrandColor.sharedInstance.brand;
  97. self.navigationController.navigationBar.tintColor = NCBrandColor.sharedInstance.navigationBarText;
  98. self.navigationController.toolbar.barTintColor = NCBrandColor.sharedInstance.tabBar;
  99. self.navigationController.toolbar.tintColor = NCBrandColor.sharedInstance.brand;
  100. // read folder
  101. [self readFolder];
  102. }
  103. // MARK: - alertView
  104. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
  105. {
  106. if (buttonIndex == 1) {
  107. NSString *nome = [alertView textFieldAtIndex:0].text;
  108. if ([nome length]) {
  109. nome = [NSString stringWithFormat:@"%@/%@", _serverUrl, [CCUtility removeForbiddenCharactersServer:nome]];
  110. }
  111. }
  112. }
  113. // MARK: - IBAction
  114. - (IBAction)cancel:(UIBarButtonItem *)sender
  115. {
  116. [self dismissViewControllerAnimated:YES completion:nil];
  117. }
  118. - (IBAction)move:(UIBarButtonItem *)sender
  119. {
  120. [_networkingOperationQueue cancelAllOperations];
  121. [self.delegate moveServerUrlTo:_serverUrl title:self.passMetadata.fileNamePrint selectedMetadatas:self.selectedMetadatas];
  122. [self dismissViewControllerAnimated:YES completion:nil];
  123. }
  124. - (IBAction)create:(UIBarButtonItem *)sender
  125. {
  126. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_create_folder_",nil) message:@"" preferredStyle:UIAlertControllerStyleAlert];
  127. [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
  128. //textField.placeholder = NSLocalizedString(@"LoginPlaceholder", @"Login");
  129. }];
  130. [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_save_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
  131. [self createFolder:alertController.textFields.firstObject.text];
  132. }]];
  133. [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_cancel_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
  134. }]];
  135. [self presentViewController:alertController animated:YES completion:nil];
  136. }
  137. // MARK: - BKPasscodeViewController
  138. - (void)passcodeViewController:(CCBKPasscode *)aViewController didFinishWithPasscode:(NSString *)aPasscode
  139. {
  140. [aViewController dismissViewControllerAnimated:YES completion:nil];
  141. [self performSegueDirectoryWithControlPasscode:false];
  142. }
  143. - (void)passcodeViewController:(BKPasscodeViewController *)aViewController authenticatePasscode:(NSString *)aPasscode resultHandler:(void (^)(BOOL))aResultHandler
  144. {
  145. if ([aPasscode isEqualToString:[CCUtility getBlockCode]]) {
  146. self.lockUntilDate = nil;
  147. self.failedAttempts = 0;
  148. aResultHandler(YES);
  149. } else {
  150. aResultHandler(NO);
  151. }
  152. }
  153. - (void)passcodeViewControllerDidFailAttempt:(BKPasscodeViewController *)aViewController
  154. {
  155. self.failedAttempts++;
  156. if (self.failedAttempts > 5) {
  157. NSTimeInterval timeInterval = 60;
  158. if (self.failedAttempts > 6) {
  159. NSUInteger multiplier = self.failedAttempts - 6;
  160. timeInterval = (5 * 60) * multiplier;
  161. if (timeInterval > 3600 * 24) {
  162. timeInterval = 3600 * 24;
  163. }
  164. }
  165. self.lockUntilDate = [NSDate dateWithTimeIntervalSinceNow:timeInterval];
  166. }
  167. }
  168. - (NSUInteger)passcodeViewControllerNumberOfFailedAttempts:(BKPasscodeViewController *)aViewController
  169. {
  170. return self.failedAttempts;
  171. }
  172. - (NSDate *)passcodeViewControllerLockUntilDate:(BKPasscodeViewController *)aViewController
  173. {
  174. return self.lockUntilDate;
  175. }
  176. - (void)passcodeViewCloseButtonPressed:(id)sender
  177. {
  178. [self dismissViewControllerAnimated:YES completion:nil];
  179. }
  180. // MARK: - NetWorking
  181. - (void)addNetworkingQueue:(CCMetadataNet *)metadataNet
  182. {
  183. OCnetworking *operation = [[OCnetworking alloc] initWithDelegate:self metadataNet:metadataNet withUser:activeUser withPassword:activePassword withUrl:activeUrl isCryptoCloudMode:_isCryptoCloudMode];
  184. _networkingOperationQueue.maxConcurrentOperationCount = k_maxConcurrentOperation;
  185. [_networkingOperationQueue addOperation:operation];
  186. }
  187. // MARK: - Download File
  188. - (void)downloadFileSuccess:(NSString *)fileID serverUrl:(NSString *)serverUrl selector:(NSString *)selector selectorPost:(NSString *)selectorPost
  189. {
  190. if ([selector isEqualToString:selectorLoadPlist]) {
  191. CCMetadata *metadata = [CCCoreData getMetadataWithPreficate:[NSPredicate predicateWithFormat:@"(fileID == %@) AND (account == %@)", fileID, activeAccount] context:nil];
  192. [CCCoreData downloadFilePlist:metadata activeAccount:activeAccount activeUrl:activeUrl directoryUser:directoryUser];
  193. [self.tableView reloadData];
  194. }
  195. }
  196. - (void)downloadFileFailure:(NSString *)fileID serverUrl:(NSString *)serverUrl selector:(NSString *)selector message:(NSString *)message errorCode:(NSInteger)errorCode
  197. {
  198. self.move.enabled = NO;
  199. }
  200. // MARK: - Read Folder
  201. - (void)readFolderFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode
  202. {
  203. [_hud hideHud];
  204. self.move.enabled = NO;
  205. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_error_",nil) message:message preferredStyle:UIAlertControllerStyleAlert];
  206. [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
  207. }]];
  208. [self presentViewController:alertController animated:YES completion:nil];
  209. }
  210. - (void)readFolderSuccess:(CCMetadataNet *)metadataNet permissions:(NSString *)permissions etag:(NSString *)etag metadatas:(NSArray *)metadatas
  211. {
  212. // remove all record
  213. [CCCoreData deleteMetadataWithPredicate:[NSPredicate predicateWithFormat:@"(account == %@) AND (directoryID == %@) AND ((session == NULL) OR (session == ''))", activeAccount, metadataNet.directoryID]];
  214. for (CCMetadata *metadata in metadatas) {
  215. // do not insert crypto file
  216. if ([CCUtility isCryptoString:metadata.fileName]) continue;
  217. // plist + crypto = completed ?
  218. if ([CCUtility isCryptoPlistString:metadata.fileName] && metadata.directory == NO) {
  219. BOOL isCryptoComplete = NO;
  220. for (CCMetadata *completeMetadata in metadatas) {
  221. if ([completeMetadata.fileName isEqualToString:[CCUtility trasformedFileNamePlistInCrypto:metadata.fileName]]) isCryptoComplete = YES;
  222. }
  223. if (isCryptoComplete == NO) continue;
  224. }
  225. [CCCoreData addMetadata:metadata activeAccount:activeAccount activeUrl:activeUrl context:nil];
  226. // if plist do not exists, download it !
  227. if ([CCUtility isCryptoPlistString:metadata.fileName] && [[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/%@", directoryUser, metadata.fileName]] == NO) {
  228. // download only the directories
  229. for (CCMetadata *metadataDirectory in metadatas) {
  230. if (metadataDirectory.directory == YES && [metadataDirectory.fileName isEqualToString:metadata.fileNameData]) {
  231. CCMetadataNet *metadataNet = [[CCMetadataNet alloc] initWithAccount:activeAccount];
  232. metadataNet.action = actionDownloadFile;
  233. metadataNet.metadata = metadata;
  234. metadataNet.downloadData = NO;
  235. metadataNet.downloadPlist = YES;
  236. metadataNet.selector = selectorLoadPlist;
  237. metadataNet.serverUrl = _serverUrl;
  238. metadataNet.session = k_download_session_foreground;
  239. metadataNet.taskStatus = k_taskStatusResume;
  240. [self addNetworkingQueue:metadataNet];
  241. }
  242. }
  243. }
  244. }
  245. [self.tableView reloadData];
  246. [_hud hideHud];
  247. }
  248. - (void)readFolder
  249. {
  250. // read folder
  251. [_hud visibleIndeterminateHud];
  252. CCMetadataNet *metadataNet = [[CCMetadataNet alloc] initWithAccount:activeAccount];
  253. metadataNet.action = actionReadFolder;
  254. metadataNet.serverUrl = _serverUrl;
  255. metadataNet.selector = selectorReadFolder;
  256. metadataNet.date = nil;
  257. [self addNetworkingQueue:metadataNet];
  258. }
  259. // MARK: - Create Folder
  260. - (void)createFolderFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode
  261. {
  262. [_hud hideHud];
  263. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_error_",nil) message:message preferredStyle:UIAlertControllerStyleAlert];
  264. [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
  265. }]];
  266. [self presentViewController:alertController animated:YES completion:nil];
  267. }
  268. - (void)createFolderSuccess:(CCMetadataNet *)metadataNet
  269. {
  270. [_hud hideHud];
  271. [CCCoreData addDirectory:[NSString stringWithFormat:@"%@/%@", metadataNet.serverUrl, metadataNet.fileName] permissions:nil activeAccount:activeAccount];
  272. // Load Folder or the Datasource
  273. [self readFolder];
  274. }
  275. - (void)createFolder:(NSString *)fileNameFolder
  276. {
  277. CCMetadataNet *metadataNet = [[CCMetadataNet alloc] initWithAccount:activeAccount];
  278. fileNameFolder = [CCUtility removeForbiddenCharactersServer:fileNameFolder];
  279. if (![fileNameFolder length]) return;
  280. metadataNet.action = actionCreateFolder;
  281. metadataNet.fileName = fileNameFolder;
  282. metadataNet.selector = selectorCreateFolder;
  283. metadataNet.selectorPost = selectorReadFolderForced;
  284. metadataNet.serverUrl = _serverUrl;
  285. [self addNetworkingQueue:metadataNet];
  286. [_hud visibleIndeterminateHud];
  287. }
  288. // MARK: - Table
  289. - (void)reloadTable
  290. {
  291. [self.tableView reloadData];
  292. }
  293. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  294. {
  295. return 1;
  296. }
  297. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  298. {
  299. NSString *directoryID = [CCCoreData getDirectoryIDFromServerUrl:_serverUrl activeAccount:activeAccount];
  300. NSPredicate *predicate;
  301. if (self.onlyClearDirectory) predicate = [NSPredicate predicateWithFormat:@"(account == %@) AND (directoryID == %@) AND (directory == 1) AND (cryptated == 0)", activeAccount, directoryID];
  302. else predicate = [NSPredicate predicateWithFormat:@"(account == %@) AND (directoryID == %@) AND (directory == 1)", activeAccount, directoryID];
  303. return [[CCCoreData getTableMetadataWithPredicate:predicate context:nil] count];
  304. }
  305. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  306. {
  307. NSPredicate *predicate;
  308. static NSString *CellIdentifier = @"MyCustomCell";
  309. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  310. if (cell == nil) {
  311. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
  312. }
  313. NSString *directoryID = [CCCoreData getDirectoryIDFromServerUrl:_serverUrl activeAccount:activeAccount];
  314. if (self.onlyClearDirectory) predicate = [NSPredicate predicateWithFormat:@"(account == %@) AND (directoryID == %@) AND (directory == 1) AND (cryptated == 0)", activeAccount, directoryID];
  315. else predicate = [NSPredicate predicateWithFormat:@"(account == %@) AND (directoryID == %@) AND (directory == 1)", activeAccount, directoryID];
  316. CCMetadata *metadata = [CCCoreData getMetadataAtIndex:predicate fieldOrder:@"fileName" ascending:YES objectAtIndex:indexPath.row];
  317. // colors
  318. if (metadata.cryptated) {
  319. cell.textLabel.textColor = NCBrandColor.sharedInstance.cryptocloud;
  320. } else {
  321. cell.textLabel.textColor = [UIColor blackColor];
  322. }
  323. cell.detailTextLabel.text = @"";
  324. cell.imageView.image = [CCGraphics changeThemingColorImage:[UIImage imageNamed:metadata.iconName] color:[NCBrandColor sharedInstance].brand];
  325. cell.textLabel.text = metadata.fileNamePrint;
  326. return cell;
  327. }
  328. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  329. {
  330. [self performSegueDirectoryWithControlPasscode:YES];
  331. }
  332. // MARK: - Navigation
  333. - (void)performSegueDirectoryWithControlPasscode:(BOOL)controlPasscode
  334. {
  335. NSString *nomeDir;
  336. NSPredicate *predicate;
  337. NSIndexPath *index = [self.tableView indexPathForSelectedRow];
  338. NSString *directoryID = [CCCoreData getDirectoryIDFromServerUrl:_serverUrl activeAccount:activeAccount];
  339. if (self.onlyClearDirectory) predicate = [NSPredicate predicateWithFormat:@"(account == %@) AND (directoryID == %@) AND (directory == 1) AND (cryptated == 0)", activeAccount, directoryID];
  340. else predicate = [NSPredicate predicateWithFormat:@"(account == %@) AND (directoryID == %@) AND (directory == 1)", activeAccount, directoryID];
  341. CCMetadata *metadata = [CCCoreData getMetadataAtIndex:predicate fieldOrder:@"fileName" ascending:YES objectAtIndex:index.row];
  342. if (metadata.errorPasscode == NO) {
  343. // lockServerUrl
  344. NSString *lockServerUrl = [CCUtility stringAppendServerUrl:_serverUrl addFileName:metadata.fileNameData];
  345. // SE siamo in presenza di una directory bloccata E è attivo il block E la sessione PASSWORD Lock è senza data ALLORA chiediamo la password per procedere
  346. if ([CCCoreData isDirectoryLock:lockServerUrl activeAccount:activeAccount] && [[CCUtility getBlockCode] length] && controlPasscode) {
  347. CCBKPasscode *viewController = [[CCBKPasscode alloc] initWithNibName:nil bundle:nil];
  348. viewController.delegate = self;
  349. //viewController.fromType = CCBKPasscodeFromLockDirectory;
  350. viewController.type = BKPasscodeViewControllerCheckPasscodeType;
  351. viewController.inputViewTitlePassword = YES;
  352. if ([CCUtility getSimplyBlockCode]) {
  353. viewController.passcodeStyle = BKPasscodeInputViewNumericPasscodeStyle;
  354. viewController.passcodeInputView.maximumLength = 6;
  355. } else {
  356. viewController.passcodeStyle = BKPasscodeInputViewNormalPasscodeStyle;
  357. viewController.passcodeInputView.maximumLength = 64;
  358. }
  359. BKTouchIDManager *touchIDManager = [[BKTouchIDManager alloc] initWithKeychainServiceName:k_serviceShareKeyChain];
  360. touchIDManager.promptText = NSLocalizedString(@"_scan_fingerprint_", nil);
  361. viewController.touchIDManager = touchIDManager;
  362. viewController.title = NSLocalizedString(@"_folder_blocked_", nil);
  363. viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(passcodeViewCloseButtonPressed:)];
  364. viewController.navigationItem.leftBarButtonItem.tintColor = NCBrandColor.sharedInstance.cryptocloud;
  365. UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
  366. [self presentViewController:navController animated:YES completion:nil];
  367. return;
  368. }
  369. if (metadata.cryptated) nomeDir = [metadata.fileName substringToIndex:[metadata.fileName length]-6];
  370. else nomeDir = metadata.fileName;
  371. CCMove *viewController = [[UIStoryboard storyboardWithName:@"CCMove" bundle:nil] instantiateViewControllerWithIdentifier:@"CCMoveVC"];
  372. viewController.delegate = self.delegate;
  373. viewController.onlyClearDirectory = self.onlyClearDirectory;
  374. viewController.selectedMetadatas = self.selectedMetadatas;
  375. viewController.move.title = self.move.title;
  376. viewController.barTintColor = self.barTintColor;
  377. viewController.tintColor = self.tintColor;
  378. viewController.tintColorTitle = self.tintColorTitle;
  379. viewController.networkingOperationQueue = _networkingOperationQueue;
  380. viewController.passMetadata = metadata;
  381. viewController.serverUrl = [CCUtility stringAppendServerUrl:_serverUrl addFileName:nomeDir];
  382. [self.navigationController pushViewController:viewController animated:YES];
  383. }
  384. }
  385. @end