mirror of
https://github.com/moparisthebest/keepass2android
synced 2024-11-25 02:32:26 -05:00
* check if entered URI looks like a directory (not a file) and issue warning in SelectStorageLocationActivity
* check if URI is directory and refuse to delete in IOConnection
This commit is contained in:
parent
6c3795ff1a
commit
ed15af3f8f
@ -519,6 +519,11 @@ namespace KeePassLib.Serialization
|
||||
{
|
||||
RaiseIOAccessPreEvent(ioc, IOAccessType.Delete);
|
||||
|
||||
//in case a user entered a directory instead of a filename, make sure we're never
|
||||
//deleting their whole WebDAV/FTP content
|
||||
if (ioc.Path.EndsWith("/"))
|
||||
throw new IOException("Delete file does not expect directory URIs.");
|
||||
|
||||
if(ioc.IsLocalFile()) { File.Delete(ioc.Path); return; }
|
||||
|
||||
#if (!KeePassLibSD && !KeePassRT)
|
||||
|
@ -9,7 +9,10 @@ using KeePassLib.Serialization;
|
||||
|
||||
namespace keepass2android.Io
|
||||
{
|
||||
//TODOC,TOTEST, TODO: unimplemented methods?
|
||||
/** FileStorage to work with content URIs
|
||||
* Supports both "old" system where data is available only temporarily as
|
||||
* well as the SAF system. Assumes that persistable permissions are "taken" by
|
||||
* the activity which receives OnActivityResult from the system file picker.*/
|
||||
public class AndroidContentStorage: IFileStorage
|
||||
{
|
||||
private readonly Context _ctx;
|
||||
@ -135,10 +138,12 @@ namespace keepass2android.Io
|
||||
private bool TryGetDisplayName(IOConnectionInfo ioc, ref string displayName)
|
||||
{
|
||||
var uri = Android.Net.Uri.Parse(ioc.Path);
|
||||
var cursor = _ctx.ContentResolver.Query(uri, null, null, null, null, null);
|
||||
|
||||
try
|
||||
{
|
||||
var cursor = _ctx.ContentResolver.Query(uri, null, null, null, null, null);
|
||||
try
|
||||
{
|
||||
|
||||
if (cursor != null && cursor.MoveToFirst())
|
||||
{
|
||||
displayName = cursor.GetString(cursor.GetColumnIndex(OpenableColumns.DisplayName));
|
||||
@ -156,6 +161,16 @@ namespace keepass2android.Io
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Kp2aLog.Log(e.ToString());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public string CreateFilePath(string parent, string newFilename)
|
||||
|
@ -258,21 +258,31 @@ namespace keepass2android
|
||||
|
||||
protected abstract void StartFileChooser(string path, int requestCode, bool isForSave);
|
||||
|
||||
protected bool OnOpenButton(String fileName, int requestCode)
|
||||
protected bool OnOpenButton(string fileName, int requestCode, Action dismissDialog)
|
||||
{
|
||||
|
||||
|
||||
IOConnectionInfo ioc = new IOConnectionInfo
|
||||
{
|
||||
Path = fileName
|
||||
};
|
||||
|
||||
int lastSlashPos = fileName.LastIndexOf('/');
|
||||
int lastDotPos = fileName.LastIndexOf('.');
|
||||
if (lastSlashPos >= lastDotPos) //no dot after last slash or == in case neither / nor .
|
||||
{
|
||||
ShowFilenameWarning(fileName, () => { IocSelected(ioc, requestCode); dismissDialog(); }, () => { /* don't do anything, leave dialog open, let user try again*/ });
|
||||
//signal that the dialog should be kept open
|
||||
return false;
|
||||
}
|
||||
|
||||
IocSelected(ioc, requestCode);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
protected abstract void ShowFilenameWarning(string fileName, Action onUserWantsToContinue, Action onUserWantsToCorrect);
|
||||
|
||||
|
||||
protected virtual void CopyFile(IOConnectionInfo targetIoc, IOConnectionInfo sourceIoc)
|
||||
{
|
||||
|
@ -14,12 +14,13 @@
|
||||
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
|
||||
<TargetFrameworkVersion>v4.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.4</TargetFrameworkVersion>
|
||||
<AndroidSupportedAbis>armeabi,armeabi-v7a,x86</AndroidSupportedAbis>
|
||||
<AndroidStoreUncompressedFileExtensions />
|
||||
<MandroidI18n />
|
||||
<JavaMaximumHeapSize />
|
||||
<JavaOptions />
|
||||
<AndroidUseLatestPlatformSdk />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@ -101,7 +102,7 @@
|
||||
<Name>KeePassLib2Android</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Kp2aBusinessLogic\Kp2aBusinessLogic.csproj">
|
||||
<Project>{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}</Project>
|
||||
<Project>{53a9cb7f-6553-4bc0-b56b-9410bb2e59aa}</Project>
|
||||
<Name>Kp2aBusinessLogic</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\KP2AKdbLibraryBinding\KP2AKdbLibraryBinding.csproj">
|
||||
|
@ -23,7 +23,7 @@ namespace Kp2aUnitTests
|
||||
//runner.AddTests(typeof(TestLoadDb).GetMethod("TestLoadKdb1WithKeyfileOnly"));
|
||||
|
||||
|
||||
//runner.AddTests(new List<Type> { typeof(TestSelectStorageLocation) });
|
||||
runner.AddTests(new List<Type> { typeof(TestSelectStorageLocation) });
|
||||
//runner.AddTests(new List<Type> { typeof(TestSynchronizeCachedDatabase)});
|
||||
//runner.AddTests(typeof(TestLoadDb).GetMethod("LoadErrorWithCertificateTrustFailure"));
|
||||
//runner.AddTests(typeof(TestLoadDb).GetMethod("LoadWithAcceptedCertificateTrustFailure"));
|
||||
@ -36,7 +36,7 @@ namespace Kp2aUnitTests
|
||||
//runner.AddTests(typeof(TestSaveDb).GetMethod("TestLoadAndSave_TestIdenticalFiles_kdb"));
|
||||
//runner.AddTests(typeof(TestSaveDb).GetMethod("TestCreateSaveAndLoad_TestIdenticalFiles_kdb"));
|
||||
|
||||
runner.AddTests(typeof(TestSaveDb).GetMethod("TestSaveTwice_kdb"));
|
||||
// runner.AddTests(typeof(TestSaveDb).GetMethod("TestSaveTwice_kdb"));
|
||||
|
||||
//runner.AddTests(typeof(TestLoadDb).GetMethod("LoadAndSaveFromRemote1And1Ftp"));
|
||||
//runner.AddTests(typeof(TestLoadDb).GetMethod("TestLoadKdbpWithPasswordOnly"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />
|
||||
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" />
|
||||
<application></application>
|
||||
</manifest>
|
@ -225,6 +225,12 @@ namespace Kp2aUnitTests
|
||||
_userAction = new SelectFileAction(isForSave, browseRequestCode, protocolId, this);
|
||||
}
|
||||
|
||||
protected override void ShowFilenameWarning(string fileName, Action onUserWantsToContinue, Action onUserWantsToCorrect)
|
||||
{
|
||||
_userAction = new ShowAlertDialogAction("filenameWarning", delegate { onUserWantsToContinue(); },
|
||||
delegate { onUserWantsToCorrect(); });
|
||||
}
|
||||
|
||||
public void HandleActivityResult(int requestCode, Result resultCode, Intent data)
|
||||
{
|
||||
OnActivityResult(requestCode, resultCode, data);
|
||||
@ -281,7 +287,7 @@ namespace Kp2aUnitTests
|
||||
|
||||
private void PressOpenButton(string path, int browseRequestCode)
|
||||
{
|
||||
OnOpenButton(path, browseRequestCode);
|
||||
OnOpenButton(path, browseRequestCode, () => { });
|
||||
}
|
||||
|
||||
|
||||
@ -523,6 +529,48 @@ namespace Kp2aUnitTests
|
||||
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestManualSelectWithDirectoryCancel()
|
||||
{
|
||||
var testee = CreateTestee();
|
||||
var action = (TestControllableSelectStorageLocationActivity.FileStorageSelectionAction)testee._userAction;
|
||||
action.ReturnProtocol("ftp");
|
||||
|
||||
Assert.IsNull(testee._result); //no result yet
|
||||
|
||||
var action2 = (TestControllableSelectStorageLocationActivity.SelectFileAction)testee._userAction;
|
||||
string path = "ftp://crocoll.net/";
|
||||
action2.PerformManualFileSelect(path);
|
||||
|
||||
Assert.IsNull(testee._result);
|
||||
|
||||
var action3 = (TestControllableSelectStorageLocationActivity.ShowAlertDialogAction) testee._userAction;
|
||||
action3.Ok();
|
||||
Assert.IsTrue((bool)testee._result);
|
||||
Assert.AreEqual(testee._resultIoc.Path, path);
|
||||
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void TestManualSelectWithDirectory()
|
||||
{
|
||||
var testee = CreateTestee();
|
||||
var action = (TestControllableSelectStorageLocationActivity.FileStorageSelectionAction)testee._userAction;
|
||||
action.ReturnProtocol("ftp");
|
||||
|
||||
Assert.IsNull(testee._result); //no result yet
|
||||
|
||||
var action2 = (TestControllableSelectStorageLocationActivity.SelectFileAction)testee._userAction;
|
||||
string path = "ftp://crocoll.net/";
|
||||
action2.PerformManualFileSelect(path);
|
||||
|
||||
Assert.IsNull(testee._result);
|
||||
|
||||
var action3 = (TestControllableSelectStorageLocationActivity.ShowAlertDialogAction)testee._userAction;
|
||||
action3.Cancel();
|
||||
|
||||
}
|
||||
[TestMethod]
|
||||
public void TestCancelManualSelect()
|
||||
{
|
||||
|
@ -441,7 +441,7 @@ namespace keepass2android
|
||||
return filename;
|
||||
}
|
||||
|
||||
private bool OnCreateButton(string filename)
|
||||
private bool OnCreateButton(string filename, Dialog dialog)
|
||||
{
|
||||
// Make sure file name exists
|
||||
if (filename.Length == 0)
|
||||
|
@ -144,7 +144,7 @@ namespace keepass2android
|
||||
get { return 0; }
|
||||
}
|
||||
|
||||
private bool OnCreateButton(string filename)
|
||||
private bool OnCreateButton(string filename, Dialog dialog)
|
||||
{
|
||||
if (filename.Length == 0)
|
||||
{
|
||||
|
@ -530,6 +530,9 @@
|
||||
|
||||
<string name="PreviewWarning">Please note! This is a preview release and might come with some flaws! If you experience *anything* unexpected, please let me know (on Codeplex or by email).</string>
|
||||
|
||||
<string name="Continue">Continue</string>
|
||||
<string name="NoFilenameWarning">The URI you have entered does not look like a filename. Are you sure this is a valid file?</string>
|
||||
|
||||
<string name="ChangeLog_0_9_7b">
|
||||
Version 0.9.7b\n
|
||||
* updated translations\n
|
||||
|
@ -100,9 +100,9 @@ namespace keepass2android
|
||||
if (defaultPath.StartsWith("sftp://"))
|
||||
Util.ShowSftpDialog(this, filename => OnReceivedSftpData(filename, browseRequestCode, isForSave), ReturnCancel);
|
||||
else
|
||||
//todo oncreate nur wenn for save?
|
||||
Util.ShowFilenameDialog(this, filename => OnOpenButton(filename, browseRequestCode),
|
||||
filename => OnOpenButton(filename, browseRequestCode),
|
||||
Util.ShowFilenameDialog(this,
|
||||
!isForSave ? delegate(string filename, Dialog dialog) { return OnOpenButton(filename, browseRequestCode, dialog.Dismiss); } : (Func<string, Dialog, bool>) null,
|
||||
isForSave ? delegate(string filename, Dialog dialog) { return OnOpenButton(filename, browseRequestCode, dialog.Dismiss); } : (Func<string, Dialog, bool>) null,
|
||||
ReturnCancel, false, defaultPath, GetString(Resource.String.enter_filename_details_url),
|
||||
browseRequestCode);
|
||||
});
|
||||
@ -224,7 +224,17 @@ namespace keepass2android
|
||||
|
||||
}
|
||||
|
||||
protected override void ShowFilenameWarning(string fileName, Action onUserWantsToContinue, Action onUserWantsToCorrect)
|
||||
{
|
||||
new AlertDialog.Builder(this)
|
||||
.SetPositiveButton(Resource.String.Continue, delegate { onUserWantsToContinue(); } )
|
||||
.SetMessage(Resource.String.NoFilenameWarning)
|
||||
.SetCancelable(false)
|
||||
.SetNegativeButton(Android.Resource.String.Cancel, delegate { onUserWantsToCorrect(); })
|
||||
.Create()
|
||||
.Show();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void OnDismiss(IDialogInterface dialog)
|
||||
|
@ -335,7 +335,7 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowFilenameDialog(Activity activity, FileSelectedHandler onOpen, FileSelectedHandler onCreate, Action onCancel, bool showBrowseButton, string defaultFilename, string detailsText, int requestCodeBrowse)
|
||||
public static void ShowFilenameDialog(Activity activity, Func<string, Dialog, bool> onOpen, Func<string, Dialog, bool> onCreate, Action onCancel, bool showBrowseButton, string defaultFilename, string detailsText, int requestCodeBrowse)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
builder.SetView(activity.LayoutInflater.Inflate(Resource.Layout.file_selection_filename, null));
|
||||
@ -362,7 +362,7 @@ namespace keepass2android
|
||||
openButton.Click += (sender, args) =>
|
||||
{
|
||||
String fileName = ((EditText) dialog.FindViewById(Resource.Id.file_filename)).Text;
|
||||
if (onOpen(fileName))
|
||||
if (onOpen(fileName, dialog))
|
||||
dialog.Dismiss();
|
||||
};
|
||||
|
||||
@ -371,7 +371,7 @@ namespace keepass2android
|
||||
createButton.Click += (sender, args) =>
|
||||
{
|
||||
String fileName = ((EditText)dialog.FindViewById(Resource.Id.file_filename)).Text;
|
||||
if (onCreate(fileName))
|
||||
if (onCreate(fileName, dialog))
|
||||
dialog.Dismiss();
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user