mirror of
https://github.com/moparisthebest/keepass2android
synced 2025-01-10 21:18:18 -05:00
allow importing database to internal folder
This commit is contained in:
parent
3110f5c9be
commit
13ab33081d
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Android.Content;
|
||||
using Java.IO;
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
@ -46,5 +47,50 @@ namespace keepass2android.Io
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
_jfs.OnCreate(((IJavaFileStorageFileStorageSetupActivity)activity), savedInstanceState);
|
||||
|
@ -249,20 +249,7 @@ namespace keepass2android
|
||||
|
||||
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
|
||||
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();
|
||||
}
|
||||
IoUtil.Copy(targetIoc, sourceIoc, _app);
|
||||
}
|
||||
|
||||
private void PrimaryIocSelected(IOConnectionInfo ioc)
|
||||
|
@ -41,6 +41,12 @@
|
||||
<string name="FileHandling_prefs">File handling</string>
|
||||
<string name="keyboard_prefs">Keyboard</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="cancel">Cancel</string>
|
||||
<string name="ClearClipboard">Clipboard cleared.</string>
|
||||
|
@ -55,6 +55,16 @@
|
||||
<intent android:action="keepass2android.ExportDatabaseActivity"/>
|
||||
</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>
|
||||
|
||||
|
@ -22,7 +22,12 @@ using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Widget;
|
||||
using Android.Preferences;
|
||||
using Java.IO;
|
||||
using KeePassLib.Cryptography.Cipher;
|
||||
using KeePassLib.Serialization;
|
||||
using KeePassLib.Utility;
|
||||
using keepass2android.Io;
|
||||
using keepass2android.Utils;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
@ -173,6 +178,98 @@ namespace keepass2android
|
||||
|
||||
Preference algorithm = FindPreference(GetString(Resource.String.algorithm_key));
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user