Splitted keepass2android project into

- keepass2android: UI stuff only
 - Kp2aBusinessLogic: Password-Database related algorithms (even though tied to android, no UI required here)

Removed dependencies of logic layer to static Application, Resource class or other UI stuff
Added MonoDroidUnitTesting (not yet used, will be used for testing logic layer)
This commit is contained in:
Philipp Crocoll
2013-06-14 06:14:50 +02:00
parent 9d8e10b236
commit 26575c4ba4
102 changed files with 5623 additions and 1184 deletions

View File

@@ -0,0 +1,67 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
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;
namespace keepass2android
{
public class ActionOnFinish: OnFinish
{
public delegate void ActionToPerformOnFinsh(bool success, String message);
ActionToPerformOnFinsh actionToPerform;
public ActionOnFinish(ActionToPerformOnFinsh actionToPerform) : base(null, null)
{
this.actionToPerform = actionToPerform;
}
public ActionOnFinish(ActionToPerformOnFinsh actionToPerform, OnFinish finish) : base(finish)
{
this.actionToPerform = actionToPerform;
}
public ActionOnFinish(ActionToPerformOnFinsh actionToPerform, Handler handler) : base(handler)
{
this.actionToPerform = actionToPerform;
}
public override void run()
{
if (this.mMessage == null)
this.mMessage = "";
if (this.mHandler != null)
{
this.mHandler.Post(() => {actionToPerform(this.mSuccess, this.mMessage);});
}
else
actionToPerform(this.mSuccess, this.mMessage);
base.run();
}
}
}

View File

@@ -0,0 +1,98 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
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;
namespace keepass2android
{
public class AddEntry : RunnableOnFinish {
protected Database mDb;
private PwEntry mEntry;
private PwGroup mParentGroup;
private Context mCtx;
public static AddEntry getInstance(Context ctx, Database db, PwEntry entry, PwGroup parentGroup, OnFinish finish) {
return new AddEntry(ctx, db, entry, parentGroup, finish);
}
protected AddEntry(Context ctx, Database db, PwEntry entry, PwGroup parentGroup, OnFinish finish):base(finish) {
mCtx = ctx;
mParentGroup = parentGroup;
mDb = db;
mEntry = entry;
mFinish = new AfterAdd(db, entry, mFinish);
}
public override void run() {
mParentGroup.AddEntry(mEntry, true);
// Commit to disk
SaveDB save = new SaveDB(mCtx, mDb, mFinish);
save.run();
}
private class AfterAdd : OnFinish {
protected Database mDb;
private PwEntry mEntry;
public AfterAdd(Database db, PwEntry entry, OnFinish finish):base(finish) {
mDb = db;
mEntry = entry;
}
public override void run() {
if ( mSuccess ) {
PwGroup parent = mEntry.ParentGroup;
// Mark parent group dirty
mDb.dirty.Add(parent);
// Add entry to global
mDb.entries[mEntry.Uuid] = mEntry;
} else {
//TODO test fail
mEntry.ParentGroup.Entries.Remove(mEntry);
}
base.run();
}
}
}
}

View File

@@ -0,0 +1,103 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
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;
namespace keepass2android
{
public class AddGroup : RunnableOnFinish {
internal Database mDb;
private String mName;
private int mIconID;
internal PwGroup mGroup;
internal PwGroup mParent;
protected bool mDontSave;
Context mCtx;
public static AddGroup getInstance(Context ctx, Database db, String name, int iconid, PwGroup parent, OnFinish finish, bool dontSave) {
return new AddGroup(ctx, db, name, iconid, parent, finish, dontSave);
}
private AddGroup(Context ctx, Database db, String name, int iconid, PwGroup parent, OnFinish finish, bool dontSave): base(finish) {
mCtx = ctx;
mDb = db;
mName = name;
mIconID = iconid;
mParent = parent;
mDontSave = dontSave;
mFinish = new AfterAdd(this, mFinish);
}
public override void run() {
PwDatabase pm = mDb.pm;
// Generate new group
mGroup = new PwGroup(true, true, mName, (PwIcon)mIconID);
mParent.AddGroup(mGroup, true);
// Commit to disk
SaveDB save = new SaveDB(mCtx, mDb, mFinish, mDontSave);
save.run();
}
private class AfterAdd : OnFinish {
AddGroup addGroup;
public AfterAdd(AddGroup addGroup,OnFinish finish): base(finish) {
this.addGroup = addGroup;
}
public override void run() {
if ( mSuccess ) {
// Mark parent group dirty
addGroup.mDb.dirty.Add(addGroup.mParent);
// Add group to global list
addGroup.mDb.groups[addGroup.mGroup.Uuid] = addGroup.mGroup;
} else {
addGroup.mParent.Groups.Remove(addGroup.mGroup);
}
base.run();
}
}
}
}

