First version of Dropbox-Support (not yet really functional - no possible to select the file to open)

This commit is contained in:
Philipp Crocoll
2013-09-15 20:08:14 +02:00
parent 042ee03f56
commit fbd3aafe71
60 changed files with 2175 additions and 306 deletions

View File

@@ -19,6 +19,17 @@ namespace keepass2android.Io
{
public class BuiltInFileStorage: IFileStorage
{
public IEnumerable<string> SupportedProtocols
{
get
{
yield return "file";
yield return "ftp";
yield return "http";
yield return "https";
}
}
public void DeleteFile(IOConnectionInfo ioc)
{
IOConnection.DeleteFile(ioc);
@@ -78,6 +89,8 @@ namespace keepass2android.Io
return new BuiltInFileTransaction(ioc, useFileTransaction);
}
public IFileStorageSetup RequiredSetup { get { return null; } }
public class BuiltInFileTransaction : IWriteTransaction
{
private readonly FileTransactionEx _transaction;
@@ -119,5 +132,10 @@ namespace keepass2android.Io
UrlUtil.GetFileName(ioc.Path));
}
public bool RequiresCredentials(IOConnectionInfo ioc)
{
return (!ioc.IsLocalFile()) && (ioc.CredSaveMode != IOCredSaveMode.SaveCred);
}
}
}

View File

@@ -77,6 +77,8 @@ namespace keepass2android.Io
IoUtil.DeleteDir(new Java.IO.File(_streamCacheDir), true);
}
public IEnumerable<string> SupportedProtocols { get { return _cachedStorage.SupportedProtocols; } }
public void DeleteFile(IOConnectionInfo ioc)
{
if (IsCached(ioc))
@@ -391,6 +393,8 @@ namespace keepass2android.Io
return new CachedWriteTransaction(ioc, useFileTransaction, this);
}
public IFileStorageSetup RequiredSetup { get { return _cachedStorage.RequiredSetup; } }
public bool CompleteIoId()
{
throw new NotImplementedException();
@@ -407,6 +411,11 @@ namespace keepass2android.Io
UrlUtil.GetFileName(ioc.Path));
}
public bool RequiresCredentials(IOConnectionInfo ioc)
{
return _cachedStorage.RequiresCredentials(ioc);
}
public string GetBaseVersionHash(IOConnectionInfo ioc)
{

View File

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.IO;
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 Keepass2android.Javafilestorage;
namespace keepass2android.Io
{
public class DropboxFileStorage: JavaFileStorage
{
public DropboxFileStorage(Context ctx) :
base(new Keepass2android.Javafilestorage.DropboxFileStorage(ctx))
{
}
public override IEnumerable<string> SupportedProtocols { get { yield return "dropbox"; } }
}
}

View File

@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.IO;
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;
namespace keepass2android.Io
{
public class GDriveFileStorage: IFileStorage
{
public IEnumerable<string> SupportedProtocols { get { yield return "gdrive"; } }
public void DeleteFile(IOConnectionInfo ioc)
{
throw new NotImplementedException();
}
public bool CheckForFileChangeFast(IOConnectionInfo ioc, string previousFileVersion)
{
throw new NotImplementedException();
}
public string GetCurrentFileVersionFast(IOConnectionInfo ioc)
{
throw new NotImplementedException();
}
public Stream OpenFileForRead(IOConnectionInfo ioc)
{
throw new NotImplementedException();
}
public IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction)
{
throw new NotImplementedException();
}
public IFileStorageSetup RequiredSetup { get; private set; }
public bool CompleteIoId()
{
throw new NotImplementedException();
}
public bool? FileExists()
{
throw new NotImplementedException();
}
public string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc)
{
throw new NotImplementedException();
}
public bool RequiresCredentials(IOConnectionInfo ioc)
{
throw new NotImplementedException();
}
}
}

View File

