private static void ProcessSubFolders(this Vault vault, SyncDownResponse rs) { var comparers = new Comparers(); var folderList = new SortedSet <IFolderNode>(vault.userFolders.Values, comparers); var recordList = new SortedSet <IRecordNode>(vault.userFolderRecords ?? Enumerable.Empty <IRecordNode>(), comparers); if (rs.userFoldersRemoved != null) { foreach (var ufr in rs.userFoldersRemoved) { folderList.RemoveWhere(x => x.FolderUid == ufr.folderUid); recordList.RemoveWhere(x => x.FolderUid == ufr.folderUid); } } if (rs.sharedFolderFolderRemoved != null) { foreach (var sffr in rs.sharedFolderFolderRemoved) { folderList.RemoveWhere(x => x.FolderUid == sffr.folderUid); recordList.RemoveWhere(x => x.FolderUid == sffr.folderUid); } } if (rs.userFolderSharedFoldersRemoved != null) { foreach (var ufsfr in rs.userFolderSharedFoldersRemoved) { folderList.RemoveWhere(x => x.FolderUid == ufsfr.folderUid); recordList.RemoveWhere(x => x.FolderUid == ufsfr.folderUid); } } if (rs.userFoldersRemovedRecords != null) { foreach (var uffr in rs.userFoldersRemovedRecords) { recordList.Remove(uffr); } } if (rs.sharedFolderFolderRecordsRemoved != null) { foreach (var sffrr in rs.sharedFolderFolderRecordsRemoved) { recordList.Remove(sffrr); } } if (rs.userFolders != null) { foreach (var uf in rs.userFolders) { var encryptedKey = uf.userFolderKey.Base64UrlDecode(); uf.unencryptedFolderKey = uf.keyType == 2 ? CryptoUtils.DecryptRsa(encryptedKey, vault.Auth.PrivateKey) : CryptoUtils.DecryptAesV1(encryptedKey, vault.Auth.DataKey); folderList.Remove(uf); folderList.Add(uf); } } if (rs.sharedFolderFolders != null) { foreach (var sff in rs.sharedFolderFolders) { if (vault.sharedFolders.TryGetValue(sff.sharedFolderUid, out SyncDownSharedFolder sf)) { var encryptedKey = sff.sharedFolderFolderKey.Base64UrlDecode(); sff.unencryptedFolderKey = CryptoUtils.DecryptAesV1(encryptedKey, sf.unencryptedSharedFolderKey); folderList.Remove(sff); folderList.Add(sff); } else { Trace.TraceError("Sync_Down: shared_folder_folders: Shared Folder UID {0} not found", sff.sharedFolderUid); } } } if (rs.userFolderSharedFolders != null) { foreach (var ufsf in rs.userFolderSharedFolders) { folderList.Remove(ufsf); folderList.Add(ufsf); } } if (rs.userFolderRecords != null) { foreach (var ufr in rs.userFolderRecords) { recordList.Add(ufr); } } if (rs.sharedFolderFolderRecords != null) { foreach (var sffr in rs.sharedFolderFolderRecords) { recordList.Add(sffr); } } var toDelete = new HashSet <string>(); foreach (var folder in vault.keeperFolders.Values) { toDelete.Add(folder.FolderUid); folder.Children.Clear(); folder.Records.Clear(); } foreach (var folder in folderList) { if (vault.keeperFolders.TryGetValue(folder.FolderUid, out FolderNode node)) { toDelete.Remove(folder.FolderUid); node.Children.Clear(); node.Records.Clear(); node.Name = null; } else { node = new FolderNode { FolderType = folder.Type, FolderUid = folder.FolderUid }; vault.keeperFolders.Add(folder.FolderUid, node); } node.ParentUid = folder.ParentUid; byte[] unencrypted_data = null; switch (folder.Type) { case FolderType.UserFolder: if (folder is SyncDownUserFolder uf) { unencrypted_data = CryptoUtils.DecryptAesV1(uf.data.Base64UrlDecode(), uf.unencryptedFolderKey); } else { Trace.TraceError("Folder UID {0} expected to be User-Folder", folder.FolderUid); } break; case FolderType.SharedFolderForder: if (folder is SyncDownSharedFolderFolder sff) { unencrypted_data = CryptoUtils.DecryptAesV1(sff.data.Base64UrlDecode(), sff.unencryptedFolderKey); } else { Trace.TraceError("Folder UID {0} expected to be Shared-Folder-Folder", folder.FolderUid); } break; case FolderType.SharedFolder: if (vault.sharedFolders.TryGetValue(folder.FolderUid, out SyncDownSharedFolder sf)) { node.Name = Encoding.UTF8.GetString(CryptoUtils.DecryptAesV1(sf.name.Base64UrlDecode(), sf.unencryptedSharedFolderKey)); } else { Trace.TraceError("Folder UID {0} expected to be Shared-Folder", folder.FolderUid); } break; } if (unencrypted_data != null) { var serializer = new DataContractJsonSerializer(typeof(FolderData)); using (var stream = new MemoryStream(unencrypted_data)) { var folderData = serializer.ReadObject(stream) as FolderData; node.Name = folderData.name; } } if (string.IsNullOrEmpty(node.Name)) { node.Name = node.FolderUid; } } foreach (var uid in toDelete) { vault.keeperFolders.Remove(uid); } vault.Root.Children.Clear(); vault.Root.Records.Clear(); foreach (var node in vault.keeperFolders.Values) { if (string.IsNullOrEmpty(node.ParentUid)) { vault.Root.Children.Add(node.FolderUid); } else { if (vault.keeperFolders.TryGetValue(node.ParentUid, out FolderNode parent)) { parent.Children.Add(node.FolderUid); } else { Trace.TraceError("Folder UID {0} was lost", node.FolderUid); } } } foreach (var record in recordList) { if (string.IsNullOrEmpty(record.FolderUid)) { vault.Root.Records.Add(record.RecordUid); } else { if (vault.keeperFolders.TryGetValue(record.FolderUid, out FolderNode node)) { node.Records.Add(record.RecordUid); } else { Trace.TraceError("Folder UID {0} was lost", node.FolderUid); vault.Root.Records.Add(record.RecordUid); } } } vault.userFolders.Clear(); foreach (var folder in folderList) { vault.userFolders.Add(folder.FolderUid, folder); } vault.userFolderRecords = recordList.ToList(); }
public bool TryGetFolder(string folderUid, out FolderNode node) { return(keeperFolders.TryGetValue(folderUid, out node)); }