View File

@@ -0,0 +1,88 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
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.Serialization;
using KeePassLib.Keys;
namespace keepass2android
{
public class CreateDB : RunnableOnFinish {
private const int DEFAULT_ENCRYPTION_ROUNDS = 1000;
private IOConnectionInfo mIoc;
private bool mDontSave;
private Context mCtx;
private IKp2aApp mApp;
public CreateDB(IKp2aApp app, Context ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave): base(finish) {
mCtx = ctx;
mIoc = ioc;
mDontSave = dontSave;
mApp = app;
}
public override void run() {
Database db = mApp.CreateNewDatabase();
db.pm = new KeePassLib.PwDatabase();
//Key will be changed/created immediately after creation:
CompositeKey tempKey = new CompositeKey();
db.pm.New(mIoc, tempKey);
db.pm.KeyEncryptionRounds = DEFAULT_ENCRYPTION_ROUNDS;
db.pm.Name = "Keepass2Android Password Database";
// Set Database state
db.root = db.pm.RootGroup;
db.mIoc = mIoc;
db.Loaded = true;
db.searchHelper = new SearchDbHelper(mApp);
// Add a couple default groups
AddGroup internet = AddGroup.getInstance(mCtx, db, "Internet", 1, db.pm.RootGroup, null, true);
internet.run();
AddGroup email = AddGroup.getInstance(mCtx, db, "eMail", 19, db.pm.RootGroup, null, true);
email.run();
// Commit changes
SaveDB save = new SaveDB(mCtx, db, mFinish, mDontSave);
mFinish = null;
save.run();
}
}
}

View File

@@ -0,0 +1,129 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
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;
namespace keepass2android
{
public class DeleteEntry : DeleteRunnable {
private PwEntry mEntry;
public DeleteEntry(Context ctx, IKp2aApp app, PwEntry entry, OnFinish finish):base(finish, app) {
mCtx = ctx;
mDb = app.GetDb();
mEntry = entry;
}
public override bool CanRecycle
{
get
{
return CanRecycleGroup(mEntry.ParentGroup);
}
}
protected override UiStringKey QuestionsResourceId
{
get
{
return UiStringKey.AskDeletePermanentlyEntry;
}
}
public override void run() {
PwDatabase pd = mDb.pm;
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
bool bUpdateGroupList = false;
DateTime dtNow = DateTime.Now;
PwEntry pe = mEntry;
PwGroup pgParent = pe.ParentGroup;
if(pgParent != null)
{
pgParent.Entries.Remove(pe);
if ((DeletePermanently) || (!CanRecycle))
{
PwDeletedObject pdo = new PwDeletedObject(pe.Uuid, dtNow);
pd.DeletedObjects.Add(pdo);
mFinish = new ActionOnFinish( (success, message) =>
{
if ( success ) {
// Mark parent dirty
if ( pgParent != null ) {
mDb.dirty.Add(pgParent);
}
} else {
// Let's not bother recovering from a failure to save a deleted entry. It is too much work.
mApp.SetShutdown();
}
}, this.mFinish);
}
else // Recycle
{
EnsureRecycleBin(ref pgRecycleBin, ref bUpdateGroupList);
pgRecycleBin.AddEntry(pe, true, true);
pe.Touch(false);
mFinish = new ActionOnFinish( (success, message) =>
{
if ( success ) {
// Mark previous parent dirty
if ( pgParent != null ) {
mDb.dirty.Add(pgParent);
}
// Mark new parent dirty
mDb.dirty.Add(pgRecycleBin);
} else {
// Let's not bother recovering from a failure to save a deleted entry. It is too much work.
mApp.SetShutdown();
}
}, this.mFinish);
}
}
// Commit database
SaveDB save = new SaveDB(mCtx, mDb, mFinish, false);
save.run();
}
}
}

