OC-2067: Adapt CreateRemoteFolderOperation to detect Invalid Characters

This commit is contained in:
masensio 2013-11-13 18:44:25 +01:00
parent 89b37b7508
commit ea0c6a71c5
9 changed files with 88 additions and 50 deletions

View file

@ -7,7 +7,9 @@
<uses-permission android:name="android.permission.USE_CREDENTIALS" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" /> <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-sdk <uses-sdk
android:minSdkVersion="8" android:minSdkVersion="8"

View file

@ -2,9 +2,9 @@
<classpath> <classpath>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/> <classpathentry kind="src" path="gen"/>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/oc_framework-test-project"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/> <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry combineaccessrules="false" kind="src" path="/oc_framework-test-project"/>
<classpathentry kind="output" path="bin/classes"/> <classpathentry kind="output" path="bin/classes"/>
</classpath> </classpath>

View file

@ -4,10 +4,10 @@ import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import com.owncloud.android.oc_framework.operations.RemoteOperationResult; import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
import com.owncloud.android.oc_framework.operations.RemoteOperationResult.ResultCode;
import com.owncloud.android.oc_framework_test_project.TestActivity; import com.owncloud.android.oc_framework_test_project.TestActivity;
import android.test.ActivityInstrumentationTestCase2; import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
public class CreateFolderTest extends ActivityInstrumentationTestCase2<TestActivity> { public class CreateFolderTest extends ActivityInstrumentationTestCase2<TestActivity> {
@ -34,17 +34,47 @@ public class CreateFolderTest extends ActivityInstrumentationTestCase2<TestActiv
boolean createFullPath = true; boolean createFullPath = true;
RemoteOperationResult result = mActivity.createFolder(remotePath, createFullPath); RemoteOperationResult result = mActivity.createFolder(remotePath, createFullPath);
Log.d("test CreateFolder", "-----------------------" + result.getCode().name()); assertTrue(result.isSuccess() || result.getCode() == ResultCode.TIMEOUT);
Log.d("test CreateFolder", "-----------------------" + result.getLogMessage());
assertTrue(result.isSuccess());
} }
public void testCreateFolderSpecialCharacters() { public void testCreateFolderSpecialCharacters() {
String remotePath = "/test^^SpecialCharacters" + mCurrentDate;
boolean createFullPath = true; boolean createFullPath = true;
String remotePath = "/testSpecialCharacters_//" + mCurrentDate;
RemoteOperationResult result = mActivity.createFolder(remotePath, createFullPath); RemoteOperationResult result = mActivity.createFolder(remotePath, createFullPath);
assertFalse(result.isSuccess()); assertTrue(result.getCode() == ResultCode.INVALID_CHARACTER_IN_NAME);
remotePath = "/testSpecialCharacters_\\" + mCurrentDate;
result = mActivity.createFolder(remotePath, createFullPath);
assertTrue(result.getCode() == ResultCode.INVALID_CHARACTER_IN_NAME);
remotePath = "/testSpecialCharacters_<" + mCurrentDate;
result = mActivity.createFolder(remotePath, createFullPath);
assertTrue(result.getCode() == ResultCode.INVALID_CHARACTER_IN_NAME);
remotePath = "/testSpecialCharacters_>" + mCurrentDate;
result = mActivity.createFolder(remotePath, createFullPath);
assertTrue(result.getCode() == ResultCode.INVALID_CHARACTER_IN_NAME);
remotePath = "/testSpecialCharacters_:" + mCurrentDate;
result = mActivity.createFolder(remotePath, createFullPath);
assertTrue(result.getCode() == ResultCode.INVALID_CHARACTER_IN_NAME);
remotePath = "/testSpecialCharacters_\"" + mCurrentDate;
result = mActivity.createFolder(remotePath, createFullPath);
assertTrue(result.getCode() == ResultCode.INVALID_CHARACTER_IN_NAME);
remotePath = "/testSpecialCharacters_|" + mCurrentDate;
result = mActivity.createFolder(remotePath, createFullPath);
assertTrue(result.getCode() == ResultCode.INVALID_CHARACTER_IN_NAME);
remotePath = "/testSpecialCharacters_?" + mCurrentDate;
result = mActivity.createFolder(remotePath, createFullPath);
assertTrue(result.getCode() == ResultCode.INVALID_CHARACTER_IN_NAME);
remotePath = "/testSpecialCharacters_*" + mCurrentDate;
result = mActivity.createFolder(remotePath, createFullPath);
assertTrue(result.getCode() == ResultCode.INVALID_CHARACTER_IN_NAME);
} }

