allow importing database to internal folder
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Android.Content;
|
||||||
using Java.IO;
|
using Java.IO;
|
||||||
using KeePassLib.Serialization;
|
using KeePassLib.Serialization;
|
||||||
|
|
||||||
@@ -46,5 +47,50 @@ namespace keepass2android.Io
|
|||||||
}
|
}
|
||||||
return iocParent;
|
return iocParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsInInternalDirectory(string path, Context context)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File filesDir = context.FilesDir.CanonicalFile;
|
||||||
|
File ourFile = new File(path).CanonicalFile;
|
||||||
|
//http://www.java2s.com/Tutorial/Java/0180__File/Checkswhetherthechilddirectoryisasubdirectoryofthebasedirectory.htm
|
||||||
|
|
||||||
|
File parentFile = ourFile;
|
||||||
|
while (parentFile != null)
|
||||||
|
{
|
||||||
|
if (filesDir.Equals(parentFile))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
parentFile = parentFile.ParentFile;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Kp2aLog.Log(e.ToString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Copy(IOConnectionInfo targetIoc, IOConnectionInfo sourceIoc, IKp2aApp app)
|
||||||
|
{
|
||||||
|
IFileStorage sourceStorage = app.GetFileStorage(sourceIoc, false); //don't cache source. file won't be used ever again
|
||||||
|
IFileStorage targetStorage = app.GetFileStorage(targetIoc);
|
||||||
|
|
||||||
|
using (
|
||||||
|
var writeTransaction = targetStorage.OpenWriteTransaction(targetIoc,
|
||||||
|
app.GetBooleanPreference(
|
||||||
|
PreferenceKey.UseFileTransactions)))
|
||||||
|
{
|
||||||
|
using (var writeStream = writeTransaction.OpenFile())
|
||||||
|
{
|
||||||
|
sourceStorage.OpenFileForRead(sourceIoc).CopyTo(writeStream);
|
||||||
|
}
|
||||||
|
writeTransaction.CommitWrite();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -293,16 +293,6 @@ namespace keepass2android.Io
|
|||||||
return false; //TODO implement. note, however, that we MAY return false even if it's read-only
|
return false; //TODO implement. note, however, that we MAY return false even if it's read-only
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsPermanentLocation(IOConnectionInfo ioc)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsReadOnly(IOConnectionInfo ioc)
|
|
||||||
{
|
|
||||||
return false; //TODO implement. note, however, that we MAY return false even if it's read-only
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnCreate(IFileStorageSetupActivity activity, Bundle savedInstanceState)
|
public void OnCreate(IFileStorageSetupActivity activity, Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
_jfs.OnCreate(((IJavaFileStorageFileStorageSetupActivity)activity), savedInstanceState);
|
_jfs.OnCreate(((IJavaFileStorageFileStorageSetupActivity)activity), savedInstanceState);
|
||||||
|
|||||||
@@ -249,20 +249,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
protected virtual void CopyFile(IOConnectionInfo targetIoc, IOConnectionInfo sourceIoc)
|
protected virtual void CopyFile(IOConnectionInfo targetIoc, IOConnectionInfo sourceIoc)
|
||||||
{
|
{
|
||||||
IFileStorage sourceStorage = _app.GetFileStorage(sourceIoc, false); //don't cache source. file won't be used ever again
|
IoUtil.Copy(targetIoc, sourceIoc, _app);
|
||||||
IFileStorage targetStorage = _app.GetFileStorage(targetIoc);
|
|
||||||
|
|
||||||
using (
|
|
||||||
var writeTransaction = targetStorage.OpenWriteTransaction(targetIoc,
|
|
||||||
_app.GetBooleanPreference(
|
|
||||||
PreferenceKey.UseFileTransactions)))
|
|
||||||
{
|
|
||||||
using (var writeStream = writeTransaction.OpenFile())
|
|
||||||
{
|
|
||||||
sourceStorage.OpenFileForRead(sourceIoc).CopyTo(writeStream);
|
|
||||||
}
|
|
||||||
writeTransaction.CommitWrite();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PrimaryIocSelected(IOConnectionInfo ioc)
|
private void PrimaryIocSelected(IOConnectionInfo ioc)
|
||||||
|
|||||||
@@ -41,6 +41,12 @@
|
|||||||
<string name="FileHandling_prefs">File handling</string>
|
<string name="FileHandling_prefs">File handling</string>
|
||||||
<string name="keyboard_prefs">Keyboard</string>
|
<string name="keyboard_prefs">Keyboard</string>
|
||||||
<string name="export_prefs">Export database...</string>
|
<string name="export_prefs">Export database...</string>
|
||||||
|
<string name="import_db_prefs">Import database to internal folder</string>
|
||||||
|
<string name="import_keyfile_prefs">Import key file to internal folder</string>
|
||||||
|
<string name="OnlyAvailableForLocalFiles">Only available for local files.</string>
|
||||||
|
<string name="FileIsInInternalDirectory">File is stored in internal directory.</string>
|
||||||
|
<string name="DatabaseFileMoved">Database file was copied to internal folder. Press Ok to open from the new location. Note: Do not forget to regularly export/backup the database!</string>
|
||||||
|
|
||||||
<string name="brackets">Brackets</string>
|
<string name="brackets">Brackets</string>
|
||||||
<string name="cancel">Cancel</string>
|
<string name="cancel">Cancel</string>
|
||||||
<string name="ClearClipboard">Clipboard cleared.</string>
|
<string name="ClearClipboard">Clipboard cleared.</string>
|
||||||
|
|||||||
@@ -55,7 +55,17 @@
|
|||||||
<intent android:action="keepass2android.ExportDatabaseActivity"/>
|
<intent android:action="keepass2android.ExportDatabaseActivity"/>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="import_db_prefs"
|
||||||
|
android:title="@string/import_db_prefs"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="import_keyfile_prefs"
|
||||||
|
android:title="@string/import_keyfile_prefs"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
|
|||||||
@@ -22,7 +22,12 @@ using Android.Content;
|
|||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
|
using Java.IO;
|
||||||
using KeePassLib.Cryptography.Cipher;
|
using KeePassLib.Cryptography.Cipher;
|
||||||
|
using KeePassLib.Serialization;
|
||||||
|
using KeePassLib.Utility;
|
||||||
|
using keepass2android.Io;
|
||||||
|
using keepass2android.Utils;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
@@ -173,6 +178,98 @@ namespace keepass2android
|
|||||||
|
|
||||||
Preference algorithm = FindPreference(GetString(Resource.String.algorithm_key));
|
Preference algorithm = FindPreference(GetString(Resource.String.algorithm_key));
|
||||||
SetAlgorithm(db, algorithm);
|
SetAlgorithm(db, algorithm);
|
||||||
|
|
||||||
|
UpdateImportDbPref();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateImportDbPref()
|
||||||
|
{
|
||||||
|
//Import db/key file preferences:
|
||||||
|
Preference importDb = FindPreference("import_db_prefs");
|
||||||
|
if (!App.Kp2a.GetDb().Ioc.IsLocalFile())
|
||||||
|
{
|
||||||
|
importDb.Summary = GetString(Resource.String.OnlyAvailableForLocalFiles);
|
||||||
|
importDb.Enabled = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (IoUtil.IsInInternalDirectory(App.Kp2a.GetDb().Ioc.Path, this))
|
||||||
|
{
|
||||||
|
importDb.Summary = GetString(Resource.String.FileIsInInternalDirectory);
|
||||||
|
importDb.Enabled = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
importDb.Enabled = true;
|
||||||
|
importDb.PreferenceClick += delegate { MoveDbToInternalFolder(); };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MoveDbToInternalFolder()
|
||||||
|
{
|
||||||
|
Func<Action> copyAndReturnPostExecute = () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var sourceIoc = App.Kp2a.GetDb().Ioc;
|
||||||
|
var newIoc = ImportFileToInternalDirectory(sourceIoc);
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var builder = new AlertDialog.Builder(this);
|
||||||
|
builder
|
||||||
|
.SetMessage(Resource.String.DatabaseFileMoved);
|
||||||
|
builder.SetPositiveButton(Android.Resource.String.Ok, (sender, args) =>
|
||||||
|
PasswordActivity.Launch(this, newIoc, new NullTask()));
|
||||||
|
builder.Show();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
Toast.MakeText(this, App.Kp2a.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, ToastLength.Long).Show();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
new SimpleLoadingDialog(this, GetString(Resource.String.CopyingFile), false,
|
||||||
|
copyAndReturnPostExecute
|
||||||
|
).Execute();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private IOConnectionInfo ImportFileToInternalDirectory(IOConnectionInfo sourceIoc)
|
||||||
|
{
|
||||||
|
string targetPath = UrlUtil.GetFileName(sourceIoc.Path);
|
||||||
|
targetPath = targetPath.Trim("|\\?*<\":>+[]/'".ToCharArray());
|
||||||
|
if (targetPath == "")
|
||||||
|
targetPath = "imported";
|
||||||
|
if (new File(FilesDir, targetPath).Exists())
|
||||||
|
{
|
||||||
|
int c = 1;
|
||||||
|
var ext = UrlUtil.GetExtension(targetPath);
|
||||||
|
var filenameWithoutExt = UrlUtil.StripExtension(targetPath);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
c++;
|
||||||
|
targetPath = filenameWithoutExt + c;
|
||||||
|
if (!String.IsNullOrEmpty(ext))
|
||||||
|
targetPath += "." + ext;
|
||||||
|
} while (new File(FilesDir, targetPath).Exists());
|
||||||
|
}
|
||||||
|
var targetIoc = IOConnectionInfo.FromPath(new File(FilesDir, targetPath).CanonicalPath);
|
||||||
|
|
||||||
|
IoUtil.Copy(targetIoc, sourceIoc, App.Kp2a);
|
||||||
|
return targetIoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetRounds(Database db, Preference rounds)
|
private void SetRounds(Database db, Preference rounds)
|
||||||
|
|||||||
Reference in New Issue
Block a user