View File

@@ -0,0 +1,169 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
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;
namespace keepass2android
{
public class DeleteGroup : DeleteRunnable {
private PwGroup mGroup;
private Activity mAct;
protected bool mDontSave;
public DeleteGroup(Context ctx, IKp2aApp app, PwGroup group, Activity act, OnFinish finish)
: base(finish, app)
{
setMembers(ctx, app, group, act, false);
}
/*
public DeleteGroup(Context ctx, Database db, PwGroup group, Activity act, OnFinish finish, bool dontSave)
: base(finish)
{
setMembers(ctx, db, group, act, dontSave);
}
public DeleteGroup(Context ctx, Database db, PwGroup group, OnFinish finish, bool dontSave):base(finish) {
setMembers(ctx, db, group, null, dontSave);
}
*/
private void setMembers(Context ctx, IKp2aApp app, PwGroup group, Activity act, bool dontSave)
{
base.setMembers(ctx, app.GetDb());
mGroup = group;
mAct = act;
mDontSave = dontSave;
}
public override bool CanRecycle
{
get
{
return CanRecycleGroup(mGroup);
}
}
protected override UiStringKey QuestionsResourceId
{
get
{
return UiStringKey.AskDeletePermanentlyGroup;
}
}
public override void run() {
//from KP Desktop
PwGroup pg = mGroup;
PwGroup pgParent = pg.ParentGroup;
if(pgParent == null) return; // Can't remove virtual or root group
PwDatabase pd = mDb.pm;
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
pgParent.Groups.Remove(pg);
if ((DeletePermanently) || (!CanRecycle))
{
pg.DeleteAllObjects(pd);
PwDeletedObject pdo = new PwDeletedObject(pg.Uuid, DateTime.Now);
pd.DeletedObjects.Add(pdo);
mFinish = new AfterDeletePermanently(mFinish, mApp, mGroup);
}
else // Recycle
{
bool bDummy = false;
EnsureRecycleBin(ref pgRecycleBin, ref bDummy);
pgRecycleBin.AddGroup(pg, true, true);
pg.Touch(false);
mFinish = new ActionOnFinish((success, message) =>
{
if ( success ) {
// Mark new parent (Recycle bin) dirty
PwGroup parent = mGroup.ParentGroup;
if ( parent != null ) {
mDb.dirty.Add(parent);
}
//Mark old parent dirty:
mDb.dirty.Add(pgParent);
} else {
// Let's not bother recovering from a failure to save a deleted group. It is too much work.
mApp.SetShutdown();
}
}, this.mFinish);
}
// Save
SaveDB save = new SaveDB(mCtx, mDb, mFinish, mDontSave);
save.run();
}
private class AfterDeletePermanently : OnFinish {
IKp2aApp mApp;
PwGroup mGroup;
public AfterDeletePermanently(OnFinish finish, IKp2aApp app, PwGroup group):base(finish) {
this.mApp = app;
this.mGroup = group;
}
public override void run() {
if ( mSuccess ) {
// Remove from group global
mApp.GetDb().groups.Remove(mGroup.Uuid);
// Remove group from the dirty global (if it is present), not a big deal if this fails (doesn't throw)
mApp.GetDb().dirty.Remove(mGroup);
// Mark parent dirty
PwGroup parent = mGroup.ParentGroup;
if ( parent != null ) {
mApp.GetDb().dirty.Add(parent);
}
} else {
// Let's not bother recovering from a failure to save a deleted group. It is too much work.
mApp.SetShutdown();
}
base.run();
}
}
}
}

View File