@@ -33,6 +33,8 @@ namespace keepass2android.Io
/// have an IIoStorageId interface in few cases.*/
public interface IFileStorage
{
IEnumerable<string> SupportedProtocols { get; }
/// <summary>
/// Deletes the given file.
/// </summary>
@@ -55,10 +57,26 @@ namespace keepass2android.Io
/// <returns>A string which should not be null.</returns>
string GetCurrentFileVersionFast(IOConnectionInfo ioc);
/// <summary>
/// Opens the given file for reading
/// </summary>
Stream OpenFileForRead(IOConnectionInfo ioc);
//Stream OpenFileForWrite( IOConnectionInfo ioc, bool useTransaction);
/// <summary>
/// Opens a write transaction for writing to the given ioc.
/// </summary>
/// <param name="ioc">ioc to write to</param>
/// <param name="useFileTransaction">if true, force to use file system level transaction. This might be ignored if the file storage has built in transaction support</param>
IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction);
/// <summary>
/// Returns an instance of an implementation of IFileStorageSetup or one of the more complex interfaces.
/// Depending on the type returned, the caller should try to follow the interface as close as possible.
/// Returns null if the file storage is setup or doesn't require anything to work.
/// </summary>
/// This is due to different storage types requiring different workflows for authentication processes
IFileStorageSetup RequiredSetup { get; }
/// <summary>
/// brings up a dialog to query credentials or something like this.
/// </summary>
@@ -73,6 +91,37 @@ namespace keepass2android.Io
bool? FileExists( /*ioId*/);
string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc);
/// <summary>
/// Returns true if the the given ioc must be filled with username/password
/// </summary>
bool RequiresCredentials(IOConnectionInfo ioc);
}
/// <summary>
/// Base interface for required setup code
/// </summary>
public interface IFileStorageSetup
{
/// <summary>
/// call this when the user explicitly wants to use this file storage. Might require user interaction.
/// May throw if the setup failed permanentaly.
/// </summary>
/// <returns>true if the setup was succesful immediately (without UI). Returns false if setup was not successful but no error occured or can be displayed.</returns>
bool TrySetup(Activity activity);
}
/// <summary>
/// Interface which can be used additionally for an IFileStorageSetup to indicate that setup must be completed in OnResume()
/// </summary>
public interface IFileStorageSetupOnResume
{
/// <summary>
/// call this after TrySetup() returned false in the next OnResume()
/// May throw if the setup failed permanentaly.
/// </summary>
/// <returns>true if setup was succesful</returns>
bool TrySetupOnResume(Activity activity);
}
public interface IWriteTransaction: IDisposable

View File

