public void Ae2Test() { PwDatabase db = DbHelper.OpenDatabase(Path.Combine(_settings.DbAFilesPath, Ae2RealData.Db), keyPath: _settings.KeyTestAPath); var group = db.RootGroup; CheckKdf(db.KdfParameters, Ae2RealData.Kdf); CheckGroup(group, Ae2RealData.Data); db.Close(); }
public void Ae6Test() { PwDatabase db = DbHelper.OpenDatabase(Path.Combine(_settings.DbAFilesPath, Ae6RealData.Db), password: _settings.DbTestPw); var group = db.RootGroup; CheckKdf(db.KdfParameters, Ae6RealData.Kdf); CheckGroup(group, Ae6RealData.Data); db.Close(); }
public static KeyValuePair <string, string> GetEntry(string entry, string databasefile, string keyfile) { /* * Assembly assembly = Assembly.LoadFrom(assemblyPath); * Type T = assembly.GetType("Company.Project.Classname"); * Company.Project.Classname instance = (Company.Project.Classname)Activator.CreateInstance(T); */ //Read string databasefile,string keyfile from config KeyValuePair <string, string> keyval = new KeyValuePair <string, string>("Username", null); DpiUtil.ConfigureProcess(); //needed? if (!KeePass.Program.CommonInit()) //check if in same dir as KeePass?? { KeePass.Program.CommonTerminate(); return(keyval); } IOConnectionInfo ioc = new IOConnectionInfo(); ioc.Path = databasefile; ioc.CredSaveMode = IOCredSaveMode.NoSave; CompositeKey cmpKey = new CompositeKey(); cmpKey.AddUserKey(new KcpKeyFile(keyfile)); if ((cmpKey == null) || (cmpKey.UserKeyCount == 0)) { return(keyval); } PwDatabase pwDb = new PwDatabase(); pwDb.Open(ioc, cmpKey, null); string password; //bool bNeedsSave; if (ReportingMod.GetEntryString(pwDb, entry, out password)) { keyval = new KeyValuePair <string, string>("Username", password); } // if (bNeedsSave) pwDb.Save(null); pwDb.Close(); return(keyval); }
/// <summary> /// Checks whether the provided master key actually unlocks the database /// </summary> /// <param name="ioInfo">IOConnectionInfo that represents the database.</param> /// <param name="key">Master Key to check.</param> internal static bool CheckMasterKey(IOConnectionInfo ioinfo, CompositeKey key) { PwDatabase db = new PwDatabase(); try { db.Open(ioinfo, key, null); bool isopen = db.IsOpen; db.Close(); return(isopen); } catch (Exception) { return(false); } }
public static void Initalize(TestContext testContext) { InitalizeSettings(testContext); PwDatabase db = DbHelper.OpenDatabase(_settings.DbAPath, _settings.DbMainPw); Exporter.Export(db); db.Close(); db = DbHelper.OpenDatabase(_settings.DbBPath, _settings.DbMainPw); Exporter.Export(db); db.Close(); db = DbHelper.OpenDatabase(_settings.DbCPath, _settings.DbMainPw); Exporter.Export(db); db.Close(); }
public void ShouldExportToTargets() { //we change the password which is used to encrypt the delta container so we can later access the delta container //more easily. PwEntry mrX = TestHelper.GetUserRootNodeFor(m_database, 0); //the first autoExport only checks if there is a delta container allready and if not it will export one //in our case there should be no existing container so a new one will be created. var exportFolder = m_database.GetExportGroup(); Assert.IsTrue(0 == exportFolder.Groups.UCount); string exportPath = GetTestPath(); m_syncManager.AddExportPath(exportPath); var exportGroup = exportFolder.Groups.GetAt(0); exportGroup.AddEntry(mrX.CreateProxyNode(), true); string exportFile = exportPath + SyncSource.FileNameFor(mrX) + SyncExporter.FileExtension; Assert.IsFalse(File.Exists(exportFile)); m_syncManager.RefeshSourcesList(); m_syncManager.Export(); mrX = TestHelper.GetUserRootNodeFor(m_database, 0); Assert.AreEqual("mrX", mrX.Strings.ReadSafe(KeeShare.KeeShare.TitleField)); Assert.IsTrue(File.Exists(exportFile)); //now we open the creted delta container and verify the contend PwDatabase deltaDB = new PwDatabase(); Assert.DoesNotThrow(delegate { deltaDB.Open(IOConnectionInfo.FromPath(exportFile), m_standardKey, null); }); Assert.AreEqual(5, deltaDB.RootGroup.GetEntries(true).UCount); Assert.AreEqual(3, deltaDB.RootGroup.Entries.UCount); Assert.AreEqual("grp1", deltaDB.RootGroup.Groups.GetAt(0).Name); Assert.AreEqual(2, deltaDB.RootGroup.Groups.GetAt(0).Entries.UCount); //now we will test in detail if there are only the expected entries in the created delta container Assert.AreEqual(Uuid1, deltaDB.RootGroup.Entries.GetAt(0).Uuid); Assert.AreEqual(Uuid3, deltaDB.RootGroup.Entries.GetAt(2).Uuid); Assert.AreEqual(Uuid6, deltaDB.RootGroup.Entries.GetAt(1).Uuid); Assert.AreEqual(Uuid4, deltaDB.RootGroup.Groups.GetAt(0).Entries.GetAt(0).Uuid); Assert.AreEqual(Uuid5, deltaDB.RootGroup.Groups.GetAt(0).Entries.GetAt(1).Uuid); Assert.AreEqual("normalEntry1", deltaDB.RootGroup.Entries.GetAt(0).GetTitle()); deltaDB.Close(); }
public void New_Test() { var db = CreateTestDatabase(out IOConnectionInfo ci, out CompositeKey key, out IFile file); var initialEnitiesCount = db.RootGroup.GetEntriesCount(true); Assert.AreNotEqual(0, initialEnitiesCount); db.Save(null); db.Close(); Assert.IsNull(db.RootGroup); db = new PwDatabase(); db.Open(ci, key, null); Assert.AreEqual(initialEnitiesCount, db.RootGroup.GetEntriesCount(true)); db.Close(); file.DeleteAsync().Wait(); }
public void ShouldHandleCyclesOfNodesInImportAndExport() { var exportPath = GetTestPath(); m_syncManager.AddExportPath(exportPath); var userMrX = TestHelper.GetUserRootNodeByNameFor(m_database, "mrX"); m_database.GetExportGroup().Groups.GetAt(0).AddEntry(userMrX.CreateProxyNode(), true); var existingEntry = new PwEntry(true, true); existingEntry.SetTitle("Entry Version 1"); m_database.RootGroup.AddEntry(existingEntry, true); m_database.RootGroup.AddEntry(userMrX.CreateProxyNode(), true); m_treeManager.CorrectStructure(); string exportFile = exportPath + SyncSource.FileNameFor(userMrX) + SyncExporter.FileExtension; Assert.IsFalse(File.Exists(exportFile)); m_syncManager.Export(); var deltaDBInitial = new PwDatabase(); deltaDBInitial.Open(IOConnectionInfo.FromPath(exportFile), m_standardKey, null); Assert.AreEqual(1, deltaDBInitial.RootGroup.GetEntries(true).Count(e => e.GetTitle() == "Entry Version 1")); foreach (var entry in deltaDBInitial.RootGroup.GetEntries(true)) { entry.SetTitle("Changed"); } deltaDBInitial.Save(null); deltaDBInitial.Close(); m_syncManager.AddImportPath(exportFile); m_database.GetImportGroup().Groups.GetAt(0).Entries.GetAt(0).SetPassword(userMrX.Strings.ReadSafe(KeeShare.KeeShare.PasswordField)); m_syncManager.RefeshSourcesList(); // Node normalEntry6 is within the user home and is relocated on export which changes the parent node - during import, the parents of // not "officially" relocated nodes is checked and an assertion is thrown Assert.AreEqual(0, m_database.RootGroup.GetEntries(true).Count(e => e.GetTitle() == "Changed")); }
public void ShouldNotImportDatabasesWithDifferentUsers() { var exportPath = GetTestPath(); m_syncManager.AddExportPath(exportPath); var userMrX = TestHelper.GetUserRootNodeByNameFor(m_database, "mrX"); var userMrY = TestHelper.GetUserRootNodeByNameFor(m_database, "mrY"); m_database.GetExportGroup().Groups.GetAt(0).AddEntry(userMrY.CreateProxyNode(), true); var existingEntry = new PwEntry(true, true); existingEntry.SetTitle("Entry Version 1"); m_database.RootGroup.AddEntry(existingEntry, true); m_database.RootGroup.AddEntry(userMrY.CreateProxyNode(), true); m_treeManager.CorrectStructure(); string exportFile = exportPath + SyncSource.FileNameFor(userMrY) + SyncExporter.FileExtension; Assert.IsFalse(File.Exists(exportFile)); m_syncManager.Export(); existingEntry.SetTitle("Entry Version 2"); var deltaDBInitial = new PwDatabase(); deltaDBInitial.Open(IOConnectionInfo.FromPath(exportFile), m_standardKey, null); Assert.AreEqual(0, deltaDBInitial.RootGroup.GetEntries(true).Count(e => e.GetTitle() == "Entry Version 2")); Assert.AreEqual(1, deltaDBInitial.RootGroup.GetEntries(true).Count(e => e.GetTitle() == "Entry Version 1")); deltaDBInitial.Close(); m_syncManager.AddImportPath(exportFile); m_database.GetImportGroup().Groups.GetAt(0).Entries.GetAt(0).SetPassword("InvalidPassword"); m_syncManager.RefeshSourcesList(); Assert.AreEqual(1, m_database.RootGroup.GetEntries(true).Count(e => e.GetTitle() == "Entry Version 2")); Assert.AreEqual(0, m_database.RootGroup.GetEntries(true).Count(e => e.GetTitle() == "Entry Version 1")); }
private void ReplaceDatabase(PwDatabase pwDatabase, byte[] dbData) { CreateBackup(pwDatabase); var pwKey = pwDatabase.MasterKey; var location = pwDatabase.IOConnectionInfo.Path; pwDatabase.Close(); File.WriteAllBytes(location, dbData); try { // try to open with current MasterKey ... _host.Database.Open(IOConnectionInfo.FromPath(location), pwKey, new NullStatusLogger()); } catch (KeePassLib.Keys.InvalidCompositeKeyException) { // ... MasterKey is different, let user enter the MasterKey _host.MainWindow.OpenDatabase(IOConnectionInfo.FromPath(location), null, true); } }
public KeePassApi(IConfiguration config) { var dbpath = config.GetValue <string>("KeePassFile"); var masterpw = config.GetValue <string>("KeePassword"); var ioConnInfo = new IOConnectionInfo { Path = dbpath }; var compKey = new CompositeKey(); compKey.AddUserKey(new KcpPassword(masterpw)); if (!File.Exists(dbpath)) { var newDb = new PwDatabase(); newDb.New(ioConnInfo, compKey); newDb.Save(null); newDb.Close(); } _db = new PwDatabase(); _db.Open(ioConnInfo, compKey, null); }
public static void GetAllEntries(string databasefile, string keyfile, out ConcurrentDictionary <string, KeyValuePair <string, string> > dictionary) { // public static void ListEntries(PwDatabase pwDb) dictionary = null; DpiUtil.ConfigureProcess(); //needed? if (!KeePass.Program.CommonInit()) //check if in same dir as KeePass?? { KeePass.Program.CommonTerminate(); return; } IOConnectionInfo ioc = new IOConnectionInfo(); ioc.Path = databasefile; ioc.CredSaveMode = IOCredSaveMode.NoSave; CompositeKey cmpKey = new CompositeKey(); cmpKey.AddUserKey(new KcpKeyFile(keyfile)); if ((cmpKey == null) || (cmpKey.UserKeyCount == 0)) { return; } PwDatabase pwDb = new PwDatabase(); pwDb.Open(ioc, cmpKey, null); EntryMod.GetAllEntries(pwDb, out dictionary); pwDb.Close(); }
private static void RunScriptLine(CommandLineArgs args) { string strCommand = args[ParamCommand]; if (strCommand == null) { throw new InvalidOperationException(KSRes.NoCommand); } if (args.FileName == null) { RunSingleCommand(strCommand.ToLower()); return; } IOConnectionInfo ioc = new IOConnectionInfo(); ioc.Url = args.FileName; ioc.CredSaveMode = IOCredSaveMode.NoSave; CompositeKey cmpKey = null; if (args[ParamGuiKey] != null) { EnsureGuiInitialized(); KeyPromptForm kpf = new KeyPromptForm(); kpf.InitEx(ioc.GetDisplayName(), false); if (kpf.ShowDialog() != DialogResult.OK) { return; } cmpKey = kpf.CompositeKey; } else if (args[ParamConsoleKey] != null) { cmpKey = new CompositeKey(); Console.WriteLine(KSRes.NoKeyPartHint); Console.WriteLine(); Console.WriteLine(KSRes.KeyPrompt); Console.Write(KSRes.PasswordPrompt + " "); string strPw = Console.ReadLine().Trim(); if ((strPw != null) && (strPw.Length > 0)) { cmpKey.AddUserKey(new KcpPassword(strPw)); } Console.Write(KSRes.KeyFilePrompt + " "); string strFile = Console.ReadLine().Trim(); if ((strFile != null) && (strFile.Length > 0)) { cmpKey.AddUserKey(new KcpKeyFile(strFile)); } Console.Write(KSRes.UserAccountPrompt + " "); string strUA = Console.ReadLine().Trim(); if (strUA != null) { string strUal = strUA.ToLower(); if ((strUal == "y") || (strUal == "j") || (strUal == "o") || (strUal == "a") || (strUal == "u")) { cmpKey.AddUserKey(new KcpUserAccount()); } } } else { cmpKey = KeyFromCmdLine(args); } PwDatabase pwDb = new PwDatabase(); pwDb.Open(ioc, cmpKey, null); bool bNeedsSave; RunFileCommand(strCommand.ToLower(), args, pwDb, out bNeedsSave); if (bNeedsSave) { pwDb.Save(null); } pwDb.Close(); }
/// <summary> /// Opens the given database using the provided password, and the optional keyfile /// </summary> /// <param name="databaseFile"></param> /// <param name="password"></param> /// <param name="keyFile"></param> /// <returns></returns> private async Task openDatabaseAsync(StorageFile databaseFile, PasswordParameter password) { try { using (var stream = await databaseFile.OpenReadAsync()) { // Build up the database var db = new PwDatabase(); var key = new CompositeKey(); if (!String.IsNullOrEmpty(password.Password)) { // Add the password key.AddUserKey(new KcpPassword(password.Password)); } if (password.KeyFile != null) { var keyFileStream = await password.KeyFile.OpenReadAsync(); if (keyFileStream != null) { key.AddUserKey(new KcpKeyFile(keyFileStream.AsStreamForRead())); } } var cancelToken = new CancellationTokenSource(); db.Open(stream.GetInputStreamAt(0).AsStreamForRead(), key, null, cancelToken.Token); // Now iterate all groups entries to create the ViewModel counterpart if (db.RootGroup != null) { if (SettingsViewModel.Instance.ViewCollectionAsTree) { _groups.Add(new PwGroupViewModel(db.RootGroup, true)); } else { _groups.Add(new PwGroupViewModel(db.RootGroup)); foreach (var group in db.RootGroup.GetGroups(false)) { _groups.Add(new PwGroupViewModel(group, true)); } } } if (SettingsViewModel.Instance.ViewCollectionAsTree) { // Create the hierarchical group foreach (var groupVM in _groups) { addHierachicalGroup(groupVM, 0); } if (_groups.Count > 0) { CurrentGroup = _groups.FirstOrDefault(); } } if (SettingsViewModel.Instance.SortingEnabled) { // Sort groups by name _groups = new ObservableCollection <PwGroupViewModel>(_groups.OrderBy(g => g.Name)); } // Initialize the filtered list instances UpdateFilterededEntries(String.Empty); db.Close(); } } catch (InvalidCompositeKeyException) { throw; } catch (Exception) { throw; } }
public void Dispose() { _db.Close(); }
private void OnClickFindEntry(object sender, EventArgs e) { string f = (sender as ToolStripItem).Name; FindInfo fi = SearchHelp.FindList.Find(x => x.Name == (sender as ToolStripItem).Name); if (CallStandardSearch(fi, (sender as ToolStripItem).Name)) { if (fi != null) { foreach (Delegate d in fi.StandardEventHandlers) { d.DynamicInvoke(new object[] { sender, e }); } } return; } PluginDebug.AddInfo("Call own find routine", 0, "Action: " + f); //Show status logger Form fOptDialog = null; IStatusLogger sl = StatusUtil.CreateStatusDialog(m_host.MainWindow, out fOptDialog, null, (KPRes.SearchingOp ?? "..."), true, false); m_host.MainWindow.UIBlockInteraction(true); m_aStandardLvInit = null; //Perform find for all open databases PwDatabase dbAll = MergeDatabases(); List <object> l = null; try { object[] parameters; if (fi.SearchType != SearchType.BuiltIn) { parameters = new object[] { dbAll, sl, null, fi } } ; else { parameters = new object[] { dbAll, sl, null } }; l = (List <object>)fi.StandardMethod.Invoke(m_host, parameters); m_aStandardLvInit = (Action <ListView>)parameters[2]; } catch (Exception ex) { l = null; PluginDebug.AddError("Call standard find routine", 0, "Action: " + f, "Reason for standard call: " + ex.Message); foreach (Delegate d in fi.StandardEventHandlers) { d.DynamicInvoke(new object[] { sender, e }); } } finally { dbAll.Close(); } m_host.MainWindow.UIBlockInteraction(false); sl.EndLogging(); if (l == null) { return; } //Fill db column ImageList il = new ImageList(); ImageList il2 = (ImageList)Tools.GetField("m_ilCurrentIcons", m_host.MainWindow); foreach (Image img in il2.Images) { il.Images.Add(img); } foreach (var o in l) { ListViewItem lvi = o as ListViewItem; if (lvi == null) { continue; } ListViewItem.ListViewSubItem lvsi = new ListViewItem.ListViewSubItem(); if (lvi.Tag is PwEntry) { lvsi.Text = SearchHelp.GetDBName(lvi.Tag as PwEntry); PwEntry pe = lvi.Tag as PwEntry; PwDatabase db = m_host.MainWindow.DocumentManager.FindContainerOf(pe); if (!pe.CustomIconUuid.Equals(PwUuid.Zero)) { il.Images.Add(db.GetCustomIcon(pe.CustomIconUuid, DpiUtil.ScaleIntX(16), DpiUtil.ScaleIntY(16))); lvi.ImageIndex = il.Images.Count - 1; } else { lvi.ImageIndex = (int)pe.IconId; } } else if (lvi.Tag is PwGroup) { PwGroup pg = lvi.Tag as PwGroup; lvsi.Text = SearchHelp.GetDBName(pg.Entries.GetAt(0)); } lvi.SubItems.Insert(0, lvsi); } if ((l.Count == 0) && !string.IsNullOrEmpty(fi.NothingFound)) { Tools.ShowInfo(fi.NothingFound); il.Dispose(); return; } //Show results ListViewForm dlg = new ListViewForm(); //Prepare ImageList (CustomIcons can be different per database) dlg.InitEx(fi.Title, fi.SubTitle, fi.Note, fi.img, l, il, InitListView); UIUtil.ShowDialogAndDestroy(dlg); if (dlg.DialogResult != DialogResult.OK) { return; } il.Dispose(); NavigateToSelectedEntry(dlg, false); }
private static IDictionary <string, ProtectedString> OpenKeePassDB(SecureString Password) { PwDatabase PwDB = new PwDatabase(); IOConnectionInfo mioInfo = new IOConnectionInfo { Path = pathToKeePassDb }; CompositeKey compositeKey = new CompositeKey(); compositeKey.AddUserKey(new KcpPassword(Marshal.PtrToStringAuto(Marshal.SecureStringToBSTR(Password)))); IStatusLogger statusLogger = new NullStatusLogger(); Dictionary <string, ProtectedString> dict = new Dictionary <string, ProtectedString>(); try { PwDB.Open(mioInfo, compositeKey, statusLogger); PwObjectList <PwGroup> groups = PwDB.RootGroup.GetGroups(true); if (workingMode == WorkingModes.Prepare) { // Check whether the requested group already exists if (!groups.Any(x => x.Name.Equals(groupName))) { PwDB.RootGroup.AddGroup(new PwGroup() { Name = groupName }, true); Trace.TraceInformation($"The Group {groupName} has been added to KeePass DB"); } PwGroup grp = PwDB.RootGroup.GetGroups(true).Where(x => x.Name.Equals(groupName)).First(); // Check if the required entry doesn't exist in the group if (!grp.GetEntries(false).Any(x => x.Strings.ReadSafe("Title").Equals(entryName))) { //Need to have a local variable for Protected dic //otherwise the clause becomes too complecated for reading ProtectedStringDictionary d = new ProtectedStringDictionary(); d.Set("Title", new ProtectedString(true, entryName)); #pragma warning disable CS0618 // Type or member is obsolete //They tell it is obsolete and recommend to use any other constructor, //but, actually, there's no other to be used. grp.AddEntry(new PwEntry(grp, true, true) { Strings = d }, true); #pragma warning restore CS0618 // Type or member is obsolete Trace.TraceInformation($"The Entry {entryName} has been added to KeePass DB"); } PwEntry ent = grp.GetEntries(false).Where(x => x.Strings.ReadSafe("Title").Equals(entryName)).First(); //Create a value for password ProtectedString aesPwd = new ProtectedString(); PwGenerator.Generate(out aesPwd, new PwProfile() { Length = 16, CharSet = new PwCharSet(PwCharSet.LowerCase + PwCharSet.UpperCase + PwCharSet.Digits + PwCharSet.PrintableAsciiSpecial) }, UTF8Encoding.UTF8.GetBytes(RndString.GetRandomString(16)), new CustomPwGeneratorPool()); //Create a vlaue for Salt ProtectedString salt = new ProtectedString(); PwGenerator.Generate(out salt, new PwProfile() { Length = 26, CharSet = new PwCharSet(PwCharSet.LowerCase + PwCharSet.UpperCase + PwCharSet.Digits + PwCharSet.PrintableAsciiSpecial) }, UTF8Encoding.UTF8.GetBytes(RndString.GetRandomString(28)), new CustomPwGeneratorPool()); ent.Strings.Set("AESpassword", new ProtectedString(true, aesPwd.ReadString())); Trace.TraceInformation($"The value of the AESPass in the Entry {entryName} has been added to KeePass DB"); ent.Strings.Set("Salt", new ProtectedString(true, salt.ReadString())); Trace.TraceInformation($"The value of the Salt in the Entry {entryName} has been added to KeePass DB"); // Create IV SymmetricAlgorithm cipher = SymmetricAlgorithm.Create("AesManaged"); cipher.Mode = CipherMode.CBC; cipher.Padding = PaddingMode.PKCS7; ent.Strings.Set("IV", new ProtectedString(true, Convert.ToBase64String(cipher.IV))); Trace.TraceInformation($"The value of the IV in the Entry {entryName} has been added to KeePass DB"); PwDB.Save(statusLogger); // Add dummy values to the dictionary to pass the check in the end of the method dict.Add("Salt", new ProtectedString(true, ent.Strings.ReadSafe("Salt"))); dict.Add("Password", new ProtectedString(true, "dummy")); dict.Add("AESPass", new ProtectedString(true, ent.Strings.ReadSafe("AESpassword"))); dict.Add("UserName", new ProtectedString(true, "dummy")); dict.Add("IV", new ProtectedString(true, ent.Strings.ReadSafe("IV"))); dict.Add("SecurityToken", new ProtectedString(true, "dummy")); } else { foreach (PwGroup grp in groups) { if (grp.Name.Equals(groupName)) { PwObjectList <PwEntry> entries = grp.GetEntries(false); foreach (PwEntry ent in entries) { if (ent.Strings.ReadSafe("Title").Equals(entryName)) { dict.Add("Salt", new ProtectedString(true, ent.Strings.ReadSafe("Salt"))); dict.Add("Password", new ProtectedString(true, ent.Strings.ReadSafe("Password"))); dict.Add("AESPass", new ProtectedString(true, ent.Strings.ReadSafe("AESpassword"))); dict.Add("UserName", new ProtectedString(true, ent.Strings.ReadSafe("UserName"))); dict.Add("IV", new ProtectedString(true, ent.Strings.ReadSafe("IV"))); dict.Add("SecurityToken", new ProtectedString(true, ent.Strings.ReadSafe("SecurityToken"))); } } } } } } catch (Exception ex) { Trace.TraceError($"Failed to open KeePassDb \n{ex.Message}"); } finally { PwDB.Close(); } //Delete key-value pairs where values are empty dict.Where(d => d.Value.IsEmpty).ToList().ForEach(t => dict.Remove(t.Key)); return(dict); }
public void CloseDatabase() { _pwDatabase?.Close(); }
public void ShouldOnlyExportToCurrentSharedUsers() { m_treeManager.Initialize(m_database); var exportPath = GetTestPath(); m_syncManager.AddExportPath(exportPath); var exportGroup = m_database.GetExportGroup().Groups.GetAt(0); m_treeManager.CreateNewUser("Adam"); m_treeManager.CreateNewUser("Eva"); var userAdam = TestHelper.GetUserRootNodeByNameFor(m_database, "Adam"); var userEva = TestHelper.GetUserRootNodeByNameFor(m_database, "Eva"); userAdam.SetPassword(STANDARD_PASSWORD); userEva.SetPassword(STANDARD_PASSWORD); m_database.RootGroup.AddEntry(userAdam.CreateProxyNode(), true); m_database.RootGroup.AddEntry(userEva.CreateProxyNode(), true); exportGroup.AddEntry(userAdam.CreateProxyNode(), true); exportGroup.AddEntry(userEva.CreateProxyNode(), true); m_treeManager.CorrectStructure(); string exportFileAdam = exportPath + SyncSource.FileNameFor(userAdam) + SyncExporter.FileExtension; string exportFileEva = exportPath + SyncSource.FileNameFor(userEva) + SyncExporter.FileExtension; Assert.IsFalse(File.Exists(exportFileAdam)); Assert.IsFalse(File.Exists(exportFileEva)); m_syncManager.Export(); // TODO CK: At this point it may be possible that the files are not created - we need to wait for the filesystem to respond - maybe using a delay? Assert.IsTrue(File.Exists(exportFileAdam)); Assert.IsTrue(File.Exists(exportFileEva)); var homeAdam = TestHelper.GetUserHomeNodeByNameFor(m_database, "Adam"); homeAdam.ParentGroup.Groups.Remove(homeAdam); var trash = m_database.RootGroup.FindGroup(m_database.RecycleBinUuid, true); trash.AddGroup(homeAdam, true); trash.DeleteAllObjects(m_database); //update should delete all references to the non existing user m_treeManager.CorrectStructure(); var changedEntry = m_database.RootGroup.Entries.GetAt(0); changedEntry.SetTitle("Changed"); TestHelper.SimulateTouch(changedEntry); m_syncManager.Export(); TestHelper.DelayAction(); var deltaDBAdamReexport = new PwDatabase(); deltaDBAdamReexport.Open(IOConnectionInfo.FromPath(exportFileAdam), m_standardKey, null); Assert.AreEqual(Uuid1, deltaDBAdamReexport.RootGroup.Entries.GetAt(0).Uuid); Assert.AreNotEqual("Changed", deltaDBAdamReexport.RootGroup.Entries.GetAt(0).GetTitle()); deltaDBAdamReexport.Close(); var deltaDBEvaReexport = new PwDatabase(); deltaDBEvaReexport.Open(IOConnectionInfo.FromPath(exportFileEva), m_standardKey, null); Assert.AreEqual(Uuid1, deltaDBEvaReexport.RootGroup.Entries.GetAt(0).Uuid); Assert.AreEqual("Changed", deltaDBEvaReexport.RootGroup.Entries.GetAt(0).GetTitle()); deltaDBEvaReexport.Close(); }