* 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:
		| @@ -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"; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -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"; | ||||||
| @@ -50,31 +42,38 @@ public class DropboxFileStorage extends JavaFileStorageBase { | |||||||
|     DropboxAPI<AndroidAuthSession> mApi; |     DropboxAPI<AndroidAuthSession> mApi; | ||||||
| 	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; | ||||||
| 		 | 		 | ||||||
| 		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"); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -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); | ||||||
|   | |||||||
| @@ -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"; | ||||||
| 	 | 	 | ||||||
|  | 	private static final String UTF8_PREFIX = ".U8-"; | ||||||
|  | 	final static protected String NAME_ID_SEP = "-KP2A-";	 | ||||||
| 	final static protected String TAG = "KP2AJ"; | 	final static protected String TAG = "KP2AJ"; | ||||||
| 	final static protected String NAME_ID_SEP = "-KP2A-"; |  | ||||||
| 	 | 	 | ||||||
| 	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); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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) | ||||||
| @@ -416,12 +417,31 @@ 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); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Philipp Crocoll
					Philipp Crocoll