allow opening several databases which contain elements with same IDs (required as KeepassHttp stores their settings in an entry with a fixed ID)
This commit is contained in:
@@ -87,8 +87,9 @@ namespace keepass2android
|
||||
_app.DirtyGroups.Add(parent);
|
||||
|
||||
// Add entry to global
|
||||
_db.Entries[_entry.Uuid] = _entry;
|
||||
|
||||
_db.EntriesById[_entry.Uuid] = _entry;
|
||||
_db.Elements.Add(_entry);
|
||||
|
||||
} else
|
||||
{
|
||||
StatusLogger.UpdateMessage(UiStringKey.UndoingChanges);
|
||||
|
||||
@@ -70,9 +70,11 @@ namespace keepass2android
|
||||
Group.CustomIconUuid = _groupCustomIconId;
|
||||
}
|
||||
Parent.AddGroup(Group, true);
|
||||
_app.CurrentDb.GroupsById[Group.Uuid] = Group;
|
||||
_app.CurrentDb.Elements.Add(Group);
|
||||
|
||||
// Commit to disk
|
||||
SaveDb save = new SaveDb(_ctx, _app, _app.CurrentDb, OnFinishToRun, DontSave);
|
||||
// Commit to disk
|
||||
SaveDb save = new SaveDb(_ctx, _app, _app.CurrentDb, OnFinishToRun, DontSave);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
}
|
||||
@@ -92,10 +94,12 @@ namespace keepass2android
|
||||
_addGroup.App.DirtyGroups.Add(_addGroup.Parent);
|
||||
|
||||
// Add group to global list
|
||||
_addGroup.Db.Groups[_addGroup.Group.Uuid] = _addGroup.Group;
|
||||
_addGroup.Db.GroupsById[_addGroup.Group.Uuid] = _addGroup.Group;
|
||||
_addGroup.Db.Elements.Add(_addGroup.Group);
|
||||
} else {
|
||||
StatusLogger.UpdateMessage(UiStringKey.UndoingChanges);
|
||||
_addGroup.Parent.Groups.Remove(_addGroup.Group);
|
||||
|
||||
}
|
||||
|
||||
base.Run();
|
||||
|
||||
@@ -292,7 +292,7 @@ namespace keepass2android
|
||||
{
|
||||
string hexId = t.Uuid.ToHexString();
|
||||
|
||||
return db.Entries.Any(kvp => kvp.Key.Equals(t.Uuid) ||
|
||||
return db.EntriesById.Any(kvp => kvp.Key.Equals(t.Uuid) ||
|
||||
kvp.Value.Strings.ReadSafe(TemplateIdStringKey) == hexId);
|
||||
});
|
||||
}
|
||||
@@ -327,7 +327,7 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
PwGroup templateGroup;
|
||||
if (!_app.CurrentDb.Groups.TryGetValue(_app.CurrentDb.KpDatabase.EntryTemplatesGroup, out templateGroup))
|
||||
if (!_app.CurrentDb.GroupsById.TryGetValue(_app.CurrentDb.KpDatabase.EntryTemplatesGroup, out templateGroup))
|
||||
{
|
||||
//create template group
|
||||
templateGroup = new PwGroup(true, true, _app.GetResourceString(UiStringKey.TemplateGroupName), PwIcon.Folder);
|
||||
@@ -335,30 +335,31 @@ namespace keepass2android
|
||||
_app.CurrentDb.KpDatabase.EntryTemplatesGroup = templateGroup.Uuid;
|
||||
_app.CurrentDb.KpDatabase.EntryTemplatesGroupChanged = DateTime.Now;
|
||||
_app.DirtyGroups.Add(_app.CurrentDb.KpDatabase.RootGroup);
|
||||
_app.CurrentDb.Groups[templateGroup.Uuid] = templateGroup;
|
||||
_app.CurrentDb.GroupsById[templateGroup.Uuid] = templateGroup;
|
||||
_app.CurrentDb.Elements.Add(templateGroup);
|
||||
|
||||
}
|
||||
addedEntries = new List<PwEntry>();
|
||||
|
||||
foreach (var template in TemplateEntries)
|
||||
{
|
||||
if (_app.CurrentDb.Entries.ContainsKey(template.Uuid))
|
||||
if (_app.CurrentDb.EntriesById.ContainsKey(template.Uuid))
|
||||
continue;
|
||||
PwEntry entry = CreateEntry(template);
|
||||
templateGroup.AddEntry(entry, true);
|
||||
addedEntries.Add(entry);
|
||||
_app.CurrentDb.Entries[entry.Uuid] = entry;
|
||||
_app.CurrentDb.EntriesById[entry.Uuid] = entry;
|
||||
}
|
||||
return templateGroup;
|
||||
}
|
||||
|
||||
private PwEntry CreateEntry(TemplateEntry template)
|
||||
{
|
||||
PwEntry entry = new PwEntry(true, true);
|
||||
|
||||
PwEntry entry = new PwEntry(false, true);
|
||||
entry.Uuid = template.Uuid;
|
||||
entry.IconId = template.Icon;
|
||||
entry.Strings.Set(PwDefs.TitleField, new ProtectedString(false, _app.GetResourceString(template.Title)));
|
||||
entry.Strings.Set("_etm_template", new ProtectedString(false, "1"));
|
||||
entry.Strings.Set(TemplateIdStringKey, new ProtectedString(false, template.Uuid.ToHexString()));
|
||||
int position = 0;
|
||||
foreach (var field in template.Fields)
|
||||
{
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Security;
|
||||
|
||||
namespace keepass2android.database.edit
|
||||
{
|
||||
public class ChangeTemplateIds: RunnableOnFinish
|
||||
{
|
||||
private readonly IKp2aApp _app;
|
||||
private readonly Database _db;
|
||||
private string _etmTemplateUuid { get { return "_etm_template_uuid"; } }
|
||||
public static string TemplateIdStringKey
|
||||
{
|
||||
get { return "KP2A_TemplateId"; }
|
||||
}
|
||||
|
||||
public ChangeTemplateIds(Activity activeActivity, IKp2aApp app, Database db, OnFinish finish) : base(activeActivity, finish)
|
||||
{
|
||||
_app = app;
|
||||
_db = db;
|
||||
}
|
||||
|
||||
public override void Run()
|
||||
{
|
||||
StatusLogger.UpdateMessage(UiStringKey.UpdatingTemplateIds);
|
||||
Dictionary<string, string> uuidMap = new Dictionary<string, string>();
|
||||
foreach (var templateEntry in AddTemplateEntries.TemplateEntries)
|
||||
{
|
||||
PwEntry entry;
|
||||
if (_db.Entries.TryGetValue(templateEntry.Uuid, out entry))
|
||||
{
|
||||
PwUuid oldUuid = entry.Uuid;
|
||||
entry.Uuid = new PwUuid(true);
|
||||
uuidMap[oldUuid.ToHexString()] = entry.Uuid.ToHexString();
|
||||
entry.Strings.Set(TemplateIdStringKey,new ProtectedString(false, oldUuid.ToHexString()));
|
||||
_db.Entries.Remove(oldUuid);
|
||||
_db.Entries[entry.Uuid] = entry;
|
||||
}
|
||||
}
|
||||
foreach (var entry in _db.Entries.Values)
|
||||
{
|
||||
string templateUuid = entry.Strings.ReadSafe(_etmTemplateUuid);
|
||||
if (templateUuid != null)
|
||||
{
|
||||
string newTemplateUuid;
|
||||
if (uuidMap.TryGetValue(templateUuid, out newTemplateUuid))
|
||||
{
|
||||
entry.Strings.Set(_etmTemplateUuid, new ProtectedString(false, newTemplateUuid));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uuidMap.Any())
|
||||
{
|
||||
SaveDb save = new SaveDb( ActiveActivity, _app, _db, OnFinishToRun);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
}
|
||||
else
|
||||
{
|
||||
OnFinishToRun?.Run();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ namespace keepass2android
|
||||
|
||||
public DeleteEntry(Activity activiy, IKp2aApp app, PwEntry entry, OnFinish finish):base(activiy, finish, app) {
|
||||
Ctx = activiy;
|
||||
Db = app.FindDatabaseForEntryId(entry.Uuid);
|
||||
Db = app.FindDatabaseForElement(entry);
|
||||
_entry = entry;
|
||||
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace keepass2android
|
||||
*/
|
||||
private void SetMembers(Activity activity, IKp2aApp app, PwGroup group, bool dontSave)
|
||||
{
|
||||
base.SetMembers(activity, app.FindDatabaseForGroupId(group.Uuid));
|
||||
base.SetMembers(activity, app.FindDatabaseForElement(group));
|
||||
|
||||
_group = group;
|
||||
DontSave = dontSave;
|
||||
|
||||
@@ -100,7 +100,8 @@ namespace keepass2android
|
||||
};
|
||||
|
||||
Db.KpDatabase.RootGroup.AddGroup(pgRecycleBin, true);
|
||||
Db.Groups[pgRecycleBin.Uuid] = pgRecycleBin;
|
||||
Db.GroupsById[pgRecycleBin.Uuid] = pgRecycleBin;
|
||||
Db.Elements.Add(pgRecycleBin);
|
||||
Db.KpDatabase.RecycleBinUuid = pgRecycleBin.Uuid;
|
||||
|
||||
bGroupListUpdateRequired = true;
|
||||
@@ -185,7 +186,8 @@ namespace keepass2android
|
||||
PwDeletedObject pdo = new PwDeletedObject(pe.Uuid, dtNow);
|
||||
pd.DeletedObjects.Add(pdo);
|
||||
touchedGroups.Add(pgParent);
|
||||
Db.Entries.Remove(pe.Uuid);
|
||||
Db.EntriesById.Remove(pe.Uuid);
|
||||
Db.Elements.Remove(pe);
|
||||
}
|
||||
else // Recycle
|
||||
{
|
||||
@@ -223,7 +225,9 @@ namespace keepass2android
|
||||
{
|
||||
//remove groups from global lists if present there
|
||||
App.DirtyGroups.Remove(g);
|
||||
Db.Groups.Remove(g.Uuid);
|
||||
Db.GroupsById.Remove(g.Uuid);
|
||||
Db.Elements.Remove(g);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace keepass2android
|
||||
public class EditGroup : RunnableOnFinish {
|
||||
internal Database Db
|
||||
{
|
||||
get { return _app.FindDatabaseForGroupId(Group.Uuid); }
|
||||
get { return _app.FindDatabaseForElement(Group); }
|
||||
}
|
||||
|
||||
public IKp2aApp App { get => _app; }
|
||||
|
||||
@@ -151,76 +151,7 @@ namespace keepass2android
|
||||
Thread.Sleep(10);
|
||||
SaveFileData(_ioc, _keyfileOrProvider);
|
||||
|
||||
|
||||
bool hasLegacyTemplateIds = false;
|
||||
//make sure we never have entries with same Uuids
|
||||
foreach (var entryKey in newDb.Entries.Keys)
|
||||
{
|
||||
foreach (Database otherDb in _app.OpenDatabases)
|
||||
{
|
||||
if (otherDb == newDb)
|
||||
continue;
|
||||
if (otherDb.Entries.ContainsKey(entryKey))
|
||||
{
|
||||
if (AddTemplateEntries.IsTemplateId(entryKey))
|
||||
{
|
||||
hasLegacyTemplateIds = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_app.CloseDatabase(newDb);
|
||||
throw new Exception("Database contains entry id " + entryKey.ToHexString() + "(" +
|
||||
newDb.Entries[entryKey].Strings.ReadSafe(PwDefs.TitleField)
|
||||
+ ") which is already contained in " +
|
||||
_app.GetFileStorage(otherDb.Ioc).GetDisplayName(otherDb.Ioc) +
|
||||
"! Please close the other database before opening this one.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach (var groupKey in newDb.Groups.Keys)
|
||||
{
|
||||
foreach (Database otherDb in _app.OpenDatabases)
|
||||
{
|
||||
if (otherDb == newDb)
|
||||
continue;
|
||||
if (otherDb.Groups.ContainsKey(groupKey))
|
||||
{
|
||||
throw new Exception("Database contains group id " + groupKey.ToHexString() + "(" +
|
||||
newDb.Groups[groupKey].Name + ") which is already contained in " +
|
||||
_app.GetFileStorage(otherDb.Ioc).GetDisplayName(otherDb.Ioc) +
|
||||
"! Please close the other database before opening this one.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasLegacyTemplateIds)
|
||||
{
|
||||
_app.AskYesNoCancel(UiStringKey.ChangleLegacyTemplateIds_Title, UiStringKey.ChangleLegacyTemplateIds_Message,UiStringKey.Ok, UiStringKey.cancel,
|
||||
/*yes*/
|
||||
(sender, args) =>
|
||||
{
|
||||
ChangeTemplateIds cti = new ChangeTemplateIds(ActiveActivity, _app, newDb, new ActionOnFinish(ActiveActivity, (b, message, activity) => Finish(b, message)));
|
||||
cti.Run();
|
||||
},
|
||||
/*no*/
|
||||
(sender, args) =>
|
||||
{
|
||||
_app.CloseDatabase(newDb);
|
||||
Finish(false);
|
||||
},
|
||||
null,
|
||||
ActiveActivity
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
Finish(true, _format.SuccessMessage);
|
||||
Finish(true, _format.SuccessMessage);
|
||||
return newDb;
|
||||
}
|
||||
catch (OldFormatException)
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace keepass2android.database.edit
|
||||
}
|
||||
|
||||
HashSet<Database> removeDatabases = new HashSet<Database>();
|
||||
Database addDatabase = _app.FindDatabaseForGroupId(_targetGroup.Uuid);
|
||||
Database addDatabase = _app.FindDatabaseForElement(_targetGroup);
|
||||
if (addDatabase == null)
|
||||
{
|
||||
Finish(false, "Did not find target database. Did you lock it?");
|
||||
@@ -73,12 +73,14 @@ namespace keepass2android.database.edit
|
||||
PwEntry entry = elementToMove as PwEntry;
|
||||
if (entry != null)
|
||||
{
|
||||
var dbRem = _app.FindDatabaseForEntryId(entry.Uuid);
|
||||
var dbRem = _app.FindDatabaseForElement(entry);
|
||||
removeDatabases.Add(dbRem);
|
||||
dbRem.Entries.Remove(entry.Uuid);
|
||||
dbRem.EntriesById.Remove(entry.Uuid);
|
||||
dbRem.Elements.Remove(entry);
|
||||
pgParent.Entries.Remove(entry);
|
||||
_targetGroup.AddEntry(entry, true, true);
|
||||
addDatabase.Entries.Add(entry.Uuid, entry);
|
||||
addDatabase.EntriesById.Add(entry.Uuid, entry);
|
||||
addDatabase.Elements.Add(entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -89,18 +91,20 @@ namespace keepass2android.database.edit
|
||||
return;
|
||||
}
|
||||
|
||||
var dbRem = _app.FindDatabaseForEntryId(@group.Uuid);
|
||||
var dbRem = _app.FindDatabaseForElement(@group);
|
||||
if (dbRem == null)
|
||||
{
|
||||
Finish(false, "Did not find source database. Did you lock it?");
|
||||
return;
|
||||
}
|
||||
|
||||
dbRem.Groups.Remove(group.Uuid);
|
||||
dbRem.GroupsById.Remove(group.Uuid);
|
||||
dbRem.Elements.Remove(group);
|
||||
removeDatabases.Add(dbRem);
|
||||
pgParent.Groups.Remove(group);
|
||||
_targetGroup.AddGroup(group, true, true);
|
||||
addDatabase.Groups.Add(group.Uuid, group);
|
||||
addDatabase.GroupsById.Add(group.Uuid, group);
|
||||
addDatabase.Elements.Add(group);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,6 +139,7 @@ namespace keepass2android
|
||||
//small.
|
||||
MergeIn(fileStorage, ioc);
|
||||
PerformSaveWithoutCheck(fileStorage, ioc);
|
||||
_db.UpdateGlobals();
|
||||
Finish(true);
|
||||
};
|
||||
RunInWorkerThread(runHandler);
|
||||
|
||||
Reference in New Issue
Block a user