View file

@ -2,8 +2,8 @@ package com.owncloud.android.oc_framework_test_project;
import java.io.IOException; import java.io.IOException;
import com.owncloud.android.oc_framework.authentication.AccountUtils.AccountNotFoundException; import com.owncloud.android.oc_framework.accounts.AccountUtils.AccountNotFoundException;
import com.owncloud.android.oc_framework.network.OwnCloudClientUtils; import com.owncloud.android.oc_framework.network.webdav.OwnCloudClientFactory;
import com.owncloud.android.oc_framework.network.webdav.WebdavClient; import com.owncloud.android.oc_framework.network.webdav.WebdavClient;
import com.owncloud.android.oc_framework.operations.RemoteOperationResult; import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
import com.owncloud.android.oc_framework.operations.remote.CreateRemoteFolderOperation; import com.owncloud.android.oc_framework.operations.remote.CreateRemoteFolderOperation;
@ -34,12 +34,12 @@ public class TestActivity extends Activity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test); setContentView(R.layout.activity_test);
// This account must exists on the simulator / device
String accountHost = "beta.owncloud.com"; String accountHost = "beta.owncloud.com";
String accountUser = "masensio"; String accountUser = "masensio";
String accountName = accountUser + "@"+ accountHost; String accountName = accountUser + "@"+ accountHost;
String accountPass = "masensio"; String accountPass = "masensio";
String accountType = "owncloud"; String accountType = "owncloud";
String authorities = "org.owncloud";
AccountManager am = AccountManager.get(this); AccountManager am = AccountManager.get(this);
@ -51,19 +51,19 @@ public class TestActivity extends Activity {
} }
} }
if (mAccount == null) { // if (mAccount == null) {
mAccount = new Account(accountName, accountType); // mAccount = new Account(accountName, accountType);
am.addAccountExplicitly(mAccount, accountPass, null); // am.addAccountExplicitly(mAccount, accountPass, null);
am.setUserData(mAccount, "oc_version", "5.0.14"); // am.setUserData(mAccount, "oc_version", "5.0.14");
am.setUserData(mAccount, "oc_base_url", "http://beta.owncloud.com/owncloud"); // am.setUserData(mAccount, "oc_base_url", "http://beta.owncloud.com/owncloud");
} else { // } else {
Log.d(TAG, "oc_version --->"+ am.getUserData(mAccount, "oc_version") ); Log.d(TAG, "oc_version --->"+ am.getUserData(mAccount, "oc_version") );
Log.d(TAG, "oc_base_url --->"+ am.getUserData(mAccount, "oc_base_url") ); Log.d(TAG, "oc_base_url --->"+ am.getUserData(mAccount, "oc_base_url") );
} // }
try { try {
mClient = OwnCloudClientUtils.createOwnCloudClient(mAccount, this.getApplicationContext(), authorities); mClient = OwnCloudClientFactory.createOwnCloudClient(mAccount, this.getApplicationContext());
} catch (OperationCanceledException e) { } catch (OperationCanceledException e) {
Log.e(TAG, "Error while trying to access to " + mAccount.name, e); Log.e(TAG, "Error while trying to access to " + mAccount.name, e);
e.printStackTrace(); e.printStackTrace();

View file

@ -89,7 +89,8 @@ public class RemoteOperationResult implements Serializable {
ACCOUNT_NOT_FOUND, ACCOUNT_NOT_FOUND,
ACCOUNT_EXCEPTION, ACCOUNT_EXCEPTION,
ACCOUNT_NOT_NEW, ACCOUNT_NOT_NEW,
ACCOUNT_NOT_THE_SAME ACCOUNT_NOT_THE_SAME,
INVALID_CHARACTER_IN_NAME
} }
private boolean mSuccess = false; private boolean mSuccess = false;
@ -307,6 +308,8 @@ public class RemoteOperationResult implements Serializable {
} else if (mCode == ResultCode.ACCOUNT_NOT_THE_SAME) { } else if (mCode == ResultCode.ACCOUNT_NOT_THE_SAME) {
return "Authenticated with a different account than the one updating"; return "Authenticated with a different account than the one updating";
} else if (mCode == ResultCode.INVALID_CHARACTER_IN_NAME) {
return "The file name contains an forbidden character";
} }
return "Operation finished with HTTP status code " + mHttpCode + " (" + (isSuccess() ? "success" : "fail") + ")"; return "Operation finished with HTTP status code " + mHttpCode + " (" + (isSuccess() ? "success" : "fail") + ")";