@@ -0,0 +1,207 @@
using System;
using System.Collections.Generic;
using System.IO;
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 Java.Lang;
using KeePassLib.Serialization;
using KeePassLib.Utility;
using Keepass2android.Javafilestorage;
using Exception = System.Exception;
namespace keepass2android.Io
{
public abstract class JavaFileStorage: IFileStorage
{
public abstract IEnumerable<string> SupportedProtocols { get; }
private IJavaFileStorage _jfs;
public JavaFileStorage(IJavaFileStorage jfs)
{
this._jfs = jfs;
}
public void DeleteFile(IOConnectionInfo ioc)
{
throw new NotImplementedException();
}
public bool CheckForFileChangeFast(IOConnectionInfo ioc, string previousFileVersion)
{
try
{
return _jfs.CheckForFileChangeFast(ioc.Path, previousFileVersion);
}
catch (Java.Lang.Exception e)
{
Kp2aLog.Log(e.Message);
throw new Exception(e.Message, e);
}
}
public string GetCurrentFileVersionFast(IOConnectionInfo ioc)
{
try
{
return _jfs.GetCurrentFileVersionFast(ioc.Path);
}
catch (Java.Lang.Exception e)
{
Kp2aLog.Log(e.Message);
throw new Exception(e.Message, e);
}
}
public Stream OpenFileForRead(IOConnectionInfo ioc)
{
try
{
return _jfs.OpenFileForRead(IocToPath(ioc));
}
catch (Java.IO.FileNotFoundException e)
{
throw new System.IO.FileNotFoundException(e.Message, e);
}
catch (Java.Lang.Exception e)
{
Kp2aLog.Log(e.Message);
throw new Exception(e.Message, e);
}
}
public IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction)
{
return new JavaFileStorageWriteTransaction(IocToPath(ioc), useFileTransaction, _jfs);
}
public IFileStorageSetup RequiredSetup
{
get
{
if (_jfs.IsConnected)
return null;
return new JavaFileStorageSetup(this);
}
}
public class JavaFileStorageSetup : IFileStorageSetup, IFileStorageSetupOnResume
{
private readonly JavaFileStorage _javaFileStorage;
public JavaFileStorageSetup(JavaFileStorage javaFileStorage)
{
_javaFileStorage = javaFileStorage;
}
public bool TrySetup(Activity activity)
{
try
{
return _javaFileStorage._jfs.TryConnect(activity);
}
catch (Java.Lang.Exception e)
{
Kp2aLog.Log(e.Message);
throw new Exception(e.Message, e);
}
}
public bool TrySetupOnResume(Activity activity)
{
try
{
_javaFileStorage._jfs.OnResume();
return _javaFileStorage._jfs.IsConnected;
}
catch (Java.Lang.Exception e)
{
Kp2aLog.Log(e.Message);
throw new Exception(e.Message, e);
}
}
}
class JavaFileStorageWriteTransaction: IWriteTransaction
{
private readonly string _path;
private readonly bool _useFileTransaction;
private readonly IJavaFileStorage _javaFileStorage;
private MemoryStream _memoryStream;
public JavaFileStorageWriteTransaction(string path, bool useFileTransaction, IJavaFileStorage javaFileStorage)
{
_path = path;
_useFileTransaction = useFileTransaction;
_javaFileStorage = javaFileStorage;
}
public void Dispose()
{
_memoryStream.Dispose();
}
public Stream OpenFile()
{
_memoryStream = new MemoryStream();
return _memoryStream;
}
public void CommitWrite()
{
try
{
_javaFileStorage.UploadFile(_path, _memoryStream.ToArray(), _useFileTransaction);
}
catch (Java.Lang.Exception e)
{
Kp2aLog.Log(e.ToString());
throw new Exception(e.Message, e);
}
}
}
public bool CompleteIoId()
{
throw new NotImplementedException();
}
public bool? FileExists()
{
throw new NotImplementedException();
}
public string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc)
{
return UrlUtil.StripExtension(
UrlUtil.GetFileName(IocToPath(ioc)));
}
public bool RequiresCredentials(IOConnectionInfo ioc)
{
return false;
}
private static string IocToPath(IOConnectionInfo ioc)
{
int protocolLength = ioc.Path.IndexOf("://", System.StringComparison.Ordinal);
if (protocolLength < 0)
return ioc.Path;
else
return ioc.Path.Substring(protocolLength + 3);
}
}
}

View File

@@ -57,8 +57,11 @@
<Compile Include="database\SynchronizeCachedDatabase.cs" />
<Compile Include="Io\BuiltInFileStorage.cs" />
<Compile Include="Io\CachingFileStorage.cs" />
<Compile Include="Io\DropboxFileStorage.cs" />
<Compile Include="Io\GDriveFileStorage.cs" />
<Compile Include="Io\IFileStorage.cs" />
<Compile Include="Io\IoUtil.cs" />
<Compile Include="Io\JavaFileStorage.cs" />
<Compile Include="IProgressDialog.cs" />
<Compile Include="PreferenceKey.cs" />
<Compile Include="UiStringKey.cs" />
@@ -89,6 +92,10 @@
<Compile Include="ProgressDialogStatusLogger.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\JavaFileStorageBindings\JavaFileStorageBindings.csproj">
<Project>{48574278-4779-4b3a-a9e4-9cf1bc285d0b}</Project>
<Name>JavaFileStorageBindings</Name>
</ProjectReference>
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
<Project>{545b4a6b-8bba-4fbe-92fc-4ac060122a54}</Project>
<Name>KeePassLib2Android</Name>