@@ -0,0 +1,142 @@
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;
namespace keepass2android
{
public abstract class DeleteRunnable : RunnableOnFinish
{
public DeleteRunnable(OnFinish finish, IKp2aApp app):base(finish)
{
mApp = app;
}
protected IKp2aApp mApp;
protected Database mDb;
protected Context mCtx;
protected void setMembers(Context ctx, Database db)
{
mCtx = ctx;
mDb = db;
}
private bool mDeletePermanently = true;
public bool DeletePermanently
{
get
{
return mDeletePermanently;
}
set
{
mDeletePermanently = value;
}
}
public abstract bool CanRecycle
{
get;
}
protected bool CanRecycleGroup(PwGroup pgParent)
{
bool bShiftPressed = false;
PwDatabase pd = mDb.pm;
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
bool bPermanent = false;
if (pgParent != null)
{
if (pd.RecycleBinEnabled == false)
bPermanent = true;
else if (bShiftPressed)
bPermanent = true;
else if (pgRecycleBin == null)
{
} // Recycle
else if (pgParent == pgRecycleBin)
bPermanent = true;
else if (pgParent.IsContainedIn(pgRecycleBin))
bPermanent = true;
}
return !bPermanent;
}
protected void EnsureRecycleBin(ref PwGroup pgRecycleBin,
ref bool bGroupListUpdateRequired)
{
if ((mDb == null) || (mDb.pm == null)) { return; }
if(pgRecycleBin == mDb.pm.RootGroup)
{
pgRecycleBin = null;
}
if(pgRecycleBin == null)
{
pgRecycleBin = new PwGroup(true, true, mApp.GetResourceString(UiStringKey.RecycleBin),
PwIcon.TrashBin);
pgRecycleBin.EnableAutoType = false;
pgRecycleBin.EnableSearching = false;
pgRecycleBin.IsExpanded = false;
mDb.pm.RootGroup.AddGroup(pgRecycleBin, true);
mDb.pm.RecycleBinUuid = pgRecycleBin.Uuid;
bGroupListUpdateRequired = true;
}
else { System.Diagnostics.Debug.Assert(pgRecycleBin.Uuid.EqualsValue(mDb.pm.RecycleBinUuid)); }
}
protected abstract UiStringKey QuestionsResourceId
{
get;
}
public void start()
{
if (CanRecycle)
{
mApp.AskYesNoCancel(UiStringKey.AskDeletePermanently_title,
QuestionsResourceId,
new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) =>
{
DeletePermanently = true;
ProgressTask pt = new ProgressTask(mApp, mCtx, this, UiStringKey.saving_database);
pt.run();
}),
new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) => {
DeletePermanently = false;
ProgressTask pt = new ProgressTask(mApp, mCtx, this, UiStringKey.saving_database);
pt.run();
}),
new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) => {}),
mCtx);
} else
{
ProgressTask pt = new ProgressTask(mApp, mCtx, this, UiStringKey.saving_database);
pt.run();
}
}
}
}

View File

@@ -0,0 +1,49 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
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;
namespace keepass2android
{
public abstract class FileOnFinish : OnFinish {
private String mFilename = "";
public FileOnFinish(FileOnFinish finish):base(finish) {
}
public void setFilename(String filename) {
mFilename = filename;
}
public String getFilename() {
return mFilename;
}
}
}

View File

@@ -0,0 +1,118 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
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 Android.Preferences;
using KeePassLib.Serialization;
namespace keepass2android
{
public class LoadDB : RunnableOnFinish {
private IOConnectionInfo mIoc;
private String mPass;
private String mKey;
private IKp2aApp mApp;
private Context mCtx;
private bool mRememberKeyfile;
public LoadDB(IKp2aApp app, Context ctx, IOConnectionInfo ioc, String pass, String key, OnFinish finish): base(finish)
{
mApp = app;
mCtx = ctx;
mIoc = ioc;
mPass = pass;
mKey = key;
mRememberKeyfile = app.GetBooleanPreference(PreferenceKey.remember_keyfile);
}
public override void run ()
{
try {
mApp.GetDb().LoadData (mApp, mIoc, mPass, mKey, mStatus);
saveFileData (mIoc, mKey);
} catch (KeyFileException) {
finish(false, /*TODO Localize: use Keepass error text KPRes.KeyFileError (including "or invalid format")*/ mApp.GetResourceString(UiStringKey.keyfile_does_not_exist));
}
catch (Exception e) {
finish(false, "An error occured: " + e.Message);
return;
}
/* catch (InvalidPasswordException e) {
finish(false, mCtx.GetString(Resource.String.InvalidPassword));
return;
} catch (FileNotFoundException e) {
finish(false, mCtx.GetString(Resource.String.FileNotFound));
return;
} catch (IOException e) {
finish(false, e.getMessage());
return;
} catch (KeyFileEmptyException e) {
finish(false, mCtx.GetString(Resource.String.keyfile_is_empty));
return;
} catch (InvalidAlgorithmException e) {
finish(false, mCtx.GetString(Resource.String.invalid_algorithm));
return;
} catch (InvalidKeyFileException e) {
finish(false, mCtx.GetString(Resource.String.keyfile_does_not_exist));
return;
} catch (InvalidDBSignatureException e) {
finish(false, mCtx.GetString(Resource.String.invalid_db_sig));
return;
} catch (InvalidDBVersionException e) {
finish(false, mCtx.GetString(Resource.String.unsupported_db_version));
return;
} catch (InvalidDBException e) {
finish(false, mCtx.GetString(Resource.String.error_invalid_db));
return;
} catch (OutOfMemoryError e) {
finish(false, mCtx.GetString(Resource.String.error_out_of_memory));
return;
}
*/
finish(true);
}
private void saveFileData(IOConnectionInfo ioc, String key) {
if (!mRememberKeyfile)
{
key = "";
}
mApp.StoreOpenedFileAsRecent(ioc, key);
}
}
}