View file

@ -1,7 +1,5 @@
package com.owncloud.android.oc_framework.operations.remote; package com.owncloud.android.oc_framework.operations.remote;
import java.io.File;
import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.HttpStatus;
import org.apache.jackrabbit.webdav.client.methods.MkColMethod; import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
@ -11,6 +9,8 @@ import com.owncloud.android.oc_framework.network.webdav.WebdavClient;
import com.owncloud.android.oc_framework.network.webdav.WebdavUtils; import com.owncloud.android.oc_framework.network.webdav.WebdavUtils;
import com.owncloud.android.oc_framework.operations.RemoteOperation; import com.owncloud.android.oc_framework.operations.RemoteOperation;
import com.owncloud.android.oc_framework.operations.RemoteOperationResult; import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
import com.owncloud.android.oc_framework.operations.RemoteOperationResult.ResultCode;
import com.owncloud.android.oc_framework.utils.FileUtils;
@ -28,7 +28,7 @@ public class CreateRemoteFolderOperation extends RemoteOperation {
private static final int READ_TIMEOUT = 10000; private static final int READ_TIMEOUT = 10000;
private static final int CONNECTION_TIMEOUT = 5000; private static final int CONNECTION_TIMEOUT = 5000;
private static final String PATH_SEPARATOR = "/";
protected String mRemotePath; protected String mRemotePath;
protected boolean mCreateFullPath; protected boolean mCreateFullPath;
@ -54,26 +54,32 @@ public class CreateRemoteFolderOperation extends RemoteOperation {
RemoteOperationResult result = null; RemoteOperationResult result = null;
MkColMethod mkcol = null; MkColMethod mkcol = null;
try { boolean noInvalidChars = FileUtils.validateName(mRemotePath);
mkcol = new MkColMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath)); if (noInvalidChars) {
int status = client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT); try {
if (!mkcol.succeeded() && mkcol.getStatusCode() == HttpStatus.SC_CONFLICT && mCreateFullPath) { mkcol = new MkColMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath));
result = createParentFolder(getParentPath(), client); int status = client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT);
status = client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT); // second (and last) try if (!mkcol.succeeded() && mkcol.getStatusCode() == HttpStatus.SC_CONFLICT && mCreateFullPath) {
} result = createParentFolder(FileUtils.getParentPath(mRemotePath), client);
status = client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT); // second (and last) try
}
result = new RemoteOperationResult(mkcol.succeeded(), status, mkcol.getResponseHeaders()); result = new RemoteOperationResult(mkcol.succeeded(), status, mkcol.getResponseHeaders());
Log.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage()); Log.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage());
client.exhaustResponse(mkcol.getResponseBodyAsStream()); client.exhaustResponse(mkcol.getResponseBodyAsStream());
} catch (Exception e) { } catch (Exception e) {
result = new RemoteOperationResult(e); result = new RemoteOperationResult(e);
Log.e(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage(), e); Log.e(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage(), e);
} finally { } finally {
if (mkcol != null) if (mkcol != null)
mkcol.releaseConnection(); mkcol.releaseConnection();
}
} else {
result = new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME);
} }
return result; return result;
} }
@ -84,10 +90,6 @@ public class CreateRemoteFolderOperation extends RemoteOperation {
return operation.execute(client); return operation.execute(client);
} }
private String getParentPath() {
String parentPath = new File(mRemotePath).getParent();
parentPath = parentPath.endsWith(PATH_SEPARATOR) ? parentPath : parentPath + PATH_SEPARATOR;
return parentPath;
}
} }

View file

@ -9,5 +9,5 @@
# Project target. # Project target.
target=android-19 target=android-19
android.library.reference.1=actionbarsherlock/library android.library.reference.1=actionbarsherlock\\library
android.library.reference.2=oc_framework android.library.reference.2=oc_framework

View file

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry combineaccessrules="false" kind="src" path="/owncloud-android"/>
<classpathentry kind="output" path="bin/classes"/> <classpathentry kind="output" path="bin/classes"/>
</classpath> </classpath>

View file

@ -20,8 +20,8 @@ package com.owncloud.android.test;
import android.test.AndroidTestCase; import android.test.AndroidTestCase;
import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.oc_framework.accounts.AccountUtils;
import com.owncloud.android.utils.OwnCloudVersion; import com.owncloud.android.oc_framework.utils.OwnCloudVersion;
public class AccountUtilsTest extends AndroidTestCase { public class AccountUtilsTest extends AndroidTestCase {