introduced automatic local backups after successfully opening a database. This should make sure that users can access their database even if the file gets corrupted (#238)
This commit is contained in:
@@ -11,9 +11,11 @@ using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.OS;
|
||||
using Android.Preferences;
|
||||
using Android.Support.V13.App;
|
||||
using Android.Support.V4.App;
|
||||
using Java.IO;
|
||||
using Java.Util;
|
||||
using KeePassLib.Serialization;
|
||||
using KeePassLib.Utility;
|
||||
using ActivityCompat = Android.Support.V13.App.ActivityCompat;
|
||||
@@ -379,7 +381,14 @@ namespace keepass2android.Io
|
||||
{
|
||||
if (ioc.IsLocalFile())
|
||||
{
|
||||
if (IsLocalFileFlaggedReadOnly(ioc))
|
||||
if (IsLocalBackup(ioc))
|
||||
{
|
||||
if (reason != null)
|
||||
reason.Result = UiStringKey.ReadOnlyReason_LocalBackup;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsLocalFileFlaggedReadOnly(ioc))
|
||||
{
|
||||
if (reason != null)
|
||||
reason.Result = UiStringKey.ReadOnlyReason_ReadOnlyFlag;
|
||||
@@ -400,7 +409,20 @@ namespace keepass2android.Io
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsLocalFileFlaggedReadOnly(IOConnectionInfo ioc)
|
||||
private readonly Dictionary<string, bool> _isLocalBackupCache = new Dictionary<string, bool>();
|
||||
private bool IsLocalBackup(IOConnectionInfo ioc)
|
||||
{
|
||||
bool result;
|
||||
if (_isLocalBackupCache.TryGetValue(ioc.Path, out result))
|
||||
return result;
|
||||
|
||||
result = (PreferenceManager.GetDefaultSharedPreferences(Application.Context)
|
||||
.GetBoolean(IoUtil.GetIocPrefKey(ioc, "is_local_backup"), false));
|
||||
_isLocalBackupCache[ioc.Path] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
private bool IsLocalFileFlaggedReadOnly(IOConnectionInfo ioc)
|
||||
{
|
||||
//see http://stackoverflow.com/a/33292700/292233
|
||||
try
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Java.IO;
|
||||
using KeePassLib.Serialization;
|
||||
using KeePassLib.Utility;
|
||||
|
||||
namespace keepass2android.Io
|
||||
{
|
||||
@@ -125,5 +127,53 @@ namespace keepass2android.Io
|
||||
return ctx.FilesDir;
|
||||
}
|
||||
|
||||
}
|
||||
//creates a local ioc where the sourceIoc can be stored to
|
||||
public static IOConnectionInfo GetInternalIoc(IOConnectionInfo sourceIoc, Context ctx)
|
||||
{
|
||||
Java.IO.File internalDirectory = IoUtil.GetInternalDirectory(ctx);
|
||||
string targetPath = UrlUtil.GetFileName(sourceIoc.Path);
|
||||
targetPath = targetPath.Trim("|\\?*<\":>+[]/'".ToCharArray());
|
||||
if (targetPath == "")
|
||||
targetPath = "internal";
|
||||
if (new File(internalDirectory, 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(internalDirectory, targetPath).Exists());
|
||||
}
|
||||
return IOConnectionInfo.FromPath(new File(internalDirectory, targetPath).CanonicalPath);
|
||||
}
|
||||
|
||||
public static IOConnectionInfo ImportFileToInternalDirectory(IOConnectionInfo sourceIoc, Context ctx, IKp2aApp app)
|
||||
{
|
||||
var targetIoc = GetInternalIoc(sourceIoc, ctx);
|
||||
|
||||
|
||||
IoUtil.Copy(targetIoc, sourceIoc, app);
|
||||
return targetIoc;
|
||||
}
|
||||
|
||||
public static string GetIocPrefKey(IOConnectionInfo ioc, string suffix)
|
||||
{
|
||||
var iocAsHexString = IocAsHexString(ioc);
|
||||
|
||||
return "kp2a_ioc_key_" + iocAsHexString + suffix;
|
||||
}
|
||||
|
||||
|
||||
public static string IocAsHexString(IOConnectionInfo ioc)
|
||||
{
|
||||
SHA256Managed sha256 = new SHA256Managed();
|
||||
string iocAsHexString =
|
||||
MemUtil.ByteArrayToHexString(sha256.ComputeHash(Encoding.Unicode.GetBytes(ioc.Path.ToCharArray())));
|
||||
return iocAsHexString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user