* Switched encoding of URLs to UTF8 (inclding prefix for backward compatibility)

-> browsing folders with Cyrillic characters works as well
* Fixed Bug in Skydrive path verification with more than one subfolder
* added Dropbox App Folder Storage
This commit is contained in:
Philipp Crocoll 2013-11-24 07:12:09 +01:00
parent 831a4d3339
commit f2e2a2045c
5 changed files with 83 additions and 27 deletions

View File

@ -0,0 +1,28 @@
package keepass2android.javafilestorage;
import com.dropbox.client2.session.Session.AccessType;
import android.content.Context;
public class DropboxAppFolderFileStorage extends DropboxFileStorage {
public DropboxAppFolderFileStorage(Context ctx, String _appKey,
String _appSecret) {
super(ctx, _appKey, _appSecret, false, AccessType.APP_FOLDER);
}
public DropboxAppFolderFileStorage(Context ctx, String _appKey, String _appSecret, boolean clearKeysOnStart)
{
super(ctx, _appKey, _appSecret, clearKeysOnStart, AccessType.APP_FOLDER);
}
@Override
public String getProtocolId() {
return "dropboxKP2A";
}
}

View File

@ -33,15 +33,7 @@ import com.dropbox.client2.session.Session.AccessType;
public class DropboxFileStorage extends JavaFileStorageBase { public class DropboxFileStorage extends JavaFileStorageBase {
//NOTE: also adjust secret! final static private String TAG = "KP2AJ";
//final static private String APP_KEY = "i8shu7v1hgh7ynt"; //KP2A
//final static private String APP_KEY = "4ybka4p4a1027n6"; //FileStorageTest
// If you'd like to change the access type to the full Dropbox instead of
// an app folder, change this value.
final static private AccessType ACCESS_TYPE = AccessType.DROPBOX;
final static private String TAG = "KP2AJ";
final static private String ACCOUNT_PREFS_NAME = "prefs"; final static private String ACCOUNT_PREFS_NAME = "prefs";
final static private String ACCESS_KEY_NAME = "ACCESS_KEY"; final static private String ACCESS_KEY_NAME = "ACCESS_KEY";
@ -51,23 +43,29 @@ public class DropboxFileStorage extends JavaFileStorageBase {
private boolean mLoggedIn = false; private boolean mLoggedIn = false;
private Context mContext; private Context mContext;
protected AccessType mAccessType = AccessType.DROPBOX;
private String appKey; private String appKey;
private String appSecret; private String appSecret;
public DropboxFileStorage(Context ctx, String _appKey, String _appSecret) public DropboxFileStorage(Context ctx, String _appKey, String _appSecret)
{ {
appKey = _appKey; initialize(ctx, _appKey, _appSecret, false, mAccessType);
appSecret = _appSecret;
mContext = ctx;
// We create a new AuthSession so that we can use the Dropbox API.
AndroidAuthSession session = buildSession();
mApi = new DropboxAPI<AndroidAuthSession>(session);
checkAppKeySetup();
} }
public DropboxFileStorage(Context ctx, String _appKey, String _appSecret, boolean clearKeysOnStart) public DropboxFileStorage(Context ctx, String _appKey, String _appSecret, boolean clearKeysOnStart)
{ {
initialize(ctx, _appKey, _appSecret, clearKeysOnStart, mAccessType);
}
public DropboxFileStorage(Context ctx, String _appKey, String _appSecret, boolean clearKeysOnStart, AccessType accessType)
{
initialize(ctx, _appKey, _appSecret, clearKeysOnStart, accessType);
}
private void initialize(Context ctx, String _appKey, String _appSecret,
boolean clearKeysOnStart, AccessType accessType) {
appKey = _appKey; appKey = _appKey;
appSecret = _appSecret; appSecret = _appSecret;
mContext = ctx; mContext = ctx;
@ -75,6 +73,7 @@ public class DropboxFileStorage extends JavaFileStorageBase {
if (clearKeysOnStart) if (clearKeysOnStart)
clearKeys(); clearKeys();
this.mAccessType = accessType;
// We create a new AuthSession so that we can use the Dropbox API. // We create a new AuthSession so that we can use the Dropbox API.
AndroidAuthSession session = buildSession(); AndroidAuthSession session = buildSession();
@ -247,11 +246,11 @@ public class DropboxFileStorage extends JavaFileStorageBase {
String[] stored = getKeys(); String[] stored = getKeys();
if (stored != null) { if (stored != null) {
AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]); AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
session = new AndroidAuthSession(appKeyPair, ACCESS_TYPE, accessToken); session = new AndroidAuthSession(appKeyPair, mAccessType, accessToken);
setLoggedIn(true); setLoggedIn(true);
Log.d(TAG, "Creating Dropbox Session with accessToken"); Log.d(TAG, "Creating Dropbox Session with accessToken");
} else { } else {
session = new AndroidAuthSession(appKeyPair, ACCESS_TYPE); session = new AndroidAuthSession(appKeyPair, mAccessType);
setLoggedIn(false); setLoggedIn(false);
Log.d(TAG, "Creating Dropbox Session without accessToken"); Log.d(TAG, "Creating Dropbox Session without accessToken");
} }

View File

@ -439,7 +439,7 @@ public class GoogleDriveFileStorage extends JavaFileStorageBase {
if (driveService.files().get(parentId).execute().getLabels().getTrashed()) if (driveService.files().get(parentId).execute().getLabels().getTrashed())
throw new FileNotFoundException(parentPath + " is trashed!"); throw new FileNotFoundException(parentPath + " is trashed!");
//Log.d(TAG, "listing files in "+parentId);
Files.List request = driveService.files().list() Files.List request = driveService.files().list()
.setQ("trashed=false and '"+parentId+"' in parents"); .setQ("trashed=false and '"+parentId+"' in parents");
@ -450,6 +450,7 @@ public class GoogleDriveFileStorage extends JavaFileStorageBase {
for (File file : files.getItems()) { for (File file : files.getItems()) {
String path = new GDrivePath(parentPath, file).getFullPath(); String path = new GDrivePath(parentPath, file).getFullPath();
//Log.d(TAG, "listing file "+path);
FileEntry e = convertToFileEntry(file, path); FileEntry e = convertToFileEntry(file, path);
result.add(e); result.add(e);

View File

@ -2,6 +2,8 @@ package keepass2android.javafilestorage;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import org.apache.http.protocol.HTTP;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.util.Log; import android.util.Log;
@ -10,8 +12,9 @@ public abstract class JavaFileStorageBase implements JavaFileStorage{
private static final String ISO_8859_1 = "ISO-8859-1"; private static final String ISO_8859_1 = "ISO-8859-1";
final static protected String TAG = "KP2AJ"; private static final String UTF8_PREFIX = ".U8-";
final static protected String NAME_ID_SEP = "-KP2A-"; final static protected String NAME_ID_SEP = "-KP2A-";
final static protected String TAG = "KP2AJ";
protected String getProtocolPrefix() protected String getProtocolPrefix()
{ {
@ -21,13 +24,18 @@ public abstract class JavaFileStorageBase implements JavaFileStorage{
protected static String encode(final String unencoded) protected static String encode(final String unencoded)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
return java.net.URLEncoder.encode(unencoded, ISO_8859_1); return UTF8_PREFIX+java.net.URLEncoder.encode(unencoded, HTTP.UTF_8);
} }
protected String decode(String encodedString) protected String decode(String encodedString)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
return java.net.URLDecoder.decode(encodedString, ISO_8859_1); //the first version of encode/decode used ISO 8859-1 which doesn't work with Cyrillic characters
//this is why we need to check for the prefix, even though all new strings are UTF8 encoded.
if (encodedString.startsWith(UTF8_PREFIX))
return java.net.URLDecoder.decode(encodedString.substring(UTF8_PREFIX.length()), HTTP.UTF_8);
else
return java.net.URLDecoder.decode(encodedString, ISO_8859_1);
} }

View File

@ -163,7 +163,8 @@ public class SkyDriveFileStorage extends JavaFileStorageBase {
// Log.d(TAG, " name=" + name); // Log.d(TAG, " name=" + name);
SkyDriveObject thisFolder = mFolderCache.get(id); SkyDriveObject thisFolder = mFolderCache.get(id);
if (thisFolder == null) { if (thisFolder == null) {
thisFolder = tryAddFileToCache(this); //Log.d(TAG, "adding to cache");
thisFolder = tryAddToCache(id);
// check if it's still null // check if it's still null
if (thisFolder == null) if (thisFolder == null)
@ -417,11 +418,30 @@ public class SkyDriveFileStorage extends JavaFileStorageBase {
} }
private SkyDriveObject tryAddToCache(String skyDriveId) {
try {
SkyDriveObject obj = getSkyDriveObject(skyDriveId);
if (obj != null) {
mFolderCache.put(obj.getId(), obj);
}
return obj;
} catch (Exception e) {
return null;
}
}
private SkyDriveObject getSkyDriveObject(SkyDrivePath skyDrivePath) private SkyDriveObject getSkyDriveObject(SkyDrivePath skyDrivePath)
throws LiveOperationException, InvalidPathException, throws LiveOperationException, InvalidPathException,
UnsupportedEncodingException, SkyDriveException, FileNotFoundException { UnsupportedEncodingException, SkyDriveException, FileNotFoundException {
LiveOperation operation = mConnectClient.get(skyDrivePath String skyDriveID = skyDrivePath.getSkyDriveId();
.getSkyDriveId()); return getSkyDriveObject(skyDriveID);
}
private SkyDriveObject getSkyDriveObject(String skyDriveID)
throws LiveOperationException, SkyDriveException,
FileNotFoundException {
LiveOperation operation = mConnectClient.get(skyDriveID);
JSONObject result = operation.getResult(); JSONObject result = operation.getResult();
checkResult(result); checkResult(result);
SkyDriveObject obj = SkyDriveObject.create(result); SkyDriveObject obj = SkyDriveObject.create(result);