View File

@@ -0,0 +1,92 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
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;
namespace keepass2android
{
public abstract class OnFinish
{
protected bool mSuccess;
protected String mMessage;
protected OnFinish mOnFinish;
protected Handler mHandler;
public OnFinish() {
}
public OnFinish(Handler handler) {
mOnFinish = null;
mHandler = handler;
}
public OnFinish(OnFinish finish, Handler handler) {
mOnFinish = finish;
mHandler = handler;
}
public OnFinish(OnFinish finish) {
mOnFinish = finish;
mHandler = null;
}
public void setResult(bool success, String message) {
mSuccess = success;
mMessage = message;
}
public void setResult(bool success) {
mSuccess = success;
}
public virtual void run() {
if ( mOnFinish != null ) {
// Pass on result on call finish
mOnFinish.setResult(mSuccess, mMessage);
if ( mHandler != null ) {
mHandler.Post(mOnFinish.run);
} else {
mOnFinish.run();
}
}
}
protected void displayMessage(Context ctx) {
displayMessage(ctx, mMessage);
}
public static void displayMessage(Context ctx, string message)
{
if ( !String.IsNullOrEmpty(message) ) {
Toast.MakeText(ctx, message, ToastLength.Long).Show();
}
}
}
}

View File

@@ -0,0 +1,62 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
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;
namespace keepass2android
{
public abstract class RunnableOnFinish {
public OnFinish mFinish;
public UpdateStatus mStatus;
public RunnableOnFinish(OnFinish finish) {
mFinish = finish;
}
protected void finish(bool result, String message) {
if ( mFinish != null ) {
mFinish.setResult(result, message);
mFinish.run();
}
}
protected void finish(bool result) {
if ( mFinish != null ) {
mFinish.setResult(result);
mFinish.run();
}
}
public void setStatus(UpdateStatus status) {
mStatus = status;
}
abstract public void run();
}
}

View File

@@ -0,0 +1,77 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
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;
namespace keepass2android
{
public class SaveDB : RunnableOnFinish {
private Database mDb;
private bool mDontSave;
private Context mCtx;
public SaveDB(Context ctx, Database db, OnFinish finish, bool dontSave): base(finish) {
mCtx = ctx;
mDb = db;
mDontSave = dontSave;
}
public SaveDB(Context ctx, Database db, OnFinish finish):base(finish) {
mCtx = ctx;
mDb = db;
mDontSave = false;
}
public override void run ()
{
if (! mDontSave) {
try {
mDb.SaveData (mCtx);
if (mDb.mIoc.IsLocalFile())
mDb.mLastChangeDate = System.IO.File.GetLastWriteTimeUtc(mDb.mIoc.Path);
} catch (Exception e) {
/* TODO KPDesktop:
* catch(Exception exSave)
{
MessageService.ShowSaveWarning(pd.IOConnectionInfo, exSave, true);
bSuccess = false;
}
*/
finish (false, e.Message);
return;
}
}
finish(true);
}
}
}

View File

@@ -0,0 +1,112 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
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.Keys;
namespace keepass2android
{
public class SetPassword : RunnableOnFinish {
private String mPassword;
private String mKeyfile;
private Database mDb;
private bool mDontSave;
private Context mCtx;
public SetPassword(Context ctx, Database db, String password, String keyfile, OnFinish finish): base(finish) {
mCtx = ctx;
mDb = db;
mPassword = password;
mKeyfile = keyfile;
mDontSave = false;
}
public SetPassword(Context ctx, Database db, String password, String keyfile, OnFinish finish, bool dontSave): base(finish) {
mCtx = ctx;
mDb = db;
mPassword = password;
mKeyfile = keyfile;
mDontSave = dontSave;
}
public override void run ()
{
PwDatabase pm = mDb.pm;
CompositeKey newKey = new CompositeKey ();
if (String.IsNullOrEmpty (mPassword) == false) {
newKey.AddUserKey (new KcpPassword (mPassword));
}
if (String.IsNullOrEmpty (mKeyfile) == false) {
try {
newKey.AddUserKey (new KcpKeyFile (mKeyfile));
} catch (Exception exKF) {
//TODO MessageService.ShowWarning (strKeyFile, KPRes.KeyFileError, exKF);
return;
}
}
DateTime previousMasterKeyChanged = pm.MasterKeyChanged;
CompositeKey previousKey = pm.MasterKey;
pm.MasterKeyChanged = DateTime.Now;
pm.MasterKey = newKey;
// Save Database
mFinish = new AfterSave(previousKey, previousMasterKeyChanged, pm, mFinish);
SaveDB save = new SaveDB(mCtx, mDb, mFinish, mDontSave);
save.run();
}
private class AfterSave : OnFinish {
private CompositeKey mBackup;
private DateTime mPreviousKeyChanged;
private PwDatabase mDb;
public AfterSave(CompositeKey backup, DateTime previousKeyChanged, PwDatabase db, OnFinish finish): base(finish) {
mPreviousKeyChanged = previousKeyChanged;
mBackup = backup;
mDb = db;
}
public override void run() {
if ( ! mSuccess ) {
mDb.MasterKey = mBackup;
mDb.MasterKeyChanged = mPreviousKeyChanged;
}
base.run();
}
}
}
}

View File

@@ -0,0 +1,101 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
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;
namespace keepass2android
{
public class UpdateEntry : RunnableOnFinish {
private Database mDb;
private PwEntry mOldE;
private PwEntry mNewE;
private Context mCtx;
public UpdateEntry(Context ctx, Database db, PwEntry oldE, PwEntry newE, OnFinish finish):base(finish) {
mCtx = ctx;
mDb = db;
mOldE = oldE;
mNewE = newE;
mFinish = new AfterUpdate(oldE, newE, db, finish);
}
public override void run() {
// Commit to disk
SaveDB save = new SaveDB(mCtx, mDb, mFinish);
save.run();
}
private class AfterUpdate : OnFinish {
private PwEntry mBackup;
private PwEntry mUpdatedEntry;
private Database mDb;
public AfterUpdate(PwEntry backup, PwEntry updatedEntry, Database db, OnFinish finish):base(finish) {
mBackup = backup;
mUpdatedEntry = updatedEntry;
mDb = db;
}
public override void run() {
if ( mSuccess ) {
// Mark group dirty if title, icon or Expiry stuff changes
if ( ! mBackup.Strings.ReadSafe (PwDefs.TitleField).Equals(mUpdatedEntry.Strings.ReadSafe (PwDefs.TitleField))
|| ! mBackup.IconId.Equals(mUpdatedEntry.IconId)
|| ! mBackup.CustomIconUuid.EqualsValue(mUpdatedEntry.CustomIconUuid)
|| mBackup.Expires != mUpdatedEntry.Expires
|| (mBackup.Expires && (! mBackup.ExpiryTime.Equals(mUpdatedEntry.ExpiryTime)))
)
{
PwGroup parent = mUpdatedEntry.ParentGroup;
if ( parent != null ) {
// Mark parent group dirty
mDb.dirty.Add(parent);
}
}
} else {
// If we fail to save, back out changes to global structure
//TODO test fail
mUpdatedEntry.AssignProperties(mBackup, false, true, false);
}
base.run();
}
}
}
}