From 8f068a284952a1efff937141c929b33562b03292 Mon Sep 17 00:00:00 2001 From: masensio Date: Thu, 9 Apr 2015 18:19:22 +0200 Subject: [PATCH 001/101] Add OC-Total-Length header to ChunkedUploadRemoteFileOperation --- .../lib/resources/files/ChunkedUploadRemoteFileOperation.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java index 89379dda..3b20e388 100644 --- a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java @@ -44,6 +44,7 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation public static final long CHUNK_SIZE = 1024000; private static final String OC_CHUNKED_HEADER = "OC-Chunked"; + private static final String OC_TOTAL_LENGTH_HEADER = "OC-Total-Length"; private static final String TAG = ChunkedUploadRemoteFileOperation.class.getSimpleName(); public ChunkedUploadRemoteFileOperation(String storagePath, String remotePath, String mimeType) { @@ -75,7 +76,8 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation } mPutMethod = new PutMethod(uriPrefix + chunkCount + "-" + chunkIndex); mPutMethod.addRequestHeader(OC_CHUNKED_HEADER, OC_CHUNKED_HEADER); - ((ChunkFromFileChannelRequestEntity)mEntity).setOffset(offset); + mPutMethod.addRequestHeader(OC_TOTAL_LENGTH_HEADER, String.valueOf(file.length())); + ((ChunkFromFileChannelRequestEntity) mEntity).setOffset(offset); mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); From aaebdefe563575bc890038a82ecabc730d5dcc65 Mon Sep 17 00:00:00 2001 From: masensio Date: Fri, 10 Apr 2015 09:21:05 +0200 Subject: [PATCH 002/101] Add OC-Total-Length to UploadRemoteFileOperation --- .../lib/resources/files/ChunkedUploadRemoteFileOperation.java | 1 - .../android/lib/resources/files/UploadRemoteFileOperation.java | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java index 3b20e388..15284adb 100644 --- a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java @@ -44,7 +44,6 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation public static final long CHUNK_SIZE = 1024000; private static final String OC_CHUNKED_HEADER = "OC-Chunked"; - private static final String OC_TOTAL_LENGTH_HEADER = "OC-Total-Length"; private static final String TAG = ChunkedUploadRemoteFileOperation.class.getSimpleName(); public ChunkedUploadRemoteFileOperation(String storagePath, String remotePath, String mimeType) { diff --git a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java index 9514431a..9043fe36 100644 --- a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java @@ -53,6 +53,7 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult; public class UploadRemoteFileOperation extends RemoteOperation { + protected static final String OC_TOTAL_LENGTH_HEADER = "OC-Total-Length"; protected String mLocalPath; protected String mRemotePath; @@ -116,6 +117,7 @@ public class UploadRemoteFileOperation extends RemoteOperation { ((ProgressiveDataTransferer)mEntity) .addDatatransferProgressListeners(mDataTransferListeners); } + mPutMethod.addRequestHeader(OC_TOTAL_LENGTH_HEADER, String.valueOf(f.length())); mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); From 21c329aa126833119f4bc6ed06a3f3881964246f Mon Sep 17 00:00:00 2001 From: masensio Date: Mon, 13 Apr 2015 13:30:31 +0200 Subject: [PATCH 003/101] Set new pattern for account name --- .../lib/common/accounts/AccountUtils.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/com/owncloud/android/lib/common/accounts/AccountUtils.java b/src/com/owncloud/android/lib/common/accounts/AccountUtils.java index 586fd3f8..be7bafab 100644 --- a/src/com/owncloud/android/lib/common/accounts/AccountUtils.java +++ b/src/com/owncloud/android/lib/common/accounts/AccountUtils.java @@ -199,7 +199,7 @@ public class AccountUtils { } - public static String buildAccountName(Uri serverBaseUrl, String username) { + public static String buildAccountNameOld(Uri serverBaseUrl, String username) { if (serverBaseUrl.getScheme() == null) { serverBaseUrl = Uri.parse("https://" + serverBaseUrl.toString()); } @@ -209,7 +209,21 @@ public class AccountUtils { } return accountName; } - + + public static String buildAccountName(Uri serverBaseUrl, String username) { + if (serverBaseUrl.getScheme() == null) { + serverBaseUrl = Uri.parse("https://" + serverBaseUrl.toString()); + } + + // Remove http:// or https:// + String url = serverBaseUrl.toString(); + if (url.contains("://")) { + url = url.substring(serverBaseUrl.toString().indexOf("://") + 3); + } + String accountName = username + "@" + url; + + return accountName; + } public static void saveClient(OwnCloudClient client, Account savedAccount, Context context) { From ddb8648809b7e5c91ec6d081ccdb0597dbebd520 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Wed, 15 Apr 2015 12:49:45 +0200 Subject: [PATCH 004/101] Added version for OC accounts --- .../android/lib/common/accounts/AccountUtils.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/com/owncloud/android/lib/common/accounts/AccountUtils.java b/src/com/owncloud/android/lib/common/accounts/AccountUtils.java index be7bafab..02a12bd8 100644 --- a/src/com/owncloud/android/lib/common/accounts/AccountUtils.java +++ b/src/com/owncloud/android/lib/common/accounts/AccountUtils.java @@ -350,12 +350,18 @@ public class AccountUtils { public static final String KEY_SUPPORTS_SAML_WEB_SSO = "oc_supports_saml_web_sso"; /** * Flag signaling if the ownCloud server supports Share API" - */ + * @deprecated + */ public static final String KEY_SUPPORTS_SHARE_API = "oc_supports_share_api"; /** - * OC accout cookies + * OC account cookies */ public static final String KEY_COOKIES = "oc_account_cookies"; - } + + /** + * OC account version + */ + public static final String KEY_OC_ACCOUNT_VERSION = "oc_account_version"; + } } From 0e7319e4ed4ef067f33ff2f64e37bc7045cb8d73 Mon Sep 17 00:00:00 2001 From: masensio Date: Mon, 11 May 2015 14:29:55 +0200 Subject: [PATCH 005/101] Adapt WebDav parser for receiving exponential values in QUOTAS --- .../lib/common/network/WebdavEntry.java | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/com/owncloud/android/lib/common/network/WebdavEntry.java b/src/com/owncloud/android/lib/common/network/WebdavEntry.java index e5c5b764..4363c263 100644 --- a/src/com/owncloud/android/lib/common/network/WebdavEntry.java +++ b/src/com/owncloud/android/lib/common/network/WebdavEntry.java @@ -24,6 +24,7 @@ package com.owncloud.android.lib.common.network; +import java.math.BigDecimal; import java.util.Date; import org.apache.jackrabbit.webdav.MultiStatusResponse; @@ -37,6 +38,9 @@ import android.net.Uri; import com.owncloud.android.lib.common.utils.Log_OC; public class WebdavEntry { + + private static final String TAG = WebdavEntry.class.getSimpleName(); + public static final String NAMESPACE_OC = "http://owncloud.org/ns"; public static final String EXTENDED_PROPERTY_NAME_PERMISSIONS = "permissions"; public static final String EXTENDED_PROPERTY_NAME_REMOTE_ID = "id"; @@ -131,14 +135,29 @@ public class WebdavEntry { // {DAV:}quota-used-bytes prop = propSet.get(DavPropertyName.create(PROPERTY_QUOTA_USED_BYTES)); if (prop != null) { - mQuotaUsedBytes = Long.parseLong((String) prop.getValue()); + String quotaUsedBytesSt = (String) prop.getValue(); + try { + mQuotaUsedBytes = Long.parseLong(quotaUsedBytesSt); + } catch (NumberFormatException e) { + BigDecimal bd = new BigDecimal(quotaUsedBytesSt); + mQuotaUsedBytes = bd.longValue(); + } + Log_OC.d(TAG , "QUOTA_USED_BYTES " + quotaUsedBytesSt ); } // {DAV:}quota-available-bytes prop = propSet.get(DavPropertyName.create(PROPERTY_QUOTA_AVAILABLE_BYTES)); if (prop != null) { - mQuotaAvailableBytes = Long.parseLong((String) prop.getValue()); + String quotaAvailableBytesSt = (String) prop.getValue(); + try { + mQuotaAvailableBytes = Long.parseLong(quotaAvailableBytesSt); + } catch (NumberFormatException e) { + BigDecimal bd = new BigDecimal(quotaAvailableBytesSt); + mQuotaAvailableBytes = bd.longValue(); + } + Log_OC.d(TAG , "QUOTA_AVAILABLE_BYTES " + quotaAvailableBytesSt ); } + // OC permissions property prop = propSet.get( EXTENDED_PROPERTY_NAME_PERMISSIONS, Namespace.getNamespace(NAMESPACE_OC) From 0449645fca037f65ee66fa4ef3c055000ef98e93 Mon Sep 17 00:00:00 2001 From: masensio Date: Fri, 15 May 2015 10:51:34 +0200 Subject: [PATCH 006/101] Changes from comments in PR#63 --- .../lib/common/network/WebdavEntry.java | 22 +++++++++---------- .../lib/resources/files/RemoteFile.java | 21 +++++++++--------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/com/owncloud/android/lib/common/network/WebdavEntry.java b/src/com/owncloud/android/lib/common/network/WebdavEntry.java index 4363c263..8deb7e22 100644 --- a/src/com/owncloud/android/lib/common/network/WebdavEntry.java +++ b/src/com/owncloud/android/lib/common/network/WebdavEntry.java @@ -53,7 +53,7 @@ public class WebdavEntry { private String mName, mPath, mUri, mContentType, mEtag, mPermissions, mRemoteId; private long mContentLength, mCreateTimestamp, mModifiedTimestamp, mSize; - private long mQuotaUsedBytes, mQuotaAvailableBytes; + private BigDecimal mQuotaUsedBytes, mQuotaAvailableBytes; public WebdavEntry(MultiStatusResponse ms, String splitElement) { resetData(); @@ -137,10 +137,9 @@ public class WebdavEntry { if (prop != null) { String quotaUsedBytesSt = (String) prop.getValue(); try { - mQuotaUsedBytes = Long.parseLong(quotaUsedBytesSt); + mQuotaUsedBytes = new BigDecimal(quotaUsedBytesSt); } catch (NumberFormatException e) { - BigDecimal bd = new BigDecimal(quotaUsedBytesSt); - mQuotaUsedBytes = bd.longValue(); + Log_OC.w(TAG, "No value for QuotaUsedBytes"); } Log_OC.d(TAG , "QUOTA_USED_BYTES " + quotaUsedBytesSt ); } @@ -150,10 +149,9 @@ public class WebdavEntry { if (prop != null) { String quotaAvailableBytesSt = (String) prop.getValue(); try { - mQuotaAvailableBytes = Long.parseLong(quotaAvailableBytesSt); - } catch (NumberFormatException e) { - BigDecimal bd = new BigDecimal(quotaAvailableBytesSt); - mQuotaAvailableBytes = bd.longValue(); + mQuotaAvailableBytes = new BigDecimal(quotaAvailableBytesSt); + } catch (NumberFormatException e) { + Log_OC.w(TAG, "No value for QuotaAvailableBytes"); } Log_OC.d(TAG , "QUOTA_AVAILABLE_BYTES " + quotaAvailableBytesSt ); } @@ -241,11 +239,11 @@ public class WebdavEntry { return mSize; } - public long quotaUsedBytes() { + public BigDecimal quotaUsedBytes() { return mQuotaUsedBytes; } - public long quotaAvailableBytes() { + public BigDecimal quotaAvailableBytes() { return mQuotaAvailableBytes; } @@ -253,7 +251,7 @@ public class WebdavEntry { mName = mUri = mContentType = mPermissions = null; mRemoteId = null; mContentLength = mCreateTimestamp = mModifiedTimestamp = 0; mSize = 0; - mQuotaUsedBytes = 0; - mQuotaAvailableBytes = 0; + mQuotaUsedBytes = null; + mQuotaAvailableBytes = null; } } diff --git a/src/com/owncloud/android/lib/resources/files/RemoteFile.java b/src/com/owncloud/android/lib/resources/files/RemoteFile.java index 1a5d13f9..6be850b2 100644 --- a/src/com/owncloud/android/lib/resources/files/RemoteFile.java +++ b/src/com/owncloud/android/lib/resources/files/RemoteFile.java @@ -25,6 +25,7 @@ package com.owncloud.android.lib.resources.files; import java.io.Serializable; +import java.math.BigDecimal; import android.os.Parcel; import android.os.Parcelable; @@ -51,8 +52,8 @@ public class RemoteFile implements Parcelable, Serializable { private String mPermissions; private String mRemoteId; private long mSize; - private long mQuotaUsedBytes; - private long mQuotaAvailableBytes; + private BigDecimal mQuotaUsedBytes; + private BigDecimal mQuotaAvailableBytes; /** * Getters and Setters @@ -130,11 +131,11 @@ public class RemoteFile implements Parcelable, Serializable { mSize = size; } - public void setQuotaUsedBytes (long quotaUsedBytes) { + public void setQuotaUsedBytes (BigDecimal quotaUsedBytes) { mQuotaUsedBytes = quotaUsedBytes; } - public void setQuotaAvailableBytes (long quotaAvailableBytes) { + public void setQuotaAvailableBytes (BigDecimal quotaAvailableBytes) { mQuotaAvailableBytes = quotaAvailableBytes; } @@ -184,8 +185,8 @@ public class RemoteFile implements Parcelable, Serializable { mPermissions = null; mRemoteId = null; mSize = 0; - mQuotaUsedBytes = 0; - mQuotaAvailableBytes = 0; + mQuotaUsedBytes = null; + mQuotaAvailableBytes = null; } /** @@ -223,8 +224,8 @@ public class RemoteFile implements Parcelable, Serializable { mPermissions= source.readString(); mRemoteId = source.readString(); mSize = source.readLong(); - mQuotaUsedBytes = source.readLong(); - mQuotaAvailableBytes = source.readLong(); + mQuotaUsedBytes = (BigDecimal) source.readSerializable(); + mQuotaAvailableBytes = (BigDecimal) source.readSerializable(); } @Override @@ -243,8 +244,8 @@ public class RemoteFile implements Parcelable, Serializable { dest.writeString(mPermissions); dest.writeString(mRemoteId); dest.writeLong(mSize); - dest.writeLong(mQuotaUsedBytes); - dest.writeLong(mQuotaAvailableBytes); + dest.writeSerializable(mQuotaUsedBytes); + dest.writeSerializable(mQuotaAvailableBytes); } } From 409e8d667162cda15e58cba4f7a1e14fcf971dfa Mon Sep 17 00:00:00 2001 From: masensio Date: Tue, 26 May 2015 13:43:30 +0200 Subject: [PATCH 007/101] Fix problems reading quota values: NullPointerException --- .../owncloud/android/lib/common/network/WebdavEntry.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/com/owncloud/android/lib/common/network/WebdavEntry.java b/src/com/owncloud/android/lib/common/network/WebdavEntry.java index 8deb7e22..1979cbc8 100644 --- a/src/com/owncloud/android/lib/common/network/WebdavEntry.java +++ b/src/com/owncloud/android/lib/common/network/WebdavEntry.java @@ -139,7 +139,9 @@ public class WebdavEntry { try { mQuotaUsedBytes = new BigDecimal(quotaUsedBytesSt); } catch (NumberFormatException e) { - Log_OC.w(TAG, "No value for QuotaUsedBytes"); + Log_OC.w(TAG, "No value for QuotaUsedBytes - NumberFormatException"); + } catch (NullPointerException e ){ + Log_OC.w(TAG, "No value for QuotaUsedBytes - NullPointerException"); } Log_OC.d(TAG , "QUOTA_USED_BYTES " + quotaUsedBytesSt ); } @@ -151,6 +153,8 @@ public class WebdavEntry { try { mQuotaAvailableBytes = new BigDecimal(quotaAvailableBytesSt); } catch (NumberFormatException e) { + Log_OC.w(TAG, "No value for QuotaAvailableBytes - NumberFormatException"); + } catch (NullPointerException e ){ Log_OC.w(TAG, "No value for QuotaAvailableBytes"); } Log_OC.d(TAG , "QUOTA_AVAILABLE_BYTES " + quotaAvailableBytesSt ); From 9fc332eef9733ad1d857ea2b470b260b271fd3ca Mon Sep 17 00:00:00 2001 From: masensio Date: Tue, 2 Jun 2015 09:37:46 +0200 Subject: [PATCH 008/101] Filter only '/' character in user input when version of server is 8.1 or later --- .../android/lib/common/OwnCloudClient.java | 11 +++++++ .../files/CreateRemoteFolderOperation.java | 4 +-- .../lib/resources/files/FileUtils.java | 32 ++++++++++++------- .../files/MoveRemoteFileOperation.java | 3 +- .../files/RenameRemoteFileOperation.java | 3 +- .../lib/resources/status/OwnCloudVersion.java | 6 ++++ 6 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/com/owncloud/android/lib/common/OwnCloudClient.java b/src/com/owncloud/android/lib/common/OwnCloudClient.java index b6804708..83ec07ad 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudClient.java +++ b/src/com/owncloud/android/lib/common/OwnCloudClient.java @@ -51,6 +51,7 @@ import com.owncloud.android.lib.common.OwnCloudCredentialsFactory.OwnCloudAnonym import com.owncloud.android.lib.common.accounts.AccountUtils; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.status.OwnCloudVersion; public class OwnCloudClient extends HttpClient { @@ -67,6 +68,8 @@ public class OwnCloudClient extends HttpClient { private int mInstanceNumber = 0; private Uri mBaseUri; + + private OwnCloudVersion mVersion = null; /** * Constructor @@ -436,4 +439,12 @@ public class OwnCloudClient extends HttpClient { } + public void setOwnCloudVersion(String version){ + OwnCloudVersion ver = new OwnCloudVersion(version); + mVersion = ver; + } + + public OwnCloudVersion getOwnCloudVersion(){ + return mVersion; + } } diff --git a/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java b/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java index 0d248e6f..0bfbb453 100644 --- a/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java +++ b/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java @@ -24,7 +24,6 @@ package com.owncloud.android.lib.resources.files; -import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.client.methods.MkColMethod; import com.owncloud.android.lib.common.OwnCloudClient; @@ -73,7 +72,8 @@ public class CreateRemoteFolderOperation extends RemoteOperation { @Override protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; - boolean noInvalidChars = FileUtils.isValidPath(mRemotePath); + boolean noInvalidChars = FileUtils.isValidPath(mRemotePath, + client.getOwnCloudVersion().isVersionWithForbiddenCharacters()); if (noInvalidChars) { result = createFolder(client); if (!result.isSuccess() && mCreateFullPath && diff --git a/src/com/owncloud/android/lib/resources/files/FileUtils.java b/src/com/owncloud/android/lib/resources/files/FileUtils.java index a6fd29f6..e04e3bbf 100644 --- a/src/com/owncloud/android/lib/resources/files/FileUtils.java +++ b/src/com/owncloud/android/lib/resources/files/FileUtils.java @@ -27,9 +27,12 @@ package com.owncloud.android.lib.resources.files; import java.io.File; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.status.OwnCloudVersion; public class FileUtils { + private static final String TAG = FileUtils.class.getSimpleName(); + public static final String PATH_SEPARATOR = "/"; @@ -40,39 +43,44 @@ public class FileUtils { } /** - * Validate the fileName to detect if contains any forbidden character: / , \ , < , > , : , " , | , ? , * + * Validate the fileName to detect if contains any forbidden character: / , \ , < , > , + * : , " , | , ? , * * @param fileName + * @param versionSupportsForbiddenChars * @return */ - public static boolean isValidName(String fileName) { + public static boolean isValidName(String fileName, boolean versionSupportsForbiddenChars) { boolean result = true; - Log_OC.d("FileUtils", "fileName =======" + fileName); - if (fileName.contains(PATH_SEPARATOR) || + Log_OC.d(TAG, "fileName =======" + fileName); + if ( (versionSupportsForbiddenChars && fileName.contains(PATH_SEPARATOR)) || + (!versionSupportsForbiddenChars && ( fileName.contains(PATH_SEPARATOR) || fileName.contains("\\") || fileName.contains("<") || fileName.contains(">") || - fileName.contains(":") || fileName.contains("\"") || fileName.contains("|") || - fileName.contains("?") || fileName.contains("*")) { + fileName.contains(":") || fileName.contains("\"") || fileName.contains("|") || + fileName.contains("?") || fileName.contains("*") ) ) ) { + result = false; } return result; } /** - * Validate the path to detect if contains any forbidden character: \ , < , > , : , " , | , ? , * + * Validate the path to detect if contains any forbidden character: \ , < , > , : , " , | , + * ? , * * @param path * @return */ - public static boolean isValidPath(String path) { + public static boolean isValidPath(String path, boolean versionSupportsForbidenChars) { boolean result = true; - Log_OC.d("FileUtils", "path ....... " + path); - if (path.contains("\\") || path.contains("<") || path.contains(">") || + Log_OC.d(TAG, "path ....... " + path); + if (!versionSupportsForbidenChars && + (path.contains("\\") || path.contains("<") || path.contains(">") || path.contains(":") || path.contains("\"") || path.contains("|") || - path.contains("?") || path.contains("*")) { + path.contains("?") || path.contains("*") ) ){ result = false; } return result; } - } diff --git a/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java index 1eb88765..f1535eb1 100644 --- a/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java @@ -89,7 +89,8 @@ public class MoveRemoteFileOperation extends RemoteOperation { protected RemoteOperationResult run(OwnCloudClient client) { /// check parameters - if (!FileUtils.isValidPath(mTargetRemotePath)) { + if (!FileUtils.isValidPath(mTargetRemotePath, + client.getOwnCloudVersion().isVersionWithForbiddenCharacters())) { return new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME); } diff --git a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java index 4dc4c2c2..fa928b7c 100644 --- a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java @@ -89,7 +89,8 @@ public class RenameRemoteFileOperation extends RemoteOperation { LocalMoveMethod move = null; - boolean noInvalidChars = FileUtils.isValidPath(mNewRemotePath); + boolean noInvalidChars = FileUtils.isValidPath(mNewRemotePath, + client.getOwnCloudVersion().isVersionWithForbiddenCharacters()); if (noInvalidChars) { try { diff --git a/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java b/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java index eb56f2d2..aa89cf3d 100644 --- a/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java +++ b/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java @@ -38,6 +38,8 @@ public class OwnCloudVersion implements Comparable { 0x04050000); public static final int MINIMUM_VERSION_FOR_SHARING_API = 0x05001B00; // 5.0.27 + + public static final int MINIMUM_VERSION_WITH_FORBIDDEN_CHARS = 0x08010000; // 8.1 private static final int MAX_DOTS = 3; @@ -120,6 +122,10 @@ public class OwnCloudVersion implements Comparable { public boolean isSharedSupported() { return (mVersion >= MINIMUM_VERSION_FOR_SHARING_API); } + + public boolean isVersionWithForbiddenCharacters() { + return (mVersion >= MINIMUM_VERSION_WITH_FORBIDDEN_CHARS); + } } From 2b09aa2a89eb38a9abc8e98d3a1bc356f5872a1e Mon Sep 17 00:00:00 2001 From: masensio Date: Tue, 2 Jun 2015 13:07:43 +0200 Subject: [PATCH 009/101] Parse and show the error of invalid characters coming from the server side. Show new message in CreationFolder --- .../InvalidCharacterExceptionParser.java | 144 ++++++++++++++++++ .../operations/RemoteOperationResult.java | 64 ++++++-- .../files/CreateRemoteFolderOperation.java | 14 +- 3 files changed, 209 insertions(+), 13 deletions(-) create mode 100644 src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java diff --git a/src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java b/src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java new file mode 100644 index 00000000..7f72efe9 --- /dev/null +++ b/src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java @@ -0,0 +1,144 @@ + +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2015 ownCloud Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package com.owncloud.android.lib.common.operations; + +import android.util.Xml; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Parser for Invalid Character server exception + * @author masensio on 02/06/2015. + */ +public class InvalidCharacterExceptionParser { + + private static final String EXCEPTION_STRING = "OC\\Connector\\Sabre\\Exception\\InvalidPath"; + + // No namespaces + private static final String ns = null; + + // Nodes for XML Parser + private static final String NODE_ERROR = "d:error"; + private static final String NODE_EXCEPTION = "s:exception"; + /** + * Parse is as response of Share API + * @param is + * @return if The exception is an Invalid Char Exception + * @throws XmlPullParserException + * @throws IOException + */ + public boolean parseXMLResponse(InputStream is) throws XmlPullParserException, + IOException { + boolean result = false; + + try { + // XMLPullParser + XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); + factory.setNamespaceAware(true); + + XmlPullParser parser = Xml.newPullParser(); + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); + parser.setInput(is, null); + parser.nextTag(); + result = readError(parser); + + } finally { + is.close(); + } + return result; + } + + /** + * Parse OCS node + * @param parser + * @return List of ShareRemoteFiles + * @throws XmlPullParserException + * @throws IOException + */ + private boolean readError (XmlPullParser parser) throws XmlPullParserException, IOException { + String exception = ""; + parser.require(XmlPullParser.START_TAG, ns , NODE_ERROR); + while (parser.next() != XmlPullParser.END_TAG) { + if (parser.getEventType() != XmlPullParser.START_TAG) { + continue; + } + String name = parser.getName(); + // read NODE_EXCEPTION + if (name.equalsIgnoreCase(NODE_EXCEPTION)) { + exception = readText(parser); + } else { + skip(parser); + } + + } + return exception.equalsIgnoreCase(EXCEPTION_STRING); + + + } + + /** + * Skip tags in parser procedure + * @param parser + * @throws XmlPullParserException + * @throws IOException + */ + private void skip(XmlPullParser parser) throws XmlPullParserException, IOException { + if (parser.getEventType() != XmlPullParser.START_TAG) { + throw new IllegalStateException(); + } + int depth = 1; + while (depth != 0) { + switch (parser.next()) { + case XmlPullParser.END_TAG: + depth--; + break; + case XmlPullParser.START_TAG: + depth++; + break; + } + } + } + + /** + * Read the text from a node + * @param parser + * @return Text of the node + * @throws IOException + * @throws XmlPullParserException + */ + private String readText(XmlPullParser parser) throws IOException, XmlPullParserException { + String result = ""; + if (parser.next() == XmlPullParser.TEXT) { + result = parser.getText(); + parser.nextTag(); + } + return result; + } +} diff --git a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java index 56492955..89848ac9 100644 --- a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java +++ b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java @@ -24,7 +24,9 @@ package com.owncloud.android.lib.common.operations; +import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.Serializable; import java.net.MalformedURLException; import java.net.SocketException; @@ -40,6 +42,7 @@ import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.DavException; import org.json.JSONException; +import org.xmlpull.v1.XmlPullParserException; import android.accounts.Account; import android.accounts.AccountsException; @@ -47,6 +50,7 @@ import android.accounts.AccountsException; import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; import com.owncloud.android.lib.common.network.CertificateCombinedException; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.shares.ShareXMLParser; /** @@ -103,7 +107,8 @@ public class RemoteOperationResult implements Serializable { SHARE_FORBIDDEN, OK_REDIRECT_TO_NON_SECURE_CONNECTION, INVALID_MOVE_INTO_DESCENDANT, - PARTIAL_MOVE_DONE + PARTIAL_MOVE_DONE, + INVALID_CHARACTER_DETECT_IN_SERVER } private boolean mSuccess = false; @@ -117,7 +122,9 @@ public class RemoteOperationResult implements Serializable { public RemoteOperationResult(ResultCode code) { mCode = code; - mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || code == ResultCode.OK_NO_SSL || code == ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION); + mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || + code == ResultCode.OK_NO_SSL || + code == ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION); mData = null; } @@ -147,10 +154,11 @@ public class RemoteOperationResult implements Serializable { break; case HttpStatus.SC_FORBIDDEN: mCode = ResultCode.FORBIDDEN; - break; + break; default: mCode = ResultCode.UNHANDLED_HTTP_CODE; - Log_OC.d(TAG, "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " + httpCode); + Log_OC.d(TAG, "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " + + httpCode); } } } @@ -171,7 +179,38 @@ public class RemoteOperationResult implements Serializable { } } } - } + } + + public RemoteOperationResult(boolean success, String bodyResponse, int httpCode) { + mSuccess = success; + mHttpCode = httpCode; + + if (success) { + mCode = ResultCode.OK; + + } else if (httpCode > 0) { + switch (httpCode) { + case HttpStatus.SC_BAD_REQUEST: + + InputStream is = new ByteArrayInputStream(bodyResponse.getBytes()); + InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); + try { + if (xmlParser.parseXMLResponse(is)) + mCode = ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER; + + } catch (Exception e) { + mCode = ResultCode.UNHANDLED_HTTP_CODE; + Log_OC.e(TAG, "Exception reading exception from server", e); + } + break; + default: + mCode = ResultCode.UNHANDLED_HTTP_CODE; + Log_OC.d(TAG, "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " + + httpCode); + } + } + + } public RemoteOperationResult(Exception e) { mException = e; @@ -264,7 +303,8 @@ public class RemoteOperationResult implements Serializable { } Throwable cause = mException.getCause(); Throwable previousCause = null; - while (cause != null && cause != previousCause && !(cause instanceof CertificateCombinedException)) { + while (cause != null && cause != previousCause && + !(cause instanceof CertificateCombinedException)) { previousCause = cause; cause = cause.getCause(); } @@ -314,8 +354,10 @@ public class RemoteOperationResult implements Serializable { return "Unrecovered transport exception"; } else if (mException instanceof AccountNotFoundException) { - Account failedAccount = ((AccountNotFoundException)mException).getFailedAccount(); - return mException.getMessage() + " (" + (failedAccount != null ? failedAccount.name : "NULL") + ")"; + Account failedAccount = + ((AccountNotFoundException)mException).getFailedAccount(); + return mException.getMessage() + " (" + + (failedAccount != null ? failedAccount.name : "NULL") + ")"; } else if (mException instanceof AccountsException) { return "Exception while using account"; @@ -352,7 +394,8 @@ public class RemoteOperationResult implements Serializable { 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") + ")"; } @@ -384,7 +427,8 @@ public class RemoteOperationResult implements Serializable { * @return boolean true/false */ public boolean isNonSecureRedirection() { - return (mRedirectedLocation != null && !(mRedirectedLocation.toLowerCase().startsWith("https://"))); + return (mRedirectedLocation != null && + !(mRedirectedLocation.toLowerCase().startsWith("https://"))); } public String getAuthenticateHeader() { diff --git a/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java b/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java index 0bfbb453..89078ba3 100644 --- a/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java +++ b/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java @@ -28,6 +28,7 @@ import org.apache.jackrabbit.webdav.client.methods.MkColMethod; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.WebdavUtils; +import com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; @@ -98,9 +99,16 @@ public class CreateRemoteFolderOperation extends RemoteOperation { try { mkcol = new MkColMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath)); int status = client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT); - result = new RemoteOperationResult(mkcol.succeeded(), status, mkcol.getResponseHeaders()); - Log_OC.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage()); - client.exhaustResponse(mkcol.getResponseBodyAsStream()); + if ( status == 400 ) { + result = new RemoteOperationResult(mkcol.succeeded(), + mkcol.getResponseBodyAsString(), status); + Log_OC.d(TAG, mkcol.getResponseBodyAsString()); + + } else { + result = new RemoteOperationResult(mkcol.succeeded(), status, mkcol.getResponseHeaders()); + Log_OC.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage()); + } + client.exhaustResponse(mkcol.getResponseBodyAsStream()); } catch (Exception e) { result = new RemoteOperationResult(e); From 16c91473834c52e1493cb39c38654930e20b42a3 Mon Sep 17 00:00:00 2001 From: masensio Date: Wed, 3 Jun 2015 00:32:19 +0200 Subject: [PATCH 010/101] Parse and show the error of invalid characters coming from the server side: Move, Rename, Uploads --- .../operations/RemoteOperationResult.java | 10 ++++----- .../ChunkedUploadRemoteFileOperation.java | 17 +++++++++----- .../files/MoveRemoteFileOperation.java | 22 +++++++++++-------- .../files/RenameRemoteFileOperation.java | 20 ++++++++++------- .../files/UploadRemoteFileOperation.java | 15 +++++++++---- 5 files changed, 51 insertions(+), 33 deletions(-) diff --git a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java index 89848ac9..2d9d957f 100644 --- a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java +++ b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java @@ -42,7 +42,6 @@ import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.DavException; import org.json.JSONException; -import org.xmlpull.v1.XmlPullParserException; import android.accounts.Account; import android.accounts.AccountsException; @@ -50,7 +49,6 @@ import android.accounts.AccountsException; import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; import com.owncloud.android.lib.common.network.CertificateCombinedException; import com.owncloud.android.lib.common.utils.Log_OC; -import com.owncloud.android.lib.resources.shares.ShareXMLParser; /** @@ -64,10 +62,10 @@ import com.owncloud.android.lib.resources.shares.ShareXMLParser; public class RemoteOperationResult implements Serializable { /** Generated - should be refreshed every time the class changes!! */; - private static final long serialVersionUID = -9003837206000993465L; - - private static final String TAG = "RemoteOperationResult"; - + private static final long serialVersionUID = -4184015692120731701L; + + private static final String TAG = RemoteOperationResult.class.getSimpleName(); + public enum ResultCode { OK, OK_SSL, diff --git a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java index 15284adb..1ae71bd8 100644 --- a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java @@ -46,7 +46,7 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation private static final String OC_CHUNKED_HEADER = "OC-Chunked"; private static final String TAG = ChunkedUploadRemoteFileOperation.class.getSimpleName(); - public ChunkedUploadRemoteFileOperation(String storagePath, String remotePath, String mimeType) { + public ChunkedUploadRemoteFileOperation(String storagePath, String remotePath, String mimeType){ super(storagePath, remotePath, mimeType); } @@ -61,17 +61,21 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation raf = new RandomAccessFile(file, "r"); channel = raf.getChannel(); mEntity = new ChunkFromFileChannelRequestEntity(channel, mMimeType, CHUNK_SIZE, file); - //((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(getDataTransferListeners()); + //((ProgressiveDataTransferer)mEntity). + // addDatatransferProgressListeners(getDataTransferListeners()); synchronized (mDataTransferListeners) { - ((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(mDataTransferListeners); + ((ProgressiveDataTransferer)mEntity) + .addDatatransferProgressListeners(mDataTransferListeners); } long offset = 0; - String uriPrefix = client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath) + "-chunking-" + Math.abs((new Random()).nextInt(9000)+1000) + "-" ; + String uriPrefix = client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath) + + "-chunking-" + Math.abs((new Random()).nextInt(9000)+1000) + "-" ; long chunkCount = (long) Math.ceil((double)file.length() / CHUNK_SIZE); for (int chunkIndex = 0; chunkIndex < chunkCount ; chunkIndex++, offset += CHUNK_SIZE) { if (mPutMethod != null) { - mPutMethod.releaseConnection(); // let the connection available for other methods + mPutMethod.releaseConnection(); // let the connection available + // for other methods } mPutMethod = new PutMethod(uriPrefix + chunkCount + "-" + chunkIndex); mPutMethod.addRequestHeader(OC_CHUNKED_HEADER, OC_CHUNKED_HEADER); @@ -80,7 +84,8 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); - Log_OC.d(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ", chunk index " + chunkIndex + ", count " + chunkCount + ", HTTP result status " + status); + Log_OC.d(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ", chunk index " + + chunkIndex + ", count " + chunkCount + ", HTTP result status " + status); if (!isSuccess(status)) break; } diff --git a/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java index f1535eb1..c2fb651a 100644 --- a/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java @@ -39,6 +39,7 @@ import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.lib.common.utils.Log_OC; /** @@ -129,15 +130,18 @@ public class MoveRemoteFileOperation extends RemoteOperation { /// for other errors that could be explicitly handled, check first: /// http://www.webdav.org/specs/rfc4918.html#rfc.section.9.9.4 - } else { - - result = new RemoteOperationResult( - isSuccess(status), // move.succeeded()? trustful? - status, - move.getResponseHeaders() - ); - client.exhaustResponse(move.getResponseBodyAsStream()); - } + } else if (status == 400) { + result = new RemoteOperationResult(move.succeeded(), + move.getResponseBodyAsString(), status); + Log_OC.d(TAG, move.getResponseBodyAsString()); + } else { + result = new RemoteOperationResult( + isSuccess(status), // move.succeeded()? trustful? + status, + move.getResponseHeaders() + ); + client.exhaustResponse(move.getResponseBodyAsStream()); + } Log.i(TAG, "Move " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage()); diff --git a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java index fa928b7c..7f449560 100644 --- a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java @@ -94,11 +94,9 @@ public class RenameRemoteFileOperation extends RemoteOperation { if (noInvalidChars) { try { - if (mNewName.equals(mOldName)) { return new RemoteOperationResult(ResultCode.OK); } - // check if a file with the new name already exists if (client.existsFile(mNewRemotePath)) { @@ -109,12 +107,18 @@ public class RenameRemoteFileOperation extends RemoteOperation { WebdavUtils.encodePath(mOldRemotePath), client.getWebdavUri() + WebdavUtils.encodePath(mNewRemotePath)); int status = client.executeMethod(move, RENAME_READ_TIMEOUT, RENAME_CONNECTION_TIMEOUT); - - move.getResponseBodyAsString(); // exhaust response, although not interesting - result = new RemoteOperationResult(move.succeeded(), status, move.getResponseHeaders()); - Log_OC.i(TAG, "Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " + - result.getLogMessage()); - + + if (status == 400) { + result = new RemoteOperationResult(move.succeeded(), + move.getResponseBodyAsString(), status); + Log_OC.d(TAG, move.getResponseBodyAsString()); + } else { + move.getResponseBodyAsString(); // exhaust response, although not interesting + result = new RemoteOperationResult(move.succeeded(), status, + move.getResponseHeaders()); + Log_OC.i(TAG, "Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " + + result.getLogMessage()); + } } catch (Exception e) { result = new RemoteOperationResult(e); Log_OC.e(TAG, "Rename " + mOldRemotePath + " to " + diff --git a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java index 9043fe36..e3b2ff63 100644 --- a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java @@ -43,6 +43,7 @@ import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.OperationCancelledException; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.utils.Log_OC; /** * Remote operation performing the upload of a remote file to the ownCloud server. @@ -53,6 +54,8 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult; public class UploadRemoteFileOperation extends RemoteOperation { + private static final String TAG = UploadRemoteFileOperation.class.getSimpleName(); + protected static final String OC_TOTAL_LENGTH_HEADER = "OC-Total-Length"; protected String mLocalPath; @@ -87,10 +90,14 @@ public class UploadRemoteFileOperation extends RemoteOperation { } int status = uploadFile(client); - - result = new RemoteOperationResult(isSuccess(status), status, - (mPutMethod != null ? mPutMethod.getResponseHeaders() : null)); - + if (status == 400) { + result = new RemoteOperationResult(isSuccess(status), + mPutMethod.getResponseBodyAsString(), status); + Log_OC.d(TAG, mPutMethod.getResponseBodyAsString()); + } else { + result = new RemoteOperationResult(isSuccess(status), status, + (mPutMethod != null ? mPutMethod.getResponseHeaders() : null)); + } } catch (Exception e) { // TODO something cleaner with cancellations if (mCancellationRequested.get()) { From b8a3eb059c2c139a64876ab0191d72c24ab6f3ee Mon Sep 17 00:00:00 2001 From: masensio Date: Wed, 3 Jun 2015 11:09:32 +0200 Subject: [PATCH 011/101] Remove exhaust response in RenameRemoteFileOperation --- .../files/RenameRemoteFileOperation.java | 70 ++++++++++--------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java index 7f449560..4f27cb69 100644 --- a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java @@ -93,42 +93,44 @@ public class RenameRemoteFileOperation extends RemoteOperation { client.getOwnCloudVersion().isVersionWithForbiddenCharacters()); if (noInvalidChars) { - try { - if (mNewName.equals(mOldName)) { - return new RemoteOperationResult(ResultCode.OK); - } - - // check if a file with the new name already exists - if (client.existsFile(mNewRemotePath)) { - return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE); - } - - move = new LocalMoveMethod( client.getWebdavUri() + - WebdavUtils.encodePath(mOldRemotePath), - client.getWebdavUri() + WebdavUtils.encodePath(mNewRemotePath)); - int status = client.executeMethod(move, RENAME_READ_TIMEOUT, RENAME_CONNECTION_TIMEOUT); + try { + if (mNewName.equals(mOldName)) { + return new RemoteOperationResult(ResultCode.OK); + } - if (status == 400) { - result = new RemoteOperationResult(move.succeeded(), - move.getResponseBodyAsString(), status); - Log_OC.d(TAG, move.getResponseBodyAsString()); - } else { - move.getResponseBodyAsString(); // exhaust response, although not interesting - result = new RemoteOperationResult(move.succeeded(), status, - move.getResponseHeaders()); - Log_OC.i(TAG, "Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " + - result.getLogMessage()); + // check if a file with the new name already exists + if (client.existsFile(mNewRemotePath)) { + return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE); + } + + move = new LocalMoveMethod( client.getWebdavUri() + + WebdavUtils.encodePath(mOldRemotePath), + client.getWebdavUri() + WebdavUtils.encodePath(mNewRemotePath)); + int status = client.executeMethod(move, RENAME_READ_TIMEOUT, + RENAME_CONNECTION_TIMEOUT); + + if (status == 400) { + result = new RemoteOperationResult(move.succeeded(), + move.getResponseBodyAsString(), status); + Log_OC.d(TAG, move.getResponseBodyAsString()); + } else { + client.exhaustResponse(move.getResponseBodyAsStream());//exhaust response, + // although not interesting + result = new RemoteOperationResult(move.succeeded(), status, + move.getResponseHeaders()); + Log_OC.i(TAG, "Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " + + result.getLogMessage()); + } + } catch (Exception e) { + result = new RemoteOperationResult(e); + Log_OC.e(TAG, "Rename " + mOldRemotePath + " to " + + ((mNewRemotePath==null) ? mNewName : mNewRemotePath) + ": " + + result.getLogMessage(), e); + + } finally { + if (move != null) + move.releaseConnection(); } - } catch (Exception e) { - result = new RemoteOperationResult(e); - Log_OC.e(TAG, "Rename " + mOldRemotePath + " to " + - ((mNewRemotePath==null) ? mNewName : mNewRemotePath) + ": " + - result.getLogMessage(), e); - - } finally { - if (move != null) - move.releaseConnection(); - } } else { result = new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME); } From 4ca0ff2203a84173dca984632a1131170a169f08 Mon Sep 17 00:00:00 2001 From: masensio Date: Wed, 3 Jun 2015 11:09:58 +0200 Subject: [PATCH 012/101] Parse error 500 and InvalidPathException for Uploads --- .../InvalidCharacterExceptionParser.java | 8 +++--- .../ChunkedUploadRemoteFileOperation.java | 25 +++++++++++++++-- .../files/UploadRemoteFileOperation.java | 27 ++++++++++++++++--- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java b/src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java index 7f72efe9..63d28319 100644 --- a/src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java +++ b/src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java @@ -35,11 +35,12 @@ import java.io.InputStream; /** * Parser for Invalid Character server exception - * @author masensio on 02/06/2015. + * @author masensio */ public class InvalidCharacterExceptionParser { private static final String EXCEPTION_STRING = "OC\\Connector\\Sabre\\Exception\\InvalidPath"; + private static final String EXCEPTION_UPLOAD_STRING = "OCP\\Files\\InvalidPathException"; // No namespaces private static final String ns = null; @@ -48,7 +49,7 @@ public class InvalidCharacterExceptionParser { private static final String NODE_ERROR = "d:error"; private static final String NODE_EXCEPTION = "s:exception"; /** - * Parse is as response of Share API + * Parse is as an Invalid Path Exception * @param is * @return if The exception is an Invalid Char Exception * @throws XmlPullParserException @@ -98,7 +99,8 @@ public class InvalidCharacterExceptionParser { } } - return exception.equalsIgnoreCase(EXCEPTION_STRING); + return exception.equalsIgnoreCase(EXCEPTION_STRING) || + exception.equalsIgnoreCase(EXCEPTION_UPLOAD_STRING); } diff --git a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java index 1ae71bd8..7ab9e2d8 100644 --- a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java @@ -24,8 +24,10 @@ package com.owncloud.android.lib.resources.files; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.util.Random; @@ -37,6 +39,8 @@ import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.ChunkFromFileChannelRequestEntity; import com.owncloud.android.lib.common.network.ProgressiveDataTransferer; import com.owncloud.android.lib.common.network.WebdavUtils; +import com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; @@ -83,9 +87,26 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation ((ChunkFromFileChannelRequestEntity) mEntity).setOffset(offset); mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); + + // TODO: Detect INVALID_CHARACTER_DETECT_IN SERVER in a better way? + if (status == 400 || status == 500) { + InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); + InputStream is = new ByteArrayInputStream( + mPutMethod.getResponseBodyAsString().getBytes()); + try { + mForbiddenCharsInServer = xmlParser.parseXMLResponse(is); + + } catch (Exception e) { + mForbiddenCharsInServer = false; + Log_OC.e(TAG, "Exception reading exception from server", e); + } + } + client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); - Log_OC.d(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ", chunk index " + - chunkIndex + ", count " + chunkCount + ", HTTP result status " + status); + Log_OC.d(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + + ", chunk index " + chunkIndex + ", count " + chunkCount + + ", HTTP result status " + status); + if (!isSuccess(status)) break; } diff --git a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java index e3b2ff63..9fcd6515 100644 --- a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java @@ -24,8 +24,10 @@ package com.owncloud.android.lib.resources.files; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; @@ -40,6 +42,7 @@ import com.owncloud.android.lib.common.network.FileRequestEntity; import com.owncloud.android.lib.common.network.OnDatatransferProgressListener; import com.owncloud.android.lib.common.network.ProgressiveDataTransferer; import com.owncloud.android.lib.common.network.WebdavUtils; +import com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser; import com.owncloud.android.lib.common.operations.OperationCancelledException; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; @@ -62,6 +65,7 @@ public class UploadRemoteFileOperation extends RemoteOperation { protected String mRemotePath; protected String mMimeType; protected PutMethod mPutMethod = null; + protected boolean mForbiddenCharsInServer = false; private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); protected Set mDataTransferListeners = new HashSet(); @@ -90,10 +94,10 @@ public class UploadRemoteFileOperation extends RemoteOperation { } int status = uploadFile(client); - if (status == 400) { - result = new RemoteOperationResult(isSuccess(status), - mPutMethod.getResponseBodyAsString(), status); - Log_OC.d(TAG, mPutMethod.getResponseBodyAsString()); + // TODO: Detect INVALID_CHARACTER_DETECT_IN SERVER in a better way? + if (mForbiddenCharsInServer){ + result = new RemoteOperationResult( + RemoteOperationResult.ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER); } else { result = new RemoteOperationResult(isSuccess(status), status, (mPutMethod != null ? mPutMethod.getResponseHeaders() : null)); @@ -127,6 +131,21 @@ public class UploadRemoteFileOperation extends RemoteOperation { mPutMethod.addRequestHeader(OC_TOTAL_LENGTH_HEADER, String.valueOf(f.length())); mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); + + // TODO: Detect INVALID_CHARACTER_DETECT_IN SERVER in a better way? + if (status == 400 || status == 500) { + InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); + InputStream is = new ByteArrayInputStream( + mPutMethod.getResponseBodyAsString().getBytes()); + try { + mForbiddenCharsInServer = xmlParser.parseXMLResponse(is); + + } catch (Exception e) { + mForbiddenCharsInServer = false; + Log_OC.e(TAG, "Exception reading exception from server", e); + } + } + client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); } finally { From 41dcc337305839ab76e3196afa335045488eb691 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Thu, 11 Jun 2015 09:39:16 +0200 Subject: [PATCH 013/101] Get that ExistenceCheckRemoteOperation remembers the sequence of followed redirections after its execution Conflicts fixed: src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java --- .../android/lib/common/OwnCloudClient.java | 85 ++++++------ .../lib/common/network/RedirectionPath.java | 127 ++++++++++++++++++ .../operations/RemoteOperationResult.java | 19 ++- .../files/ExistenceCheckRemoteOperation.java | 28 +++- .../files/RenameRemoteFileOperation.java | 4 +- .../shares/RemoveRemoteShareOperation.java | 2 +- .../status/GetRemoteStatusOperation.java | 4 +- 7 files changed, 216 insertions(+), 53 deletions(-) create mode 100644 src/com/owncloud/android/lib/common/network/RedirectionPath.java diff --git a/src/com/owncloud/android/lib/common/OwnCloudClient.java b/src/com/owncloud/android/lib/common/OwnCloudClient.java index b6804708..7364f345 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudClient.java +++ b/src/com/owncloud/android/lib/common/OwnCloudClient.java @@ -49,13 +49,14 @@ import android.net.Uri; import com.owncloud.android.lib.common.OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials; import com.owncloud.android.lib.common.accounts.AccountUtils; +import com.owncloud.android.lib.common.network.RedirectionPath; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.utils.Log_OC; public class OwnCloudClient extends HttpClient { private static final String TAG = OwnCloudClient.class.getSimpleName(); - private static final int MAX_REDIRECTIONS_COUNT = 3; + public static final int MAX_REDIRECTIONS_COUNT = 3; private static final String PARAM_SINGLE_COOKIE_HEADER = "http.protocol.single-cookie-header"; private static final boolean PARAM_SINGLE_COOKIE_HEADER_VALUE = true; @@ -168,13 +169,13 @@ public class OwnCloudClient extends HttpClient { * * The timeouts are both in milliseconds; 0 means 'infinite'; * < 0 means 'do not change the default' - * + * * @param method HTTP method request. * @param readTimeout Timeout to set for data reception * @param connectionTimeout Timeout to set for connection establishment */ - public int executeMethod(HttpMethodBase method, int readTimeout, int connectionTimeout) - throws HttpException, IOException { + public int executeMethod(HttpMethodBase method, int readTimeout, int connectionTimeout) throws IOException { + int oldSoTimeout = getParams().getSoTimeout(); int oldConnectionTimeout = getHttpConnectionManager().getParams().getConnectionTimeout(); try { @@ -191,55 +192,53 @@ public class OwnCloudClient extends HttpClient { getHttpConnectionManager().getParams().setConnectionTimeout(oldConnectionTimeout); } } - - - @Override - public int executeMethod(HttpMethod method) throws IOException, HttpException { - try { // just to log - boolean customRedirectionNeeded = false; - - try { - method.setFollowRedirects(mFollowRedirects); - } catch (Exception e) { - /* - if (mFollowRedirects) - Log_OC.d(TAG, "setFollowRedirects failed for " + method.getName() - + " method, custom redirection will be used if needed"); - */ - customRedirectionNeeded = mFollowRedirects; - } + + /** + * Requests the received method. + * + * Executes the method through the inherited HttpClient.executedMethod(method). + * + * @param method HTTP method request. + */ + @Override + public int executeMethod(HttpMethod method) throws IOException { + try { // Update User Agent HttpParams params = method.getParams(); String userAgent = OwnCloudClientManagerFactory.getUserAgent(); params.setParameter(HttpMethodParams.USER_AGENT, userAgent); - Log_OC.d(TAG + " #" + mInstanceNumber, "REQUEST " + - method.getName() + " " + method.getPath()); - + Log_OC.d(TAG + " #" + mInstanceNumber, "REQUEST " + + method.getName() + " " + method.getPath()); + // logCookiesAtRequest(method.getRequestHeaders(), "before"); // logCookiesAtState("before"); - - int status = super.executeMethod(method); - - if (customRedirectionNeeded) { - status = patchRedirection(status, method); - } + method.setFollowRedirects(false); + + int status = super.executeMethod(method); + + if (mFollowRedirects) { + status = followRedirection(method).getLastStatus(); + } // logCookiesAtRequest(method.getRequestHeaders(), "after"); // logCookiesAtState("after"); // logSetCookiesAtResponse(method.getResponseHeaders()); - - return status; - + + return status; + } catch (IOException e) { - Log_OC.d(TAG + " #" + mInstanceNumber, "Exception occurred", e); - throw e; + //Log_OC.d(TAG + " #" + mInstanceNumber, "Exception occurred", e); + throw e; } } - private int patchRedirection(int status, HttpMethod method) throws HttpException, IOException { + + public RedirectionPath followRedirection(HttpMethod method) throws IOException { int redirectionsCount = 0; + int status = method.getStatusCode(); + RedirectionPath result = new RedirectionPath(status, MAX_REDIRECTIONS_COUNT); while (redirectionsCount < MAX_REDIRECTIONS_COUNT && ( status == HttpStatus.SC_MOVED_PERMANENTLY || status == HttpStatus.SC_MOVED_TEMPORARILY || @@ -254,18 +253,20 @@ public class OwnCloudClient extends HttpClient { Log_OC.d(TAG + " #" + mInstanceNumber, "Location to redirect: " + location.getValue()); + String locationStr = location.getValue(); + result.addLocation(locationStr); + // Release the connection to avoid reach the max number of connections per host // due to it will be set a different url exhaustResponse(method.getResponseBodyAsStream()); method.releaseConnection(); - method.setURI(new URI(location.getValue(), true)); + method.setURI(new URI(locationStr, true)); Header destination = method.getRequestHeader("Destination"); if (destination == null) { destination = method.getRequestHeader("destination"); } if (destination != null) { - String locationStr = location.getValue(); int suffixIndex = locationStr.lastIndexOf( (mCredentials instanceof OwnCloudBearerCredentials) ? AccountUtils.ODAV_PATH : @@ -281,6 +282,7 @@ public class OwnCloudClient extends HttpClient { method.setRequestHeader(destination); } status = super.executeMethod(method); + result.addStatus(status); redirectionsCount++; } else { @@ -288,7 +290,7 @@ public class OwnCloudClient extends HttpClient { status = HttpStatus.SC_NOT_FOUND; } } - return status; + return result; } /** @@ -356,7 +358,10 @@ public class OwnCloudClient extends HttpClient { mFollowRedirects = followRedirects; } - + public boolean getFollowRedirects() { + return mFollowRedirects; + } + private void logCookiesAtRequest(Header[] headers, String when) { int counter = 0; for (int i=0; i= 0; i--) { + if (mStatuses[i] == HttpStatus.SC_MOVED_PERMANENTLY && i <= mLastLocation) { + return mLocations[i]; + } + } + return null; + } + + /** + * @return Count of locations. + */ + public int getRedirectionsCount() { + return mLastLocation + 1; + } + + +} diff --git a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java index 56492955..bde719ae 100644 --- a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java +++ b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java @@ -60,11 +60,11 @@ import com.owncloud.android.lib.common.utils.Log_OC; public class RemoteOperationResult implements Serializable { /** Generated - should be refreshed every time the class changes!! */; - private static final long serialVersionUID = -9003837206000993465L; - - private static final String TAG = "RemoteOperationResult"; - - public enum ResultCode { + private static final long serialVersionUID = 25745846447996048L; + + private static final String TAG = RemoteOperationResult.class.getSimpleName(); + + public enum ResultCode { OK, OK_SSL, OK_NO_SSL, @@ -112,6 +112,7 @@ public class RemoteOperationResult implements Serializable { private ResultCode mCode = ResultCode.UNKNOWN_ERROR; private String mRedirectedLocation; private String mAuthenticate; + private String mLastPermanentLocation = null; private ArrayList mData; @@ -391,4 +392,12 @@ public class RemoteOperationResult implements Serializable { return mAuthenticate; } + public String getLastPermanentLocation() { + return mLastPermanentLocation; + } + + public void setLastPermanentLocation(String lastPermanentLocation) { + mLastPermanentLocation = lastPermanentLocation; + } + } diff --git a/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java b/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java index 154c8b14..4596594b 100644 --- a/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java @@ -31,6 +31,7 @@ import android.content.Context; import android.net.ConnectivityManager; import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.network.RedirectionPath; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; @@ -52,7 +53,10 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation { private Context mContext; private boolean mSuccessIfAbsent; - + /** Sequence of redirections followed. Available only after executing the operation */ + private RedirectionPath mRedirectionPath = null; + // TODO move to {@link RemoteOperation}, that needs a nice refactoring + /** * Full constructor. Success of the operation will depend upon the value of successIfAbsent. * @@ -75,9 +79,13 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation { } RemoteOperationResult result = null; HeadMethod head = null; + boolean previousFollowRedirects = client.getFollowRedirects(); try { head = new HeadMethod(client.getWebdavUri() + WebdavUtils.encodePath(mPath)); - int status = client.executeMethod(head, TIMEOUT, TIMEOUT); + client.setFollowRedirects(false); + client.executeMethod(head, TIMEOUT, TIMEOUT); + mRedirectionPath = client.followRedirection(head); + int status = mRedirectionPath.getLastStatus(); client.exhaustResponse(head.getResponseBodyAsStream()); boolean success = (status == HttpStatus.SC_OK && !mSuccessIfAbsent) || (status == HttpStatus.SC_NOT_FOUND && mSuccessIfAbsent); @@ -97,6 +105,7 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation { } finally { if (head != null) head.releaseConnection(); + client.setFollowRedirects(previousFollowRedirects); } return result; } @@ -109,4 +118,19 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation { } + /** + * Gets the sequence of redirections followed during the execution of the operation. + * + * @return Sequence of redirections followed, if any, or NULL if the operation was not executed. + */ + public RedirectionPath getRedirectionPath() { + return mRedirectionPath; + } + + /** + * @return 'True' if the operation was executed and at least one redirection was followed. + */ + public boolean wasRedirected() { + return (mRedirectionPath != null && mRedirectionPath.getRedirectionsCount() > 0); + } } diff --git a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java index 4dc4c2c2..d3af55f5 100644 --- a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java @@ -93,7 +93,7 @@ public class RenameRemoteFileOperation extends RemoteOperation { if (noInvalidChars) { try { - + if (mNewName.equals(mOldName)) { return new RemoteOperationResult(ResultCode.OK); } @@ -103,7 +103,7 @@ public class RenameRemoteFileOperation extends RemoteOperation { if (client.existsFile(mNewRemotePath)) { return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE); } - + move = new LocalMoveMethod( client.getWebdavUri() + WebdavUtils.encodePath(mOldRemotePath), client.getWebdavUri() + WebdavUtils.encodePath(mNewRemotePath)); diff --git a/src/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.java index dea4fe93..4db29051 100644 --- a/src/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.java @@ -72,7 +72,7 @@ public class RemoveRemoteShareOperation extends RemoteOperation { delete = new DeleteMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH + id); delete.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); - + status = client.executeMethod(delete); if(isSuccess(status)) { diff --git a/src/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.java b/src/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.java index aecc12f3..2b4def0a 100644 --- a/src/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.java +++ b/src/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.java @@ -103,9 +103,7 @@ public class GetRemoteStatusOperation extends RemoteOperation { ); get.releaseConnection(); get = new GetMethod(redirectedLocation); - status = client.executeMethod( - get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT - ); + status = client.executeMethod(get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT); mLatestResult = new RemoteOperationResult( (status == HttpStatus.SC_OK), status, From 1811be1b52a5d80a70eb6a9eab93201cb8063af1 Mon Sep 17 00:00:00 2001 From: masensio Date: Tue, 16 Jun 2015 10:39:40 +0200 Subject: [PATCH 014/101] Prevent NullPointException when OwncloudVersion is null in CreateRemoteFolderOperation --- .../files/CreateRemoteFolderOperation.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java b/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java index 89078ba3..79a7de2f 100644 --- a/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java +++ b/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java @@ -28,12 +28,11 @@ import org.apache.jackrabbit.webdav.client.methods.MkColMethod; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.WebdavUtils; -import com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; - +import com.owncloud.android.lib.resources.status.OwnCloudVersion; /** @@ -58,7 +57,8 @@ public class CreateRemoteFolderOperation extends RemoteOperation { * Constructor * * @param remotePath Full path to the new directory to create in the remote server. - * @param createFullPath 'True' means that all the ancestor folders should be created if don't exist yet. + * @param createFullPath 'True' means that all the ancestor folders should be created + * if don't exist yet. */ public CreateRemoteFolderOperation(String remotePath, boolean createFullPath) { mRemotePath = remotePath; @@ -73,8 +73,10 @@ public class CreateRemoteFolderOperation extends RemoteOperation { @Override protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; - boolean noInvalidChars = FileUtils.isValidPath(mRemotePath, - client.getOwnCloudVersion().isVersionWithForbiddenCharacters()); + OwnCloudVersion version = client.getOwnCloudVersion(); + boolean versionWithForbiddenChars = + (version != null && version.isVersionWithForbiddenCharacters()); + boolean noInvalidChars = FileUtils.isValidPath(mRemotePath, versionWithForbiddenChars); if (noInvalidChars) { result = createFolder(client); if (!result.isSuccess() && mCreateFullPath && @@ -105,7 +107,8 @@ public class CreateRemoteFolderOperation extends RemoteOperation { Log_OC.d(TAG, mkcol.getResponseBodyAsString()); } else { - result = new RemoteOperationResult(mkcol.succeeded(), status, mkcol.getResponseHeaders()); + result = new RemoteOperationResult(mkcol.succeeded(), status, + mkcol.getResponseHeaders()); Log_OC.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage()); } client.exhaustResponse(mkcol.getResponseBodyAsStream()); From dcad9157aa0803e14de4a7fb73456903a4333e28 Mon Sep 17 00:00:00 2001 From: masensio Date: Tue, 16 Jun 2015 10:51:50 +0200 Subject: [PATCH 015/101] Prevent NullPointerException when OwncloudVersion is null in MoveRemoteFileOperation and RenameRemoteFileOperation --- .../lib/resources/files/MoveRemoteFileOperation.java | 10 +++++++--- .../lib/resources/files/RenameRemoteFileOperation.java | 9 ++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java index c2fb651a..ed68535d 100644 --- a/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java @@ -40,6 +40,7 @@ import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.status.OwnCloudVersion; /** @@ -88,10 +89,13 @@ public class MoveRemoteFileOperation extends RemoteOperation { */ @Override protected RemoteOperationResult run(OwnCloudClient client) { - + + OwnCloudVersion version = client.getOwnCloudVersion(); + boolean versionWithForbiddenChars = + (version != null && version.isVersionWithForbiddenCharacters()); + /// check parameters - if (!FileUtils.isValidPath(mTargetRemotePath, - client.getOwnCloudVersion().isVersionWithForbiddenCharacters())) { + if (!FileUtils.isValidPath(mTargetRemotePath, versionWithForbiddenChars)) { return new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME); } diff --git a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java index 30b88a86..0ceaf227 100644 --- a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java @@ -34,6 +34,7 @@ import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.status.OwnCloudVersion; /** @@ -88,9 +89,11 @@ public class RenameRemoteFileOperation extends RemoteOperation { RemoteOperationResult result = null; LocalMoveMethod move = null; - - boolean noInvalidChars = FileUtils.isValidPath(mNewRemotePath, - client.getOwnCloudVersion().isVersionWithForbiddenCharacters()); + + OwnCloudVersion version = client.getOwnCloudVersion(); + boolean versionWithForbiddenChars = + (version != null && version.isVersionWithForbiddenCharacters()); + boolean noInvalidChars = FileUtils.isValidPath(mNewRemotePath, versionWithForbiddenChars); if (noInvalidChars) { try { From 58deabb7738461da8cca36c0e64416cc441a61ae Mon Sep 17 00:00:00 2001 From: masensio Date: Tue, 16 Jun 2015 15:15:36 +0200 Subject: [PATCH 016/101] Changes from comments in Code Review --- .../resources/files/ChunkedUploadRemoteFileOperation.java | 7 +++---- .../lib/resources/files/UploadRemoteFileOperation.java | 4 +--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java index 7ab9e2d8..1fa9d5fd 100644 --- a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java @@ -40,7 +40,6 @@ import com.owncloud.android.lib.common.network.ChunkFromFileChannelRequestEntity import com.owncloud.android.lib.common.network.ProgressiveDataTransferer; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; @@ -88,9 +87,9 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); - // TODO: Detect INVALID_CHARACTER_DETECT_IN SERVER in a better way? - if (status == 400 || status == 500) { - InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); + if (status == 400) { + InvalidCharacterExceptionParser xmlParser = + new InvalidCharacterExceptionParser(); InputStream is = new ByteArrayInputStream( mPutMethod.getResponseBodyAsString().getBytes()); try { diff --git a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java index 9fcd6515..25dc87f5 100644 --- a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java @@ -94,7 +94,6 @@ public class UploadRemoteFileOperation extends RemoteOperation { } int status = uploadFile(client); - // TODO: Detect INVALID_CHARACTER_DETECT_IN SERVER in a better way? if (mForbiddenCharsInServer){ result = new RemoteOperationResult( RemoteOperationResult.ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER); @@ -132,8 +131,7 @@ public class UploadRemoteFileOperation extends RemoteOperation { mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); - // TODO: Detect INVALID_CHARACTER_DETECT_IN SERVER in a better way? - if (status == 400 || status == 500) { + if (status == 400) { InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); InputStream is = new ByteArrayInputStream( mPutMethod.getResponseBodyAsString().getBytes()); From a22b1da16b16a759d260d950fcd246d8527fbf00 Mon Sep 17 00:00:00 2001 From: masensio Date: Fri, 19 Jun 2015 15:10:36 +0200 Subject: [PATCH 017/101] Don't send public_upload value in createShare --- .../lib/resources/shares/CreateRemoteShareOperation.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java index e6637e3a..f3d38779 100644 --- a/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java @@ -110,7 +110,9 @@ public class CreateRemoteShareOperation extends RemoteOperation { post.addParameter(PARAM_PATH, mRemoteFilePath); post.addParameter(PARAM_SHARE_TYPE, Integer.toString(mShareType.getValue())); post.addParameter(PARAM_SHARE_WITH, mShareWith); - post.addParameter(PARAM_PUBLIC_UPLOAD, Boolean.toString(mPublicUpload)); + if (mPublicUpload) { + post.addParameter(PARAM_PUBLIC_UPLOAD, Boolean.toString(mPublicUpload)); + } if (mPassword != null && mPassword.length() > 0) { post.addParameter(PARAM_PASSWORD, mPassword); } From c84530d359e40f2a13827c796091bb26780683a7 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Fri, 19 Jun 2015 14:05:08 +0200 Subject: [PATCH 018/101] Added helper method to check if a server version supports remote thumbnails --- src/com/owncloud/android/lib/common/OwnCloudClient.java | 5 ++--- .../android/lib/resources/status/OwnCloudVersion.java | 4 ++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/com/owncloud/android/lib/common/OwnCloudClient.java b/src/com/owncloud/android/lib/common/OwnCloudClient.java index a02e9ee3..037d8fb4 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudClient.java +++ b/src/com/owncloud/android/lib/common/OwnCloudClient.java @@ -444,9 +444,8 @@ public class OwnCloudClient extends HttpClient { } - public void setOwnCloudVersion(String version){ - OwnCloudVersion ver = new OwnCloudVersion(version); - mVersion = ver; + public void setOwnCloudVersion(OwnCloudVersion version){ + mVersion = version; } public OwnCloudVersion getOwnCloudVersion(){ diff --git a/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java b/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java index aa89cf3d..9c5a4a82 100644 --- a/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java +++ b/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java @@ -40,6 +40,8 @@ public class OwnCloudVersion implements Comparable { public static final int MINIMUM_VERSION_FOR_SHARING_API = 0x05001B00; // 5.0.27 public static final int MINIMUM_VERSION_WITH_FORBIDDEN_CHARS = 0x08010000; // 8.1 + + public static final int MINIMUM_SERVER_VERSION_FOR_REMOTE_THUMBNAILS = 0x07080000; // 7.8.0 private static final int MAX_DOTS = 3; @@ -126,6 +128,8 @@ public class OwnCloudVersion implements Comparable { public boolean isVersionWithForbiddenCharacters() { return (mVersion >= MINIMUM_VERSION_WITH_FORBIDDEN_CHARS); } + + public boolean supportsRemoteThumbnails() { return (mVersion >= MINIMUM_SERVER_VERSION_FOR_REMOTE_THUMBNAILS); } } From 02c24c8a3bd87382590ece0e0744ad430718b51a Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Thu, 2 Jul 2015 14:02:31 +0200 Subject: [PATCH 019/101] Fixed existence check on files when automatic redirections are explicitly disabled (SAML SSO) --- .../resources/files/ExistenceCheckRemoteOperation.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java b/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java index 4596594b..71a2e46f 100644 --- a/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java @@ -83,9 +83,11 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation { try { head = new HeadMethod(client.getWebdavUri() + WebdavUtils.encodePath(mPath)); client.setFollowRedirects(false); - client.executeMethod(head, TIMEOUT, TIMEOUT); - mRedirectionPath = client.followRedirection(head); - int status = mRedirectionPath.getLastStatus(); + int status = client.executeMethod(head, TIMEOUT, TIMEOUT); + if (previousFollowRedirects) { + mRedirectionPath = client.followRedirection(head); + status = mRedirectionPath.getLastStatus(); + } client.exhaustResponse(head.getResponseBodyAsStream()); boolean success = (status == HttpStatus.SC_OK && !mSuccessIfAbsent) || (status == HttpStatus.SC_NOT_FOUND && mSuccessIfAbsent); From d89387b8df6d1829d6ea57b1cdf74eaa9043e035 Mon Sep 17 00:00:00 2001 From: masensio Date: Fri, 31 Jul 2015 11:22:04 +0200 Subject: [PATCH 020/101] Update build.gradle with jackrabbit version 2.10.1 --- build.gradle | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index ba1be48a..13768280 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:1.0.0' + classpath 'com.android.tools.build:gradle:1.2.3' } } apply plugin: 'com.android.library' @@ -13,9 +13,7 @@ repositories { } dependencies { - compile 'commons-httpclient:commons-httpclient:3.1' - compile 'org.apache.jackrabbit:jackrabbit-webdav:2.7.2' - compile 'org.slf4j:slf4j-api:1.7.5' + compile 'org.apache.jackrabbit:jackrabbit-webdav:2.10.1' } android { From 4b1c9725c641db7daf6197f92fa29430926827c1 Mon Sep 17 00:00:00 2001 From: masensio Date: Fri, 31 Jul 2015 15:19:38 +0200 Subject: [PATCH 021/101] Replace jackrabbit 2.7.2 jar file by jackrabbit 2.10.1 jar file --- libs/jackrabbit-webdav-2.7.2.jar | Bin 326424 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 libs/jackrabbit-webdav-2.7.2.jar diff --git a/libs/jackrabbit-webdav-2.7.2.jar b/libs/jackrabbit-webdav-2.7.2.jar deleted file mode 100644 index 6ebfbf70a739c54704c183183c306bc9e58a31f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 326424 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

4`nqp^TRChX1835wTu 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

81|8fP(!Q8EU8Q6((%6?ZDA2o5Z2)fa#04cx)l9 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

-Z+q9s>NziluPV+p(~&-smNCC*~6%GMlw`WGHJe1DBCUF zdc)w};uN{I1XnP5$_|8x;w9iKY}RBS4~5u80o{{`C!OVi_*ceM&!M+*mC%^Kh8p+> z$8eCCPO7EcP~9*3OOR$0n3a z7CnDz6iB2P-iEL@5&x1$p6FHJI3e|XxrLt+qP}nwr$(J+P3Z0w$0VHZQFMD z`g)&za=(*{eb2s0y{UhdHf8Qd@5&b^Ugo-2`2IeY zU^~M7?bZ(T=7;#aO>Kz}M-VK2c;qAadizcAv%MG05dj}+SJ8WQW+iU4IgIpU#QW6( z0e@fw6$fgUVc6S4C-W{ikQ@~U@uyMi8!)dna2aQ!>~rBJsulC?yH$nG;q0YtEpKh? z-c;FHT3_Btx;)=qNRD=OX|*;_C+TK6phZ$#{6Vannj!O&WTKdqFs-Gv9%)%lsJq*R zsqyF{#@*uL23?h@Hhk2gr6m>xf104H<=tBT^h{Pgs@Kh)4=Wz(%ACbAkElF@QG$Bb zWWQC2nUe_;3eNRZ#b`2IKAhrwfb4vom83brApUS@a=fsw=EPwc1En%GS)qwd_nUex zU530GtUyN*6Zw`66Vj@&h&5w*BMi*TwNd**_KfY*krs7fvdG&Vy?a@JiF%fa9!85* zdPXazrlUp>j$u*!Y{k|ak8Hg3m--|v*9BJ5~Xe}Hb_S~|v=f3I4LaJ3A zQlx*2u+GU!D!`PIo9o`t4qLNGS!0bwMx8-Vi+rKV;8rH#(`tAT`IpX&8EjH2jq5Xv z=9o%R3gr;)HlX-1L%jxnZ8nVrRjpa3H3*wds{t4#uPj(WNG8eKZ@4_B*k91YN*-$N zaUWINU|kG886*?=#cwtz z)<>olDvIKstLg+zLB&?Sg78r)aGG0Vcud9AbCD}p-2>_z5TVTH%tD+IWAfUaMQBmp z2Mc^jm(^0S?Mnr$$~fiNzz#LLj7pS>33vaZush$(hWJTeNI)O4!*O&8zcnaS?pmVG z>=p&em%p;`749}t+F>!z3v*<}$k9S$=~_q*%5h5goeT;^rEb2+2jT z#*RgV=Bef)4DSY&%^MSrB_14jQ}K$|Q@aoTnjeT?{>tb}1Q5{7yq>}s6K$teh?qf$ zdmR;-w{K468>>Hx@md_Izqdl=8??g|t@wJi&5T z`R+#$gI=lJ+nsHR9+?l=j_WyN;g>={h#ar!f}rK;X@V@%7GX8O(Az*6%t$mmZ1k0r zL#*9OQ)`i}NUWWj(;B{wC82KaY_FnSom<#MLaEGDO^q5*&DX%5Yud$k z8v;5sts0LowMbPMFmi5vQ`R*bHPAjNns?~wGg8Ny89Pu559GW)B2p=9GLp7Za=%Ri zLG>r#O2tCF{qAyUDR&y@lx$cX%r@RK6PpSMkv^Y~56Z*g(x6Wy25NpNG$Y{7F;NP& z%^LSgGIj<8n*lFT7L!Wv;Lusq<>CQHyFPyROipuDK+A)R?7ecvKYa+D*6eF9RODab zTB$0fp;c2rM&ksFIXS+zJihoVKm2aWe&I&;QCU(6<(&JJCSOm3u*ihTn`2=_EDNFI z(cyE&<0-dmPVbnW=R$WAd9To8Xx2C)4#Y*yk0^mL%3wiW*hmteNorSO$|9{GBT9bp z0yM}8E@^dz2O#w@lGR@r)iiFKyXhnOtt3{qi6r@IAQQm>w?U^AgEd&sN@^66&luA#3m z+CW)s+E^1t_GvK)?8%RqMDn3;^pPdD3*_6-+g>)LHQk<800PJv2*d$=Q6FHP_RtQ2 z{_qtU_`<9}2e0(ZJVXARBMz{QdcDUPwNm+pwwFW95?L85gwxW>dZ%SXua=*ozO?2~ z!6pc|!IRlO*i2XN4kH>yHfu-o`zdyzWfzsswpm*H(9;I!s03)dz;Rr?AjQ52~}41ml$P!lKxzL92Q@fzbVKba%9YghEby_xUL+F-GEA0@ z03&A1l{Xrls0$mzN=IH++WqSx4_4Zj+YEDFaUS4lX#N*|jbCyXj=^pc3L_47a3`pH z6w~~HthPG$Ck_DuUQ-cIdNc3)4f{+t#NkWHsI}G9l=NeJLho|rbm~rRWf0(XJ&)P9 zh$=Y#e{?K)!=p%c?h_eRjulc)v`(mBLbkq0H{Go3IbQb*!Rw1`VfNnXU32uTM=DX=7xz8d2MoPJKj->b3#8JCE?qZ_A&1wg1A; z!>g-5HwL>Q#KQ8qA$A4+`V*k($%#x2n6s@vVDEEUnha&c=1)=_7I8|)hpK#S_kBeg z`+=!V`KwTZ=+x*Yzv$wMEB<&x%GcQhGx1FkTLGi7=LA2;WGwN9CBwAroi(CXhP;CbgZzxj{7Tf;|CzdZni+w@_`fo^x_0D2-u28Sj2@kSi`K7uiNNDuiaX};V5cKVc=a-WScc2e$m zF=s|S)PxjymdNv~XiXnOre42Y!TW8?d-$fx(sq}VK9rHzR=upWVg{RT0a=}96}-G$ zsl7EWVk*A&e5V+mRG4fm&XNs7xUa;iIVt;A@U0n}zH~E54GlK{oAqJMX?XFD16Qx+ zKN2fa7+D}I$#3k&dxn=x^xGzw9!>PW(40JAr({f{AuxrQwU>&X-MN|$A8h86I+{ba z)zqG5>xWfTkkQU0tBI3Nm!j>O*=yDe!^`gQmS%@K8&6w|Iw2bHqU^LN zjTx{}wTNCU)m{uTjo8)HrikkT*|V^67?-Hb@k8Fs6hW$rCWyp4Gu?#t?eW4bETdpx zqHV0$ii6*Qjwh=Iafww#;OHc~gO$RTAWLD(idz~6*hTy2RERclR*%k28r{sK z!I178W7VXYRiLWV?y{p#NNJX*o@F-Y&l*!08^zW~*NF31rLLp~Nf*`Rl(v&2O>C}I z)9S~tT`5RtvT~LCfrNw`0eAjS&Oe90#RM~s-nCGExH#3SNakjI+%9((#IZHwkJ z4Pl{Dai_b4Wi9r1Tc@{00HX@N(+Le9F5{P&A;~;Z1q!^DK)WaUw2EkuCcwhTFpOXz zN^!_Nyif1}`YEJX8MT(Q5XwCnXN1q8nR@6CM7Kp)T$D+!liB^!WZPuX!(4`%Sj*(H z=|Hs|pyiiDrfe0bFl?3U0P#~DrTQ$pNDL=*0=Ltpw8Vb+mjyZPRJyDe;nLwOtdBM> zCd*o(C7_M2L>P)meJV_R7?(?dh{A>PbGzTkh&ZJ&hbZ79H{i@=WQ7MH$d#`BcWJ0L z{br!};#q-aHp&iQ#7N5!PmbIs&D}xG^)|DCTF)@x%>hkl`Nv#n;f_OavelG8?2(O3 z!zf*W&PXlpBTc)LK**R$HFGYi@?c8_JrABvL2OVLCZ7Vs@TgspD;k9;U9ote_PgRx zzR`K3ujPRcZNCk8`HFUtS1S$3-6YGhuLPBE$$U$8X+L%P_%;O{C|^N+%XigJ30F}* zvHmFDYJbM2E8lwka7y6Y2oB<)zJvLxU!lJ%3~=q#ZrOj{a5w#lei9aK``F6E{HR?) zev%q2j?^|cyuB*7hm&6o33YaAGO}8mN?zd>3rb07@PGF$&pU##kAID!7-bwcp-UO# zLEG=tf?>=G zB*y7@q^axC3AicSIjhLth%UMCT8f4GSUeWtG8!Zp@AC=m6~{LB|AZ zn|(|@&VgGmKY8 zx^)NfMe?(<-&&qqDvc&`RY_qLQqnp{Dn{xe!zwh2>|rWNvwL}uhKyf-2NU8THeR${QNADy2%plt zbivJF)SP76nCsvTU_ly}xg_|SPC-Hr~sAjcEbc}Igc{NMpXzuLDpF}l(?Sr(ijQ-S0p%Bd|Z7c=%4 z{`;`OB^qHex54;ScoOcC@if>hffqTzb)f_tq9X{V96%TJFzR+Z{4cnd35f~GPKbMD z^kSfU{h;W+ON~}_gJ>fet=KD#od+aqsf~-Q|A|>_*rg5jKZ|R#okQj)Kafl(w11_o zIR4Es+dsok|Fn#A6er{c7!YvS^8-@F1M(#3FrFl8{DVP+tPq4Y+4?}h*&}e+QTSqj z@q5Jy*~$m&A>b<4o-Siw?%tlh0SzL906GDmfn-1eb=tF5v>>yC=S)qVC0R}7rO=Xj zwWXA=4x^;-%TlTvVrrx;RdqGV&3Rp#>wELaB+CiXtw>_EtLXjzs` z9=U3jMd!t?oYS0$ZBNM-RFM_#P+Va}_-_0#nuP%a0JBC$9=x~7*#L$K1M%4Fhc3f4 z^BgBzroI8Vcm6TX1Rc)u0QyNy-Tlkt)PK7m_@B+Af8OW+iU{=d{;33g>zR?!XYfFf zfP^CnB4(Q)iS;Q-BScGD6e7g?1L^9Uf2%NHP3WtkbTDho3kid*7xx5*EbZ5GBJ$L`?cLhvZ!agFjNu z)dH>0JSmM>k~q8ZBd&2J1fBn#1&EgOE3nbH9o@cybrQO3nQO>InZF)#yVsOMef1&!G@1xJga)5|Pn)c!!Fs54-Qn^ZP&$ zSAStwy66ClO09(XPJ+#G?<|X$df~1u#d48>vbB0cDAl3J2BW}>aqqdcd5YKEP;WpYc@uV#V_&0MC}Nc+6s zrO@K{QG}%epS1?pp2r5s?skNIo(E|7Udilgqz~&6B^Mp9814v0V1c?(dQcLV(_;Pj zrP`4o)5U8?Y}jfri%J+&YR$M{LdvXy>MeH)*Jvj+*7zW`y_(5Gy~Ahv7OX8Nwej(M zhFA+ZF1$5Fi(O3O;UvRF8;RYK7S8yGP_xi4Iu1;Cplq}X+C{Sx=p0$@6k9ioD^K@H z&TSF=hV0l=L#&lgG+K#U@`X}F+J5LbT@w*KDP`deSDpexs>1OXm#_L?zmhLeUos=` z&e9gdU*OSVwMpU{TB9Aqv6pcg#f`Zthnb@O3|qx*CzP6v^z$?_KnH^)6?!%VO5t4; zZ7ktU^dXNHvy(&!4OsAN&ClVDBor1YO2gs~2=ABv&;h0rLN zS+eZqs+wRD!@CuEF)3Py(27gF-QLv+#Iwytt8&3%y@C~h{d_~2m^Sm&EGlqjN0-P9 zZ<1j$*5R0AdJs=D+>+5S&W0EB7?MS1YP_cgFxOA^V%KR5@Qe&_VqO@jx!K8?bG6vY zHG~zaWHMXJRgfoW{65$K>j@fRUF@kc#d_3=Pk*n0QW<$6S-wd+-_MN2$9T;jyeIzD zC~Cp-0FuY@fRb;F!F+|xWxS>F9S^nMHTQ^ZV!CzaG2cahEe_BhJJCPzoZsoSztsj( zCzt{AB~Qg?y7l_(6F}2>BmOqooq3H4__J@%rN?mV{yEUgKlEDMCNr=ff&0bvZTb(B z-Ckh8MQ5vhEwaHy4mT~1W*;u9n#53le^aF7FiA^zi`x8&nlZyYFdp9cgHDsDgIfk7 z&-Gl&B>tQDx|Ioc?UEo{ydD8Kk^C0I*`Tk~?W{TD<)F;0}KwMRQES_sq_@HAg zQLcvE04pzt=-@s^mNScaiBNfcyQ!ktSXSAYnmaCANY{<%*mc*#!e+wDCw8nM zIz{G1YrHG;4fJvu?YzfSn9iJrtiZPa_Gl;e6}ot0vPE0lxkCJ5STS{f5ZFxYwCsd8 zs~}_aST#i0#x>_Iqdq;z^dGeUzMBA;WVsDzP4!TaFyz<#BqNj2(%t$>h7L|4=ES6? z-aH-Gc*fs%mB%Kb7LVl(N!J{;KTPtJ2rni5A$D%=+U4mJahPx279p6XP#MQcODs9h zEcPa9naE~r7hK%u{E!@orG|(s*|A0-N5S9M+-q`)v^B zh1myYO}A^~DUG`)R0>My&z8Wm&s628-e61bNT-W0X0avQP9D(f0IXc#CrVKk+GkeW zVe8(pEt(-s%?jF;^K2st*oCrU`+f=Yo#RU%Y9M8p6t&PVh2efZny|pPCzbj!V;Y5v zE1dhe?@sbQ?Uj0BK=JaJR_?Gl(!%>1mbz_vw;0Ao#9tdMM1e{(BIV;jC1Qz?UTpIh{boadTBG0-68DCBYIPnlWN|{^p^5Mi zw?*8RB;;3By}!|A*usjUU<>42jceG_+e54TvD4i{iFek=_DK=-VkVxe)EF*{QNC)6Ib6OfU69w3i&X7go6sb>85J`BP z4CZ@dka8t~H^zI|=N9JI4pNDeYqq?;wKoi<3Hp zS}GBJC1e{7V+4(J@O2O&ue{T#_&FSP=hrej*G7HXR;OYco!Hc;m0?x6qoHsyefMri z!kRu=kCof4oZi;2O(iLgjxBSeH$^}zfcM^kA?(BE7$(ceu|tJ9y4Fy9GMR#+gS!k3xd&7u1mj z-@d!CXV|h-d#}+5Y#x0y*@c)5ss53X4u+o!a!!g4twNWJr2dY$77+OhGm)y4Yv=ss zFb6w~0rKyGr(=59a#Zj=X|A{UY>nmWZ&bpXx9;E^*|&)`aNy+ZVLb|yj3@`e2Aw{< zu}++ibeE2Ty~jyX>GWLTvaGSo?mXD}zCDr<1Z0JX1vrB}-t-1_Le^*#-aLGTQ{UUa z|IoF)PZv0Zg_|grrklzt zh73F$IzmL!1r?rHLOO6=R|Us>aS4#fW~-Iea@NT>HBm&CX@TGJgeV|fSt2W&#W(-b z`B&6$vNSK(%RF_+6t=DE7r|A_#H}cg#hzjqgv^My&BB!_!R%IN|BS+eSlc zqtemuj1l<}cju$q0Q5@@hX*KaT{gZQN)h8K%?ka6thvfdKvZ0=)yYzBgHvYvucWN1 zq$TIA9Q}xDsF#Dwp)mBQ>KAh7QF!sLTPK6@><_&tBuTkSLSLxofJ>N|66^Yv&n09s zVB{;zs0>dHm1VI?P_GZR00=EMMLQ*f5_-O4bFcRTdL%@8W4&!5DdH|KY|rg*udgo7 zVjf{(AT_qu7Uo$HFzxWL>~2o+PtOWDR{&izLrf!(58KQ{P^+~u$w#7G&y_%ehFx!B z&Su-tuH~eYGLW!!qDqRCV1&)c`9zVf)||P6Jlm!Q)SH;|$*XjMjJ{KHCz{)wEzE&y zaZz^d7>!U8@27)n+~lL<%8vb+3d(urC_I89GYod7i#D*N6<{iAbPErhmgBy61W&Lv zk1J7FRfm+WI04B&+080cmuO7u#*0twhL&RkxhrhkywcS99-kM;Je4?>K`gKGr(CffOMJEwryY*I&(lZh+O zqYn71wVsH+>GtqnOM`V^8Bn98sqBcX$wLVzR8%4V3YGeMsUtlKemMItF0_(?T4@Qg zy0`zLC_k-Nm}g0>uvGN)-jT8qZ*!|H%x2perl~bUZ7vQKD-l+K&lo;7l7(_EDo8a{NIKEwNY%O-xHv$>Y<^j zh?CPO>P~@^H>3HkLD)4@-+7{0NX=t~>FD(~ksjNAIsJ?me{hGkWOWn1w@XqXtWHZ2 zL02QZ6k+IzbpS3_y}$scSm*?xD==y2+cFa{ZrmTXN1)KQcWxe4hHi7M(m}uQ8nk=2 zVXQtZjwR2b*XRN`Ap&+`pnzPN9YBSc9l$HLm??OqE9oAcNkkW~{jpyVdccwq*P(>8 zWj(+xOtWkuy*TjLj3hw#j5MHL!}DG45C@Ki31UdaE23`Oaf`ex?eIfwvV|bm+!j7n zc3DxT3r?X1uNCU9iFoLOr(I?SxSOh$C8#S=A zhrrDgeb!xn5fYDcJaPnJ4p243*I#MZT@7$>5;~CUAgIm7pNpC&G3=mFkhERfR8iW^ zOvea~C2_2IBpzzi=tJp0|FDhQMwN-A}3wYzTGN!mdZA*=bRkptIB~N$! z#6JkJ&Xi=7yw|pR4jIs~8G8_3!|O!=2|2DA z#6#)n9DC|&N3g<`?m9Kdji?r7UJeaA$QuSo!bbmC^6cY$GOkCNT6huom^FV+Qgm`t za`lA}Lvx9@aCDKVqM5)TP7bn1;Zr6s3bO}k04IaBNqo=HcVJ#6XA&=}8*smj_FxWC zPHi5p{r?VGti%Dt#vpO7c0F2{3!KMzO zDH+uzwmjZR4crbd^etH7F$GP}10V?_S5bCIsrrV^a|~ZpMl#J#t;tu%38GrZe13NJ z{hoE5dzbh3>mH()&|5vy7Y0NzNDx$5(1TGY(kdF{4U<+F#rU3CFBCF6A+Hf?8dNd# zL1|A20e{yB0AGqYE$|gW3xKiRyB@}oq$sv#*9k#VMyfG1kP^^-Tm~xnB}bDFdKHp672@VLPB=Xs70T=HuzO)6Sn2R89|G}SFnHWgv{yu zpM+)b#s$VLtOX;=El}JQCFD%g(H+nHnGBZj=S6A2a5HA7MPyDA7=u+N=8hvB^6cl? z5Tn9`+aPHgC>-i#B;W-a>)PJCg1%W1DfxxqQ{-EWY@2YdP5$4eI@jsgP*{{pND*_U z=^H||NZ)7!dP8;zXdm-wQ!VcgKq(VS)iZOnQ;eo9RH=N#u93uR%{9A`0tDsU$XZkr zqpiW`c~b8Sm8P}H=e{F6+&M@VNO(@{nL#{ZAcZ__Bx8;$@1Q}UZqN}o;KB#$n z&Y=2buSoj!(8onQSg863*r?S8huyWM)s$`d``Vi-ic##VDv^BZZhNJbiocCwCQ&SW z32(Q4jn9#FOg3FvScY|XF>&$n@UU<#FZftCiObQ6dJTib_873y33HdpPVl{UeK%e& zKQt8DY9x$x6|d53M(3ACiMv($D-sm{61~va?jU3JQuuS+#*X*$I)5EUHGsEd-q4}T z(WfJ_*qS z&agzi9(2%=@z4*19`IY1PpF%A@Y^q#zr5}vS)X=AXb$OKSqcGWmq+xht?(apd4)}$ z1ojW^R%s44dIM$$0AS@diMgXzywM z&eZSIhT1;n?@RwK(HPCmg)hw#<7L_n%?tO#iv%}MEraZ^E`2q+b~aQ!ae=;8K_|FT z=i*CjedTo}DXVMZi1Y6i@W3kuYE_t!RM=%thGk=&7VHN7b2EJvGP2DLYE*$q_gYjt zfYBYD6wD0sRdvxF;C2x%`Tp~FM1iz)MD~CR7-IJ|asg1c{SZ_fyg!hwAU$;*k}-(s z%zEh=w`qg5_o0j@n0oWrvnOiZ#yymefPG{TphglxIc*F$u)(1a;n|Le?JTvT+m_Jj zc3kkY@QtJ^{|xKv<>sX=CNI9WbsFKN9DYCdhLVs^B?oJ58sEhtjd4spxi@~g8KBr#|3eca+@+%xvA>z0^g#-XHR38KsAxk^CuZtgj9Za~cZ zDN~r0UeEn)>rAf6odNF=(afpxgX;5zT?S(5)`;@jL@iMPt-v?Bh+B1=sjec0X8PmI z^RnmT&hy3pkBLINqTc=bPo)*&UshU$|IK&Ge@6XPoJ@b1n*Sx~rT(FfqmJooPCt3g zG%El!HtfIA#5h4`xRE>yA~BB^u1iV+I#{B5P{*wqO2eJCris+Gw47RI%evf@`k1;* zrB`vR1`#9sly-h#|Bd(!&*yXB)MM_psw)9gcXyZOJe}>_bK|}9p?iX#=j(vmE2jhh z8`RkM6a(IXJ2r}t)>uevc&3<;_+lUez?)%6k*+r@72ea4gVIe7tPZf$MCR?b8sPla z7IOzt+ZfOreFu3!d4K(7=+*^bW*2<_QInB}JY5EQyR`C7__GX)fB3=3BOi-?pWNux zlC_INIVNwf*h*zDIyw*B0gZmbLv)zlq>HLAhfN9T`~#L5b)q<~Id0@VMn#Iblf>h3 zl2N$d?n7p(B7%{Yt%fW%>-@CLZb;6mP|}r&tvrKsYjjYC);e9yW;S=fhy*;Z{3yCB zW0pk3Zl+j02gl_)v8F>h*g?U}T*GPpqY-z5^EGkD~fw-bP z%HDjzIOdEK@?(YMSz^z5b+IWBELlj-a`{#zm4rH2G zbomkz+b9QL%j4-(#R?YC%B zy)LywM|Zg1goihgZt}??aD>KudiWDo#Ak47eTP=6%}X(>S6WS~i=Bi;7i)2_7FN?F z3X+z3gY}y2d?%R`HP^jTWaeB~t{hSu4I#M{{nrdk4r@%6nU-?kVO=Ah0(leR)OlpB zo(N$3rG|*m$d5q`BCXl`OJ$);y+24^ZIYncbW|V`*;JPXLd`|AD)O2pni$CPq+%~d zJF{FXbky0-j50JxU{Nq0QJ?euagU@JD~WNGsTYdCIP~(&D|X$Rrasl85<_Ljtc z$BaUB+0kN#Ua&Of4FWMOvUi~Hwb(tqHPF{L#Z6!EW(hs`3D}0xBuyKWe}Uyx|LmYo zZ4_}y&Fu*~pYkms^uAc35-6CJS!A}QldePRP^a2xm7n3ezeL4czwXy?bWxZTzDM`NK%u6&w24zV{kjX5|@}kn}LkhjqkvL&&WhcNb+DU;aSKO**^O*YW zx0n+7RQM~l%W~(d@(Wx;N@KYB0&bM_5>kB|!bZog4%n*TcS>I7Pl86<^Y*!DNoV@3 zCG8V^-|pM3r8fkkz=4S}>4tna`HC5pgie=~Q)ocq_6Wxs01jS35Vn<}MSACp* z;63BCUA_bf7rc9sD_(BmZu9e88l@dSB8NpI6lx83)u0ps;Tm;7Oq4tnA*P{DW3dz7 zxZ}(aC(ai}->Lo{Zx}#n1?Ju3N4$CcHI}#dc@gu|wJQ59 zaK%Ov3;HuMF&I}8uO85CWnvsjadnlmpa@4Xli0Z|c3O~A{a2@07cEGIE}cLmRIDNL z@LceLDG&=fs6`7P1;lP>Q~9N*q>Er|{d1xW!uuJi``w%CL^ZGG@Rt7J^$7YM#f)x2 zrISWZNx}Yd?kMV_Z!`e;n|)b(Xb17r(}Tv}IaV7Ernu1Wa1O+@<5`V#w)yR>0`y2J zwnWrh7Ta%_6z^EK+~bAP36Zsfa3rC4zPTF;DGKW^9&=??1gT6Ca(?-eLUqK;N3iY{ z?ut!Zr=U%RC%E;%Z7@&s(pp!zEOQ0)M-U&^*G@0EysQwS97$)jpIYLg`^~wb zoS%OqsD2@aZops>`2pVT*`ENlNS@}2G8lmy@WNN1-G&SWG1ach#Q0Ane?p0@Y(#U~ z7$0m*SCY=0*0CZgy7MOv7Vcs`Mq*o({OltP*bP#XNz=AH3h4c1^C$Awlts6xQJE4+ zivzE*koXDzABy7!_&gHuCj%9O@?SlS|Cycq-zKI1XEx`5hfto70v1H5lGI@*L+?H$ zI)rb)<%P_3f&>AP1lsm;+i+cWC7Ya%{hJzuzbhVr4BQub&V};y`pxML*fv5kq8eM@ z?{V@=e|)^Dz@hQvKF2x(`=?YLN=&_J=Y>5PR%OeQGgnPh?HUl|*rJ@ydshN4w5~R2 z9-ueq9)XYAFlw7u(Aa6DNP~ixT^pf1lckWf&SPy0(x$(>dzag8WHDE%BdBk=QdmB*vp65r7ON%CI3sNf|K&6U>oN z0HQRl6JjRL*-XoT=vX&5S4OUbUe=&iwussY$J4E=**4QvZ|P`NZ&kV3+g28M|8?HU zVW&@m1kvVyb=+~g;r!dU?RWNiyJsDVLhB8H&nhmvAAK zq}_N*rFV3o4AhmmA;YJdE1wj1<$Jv=m$dRqDKFuAd&ZQF_#4@?IhNtGPF^aj~p6#hthfa>A~}}1|ZC%5oU|&F&&4^Gb#_w09E1z#k^)-d181c48}pNyIc9lw-QviJfRbl*~Tmf-R}_qdb5< zbq@)XE@dSRa>UuRO-DeFkf>XmPls~AD|oq`uV;Kl-53pTo7(**NpofN;KOto9H=Rm zpJE{F@NR&~TSP*Sdcc+GMk}c{?ZWlmHcX~lFce#qoPDe+Zv0^6@cKaLQW|5N+LsHZ-_RkiZ%6jc^MhW`$c+9`?bt!t z*vBW&@JGmOcf+p#n7;Y_Bm5K7Q7gQt*M;$yb}aXw9-p#Sb{t!Saozf!Y9G^!^#?W9 z)++5rH)7?wug_W0eA}lDu=k5F;W-TstV(^(MP4QZyy#kth{u=U!b+j7yZlo(8hVY^ zmi9*LrOakrJERmkq&o`>h89x_E`>jIjwfXCYZ#c(gIWId4OYNOt)^wJOMV?%}S>co0glr>#hfS6b5q#Ac!Tx~J2Hj&P7BSQBR^81!;xAqL% z`x-c{Bz^oW>RNj|onfTTV%>uee1v(c=T74>`Zp5=lDAO9U~uydNsGsJ1U`umGwzM{ zPy}R}Qv*xzpxY% zO*BbV=ia8yO89vTm-&Ho+zqx4p)UESdg-z-8H5Q%g_~3oiASvDJ~DoU93ZVG86v%4 zWlfF`2s9hdJ5Iba2d|Ud?Kv1{dZrJpLc9wxhUByEY3rsS%iimU-jdx)j-KD1eeFDC zkSzO1VUL0%KW3S5WjHM;!;lmyiqv{~-ESk3TZ`G=F+2-5k34mOzIa00tdl`MwhB}t zROp~a3@ddNQpMzxHHPYYb0i={&eH}1zYm#2NIuLf<;4@g=YcO(kVUlANZc4u@F9sd zxkxA?yc6ubx5%_~{W!OL7Sv5kgt#y0WT+vQkHT8lzG z`jMZTdzawzy^%&s9(eb=N%UmQvRyqUhDCG|$Qv+Pn5!2k(7=R)XQr*q9)wUPOUd^K(80fN9X?3$ z>h$0-CRxN^Ly{z!ZBDxTu-BsfJI=rsXGhY3*BNQO#fF1*DS3N1^}MmL1eWA+vBm=w z?m0at(%@OmW#cAf{mTsHIGjq`90-qW*R1l_84Kf>CB@MGm@<4xyEqqyp#H6H$vbhr z1~Zbo>vHeDBA;@$FAz?7eW!k2<7;QASi#nwD&koYjSrm?`2|f!Y7O%nHX6SGe&eg4 z@96%`*sTvH-f>uZ>`l~2SlZGGHRU;h=$0n#6@|9Z-K+tR+8@%Y@#uGrHte+Zy;B8u z4z!?r8sA_)0DayLXXL1Dd3*z{+2YZZAXU#q6HgK~J`NQ6xEL6Ccu_;&B>d)|K6JL_ zv*C;u%{zh5=sx*t7}?*S(-~TcvB(w>HQ3K?t8YWsDg$=4%00QSy|N+x<2;Q|<<S zyt^4$-|_v@H_WKKBYlle>2|N!JaZ}uH07x|3yV$_l~YmLZ`3~qceQWq4oQn{OZz+X zWkY`s%x60^KfQbrt1E~6cF}2lB~!a6{XmYIWIY_;!4~%U@ABphwJ!71GNd-Cwcmvb zk{n!2DexLz=>xxNKiQ-H(sg|Yi2sT=xc3|1dU&Lc@(mQ<{8~R$r(ruajnd0M@u!g0 zikGh~yyaTg!rmVFo4B{b^f_V#hV83b*9~?wyYuQArB}>O%N1Nl#`N}k$bR&M-IT*5 z-n7n8LuVi*b&s(N%^U+0gJWUeGTR(8!zIczJrrKlr{grSoNr>3=`$5^H%~j%)I?h> zHo+Qm!N7=kW_0Lzm5TvqNAG$u=BQcrNEkT5quqI5F*b%2j(Jg2j1R&A5S{3IJzIp& zr=a_BE)|j=AM3I_gfSWj6H2yllqu4Zr5)KO>@tdm?gT0-NGGCH`ZpahHhUVS?VeeN zD1J#?`moDHx?wWGS`~5ve$#^;5P^MUj=_K>9_M_q$8$1Ry0*2&P)ta|&8#ZONQ$=Z(4D+Vo=8|`6 zk~oqeC3%#!j=i~z8$*bam$!8CK2tvOK6e) zgPL99qn^LKZFi7xf4-@OK#_Qm(%!GiLdn*6^XI-5m!%}!q-mx_{8-nGCE#535LbSU zY%_T^oYLZNH2@lamNKfr0aW3O_X1(;pNbF*QS{kLeH_ zs0igCB@{p0{Q_hy2a->PRy4i4v{Fp;1PT7Oz#@l-Qfevirj zf31B7JeS@3za)fEA)?62-ZCQDdt~n|*?Sd=jLgcG$d*XY@U zyNr*1|ND9F*VpTLeLvUxT-UkQxz2UYeXOk~rT1$(PW;sC^{cX7MFMgvo z&QpsTJb!*B9IaJB?O46Gb2w3lN?{6Jeygxuj-ZocY*$bJd$2!hCz+vjlPi}to%Owf z?}ouN2|0VOQs`%XQDm8%`WiiIU*8T&|EJG*E;oN;`(n>|+@8AqVED?@8pR$Y z4_Y=JqVqEkKi*BXoqr~4lar-mR)2CV zT9EtJ(mpFh_kRd(?*bh`>=x8~eta_PbWaWCv%e09X5`s{i}ZVqiM6KPu5pi8Kz&TW9DaGuRVXoYm|jRNm*5$fH+SNeMb0m|EzXRaS(&s8;*vD+2$MJ zQ>87vWVK;h$^)g>Z4WG^~# z|0@Zdv2p6roEs{H5e&-XWo~IHd^iCnX;SMuSe0ZkR0~U7%_$j^XV-6^AB}9madMxc z=)}e4$O?ED9q(7`%o{f??m!cEvR~Ad!xE#{gIS?MQ-VV`f9AM7*+6oAJl=`fk?P)0~q`doSLRpc{Et%sBd6frdt79Y2-iU0gZ(dUoixVVyL+K{(BkS;Jc?!YV&F4ynx8|oCljq-xo7TS| z=OY|#AxKMUrEXJOb}2o^>h+p=8eMrNRc_-U;cCj{r0P?MN{FQ z^WBZRY5Ov;`3U>^&@V9U(F_O*D0<)k)A+WJ-yNJ z^{676bo0zSTQl;g8pbWUthkCN*9q;3!|9jiQn((ZR+l|_OW-;_N1h=P7tB1_l)+oR z`Hqa8eKXy2icqoe$#}!Fb#SwHi02?;%AiCEQ@2!<`30N`jAxdWc7%#C*!CBi6K`F( za|W5y1M^*1c>Tnkd2OSJm1XG-yySZCkAtGCg27g1PPrdlQLKcPO-5Zp7o|3`#Ifc- zbzS9>48EHGjq%2M7jgVCY*)Qo^Zce>4DZ|nFi9lCC*z+XbEASXw8p1%Nz<`mI$ED9 z?$4JfcgPtxZX2#pb$%fYbqe+C6Bb8jL{La{!@iAyy-J4vMVRD#yu`f%R8P7(J6a?$ zR2}j5sawl#s5)L>3g?fZ*7{DJ9E<&2aMl%j1!bAa>*Tcnsu5`#mMP}Y^ApchsNa0l zZ#yk9NNnm-W`oN+j$C)c28E|Hb5MHl5xM;3E5s;17a!Z-nR@i3e@o0o9r^kdzsnj8 zcmycaeaXa60&nZCoffT}7^1;h^47am&@7j4XHL_a#=k_Mf;4UxM=(En5x3RmvAVeo zpF<+kv!rY$RV`K#NuUq8^w-d9)62Czk5*(lADd;DA;%@X-1ksXj8EmEq36!(d}rwB z6SFpjM?38b!?!hQcDndihIa1lus*uYIPU)(&9l>B8PiBZ4{Z1HqELm>N4lUBeLc2J zw}ptr%B~RUVizKHTfEgI)mX1$R#svXrD3`136B#OhEnQyo6Spm4xYZRDPEZ+>K|gl zD}rW1DN^`kU$uclfK^hO8rZQH$+#m~9BxM33@9()zLH@UQ0{o=dYED0`-RKt@#KQo zvDu-y5-f8`r&l#+g}tskeB@9PQm!d{1e0`2iOi<+-R0tlv-AB;0l3qY*;%jMNfx3! z&Kdami!$0y%O~F#4U?h|{{AmRbT;#=3uvy7&9s#WCS5iPB4)3|dPIC~%3HRMM)4er zbk_T5L>j5mkiyc6RPuo0WW{H^Sxv)EPdC_26IO1eF)dJCQS<+B#Z-cVeTGIVmo1&{=ELpy zY4}>ARXV$^CcBLyyDcTV&4|sH zG3}V^F{Kd~W}UH7UoHeP<;AN@OJU&{H%vToPtp3B(*_kaoA+H}yzsuK*vYIv;7*w% z>74wTxv|TjAQ6eU{BgT&1iTivf%lay# z1bS%)@|NgEXx3QV`{DPQw5NOGBV{l`{cZFR*OXU^b4Sys4RI4M8Eo^cui@pcDboxw zUiI%IskBtDE^7C4)^2esxirFK%!TtQ>)u-gIv;}2h;!2-OXz!Vq z=9+w!5nnOrD76zvZH?@~U|)FCt?iD`d1bnH`0b<)cWBuAR}RUM?{6z6Yp8D0RHQl; z(=8gFPbO8q^_sSu#)9)n$4!$C>#yxJB6nrsgx3juWQlh`1iyE^Izd#9hf8FdcAZEpR-1@AM;W&FzA-9-a@}wU5Bb6!XAp4`r zZ+m&VF|H|EkP)S{hs-E_th|k|8ToqqepY|@1XGhjZw>*efstq31#wybx`^uQR!i9_ zvrk1bm^qZ{Z{Kaa{d$c3?ReL@3waM`=H3h7aq^(&TZHh86>&E&DGt2HO$@v2erEmd zvr{rXQmOe+gu$0R0@5uJ(Nvv1uSRz-m@abcM!K70* zVsRPLOaqiXoUBW%qcJ8j$(hp^k{(DU)f;(DJt`G%?+$RD@G>}`%!9Y4w%C_6?rte~0$79>J&fGopS1x010m4dhsK!^eVLM#1@jgdA(l_&I@#($fs@o15DP9v6xx z=+D^U-%>PfQYh$}3fXv2+Df&Mx?EJtvPf_u%z%xXTDqLJlD>5~BCTXNIB&k?E>c8| zdomVd){#P@i9Ff?{Toj7o>Ik5$kzfKE)0A~wY4H^Cpz9BDz14V z;t0_rlk(FQQzZ-zboOYm-k9;;XCL@2QWL%nY0@=u=+9i_B~C^RwF|SgWq-%{60N4q z%T_m(mA#MwB}Rk)45CU{Dk1ZkIC)Y26wEmJI-ZnX9xlu{y7hCKWW|aTJ}#YN_t(=D zGms`LG)8)4jR`tVX6C%_=XJlx%#dV0f;Logiu)#(623|ak$qe{Qj5Yjf{psbi(ERF zsU-5vh5WwJWj*|+`Z@7*bG@tYj>xSTpI7EAVpC)0Bt6pnw|rD9$Y!{5d-D5-Ehpy^O|UR7xMv_5sOhVsJK8BTq4N^FgL!R=Y*ktUU_DRKU3ZR-I6!4(RjrJ*>l zCsoH}BfjySJTc2XaF3Dyo$;G7Wh&7o)VYUupMQJkX8-V6u)k#g=C#aA&+2r z2A3+VZ$4W(h3bTI9B%)&S>HOY*ta|>igVGz>~TH$)e0gPZ;lsRU*h77VQV?tQCDF3 z*vK<4_;Z1HRq3tRyhw)gDU#f#nD0{BNVOgBFnqk1wdBuybCpUfnx|R0ayXr$T>*t@ zg<;&z`Qf0>#Jv6$ye8>Km6B_mndM4qZ9`7)V*R(;sB>@2-uxP*d;3&3hji7p^A$b$ zuUD?TUzavWzhceE5T8*yIen|1PvlF5uWjw5+v>ZTs&Fme@rxv@m##5*4+S?Oo#goT zed9=N9-&JOv_5Wu^DY1Fg8ca%kxTGwS_qpPSr}Q`i`yI7>Vfa9|2#Uctf8Qwg0t<& zKommcg-9A-`1IHX{`wvc|MT`-`rY_zbU{ZDv&ElSD9b)HGymm(%HM|Qc{hzjH|6TDi!Ij8zLX$ z5$Dx2Y`JM2$inj#xavhO09-WhH zImY5;o8MNL9g^2nT&NwC@ND8drK%NGc%x7tbLi;~P37u}z~n>}6vdgUb{a?BG=CZU zbbJ9~tF>c}R@j`8P2+7-inT0>X>AyKsUb<|C&`)_!**D6HP1DKb?Q;Jd8>+m@0g}2 z&WIHGlX23$%dzonP^3B&UFd?F!+FI9e8XT&Sr}Oj7tfYPgqiZ4;#fA#IFqcBTz32? znp(wjKQo^48V~C6mvu_To<&OKcb$}YyfHm|7P%jo)1dQnWl^5AWz>m4OrLa&aM5bY z7D;V(4r|WsC*kdM5S6&l9{(^?=BrUb&{q->9UKhczj+y z9+?eq%(fLxTsk_hix6Y|fT2nO$Nd?Z5W*$HjRZMQJC+)%~)BRsWE7JaD24GTVcN&OWM z-uj@2?aQ1?Sgix3+Clv#R5=}<;XxEs4^b?Q+B(KJaHVPI89rM3*KFRVJ9B(C8STiI z(+QuG?-O?WU_C{@LVk+)WYA~Dy!#X-?*4^Abiw*j`9l{z8jIs*CV1#SN10KlW#f}! zw-uXqu--m;-}B`A^)nN3jHsK~Pr9SqIhD+A;GrVV4U0#xf5)xRC^v-=_2%o-DW?~?(9&0`);Y@2WY})i`)5(d zJQil|&Y;cqkBG6p9C2;ncPtv^iwIH6P^~l* zU*0)0#=7=BegrLVzv~CBj_erw#SbQU;)jf$h0*sfhX05h;fmK(2$it6EiW}#hR}Cd zBq&SpA487`JLa#hZqASNTw0zSCqY!Um2!ZRFcOJFQsK7$?bm5M`5)wi<3`?JY+Vp_ zd0f)tgT46fWm8jZtkv~74!hNlJMKHDU-LMI6yHffQgp5Tgcr~!eyWj9S<$uSrqY`; znO&-xd21|wFRXo!sp*U`jO3oRJ-cW=*q)s*On8Yy2?q)1g*F~juEQ&H_VPM(C0Y%} z$a6cXufYcd49r&b+$oBbyH(Y+PS@8n-TKI&M3i9~={`TJ|NcZ~s)DN_UryYdi}K*0 z-C3L=IZxKhCFUHi4_ej*iY~tVa{2y1TL0BfcYTdGEm{rl*G^_eRkSECC7C5Hn@?CC z*No;qXWz?OL65EVoX_^D_J`+O>vt;>N342;TOY2{^$ZrymbqfazK{QO328a^w0-HB zZr40hs|K+P@llT}h$FP;6h`S4D4)&-J*ZhyXy0-URH)x-zHC?=gvfu)XQR{YDp7~F zal}H-O*tFaBhU3YXe?yH(@kVXzd7sP3W^h2^;b&6sTY!{Q03+7oF}8upm7-%q9%~0 zReMUjMqxZ)B!bNC6r-0JyqfcLgr(L#FwYr_jJvIVve-ZH&ic5f%`+^d_z|>J)hKSf z`5b@x*ug$_+*Jqj5shfvkLb04GPlh z;}oF3(qC7gDv|u6n9QkVG7Rjl&`|=bH}!9XyFalAsB2OQyk~oqEfq9>QY3nZWSutA z_uhc?t4kw2eDQOSrc~a=T?-`rj7cWKB3PUuR+*TYHyRUJ;M-SH6_CTuU?v+X?I16% z)`wx%dW~&0LE?e7{v|L^vBU$UW3!gViK6PNKH=7WS!BX{%iU&`ikbku1!aH1DRG_ zyCZAe&V7=~NGo`r^&wxzZ27goxAVewTRHjb==$%KH>{rWy%{o}dKLdR`6zu#Cu@sV z2-dx^FE@f-rfs=)v$y2Pd^TVUmAzk=j(H8eD+fPf@FDtfy2p2KdR3m`Z0s{24@8=6 zMHd>II``&5n%$!PAbv>N@WkTTIx}8@02YZalPoKhh64}S`hO&va>Y9D8;>F&6r=3t zDA?g~6!J!P4(9e^M&{N=w!gkk7ak}rgUFBVtwY_*9m3TA+FN6G2scpZjF*s%+<-zf zam@L)fp3q$f1A#S(!5(e{3fH0{Ce>1&7*gmFmS^J_^I%=xK*PIWl%?m{mdd?RzD{% zcPQ7ZnrzqTs{7EzDlV-<&2!S8*tD6pFlaJ()=Jl)H@QfkW^i(#ZOW{@(F>t!zVFs? z;$VX?F{)Pg+3v2JmfSgh^Bas7>yJ}7ikmF74bKiStRk#(5ijAc`?e@vc?=S66x90> z_eKi<*IVG-I{`oNl6Y7f5=1TvMz$t;<|a2yER6-NEbT#JE(SjBXKwT}FMqCz?y6}N zzVpPzcwDAe=CVl|J)3U4$@yd~!d@ISc6v5Bc@lbhte%SKe%MEl+M>k?r~M~Mb2G|F zX&u_bKapA@b!d50dXb`L?(vDz-}hNar~2lc?;j=mc`=%4o6|o#VEwe#m5jy-dl#w5 zIs;Ch_xQE*UbzHaT^GqX&kM80`6pmLQJI`#it|fEzCXR_jT+ZEVRv&n;O3Adnj4qr zX^C6%krUxVvMb+I?7=sLZ>P4tNDqARc`*q8rJvQ*qJ`GBCf7Ib^Bav!+cci{X+vKH z4_T3}X$&o83$iJm+0kG@@vj8yEva#*j!clU~P zSigw7VGzD}dSJ~sWiy?DuYF9%eqBXtTRQT#O31~kwN|EWN$hh}oVQp6`&ep1bms~y zz8)zv$_{HNq`H2Wgh#c$IHuFfar6cIXjk`9PcGaJp$EmiMulXr@*Xgg=Ugch(e58}-7Q1<`7T;tuSyx_B3+k?&n20$pDm_naPRdqoldF~%o6Op z&ia+w^CW+z7KL_P)5RvqTgj`^rwODc^45t~COobdX(ina(rfxlTEb59Y)@`2-Yq%55r11?NvwtI zsqs^t0UQyx+UGTBKIgWMsy(V%Y$*)IEy$8TexArSHzn4TE#S^^K^1ea7hNuAyR))| z)7rTMcdkD~9l4E7O|_pB=Vtr;H*IGyY+ejwSrb zZIV{nrq<>0#bZJKT5dRUhR^0b8$1NA%;E$j&(`BgdROL)Fj)xdta6u&#n&KKO<(dUyuunyvC#>4$F79!JuQC9}e)2SoU}3>NUeut#$&*nh}DKb=Ay zxPyDudX}KESxwnfNkr%4I|(i2$_r$|eIj&B(*^QAYxOw;-pt&{f0YcUO-rDGW%8rRiDgr4(0 z%q-wt@6~)+-7H@!Td|;5x&Eru=Yc$4UjK5q#8C@+dK9el<?0+##d%nA!K)nB=5 z1&Cxt%2s}Dj&U^4HT0t^m?v~j^ZreE4b#=5Tv(yu~PDc4tE$WM$-D_OkQhfu16Qzm@<FHAE$xpB$SYZ- zMHYisaY&o;A6J%V>Utq*KdG?3B->0GzpjEU^UA2chwp}QKvp*4%nXS)eL7z|hCZ|X zTdK;wk26tABEF@b?N9iIo)W7xeVA$H)Sj{T>8D<#v zbJc#&gsk(%X3dI7a0uTsRQH~4l`IC16k6GsY`Mo=#W8+c%qq53@1%(lU4NP4PpEG9U~Csk| zkqYm=fgf?12vZ$4Tj`6NezmDAL@LhdAN#AUEZ<+%K>V2EpglzY(${X@tz(2Df5;aj zpZMW;U4EbJwd&TUW>c-$#t4QBzU3tr$B%lsc3V|-?x1TD1}JF`qzU@na&U=~s_J)n zwty68|6--v>)82gE9qNYSCBt%`Pp4IiR+~l3^je!cgf%AxrgEFRRn$MZ9`q0g4kvY z4_z}kt6uZq6C;|fJk)cH63C)9=V#kpjO9dR+(|teFJ9^JBc?y~y5>}M%BdGgRAfmF#cq znIlaulQ?4=Z=6wbzQy2`J$|N%vO$~@Wy-x6YD&7$)Yi@8Gq(MKL>doYv|@;#&P?oB z$4gpQYY${%vC*3XXZbwXr?>Rjq`BSj8+pFC6pIjxyzdxAcDeX4M=w3}(u&qQ&Rq7< z2D1~J8e|P(EXyR?ZRO%3Jgt|Cl&BqQZn5D?YqI%A=n0*o70rHkI$BkjIsGYZ2K~5I z!MEoNhCBrB*o5-T+7~RdbTL1qJkzW;z02vjW|LXMyzqfJ(~a_-X;A!h3+IdVlw=2R zF>z(6Y6J#x<>QeXDaiqSo@7szIdSpdlosl$Ju#$-Qk7N95z=^OibE*!fGO$*ft|6J zd8CwLN^R>mavKXW2wEu{nYp0hDZmms!^3|};X{JG8DxWi46(1`<7!PZg2RbbYdG#_@-kOgY zwLNosPUe$9xj6n83Y-tcv0~T)P9?_$Cfz9caZ3A=qXk}hf4u(9tSwM)J3}?TWbuOn z-Cd2GIDs3PFxCheA0EdQP&)wwtV|#kFR88 zZfMG~TY66P)M}{iV?_9cdaiwDMm&ak3D}$AaKR^DUUL9PVHL( z{WYpNj-w;*ZF!`OyO~3W@d>Wjob|!Ne@^SL)!oyas?r=KJ+|~TB<z-`{b(Mi z+MbTIo$AHR_6Cj=_0iz1)OKx)Y99&~QdODwp%#}bL4)wLQgk|D2_SDaJ zUG*(TBVp^cMAk`pcJSf#%Y^%_*H{m`j{Uh?qH+sd5=P*TSw!G-%?6i|EuCCf2)mHn zgv_)Z8!06oA1^3MnYHYeDzdS0A#0vz3A@E3$_mN~j*8T-<&Z)VjR)^2x5}QR>X1l3 zv2%P_Lx*4WrH+erqP%Fr<)ce$&(60mvrY*8_nj~d=~3%NmUVjth;5Ot({;SDsG?)Y zsAPS}F`QBNy85Y~rw5~IH(Gjx0K1Usy-qpB4_Q%Bc}({+kmFe9^ZktJW-9YcceqaL zuq~8(GY&UWYBMe1o@RWs_H1z{#3S;AYjc&m>wo~tOTD2OTF&xF zXz-I2Ln^t?$GAMIRk6oI9&&6AncLFUj~P0LX-volr9W4j@DE)k;)|53xgc$AhTbfc zGg3D}^nyzIo6u|g^Z1X6oE@zq|7^ z&9mIRZ1y}3e%mr>3@4;yWCD3^I@(fEkT9UmET=SyOf1C_pQy$l(F(+U+S_usKa&t6 zS6;U->T_dzjjOs(s7!C@*=w~6EnG+~tBd+?G$(7(RH8=~12s7ewwyAaM znQTs023->0YLd7V^Qm(ZX)gVl@{v2GSOeld(Q%G;HSexj)7Y?kjdg$N1y{TCvCiA! z<=%0SjF~dy9N)0~mfbSKHO?GoL#D+23^UdC8^t$I%*G>o-LmE)?CY8PLZ7?5gvY*;d$Ijl70fVS58xKduMO? z@tJXz4|w5(o`dEwj+%_}){|@8mP}kO1g%JFi1BvU-_?G^B~sXkCXpP+@9b$9j(Zbk zzeU&QcQuH(+ZpL-X6cES+u^o+Iq7UpnSHMm-|fh~@qB%ePyPb>Ou7`7L1wopF(oTY zA0CRuvs!zM+~*;$tzFy}CW|qBeCd2m{M9AX>ALnj z7QvgLF-b+T@dlK^=%OJFB_$<;B`7z;ujo;3Zfs&*bi2q%cGiH}$!#r*D*FrO@sl^S zUfE?R$P1}>*H~|!D?oor_*q+IOR_2?7Q!5437C0A)6uYzAizzw%Z8-(+V-9hRYQ^dzF)uA&jAQcYV6~~--b?%Jc(y5a? ze$1RvLXS=nm>LZW>PMZm=-^m)MZCCP7<86wjqdqo^<@eAA)KA5F<#9}*1fOS$UeC} zHW8yMwAgiXtZ?lGFxYe}V6j;6A`!^3++-qQBwc<$&5)CBv5+_2I) zAFWgR?s22$EPS-c8!MREPAE4m6IYQ#I2QbFCw)OSwfeM8ctb_R`%tHJn28oAF zshF8Bfvdlrrz}@#?n_*zmecCn>s!@H)I4{5PnB_}MoGOK zjp^E4Kw=W)5W-Isybh))oA?P1j>TaJ;(21ELzwcruUtn~V zgiX#@-HTFvMWAdN*%J#UhkLbTI>{gpcn7KM{wW8zGKJj^;#NvjU&U$cc;5Ln@eHHq z?RQtox_D=Wv5~G-ZpM67OS>Ga)@!oT$Fp|CJ&cp)o(H)v`0z<9a~)bxFl)=ihd=pz87E2BlKgh& zT~eUJa*#l2cC3Mex{8BCy4*$%S@7jn0XI!THM7%`!uE~m6`0^;zZ~bfJAZ_hXi;e- z<>Mo0$K4+e4T-9VC7ogB3T&bzaytSO&=O}R?Q0;M>F)wMf{25FgMf;PiqM>IB*=U> z>BM6s1O)vv2;jehKOm2^up&RbxQqy+G{20vh_HepgS5!@TUbH{r2_jA;?G}#JHCE< zJ^_;dqw@RDVDr=TYzOl`_{u>W*ss9-?MDa*gkY=le?JovmJ^l{5|$AZ7gqR_M1KA! z9}6r51Z_G51Z)V2SzsFfBOxU&C@iBO{O7N85`uZMz^_oiAOMlyo+$8mnXJBTl zr>}2fzb{D+2+1>`@#v57>`wAO>hw-V`i6Rre}NeCg0rQ7cqn*-j@bTl{o{~Lj>@u;iHZguaAw5U1C1>SeYhd(q2;vsjKM(c)iGHE%ExSE%E;OKzf(wFP zO#M&jKNggK!o*dw%RT~L%@gP?69gud@cA(2LS`UB zK<>9E0E9W1mj2Yazvt>ZbxS*YJxhDL-G`3Ei{h&ahTQ`e-%#SZKrap=F6?YzWNmL^ zWw|?X-_aHF3NYR!pk-{ojT`uXfrE)d6>N8e+ivBAg&+p8fq+5}L0|(O`=H@V8`qmf;a$GRav!zAwW9qXl`ULZ)D>Dz9PRng5|Tb zAtQhZO&~DnoOf#+0>RGO%F=ERPa&By|LGl&z7R}Skoh>T4G)B!-JYh59UkD*07zN@ z($LY1>%dJ~&eqD&#PCV47G-DH{hoYjCvpG512)B=>bcS#6&;<(dD`JUD7tCdJAL6jFM0Qu{G>ir$>!%*MbcyBc&TzCQiuz=<;|0Wa!gyR`- zBJ3yiIK^ejQV`xrNdHt!l*~hs-<^X$(?o#s+e2P*0EE7Yr6DAbgXKh3+sKKMB-*a;v){iI#g+nl*2P*7{q^HkNeY7$u%6}vB7jI0w$n- zU#bdT>hQQstUwEc4Iu7GfW`Tn*bxw_-@uClt8nZejNL1Wb*6x<^nt9Pu8q6~9uzq} zThIsg^PI-+zCRE82=_pJ1_7@$86QXwdPN|0jgn`M1B042-4>BA}mbObCRufe!KgBKcnTYBK3|92th zca8nigvlWin(sXT!NA-EOfSTU|D*`25x+e`eehAV_>p}=D8t+XnuCF-El`$6AQgeG z&EgM9ncu+tM~b_<+FVzEI7SFSq(RUX{fz+xgj<7$V?jXA&dA)v(g@ZQX=}AFsOnk( zE*9Xf9ymX6I_kFvedLg!Kxg-3k9%xH(+wcS0v7px!$Cms8ao`4;0+@KGZV}Gz{KcQ zmyrONA7JY$1k7^sAHb{}?Ds=^=*l3350FlPl^axuL!j)puR;D)XN#Z8Cun8uvL8~u z35lgOaKCQ=Z%}2_pF129Sc~olG<%;k;0yR(lncS1vvqm?AAw+6xx402w`m+=de&J zR<>r}&-v^(Z8CWQ!yy0=w#tPnh~b$-0$MrlJ8L~Oa`^H<v!SYm2&)(q1et13DZzl+V7*zo#)O~bQ9u7~=%KWEA z?^QruqK~iW0)mV?`R9~rQU5E}?oM$|s>SUXK)MaquU8@37{`1_Bv9QKIUqW_3CR`S z2T0>22nhTTw3A$iM>}xJmP2ymV3m8ARYT(#me?WT_7Ba(b&R8@0Z<13g6f8|#NmK` zWaazm;iOAJzaYR#1!({jYgOv7Sg=nY?1x2N^@`*k!0H4V0>w&|I~L!Q8vo_S*KaIoXwl{^XTM~gBMIaN$V}3ZSpI;n-W35!8nR0d> z;5`90Cjh~GWqCME(DL!K3@B`A4-%liBLHk29#OFrS_g1ezzel;V!OlP{a;q(^7aQ{ z-7wMvQTnfSa|3d~vkyQMN`dEqR*O>Mq$p@*Xk@5lYcBR3;BOhhR_ChPUmx}Xlm`F> zS}pqI0^hiWz?RvK{UAEk+}+~A6f}SrTD&8<4IjjQ)bo}I-aH4CSHTM{ww%8MA9eBT zKj`n3vdFI0oT~@aLA*l{0{{EpL+^1&gkMnN;H;(Xb-lf|NG)^3-#r6{!T~B7(51ey z=RYD!ne4TZ<1{<5sRF=)|B8g}KK}?Nt!KTvwiWDjGqVD1GX>hl^`9KUU;O@u#@d^u z$$O{JTY+<<2Sq-p;r9jq6AbV&w!1hPm;s?!+3%DC&9DR_ggQ06kblP#w%0S>U4+tY zlP;A2&lcbbLPRJK_V0L#R%S+f?0Ua=I_4V!T7;@d{;ZbTM;s1tcZPgS5ob>TW-f!Q z59)!gr@}}7dm&*zA8~fgrTGkiKm`y`wfm3`AB3!@Iv<( zB@5sKIb75vfiPlIcmRfp)n5_weBr$zSTkG#c%gOuN;s&ATUtBVe?JB9yvM$TQ6{2E z67XLBz|Cot42ZJ0=Z%BWW5dy++^#SzFK`HPr%^`iV zI7kbG@&O11x&z2s0}s7lO=RB-a5eQEkIva9{}g#3cS$ z(G4}AK%M{!D*m1(xL{y)#eLXVbki0f2Q27=4KyelAuaIG7c#o82U;8sl2(bMY-a(O zT|~eNR8`M)zykx5l8}j=0jTZm-O(o_m!r}P;=OFiSgnsPANIb~yj=7xe63wns-5SfDq zK*0bs`tC0H1=BNc(m+5q#{bhOctBEcu;3L;K;PtdquZB*EZ@zYRbbb8K#hbT97ycI z1>;~1tBn~M!X}zr1(wqsFy-X=nXM{7X6h&YRN6d5M0gnc9dUQrF*uvz2myxBK?N1M z`)q*<4}_x2ZnFZ5M6qZHK9xXBfA7VkgYw70vvRmtL=Bk`2J8b6tn}?br=1?Gd=+W9|A?h#2gd^c4wr#bUp|fn4bd(wt^7-S|&XNgzSI1c0jY$x8tVY zwgAu|kenn0&EA(%GV6PmW{wNYv4A*4<_z?h0L4b#;|L?&2b=@I{IWejO z)Z-xT2tbf!Y5xs*{~j%60ki_pZ-8(OU_w`l1fVGxZV~^inD5iF&Os3RAp?e?;6n zNAbne&bR>P&HFE15f%JLuss7l%*AXp;ILMMsapguR9Cve&I{bSa=1W73DK2fA_oD% z_L;#Ya(_j!opg$bO^~gqfs_&I@HOD3Df_=oY;tKM3;o^vBrJv*D%6FR12tF2{d09* zDGu-O|AYEl(O?)){c5|{06WvbA4Az0mOm86j|=zqYk9?qoXJ`TvoH@-O&Bs8Ldu7Q zg46%12#%qEo)CmO@Iu=uvQ-WXxxfD#)Slyl6*2Dv8-fOBI<>Tl*45i^on$|0TFb-Zu z@c#GY8XSPKKk+{sKcQCNVt5eoAEzE&{<8Y4umm(~AovGh#Q@#EAUA@S=C6_p&|PrO z0(QD`j{^J=Q(HkMpi61ME}>O|Bj)ge9SAa@+Y$uJi8cWcl%oiXe*oG491;TMFvkht z$>_lv8|v{9to{KEc4hMJ?hLo}^YvE1RUqI>@IS2re>s8%f_+2F&l9gMjK7Hv2DCqC zkIpUP!ip0F0PrdVu+aG*0YMk}UWv$a5$j_OKr7}z@KJ!E4Y~Xu(0-}o!R%Ib4|XpD zJ8(Sx=ROn-=;Zw;`R>^?pGNvbvlK81`W63h-u_BT#@jR05S1=;{4 zf3u1`u$)S4%K=X;pbrijIntxx#S*hMy8cTUcSphV)Iib)Q-utYV`!naF&$p5KpwWg1JwbWRCpnN5=7t~O{rB7l0R}!DfZ)Ku_V&PUgo|l30n{;2<$@pqcioeM9@;W7#G|KtY#Ld-t^#qN6#-CucxmW@+iGnfoppuW(_P==G@H3v}o z7q!*1urRWPxwM~u{w*e0zIaWp94`mhKN+Y(LaimF7(NF6fZH9$JF?vG2?$Hf01688 z>?M3KKUxkCDC2P3R>^aKGWQFjKeONL%EQ3yy%K&^;$(me>~RXbP~{bGISj%td-+>j zFy(DtugId{4-h9X!{o!{=J%#sK=e6n}Etb2CfR4X9o@Z z1JK`-4Ku-x=YH)}KwzLa^#{nykwbv&tx+(LTWy94(I6_C0I@+67|F52f!N!cfUQz+ zcJ^5FH6HM`%S=X&PQYK?hsdxlARnV<2Y>PJNgg85;qQwmr^oM@y7v9(`2(jeiWz%Ehx4_Q@~OrxS@XScl~dkc4uqtD#wW= zpyw`tEpgx|{(I2S{vB&yoq+k%jCuT5yC(zWpbhH)fBI9Jhx4fP|8WNXlEH)*#nuS6 zQ~6g`@aa==Odyz}1&|d$<(6?+(!YufzqCXCJL2xsb-uwz;VMw{aIlyYhH#X1`j8xb zck4f`YCp(j41aWYz-cbfMo|c)9^oM&|7XS0u+u>Mf!>vW8vh1>!D=cJ5Ku*ue+B)K zu>3&XE0Eo!v=Su+R^A8vl?nv+{)PW9xIYHLZ)@xT`vT$alkB^M=>%J9T7c4v7-SHa zDE@y8Vs}*5Z}I#vk%N;$2+|PL_jHFu{lO&cmVjT8VSlNc;OFZc0S@R4So0b{ps^VK ze?k9G_kIlS*T8m{g}rmixiv7LdthMPyI{bH*F z=z|O6EbYKWal7?xoaDUck_e*uJjnM1A!JWlAA+pne-Hj>kK`ell;E&%r44(5rJ&qAAh$B*fDGwk>XkCl%_Mw0dXyPJ#UG@qc z2+$8;LHG8Sz^wuBYl$-qXW#v5Pgw(-YA{8A?^oZrdkCcc9mJmoObXG7aIXV^9PCZZ z|MH*-1SfqO!8B-r1cV7fZvrlQf(r5?N`Ua+E)%xsv{;$C-U76#;KZNq4BH=`(F$9_ z{Mp|0y9g;6t-<6z031NeBv(SxILQ}(2 z;LQKNO7vagQYMyWKh8CXm>8KGf}4iGYL*=KU*(O=zqi5dF1sL#z#eNbD+OSU30(lb zi1}ySzoEXDO1-NlV3F-Jc%gg7{>kt_9Zqd2AZqqJUw7;54>VAz=4}BY=rCCMK;2>{ zI2gCDru`C)y!u&A(Vf_1K{Ie*OZwX8Sd|eUS2Y6 zhP9KS0aShn;&X5;AFlcOi6{n66N6i__lG-$tyz8*Oj{aIMyPsVEFBJRf1GkM>f=WM zTcO~Eu0!&_9uDW=%N31d67xVuJOUyRA=H#Ftig%(znhKr<_eaG1V}mAR)R@_wFyJF zTN1%Vn{Z9m;c^jBJNWIX--HvycK0H!#B6ZlCE!!#3e%CP&y!IhN%5*OJb1*sT%ipesij!nPf_g%K_V z{V8lIu>YnH5Lwv5!2CS{^9OZh zXD|N?(%yZzCD*hUdx3$V0t1nPOc%cJ;gJ3p#(#+Lz%c&h=(PV4peR8&e-`7+B@c)E zQ!5p1jllK0yDJIIYiCEWCf5NLSHKI6MS}{513aAbz5o&HNu>j@U>}12{Z3g}mZdh2 z(4_`+VGAe&1B9GDJmiF|EcPx=1TAmB>jxUZ4hjd*Ec=Wl97Fwi8S(zTrEe4({%9?nm4kEdWx1H373jq;tm^4(cG*g9FcEM&_WAd9URC z_m4(G9cq-zVIjae(L~SO0845Y3gUp|6%#L5&Tn6TO!!v6!m73b6d From 482a70fba1775a849a643761efc3952875e31f77 Mon Sep 17 00:00:00 2001 From: masensio Date: Fri, 31 Jul 2015 15:20:23 +0200 Subject: [PATCH 022/101] Replace jackrabbit 2.7.2 jar file by jackrabbit 2.10.1 jar file --- libs/jackrabbit-webdav-2.10.1.jar | Bin 0 -> 330116 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 libs/jackrabbit-webdav-2.10.1.jar diff --git a/libs/jackrabbit-webdav-2.10.1.jar b/libs/jackrabbit-webdav-2.10.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..068346888dbef204bd1af1ffe573a12091c235b6 GIT binary patch literal 330116 zcmbrlV~}mpk~LbkZJVcT+f}D*+qQSvI%V6oZJ(-Bwr%5``*p{=-8bUv*WGVNtcd+% zWvhkRPA@p`k#=+N(@DUFzZ`2Z( z_WGXF$afe(sy`LV1e?Q{GnSC$EA+}#val`HZqEpkb;Ug{MI%W>3^;;c!Eux_gW?ol zH_kzYB|-!ayQA97fd8X}gHa>o@yWOAfHJQG%Gn)u!zCtda@3|1@600)Pt-Sm(OXDX z)a4jNXNEhHH11kI9tK@Eo2vjr*T?j-FxzRj2OOr2axE(HP)T7wGkvvdj>@8fB;k>x z@&=v4g8@UyA9NGA__8fp#S-;{>~{AJLTE5v-33O~R?TJ?!Jst)XFLJ# zHmi6qO4rlry_MpRT6u)Pa=dgG*%iPu-SUlH#fiYNrbSJ^*9vZkXX4lXh*#@EWcAvP z*ElYB8dV!3%>}v=sJR>sdX+wTi$8bh_<%!?dVkP+e=FH(9$8q_nD+E}bCi$)@V-O^?I5lJ}} zA^=%Ecn{hY_3`TEh^Sm*ga+NT};hdA{e1+IT`fbQ(IAuLs#Km z6-}s@$QFEgFM2Yr{>?=Xc{nTeZrJ(>D5W0I+RCr%{5c=rmb&sebg3jwk@O`U2jBKN zVd6=ARzE>_w1&9Uoai_6>5dttj#_M%@>uwWyRVEMeQUw{2Cpas31!FeOpp!+1Z0j0 z1f=+Xg*WKGQ1}1B8|dE~A))>Oejxvjfd4eS`WIY8|Br^EVv1t&qGIwQQew*0iE;}2 zKafJNU(ubRAZ$jUGiFYU{CurbPI0!A1tiPe}q*px&C1K_2(l1Mi$EA zJ(c#A@nvVRY!Kj^C+K37NWZY~)!zP%Bnj~9fuHrZwp95c}1$W_uk7RjaeW+0qMK0O= z(rY$6>WmUkIYrkV_y2jSvS61hfG9AGgB4t|-!f zTv1sm5ixmXu}v*)=k*bEzvtQ&rxImLh>~npOWfm#`h(DF5lhi_JBp+*@;ahch`KQb zqR7ujzSQo(A`|yFHMtTtsf*RdL5Rfn?V;m%a1X zbKws;x56gK+sE@i+q~@-9B`kR>a|brpE?Wd&c>~^I9n6lUV*UJwby=HQNw4_UEP|x z^w+5zmCYXR&XoLBwXlxvzTWQ6kGu4Kx^v3vlaHU9cVUPx@X#+-3^gj%JbVF8c3%V5 zEccWd(5*>wq*~-WOnp+2rrMMy>JbYr=(Q-#^+qlgNNSJED#j7|n0jdZ+Ljy|-PpI@ z#MxyIGO7{NLRG5c!aX3b%hBuEFY;+P{1zTF$;Oo(yBdtf3TU)){&ilRxPVpn2^d9a zjI&*$1I~-+rSFo@t}JKT&}=*~n~r7_3^#4Bv2|i)L0ePO8mWf}6yq>Rvdffsaw%x7 z0PG!2#*scyJ)vqmdw2-^DoYsRY8XPCpB;URJFUj*{S6CE)u&x#-+3$NhNDg%gY6#X zbf@!iEgVQp;}!F}{SqvUrs5Kgd&2s6KO5CsfSxsPP-yabzTAl+NTs3WM~}PEz9Q%h z#AtciRZn;~{=^*4(5i)h%Fo~Szca`ZKy4$Rm4R zo*u6mEqOqX3w05+4p62`m{b$vvrU3 z!oKGy5Ib;`exZB%cmSUvH!UHc19xj*;(_xHV^adRACmoEuG5C5hB{p$kkGPMt*#0= ze6W_o_y%Yqc*!nus}zLC(WANQLy^ z1QY=uwU2I14?JzfO4vRdHecZR4iz022p{-u#x_&}R@PcC^&8^|O$g8+O7mPkKSKiw z>~X&9F@Dy0O6oB2<)u2h$Vz7F84F|ooFR0EO#m_vsHKFQnTM5s>pQtrL^!sqq@f>n zIJr0WXMI|Prn=abSx9q$BBd`5xEf$G0;xOwsMpd2j^~x!9Fs%66BsN8nMVVyOXg2D z843xoGl1~m9Kh9vAy_t1QS$|CnZxh zeo7sOQJ*-2tlJAlu|VSBi3Qr&?}Gn0?IvpxQuHCk=dLYOsd7M!_6sK%q1lMs2x+g| zK6OeB1m?63zyV6PTneU8H$n@x^vQt&$6#mo0YToH_GI@o)HqBImLxuxS(#!@Myr#x zcZKZCdiy|&1C?J&dSD!?f9-nwk3rAZ@}xi8B+2hM{>%HLTu937>x?*alsaX_ zN{DFex6s25hv|~>CM)bsFn<2huOu>&z)IVF%W?s>9CkoFydGd%Li1u7NnZTu7Ni5W zs9MNfvWHizRtc!+qNZyE`@V&JX>4hGmUnliOL|j#>1KKuf8L=c>m=FY1D1iXFi%2a zY^Y+NF#foT@{i1D>l6LSS=O(GZrdNce(w6HwzfqfM|r6lY|{N*5I}vu(n4*l==DIkX)8b+fQI z76H)K1PvBP6z_JfRBb%3V+?G8{g%kY0o-iV`Lm&We)+E!luS z{UVuNdc9x`iFtWO2C#R0tCzq?S*3k zaRHP;2G5s(enIa-&izsGj?pP(*_65K3P#-@P3`l#z`&(+j-Ph$(9{OcWku?QR3?ef zRdL?_-VM!P4?>SO<{P<%ULfbZ9)+(0rxnh7iUA15Z3oQgSmFEbM~H2;95wbvTN`q~FgI??OF)tye8O%As1(E~?#o`vo%-?IWTm$Pu8uGm6g&%^4 zl*O^T#_%FW23P_4z4`+yMdPn9Aw%*iJypdUP-MZ$_3^`WPW0H-b89IDdd zmiKRc*tl`lkwA}E<2p75U%1L^$*pQ?3+B$vQ{h|b=e%HEp{yA!QtKlFe+49nswqsy zVgf)N!_F(|%Vx>!E3&qY;%cCp?HGQsy$L)CBgDfPb90-{X{!m@k$=e&9pgSnsnn6Q zwv4o=n*87uw-i56_`v366eE4M`wdFatfb8VVo;ywvj-+o_JY@^Bxf+3ZQq=f#mse# z6pQ{bkD?6DBs*M^fJLQjA?{lO5GOrMWAqGEb#(1R6T1%4NMJx}f$4$k$E=23s8guI zg6T<*;z>~mJ!*2LMTB0BRf2L*gtTMnFErO6Xa}<-wP6PtQ^F%I4E*M(Cs9~8W7t(7 z(oE1IW|oAhR-=A$vc)-xXzPKz@IpPi21O3M5hMhshp4i4Kq(%oGE}C zM>KQd3|Ib=nuc3w9xpVZ8VW_Pg3U{jk;F2CQ0{OmB`@>%+hU14NbRB5{$p;bacTPV z?(z{X@!FBd+j#AjFW$-g{a`gks4rcXtDf$a78PAf0h&J<{V|RDIxgG^VWd*rF1_8GY&a^i}Gvo7NgWE%n%g2FY51Pp;41_lYA+ac5~Mk ze#m>N_(M-Vd_ibk%B=pxb~*GLm7eF7+_Gl(^)_P_ z1OD0K~vHlViIqOw33SKmQAaZE9Ac%fJZ zp^f9Bi!>+cX^<cW9l#VQ!DdR7VoB#Fx1Z+s(0j za4xgknT?oMbrZ^GEtHFz%F8u*dFLY!7TeRL$q-v-N<5_klh!Mw&||A`&BsNHnPMr7 z(^tyzTtQI7d}O9$d!cvq*y;s2FbTQK3SzTL2n-8<8o$e+G{PowZgb)_j@hK8#MI~D z>5`Yk@em+7rJdQ{o!Yhk*?*-<|B+m)`RY#r=wP z6ecnU5hGGm#J*IqEq-YqSC_|g1O3azi5kssaqp4U3RDeZOKAYOo7QMCFljC6)n=?@ zheIEJCK;&Zckc0?G>=vG%|Z(XVW5AIE&>yDK}9AgN8N8v=bg?qRv0D9nOH{7}6tgNW5X{ z4W`}?Ki|(ms(QTIb-FvXYrecb7az}hkOXwMyFZbebUx~Qdb_^Ug-_;63er?#XZXwRLuD>N__dt`9)iV+ei|urIls3v#e*pvw<}^P0=qvn@DtJHXF} z#3_D|4^1Bx^V+%~a3T|M^fkKyE@qOsTgKtezH(AZ>R-jqEm5zOoJwIR*`}^Xl zRb1lH*sr*op5|t4847R=Io+s;TD$eQgTS3^C2Qvtx%hrT1vYPbd&x*#{o#>+esUBZ zT9IXXU7)n*lXx7-A$5WG?Mz?xeR?1rn+_RvR1vW1CN6(H!jA#j18$sx zF=w%FHg)KvtDr4H0=nAnNzl*esQItrI}{clUm9*!&s+M0C$pJ&!HcDi4;r$~YWmi# z#5_P0C2%HcRD8m7M)L?h5zyQ#E^n3+S&@tz*@fH<*<*5rk?lQ0>Vl_IYqfTG(-?bt z7l4I~gKrC0jVXt!O<1v3Sx~cPB z=-@tNvAijCS@?|yoO_aN&nz;fm*#42U<^i<(&yWo=!unx{>(>GXG>Tw+NS5?fl`R5 z$4=8ADn%`}-yZFZi*wHb)5qK3jDPS)jYPAH>v9Ivs;g_L&vrvd^fKDn?i!2@&n4n6S!ZsDodO|V8FiW)kzXvBcPlrE!BF!nuHPEuy%-p3WS_%cdIWzJ3cXx2fV-amF5%9@ zM1mH)EhOmS8Jlo((L%Q37@+wyr!)mM~*;>Ew-?>-#pw#J(+A`WXh zM6j>o!dfuhV}yKpSN#z73eJ&et?FIa=a;OgGS3KANa#hPVYmr=nK?XsrXqPDg#y#* z`FP=-^Voc4PtIc!S1IBoas4zCS!CwIUJViaB?9$4+wJs5(DrWS`-!4bLaskBm%B&s zmCb^d6!Tkt+hIT^_#?0s>*ZUr7xb2*u{tHA3@Iqf0)7Y%uX;Te$w3f0kIrS({^`|H zYVZ8&LFXRx8~7isdQ;P0s4XH8kRIKC)vEu!;h(CFyn@Q#X5BZo9%0}I9JsrGhy<1e zY*0wGA`=li(v-ZBg=l#pS@FcSay(LY+Llv?cO9kgb5U}PhoNeUIj_dyIOR&D%+}Uf zcvOML492ieNNGmBOHmlt1l!XAw);YJXh90bj>>w#Ow_51==xa+3*HYOr9lO|p?aan zo9&P!Zt>Qc`<`o-H-q#SZT@K>0}(?9IK}uGYjOHerO?Kf;u5LCSZPJ2H}DZP5$eS| z4_f_yMB3bW{8{}s4#>a4#6M-Gf0f_=Q>3GD5v%JJWI`cMD#?xsd2hHn3($B6y!ALC$e%i!Q-?_lcWVrl9u zH}!XG5TOaqXV-d2nM2RDv7VYlpYE9W?*P}LkqaVKe0p!XbaSzm9cy+Byv5CxcOk>LGLoExxh`quhg!JH>`1=P>NZQfWCTgcI{35~%4AqxpBV&y7LZNI z?^!U{*J8R;l%q_|qEGCB zAWM=_$yrns!T%`u-S-T+zx7Hkt07Bl(!dF5olVcMB4RT|Inv?n1Iw4hV)kW=2rQ(itI|HGb4kym~L3YKZ#Qyhk8aA@-?CZ z<}a@VR)Tyh`jSnVkjFRY&s`t7X>JeCn&3Ug$zCJW)yin(zhj6gPd+J|J0+&p( zR9~1IYL+gH43bCb{)G*{0syzr!Z{=>Kys`KR5_Lu7aJ%-C>IUN4~@_qNFFC|w@&RD zYjBA$3EEy11Xfd_nbk6dLt!qo1Ipw$8T_y8-*8Y?_IWCzFC(FHGc&F1_N$QUfJiIy=IrM$8K`Ha@BMhd#-YBq&|l= z$Y0nhD#y3(=7y9VP03D?dTvu@g__k2?=3l9PMEmLPTj=kL4>Rperyasq(Z8S(w&#{kWXf&d-AmPCST$&S*b#fBSd-h><|L1C>{0nJ zVWwVFY3gi3!D<#&oo54CQU(~{t_0eIkKq!|>J?EoaY;l_n73 za(rvzl&1OWa%|2>xItp+W~7bZ&ECaOtAXp2LLPjbqab;QSl=$5 ztJ2Wd)p)Fw6&_v}gi)0WJG}j10n!@fOPiHHfITB+&$eCePC2&PU#|Eh1=i6?=DxBR z+53N>HCUI@<;Ysl_Hk{M@|B%+3;8m)D%Bd&z$Q4FJ(5@=gXuBM#60M=YWgaC9#{R@ zUolHxve9ZF2S?qLU*)#k$-jK^3Ctd&4Yl2}jdYzhdR~|)-Y%1G4-USRD8vUzu&vXY zdd|7=uR^MMyk%P@x~gemvyWu_OCal@P-UTI1QIn)%(8p{>PcRpe2ch;M<)hb6RpQ0 z=PyNzT;Mi!^?u^CLunFT7_0&YyZqtwpHUOcHH@Rjwihu~+byL4Ynwzli0TL2sLj>( zCW=Jw&o7^-+}y6rJ_Xa8Me3|lo?iJD20GR!it2%_=PW?>T5fyOyeB^s>AoLDaV+}K z%Dcu5o_uq&rQ-@r6vq|5q>njY{PDU(Wh?{=b|F89BQ+85+CD+8Z0X*gJ{;{cG>! zNyfxrY-8x`oE;+<3BrUFqW}8Gn0CdRqcQCf3>}fEfQX8LSBN~cWt}2{j7D!d1oB4F zXsDX@TuA_tK!20)4{iW)2XrDBHSy+3p|Y2rO2%BSBq3g9T~lPR>%E7T`zzz?5MXPn zY~pR;fEM4)Ei+F9OFI>ozi!P^sbP)hR|C{u)!{FNJ(g>GL7@E3AL5;s!&}x0V|x0c z!xWg-npWsgg^W9^_M(4oYP`@2tn;wlL902}>lf4VQz!j${;@;&Ze=K1|3;7cpNiCf z&5z>$GC!h*Za+<(?OmOWP5(V}Qnn5@|CY3AwN-oELyT|V+o65#q#>z{fFuYwj-uGh z-dApejb5z(e{08UTPG z6jB$7t}5mXw!+2`lVZWUL-B#nWY*`$%k$ezxwvHyxC5qhCvDwMcb=ic6CReidM0$1j-Vbk!|(EY&BnW1eYl_Gs)Z z-4w7g!0k2JVHj6fW43QwM_YkBf_kZ~C*;an9i>a5c)Xx$<|WqDWBBHOOVJ zogU3ErKe4qQgueysIhpnRG3;0anxb8a?{Y3s(2@QPCTT;7Hnq_;x5V>-Iz69aHgt~ zmE8@pYvQRm$6f<)u;a!(vJB|zOmrHI8C)@FY5K@E}O`q)1_?Sx7@DeuK?YlgPWvn~oJuYGy#MaDU@T(rs4I z@hwOcq0$YBUV#GIt~A1_X;*;(&l?)qkFp&cok{mvnl`}oo8}u6xcWXDc&CtL_k%wN zy(MePz7EkB$7pz8hL{KItP9imLk9zlzI@#ETd<+{vtOy`a`;SAf8~*rmYYgmCyINB z#Gnv}(26;3qut2Y@9C~;^F7~HG`ZYL3z;W2+Tx>)*1Y?ssl@IT%Queqvf_n`RguG_ zfruJCug)so(#hM_^ctFU3usCjf6m^Z%S9(#;cdbf!27IP0{* z>ATRv4SNQx1va!7ET?hz1|6ZeOrsB2e_pHRFL78-79@XUHX(cC_*IgrKin}b9OFue z%gEhWkD>yDC_eJQzJU}z5kx%$t1lUecks*m+BPHZbGLjp9|52*$Z`9WykWVwIDYxp zd4@#JJ1YS(0gd~jYFs?>#iOf^%;e^yr&Sb}twyK}MMH!{Ur}SI>2$#O@qVPv4bk+> zUM4o#pM}1RI|31n09mQ+&>o{RDcl%Jtx8gRA#V9h8cNn$=hw>pf}bW1x@f#5G*I4? zfRNIH8*=oJ%E^#(8W?*<=r|+}f9;V0!u$|SNI015vWv;ssQqH$B}W`FS{zYaEwOjJ z%}JfjOnf~fWY%;>*O&`3Qk{sBlhJrS2_@W!o?y2?kQr{Z1>FaZy%QVihSbPaz~m3X zZ4MqKl~t@J;Wqz$wD-GHuGgnxJj^W|g4yo2uSKAd^Q_na@Axr1n!68hSOJ8PHC~jG` z)O|3}ya^wS9geLkBXg;z#y2LM%UTD7jOY8;DTBKtpJQhiQYtQp)HYO_H=hG))9UVH zQ^t>v#@?mx9`-u#!Z!BY#YydvjN-%uM2`)@3JLR^<8`zM3cpj$oY^R~tBVNt*a!NB z#`X|?NAS#(T?vP^l>(wDSa-M^#$3r;qc$tprOA%XpU%>ioCpq1UCP;o>pGeSGL3HxGqS-{Vz7a2+$FQvb%$~c zFg9dl0P4k1J-8&!QaF!kBH4Mz{|6(3E>KjUK>`7#{~cHPr;_lmjLh}FW8{CM-fA^% zdsGRuuaPZ}OH*eSM@dP>P$#Aq)Kn*1VQOMBTcX`WAmZe8FFr?hn`JZiY{0LIpM-DA zJuO7dd(cHse|0=znI(Ref--^p55QMQc<6)1130k8IuD~_&ccII zvQX#Aky7xsoYhJj&!W!a!i`dW|=5Lz;MmX@fvY`I9RezZtjaOAEC^#UL=KDM>v}P zye*~Q>kvs~iVWqNW?>2SoM&s$oSdDyx0y+sd@$$RW|Qr0h#_W%y)rdIWzn^J@fl{v zrm%{y6ncIwn>~{V@6b-?mX>B>ox$9QA`mN!4ju-v4TDco9FB~hV8v!lH9heN9sFAO zovhO1xIqb0D6Rw};#o){VLolpJ*W1SJ3ak7!nK3oM==$;bwgLZX=1}7T(##_oa4d* z3Z!n%_Ggf}7O7>XX z(indH&y~@->ev+;hI0=>!V`_KM>u+gCm%ANLAl)g<6dS21#q$OOb!-fXnolnnU0xO}s%fLpL5c%(6zhD6x0P{}>W# z&cf5@6n3o>nj>@cSNN@Ze@?6TD72KKaYx!_cG%jSQH@L^c1Rr>qfklNyPi_feNkCe zRjA;L>AS5j43yEv@i2&t4j%56a#Zf6*qJUaa)6wtC&Lg(uI!H7CQ=B5@|%7B8!8?U zght{L)jC(!eIeIKEvQ98gO294ts6W3C77ldAaSZc??Kozt&Zr^9V(X*ZfU zJhfoqiX1n{C`sNR(GoADS*->Pc%d(^JD`?7@QHe-xX6fW4xMG^Yfw4hYn760%};2A zt3k(wzFTCaRTrt z%1O-2iDr#(Qp-QF5cmrt-?@$);bGh4*{&dJb};ydbbSDXHT8lEvRMK^ z=9j4SaLx3kZFSsyu@T3LzD7uVB!?wYuC6I)Jmj{vREaT~NIrj}Y;mX5;?w$)4vZ9z z{@5kiq`YcI0?l+d8A|*wBFyC7cbZ*+;w}{2=+Wd##ZG$^c@F&3j0xc4g=~0Q1c{{j z9&y^9gfZ{Q^UASX8mF#EyitM(x~f)-5aG&9^2`Q78ju8`wa$Va+Y8XLYfQd`^|(No zrAKBeWQ~|u?~@M<>ubsC97$x#I?$gvLR~bq=0J>#uX*IMz1R4ApWFX{cH+(nHWzRp zAR4&;3fh1Ce?j}-u1duIZy#l8XlHEtZ-^d~tgXDRhBW%TGJ;VtGk*V17oGVd5kccdfjA!xLFRbS=pV8M=KQY~nf-o<)Ft>oE`y*}~4cTMt zheT)ZW6maDC(p<2to>}bMM#I|&$1j+HU;Vm+TZa%lX9E!s*f##l{z{%Oj!#F?}%%? zHnwZE98ccfTe0QJ0ttsV;&?W2p+Yhiyo)R6j(=)~G>l7@mtUHdu5KwyLM~bVD&f%1 z5Y~<^S%R0_WOZBHG^^~a{-ctn9X;}(rMrmEoM&fw#9g%>-N3URqlNp18O`9zx@d({ zU1Qa>RsyV_G`|5Wu4^qAA_y!lLrm*vUufA3kIL4JEq94?WY*Zc#l|+d!eolf6FpMA zv_`P>+mO{d4St#zb^fPC>b!}ZD%&J?^?{6dx>w_pqD9<1t@!4`l>B8;Q0+}5PtEnn z^IYBn?||9wJW9pXtG5C+&K9wiqZUe&LC`R7e1eX|TwIphKwKuR-@y*O6Ym>bNJ}DD zcp)1tn{96zD}4M_>@SM&vF|yPz7htq>e+qn9zIsed<0@3fp#ebIl1Q_VufZ52uD1Z zS#iwXLP#F#(KXrc`TQOak^m?7Dy$Iu+piPL6+v-NS}Z`UhO@-AzAMm%(9#a*+R{}$Dd1IWXd

@?Gep>&EaJyO1Ch(4}6tOiGjf;6GjAp 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 &8lZVJQI}=kTomGw|MUrMp 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

oL+Y+cEeq@>+1!_tryi>-5ZFB|F2Rf; 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

03*wJ3# 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�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�H5d%Nzv!)&2b? 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 oBm%Zp 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 z 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

Gas7 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 z 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 literal 0 HcmV?d00001 From dc057816d3b2b5e2f1544773249d86ac875df4b3 Mon Sep 17 00:00:00 2001 From: masensio Date: Tue, 4 Aug 2015 11:14:07 +0200 Subject: [PATCH 023/101] Update buildTools version to 22.0.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 13768280..9119948a 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,7 @@ dependencies { android { compileSdkVersion 19 - buildToolsVersion "20.0.0" + buildToolsVersion "22.0.1" sourceSets { main { From 8d9e0bf682646367999ed5b98034fb700086d863 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Tue, 4 Aug 2015 11:33:18 +0200 Subject: [PATCH 024/101] Fixed build tools dependency in Travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d553cf73..d663a0c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: android android: components: - - build-tools-20.0.0 + - build-tools-22.0.1 - android-19 - android-17 - android-14 From 3ecefdfbcc15fa78a0ab40b9f882579fff4abee2 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Tue, 4 Aug 2015 11:49:07 +0200 Subject: [PATCH 025/101] Updated buildTools in all the Gradle files --- sample_client/build.gradle | 2 +- test_client/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sample_client/build.gradle b/sample_client/build.gradle index 20889409..3518d29e 100644 --- a/sample_client/build.gradle +++ b/sample_client/build.gradle @@ -10,7 +10,7 @@ dependencies { android { compileSdkVersion 19 - buildToolsVersion "20.0.0" + buildToolsVersion "22.0.1" sourceSets { main { diff --git a/test_client/build.gradle b/test_client/build.gradle index 7eab7e57..d9d8f39d 100644 --- a/test_client/build.gradle +++ b/test_client/build.gradle @@ -12,7 +12,7 @@ dependencies { android { compileSdkVersion 19 - buildToolsVersion "20.0.0" + buildToolsVersion "22.0.1" sourceSets { main { From 6752b25b8d85952ca9505ab9dea799aa84e3e4b3 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Mon, 3 Aug 2015 11:20:05 +0200 Subject: [PATCH 026/101] Added username to OwnCloudSamlSsoCredentials --- .../android/lib/common/OwnCloudClientFactory.java | 14 +++++++------- .../lib/common/OwnCloudCredentialsFactory.java | 4 ++-- .../lib/common/OwnCloudSamlSsoCredentials.java | 8 +++++--- .../android/lib/common/accounts/AccountUtils.java | 7 ++++--- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/com/owncloud/android/lib/common/OwnCloudClientFactory.java b/src/com/owncloud/android/lib/common/OwnCloudClientFactory.java index bc6d61c5..740aed54 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudClientFactory.java +++ b/src/com/owncloud/android/lib/common/OwnCloudClientFactory.java @@ -82,8 +82,9 @@ public class OwnCloudClientFactory { boolean isSamlSso = am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null; OwnCloudClient client = createOwnCloudClient(baseUri, appContext, !isSamlSso); - - if (isOauth2) { + + String username = account.name.substring(0, account.name.lastIndexOf('@')); + if (isOauth2) { String accessToken = am.blockingGetAuthToken( account, AccountTypeUtils.getAuthTokenTypeAccessToken(account.type), @@ -100,11 +101,10 @@ public class OwnCloudClientFactory { false); client.setCredentials( - OwnCloudCredentialsFactory.newSamlSsoCredentials(accessToken) + OwnCloudCredentialsFactory.newSamlSsoCredentials(username, accessToken) ); } else { - String username = account.name.substring(0, account.name.lastIndexOf('@')); //String password = am.getPassword(account); String password = am.blockingGetAuthToken( account, @@ -136,7 +136,8 @@ public class OwnCloudClientFactory { boolean isSamlSso = am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null; OwnCloudClient client = createOwnCloudClient(baseUri, appContext, !isSamlSso); - + + String username = account.name.substring(0, account.name.lastIndexOf('@')); if (isOauth2) { // TODO avoid a call to getUserData here AccountManagerFuture future = am.getAuthToken( account, @@ -166,12 +167,11 @@ public class OwnCloudClientFactory { String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN); if (accessToken == null) throw new AuthenticatorException("WTF!"); client.setCredentials( - OwnCloudCredentialsFactory.newSamlSsoCredentials(accessToken) + OwnCloudCredentialsFactory.newSamlSsoCredentials(username, accessToken) ); } else { - String username = account.name.substring(0, account.name.lastIndexOf('@')); //String password = am.getPassword(account); //String password = am.blockingGetAuthToken(account, MainApp.getAuthTokenTypePass(), // false); diff --git a/src/com/owncloud/android/lib/common/OwnCloudCredentialsFactory.java b/src/com/owncloud/android/lib/common/OwnCloudCredentialsFactory.java index c1632cde..e854fd67 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudCredentialsFactory.java +++ b/src/com/owncloud/android/lib/common/OwnCloudCredentialsFactory.java @@ -36,8 +36,8 @@ public class OwnCloudCredentialsFactory { return new OwnCloudBearerCredentials(authToken); } - public static OwnCloudCredentials newSamlSsoCredentials(String sessionCookie) { - return new OwnCloudSamlSsoCredentials(sessionCookie); + public static OwnCloudCredentials newSamlSsoCredentials(String username, String sessionCookie) { + return new OwnCloudSamlSsoCredentials(username, sessionCookie); } public static final OwnCloudCredentials getAnonymousCredentials() { diff --git a/src/com/owncloud/android/lib/common/OwnCloudSamlSsoCredentials.java b/src/com/owncloud/android/lib/common/OwnCloudSamlSsoCredentials.java index 16c1686e..e2d67ee8 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudSamlSsoCredentials.java +++ b/src/com/owncloud/android/lib/common/OwnCloudSamlSsoCredentials.java @@ -30,9 +30,11 @@ import android.net.Uri; public class OwnCloudSamlSsoCredentials implements OwnCloudCredentials { + private String mUsername; private String mSessionCookie; - public OwnCloudSamlSsoCredentials(String sessionCookie) { + public OwnCloudSamlSsoCredentials(String username, String sessionCookie) { + mUsername = username != null ? username : ""; mSessionCookie = sessionCookie != null ? sessionCookie : ""; } @@ -63,8 +65,8 @@ public class OwnCloudSamlSsoCredentials implements OwnCloudCredentials { @Override public String getUsername() { - // its unknown - return null; + // not relevant for authentication, but relevant for informational purposes + return mUsername; } @Override diff --git a/src/com/owncloud/android/lib/common/accounts/AccountUtils.java b/src/com/owncloud/android/lib/common/accounts/AccountUtils.java index 6d2b033e..62eeed7b 100644 --- a/src/com/owncloud/android/lib/common/accounts/AccountUtils.java +++ b/src/com/owncloud/android/lib/common/accounts/AccountUtils.java @@ -167,7 +167,9 @@ public class AccountUtils { boolean isSamlSso = am.getUserData( account, AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null; - + + String username = account.name.substring(0, account.name.lastIndexOf('@')); + if (isOauth2) { String accessToken = am.blockingGetAuthToken( account, @@ -182,10 +184,9 @@ public class AccountUtils { AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(account.type), false); - credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials(accessToken); + credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials(username, accessToken); } else { - String username = account.name.substring(0, account.name.lastIndexOf('@')); String password = am.blockingGetAuthToken( account, AccountTypeUtils.getAuthTokenTypePass(account.type), From 1fa8e79b3fbf3e255f62484aa5fbf33f2ce35f1a Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Mon, 3 Aug 2015 11:40:18 +0200 Subject: [PATCH 027/101] Fixed unit tests --- .../android/lib/test_project/test/OwnCloudClientTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/OwnCloudClientTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/OwnCloudClientTest.java index 5328e9cf..e11aff8a 100644 --- a/test_client/tests/src/com/owncloud/android/lib/test_project/test/OwnCloudClientTest.java +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/OwnCloudClientTest.java @@ -135,7 +135,7 @@ public class OwnCloudClientTest extends AndroidTestCase { client.setCredentials(credentials); assertEquals("Bearer credentials not set", credentials, client.getCredentials()); - credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials("samlSessionCookie=124"); + credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials("user", "samlSessionCookie=124"); client.setCredentials(credentials); assertEquals("SAML2 session credentials not set", credentials, client.getCredentials()); From 0ae4d1dac934dc0c46fd27e3e3f0b4b8232472d7 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Thu, 6 Aug 2015 12:40:59 +0200 Subject: [PATCH 028/101] Updated README.md with new policy: PRs should go to master, no more to develop --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3cf3db3f..56f6fcbc 100644 --- a/README.md +++ b/README.md @@ -19,14 +19,14 @@ __Step 2.__ Define a dependency within your project. For that, access to Propert The repository holds two main branches with an infinite lifetime: -- master -- develop +- stable +- master -Branch __origin/master__ is considered the main branch where the source code of HEAD always reflects a production-ready state. +Branch __origin/stable__ is considered the main branch where the source code of HEAD always reflects a production-ready state. -Branch __origin/develop__ is considered the main branch where the source code of HEAD always reflects a state with the latest delivered development changes for the next release. +Branch __origin/master__ is considered the main branch where the source code of HEAD always reflects a state with the latest delivered development changes for the next release. -When the source code in the develop branch reaches a stable point and is ready to be released, all of the changes should be merged back into master somehow and then tagged with a release number. +When the source code in the master branch reaches a stable point and is ready to be released, all of the changes should be merged back into stable somehow and then tagged with a release number. Other branches, some supporting branches are used to aid parallel development between team members, ease tracking of features, prepare for production releases and to assist in quickly fixing live production problems. Unlike the main branches, these branches always have a limited life time, since they will be removed eventually. @@ -35,7 +35,7 @@ The different types of branches we may use are: - Branch __perNewFeature__ - Branch __releaseBranches__ -Both of them branch off from develop and must merge back into develop branch through a Pull Request in Github. Once the PR is approved and merged, the US branch may be deleted. +Both of them branch off from master and must merge back into master branch through a Pull Request in Github. Once the PR is approved and merged, the US branch may be deleted. Source: http://nvie.com/posts/a-successful-git-branching-model From e71ba7faee2b24b285a05fae6a596cf8d5e76b33 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Fri, 7 Aug 2015 09:09:20 +0200 Subject: [PATCH 029/101] Removed reference to git branching model to avoid confussion --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 56f6fcbc..715e2f3b 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,6 @@ The different types of branches we may use are: Both of them branch off from master and must merge back into master branch through a Pull Request in Github. Once the PR is approved and merged, the US branch may be deleted. -Source: http://nvie.com/posts/a-successful-git-branching-model ### License From d73180ab67b1deed77add0a7078d362d1cbf3256 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Fri, 19 Sep 2014 11:53:21 +0200 Subject: [PATCH 030/101] Added build.gradle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9119948a..f9a7cef7 100644 --- a/build.gradle +++ b/build.gradle @@ -49,4 +49,4 @@ android { abortOnError false } } -} +} \ No newline at end of file From 39b3f376e218d577ba7f85204774063a28865130 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Fri, 19 Sep 2014 12:07:17 +0200 Subject: [PATCH 031/101] Added gradle folder to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dd7c979e..984d59e0 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ # generated files bin/ build/ +gradle/ gen/ target/ *.iml From 7fd0028cc993e44581f5a0d42d9b91a65fb35912 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Fri, 19 Sep 2014 12:20:14 +0200 Subject: [PATCH 032/101] Added sample_client build.gradle --- sample_client/build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sample_client/build.gradle b/sample_client/build.gradle index 3518d29e..be251c14 100644 --- a/sample_client/build.gradle +++ b/sample_client/build.gradle @@ -5,6 +5,7 @@ repositories { } dependencies { + compile fileTree(dir: 'libs', include: '*.jar') compile project(':') } @@ -35,7 +36,7 @@ android { debug.setRoot('build-types/debug') release.setRoot('build-types/release') } - + lintOptions { abortOnError false } From 4a76d429abadf7ad40cafa762fb590f49e9e914f Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Fri, 19 Sep 2014 12:37:30 +0200 Subject: [PATCH 033/101] Updated build.gradle to allow Android Studio to properly identify test_client as a module --- sample_client/build.gradle | 2 +- test_client/build.gradle | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/sample_client/build.gradle b/sample_client/build.gradle index be251c14..ea875afd 100644 --- a/sample_client/build.gradle +++ b/sample_client/build.gradle @@ -36,7 +36,7 @@ android { debug.setRoot('build-types/debug') release.setRoot('build-types/release') } - + lintOptions { abortOnError false } diff --git a/test_client/build.gradle b/test_client/build.gradle index d9d8f39d..98a93568 100644 --- a/test_client/build.gradle +++ b/test_client/build.gradle @@ -7,7 +7,6 @@ repositories { dependencies { compile 'commons-httpclient:commons-httpclient:3.1' compile 'com.android.support:support-v4:20.0.0' - compile project(':') } android { From c3478eb8d4d8544f321cbff7c250ca5ed5fd0d40 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Fri, 19 Sep 2014 13:38:04 +0200 Subject: [PATCH 034/101] Disabled abort-build-on-lint-error check (all modules have errors). --- build.gradle | 2 +- sample_client/build.gradle | 5 +++++ test_client/build.gradle | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f9a7cef7..9119948a 100644 --- a/build.gradle +++ b/build.gradle @@ -49,4 +49,4 @@ android { abortOnError false } } -} \ No newline at end of file +} diff --git a/sample_client/build.gradle b/sample_client/build.gradle index ea875afd..31503a37 100644 --- a/sample_client/build.gradle +++ b/sample_client/build.gradle @@ -44,4 +44,9 @@ android { packagingOptions { exclude 'META-INF/LICENSE.txt' } + android { + lintOptions { + abortOnError false + } + } } diff --git a/test_client/build.gradle b/test_client/build.gradle index 98a93568..05d527b8 100644 --- a/test_client/build.gradle +++ b/test_client/build.gradle @@ -44,4 +44,9 @@ android { packagingOptions { exclude 'META-INF/LICENSE.txt' } + android { + lintOptions { + abortOnError false + } + } } From 5f66b204bb49daedc362b1592ea97ae1f6898ca5 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Fri, 19 Sep 2014 13:49:46 +0200 Subject: [PATCH 035/101] Updated .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 984d59e0..dd7c979e 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ # generated files bin/ build/ -gradle/ gen/ target/ *.iml From 0842c4c4072815ae889cfd23910fd794c5bfb427 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Thu, 23 Oct 2014 22:46:49 +0200 Subject: [PATCH 036/101] Added some neccesities for the copy operation --- .../operations/RemoteOperationResult.java | 129 ++++++----- .../files/CopyRemoteFileOperation.java | 215 ++++++++++++++++++ 2 files changed, 283 insertions(+), 61 deletions(-) create mode 100644 src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java diff --git a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java index 8075d1ef..e4295311 100644 --- a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java +++ b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java @@ -33,8 +33,12 @@ import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; import java.util.ArrayList; +import android.accounts.Account; +import android.accounts.AccountsException; -import javax.net.ssl.SSLException; +import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; +import com.owncloud.android.lib.common.network.CertificateCombinedException; +import com.owncloud.android.lib.common.utils.Log_OC; import org.apache.commons.httpclient.ConnectTimeoutException; import org.apache.commons.httpclient.Header; @@ -43,24 +47,27 @@ import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.DavException; import org.json.JSONException; -import android.accounts.Account; -import android.accounts.AccountsException; +import java.io.IOException; +import java.io.Serializable; +import java.net.MalformedURLException; +import java.net.SocketException; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; +import java.util.ArrayList; -import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; -import com.owncloud.android.lib.common.network.CertificateCombinedException; -import com.owncloud.android.lib.common.utils.Log_OC; +import javax.net.ssl.SSLException; /** * The result of a remote operation required to an ownCloud server. - * + *

* Provides a common classification of remote operation results for all the * application. - * + * * @author David A. Velasco */ public class RemoteOperationResult implements Serializable { - + /** Generated - should be refreshed every time the class changes!! */; private static final long serialVersionUID = -1909603208238358633L; @@ -71,32 +78,32 @@ public class RemoteOperationResult implements Serializable { OK_SSL, OK_NO_SSL, UNHANDLED_HTTP_CODE, - UNAUTHORIZED, - FILE_NOT_FOUND, - INSTANCE_NOT_CONFIGURED, - UNKNOWN_ERROR, - WRONG_CONNECTION, - TIMEOUT, - INCORRECT_ADDRESS, - HOST_NOT_AVAILABLE, - NO_NETWORK_CONNECTION, + UNAUTHORIZED, + FILE_NOT_FOUND, + INSTANCE_NOT_CONFIGURED, + UNKNOWN_ERROR, + WRONG_CONNECTION, + TIMEOUT, + INCORRECT_ADDRESS, + HOST_NOT_AVAILABLE, + NO_NETWORK_CONNECTION, SSL_ERROR, SSL_RECOVERABLE_PEER_UNVERIFIED, BAD_OC_VERSION, - CANCELLED, - INVALID_LOCAL_FILE_NAME, + CANCELLED, + INVALID_LOCAL_FILE_NAME, INVALID_OVERWRITE, - CONFLICT, + CONFLICT, OAUTH2_ERROR, SYNC_CONFLICT, - LOCAL_STORAGE_FULL, - LOCAL_STORAGE_NOT_MOVED, - LOCAL_STORAGE_NOT_COPIED, + LOCAL_STORAGE_FULL, + LOCAL_STORAGE_NOT_MOVED, + LOCAL_STORAGE_NOT_COPIED, OAUTH2_ERROR_ACCESS_DENIED, - QUOTA_EXCEEDED, - ACCOUNT_NOT_FOUND, - ACCOUNT_EXCEPTION, - ACCOUNT_NOT_NEW, + QUOTA_EXCEEDED, + ACCOUNT_NOT_FOUND, + ACCOUNT_EXCEPTION, + ACCOUNT_NOT_NEW, ACCOUNT_NOT_THE_SAME, INVALID_CHARACTER_IN_NAME, SHARE_NOT_FOUND, @@ -106,6 +113,7 @@ public class RemoteOperationResult implements Serializable { OK_REDIRECT_TO_NON_SECURE_CONNECTION, INVALID_MOVE_INTO_DESCENDANT, PARTIAL_MOVE_DONE, + PARTIAL_COPY_DONE, INVALID_CHARACTER_DETECT_IN_SERVER } @@ -161,20 +169,20 @@ public class RemoteOperationResult implements Serializable { } } } - + public RemoteOperationResult(boolean success, int httpCode, Header[] headers) { this(success, httpCode); if (headers != null) { Header current; - for (int i=0; i files){ - mData = files; + public void setData(ArrayList files) { + mData = files; } - - public ArrayList getData(){ - return mData; - } - + + public ArrayList getData() { + return mData; + } + public boolean isSuccess() { return mSuccess; } @@ -291,9 +299,9 @@ public class RemoteOperationResult implements Serializable { return mCode == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED; } - public boolean isRedirectToNonSecureConnection() { - return mCode == ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION; - } + public boolean isRedirectToNonSecureConnection() { + return mCode == ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION; + } private CertificateCombinedException getCertificateCombinedException(Exception e) { CertificateCombinedException result = null; @@ -360,10 +368,10 @@ public class RemoteOperationResult implements Serializable { } else if (mException instanceof AccountsException) { return "Exception while using account"; - + } else if (mException instanceof JSONException) { - return "JSON exception"; - + return "JSON exception"; + } else { return "Unexpected exception"; } @@ -415,25 +423,24 @@ public class RemoteOperationResult implements Serializable { public String getRedirectedLocation() { return mRedirectedLocation; } - + public boolean isIdPRedirection() { return (mRedirectedLocation != null && - (mRedirectedLocation.toUpperCase().contains("SAML") || - mRedirectedLocation.toLowerCase().contains("wayf"))); + (mRedirectedLocation.toUpperCase().contains("SAML") || + mRedirectedLocation.toLowerCase().contains("wayf"))); + } + + /** + * Checks if is a non https connection + * + * @return boolean true/false + */ + public boolean isNonSecureRedirection() { + return (mRedirectedLocation != null && !(mRedirectedLocation.toLowerCase().startsWith("https://"))); } - - /** - * Checks if is a non https connection - * - * @return boolean true/false - */ - public boolean isNonSecureRedirection() { - return (mRedirectedLocation != null && - !(mRedirectedLocation.toLowerCase().startsWith("https://"))); - } public String getAuthenticateHeader() { - return mAuthenticate; + return mAuthenticate; } public String getLastPermanentLocation() { diff --git a/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java new file mode 100644 index 00000000..56e7eeb9 --- /dev/null +++ b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java @@ -0,0 +1,215 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2014 ownCloud Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.resources.files; + +import android.util.Log; + +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.network.WebdavUtils; +import com.owncloud.android.lib.common.operations.RemoteOperation; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.lib.resources.status.OwnCloudVersion; + +import org.apache.commons.httpclient.HttpStatus; +import org.apache.jackrabbit.webdav.DavException; +import org.apache.jackrabbit.webdav.MultiStatusResponse; +import org.apache.jackrabbit.webdav.Status; +import org.apache.jackrabbit.webdav.client.methods.CopyMethod; + +import java.io.IOException; + + +/** + * Remote operation moving a remote file or folder in the ownCloud server to a different folder + * in the same account. + *

+ * Allows renaming the moving file/folder at the same time. + * + * @author David A. Velasco + */ +public class CopyRemoteFileOperation extends RemoteOperation { + + private static final String TAG = CopyRemoteFileOperation.class.getSimpleName(); + + private static final int COPY_READ_TIMEOUT = 600000; + private static final int COPY_CONNECTION_TIMEOUT = 5000; + + private String mSrcRemotePath; + private String mTargetRemotePath; + + private boolean mOverwrite; + + + /** + * Constructor. + *

+ * TODO Paths should finish in "/" in the case of folders. ? + * + * @param srcRemotePath Remote path of the file/folder to move. + * @param targetRemotePath Remove path desired for the file/folder after moving it. + */ + public CopyRemoteFileOperation( + String srcRemotePath, String targetRemotePath, boolean overwrite + ) { + + mSrcRemotePath = srcRemotePath; + mTargetRemotePath = targetRemotePath; + mOverwrite = overwrite; + } + + + /** + * Performs the rename operation. + * + * @param client Client object to communicate with the remote ownCloud server. + */ + @Override + protected RemoteOperationResult run(OwnCloudClient client) { + + OwnCloudVersion version = client.getOwnCloudVersion(); + boolean versionWithForbiddenChars = + (version != null && version.isVersionWithForbiddenCharacters()); + + /// check parameters + if (!FileUtils.isValidPath(mTargetRemotePath, versionWithForbiddenChars)) { + return new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME); + } + + if (mTargetRemotePath.equals(mSrcRemotePath)) { + // nothing to do! + return new RemoteOperationResult(ResultCode.OK); + } + + if (mTargetRemotePath.startsWith(mSrcRemotePath)) { + return new RemoteOperationResult(ResultCode.INVALID_MOVE_INTO_DESCENDANT); + } + + + /// perform remote operation + CopyMethod copyMethod = null; + RemoteOperationResult result = null; + try { + copyMethod = new CopyMethod( + client.getWebdavUri() + WebdavUtils.encodePath(mSrcRemotePath), + client.getWebdavUri() + WebdavUtils.encodePath(mTargetRemotePath), + mOverwrite + ); + int status = client.executeMethod(copyMethod, COPY_READ_TIMEOUT, COPY_CONNECTION_TIMEOUT); + + /// process response + if (status == HttpStatus.SC_MULTI_STATUS) { + result = processPartialError(copyMethod); + + } else if (status == HttpStatus.SC_PRECONDITION_FAILED && !mOverwrite) { + + result = new RemoteOperationResult(ResultCode.INVALID_OVERWRITE); + client.exhaustResponse(copyMethod.getResponseBodyAsStream()); + + + /// for other errors that could be explicitly handled, check first: + /// http://www.webdav.org/specs/rfc4918.html#rfc.section.9.9.4 + + } else { + result = new RemoteOperationResult( + isSuccess(status), // copy.succeeded()? trustful? + status, + copyMethod.getResponseHeaders() + ); + client.exhaustResponse(copyMethod.getResponseBodyAsStream()); + } + + Log.i(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + + result.getLogMessage()); + + } catch (Exception e) { + result = new RemoteOperationResult(e); + Log.e(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + + result.getLogMessage(), e); + + } finally { + if (copyMethod != null) + copyMethod.releaseConnection(); + } + + return result; + } + + + /** + * Analyzes a multistatus response from the OC server to generate an appropriate result. + *

+ * In WebDAV, a COPY request on collections (folders) can be PARTIALLY successful: some + * children are copied, some other aren't. + *

+ * According to the WebDAV specification, a multistatus response SHOULD NOT include partial + * successes (201, 204) nor for descendants of already failed children (424) in the response + * entity. But SHOULD NOT != MUST NOT, so take carefully. + * + * @param copyMethod Copy operation just finished with a multistatus response + * @return A result for the {@link com.owncloud.android.lib.resources.files.CopyRemoteFileOperation} caller + * @throws java.io.IOException If the response body could not be parsed + * @throws org.apache.jackrabbit.webdav.DavException If the status code is other than MultiStatus or if obtaining + * the response XML document fails + */ + private RemoteOperationResult processPartialError(CopyMethod copyMethod) + throws IOException, DavException { + // Adding a list of failed descendants to the result could be interesting; or maybe not. + // For the moment, let's take the easy way. + + /// check that some error really occurred + MultiStatusResponse[] responses = copyMethod.getResponseBodyAsMultiStatus().getResponses(); + Status[] status; + boolean failFound = false; + for (int i = 0; i < responses.length && !failFound; i++) { + status = responses[i].getStatus(); + failFound = ( + status != null && + status.length > 0 && + status[0].getStatusCode() > 299 + ); + } + + RemoteOperationResult result; + if (failFound) { + result = new RemoteOperationResult(ResultCode.PARTIAL_COPY_DONE); + } else { + result = new RemoteOperationResult( + true, + HttpStatus.SC_MULTI_STATUS, + copyMethod.getResponseHeaders() + ); + } + + return result; + + } + + + protected boolean isSuccess(int status) { + return status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT; + } + +} From 43e82df560507b46036f4ea89d4d320251c469c3 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Thu, 23 Oct 2014 23:04:54 +0200 Subject: [PATCH 037/101] New Travis-CI conf test --- .travis.yml | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index d663a0c8..2a46a99f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,21 +3,13 @@ android: components: - build-tools-22.0.1 - android-19 - - android-17 - - android-14 - - extra-android-support - licenses: - - 'android-sdk-license-5be876d5' - - 'android-sdk-license-598b93a6' -jdk: oraclejdk7 before_install: -- echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI -c 20M -- emulator -avd test -no-skin -no-audio -no-window & -- rm pom.xml -- android update project -p . -before_script: -- chmod +x ./wait_for_emulator.sh -- ./wait_for_emulator.sh + - echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI -c 20M + - emulator -avd test -no-skin -no-audio -no-window & + - rm pom.xml + - android update project -p . + - chmod +x ./wait_for_emulator.sh + - ./wait_for_emulator.sh script: - ant clean - ant debug From 3e28768d8f5b19e329cce20f6d46bfcfdfb49549 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Mon, 27 Oct 2014 23:43:16 +0100 Subject: [PATCH 038/101] Updated some dependencies --- test_client/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/test_client/build.gradle b/test_client/build.gradle index 05d527b8..e815f1f3 100644 --- a/test_client/build.gradle +++ b/test_client/build.gradle @@ -7,6 +7,7 @@ repositories { dependencies { compile 'commons-httpclient:commons-httpclient:3.1' compile 'com.android.support:support-v4:20.0.0' + compile project(':') } android { From 542e596bf5c74c38ccb34f54412c70a59bfc663f Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Tue, 28 Oct 2014 12:17:27 +0100 Subject: [PATCH 039/101] Removed unnecessary command --- .../lib/test_project/test/CopyFileTest.java | 459 ++++++++++++++++++ 1 file changed, 459 insertions(+) create mode 100644 test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java new file mode 100644 index 00000000..5f846691 --- /dev/null +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java @@ -0,0 +1,459 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2014 ownCloud Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.test_project.test; + +import android.content.Context; +import android.net.Uri; +import android.test.ActivityInstrumentationTestCase2; +import android.util.Log; + +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.OwnCloudClientFactory; +import com.owncloud.android.lib.common.OwnCloudCredentialsFactory; +import com.owncloud.android.lib.common.network.NetworkUtils; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.lib.resources.files.CopyRemoteFileOperation; +import com.owncloud.android.lib.test_project.R; +import com.owncloud.android.lib.test_project.SelfSignedConfidentSslSocketFactory; +import com.owncloud.android.lib.test_project.TestActivity; + +import junit.framework.AssertionFailedError; + +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; + +import java.io.File; +import java.security.GeneralSecurityException; + +//import android.test.AndroidTestCase; + +/** + * Class to test CopyRemoteFileOperation + *

+ * With this TestCase we are experimenting a bit to improve the test suite design, in two aspects: + *

+ * - Reduce the dependency from the set of test cases on the "test project" needed to + * have an instrumented APK to install in the device, as required by the testing framework + * provided by Android. To get there, this class avoids calling TestActivity methods in the test + * method. + *

+ * - Reduce the impact of creating a remote fixture over the Internet, while the structure of the + * TestCase is kept easy to maintain. To get this, all the tests are done in a single test method, + * granting this way that setUp and tearDown are run only once. + * + * @author David A. Velasco + */ + +//public class CopyFileTest extends AndroidTestCase { +public class CopyFileTest extends ActivityInstrumentationTestCase2 { + + private static final String LOG_TAG = CopyFileTest.class.getCanonicalName(); + + + /// Paths to files and folders in fixture + + private static final String SRC_BASE_FOLDER = "/src/"; + private static final String TARGET_BASE_FOLDER = "/target/"; + private static final String NO_FILE = "nofile.txt"; + private static final String FILE1 = "file1.txt"; + private static final String FILE2 = "file2.txt"; + private static final String FILE3 = "file3.txt"; + private static final String FILE4 = "file4.txt"; + private static final String FILE5 = "file5.txt"; + private static final String FILE6 = "file6.txt"; + private static final String FILE7 = "file7.txt"; + private static final String EMPTY = "empty/"; + private static final String NO_FOLDER = "nofolder/"; + private static final String FOLDER1 = "folder1/"; + private static final String FOLDER2 = "folder2/"; + private static final String FOLDER3 = "folder3/"; + private static final String FOLDER4 = "folder4/"; + + private static final String SRC_PATH_TO_FILE_1 = SRC_BASE_FOLDER + FILE1; + private static final String TARGET_PATH_TO_FILE_1 = TARGET_BASE_FOLDER + FILE1; + + private static final String SRC_PATH_TO_FILE_2 = SRC_BASE_FOLDER + FILE2; + private static final String TARGET_PATH_TO_FILE_2_RENAMED = + TARGET_BASE_FOLDER + "renamed_" + FILE2; + + private static final String SRC_PATH_TO_FILE_3 = SRC_BASE_FOLDER + FILE3; + private static final String SRC_PATH_TO_FILE_3_RENAMED = SRC_BASE_FOLDER + "renamed_" + FILE3; + + private static final String SRC_PATH_TO_FILE_4 = SRC_BASE_FOLDER + FILE4; + + private static final String SRC_PATH_TO_FILE_5 = SRC_BASE_FOLDER + FILE5; + + private static final String SRC_PATH_TO_FILE_6 = SRC_BASE_FOLDER + FILE6; + + private static final String SRC_PATH_TO_FILE_7 = SRC_BASE_FOLDER + FILE7; + + private static final String SRC_PATH_TO_NON_EXISTENT_FILE = SRC_BASE_FOLDER + NO_FILE; + + private static final String SRC_PATH_TO_EMPTY_FOLDER = SRC_BASE_FOLDER + EMPTY; + private static final String TARGET_PATH_TO_EMPTY_FOLDER = TARGET_BASE_FOLDER + EMPTY; + + private static final String SRC_PATH_TO_FULL_FOLDER_1 = SRC_BASE_FOLDER + FOLDER1; + private static final String TARGET_PATH_TO_FULL_FOLDER_1 = TARGET_BASE_FOLDER + FOLDER1; + + private static final String SRC_PATH_TO_FULL_FOLDER_2 = SRC_BASE_FOLDER + FOLDER2; + + private static final String TARGET_PATH_TO_FULL_FOLDER_2_RENAMED = + TARGET_BASE_FOLDER + "renamed_" + FOLDER2; + + private static final String SRC_PATH_TO_FULL_FOLDER_3 = SRC_BASE_FOLDER + FOLDER3; + private static final String SRC_PATH_TO_FULL_FOLDER_4 = SRC_BASE_FOLDER + FOLDER4; + + private static final String SRC_PATH_TO_FULL_FOLDER_3_RENAMED = + SRC_BASE_FOLDER + "renamed_" + FOLDER3; + + private static final String TARGET_PATH_RENAMED_WITH_INVALID_CHARS = + SRC_BASE_FOLDER + "renamed:??_" + FILE6; + + private static final String TARGET_PATH_TO_ALREADY_EXISTENT_EMPTY_FOLDER_4 = TARGET_BASE_FOLDER + + FOLDER4; + + private static final String TARGET_PATH_TO_NON_EXISTENT_FILE = TARGET_BASE_FOLDER + NO_FILE; + + private static final String TARGET_PATH_TO_FILE_5_INTO_NON_EXISTENT_FOLDER = + TARGET_BASE_FOLDER + NO_FOLDER + FILE5; + + private static final String TARGET_PATH_TO_ALREADY_EXISTENT_FILE_7 = TARGET_BASE_FOLDER + FILE7; + + private static final String[] FOLDERS_IN_FIXTURE = { + SRC_PATH_TO_EMPTY_FOLDER, + + SRC_PATH_TO_FULL_FOLDER_1, + SRC_PATH_TO_FULL_FOLDER_1 + FOLDER1, + SRC_PATH_TO_FULL_FOLDER_1 + FOLDER2, + SRC_PATH_TO_FULL_FOLDER_1 + FOLDER2 + FOLDER1, + SRC_PATH_TO_FULL_FOLDER_1 + FOLDER2 + FOLDER2, + + SRC_PATH_TO_FULL_FOLDER_2, + SRC_PATH_TO_FULL_FOLDER_2 + FOLDER1, + SRC_PATH_TO_FULL_FOLDER_2 + FOLDER2, + SRC_PATH_TO_FULL_FOLDER_2 + FOLDER2 + FOLDER1, + SRC_PATH_TO_FULL_FOLDER_2 + FOLDER2 + FOLDER2, + + SRC_PATH_TO_FULL_FOLDER_3, + SRC_PATH_TO_FULL_FOLDER_3 + FOLDER1, + SRC_PATH_TO_FULL_FOLDER_3 + FOLDER2, + SRC_PATH_TO_FULL_FOLDER_3 + FOLDER2 + FOLDER1, + SRC_PATH_TO_FULL_FOLDER_3 + FOLDER2 + FOLDER2, + + SRC_PATH_TO_FULL_FOLDER_4, + SRC_PATH_TO_FULL_FOLDER_4 + FOLDER1, + SRC_PATH_TO_FULL_FOLDER_4 + FOLDER2, + SRC_PATH_TO_FULL_FOLDER_4 + FOLDER2 + FOLDER1, + SRC_PATH_TO_FULL_FOLDER_4 + FOLDER2 + FOLDER2, + + TARGET_BASE_FOLDER, + TARGET_PATH_TO_ALREADY_EXISTENT_EMPTY_FOLDER_4 + }; + + private static final String[] FILES_IN_FIXTURE = { + SRC_PATH_TO_FILE_1, + SRC_PATH_TO_FILE_2, + SRC_PATH_TO_FILE_3, + SRC_PATH_TO_FILE_4, + SRC_PATH_TO_FILE_5, + + SRC_PATH_TO_FULL_FOLDER_1 + FILE1, + SRC_PATH_TO_FULL_FOLDER_1 + FOLDER2 + FILE1, + SRC_PATH_TO_FULL_FOLDER_1 + FOLDER2 + FILE2, + SRC_PATH_TO_FULL_FOLDER_1 + FOLDER2 + FOLDER2 + FILE2, + + SRC_PATH_TO_FULL_FOLDER_2 + FILE1, + SRC_PATH_TO_FULL_FOLDER_2 + FOLDER2 + FILE1, + SRC_PATH_TO_FULL_FOLDER_2 + FOLDER2 + FILE2, + SRC_PATH_TO_FULL_FOLDER_2 + FOLDER2 + FOLDER2 + FILE2, + + SRC_PATH_TO_FULL_FOLDER_3 + FILE1, + SRC_PATH_TO_FULL_FOLDER_3 + FOLDER2 + FILE1, + SRC_PATH_TO_FULL_FOLDER_3 + FOLDER2 + FILE2, + SRC_PATH_TO_FULL_FOLDER_3 + FOLDER2 + FOLDER2 + FILE2, + + SRC_PATH_TO_FULL_FOLDER_4 + FILE1, + SRC_PATH_TO_FULL_FOLDER_4 + FOLDER2 + FILE1, + SRC_PATH_TO_FULL_FOLDER_4 + FOLDER2 + FILE2, + SRC_PATH_TO_FULL_FOLDER_4 + FOLDER2 + FOLDER2 + FILE2, + + TARGET_PATH_TO_ALREADY_EXISTENT_FILE_7 + }; + + + String mServerUri, mUser, mPass; + OwnCloudClient mClient = null; + + public CopyFileTest() { + super(TestActivity.class); + + Protocol pr = Protocol.getProtocol("https"); + if (pr == null || !(pr.getSocketFactory() instanceof SelfSignedConfidentSslSocketFactory)) { + try { + ProtocolSocketFactory psf = new SelfSignedConfidentSslSocketFactory(); + Protocol.registerProtocol( + "https", + new Protocol("https", psf, 443)); + + } catch (GeneralSecurityException e) { + throw new AssertionFailedError( + "Self-signed confident SSL context could not be loaded"); + } + } + + } + + + protected Context getContext() { + return getActivity(); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + // Next initialization cannot be done in the constructor because getContext() is not + // ready yet, returns NULL. + initAccessToServer(getContext()); + + Log.v(LOG_TAG, "Setting up the remote fixture..."); + + RemoteOperationResult result = null; + for (String folderPath : FOLDERS_IN_FIXTURE) { + result = TestActivity.createFolder(folderPath, true, mClient); + if (!result.isSuccess()) { + Utils.logAndThrow(LOG_TAG, result); + } + } + + File txtFile = TestActivity.extractAsset( + TestActivity.ASSETS__TEXT_FILE_NAME, getContext() + ); + for (String filePath : FILES_IN_FIXTURE) { + result = TestActivity.uploadFile( + txtFile.getAbsolutePath(), filePath, "txt/plain", mClient + ); + if (!result.isSuccess()) { + Utils.logAndThrow(LOG_TAG, result); + } + } + + Log.v(LOG_TAG, "Remote fixture created."); + + } + + + /** + * Test copy folder + */ + public void testCopyRemoteFileOperation() { + Log.v(LOG_TAG, "testCopyFolder in"); + + /// successful cases + + // copy file + CopyRemoteFileOperation copyOperation = new CopyRemoteFileOperation( + SRC_PATH_TO_FILE_1, + TARGET_PATH_TO_FILE_1, + false + ); + RemoteOperationResult result = copyOperation.execute(mClient); + assertTrue(result.isSuccess()); + + // copy & rename file, different location + copyOperation = new CopyRemoteFileOperation( + SRC_PATH_TO_FILE_2, + TARGET_PATH_TO_FILE_2_RENAMED, + false + ); + result = copyOperation.execute(mClient); + assertTrue(result.isSuccess()); + + // copy & rename file, same location (rename file) + copyOperation = new CopyRemoteFileOperation( + SRC_PATH_TO_FILE_3, + SRC_PATH_TO_FILE_3_RENAMED, + false + ); + result = copyOperation.execute(mClient); + assertTrue(result.isSuccess()); + + // copy empty folder + copyOperation = new CopyRemoteFileOperation( + SRC_PATH_TO_EMPTY_FOLDER, + TARGET_PATH_TO_EMPTY_FOLDER, + false + ); + result = copyOperation.execute(mClient); + assertTrue(result.isSuccess()); + + // copy non-empty folder + copyOperation = new CopyRemoteFileOperation( + SRC_PATH_TO_FULL_FOLDER_1, + TARGET_PATH_TO_FULL_FOLDER_1, + false + ); + result = copyOperation.execute(mClient); + assertTrue(result.isSuccess()); + + // copy & rename folder, different location + copyOperation = new CopyRemoteFileOperation( + SRC_PATH_TO_FULL_FOLDER_2, + TARGET_PATH_TO_FULL_FOLDER_2_RENAMED, + false + ); + result = copyOperation.execute(mClient); + assertTrue(result.isSuccess()); + + // copy & rename folder, same location (rename folder) + copyOperation = new CopyRemoteFileOperation( + SRC_PATH_TO_FULL_FOLDER_3, + SRC_PATH_TO_FULL_FOLDER_3_RENAMED, + false + ); + result = copyOperation.execute(mClient); + assertTrue(result.isSuccess()); + + // copy for nothing (success, but no interaction with network) + copyOperation = new CopyRemoteFileOperation( + SRC_PATH_TO_FILE_4, + SRC_PATH_TO_FILE_4, + false + ); + result = copyOperation.execute(mClient); + assertTrue(result.isSuccess()); + + // copy overwriting + copyOperation = new CopyRemoteFileOperation( + SRC_PATH_TO_FULL_FOLDER_4, + TARGET_PATH_TO_ALREADY_EXISTENT_EMPTY_FOLDER_4, + true + ); + result = copyOperation.execute(mClient); + assertTrue(result.isSuccess()); + + + /// Failed cases + + // file to copy does not exist + copyOperation = new CopyRemoteFileOperation( + SRC_PATH_TO_NON_EXISTENT_FILE, + TARGET_PATH_TO_NON_EXISTENT_FILE, + false + ); + result = copyOperation.execute(mClient); + assertTrue(result.getCode() == ResultCode.FILE_NOT_FOUND); + + // folder to copy into does no exist + copyOperation = new CopyRemoteFileOperation( + SRC_PATH_TO_FILE_5, + TARGET_PATH_TO_FILE_5_INTO_NON_EXISTENT_FOLDER, + false + ); + result = copyOperation.execute(mClient); + assertTrue(result.getHttpCode() == HttpStatus.SC_CONFLICT); + + // target location (renaming) has invalid characters + copyOperation = new CopyRemoteFileOperation( + SRC_PATH_TO_FILE_6, + TARGET_PATH_RENAMED_WITH_INVALID_CHARS, + false + ); + result = copyOperation.execute(mClient); + assertTrue(result.getCode() == ResultCode.INVALID_CHARACTER_IN_NAME); + + // name collision + copyOperation = new CopyRemoteFileOperation( + SRC_PATH_TO_FILE_7, + TARGET_PATH_TO_ALREADY_EXISTENT_FILE_7, + false + ); + result = copyOperation.execute(mClient); + assertTrue(result.getCode() == ResultCode.INVALID_OVERWRITE); + + // copy a folder into a descendant + copyOperation = new CopyRemoteFileOperation( + SRC_BASE_FOLDER, + SRC_PATH_TO_EMPTY_FOLDER, + false + ); + result = copyOperation.execute(mClient); + assertTrue(result.getCode() == ResultCode.INVALID_COPY_INTO_DESCENDANT); + + } + + @Override + protected void tearDown() throws Exception { + Log.v(LOG_TAG, "Deleting remote fixture..."); + + String[] mPathsToCleanUp = { + SRC_BASE_FOLDER, + TARGET_BASE_FOLDER + }; + + for (String path : mPathsToCleanUp) { + RemoteOperationResult removeResult = + TestActivity.removeFile(path, mClient); + if (!removeResult.isSuccess() && removeResult.getCode() != ResultCode.TIMEOUT) { + Utils.logAndThrow(LOG_TAG, removeResult); + } + } + + super.tearDown(); + + Log.v(LOG_TAG, "Remote fixture delete."); + } + + + private void initAccessToServer(Context context) { + Log.v(LOG_TAG, "Setting up client instance to access OC server..."); + + mServerUri = context.getString(R.string.server_base_url); + mUser = context.getString(R.string.username); + mPass = context.getString(R.string.password); + + mClient = new OwnCloudClient( + Uri.parse(mServerUri), + NetworkUtils.getMultiThreadedConnManager() + ); + mClient.setDefaultTimeouts( + OwnCloudClientFactory.DEFAULT_DATA_TIMEOUT, + OwnCloudClientFactory.DEFAULT_CONNECTION_TIMEOUT); + mClient.setFollowRedirects(true); + mClient.setCredentials( + OwnCloudCredentialsFactory.newBasicCredentials( + mUser, + mPass + ) + ); + + Log.v(LOG_TAG, "Client instance set up."); + + } + + +} From f753b1bde825396c46360979c13d41cff478237f Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Tue, 28 Oct 2014 12:46:44 +0100 Subject: [PATCH 040/101] Added INVALID_COPY_INTO_DESCENDANT code --- .../common/operations/RemoteOperationResult.java | 13 +++---------- .../resources/files/CopyRemoteFileOperation.java | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java index e4295311..f8eb8cc1 100644 --- a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java +++ b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java @@ -47,14 +47,6 @@ import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.DavException; import org.json.JSONException; -import java.io.IOException; -import java.io.Serializable; -import java.net.MalformedURLException; -import java.net.SocketException; -import java.net.SocketTimeoutException; -import java.net.UnknownHostException; -import java.util.ArrayList; - import javax.net.ssl.SSLException; @@ -69,7 +61,7 @@ import javax.net.ssl.SSLException; public class RemoteOperationResult implements Serializable { /** Generated - should be refreshed every time the class changes!! */; - private static final long serialVersionUID = -1909603208238358633L; + private static final long serialVersionUID = 1129130415603799707L; private static final String TAG = RemoteOperationResult.class.getSimpleName(); @@ -111,7 +103,8 @@ public class RemoteOperationResult implements Serializable { FORBIDDEN, SHARE_FORBIDDEN, OK_REDIRECT_TO_NON_SECURE_CONNECTION, - INVALID_MOVE_INTO_DESCENDANT, + INVALID_MOVE_INTO_DESCENDANT, + INVALID_COPY_INTO_DESCENDANT, PARTIAL_MOVE_DONE, PARTIAL_COPY_DONE, INVALID_CHARACTER_DETECT_IN_SERVER diff --git a/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java index 56e7eeb9..f8708761 100644 --- a/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java @@ -104,7 +104,7 @@ public class CopyRemoteFileOperation extends RemoteOperation { } if (mTargetRemotePath.startsWith(mSrcRemotePath)) { - return new RemoteOperationResult(ResultCode.INVALID_MOVE_INTO_DESCENDANT); + return new RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT); } From 8e0739aed00fafc3b311b1426dd1f2aa357070e9 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Fri, 19 Sep 2014 12:07:17 +0200 Subject: [PATCH 041/101] Added gradle folder to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dd7c979e..984d59e0 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ # generated files bin/ build/ +gradle/ gen/ target/ *.iml From 775fb5b1f25517e0f152ef68b5f21571b3d002a2 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Fri, 19 Sep 2014 12:37:30 +0200 Subject: [PATCH 042/101] Updated build.gradle to allow Android Studio to properly identify test_client as a module --- test_client/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/test_client/build.gradle b/test_client/build.gradle index e815f1f3..7a89bad0 100644 --- a/test_client/build.gradle +++ b/test_client/build.gradle @@ -1,3 +1,4 @@ + apply plugin: 'com.android.application' repositories { From 25ec49acfb2ab5fbadb40b2cec13694530c38703 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Fri, 19 Sep 2014 13:29:33 +0200 Subject: [PATCH 043/101] Replaced obsolete Android plugins and updated Gradle plugin version to 0.13 --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 9119948a..2fc53f41 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,7 @@ buildscript { classpath 'com.android.tools.build:gradle:1.2.3' } } + apply plugin: 'com.android.library' repositories { From b8830e0faf9e9223026ecafa9522b968ad700de0 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Fri, 19 Sep 2014 13:38:04 +0200 Subject: [PATCH 044/101] Disabled abort-build-on-lint-error check (all modules have errors). --- test_client/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/test_client/build.gradle b/test_client/build.gradle index 7a89bad0..e815f1f3 100644 --- a/test_client/build.gradle +++ b/test_client/build.gradle @@ -1,4 +1,3 @@ - apply plugin: 'com.android.application' repositories { From 97b133b36af56b7de08f5e73cd95b813a5088f78 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Fri, 19 Sep 2014 13:49:46 +0200 Subject: [PATCH 045/101] Updated .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 984d59e0..dd7c979e 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ # generated files bin/ build/ -gradle/ gen/ target/ *.iml From b53c8ccf9dc2e2413f77c1d0709b08972baa6fc3 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Mon, 27 Oct 2014 23:43:16 +0100 Subject: [PATCH 046/101] Updated some dependencies --- sample_client/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/sample_client/build.gradle b/sample_client/build.gradle index 31503a37..5e4ae3c9 100644 --- a/sample_client/build.gradle +++ b/sample_client/build.gradle @@ -5,7 +5,6 @@ repositories { } dependencies { - compile fileTree(dir: 'libs', include: '*.jar') compile project(':') } From 8633efbb493d657ce1ab292d27ecb74e50b7d7b4 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Thu, 23 Oct 2014 22:46:49 +0200 Subject: [PATCH 047/101] Added some neccesities for the copy operation --- .../android/lib/resources/files/CopyRemoteFileOperation.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java index f8708761..934c69be 100644 --- a/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java @@ -107,7 +107,6 @@ public class CopyRemoteFileOperation extends RemoteOperation { return new RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT); } - /// perform remote operation CopyMethod copyMethod = null; RemoteOperationResult result = null; From 2970b54e7c3557a8a61fd2fcfb329676676c3234 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Tue, 4 Nov 2014 15:56:30 +0100 Subject: [PATCH 048/101] Updated CopyRemoteFileOperation and verified with the unit tests --- .../files/CopyRemoteFileOperation.java | 11 +++-- .../lib/test_project/test/CopyFileTest.java | 42 ++++++++----------- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java index 934c69be..bd7f118e 100644 --- a/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java @@ -24,6 +24,7 @@ package com.owncloud.android.lib.resources.files; +import android.content.Context; import android.util.Log; import com.owncloud.android.lib.common.OwnCloudClient; @@ -61,6 +62,7 @@ public class CopyRemoteFileOperation extends RemoteOperation { private String mTargetRemotePath; private boolean mOverwrite; + private Context mContext; /** @@ -71,10 +73,9 @@ public class CopyRemoteFileOperation extends RemoteOperation { * @param srcRemotePath Remote path of the file/folder to move. * @param targetRemotePath Remove path desired for the file/folder after moving it. */ - public CopyRemoteFileOperation( - String srcRemotePath, String targetRemotePath, boolean overwrite + public CopyRemoteFileOperation(Context context, String srcRemotePath, String targetRemotePath, boolean overwrite ) { - + mContext = context; mSrcRemotePath = srcRemotePath; mTargetRemotePath = targetRemotePath; mOverwrite = overwrite; @@ -107,6 +108,10 @@ public class CopyRemoteFileOperation extends RemoteOperation { return new RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT); } + if (!new ExistenceCheckRemoteOperation(mSrcRemotePath, mContext, Boolean.FALSE).run(getClient()).isSuccess()) { + return new RemoteOperationResult(ResultCode.FILE_NOT_FOUND); + } + /// perform remote operation CopyMethod copyMethod = null; RemoteOperationResult result = null; diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java index 5f846691..7b9bbbf2 100644 --- a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java @@ -36,18 +36,11 @@ import com.owncloud.android.lib.common.network.NetworkUtils; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.resources.files.CopyRemoteFileOperation; -import com.owncloud.android.lib.test_project.R; -import com.owncloud.android.lib.test_project.SelfSignedConfidentSslSocketFactory; import com.owncloud.android.lib.test_project.TestActivity; -import junit.framework.AssertionFailedError; - import org.apache.commons.httpclient.HttpStatus; -import org.apache.commons.httpclient.protocol.Protocol; -import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; import java.io.File; -import java.security.GeneralSecurityException; //import android.test.AndroidTestCase; @@ -210,21 +203,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 public CopyFileTest() { super(TestActivity.class); - - Protocol pr = Protocol.getProtocol("https"); - if (pr == null || !(pr.getSocketFactory() instanceof SelfSignedConfidentSslSocketFactory)) { - try { - ProtocolSocketFactory psf = new SelfSignedConfidentSslSocketFactory(); - Protocol.registerProtocol( - "https", - new Protocol("https", psf, 443)); - - } catch (GeneralSecurityException e) { - throw new AssertionFailedError( - "Self-signed confident SSL context could not be loaded"); - } - } - } @@ -277,6 +255,7 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy file CopyRemoteFileOperation copyOperation = new CopyRemoteFileOperation( + getContext(), SRC_PATH_TO_FILE_1, TARGET_PATH_TO_FILE_1, false @@ -286,6 +265,7 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy & rename file, different location copyOperation = new CopyRemoteFileOperation( + getContext(), SRC_PATH_TO_FILE_2, TARGET_PATH_TO_FILE_2_RENAMED, false @@ -295,6 +275,7 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy & rename file, same location (rename file) copyOperation = new CopyRemoteFileOperation( + getContext(), SRC_PATH_TO_FILE_3, SRC_PATH_TO_FILE_3_RENAMED, false @@ -304,6 +285,7 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy empty folder copyOperation = new CopyRemoteFileOperation( + getContext(), SRC_PATH_TO_EMPTY_FOLDER, TARGET_PATH_TO_EMPTY_FOLDER, false @@ -313,6 +295,7 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy non-empty folder copyOperation = new CopyRemoteFileOperation( + getContext(), SRC_PATH_TO_FULL_FOLDER_1, TARGET_PATH_TO_FULL_FOLDER_1, false @@ -322,6 +305,7 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy & rename folder, different location copyOperation = new CopyRemoteFileOperation( + getContext(), SRC_PATH_TO_FULL_FOLDER_2, TARGET_PATH_TO_FULL_FOLDER_2_RENAMED, false @@ -331,6 +315,7 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy & rename folder, same location (rename folder) copyOperation = new CopyRemoteFileOperation( + getContext(), SRC_PATH_TO_FULL_FOLDER_3, SRC_PATH_TO_FULL_FOLDER_3_RENAMED, false @@ -340,6 +325,7 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy for nothing (success, but no interaction with network) copyOperation = new CopyRemoteFileOperation( + getContext(), SRC_PATH_TO_FILE_4, SRC_PATH_TO_FILE_4, false @@ -349,6 +335,7 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy overwriting copyOperation = new CopyRemoteFileOperation( + getContext(), SRC_PATH_TO_FULL_FOLDER_4, TARGET_PATH_TO_ALREADY_EXISTENT_EMPTY_FOLDER_4, true @@ -361,6 +348,7 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // file to copy does not exist copyOperation = new CopyRemoteFileOperation( + getContext(), SRC_PATH_TO_NON_EXISTENT_FILE, TARGET_PATH_TO_NON_EXISTENT_FILE, false @@ -370,6 +358,7 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // folder to copy into does no exist copyOperation = new CopyRemoteFileOperation( + getContext(), SRC_PATH_TO_FILE_5, TARGET_PATH_TO_FILE_5_INTO_NON_EXISTENT_FOLDER, false @@ -379,6 +368,7 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // target location (renaming) has invalid characters copyOperation = new CopyRemoteFileOperation( + getContext(), SRC_PATH_TO_FILE_6, TARGET_PATH_RENAMED_WITH_INVALID_CHARS, false @@ -388,7 +378,8 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // name collision copyOperation = new CopyRemoteFileOperation( - SRC_PATH_TO_FILE_7, + getContext(), + SRC_PATH_TO_FILE_1, TARGET_PATH_TO_ALREADY_EXISTENT_FILE_7, false ); @@ -397,13 +388,13 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy a folder into a descendant copyOperation = new CopyRemoteFileOperation( + getContext(), SRC_BASE_FOLDER, SRC_PATH_TO_EMPTY_FOLDER, false ); result = copyOperation.execute(mClient); assertTrue(result.getCode() == ResultCode.INVALID_COPY_INTO_DESCENDANT); - } @Override @@ -437,12 +428,13 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 mPass = context.getString(R.string.password); mClient = new OwnCloudClient( - Uri.parse(mServerUri), + Uri.parse("http://" + mServerUri), NetworkUtils.getMultiThreadedConnManager() ); mClient.setDefaultTimeouts( OwnCloudClientFactory.DEFAULT_DATA_TIMEOUT, OwnCloudClientFactory.DEFAULT_CONNECTION_TIMEOUT); + mClient.setBaseUri(Uri.parse("http://" + mServerUri)); mClient.setFollowRedirects(true); mClient.setCredentials( OwnCloudCredentialsFactory.newBasicCredentials( From ed720d0a65a3625cfb21d30645c6fb3d68c822e1 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Tue, 4 Nov 2014 16:08:24 +0100 Subject: [PATCH 049/101] Cleanup --- .../lib/test_project/test/CopyFileTest.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java index 7b9bbbf2..1218eeb4 100644 --- a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java @@ -203,6 +203,21 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 public CopyFileTest() { super(TestActivity.class); + + Protocol pr = Protocol.getProtocol("https"); + if (pr == null || !(pr.getSocketFactory() instanceof SelfSignedConfidentSslSocketFactory)) { + try { + ProtocolSocketFactory psf = new SelfSignedConfidentSslSocketFactory(); + Protocol.registerProtocol( + "https", + new Protocol("https", psf, 443)); + + } catch (GeneralSecurityException e) { + throw new AssertionFailedError( + "Self-signed confident SSL context could not be loaded"); + } + } + } @@ -428,13 +443,12 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 mPass = context.getString(R.string.password); mClient = new OwnCloudClient( - Uri.parse("http://" + mServerUri), + Uri.parse(mServerUri), NetworkUtils.getMultiThreadedConnManager() ); mClient.setDefaultTimeouts( OwnCloudClientFactory.DEFAULT_DATA_TIMEOUT, OwnCloudClientFactory.DEFAULT_CONNECTION_TIMEOUT); - mClient.setBaseUri(Uri.parse("http://" + mServerUri)); mClient.setFollowRedirects(true); mClient.setCredentials( OwnCloudCredentialsFactory.newBasicCredentials( From 6f1232493087fc70dfe24e97a92cfe88c731107e Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Tue, 4 Nov 2014 16:31:12 +0100 Subject: [PATCH 050/101] Added some missing imports --- .../android/lib/test_project/test/CopyFileTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java index 1218eeb4..2b36ddbd 100644 --- a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java @@ -36,11 +36,18 @@ import com.owncloud.android.lib.common.network.NetworkUtils; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.resources.files.CopyRemoteFileOperation; +import com.owncloud.android.lib.test_project.R; +import com.owncloud.android.lib.test_project.SelfSignedConfidentSslSocketFactory; import com.owncloud.android.lib.test_project.TestActivity; +import junit.framework.AssertionFailedError; + import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; import java.io.File; +import java.security.GeneralSecurityException; //import android.test.AndroidTestCase; From b281585c93a7eec52e467f51850811f8b0a92955 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Tue, 18 Aug 2015 13:27:44 +0200 Subject: [PATCH 051/101] Updated CopyRemoteFileOperation constructor --- .../resources/files/CopyRemoteFileOperation.java | 12 ++++-------- .../resources/files/MoveRemoteFileOperation.java | 2 -- .../lib/test_project/test/CopyFileTest.java | 14 -------------- 3 files changed, 4 insertions(+), 24 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java index bd7f118e..f9f9d346 100644 --- a/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java @@ -24,7 +24,6 @@ package com.owncloud.android.lib.resources.files; -import android.content.Context; import android.util.Log; import com.owncloud.android.lib.common.OwnCloudClient; @@ -62,7 +61,6 @@ public class CopyRemoteFileOperation extends RemoteOperation { private String mTargetRemotePath; private boolean mOverwrite; - private Context mContext; /** @@ -73,9 +71,8 @@ public class CopyRemoteFileOperation extends RemoteOperation { * @param srcRemotePath Remote path of the file/folder to move. * @param targetRemotePath Remove path desired for the file/folder after moving it. */ - public CopyRemoteFileOperation(Context context, String srcRemotePath, String targetRemotePath, boolean overwrite + public CopyRemoteFileOperation(String srcRemotePath, String targetRemotePath, boolean overwrite ) { - mContext = context; mSrcRemotePath = srcRemotePath; mTargetRemotePath = targetRemotePath; mOverwrite = overwrite; @@ -108,10 +105,6 @@ public class CopyRemoteFileOperation extends RemoteOperation { return new RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT); } - if (!new ExistenceCheckRemoteOperation(mSrcRemotePath, mContext, Boolean.FALSE).run(getClient()).isSuccess()) { - return new RemoteOperationResult(ResultCode.FILE_NOT_FOUND); - } - /// perform remote operation CopyMethod copyMethod = null; RemoteOperationResult result = null; @@ -136,6 +129,9 @@ public class CopyRemoteFileOperation extends RemoteOperation { /// for other errors that could be explicitly handled, check first: /// http://www.webdav.org/specs/rfc4918.html#rfc.section.9.9.4 + } else if (status == 400) { + result = new RemoteOperationResult(copyMethod.succeeded(), + copyMethod.getResponseBodyAsString(), status); } else { result = new RemoteOperationResult( isSuccess(status), // copy.succeeded()? trustful? diff --git a/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java index ed68535d..919b7926 100644 --- a/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java @@ -39,7 +39,6 @@ import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; -import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.resources.status.OwnCloudVersion; @@ -137,7 +136,6 @@ public class MoveRemoteFileOperation extends RemoteOperation { } else if (status == 400) { result = new RemoteOperationResult(move.succeeded(), move.getResponseBodyAsString(), status); - Log_OC.d(TAG, move.getResponseBodyAsString()); } else { result = new RemoteOperationResult( isSuccess(status), // move.succeeded()? trustful? diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java index 2b36ddbd..468d2de1 100644 --- a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java @@ -277,7 +277,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy file CopyRemoteFileOperation copyOperation = new CopyRemoteFileOperation( - getContext(), SRC_PATH_TO_FILE_1, TARGET_PATH_TO_FILE_1, false @@ -287,7 +286,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy & rename file, different location copyOperation = new CopyRemoteFileOperation( - getContext(), SRC_PATH_TO_FILE_2, TARGET_PATH_TO_FILE_2_RENAMED, false @@ -297,7 +295,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy & rename file, same location (rename file) copyOperation = new CopyRemoteFileOperation( - getContext(), SRC_PATH_TO_FILE_3, SRC_PATH_TO_FILE_3_RENAMED, false @@ -307,7 +304,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy empty folder copyOperation = new CopyRemoteFileOperation( - getContext(), SRC_PATH_TO_EMPTY_FOLDER, TARGET_PATH_TO_EMPTY_FOLDER, false @@ -317,7 +313,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy non-empty folder copyOperation = new CopyRemoteFileOperation( - getContext(), SRC_PATH_TO_FULL_FOLDER_1, TARGET_PATH_TO_FULL_FOLDER_1, false @@ -327,7 +322,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy & rename folder, different location copyOperation = new CopyRemoteFileOperation( - getContext(), SRC_PATH_TO_FULL_FOLDER_2, TARGET_PATH_TO_FULL_FOLDER_2_RENAMED, false @@ -337,7 +331,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy & rename folder, same location (rename folder) copyOperation = new CopyRemoteFileOperation( - getContext(), SRC_PATH_TO_FULL_FOLDER_3, SRC_PATH_TO_FULL_FOLDER_3_RENAMED, false @@ -347,7 +340,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy for nothing (success, but no interaction with network) copyOperation = new CopyRemoteFileOperation( - getContext(), SRC_PATH_TO_FILE_4, SRC_PATH_TO_FILE_4, false @@ -357,7 +349,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy overwriting copyOperation = new CopyRemoteFileOperation( - getContext(), SRC_PATH_TO_FULL_FOLDER_4, TARGET_PATH_TO_ALREADY_EXISTENT_EMPTY_FOLDER_4, true @@ -370,7 +361,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // file to copy does not exist copyOperation = new CopyRemoteFileOperation( - getContext(), SRC_PATH_TO_NON_EXISTENT_FILE, TARGET_PATH_TO_NON_EXISTENT_FILE, false @@ -380,7 +370,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // folder to copy into does no exist copyOperation = new CopyRemoteFileOperation( - getContext(), SRC_PATH_TO_FILE_5, TARGET_PATH_TO_FILE_5_INTO_NON_EXISTENT_FOLDER, false @@ -390,7 +379,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // target location (renaming) has invalid characters copyOperation = new CopyRemoteFileOperation( - getContext(), SRC_PATH_TO_FILE_6, TARGET_PATH_RENAMED_WITH_INVALID_CHARS, false @@ -400,7 +388,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // name collision copyOperation = new CopyRemoteFileOperation( - getContext(), SRC_PATH_TO_FILE_1, TARGET_PATH_TO_ALREADY_EXISTENT_FILE_7, false @@ -410,7 +397,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy a folder into a descendant copyOperation = new CopyRemoteFileOperation( - getContext(), SRC_BASE_FOLDER, SRC_PATH_TO_EMPTY_FOLDER, false From 819b4653853ed26f3e427118437af39c9b42d651 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Tue, 18 Aug 2015 14:07:59 +0200 Subject: [PATCH 052/101] Recovered error when file to copy doesn't exist but still keeping dependency on Context out --- .../files/CopyRemoteFileOperation.java | 4 +++ .../files/ExistenceCheckRemoteOperation.java | 36 +++++++++---------- .../lib/test_project/test/CopyFileTest.java | 1 + 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java index f9f9d346..38bdcf5a 100644 --- a/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java @@ -105,6 +105,10 @@ public class CopyRemoteFileOperation extends RemoteOperation { return new RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT); } + if (!new ExistenceCheckRemoteOperation(mSrcRemotePath, Boolean.FALSE).run(getClient()).isSuccess()) { + return new RemoteOperationResult(ResultCode.FILE_NOT_FOUND); + } + /// perform remote operation CopyMethod copyMethod = null; RemoteOperationResult result = null; diff --git a/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java b/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java index 71a2e46f..e6a4b73c 100644 --- a/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java @@ -28,7 +28,6 @@ import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.HeadMethod; import android.content.Context; -import android.net.ConnectivityManager; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.RedirectionPath; @@ -50,7 +49,6 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation { private static final String TAG = ExistenceCheckRemoteOperation.class.getSimpleName(); private String mPath; - private Context mContext; private boolean mSuccessIfAbsent; /** Sequence of redirections followed. Available only after executing the operation */ @@ -59,24 +57,31 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation { /** * Full constructor. Success of the operation will depend upon the value of successIfAbsent. - * - * @param remotePath Path to append to the URL owned by the client instance. - * @param context Android application context. + * + * @param remotePath Path to append to the URL owned by the client instance. * @param successIfAbsent When 'true', the operation finishes in success if the path does * NOT exist in the remote server (HTTP 404). */ - public ExistenceCheckRemoteOperation(String remotePath, Context context, boolean successIfAbsent) { + public ExistenceCheckRemoteOperation(String remotePath, boolean successIfAbsent) { mPath = (remotePath != null) ? remotePath : ""; - mContext = context; mSuccessIfAbsent = successIfAbsent; } - - @Override + /** + * Full constructor. Success of the operation will depend upon the value of successIfAbsent. + * + * @param remotePath Path to append to the URL owned by the client instance. + * @param context Android application context. + * @param successIfAbsent When 'true', the operation finishes in success if the path does + * NOT exist in the remote server (HTTP 404). + * @deprecated + */ + public ExistenceCheckRemoteOperation(String remotePath, Context context, boolean successIfAbsent) { + this(remotePath, successIfAbsent); + } + + @Override protected RemoteOperationResult run(OwnCloudClient client) { - if (!isOnline()) { - return new RemoteOperationResult(RemoteOperationResult.ResultCode.NO_NETWORK_CONNECTION); - } RemoteOperationResult result = null; HeadMethod head = null; boolean previousFollowRedirects = client.getFollowRedirects(); @@ -112,13 +117,6 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation { return result; } - private boolean isOnline() { - ConnectivityManager cm = (ConnectivityManager) mContext - .getSystemService(Context.CONNECTIVITY_SERVICE); - return cm != null && cm.getActiveNetworkInfo() != null - && cm.getActiveNetworkInfo().isConnectedOrConnecting(); - } - /** * Gets the sequence of redirections followed during the execution of the operation. diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java index 468d2de1..e7f84003 100644 --- a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java @@ -397,6 +397,7 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy a folder into a descendant copyOperation = new CopyRemoteFileOperation( + getContext(), SRC_BASE_FOLDER, SRC_PATH_TO_EMPTY_FOLDER, false From b15fb19399270dab59251b4abb36037d2c435366 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Tue, 18 Aug 2015 14:18:37 +0200 Subject: [PATCH 053/101] Fixed broken copy test --- .../com/owncloud/android/lib/test_project/test/CopyFileTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java index e7f84003..468d2de1 100644 --- a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CopyFileTest.java @@ -397,7 +397,6 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2 // copy a folder into a descendant copyOperation = new CopyRemoteFileOperation( - getContext(), SRC_BASE_FOLDER, SRC_PATH_TO_EMPTY_FOLDER, false From 5ac5c808099e90b43c1c3343135e77bf07030e90 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Tue, 18 Aug 2015 18:06:06 +0200 Subject: [PATCH 054/101] Return FILE_NOT_FOUND error only if the file is not found in the server, not in case of any other error checking its existence --- .../android/lib/resources/files/CopyRemoteFileOperation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java index 38bdcf5a..dca36494 100644 --- a/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java @@ -105,7 +105,7 @@ public class CopyRemoteFileOperation extends RemoteOperation { return new RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT); } - if (!new ExistenceCheckRemoteOperation(mSrcRemotePath, Boolean.FALSE).run(getClient()).isSuccess()) { + if (new ExistenceCheckRemoteOperation(mSrcRemotePath, true).run(getClient()).isSuccess()) { return new RemoteOperationResult(ResultCode.FILE_NOT_FOUND); } From 27b0308e06184225d6cb7d8c0f8f8acdf51c20ff Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Tue, 1 Sep 2015 16:01:41 +0200 Subject: [PATCH 055/101] //This extra check is unnecessary after https://github.com/owncloud/core/pull/14505 --- .../android/lib/resources/files/CopyRemoteFileOperation.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java index dca36494..f9f9d346 100644 --- a/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java @@ -105,10 +105,6 @@ public class CopyRemoteFileOperation extends RemoteOperation { return new RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT); } - if (new ExistenceCheckRemoteOperation(mSrcRemotePath, true).run(getClient()).isSuccess()) { - return new RemoteOperationResult(ResultCode.FILE_NOT_FOUND); - } - /// perform remote operation CopyMethod copyMethod = null; RemoteOperationResult result = null; From ef07416c6a97d9f87c3952875b44f4d33c528253 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 1 Sep 2015 15:29:50 +0000 Subject: [PATCH 056/101] Updated target server for automatic tests --- .travis.yml | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a46a99f..8ccad6c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,26 +1,27 @@ language: android android: components: - - build-tools-22.0.1 - - android-19 + - build-tools-22.0.1 + - android-19 before_install: - - echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI -c 20M - - emulator -avd test -no-skin -no-audio -no-window & - - rm pom.xml - - android update project -p . - - chmod +x ./wait_for_emulator.sh - - ./wait_for_emulator.sh +- echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI + -c 20M +- emulator -avd test -no-skin -no-audio -no-window & +- rm pom.xml +- android update project -p . +- chmod +x ./wait_for_emulator.sh +- ./wait_for_emulator.sh script: - - ant clean - - ant debug - - cd test_client/tests - - ant acceptance-test - - cd ../.. - - ./gradlew clean build +- ant clean +- ant debug +- cd test_client/tests +- ant acceptance-test +- cd ../.. +- ./gradlew clean build env: global: - - secure: f4Kms/mzkYRG4Kp8k6hsvG3Y0ztbJnA2J79OBw3VdqJOKVTzwsxMd1Yh325YDYO7I4HeHxGXy0H4p3rAPzIWr/nrOJ4wmcDwQYDQtVjF7S1ARWsX51FrCEV6A9ec2LAqNCQ8ZC0SoGb+HsmpFCE3uKAxRQt+B5MzOZvKNcvYpMA= - - secure: aF4U20Xlu/rfrbxCmoJAiGh1doYTAZ10UEDmajuinT+ZGSJLivuqD7DDY/00sI6IXWg+J1vL+7jJm4JSYusHPg38UHZ4q92k6RmZycW2ATUzZnGT54O5FRnY67MfVwgVpIMK9UOL/6NEciBHEjlIOL0wbKQiJB++1YtBZOQLGL4= - - secure: N+ECSwNg8v2GsAFJ2y/tCiffauHDpN76zuFI2pDqf0fjmCtJZHu4BH5ArXBHjyHKmgn20a/8eZXcwJaH1HsJ80bo7vDJ2miShjGIQ90hPcdmUiB2XVJcew4f04CtvMDH5o7DRt4ykWArlbPL2rhVag0jotlSidolHBwRFnbDhDY= + - secure: HxHoqnC8mauCKi87zlo7pQcSsSw0W5MtW+iUcB8T11quwTBgUPWIOmycXv2FcmwpST0E43Ct+dhE+mttm+6P+5PSB33HQNLq00hfTVIJ4ttcb/5eWW8MnP7L+kPK8d0EtfDG6GQto7QktaybeG4+sNKKD336ZlFfM7xgPtPv+tg= + - secure: WQMw0ciloe8i2ApGhePhuTmmH8UgAV1Ri10C1qhUH9hVOJAr+/1X5A93VPYGrgJ2EH5MdiL6f2XMDCYAgb9efuvZIUKNE0J92xh8m/yRa8nAVWNBE0PBdS4+OycoHpIQfMcUghooERXjP4GUYd/ZwICvWA+sXdOYWDdKjODUgl4= + - secure: QPxKT8vC7sm1b/hYJcfkQkLgpwNRBvVKk8S8S0t43mmqPJfs94FJTQHH4kZaGSwOeuDkRQbGuKzYtXOnGOKX2hhUBqKJd1idpJnUID8id8Kqo6VutjG017+XxZQp0hPHmfmDxYkDvlaLeoZpP2NkpwZ1p4TL2MSCr2Ibl6uTWvc= matrix: - - ANDROID_TARGET=android-19 ANDROID_ABI=armeabi-v7a + - ANDROID_TARGET=android-19 ANDROID_ABI=armeabi-v7a From 30df7c33fbaac5db856482e4f72f7b119829dfae Mon Sep 17 00:00:00 2001 From: masensio Date: Fri, 11 Sep 2015 14:48:19 +0200 Subject: [PATCH 057/101] Build the share link of a file if it isn't in the response of the server --- .../shares/GetRemoteSharesForFileOperation.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java index 3c53e7f7..45e27769 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java @@ -65,12 +65,14 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation { * Constructor * * @param remoteFilePath Path to file or folder - * @param reshares If set to false (default), only shares from the current user are returned + * @param reshares If set to false (default), only shares from the current user are + * returned * If set to true, all shares from the given file are returned * @param subfiles If set to false (default), lists only the folder being shared * If set to true, all shared files within the folder are returned. */ - public GetRemoteSharesForFileOperation(String remoteFilePath, boolean reshares, boolean subfiles) { + public GetRemoteSharesForFileOperation(String remoteFilePath, boolean reshares, + boolean subfiles) { mRemoteFilePath = remoteFilePath; mReshares = reshares; mSubfiles = subfiles; @@ -113,9 +115,11 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation { result = new RemoteOperationResult(ResultCode.OK); ArrayList sharesObjects = new ArrayList(); for (OCShare share: mShares) { - // Build the link - if (share.getToken().length() > 0) { - share.setShareLink(client.getBaseUri() + ShareUtils.SHARING_LINK_TOKEN + share.getToken()); + // Build the link + if (( share.getShareLink() == null) && + (share.getToken().length() > 0)) { + share.setShareLink(client.getBaseUri() + ShareUtils.SHARING_LINK_TOKEN + + share.getToken()); } sharesObjects.add(share); } From ecc3415e3e3c13fa8f73fdd51a88c1ab7087b199 Mon Sep 17 00:00:00 2001 From: masensio Date: Mon, 14 Sep 2015 13:21:00 +0200 Subject: [PATCH 058/101] Fix bug: Sharing an already shared file generates the old link --- .../GetRemoteSharesForFileOperation.java | 15 ++++++----- .../lib/resources/shares/ShareUtils.java | 17 ++++++++++-- .../lib/resources/shares/ShareXMLParser.java | 26 ++++++++++++++----- .../lib/resources/status/OwnCloudVersion.java | 10 ++++++- 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java index 45e27769..37241844 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java @@ -37,6 +37,7 @@ import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.status.OwnCloudVersion; /** * Provide a list shares for a specific file. @@ -90,11 +91,11 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation { get = new GetMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH); // Add Parameters to Get Method - get.setQueryString(new NameValuePair[] { - new NameValuePair(PARAM_PATH, mRemoteFilePath), - new NameValuePair(PARAM_RESHARES, String.valueOf(mReshares)), - new NameValuePair(PARAM_SUBFILES, String.valueOf(mSubfiles)) - }); + get.setQueryString(new NameValuePair[]{ + new NameValuePair(PARAM_PATH, mRemoteFilePath), + new NameValuePair(PARAM_RESHARES, String.valueOf(mReshares)), + new NameValuePair(PARAM_SUBFILES, String.valueOf(mSubfiles)) + }); get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); @@ -118,7 +119,9 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation { // Build the link if (( share.getShareLink() == null) && (share.getToken().length() > 0)) { - share.setShareLink(client.getBaseUri() + ShareUtils.SHARING_LINK_TOKEN + + String linkToken = ShareUtils.getSharingToken( + client.getOwnCloudVersion()); + share.setShareLink(client.getBaseUri() + linkToken + share.getToken()); } sharesObjects.add(share); diff --git a/src/com/owncloud/android/lib/resources/shares/ShareUtils.java b/src/com/owncloud/android/lib/resources/shares/ShareUtils.java index d829acc8..8ab9b118 100644 --- a/src/com/owncloud/android/lib/resources/shares/ShareUtils.java +++ b/src/com/owncloud/android/lib/resources/shares/ShareUtils.java @@ -24,6 +24,8 @@ package com.owncloud.android.lib.resources.shares; +import com.owncloud.android.lib.resources.status.OwnCloudVersion; + /** * Contains Constants for Share Operation * @@ -36,7 +38,18 @@ public class ShareUtils { // OCS Route public static final String SHARING_API_PATH ="/ocs/v1.php/apps/files_sharing/api/v1/shares"; - // String to build the link with the token of a share: server address + "/public.php?service=files&t=" + token - public static final String SHARING_LINK_TOKEN = "/public.php?service=files&t="; + // String to build the link with the token of a share: + // server address + "/public.php?service=files&t=" + token + public static final String SHARING_LINK_TOKEN_BEFORE_VERSION_8 = "/public.php?service=files&t="; + public static final String SHARING_LINK_TOKEN_AFTER_VERSION_8= "/index.php/s/"; + + public static String getSharingToken(OwnCloudVersion version){ + if (version!= null && version.isAfter8Version()){ + return SHARING_LINK_TOKEN_AFTER_VERSION_8; + } else { + return SHARING_LINK_TOKEN_BEFORE_VERSION_8; + } + + } } diff --git a/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java b/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java index 26f4df07..b19d5772 100644 --- a/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java +++ b/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java @@ -126,7 +126,8 @@ public class ShareXMLParser { * @throws XmlPullParserException * @throws IOException */ - public ArrayList parseXMLResponse(InputStream is) throws XmlPullParserException, IOException { + public ArrayList parseXMLResponse(InputStream is) throws XmlPullParserException, + IOException { try { // XMLPullParser @@ -151,7 +152,8 @@ public class ShareXMLParser { * @throws XmlPullParserException * @throws IOException */ - private ArrayList readOCS (XmlPullParser parser) throws XmlPullParserException, IOException { + private ArrayList readOCS (XmlPullParser parser) throws XmlPullParserException, + IOException { ArrayList shares = new ArrayList(); parser.require(XmlPullParser.START_TAG, ns , NODE_OCS); while (parser.next() != XmlPullParser.END_TAG) { @@ -209,7 +211,8 @@ public class ShareXMLParser { * @throws XmlPullParserException * @throws IOException */ - private ArrayList readData(XmlPullParser parser) throws XmlPullParserException, IOException { + private ArrayList readData(XmlPullParser parser) throws XmlPullParserException, + IOException { ArrayList shares = new ArrayList(); OCShare share = null; @@ -259,7 +262,8 @@ public class ShareXMLParser { * @throws XmlPullParserException * @throws IOException */ - private void readElement(XmlPullParser parser, ArrayList shares) throws XmlPullParserException, IOException { + private void readElement(XmlPullParser parser, ArrayList shares) + throws XmlPullParserException, IOException { parser.require(XmlPullParser.START_TAG, ns, NODE_ELEMENT); OCShare share = new OCShare(); @@ -273,7 +277,8 @@ public class ShareXMLParser { String name = parser.getName(); if (name.equalsIgnoreCase(NODE_ELEMENT)) { - // patch to work around servers responding with extra surrounding all the shares on the same file before + // patch to work around servers responding with extra surrounding all + // the shares on the same file before // https://github.com/owncloud/core/issues/6992 was fixed readElement(parser, shares); @@ -327,6 +332,11 @@ public class ShareXMLParser { } else if (name.equalsIgnoreCase(NODE_SHARE_WITH_DISPLAY_NAME)) { share.setSharedWithDisplayName(readNode(parser, NODE_SHARE_WITH_DISPLAY_NAME)); + } else if (name.equalsIgnoreCase(NODE_URL)) { + share.setShareType(ShareType.PUBLIC_LINK); + String value = readNode(parser, NODE_URL); + share.setShareLink(value); + } else { skip(parser); } @@ -344,7 +354,8 @@ public class ShareXMLParser { } private void fixPathForFolder(OCShare share) { - if (share.isFolder() && share.getPath() != null && share.getPath().length() > 0 && !share.getPath().endsWith(FileUtils.PATH_SEPARATOR)) { + if (share.isFolder() && share.getPath() != null && share.getPath().length() > 0 && + !share.getPath().endsWith(FileUtils.PATH_SEPARATOR)) { share.setPath(share.getPath() + FileUtils.PATH_SEPARATOR); } } @@ -357,7 +368,8 @@ public class ShareXMLParser { * @throws XmlPullParserException * @throws IOException */ - private String readNode (XmlPullParser parser, String node) throws XmlPullParserException, IOException{ + private String readNode (XmlPullParser parser, String node) throws XmlPullParserException, + IOException{ parser.require(XmlPullParser.START_TAG, ns, node); String value = readText(parser); //Log_OC.d(TAG, "node= " + node + ", value= " + value); diff --git a/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java b/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java index 9c5a4a82..f3da9f47 100644 --- a/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java +++ b/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java @@ -42,6 +42,8 @@ public class OwnCloudVersion implements Comparable { public static final int MINIMUM_VERSION_WITH_FORBIDDEN_CHARS = 0x08010000; // 8.1 public static final int MINIMUM_SERVER_VERSION_FOR_REMOTE_THUMBNAILS = 0x07080000; // 7.8.0 + + public static final int VERSION_8 = 0x08000000; // 8.0 private static final int MAX_DOTS = 3; @@ -129,7 +131,13 @@ public class OwnCloudVersion implements Comparable { return (mVersion >= MINIMUM_VERSION_WITH_FORBIDDEN_CHARS); } - public boolean supportsRemoteThumbnails() { return (mVersion >= MINIMUM_SERVER_VERSION_FOR_REMOTE_THUMBNAILS); } + public boolean supportsRemoteThumbnails() { + return (mVersion >= MINIMUM_SERVER_VERSION_FOR_REMOTE_THUMBNAILS); + } + + public boolean isAfter8Version(){ + return (mVersion >= VERSION_8); + } } From 8bf276377c219b490a52070035ea1ffeb03a77a7 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Tue, 21 Jul 2015 16:50:48 +0200 Subject: [PATCH 059/101] Minor improvements for upload cancelation and conflicts in synchronization --- .../lib/common/operations/RemoteOperationResult.java | 9 +++++++-- src/com/owncloud/android/lib/common/utils/Log_OC.java | 3 +-- .../files/ChunkedUploadRemoteFileOperation.java | 2 +- .../lib/resources/files/DownloadRemoteFileOperation.java | 3 +++ .../lib/resources/files/UploadRemoteFileOperation.java | 6 ++---- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java index f8eb8cc1..ceb3f25f 100644 --- a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java +++ b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java @@ -390,11 +390,16 @@ public class RemoteOperationResult implements Serializable { } else if (mCode == ResultCode.ACCOUNT_NOT_THE_SAME) { 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"; + } else if (mCode == ResultCode.FILE_NOT_FOUND) { - return "Local file does not exist"; - } + return "Local file does not exist"; + + } else if (mCode == ResultCode.SYNC_CONFLICT) { + return "Synchronization conflict"; + } return "Operation finished with HTTP status code " + mHttpCode + " (" + (isSuccess() ? "success" : "fail") + ")"; diff --git a/src/com/owncloud/android/lib/common/utils/Log_OC.java b/src/com/owncloud/android/lib/common/utils/Log_OC.java index 8ed8c52c..4d4760e6 100644 --- a/src/com/owncloud/android/lib/common/utils/Log_OC.java +++ b/src/com/owncloud/android/lib/common/utils/Log_OC.java @@ -32,8 +32,7 @@ public class Log_OC { } public static void i(String TAG, String message){ - - // Write the log message to the file + Log.i(TAG, message); appendLog(TAG+" : "+ message); } diff --git a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java index 1fa9d5fd..f8c19d3e 100644 --- a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java @@ -54,7 +54,7 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation } @Override - protected int uploadFile(OwnCloudClient client) throws HttpException, IOException { + protected int uploadFile(OwnCloudClient client) throws IOException { int status = -1; FileChannel channel = null; diff --git a/src/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java index bcb209db..95adc804 100644 --- a/src/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java @@ -140,6 +140,9 @@ public class DownloadRemoteFileOperation extends RemoteOperation { if (transferred == totalToTransfer) { // Check if the file is completed savedFile = true; Header modificationTime = mGet.getResponseHeader("Last-Modified"); + if (modificationTime == null) { + modificationTime = mGet.getResponseHeader("last-modified"); + } if (modificationTime != null) { Date d = WebdavUtils.parseResponseDate((String) modificationTime.getValue()); mModificationTimestamp = (d != null) ? d.getTime() : 0; diff --git a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java index 25dc87f5..d6e90922 100644 --- a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java @@ -102,8 +102,7 @@ public class UploadRemoteFileOperation extends RemoteOperation { (mPutMethod != null ? mPutMethod.getResponseHeaders() : null)); } } catch (Exception e) { - // TODO something cleaner with cancellations - if (mCancellationRequested.get()) { + if (mCancellationRequested.get() && !(e instanceof OperationCancelledException)) { result = new RemoteOperationResult(new OperationCancelledException()); } else { result = new RemoteOperationResult(e); @@ -117,8 +116,7 @@ public class UploadRemoteFileOperation extends RemoteOperation { status == HttpStatus.SC_NO_CONTENT)); } - protected int uploadFile(OwnCloudClient client) throws HttpException, IOException, - OperationCancelledException { + protected int uploadFile(OwnCloudClient client) throws IOException { int status = -1; try { File f = new File(mLocalPath); From 522ea30da06e2c1a6a7243847cd349a5a3a0149d Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Wed, 22 Jul 2015 10:40:50 +0200 Subject: [PATCH 060/101] Simplified flow of interruption of uploads in cancellations --- .../ChunkedUploadRemoteFileOperation.java | 5 ++- .../files/UploadRemoteFileOperation.java | 33 ++++++++++--------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java index f8c19d3e..281745ad 100644 --- a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java @@ -32,7 +32,6 @@ import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.util.Random; -import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.methods.PutMethod; import com.owncloud.android.lib.common.OwnCloudClient; @@ -85,6 +84,10 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation mPutMethod.addRequestHeader(OC_TOTAL_LENGTH_HEADER, String.valueOf(file.length())); ((ChunkFromFileChannelRequestEntity) mEntity).setOffset(offset); mPutMethod.setRequestEntity(mEntity); + if (mCancellationRequested.get()) { + mPutMethod.abort(); + // next method will throw an exception + } status = client.executeMethod(mPutMethod); if (status == 400) { diff --git a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java index d6e90922..7e4ad499 100644 --- a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java @@ -67,7 +67,7 @@ public class UploadRemoteFileOperation extends RemoteOperation { protected PutMethod mPutMethod = null; protected boolean mForbiddenCharsInServer = false; - private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); + protected final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); protected Set mDataTransferListeners = new HashSet(); protected RequestEntity mEntity = null; @@ -83,27 +83,28 @@ public class UploadRemoteFileOperation extends RemoteOperation { RemoteOperationResult result = null; try { - // / perform the upload - synchronized (mCancellationRequested) { - if (mCancellationRequested.get()) { - throw new OperationCancelledException(); + mPutMethod = new PutMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath)); + + if (mCancellationRequested.get()) { + // the operation was cancelled before getting it's turn to be executed in the queue of uploads + result = new RemoteOperationResult(new OperationCancelledException()); + + } else { + // perform the upload + int status = uploadFile(client); + if (mForbiddenCharsInServer){ + result = new RemoteOperationResult( + RemoteOperationResult.ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER); } else { - mPutMethod = new PutMethod(client.getWebdavUri() + - WebdavUtils.encodePath(mRemotePath)); + result = new RemoteOperationResult(isSuccess(status), status, + (mPutMethod != null ? mPutMethod.getResponseHeaders() : null)); } } - int status = uploadFile(client); - if (mForbiddenCharsInServer){ - result = new RemoteOperationResult( - RemoteOperationResult.ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER); - } else { - result = new RemoteOperationResult(isSuccess(status), status, - (mPutMethod != null ? mPutMethod.getResponseHeaders() : null)); - } } catch (Exception e) { - if (mCancellationRequested.get() && !(e instanceof OperationCancelledException)) { + if (mPutMethod != null && mPutMethod.isAborted()) { result = new RemoteOperationResult(new OperationCancelledException()); + } else { result = new RemoteOperationResult(e); } From 092c790030ef42b34352225e9c1d8480a0e38674 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Tue, 28 Jul 2015 16:21:27 +0200 Subject: [PATCH 061/101] Add capability to reatin ETag value in download operations --- .../files/DownloadRemoteFileOperation.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java index 95adc804..3873b5ec 100644 --- a/src/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java @@ -61,6 +61,7 @@ public class DownloadRemoteFileOperation extends RemoteOperation { private Set mDataTransferListeners = new HashSet(); private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); private long mModificationTimestamp = 0; + private String mEtag = ""; private GetMethod mGet; private String mRemotePath; @@ -146,9 +147,25 @@ public class DownloadRemoteFileOperation extends RemoteOperation { if (modificationTime != null) { Date d = WebdavUtils.parseResponseDate((String) modificationTime.getValue()); mModificationTimestamp = (d != null) ? d.getTime() : 0; - } + } else { + Log_OC.e(TAG, "Could not read modification time from response downloading " + mRemotePath); + } + Header eTag = mGet.getResponseHeader("ETag"); + if (eTag == null) { + eTag = mGet.getResponseHeader("etag"); + } + if (eTag != null) { + mEtag = eTag.getValue(); + if (mEtag.charAt(0) == '"' && mEtag.charAt(mEtag.length() - 1) == '"') { + mEtag = mEtag.substring(1, mEtag.length() - 1); + } + } else { + Log_OC.e(TAG, "Could not read eTag from response downloading " + mRemotePath); + } + } else { client.exhaustResponse(mGet.getResponseBodyAsStream()); + // TODO some kind of error control! } } else { @@ -193,4 +210,7 @@ public class DownloadRemoteFileOperation extends RemoteOperation { return mModificationTimestamp; } + public String getEtag() { + return mEtag; + } } From f61b466124ad3a3ea2c905ebdb60ac3184d4dc7f Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Mon, 28 Sep 2015 10:49:45 +0200 Subject: [PATCH 062/101] Improved ETag parsing --- .../lib/common/network/WebdavEntry.java | 2 +- .../lib/common/network/WebdavUtils.java | 45 +++++++++++++++++++ .../files/DownloadRemoteFileOperation.java | 13 ++---- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/com/owncloud/android/lib/common/network/WebdavEntry.java b/src/com/owncloud/android/lib/common/network/WebdavEntry.java index 1979cbc8..64d21e7e 100644 --- a/src/com/owncloud/android/lib/common/network/WebdavEntry.java +++ b/src/com/owncloud/android/lib/common/network/WebdavEntry.java @@ -129,7 +129,7 @@ public class WebdavEntry { prop = propSet.get(DavPropertyName.GETETAG); if (prop != null) { mEtag = (String) prop.getValue(); - mEtag = mEtag.substring(1, mEtag.length()-1); + mEtag = WebdavUtils.parseEtag(mEtag); } // {DAV:}quota-used-bytes diff --git a/src/com/owncloud/android/lib/common/network/WebdavUtils.java b/src/com/owncloud/android/lib/common/network/WebdavUtils.java index bf2e986d..c5d2e829 100644 --- a/src/com/owncloud/android/lib/common/network/WebdavUtils.java +++ b/src/com/owncloud/android/lib/common/network/WebdavUtils.java @@ -32,6 +32,8 @@ import java.util.Locale; import android.net.Uri; +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpMethod; import org.apache.jackrabbit.webdav.property.DavPropertyName; import org.apache.jackrabbit.webdav.property.DavPropertyNameSet; import org.apache.jackrabbit.webdav.xml.Namespace; @@ -131,4 +133,47 @@ public class WebdavUtils { return propSet; } + + /** + * + * @param rawEtag + * @return + */ + public static String parseEtag(String rawEtag) { + if (rawEtag == null || rawEtag.length() == 0) { + return ""; + } + if (rawEtag.endsWith("-gzip")) { + rawEtag = rawEtag.substring(0, rawEtag.length() - 5); + } + if (rawEtag.length() >= 2 && rawEtag.startsWith("\"") && rawEtag.endsWith("\"")) { + rawEtag = rawEtag.substring(1, rawEtag.length() - 1); + } + return rawEtag; + } + + + /** + * + * @param method + * @return + */ + public static String getEtagFromResponse(HttpMethod method) { + Header eTag = method.getResponseHeader("OC-ETag"); + if (eTag == null) { + eTag = method.getResponseHeader("oc-etag"); + } + if (eTag == null) { + eTag = method.getResponseHeader("ETag"); + } + if (eTag == null) { + eTag = method.getResponseHeader("etag"); + } + String result = ""; + if (eTag != null) { + result = parseEtag(eTag.getValue()); + } + return result; + } + } diff --git a/src/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java index 3873b5ec..b9c404c3 100644 --- a/src/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java @@ -150,16 +150,9 @@ public class DownloadRemoteFileOperation extends RemoteOperation { } else { Log_OC.e(TAG, "Could not read modification time from response downloading " + mRemotePath); } - Header eTag = mGet.getResponseHeader("ETag"); - if (eTag == null) { - eTag = mGet.getResponseHeader("etag"); - } - if (eTag != null) { - mEtag = eTag.getValue(); - if (mEtag.charAt(0) == '"' && mEtag.charAt(mEtag.length() - 1) == '"') { - mEtag = mEtag.substring(1, mEtag.length() - 1); - } - } else { + + mEtag = WebdavUtils.getEtagFromResponse(mGet); + if (mEtag.length() == 0) { Log_OC.e(TAG, "Could not read eTag from response downloading " + mRemotePath); } From eb4f8a723490a18c5a07fbdc3bf19928c49c4a10 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Mon, 28 Sep 2015 11:13:44 +0200 Subject: [PATCH 063/101] Added constructors to grant that upload operations only succeed if the remote copy keeps a given ETag --- .../ChunkedUploadRemoteFileOperation.java | 25 +++++++++++++++---- .../files/UploadRemoteFileOperation.java | 13 ++++++++-- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java index 281745ad..2bacc883 100644 --- a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java @@ -46,10 +46,17 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation public static final long CHUNK_SIZE = 1024000; private static final String OC_CHUNKED_HEADER = "OC-Chunked"; + private static final String OC_CHUNK_SIZE_HEADER = "OC-Chunk-Size"; private static final String TAG = ChunkedUploadRemoteFileOperation.class.getSimpleName(); public ChunkedUploadRemoteFileOperation(String storagePath, String remotePath, String mimeType){ - super(storagePath, remotePath, mimeType); + super(storagePath, remotePath, mimeType); + } + + public ChunkedUploadRemoteFileOperation( + String storagePath, String remotePath, String mimeType, String requiredEtag + ){ + super(storagePath, remotePath, mimeType, requiredEtag); } @Override @@ -63,8 +70,6 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation raf = new RandomAccessFile(file, "r"); channel = raf.getChannel(); mEntity = new ChunkFromFileChannelRequestEntity(channel, mMimeType, CHUNK_SIZE, file); - //((ProgressiveDataTransferer)mEntity). - // addDatatransferProgressListeners(getDataTransferListeners()); synchronized (mDataTransferListeners) { ((ProgressiveDataTransferer)mEntity) .addDatatransferProgressListeners(mDataTransferListeners); @@ -73,15 +78,25 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation long offset = 0; String uriPrefix = client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath) + "-chunking-" + Math.abs((new Random()).nextInt(9000)+1000) + "-" ; - long chunkCount = (long) Math.ceil((double)file.length() / CHUNK_SIZE); + long totalLength = file.length(); + long chunkCount = (long) Math.ceil((double)totalLength / CHUNK_SIZE); + String chunkSizeStr = String.valueOf(CHUNK_SIZE); + String totalLengthStr = String.valueOf(file.length()); for (int chunkIndex = 0; chunkIndex < chunkCount ; chunkIndex++, offset += CHUNK_SIZE) { + if (chunkIndex == chunkCount - 1) { + chunkSizeStr = String.valueOf(CHUNK_SIZE * chunkCount - totalLength); + } if (mPutMethod != null) { mPutMethod.releaseConnection(); // let the connection available // for other methods } mPutMethod = new PutMethod(uriPrefix + chunkCount + "-" + chunkIndex); + if (mRequiredEtag != null && mRequiredEtag.length() > 0) { + mPutMethod.addRequestHeader(IF_MATCH_HEADER, "\"" + mRequiredEtag + "\""); + } mPutMethod.addRequestHeader(OC_CHUNKED_HEADER, OC_CHUNKED_HEADER); - mPutMethod.addRequestHeader(OC_TOTAL_LENGTH_HEADER, String.valueOf(file.length())); + mPutMethod.addRequestHeader(OC_CHUNK_SIZE_HEADER, chunkSizeStr); + mPutMethod.addRequestHeader(OC_TOTAL_LENGTH_HEADER, totalLengthStr); ((ChunkFromFileChannelRequestEntity) mEntity).setOffset(offset); mPutMethod.setRequestEntity(mEntity); if (mCancellationRequested.get()) { diff --git a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java index 7e4ad499..422b17cf 100644 --- a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java @@ -32,7 +32,6 @@ import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.methods.PutMethod; import org.apache.commons.httpclient.methods.RequestEntity; import org.apache.http.HttpStatus; @@ -60,12 +59,14 @@ public class UploadRemoteFileOperation extends RemoteOperation { private static final String TAG = UploadRemoteFileOperation.class.getSimpleName(); protected static final String OC_TOTAL_LENGTH_HEADER = "OC-Total-Length"; + protected static final String IF_MATCH_HEADER = "If-Match"; protected String mLocalPath; protected String mRemotePath; protected String mMimeType; protected PutMethod mPutMethod = null; protected boolean mForbiddenCharsInServer = false; + protected String mRequiredEtag = null; protected final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); protected Set mDataTransferListeners = new HashSet(); @@ -75,7 +76,12 @@ public class UploadRemoteFileOperation extends RemoteOperation { public UploadRemoteFileOperation(String localPath, String remotePath, String mimeType) { mLocalPath = localPath; mRemotePath = remotePath; - mMimeType = mimeType; + mMimeType = mimeType; + } + + public UploadRemoteFileOperation(String localPath, String remotePath, String mimeType, String requiredEtag) { + this(localPath, remotePath, mimeType); + mRequiredEtag = requiredEtag; } @Override @@ -126,6 +132,9 @@ public class UploadRemoteFileOperation extends RemoteOperation { ((ProgressiveDataTransferer)mEntity) .addDatatransferProgressListeners(mDataTransferListeners); } + if (mRequiredEtag != null && mRequiredEtag.length() > 0) { + mPutMethod.addRequestHeader(IF_MATCH_HEADER, "\"" + mRequiredEtag + "\""); + } mPutMethod.addRequestHeader(OC_TOTAL_LENGTH_HEADER, String.valueOf(f.length())); mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); From c3f24e817e5f94b08b7e416ef99ef03ed3b61d3a Mon Sep 17 00:00:00 2001 From: masensio Date: Mon, 5 Oct 2015 11:23:39 +0200 Subject: [PATCH 064/101] Add method to know if server supports search users function --- .../android/lib/resources/status/OwnCloudVersion.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java b/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java index f3da9f47..8c30c7ab 100644 --- a/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java +++ b/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java @@ -43,6 +43,8 @@ public class OwnCloudVersion implements Comparable { public static final int MINIMUM_SERVER_VERSION_FOR_REMOTE_THUMBNAILS = 0x07080000; // 7.8.0 + public static final int MINIMUM_VERSION_FOR_SEARCHING_USERS = 0x08020000; //8.2 + public static final int VERSION_8 = 0x08000000; // 8.0 private static final int MAX_DOTS = 3; @@ -138,6 +140,10 @@ public class OwnCloudVersion implements Comparable { public boolean isAfter8Version(){ return (mVersion >= VERSION_8); } + + public boolean isSearchUsersSupported() { + return (mVersion >= MINIMUM_VERSION_FOR_SEARCHING_USERS); + } } From 0c6dfef90830476573ff84e8a58517288fc393dc Mon Sep 17 00:00:00 2001 From: masensio Date: Thu, 8 Oct 2015 18:32:50 +0200 Subject: [PATCH 065/101] Add operation to get users from the server --- .../users/GetRemoteUsersOperation.java | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 src/com/owncloud/android/lib/resources/users/GetRemoteUsersOperation.java diff --git a/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOperation.java b/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOperation.java new file mode 100644 index 00000000..d590089f --- /dev/null +++ b/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOperation.java @@ -0,0 +1,166 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2015 ownCloud Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.resources.users; + +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.operations.RemoteOperation; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.utils.Log_OC; + +import org.apache.commons.httpclient.NameValuePair; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.http.HttpStatus; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.util.ArrayList; + +/** + * Created by masensio on 08/10/2015. + * + * Retrieves a list of users from the ownCloud server. Authentication is done by sending a Basic HTTP Authorization header. + * Syntax: ocs/v1.php/cloud/users + * HTTP method: GET + * url arguments: search - string, optional search string + * url arguments: limit - int, optional limit value + * url arguments: offset - int, optional offset value + * + * Status codes: + * 100 - successful + */ +public class GetRemoteUsersOperation extends RemoteOperation{ + + private static final String TAG = GetRemoteUserNameOperation.class.getSimpleName(); + + // OCS Route + private static final String OCS_ROUTE ="/ocs/v1.php/cloud/users?format=json"; + + // Arguments + private static final String PARAM_SEARCH = "search"; + private static final String PARAM_LIMIT = "limit"; + private static final String PARAM_OFFSET = "offset"; + + // JSON Node names + private static final String NODE_OCS = "ocs"; + private static final String NODE_META = "meta"; + private static final String NODE_STATUS = "status"; + private static final String NODE_STATUSCODE = "statuscode"; + private static final String NODE_MESSAGE = "message"; + private static final String NODE_DATA = "data"; + private static final String NODE_USERS = "users"; + + private ArrayList mUsers; // List of users + + private String mSearchString; + private int mLimit; + private int mOffset; + + /** + * Constructor + * + * @param searchString string for searching users, optional + * @param limit limit, optional + * @param offset offset, optional + */ + public GetRemoteUsersOperation(String searchString, int limit, int offset) { + mSearchString = searchString; + mLimit = limit; + mOffset = offset; + } + + @Override + protected RemoteOperationResult run(OwnCloudClient client) { + RemoteOperationResult result = null; + int status = -1; + GetMethod get = null; + + try{ + // Get Method + get = new GetMethod(client.getBaseUri() + OCS_ROUTE); + + // Add Parameters to Get Method + get.setQueryString(new NameValuePair[]{ + new NameValuePair(PARAM_SEARCH, mSearchString), + new NameValuePair(PARAM_LIMIT, String.valueOf(mLimit)), + new NameValuePair(PARAM_OFFSET, String.valueOf(mOffset)) + }); + + //Âż? + get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); + + status = client.executeMethod(get); + + if(isSuccess(status)) { + String response = get.getResponseBodyAsString(); + Log_OC.d(TAG, "Successful response: " + response); + + // Parse the response + JSONObject respJSON = new JSONObject(response); + JSONObject respOCS = respJSON.getJSONObject(NODE_OCS); + JSONObject respData = respOCS.getJSONObject(NODE_DATA); + JSONArray respUsers = respData.getJSONArray(NODE_USERS); + mUsers = new ArrayList(); + ArrayList data = new ArrayList(); // For result data + for(int i=0; i<= respUsers.length(); i++){ + JSONObject jsonUser = respUsers.getJSONObject(i); + String user = jsonUser.toString(); + mUsers.add(user); + data.add(user); + Log_OC.d(TAG, "*** USER : " + user); + } + + // Result + result = new RemoteOperationResult(true, status, get.getResponseHeaders()); + result.setData(data); + + Log_OC.d(TAG, "*** Get Users completed " ); + + } else { + result = new RemoteOperationResult(false, status, get.getResponseHeaders()); + String response = get.getResponseBodyAsString(); + Log_OC.e(TAG, "Failed response while getting users from the server "); + if (response != null) { + Log_OC.e(TAG, "*** status code: " + status + "; response message: " + response); + } else { + Log_OC.e(TAG, "*** status code: " + status); + } + } + + } catch (Exception e) { + result = new RemoteOperationResult(e); + Log_OC.e(TAG, "Exception while getting users", e); + + } finally { + if (get != null) { + get.releaseConnection(); + } + } + return result; + } + + private boolean isSuccess(int status) { + return (status == HttpStatus.SC_OK); + } +} From fa17c6947e03e09b0c675b260d6b7fb21d0e0c1a Mon Sep 17 00:00:00 2001 From: masensio Date: Fri, 9 Oct 2015 10:02:03 +0200 Subject: [PATCH 066/101] Remove unused constants --- .../android/lib/resources/users/GetRemoteUsersOperation.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOperation.java b/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOperation.java index d590089f..c7f708ea 100644 --- a/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOperation.java +++ b/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOperation.java @@ -64,10 +64,6 @@ public class GetRemoteUsersOperation extends RemoteOperation{ // JSON Node names private static final String NODE_OCS = "ocs"; - private static final String NODE_META = "meta"; - private static final String NODE_STATUS = "status"; - private static final String NODE_STATUSCODE = "statuscode"; - private static final String NODE_MESSAGE = "message"; private static final String NODE_DATA = "data"; private static final String NODE_USERS = "users"; From cea7054a3d94b484691c6b06fe1a1536b8a17911 Mon Sep 17 00:00:00 2001 From: masensio Date: Fri, 9 Oct 2015 12:29:23 +0200 Subject: [PATCH 067/101] Add Get Groups Operation to the library --- ...a => GetRemoteUsersOrGroupsOperation.java} | 55 ++++++++++++------- 1 file changed, 35 insertions(+), 20 deletions(-) rename src/com/owncloud/android/lib/resources/users/{GetRemoteUsersOperation.java => GetRemoteUsersOrGroupsOperation.java} (71%) diff --git a/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOperation.java b/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOrGroupsOperation.java similarity index 71% rename from src/com/owncloud/android/lib/resources/users/GetRemoteUsersOperation.java rename to src/com/owncloud/android/lib/resources/users/GetRemoteUsersOrGroupsOperation.java index c7f708ea..404e88a2 100644 --- a/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOperation.java +++ b/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOrGroupsOperation.java @@ -40,8 +40,10 @@ import java.util.ArrayList; /** * Created by masensio on 08/10/2015. * - * Retrieves a list of users from the ownCloud server. Authentication is done by sending a Basic HTTP Authorization header. - * Syntax: ocs/v1.php/cloud/users + * Retrieves a list of users or groups from the ownCloud server. + * Authentication is done by sending a Basic HTTP Authorization header. + * Syntax: ocs/v1.php/cloud/users (Users) + * ocs/v1.php/cloud/groups (Groups) * HTTP method: GET * url arguments: search - string, optional search string * url arguments: limit - int, optional limit value @@ -50,12 +52,13 @@ import java.util.ArrayList; * Status codes: * 100 - successful */ -public class GetRemoteUsersOperation extends RemoteOperation{ +public class GetRemoteUsersOrGroupsOperation extends RemoteOperation{ - private static final String TAG = GetRemoteUserNameOperation.class.getSimpleName(); + private static final String TAG = GetRemoteUsersOrGroupsOperation.class.getSimpleName(); - // OCS Route - private static final String OCS_ROUTE ="/ocs/v1.php/cloud/users?format=json"; + // OCS Routes + private static final String OCS_ROUTE_USERS ="/ocs/v1.php/cloud/users?format=json"; + private static final String OCS_ROUTE_GROUPS ="/ocs/v1.php/cloud/groups?format=json"; // Arguments private static final String PARAM_SEARCH = "search"; @@ -66,12 +69,14 @@ public class GetRemoteUsersOperation extends RemoteOperation{ private static final String NODE_OCS = "ocs"; private static final String NODE_DATA = "data"; private static final String NODE_USERS = "users"; + private static final String NODE_GROUPS = "groups"; - private ArrayList mUsers; // List of users + private ArrayList mNames; // List of users or groups private String mSearchString; private int mLimit; private int mOffset; + private boolean mGetGroup = false; /** * Constructor @@ -79,11 +84,14 @@ public class GetRemoteUsersOperation extends RemoteOperation{ * @param searchString string for searching users, optional * @param limit limit, optional * @param offset offset, optional + * @param getGroups true: for searching groups, false: for searching users */ - public GetRemoteUsersOperation(String searchString, int limit, int offset) { + public GetRemoteUsersOrGroupsOperation(String searchString, int limit, int offset, + boolean getGroups) { mSearchString = searchString; mLimit = limit; mOffset = offset; + mGetGroup = getGroups; } @Override @@ -92,9 +100,16 @@ public class GetRemoteUsersOperation extends RemoteOperation{ int status = -1; GetMethod get = null; + String ocs_route = OCS_ROUTE_USERS; + String nodeUsersOrGroups = NODE_USERS; + if(mGetGroup){ + ocs_route = OCS_ROUTE_GROUPS; + nodeUsersOrGroups = NODE_GROUPS; + } + try{ // Get Method - get = new GetMethod(client.getBaseUri() + OCS_ROUTE); + get = new GetMethod(client.getBaseUri() + ocs_route); // Add Parameters to Get Method get.setQueryString(new NameValuePair[]{ @@ -116,27 +131,27 @@ public class GetRemoteUsersOperation extends RemoteOperation{ JSONObject respJSON = new JSONObject(response); JSONObject respOCS = respJSON.getJSONObject(NODE_OCS); JSONObject respData = respOCS.getJSONObject(NODE_DATA); - JSONArray respUsers = respData.getJSONArray(NODE_USERS); - mUsers = new ArrayList(); + JSONArray respUsersOrGroups = respData.getJSONArray(nodeUsersOrGroups); + mNames = new ArrayList(); ArrayList data = new ArrayList(); // For result data - for(int i=0; i<= respUsers.length(); i++){ - JSONObject jsonUser = respUsers.getJSONObject(i); - String user = jsonUser.toString(); - mUsers.add(user); - data.add(user); - Log_OC.d(TAG, "*** USER : " + user); + for(int i=0; i<= respUsersOrGroups.length(); i++){ + JSONObject jsonUser = respUsersOrGroups.getJSONObject(i); + String name = jsonUser.toString(); + mNames.add(name); + data.add(name); + Log_OC.d(TAG, "*** "+ nodeUsersOrGroups + " : " + name); } // Result result = new RemoteOperationResult(true, status, get.getResponseHeaders()); result.setData(data); - Log_OC.d(TAG, "*** Get Users completed " ); + Log_OC.d(TAG, "*** Get Users or groups completed " ); } else { result = new RemoteOperationResult(false, status, get.getResponseHeaders()); String response = get.getResponseBodyAsString(); - Log_OC.e(TAG, "Failed response while getting users from the server "); + Log_OC.e(TAG, "Failed response while getting users/groups from the server "); if (response != null) { Log_OC.e(TAG, "*** status code: " + status + "; response message: " + response); } else { @@ -146,7 +161,7 @@ public class GetRemoteUsersOperation extends RemoteOperation{ } catch (Exception e) { result = new RemoteOperationResult(e); - Log_OC.e(TAG, "Exception while getting users", e); + Log_OC.e(TAG, "Exception while getting users/groups", e); } finally { if (get != null) { From d9eb3655fd27462fe879979289e26bf2e0e0f4ad Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Thu, 15 Oct 2015 09:24:06 +0200 Subject: [PATCH 068/101] Removed constrain to parse only public shares --- .../resources/shares/GetRemoteSharesForFileOperation.java | 6 ++++-- .../android/lib/resources/shares/ShareXMLParser.java | 4 +--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java index 37241844..1518b516 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java @@ -117,8 +117,10 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation { ArrayList sharesObjects = new ArrayList(); for (OCShare share: mShares) { // Build the link - if (( share.getShareLink() == null) && - (share.getToken().length() > 0)) { + if ( share.getShareType() == ShareType.PUBLIC_LINK && + share.getShareLink() == null && + share.getToken().length() > 0 + ) { String linkToken = ShareUtils.getSharingToken( client.getOwnCloudVersion()); share.setShareLink(client.getBaseUri() + linkToken + diff --git a/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java b/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java index b19d5772..cb984fd4 100644 --- a/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java +++ b/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java @@ -348,9 +348,7 @@ public class ShareXMLParser { } private boolean isValidShare(OCShare share) { - return ((share.getIdRemoteShared() > -1) && - (share.getShareType() == ShareType.PUBLIC_LINK) // at this moment we only care about public shares - ); + return (share.getIdRemoteShared() > -1); } private void fixPathForFolder(OCShare share) { From 0793d3fca79e45683c457a20c99d056bef8951ed Mon Sep 17 00:00:00 2001 From: masensio Date: Fri, 16 Oct 2015 11:00:41 +0200 Subject: [PATCH 069/101] Fix NODE_SHARE_WITH_DISPLAY_NAME tag in ShareXMLParser --- .../owncloud/android/lib/resources/shares/ShareXMLParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java b/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java index cb984fd4..8189eac0 100644 --- a/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java +++ b/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java @@ -75,7 +75,7 @@ public class ShareXMLParser { private static final String NODE_TOKEN = "token"; private static final String NODE_STORAGE = "storage"; private static final String NODE_MAIL_SEND = "mail_send"; - private static final String NODE_SHARE_WITH_DISPLAY_NAME = "share_with_display_name"; + private static final String NODE_SHARE_WITH_DISPLAY_NAME = "share_with_displayname"; private static final String NODE_URL = "url"; From 3b3b992a79f529c4aadf23800452038b28207578 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Mon, 19 Oct 2015 15:06:52 +0200 Subject: [PATCH 070/101] Get users or groups available to share with via SHAREE API --- .../users/GetRemoteUserNameOperation.java | 2 +- .../GetRemoteUsersOrGroupsOperation.java | 110 +++++++++++------- 2 files changed, 66 insertions(+), 46 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/users/GetRemoteUserNameOperation.java b/src/com/owncloud/android/lib/resources/users/GetRemoteUserNameOperation.java index cecd639f..d6b85a7a 100644 --- a/src/com/owncloud/android/lib/resources/users/GetRemoteUserNameOperation.java +++ b/src/com/owncloud/android/lib/resources/users/GetRemoteUserNameOperation.java @@ -50,7 +50,7 @@ public class GetRemoteUserNameOperation extends RemoteOperation { private static final String TAG = GetRemoteUserNameOperation.class.getSimpleName(); // OCS Route - private static final String OCS_ROUTE ="/index.php/ocs/cloud/user?format=json"; + private static final String OCS_ROUTE ="/index.php/ocs/cloud/user?format=json"; // JSON Node names private static final String NODE_OCS = "ocs"; diff --git a/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOrGroupsOperation.java b/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOrGroupsOperation.java index 404e88a2..122b488a 100644 --- a/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOrGroupsOperation.java +++ b/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOrGroupsOperation.java @@ -1,4 +1,7 @@ /* ownCloud Android Library is available under MIT license + * + * @author masensio + * @author David A. Velasco * Copyright (C) 2015 ownCloud Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -24,12 +27,14 @@ package com.owncloud.android.lib.resources.users; +import android.net.Uri; +import android.util.Pair; + import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; -import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.http.HttpStatus; import org.json.JSONArray; @@ -57,69 +62,69 @@ public class GetRemoteUsersOrGroupsOperation extends RemoteOperation{ private static final String TAG = GetRemoteUsersOrGroupsOperation.class.getSimpleName(); // OCS Routes - private static final String OCS_ROUTE_USERS ="/ocs/v1.php/cloud/users?format=json"; - private static final String OCS_ROUTE_GROUPS ="/ocs/v1.php/cloud/groups?format=json"; + private static final String OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/sharees"; // from OC 8.2 - // Arguments + // Arguments - names + private static final String PARAM_FORMAT = "format"; + private static final String PARAM_ITEM_TYPE = "itemType"; private static final String PARAM_SEARCH = "search"; - private static final String PARAM_LIMIT = "limit"; - private static final String PARAM_OFFSET = "offset"; + private static final String PARAM_PAGE = "page"; // default = 1 + private static final String PARAM_PER_PAGE = "perPage"; // default = 200 + + // Arguments - constant values + private static final String VALUE_FORMAT = "json"; + private static final String VALUE_ITEM_TYPE = "search"; // to get the server search for users / groups + // JSON Node names private static final String NODE_OCS = "ocs"; private static final String NODE_DATA = "data"; + private static final String NODE_EXACT = "exact"; private static final String NODE_USERS = "users"; private static final String NODE_GROUPS = "groups"; + private static final String NODE_VALUE = "value"; + private static final String PROPERTY_LABEL = "label"; + private static final String PROPERTY_SHARE_TYPE = "shareType"; - private ArrayList mNames; // List of users or groups + // Result types + public static final Byte USER_TYPE = 0; + public static final Byte GROUP_TYPE = 1; private String mSearchString; - private int mLimit; - private int mOffset; - private boolean mGetGroup = false; + private int mPage; + private int mPerPage; /** * Constructor * * @param searchString string for searching users, optional - * @param limit limit, optional - * @param offset offset, optional - * @param getGroups true: for searching groups, false: for searching users + * @param page page index in the list of results; beginning in 1 + * @param perPage maximum number of results in a single page */ - public GetRemoteUsersOrGroupsOperation(String searchString, int limit, int offset, - boolean getGroups) { + public GetRemoteUsersOrGroupsOperation(String searchString, int page, int perPage) { mSearchString = searchString; - mLimit = limit; - mOffset = offset; - mGetGroup = getGroups; + mPage = page; + mPerPage = perPage; } @Override protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; - int status = -1; + int status; GetMethod get = null; - String ocs_route = OCS_ROUTE_USERS; - String nodeUsersOrGroups = NODE_USERS; - if(mGetGroup){ - ocs_route = OCS_ROUTE_GROUPS; - nodeUsersOrGroups = NODE_GROUPS; - } - try{ + Uri requestUri = client.getBaseUri(); + Uri.Builder uriBuilder = requestUri.buildUpon(); + uriBuilder.appendEncodedPath(OCS_ROUTE); + uriBuilder.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT); + uriBuilder.appendQueryParameter(PARAM_ITEM_TYPE, VALUE_ITEM_TYPE); + uriBuilder.appendQueryParameter(PARAM_SEARCH, Uri.encode(mSearchString)); + uriBuilder.appendQueryParameter(PARAM_PAGE, String.valueOf(mPage)); + uriBuilder.appendQueryParameter(PARAM_PER_PAGE, String.valueOf(mPerPage)); + // Get Method - get = new GetMethod(client.getBaseUri() + ocs_route); - - // Add Parameters to Get Method - get.setQueryString(new NameValuePair[]{ - new NameValuePair(PARAM_SEARCH, mSearchString), - new NameValuePair(PARAM_LIMIT, String.valueOf(mLimit)), - new NameValuePair(PARAM_OFFSET, String.valueOf(mOffset)) - }); - - //Âż? - get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); + get = new GetMethod(uriBuilder.build().toString()); status = client.executeMethod(get); @@ -131,15 +136,30 @@ public class GetRemoteUsersOrGroupsOperation extends RemoteOperation{ JSONObject respJSON = new JSONObject(response); JSONObject respOCS = respJSON.getJSONObject(NODE_OCS); JSONObject respData = respOCS.getJSONObject(NODE_DATA); - JSONArray respUsersOrGroups = respData.getJSONArray(nodeUsersOrGroups); - mNames = new ArrayList(); + JSONObject respExact = respData.getJSONObject(NODE_EXACT); + JSONArray respExactUsers = respExact.getJSONArray(NODE_USERS); + JSONArray respExactGroups = respExact.getJSONArray(NODE_GROUPS); + JSONArray respPartialUsers = respData.getJSONArray(NODE_USERS); + JSONArray respPartialGroups = respData.getJSONArray(NODE_GROUPS); + JSONArray[] jsonResults = { + respExactUsers, + respExactGroups, + respPartialUsers, + respPartialGroups + }; + ArrayList data = new ArrayList(); // For result data - for(int i=0; i<= respUsersOrGroups.length(); i++){ - JSONObject jsonUser = respUsersOrGroups.getJSONObject(i); - String name = jsonUser.toString(); - mNames.add(name); - data.add(name); - Log_OC.d(TAG, "*** "+ nodeUsersOrGroups + " : " + name); + Pair match; + for (int i=0; i<4; i++) { + for(int j=0; j< jsonResults[i].length(); j++){ + JSONObject jsonResult = jsonResults[i].getJSONObject(j); + match = new Pair( + jsonResult.getString(PROPERTY_LABEL), + (byte)jsonResult.getJSONObject(NODE_VALUE).getInt(PROPERTY_SHARE_TYPE) + ); + data.add(match); + Log_OC.d(TAG, "*** Added item: " + match.first); + } } // Result From 68e0633b74debd1d3c80875a7f68cb0b6c83534c Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Wed, 21 Oct 2015 14:44:04 +0200 Subject: [PATCH 071/101] Add option to retrieve share details in CreateRemoteShareOperation; by default the server only returns the share id --- .../shares/CreateRemoteShareOperation.java | 34 +++++- .../shares/GetRemoteShareOperation.java | 110 ++++++++++++++++++ .../shares/GetRemoteSharesOperation.java | 2 +- 3 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java diff --git a/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java index f3d38779..6aaa7d1f 100644 --- a/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java @@ -62,6 +62,7 @@ public class CreateRemoteShareOperation extends RemoteOperation { private boolean mPublicUpload; private String mPassword; private int mPermissions; + private boolean mGetShareDetails; /** * Constructor @@ -81,8 +82,14 @@ public class CreateRemoteShareOperation extends RemoteOperation { * To obtain combinations, add the desired values together. * For instance, for Re-Share, delete, read, update, add 16+8+2+1 = 27. */ - public CreateRemoteShareOperation(String remoteFilePath, ShareType shareType, String shareWith, boolean publicUpload, - String password, int permissions) { + public CreateRemoteShareOperation( + String remoteFilePath, + ShareType shareType, + String shareWith, + boolean publicUpload, + String password, + int permissions + ) { mRemoteFilePath = remoteFilePath; mShareType = shareType; @@ -90,6 +97,15 @@ public class CreateRemoteShareOperation extends RemoteOperation { mPublicUpload = publicUpload; mPassword = password; mPermissions = permissions; + mGetShareDetails = false; // defaults to false for backwards compatibility + } + + public boolean isGettingShareDetails () { + return mGetShareDetails; + } + + public void setGetShareDetails(boolean set) { + mGetShareDetails = set; } @Override @@ -141,11 +157,25 @@ public class CreateRemoteShareOperation extends RemoteOperation { sharesObjects.add(share); } result.setData(sharesObjects); + + if (mGetShareDetails) { + // retrieve more info + OCShare emptyShare = (OCShare) sharesObjects.get(0); + + GetRemoteShareOperation getInfo = new GetRemoteShareOperation(emptyShare.getIdRemoteShared()); + result = getInfo.execute(client); + } + + } else { + result = new RemoteOperationResult(ResultCode.UNKNOWN_ERROR); + Log_OC.e(TAG, "Successful response with no share in it"); } + } else if (xmlParser.isFileNotFound()){ result = new RemoteOperationResult(ResultCode.SHARE_NOT_FOUND); } else if (xmlParser.isFailure()) { + // TODO need deeper processing result = new RemoteOperationResult(ResultCode.SHARE_FORBIDDEN); } else { diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java new file mode 100644 index 00000000..6dcb28a2 --- /dev/null +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java @@ -0,0 +1,110 @@ +/* ownCloud Android Library is available under MIT license + * @author David A. Velasco + * Copyright (C) 2015 ownCloud Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.resources.shares; + +import android.net.Uri; + +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.operations.RemoteOperation; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.lib.common.utils.Log_OC; + +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.http.HttpStatus; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + + +/** + * Get the data about a Share resource, known its remote ID. + */ + +public class GetRemoteShareOperation extends RemoteOperation { + + private static final String TAG = GetRemoteShareOperation.class.getSimpleName(); + + private long mRemoteId; + + + public GetRemoteShareOperation(long remoteId) { + mRemoteId = remoteId; + } + + + @Override + protected RemoteOperationResult run(OwnCloudClient client) { + RemoteOperationResult result = null; + int status = -1; + + // Get Method + GetMethod get = null; + + // Get the response + try{ + get = new GetMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH + "/" + Long.toString(mRemoteId)); + //get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); + status = client.executeMethod(get); + if(isSuccess(status)) { + String response = get.getResponseBodyAsString(); + + // Parse xml response --> obtain the response in ShareFiles ArrayList + // convert String into InputStream + InputStream is = new ByteArrayInputStream(response.getBytes()); + ShareXMLParser xmlParser = new ShareXMLParser(); + List shares = xmlParser.parseXMLResponse(is); + if (shares != null && shares.size() > 0) { + Log_OC.d(TAG, "Got " + shares.size() + " shares"); + result = new RemoteOperationResult(ResultCode.OK); + ArrayList sharesObjects = new ArrayList(); + sharesObjects.add(shares.get(0)); + result.setData(sharesObjects); + } + } else { + result = new RemoteOperationResult(false, status, get.getResponseHeaders()); + } + + } catch (Exception e) { + result = new RemoteOperationResult(e); + Log_OC.e(TAG, "Exception while getting remote shares ", e); + + } finally { + if (get != null) { + get.releaseConnection(); + } + } + return result; + } + + private boolean isSuccess(int status) { + return (status == HttpStatus.SC_OK); + } + + +} diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java index 38b75194..18326549 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java @@ -39,7 +39,7 @@ import com.owncloud.android.lib.common.utils.Log_OC; /** - * Get the data from the server to know shares + * Get the data from the server about ALL the known shares owned by the requester. * * @author masensio * From 3d34e504ffd5a2116acb255511f162b846396143 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Fri, 23 Oct 2015 11:33:22 +0200 Subject: [PATCH 072/101] Refactored resources.users.GetRemoteUsersAndGroupsOperation to resources.shares.GetRemoteShareesOperation --- .../GetRemoteShareesOperation.java} | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) rename src/com/owncloud/android/lib/resources/{users/GetRemoteUsersOrGroupsOperation.java => shares/GetRemoteShareesOperation.java} (88%) diff --git a/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOrGroupsOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java similarity index 88% rename from src/com/owncloud/android/lib/resources/users/GetRemoteUsersOrGroupsOperation.java rename to src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java index 122b488a..b54f8430 100644 --- a/src/com/owncloud/android/lib/resources/users/GetRemoteUsersOrGroupsOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java @@ -25,7 +25,7 @@ * */ -package com.owncloud.android.lib.resources.users; +package com.owncloud.android.lib.resources.shares; import android.net.Uri; import android.util.Pair; @@ -45,21 +45,27 @@ import java.util.ArrayList; /** * Created by masensio on 08/10/2015. * - * Retrieves a list of users or groups from the ownCloud server. - * Authentication is done by sending a Basic HTTP Authorization header. - * Syntax: ocs/v1.php/cloud/users (Users) - * ocs/v1.php/cloud/groups (Groups) + * Retrieves a list of sharees (possible targets of a share) from the ownCloud server. + * + * Currently only handles users and groups. Users in other OC servers (federation) should be added later. + * + * Depends on SHAREE API. {@See https://github.com/owncloud/documentation/issues/1626} + * + * Syntax: + * Entry point: ocs/v2.php/apps/files_sharing/api/v1/sharees * HTTP method: GET - * url arguments: search - string, optional search string - * url arguments: limit - int, optional limit value - * url arguments: offset - int, optional offset value + * url argument: itemType - string, required + * url argument: format - string, optional + * url argument: search - string, optional + * url arguments: perPage - int, optional + * url arguments: page - int, optional * * Status codes: * 100 - successful */ -public class GetRemoteUsersOrGroupsOperation extends RemoteOperation{ +public class GetRemoteShareesOperation extends RemoteOperation{ - private static final String TAG = GetRemoteUsersOrGroupsOperation.class.getSimpleName(); + private static final String TAG = GetRemoteShareesOperation.class.getSimpleName(); // OCS Routes private static final String OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/sharees"; // from OC 8.2 @@ -73,7 +79,7 @@ public class GetRemoteUsersOrGroupsOperation extends RemoteOperation{ // Arguments - constant values private static final String VALUE_FORMAT = "json"; - private static final String VALUE_ITEM_TYPE = "search"; // to get the server search for users / groups + private static final String VALUE_ITEM_TYPE = "search"; // to get the server search for users / groups // JSON Node names @@ -101,7 +107,7 @@ public class GetRemoteUsersOrGroupsOperation extends RemoteOperation{ * @param page page index in the list of results; beginning in 1 * @param perPage maximum number of results in a single page */ - public GetRemoteUsersOrGroupsOperation(String searchString, int page, int perPage) { + public GetRemoteShareesOperation(String searchString, int page, int perPage) { mSearchString = searchString; mPage = page; mPerPage = perPage; From ad60bc9e8e0328e0f6c382890536ded8f7b139a8 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Fri, 23 Oct 2015 15:27:37 +0200 Subject: [PATCH 073/101] Complete error handling and add error message from server to response --- .../operations/RemoteOperationResult.java | 3 +- .../shares/CreateRemoteShareOperation.java | 34 ++++++----- .../shares/GetRemoteShareOperation.java | 39 ++++++++++--- .../GetRemoteSharesForFileOperation.java | 58 +++++++++++++------ .../shares/GetRemoteSharesOperation.java | 36 +++++++++--- .../shares/RemoveRemoteShareOperation.java | 21 +++++-- .../lib/resources/shares/ShareXMLParser.java | 38 +++++++++--- 7 files changed, 167 insertions(+), 62 deletions(-) diff --git a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java index ceb3f25f..28709905 100644 --- a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java +++ b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java @@ -107,7 +107,8 @@ public class RemoteOperationResult implements Serializable { INVALID_COPY_INTO_DESCENDANT, PARTIAL_MOVE_DONE, PARTIAL_COPY_DONE, - INVALID_CHARACTER_DETECT_IN_SERVER + SHARE_WRONG_PARAMETER, + WRONG_SERVER_RESPONSE, INVALID_CHARACTER_DETECT_IN_SERVER } private boolean mSuccess = false; diff --git a/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java index 6aaa7d1f..10b447a9 100644 --- a/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java @@ -140,46 +140,52 @@ public class CreateRemoteShareOperation extends RemoteOperation { if(isSuccess(status)) { String response = post.getResponseBodyAsString(); + ArrayList resultData = new ArrayList(); - result = new RemoteOperationResult(ResultCode.OK); - // Parse xml response --> obtain the response in ShareFiles ArrayList // convert String into InputStream InputStream is = new ByteArrayInputStream(response.getBytes()); ShareXMLParser xmlParser = new ShareXMLParser(); mShares = xmlParser.parseXMLResponse(is); if (xmlParser.isSuccess()) { - if (mShares != null) { + if (mShares != null && mShares.size() > 0) { Log_OC.d(TAG, "Created " + mShares.size() + " share(s)"); result = new RemoteOperationResult(ResultCode.OK); - ArrayList sharesObjects = new ArrayList(); for (OCShare share: mShares) { - sharesObjects.add(share); + resultData.add(share); } - result.setData(sharesObjects); + result.setData(resultData); if (mGetShareDetails) { // retrieve more info - OCShare emptyShare = (OCShare) sharesObjects.get(0); + OCShare emptyShare = (OCShare) resultData.get(0); GetRemoteShareOperation getInfo = new GetRemoteShareOperation(emptyShare.getIdRemoteShared()); result = getInfo.execute(client); } } else { - result = new RemoteOperationResult(ResultCode.UNKNOWN_ERROR); - Log_OC.e(TAG, "Successful response with no share in it"); + result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); + Log_OC.e(TAG, "Successful status with no share in it"); } - } else if (xmlParser.isFileNotFound()){ + } else if (xmlParser.isWrongParameter()){ + result = new RemoteOperationResult(ResultCode.SHARE_WRONG_PARAMETER); + resultData.add(xmlParser.getMessage()); + result.setData(resultData); + + } else if (xmlParser.isNotFound()){ result = new RemoteOperationResult(ResultCode.SHARE_NOT_FOUND); - - } else if (xmlParser.isFailure()) { - // TODO need deeper processing + resultData.add(xmlParser.getMessage()); + result.setData(resultData); + + } else if (xmlParser.isForbidden()) { result = new RemoteOperationResult(ResultCode.SHARE_FORBIDDEN); + resultData.add(xmlParser.getMessage()); + result.setData(resultData); } else { - result = new RemoteOperationResult(false, status, post.getResponseHeaders()); + result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); } } else { diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java index 6dcb28a2..f7ab0b29 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java @@ -25,8 +25,6 @@ package com.owncloud.android.lib.resources.shares; -import android.net.Uri; - import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; @@ -71,21 +69,46 @@ public class GetRemoteShareOperation extends RemoteOperation { get = new GetMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH + "/" + Long.toString(mRemoteId)); //get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); status = client.executeMethod(get); + if(isSuccess(status)) { String response = get.getResponseBodyAsString(); + ArrayList resultData = new ArrayList(); // Parse xml response --> obtain the response in ShareFiles ArrayList // convert String into InputStream InputStream is = new ByteArrayInputStream(response.getBytes()); ShareXMLParser xmlParser = new ShareXMLParser(); List shares = xmlParser.parseXMLResponse(is); - if (shares != null && shares.size() > 0) { - Log_OC.d(TAG, "Got " + shares.size() + " shares"); - result = new RemoteOperationResult(ResultCode.OK); - ArrayList sharesObjects = new ArrayList(); - sharesObjects.add(shares.get(0)); - result.setData(sharesObjects); + if (xmlParser.isSuccess()) { + if (shares != null && shares.size() > 0) { + Log_OC.d(TAG, "Got " + shares.size() + " shares"); + result = new RemoteOperationResult(ResultCode.OK); + resultData.add(shares.get(0)); + result.setData(resultData); + } else { + result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); + Log_OC.e(TAG, "Successful status with no share in it"); + } + + } else if (xmlParser.isWrongParameter()){ + result = new RemoteOperationResult(ResultCode.SHARE_WRONG_PARAMETER); + resultData.add(xmlParser.getMessage()); + result.setData(resultData); + + } else if (xmlParser.isNotFound()){ + result = new RemoteOperationResult(ResultCode.SHARE_NOT_FOUND); + resultData.add(xmlParser.getMessage()); + result.setData(resultData); + + } else if (xmlParser.isForbidden()) { + result = new RemoteOperationResult(ResultCode.SHARE_FORBIDDEN); + resultData.add(xmlParser.getMessage()); + result.setData(resultData); + + } else { + result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); } + } else { result = new RemoteOperationResult(false, status, get.getResponseHeaders()); } diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java index 1518b516..98c8c9d8 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java @@ -37,7 +37,6 @@ import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; -import com.owncloud.android.lib.resources.status.OwnCloudVersion; /** * Provide a list shares for a specific file. @@ -103,32 +102,53 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation { if(isSuccess(status)) { String response = get.getResponseBodyAsString(); + ArrayList resultData = new ArrayList(); - result = new RemoteOperationResult(ResultCode.OK); - // Parse xml response --> obtain the response in ShareFiles ArrayList // convert String into InputStream InputStream is = new ByteArrayInputStream(response.getBytes()); ShareXMLParser xmlParser = new ShareXMLParser(); mShares = xmlParser.parseXMLResponse(is); - if (mShares != null) { - Log_OC.d(TAG, "Got " + mShares.size() + " shares"); - result = new RemoteOperationResult(ResultCode.OK); - ArrayList sharesObjects = new ArrayList(); - for (OCShare share: mShares) { - // Build the link - if ( share.getShareType() == ShareType.PUBLIC_LINK && - share.getShareLink() == null && - share.getToken().length() > 0 - ) { - String linkToken = ShareUtils.getSharingToken( - client.getOwnCloudVersion()); - share.setShareLink(client.getBaseUri() + linkToken + - share.getToken()); + if (xmlParser.isSuccess()) { + if (mShares != null) { // 0 shares is a right response + Log_OC.d(TAG, "Got " + mShares.size() + " shares"); + result = new RemoteOperationResult(ResultCode.OK); + for (OCShare share: mShares) { + // Build the link + if ( share.getShareType() == ShareType.PUBLIC_LINK && + share.getShareLink() == null && + share.getToken().length() > 0 + ) { + String linkToken = ShareUtils.getSharingToken( + client.getOwnCloudVersion()); + share.setShareLink(client.getBaseUri() + linkToken + + share.getToken()); + } + resultData.add(share); } - sharesObjects.add(share); + result.setData(resultData); + } else { + result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); + Log_OC.e(TAG, "Successful status with no share in it"); } - result.setData(sharesObjects); + + } else if (xmlParser.isWrongParameter()){ + result = new RemoteOperationResult(ResultCode.SHARE_WRONG_PARAMETER); + resultData.add(xmlParser.getMessage()); + result.setData(resultData); + + } else if (xmlParser.isNotFound()){ + result = new RemoteOperationResult(ResultCode.SHARE_NOT_FOUND); + resultData.add(xmlParser.getMessage()); + result.setData(resultData); + + } else if (xmlParser.isForbidden()) { + result = new RemoteOperationResult(ResultCode.SHARE_FORBIDDEN); + resultData.add(xmlParser.getMessage()); + result.setData(resultData); + + } else { + result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); } } else { diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java index 18326549..295eaba4 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java @@ -68,23 +68,45 @@ public class GetRemoteSharesOperation extends RemoteOperation { get = new GetMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH); get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); status = client.executeMethod(get); + if(isSuccess(status)) { String response = get.getResponseBodyAsString(); + ArrayList resultData = new ArrayList(); // Parse xml response --> obtain the response in ShareFiles ArrayList // convert String into InputStream InputStream is = new ByteArrayInputStream(response.getBytes()); ShareXMLParser xmlParser = new ShareXMLParser(); mShares = xmlParser.parseXMLResponse(is); - if (mShares != null) { - Log_OC.d(TAG, "Got " + mShares.size() + " shares"); - result = new RemoteOperationResult(ResultCode.OK); - ArrayList sharesObjects = new ArrayList(); - for (OCShare share: mShares) { - sharesObjects.add(share); + if (xmlParser.isSuccess()) { + if (mShares != null) { // 0 shares is a right response + Log_OC.d(TAG, "Got " + mShares.size() + " shares"); + result = new RemoteOperationResult(ResultCode.OK); + for (OCShare share : mShares) { + resultData.add(share); + } + result.setData(resultData); } - result.setData(sharesObjects); + + } else if (xmlParser.isWrongParameter()){ + result = new RemoteOperationResult(ResultCode.SHARE_WRONG_PARAMETER); + resultData.add(xmlParser.getMessage()); + result.setData(resultData); + + } else if (xmlParser.isNotFound()){ + result = new RemoteOperationResult(ResultCode.SHARE_NOT_FOUND); + resultData.add(xmlParser.getMessage()); + result.setData(resultData); + + } else if (xmlParser.isForbidden()) { + result = new RemoteOperationResult(ResultCode.SHARE_FORBIDDEN); + resultData.add(xmlParser.getMessage()); + result.setData(resultData); + + } else { + result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); } + } else { result = new RemoteOperationResult(false, status, get.getResponseHeaders()); } diff --git a/src/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.java index 4db29051..c4245718 100644 --- a/src/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.java @@ -26,6 +26,7 @@ package com.owncloud.android.lib.resources.shares; import java.io.ByteArrayInputStream; import java.io.InputStream; +import java.util.ArrayList; import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.client.methods.DeleteMethod; @@ -77,9 +78,8 @@ public class RemoveRemoteShareOperation extends RemoteOperation { if(isSuccess(status)) { String response = delete.getResponseBodyAsString(); + ArrayList resultData = new ArrayList(); - result = new RemoteOperationResult(ResultCode.OK); - // Parse xml response // convert String into InputStream InputStream is = new ByteArrayInputStream(response.getBytes()); @@ -87,10 +87,23 @@ public class RemoveRemoteShareOperation extends RemoteOperation { xmlParser.parseXMLResponse(is); if (xmlParser.isSuccess()) { result = new RemoteOperationResult(ResultCode.OK); - } else if (xmlParser.isFileNotFound()){ + } else if (xmlParser.isWrongParameter()){ + result = new RemoteOperationResult(ResultCode.SHARE_WRONG_PARAMETER); + resultData.add(xmlParser.getMessage()); + result.setData(resultData); + + } else if (xmlParser.isNotFound()){ result = new RemoteOperationResult(ResultCode.SHARE_NOT_FOUND); + resultData.add(xmlParser.getMessage()); + result.setData(resultData); + + } else if (xmlParser.isForbidden()) { + result = new RemoteOperationResult(ResultCode.SHARE_FORBIDDEN); + resultData.add(xmlParser.getMessage()); + result.setData(resultData); + } else { - result = new RemoteOperationResult(false, status, delete.getResponseHeaders()); + result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); } Log_OC.d(TAG, "Unshare " + id + ": " + result.getLogMessage()); diff --git a/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java b/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java index 8189eac0..e672deeb 100644 --- a/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java +++ b/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java @@ -57,7 +57,7 @@ public class ShareXMLParser { private static final String NODE_META = "meta"; private static final String NODE_STATUS = "status"; private static final String NODE_STATUS_CODE = "statuscode"; - //private static final String NODE_MESSAGE = "message"; + private static final String NODE_MESSAGE = "message"; private static final String NODE_DATA = "data"; private static final String NODE_ELEMENT = "element"; @@ -82,11 +82,13 @@ public class ShareXMLParser { private static final String TYPE_FOLDER = "folder"; private static final int SUCCESS = 100; - private static final int FAILURE = 403; - private static final int FILE_NOT_FOUND = 404; + private static final int ERROR_WRONG_PARAMETER = 403; + private static final int ERROR_FORBIDDEN = 403; + private static final int ERROR_NOT_FOUND = 404; private String mStatus; private int mStatusCode; + private String mMessage; // Getters and Setters public String getStatus() { @@ -104,21 +106,36 @@ public class ShareXMLParser { public void setStatusCode(int statusCode) { this.mStatusCode = statusCode; } + + public String getMessage() { + return mMessage; + } + + public void setMessage(String message) { + this.mMessage = message; + } + // Constructor public ShareXMLParser() { - mStatusCode = 100; + mStatusCode = -1; } public boolean isSuccess() { return mStatusCode == SUCCESS; } - public boolean isFailure() { - return mStatusCode == FAILURE; + + public boolean isForbidden() { + return mStatusCode == ERROR_FORBIDDEN; } - public boolean isFileNotFound() { - return mStatusCode == FILE_NOT_FOUND; + + public boolean isNotFound() { + return mStatusCode == ERROR_NOT_FOUND; } - + + public boolean isWrongParameter() { + return mStatusCode == ERROR_WRONG_PARAMETER; + } + /** * Parse is as response of Share API * @param is @@ -197,6 +214,9 @@ public class ShareXMLParser { } else if (name.equalsIgnoreCase(NODE_STATUS_CODE)) { setStatusCode(Integer.parseInt(readNode(parser, NODE_STATUS_CODE))); + } else if (name.equalsIgnoreCase(NODE_MESSAGE)) { + setMessage(readNode(parser, NODE_MESSAGE)); + } else { skip(parser); } From 4d9ff3e02275f03642fb4b5ed16f3164a0412e21 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Mon, 26 Oct 2015 11:22:22 +0100 Subject: [PATCH 074/101] Refactoed operations on Shares --- .../shares/CreateRemoteShareOperation.java | 72 +++------ .../shares/GetRemoteShareOperation.java | 52 ++----- .../GetRemoteSharesForFileOperation.java | 68 ++------- .../shares/GetRemoteSharesOperation.java | 52 ++----- .../shares/RemoveRemoteShareOperation.java | 42 +---- .../ShareToRemoteOperationResultParser.java | 144 ++++++++++++++++++ .../lib/resources/shares/ShareUtils.java | 14 +- 7 files changed, 206 insertions(+), 238 deletions(-) create mode 100644 src/com/owncloud/android/lib/resources/shares/ShareToRemoteOperationResultParser.java diff --git a/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java index 10b447a9..403c62c7 100644 --- a/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java @@ -1,4 +1,6 @@ /* ownCloud Android Library is available under MIT license + * @author masensio + * @author David A. Velasco * Copyright (C) 2015 ownCloud Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -24,24 +26,16 @@ package com.owncloud.android.lib.resources.shares; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.ArrayList; - import org.apache.commons.httpclient.methods.PostMethod; import org.apache.http.HttpStatus; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; /** * Creates a new share. This allows sharing with a user or group or as a link. - * - * @author masensio - * */ public class CreateRemoteShareOperation extends RemoteOperation { @@ -54,8 +48,6 @@ public class CreateRemoteShareOperation extends RemoteOperation { private static final String PARAM_PASSWORD = "password"; private static final String PARAM_PERMISSIONS = "permissions"; - private ArrayList mShares; // List of shares for result, one share in this case - private String mRemoteFilePath; private ShareType mShareType; private String mShareWith; @@ -118,7 +110,6 @@ public class CreateRemoteShareOperation extends RemoteOperation { try { // Post Method post = new PostMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH); - //Log_OC.d(TAG, "URL ------> " + client.getBaseUri() + ShareUtils.SHARING_API_PATH); post.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); // necessary for special characters @@ -127,7 +118,7 @@ public class CreateRemoteShareOperation extends RemoteOperation { post.addParameter(PARAM_SHARE_TYPE, Integer.toString(mShareType.getValue())); post.addParameter(PARAM_SHARE_WITH, mShareWith); if (mPublicUpload) { - post.addParameter(PARAM_PUBLIC_UPLOAD, Boolean.toString(mPublicUpload)); + post.addParameter(PARAM_PUBLIC_UPLOAD, Boolean.toString(true)); } if (mPassword != null && mPassword.length() > 0) { post.addParameter(PARAM_PASSWORD, mPassword); @@ -140,52 +131,23 @@ public class CreateRemoteShareOperation extends RemoteOperation { if(isSuccess(status)) { String response = post.getResponseBodyAsString(); - ArrayList resultData = new ArrayList(); - // Parse xml response --> obtain the response in ShareFiles ArrayList - // convert String into InputStream - InputStream is = new ByteArrayInputStream(response.getBytes()); - ShareXMLParser xmlParser = new ShareXMLParser(); - mShares = xmlParser.parseXMLResponse(is); - if (xmlParser.isSuccess()) { - if (mShares != null && mShares.size() > 0) { - Log_OC.d(TAG, "Created " + mShares.size() + " share(s)"); - result = new RemoteOperationResult(ResultCode.OK); - for (OCShare share: mShares) { - resultData.add(share); - } - result.setData(resultData); + ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser( + new ShareXMLParser() + ); + parser.setOneOrMoreSharesRequired(true); + parser.setOwnCloudVersion(client.getOwnCloudVersion()); + parser.setServerBaseUri(client.getBaseUri()); + result = parser.parse(response); - if (mGetShareDetails) { - // retrieve more info - OCShare emptyShare = (OCShare) resultData.get(0); - - GetRemoteShareOperation getInfo = new GetRemoteShareOperation(emptyShare.getIdRemoteShared()); - result = getInfo.execute(client); - } - - } else { - result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); - Log_OC.e(TAG, "Successful status with no share in it"); + if (result.isSuccess()) { + Log_OC.d(TAG, "Created " + result.getData().size() + " share(s)"); // should be one + if (mGetShareDetails) { + // retrieve more info - POST operation only returns the index of the new share + OCShare emptyShare = (OCShare) result.getData().get(0); + GetRemoteShareOperation getInfo = new GetRemoteShareOperation(emptyShare.getIdRemoteShared()); + result = getInfo.execute(client); } - - } else if (xmlParser.isWrongParameter()){ - result = new RemoteOperationResult(ResultCode.SHARE_WRONG_PARAMETER); - resultData.add(xmlParser.getMessage()); - result.setData(resultData); - - } else if (xmlParser.isNotFound()){ - result = new RemoteOperationResult(ResultCode.SHARE_NOT_FOUND); - resultData.add(xmlParser.getMessage()); - result.setData(resultData); - - } else if (xmlParser.isForbidden()) { - result = new RemoteOperationResult(ResultCode.SHARE_FORBIDDEN); - resultData.add(xmlParser.getMessage()); - result.setData(resultData); - - } else { - result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); } } else { diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java index f7ab0b29..9189b9f0 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java @@ -28,17 +28,11 @@ package com.owncloud.android.lib.resources.shares; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.http.HttpStatus; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - /** * Get the data about a Share resource, known its remote ID. @@ -67,47 +61,21 @@ public class GetRemoteShareOperation extends RemoteOperation { // Get the response try{ get = new GetMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH + "/" + Long.toString(mRemoteId)); - //get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); + get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); + status = client.executeMethod(get); if(isSuccess(status)) { String response = get.getResponseBodyAsString(); - ArrayList resultData = new ArrayList(); - // Parse xml response --> obtain the response in ShareFiles ArrayList - // convert String into InputStream - InputStream is = new ByteArrayInputStream(response.getBytes()); - ShareXMLParser xmlParser = new ShareXMLParser(); - List shares = xmlParser.parseXMLResponse(is); - if (xmlParser.isSuccess()) { - if (shares != null && shares.size() > 0) { - Log_OC.d(TAG, "Got " + shares.size() + " shares"); - result = new RemoteOperationResult(ResultCode.OK); - resultData.add(shares.get(0)); - result.setData(resultData); - } else { - result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); - Log_OC.e(TAG, "Successful status with no share in it"); - } - - } else if (xmlParser.isWrongParameter()){ - result = new RemoteOperationResult(ResultCode.SHARE_WRONG_PARAMETER); - resultData.add(xmlParser.getMessage()); - result.setData(resultData); - - } else if (xmlParser.isNotFound()){ - result = new RemoteOperationResult(ResultCode.SHARE_NOT_FOUND); - resultData.add(xmlParser.getMessage()); - result.setData(resultData); - - } else if (xmlParser.isForbidden()) { - result = new RemoteOperationResult(ResultCode.SHARE_FORBIDDEN); - resultData.add(xmlParser.getMessage()); - result.setData(resultData); - - } else { - result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); - } + // Parse xml response and obtain the list of shares + ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser( + new ShareXMLParser() + ); + parser.setOneOrMoreSharesRequired(true); + parser.setOwnCloudVersion(client.getOwnCloudVersion()); + parser.setServerBaseUri(client.getBaseUri()); + result = parser.parse(response); } else { result = new RemoteOperationResult(false, status, get.getResponseHeaders()); diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java index 98c8c9d8..1381d272 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java @@ -1,4 +1,6 @@ /* ownCloud Android Library is available under MIT license + * @author masensio + * @author David A. Velasco * Copyright (C) 2015 ownCloud Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -24,10 +26,6 @@ package com.owncloud.android.lib.resources.shares; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.ArrayList; - import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.http.HttpStatus; @@ -35,18 +33,14 @@ import org.apache.http.HttpStatus; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; + /** * Provide a list shares for a specific file. * The input is the full path of the desired file. * The output is a list of everyone who has the file shared with them. - * - * @author masensio - * */ - public class GetRemoteSharesForFileOperation extends RemoteOperation { private static final String TAG = GetRemoteSharesForFileOperation.class.getSimpleName(); @@ -55,8 +49,6 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation { private static final String PARAM_RESHARES = "reshares"; private static final String PARAM_SUBFILES = "subfiles"; - private ArrayList mShares; // List of shares for result, one share in this case - private String mRemoteFilePath; private boolean mReshares; private boolean mSubfiles; @@ -102,53 +94,17 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation { if(isSuccess(status)) { String response = get.getResponseBodyAsString(); - ArrayList resultData = new ArrayList(); - // Parse xml response --> obtain the response in ShareFiles ArrayList - // convert String into InputStream - InputStream is = new ByteArrayInputStream(response.getBytes()); - ShareXMLParser xmlParser = new ShareXMLParser(); - mShares = xmlParser.parseXMLResponse(is); - if (xmlParser.isSuccess()) { - if (mShares != null) { // 0 shares is a right response - Log_OC.d(TAG, "Got " + mShares.size() + " shares"); - result = new RemoteOperationResult(ResultCode.OK); - for (OCShare share: mShares) { - // Build the link - if ( share.getShareType() == ShareType.PUBLIC_LINK && - share.getShareLink() == null && - share.getToken().length() > 0 - ) { - String linkToken = ShareUtils.getSharingToken( - client.getOwnCloudVersion()); - share.setShareLink(client.getBaseUri() + linkToken + - share.getToken()); - } - resultData.add(share); - } - result.setData(resultData); - } else { - result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); - Log_OC.e(TAG, "Successful status with no share in it"); - } + // Parse xml response and obtain the list of shares + ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser( + new ShareXMLParser() + ); + parser.setOwnCloudVersion(client.getOwnCloudVersion()); + parser.setServerBaseUri(client.getBaseUri()); + result = parser.parse(response); - } else if (xmlParser.isWrongParameter()){ - result = new RemoteOperationResult(ResultCode.SHARE_WRONG_PARAMETER); - resultData.add(xmlParser.getMessage()); - result.setData(resultData); - - } else if (xmlParser.isNotFound()){ - result = new RemoteOperationResult(ResultCode.SHARE_NOT_FOUND); - resultData.add(xmlParser.getMessage()); - result.setData(resultData); - - } else if (xmlParser.isForbidden()) { - result = new RemoteOperationResult(ResultCode.SHARE_FORBIDDEN); - resultData.add(xmlParser.getMessage()); - result.setData(resultData); - - } else { - result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); + if (result.isSuccess()) { + Log_OC.d(TAG, "Got " + result.getData().size() + " shares"); } } else { diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java index 295eaba4..acd8ca23 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java @@ -1,4 +1,6 @@ /* ownCloud Android Library is available under MIT license + * @author masensio + * @author David A. Velasco * Copyright (C) 2015 ownCloud Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -24,34 +26,25 @@ package com.owncloud.android.lib.resources.shares; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.ArrayList; - import org.apache.commons.httpclient.methods.GetMethod; import org.apache.http.HttpStatus; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; /** * Get the data from the server about ALL the known shares owned by the requester. * - * @author masensio - * */ public class GetRemoteSharesOperation extends RemoteOperation { private static final String TAG = GetRemoteSharesOperation.class.getSimpleName(); - private ArrayList mShares; // List of shares for result - public GetRemoteSharesOperation() { } @@ -71,41 +64,14 @@ public class GetRemoteSharesOperation extends RemoteOperation { if(isSuccess(status)) { String response = get.getResponseBodyAsString(); - ArrayList resultData = new ArrayList(); - // Parse xml response --> obtain the response in ShareFiles ArrayList - // convert String into InputStream - InputStream is = new ByteArrayInputStream(response.getBytes()); - ShareXMLParser xmlParser = new ShareXMLParser(); - mShares = xmlParser.parseXMLResponse(is); - if (xmlParser.isSuccess()) { - if (mShares != null) { // 0 shares is a right response - Log_OC.d(TAG, "Got " + mShares.size() + " shares"); - result = new RemoteOperationResult(ResultCode.OK); - for (OCShare share : mShares) { - resultData.add(share); - } - result.setData(resultData); - } - - } else if (xmlParser.isWrongParameter()){ - result = new RemoteOperationResult(ResultCode.SHARE_WRONG_PARAMETER); - resultData.add(xmlParser.getMessage()); - result.setData(resultData); - - } else if (xmlParser.isNotFound()){ - result = new RemoteOperationResult(ResultCode.SHARE_NOT_FOUND); - resultData.add(xmlParser.getMessage()); - result.setData(resultData); - - } else if (xmlParser.isForbidden()) { - result = new RemoteOperationResult(ResultCode.SHARE_FORBIDDEN); - resultData.add(xmlParser.getMessage()); - result.setData(resultData); - - } else { - result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); - } + // Parse xml response and obtain the list of shares + ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser( + new ShareXMLParser() + ); + parser.setOwnCloudVersion(client.getOwnCloudVersion()); + parser.setServerBaseUri(client.getBaseUri()); + result = parser.parse(response); } else { result = new RemoteOperationResult(false, status, get.getResponseHeaders()); diff --git a/src/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.java index c4245718..68a94db4 100644 --- a/src/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.java @@ -1,4 +1,6 @@ /* ownCloud Android Library is available under MIT license + * @author masensio + * @author David A. Velasco * Copyright (C) 2015 ownCloud Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -24,24 +26,16 @@ package com.owncloud.android.lib.resources.shares; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.ArrayList; - import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.client.methods.DeleteMethod; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; /** * Remove a share - * - * @author masensio - * */ public class RemoveRemoteShareOperation extends RemoteOperation { @@ -78,35 +72,15 @@ public class RemoveRemoteShareOperation extends RemoteOperation { if(isSuccess(status)) { String response = delete.getResponseBodyAsString(); - ArrayList resultData = new ArrayList(); - // Parse xml response - // convert String into InputStream - InputStream is = new ByteArrayInputStream(response.getBytes()); - ShareXMLParser xmlParser = new ShareXMLParser(); - xmlParser.parseXMLResponse(is); - if (xmlParser.isSuccess()) { - result = new RemoteOperationResult(ResultCode.OK); - } else if (xmlParser.isWrongParameter()){ - result = new RemoteOperationResult(ResultCode.SHARE_WRONG_PARAMETER); - resultData.add(xmlParser.getMessage()); - result.setData(resultData); + // Parse xml response and obtain the list of shares + ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser( + new ShareXMLParser() + ); + result = parser.parse(response); - } else if (xmlParser.isNotFound()){ - result = new RemoteOperationResult(ResultCode.SHARE_NOT_FOUND); - resultData.add(xmlParser.getMessage()); - result.setData(resultData); - - } else if (xmlParser.isForbidden()) { - result = new RemoteOperationResult(ResultCode.SHARE_FORBIDDEN); - resultData.add(xmlParser.getMessage()); - result.setData(resultData); - - } else { - result = new RemoteOperationResult(ResultCode.WRONG_SERVER_RESPONSE); - } - Log_OC.d(TAG, "Unshare " + id + ": " + result.getLogMessage()); + } else { result = new RemoteOperationResult(false, status, delete.getResponseHeaders()); } diff --git a/src/com/owncloud/android/lib/resources/shares/ShareToRemoteOperationResultParser.java b/src/com/owncloud/android/lib/resources/shares/ShareToRemoteOperationResultParser.java new file mode 100644 index 00000000..c59ba8ed --- /dev/null +++ b/src/com/owncloud/android/lib/resources/shares/ShareToRemoteOperationResultParser.java @@ -0,0 +1,144 @@ +/* ownCloud Android Library is available under MIT license + * @author David A. Velasco + * Copyright (C) 2015 ownCloud Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.resources.shares; + +import android.net.Uri; + +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.status.OwnCloudVersion; + +import org.xmlpull.v1.XmlPullParserException; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +public class ShareToRemoteOperationResultParser { + + private static final String TAG = ShareToRemoteOperationResultParser.class.getSimpleName(); + + private ShareXMLParser mShareXmlParser = null; + private boolean mOneOrMoreSharesRequired = false; + private OwnCloudVersion mOwnCloudVersion = null; + private Uri mServerBaseUri = null; + + + public ShareToRemoteOperationResultParser(ShareXMLParser shareXmlParser) { + mShareXmlParser = shareXmlParser; + } + + public void setOneOrMoreSharesRequired(boolean oneOrMoreSharesRequired) { + mOneOrMoreSharesRequired = oneOrMoreSharesRequired; + } + + public void setOwnCloudVersion(OwnCloudVersion ownCloudVersion) { + mOwnCloudVersion = ownCloudVersion; + } + + public void setServerBaseUri(Uri serverBaseURi) { + mServerBaseUri = serverBaseURi; + } + + public RemoteOperationResult parse(String serverResponse) { + if (serverResponse == null || serverResponse.length() == 0) { + return new RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE); + } + + RemoteOperationResult result = null; + ArrayList resultData = new ArrayList(); + + try { + // Parse xml response and obtain the list of shares + InputStream is = new ByteArrayInputStream(serverResponse.getBytes()); + if (mShareXmlParser == null) { + Log_OC.w(TAG, "No ShareXmlParser provided, creating new instance "); + mShareXmlParser = new ShareXMLParser(); + } + List shares = mShareXmlParser.parseXMLResponse(is); + + if (mShareXmlParser.isSuccess()) { + if ((shares != null && shares.size() > 0) || !mOneOrMoreSharesRequired) { + result = new RemoteOperationResult(RemoteOperationResult.ResultCode.OK); + if (shares != null) { + for (OCShare share : shares) { + resultData.add(share); + // build the share link if not in the response (only received when the share is created) + if (share.getShareType() == ShareType.PUBLIC_LINK && + share.getShareLink() == null && + share.getToken().length() > 0 + ) { + if (mServerBaseUri != null) { + String sharingLinkPath = ShareUtils.getSharingLinkPath(mOwnCloudVersion); + share.setShareLink(mServerBaseUri + sharingLinkPath + share.getToken()); + } else { + Log_OC.e(TAG, "Couldn't build link for public share"); + } + } + } + } + result.setData(resultData); + + } else { + result = new RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE); + Log_OC.e(TAG, "Successful status with no share in the response"); + } + + } else if (mShareXmlParser.isWrongParameter()){ + result = new RemoteOperationResult(RemoteOperationResult.ResultCode.SHARE_WRONG_PARAMETER); + resultData.add(mShareXmlParser.getMessage()); + result.setData(resultData); + + } else if (mShareXmlParser.isNotFound()){ + result = new RemoteOperationResult(RemoteOperationResult.ResultCode.SHARE_NOT_FOUND); + resultData.add(mShareXmlParser.getMessage()); + result.setData(resultData); + + } else if (mShareXmlParser.isForbidden()) { + result = new RemoteOperationResult(RemoteOperationResult.ResultCode.SHARE_FORBIDDEN); + resultData.add(mShareXmlParser.getMessage()); + result.setData(resultData); + + } else { + result = new RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE); + + } + + } catch (XmlPullParserException e) { + Log_OC.e(TAG, "Error parsing response from server ", e); + result = new RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE); + + } catch (IOException e) { + Log_OC.e(TAG, "Error reading response from server ", e); + result = new RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE); + } + + return result; + } + +} diff --git a/src/com/owncloud/android/lib/resources/shares/ShareUtils.java b/src/com/owncloud/android/lib/resources/shares/ShareUtils.java index 8ab9b118..ae4bc8b8 100644 --- a/src/com/owncloud/android/lib/resources/shares/ShareUtils.java +++ b/src/com/owncloud/android/lib/resources/shares/ShareUtils.java @@ -39,17 +39,15 @@ public class ShareUtils { public static final String SHARING_API_PATH ="/ocs/v1.php/apps/files_sharing/api/v1/shares"; // String to build the link with the token of a share: - // server address + "/public.php?service=files&t=" + token - public static final String SHARING_LINK_TOKEN_BEFORE_VERSION_8 = "/public.php?service=files&t="; - public static final String SHARING_LINK_TOKEN_AFTER_VERSION_8= "/index.php/s/"; + public static final String SHARING_LINK_PATH_BEFORE_VERSION_8 = "/public.php?service=files&t="; + public static final String SHARING_LINK_PATH_AFTER_VERSION_8 = "/index.php/s/"; - public static String getSharingToken(OwnCloudVersion version){ + public static String getSharingLinkPath(OwnCloudVersion version){ if (version!= null && version.isAfter8Version()){ - return SHARING_LINK_TOKEN_AFTER_VERSION_8; + return SHARING_LINK_PATH_AFTER_VERSION_8; } else { - return SHARING_LINK_TOKEN_BEFORE_VERSION_8; + return SHARING_LINK_PATH_BEFORE_VERSION_8; } - } - + } From bfe4fcd977de4d91b68cf0e439872fb95570572a Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Tue, 27 Oct 2015 09:23:36 +0100 Subject: [PATCH 075/101] Changes after cr --- .../shares/CreateRemoteShareOperation.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java index 403c62c7..65bbb0c4 100644 --- a/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java @@ -60,7 +60,8 @@ public class CreateRemoteShareOperation extends RemoteOperation { * Constructor * @param remoteFilePath Full path of the file/folder being shared. Mandatory argument * @param shareType 0 = user, 1 = group, 3 = Public link. Mandatory argument - * @param shareWith User/group ID with who the file should be shared. This is mandatory for shareType of 0 or 1 + * @param shareWith User/group ID with who the file should be shared. This is mandatory for shareType + * of 0 or 1 * @param publicUpload If false (default) public cannot upload to a public shared folder. * If true public can upload to a shared folder. Only available for public link shares * @param password Password to protect a public link share. Only available for public link shares @@ -140,14 +141,13 @@ public class CreateRemoteShareOperation extends RemoteOperation { parser.setServerBaseUri(client.getBaseUri()); result = parser.parse(response); - if (result.isSuccess()) { - Log_OC.d(TAG, "Created " + result.getData().size() + " share(s)"); // should be one - if (mGetShareDetails) { - // retrieve more info - POST operation only returns the index of the new share - OCShare emptyShare = (OCShare) result.getData().get(0); - GetRemoteShareOperation getInfo = new GetRemoteShareOperation(emptyShare.getIdRemoteShared()); - result = getInfo.execute(client); - } + if (result.isSuccess() && mGetShareDetails) { + // retrieve more info - POST only returns the index of the new share + OCShare emptyShare = (OCShare) result.getData().get(0); + GetRemoteShareOperation getInfo = new GetRemoteShareOperation( + emptyShare.getIdRemoteShared() + ); + result = getInfo.execute(client); } } else { From 0acd17d8ac5900251e31ddefa370f9bf19eca604 Mon Sep 17 00:00:00 2001 From: masensio Date: Wed, 28 Oct 2015 10:47:22 +0100 Subject: [PATCH 076/101] Fix: user whose name includes @ are not found --- .../android/lib/resources/shares/GetRemoteShareesOperation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java index b54f8430..bfe5195d 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java @@ -125,7 +125,7 @@ public class GetRemoteShareesOperation extends RemoteOperation{ uriBuilder.appendEncodedPath(OCS_ROUTE); uriBuilder.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT); uriBuilder.appendQueryParameter(PARAM_ITEM_TYPE, VALUE_ITEM_TYPE); - uriBuilder.appendQueryParameter(PARAM_SEARCH, Uri.encode(mSearchString)); + uriBuilder.appendQueryParameter(PARAM_SEARCH, Uri.encode(mSearchString, "@")); uriBuilder.appendQueryParameter(PARAM_PAGE, String.valueOf(mPage)); uriBuilder.appendQueryParameter(PARAM_PER_PAGE, String.valueOf(mPerPage)); From a9ada0b508343948431998170189a1267708dfec Mon Sep 17 00:00:00 2001 From: masensio Date: Wed, 28 Oct 2015 18:38:53 +0100 Subject: [PATCH 077/101] Fix problem searching users on Shibboleth Server. Add OC_API_HEADER to GetRemoteShareesOperation --- .../android/lib/resources/shares/GetRemoteShareesOperation.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java index bfe5195d..9045fc88 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java @@ -131,6 +131,7 @@ public class GetRemoteShareesOperation extends RemoteOperation{ // Get Method get = new GetMethod(uriBuilder.build().toString()); + get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); status = client.executeMethod(get); From ea26e43c0d173aef2346301cb1e9398ec4bd9da7 Mon Sep 17 00:00:00 2001 From: masensio Date: Thu, 29 Oct 2015 10:42:57 +0100 Subject: [PATCH 078/101] GetRemoteShareeOperation returns ArrayList with Users and Groups --- .../shares/GetRemoteShareesOperation.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java index 9045fc88..6809fac6 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java @@ -88,9 +88,10 @@ public class GetRemoteShareesOperation extends RemoteOperation{ private static final String NODE_EXACT = "exact"; private static final String NODE_USERS = "users"; private static final String NODE_GROUPS = "groups"; - private static final String NODE_VALUE = "value"; - private static final String PROPERTY_LABEL = "label"; - private static final String PROPERTY_SHARE_TYPE = "shareType"; + public static final String NODE_VALUE = "value"; + public static final String PROPERTY_LABEL = "label"; + public static final String PROPERTY_SHARE_TYPE = "shareType"; + public static final String PROPERTY_SHARE_WITH = "shareWith"; // Result types public static final Byte USER_TYPE = 0; @@ -156,16 +157,16 @@ public class GetRemoteShareesOperation extends RemoteOperation{ }; ArrayList data = new ArrayList(); // For result data - Pair match; +// Pair match; for (int i=0; i<4; i++) { for(int j=0; j< jsonResults[i].length(); j++){ JSONObject jsonResult = jsonResults[i].getJSONObject(j); - match = new Pair( - jsonResult.getString(PROPERTY_LABEL), - (byte)jsonResult.getJSONObject(NODE_VALUE).getInt(PROPERTY_SHARE_TYPE) - ); - data.add(match); - Log_OC.d(TAG, "*** Added item: " + match.first); +// match = new Pair( +// jsonResult.getString(PROPERTY_LABEL), +// (byte)jsonResult.getJSONObject(NODE_VALUE).getInt(PROPERTY_SHARE_TYPE) +// ); + data.add(jsonResult); + Log_OC.d(TAG, "*** Added item: " + jsonResult.getString(PROPERTY_LABEL)); } } From 642051cf450ee70c10235041029361f12a0a9717 Mon Sep 17 00:00:00 2001 From: masensio Date: Thu, 29 Oct 2015 10:49:19 +0100 Subject: [PATCH 079/101] Remove commented code --- .../lib/resources/shares/GetRemoteShareesOperation.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java index 6809fac6..132b017f 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java @@ -28,7 +28,6 @@ package com.owncloud.android.lib.resources.shares; import android.net.Uri; -import android.util.Pair; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperation; @@ -157,14 +156,9 @@ public class GetRemoteShareesOperation extends RemoteOperation{ }; ArrayList data = new ArrayList(); // For result data -// Pair match; for (int i=0; i<4; i++) { for(int j=0; j< jsonResults[i].length(); j++){ JSONObject jsonResult = jsonResults[i].getJSONObject(j); -// match = new Pair( -// jsonResult.getString(PROPERTY_LABEL), -// (byte)jsonResult.getJSONObject(NODE_VALUE).getInt(PROPERTY_SHARE_TYPE) -// ); data.add(jsonResult); Log_OC.d(TAG, "*** Added item: " + jsonResult.getString(PROPERTY_LABEL)); } From 875fce9f9c19190ba976cfc3634c63029362eda5 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Thu, 29 Oct 2015 16:32:57 +0100 Subject: [PATCH 080/101] Added constant to let server decide share permissions --- .../lib/resources/shares/CreateRemoteShareOperation.java | 4 +++- src/com/owncloud/android/lib/resources/shares/OCShare.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java index 65bbb0c4..21545222 100644 --- a/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java @@ -124,7 +124,9 @@ public class CreateRemoteShareOperation extends RemoteOperation { if (mPassword != null && mPassword.length() > 0) { post.addParameter(PARAM_PASSWORD, mPassword); } - post.addParameter(PARAM_PERMISSIONS, Integer.toString(mPermissions)); + if (OCShare.DEFAULT_PERMISSION != mPermissions) { + post.addParameter(PARAM_PERMISSIONS, Integer.toString(mPermissions)); + } post.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); diff --git a/src/com/owncloud/android/lib/resources/shares/OCShare.java b/src/com/owncloud/android/lib/resources/shares/OCShare.java index 16f0c394..644955cc 100644 --- a/src/com/owncloud/android/lib/resources/shares/OCShare.java +++ b/src/com/owncloud/android/lib/resources/shares/OCShare.java @@ -45,7 +45,9 @@ public class OCShare implements Parcelable, Serializable { private static final long serialVersionUID = 4124975224281327921L; private static final String TAG = OCShare.class.getSimpleName(); - + + public static final int DEFAULT_PERMISSION = -1; + private long mId; private long mFileSource; private long mItemSource; From caa9bb3d01a14423bb5c9f82357d3ebbd27acf26 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Tue, 27 Oct 2015 09:13:15 +0100 Subject: [PATCH 081/101] Added test for GetRemoteShareesOperation --- .../lib/test_project/test/GetShareesTest.java | 228 ++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 test_client/tests/src/com/owncloud/android/lib/test_project/test/GetShareesTest.java diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/GetShareesTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/GetShareesTest.java new file mode 100644 index 00000000..80bcd107 --- /dev/null +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/GetShareesTest.java @@ -0,0 +1,228 @@ +/* ownCloud Android Library is available under MIT license + * @author David A. Velasco + * Copyright (C) 2015 ownCloud Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.test_project.test; + +import java.security.GeneralSecurityException; + +import junit.framework.AssertionFailedError; + +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; +import org.json.JSONException; +import org.json.JSONObject; + +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.OwnCloudClientFactory; +import com.owncloud.android.lib.common.OwnCloudCredentialsFactory; +import com.owncloud.android.lib.common.network.NetworkUtils; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.resources.shares.GetRemoteShareesOperation; +import com.owncloud.android.lib.test_project.R; +import com.owncloud.android.lib.test_project.SelfSignedConfidentSslSocketFactory; + +import android.content.Context; +import android.net.Uri; +import android.util.Log; + +/** + * Class to test GetRemoteShareesOperation + * + * With this TestCase we are experimenting a bit to improve the test suite design, in two aspects: + * + * - Reduce the dependency from the set of test cases on the "test project" needed to + * have an instrumented APK to install in the device, as required by the testing framework + * provided by Android. To get there, this class avoids calling TestActivity methods in the test + * method. + * + * - Reduce the impact of creating a remote fixture over the Internet, while the structure of the + * TestCase is kept easy to maintain. To get this, all the tests are done in a single test method, + * granting this way that setUp and tearDown are run only once. + * + */ + +public class GetShareesTest extends RemoteTest { + + private static final String LOG_TAG = GetShareesTest.class.getCanonicalName(); + + String mServerUri, mUser, mPass; + OwnCloudClient mClient = null; + + public GetShareesTest() { + super(); + + Protocol pr = Protocol.getProtocol("https"); + if (pr == null || !(pr.getSocketFactory() instanceof SelfSignedConfidentSslSocketFactory)) { + try { + ProtocolSocketFactory psf = new SelfSignedConfidentSslSocketFactory(); + Protocol.registerProtocol( + "https", + new Protocol("https", psf, 443)); + + } catch (GeneralSecurityException e) { + throw new AssertionFailedError( + "Self-signed confident SSL context could not be loaded"); + } + } + + } + + + protected Context getContext() { + return getActivity(); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + // Next initialization cannot be done in the constructor because getContext() is not + // ready yet, returns NULL. + initAccessToServer(getContext()); + + Log.v(LOG_TAG, "Setting up the remote fixture..."); + + Log.v(LOG_TAG, "Remote fixture created."); + + } + + + /** + * Test get sharees + * + * Requires OC server 8.2 or later + */ + public void testGetRemoteShareesOperation() { + Log.v(LOG_TAG, "testGetRemoteSharees in"); + + /// successful cases + + // search for sharees including "a" + GetRemoteShareesOperation getShareesOperation = new GetRemoteShareesOperation("a", 1, 50); + RemoteOperationResult result = getShareesOperation.execute(mClient); + JSONObject resultItem; + JSONObject value; + byte type; + int userCount = 0, groupCount = 0; + assertTrue(result.isSuccess() && result.getData().size() == 3); + try { + for (int i=0; i<3; i++) { + resultItem = (JSONObject) result.getData().get(i); + value = resultItem.getJSONObject(GetRemoteShareesOperation.NODE_VALUE); + type = (byte) value.getInt(GetRemoteShareesOperation.PROPERTY_SHARE_TYPE); + if (GetRemoteShareesOperation.GROUP_TYPE.equals(type)) { + groupCount++; + } else { + userCount++; + } + } + assertEquals(userCount, 2); + assertEquals(groupCount, 1); + } catch (JSONException e) { + AssertionFailedError afe = new AssertionFailedError(e.getLocalizedMessage()); + afe.setStackTrace(e.getStackTrace()); + throw afe; + } + + // search for sharees including "ad" + getShareesOperation = new GetRemoteShareesOperation("ad", 1, 50); + result = getShareesOperation.execute(mClient); + assertTrue(result.isSuccess() && result.getData().size() == 2); + userCount = 0; groupCount = 0; + try { + for (int i=0; i<2; i++) { + resultItem = (JSONObject) result.getData().get(i); + value = resultItem.getJSONObject(GetRemoteShareesOperation.NODE_VALUE); + type = (byte) value.getInt(GetRemoteShareesOperation.PROPERTY_SHARE_TYPE); + if (GetRemoteShareesOperation.GROUP_TYPE.equals(type)) { + groupCount++; + } else { + userCount++; + } + } + assertEquals(userCount, 1); + assertEquals(groupCount, 1); + } catch (JSONException e) { + AssertionFailedError afe = new AssertionFailedError(e.getLocalizedMessage()); + afe.setStackTrace(e.getStackTrace()); + throw afe; + } + + + // search for sharees including "b" + getShareesOperation = new GetRemoteShareesOperation("b", 1, 50); + result = getShareesOperation.execute(mClient); + assertTrue(result.isSuccess() && result.getData().size() == 0); + + + /// failed cases + + // search for sharees including wrong page values + getShareesOperation = new GetRemoteShareesOperation("a", 0, 50); + result = getShareesOperation.execute(mClient); + assertTrue(!result.isSuccess() && result.getHttpCode() == HttpStatus.SC_BAD_REQUEST); + + getShareesOperation = new GetRemoteShareesOperation("a", 1, 0); + result = getShareesOperation.execute(mClient); + assertTrue(!result.isSuccess() && result.getHttpCode() == HttpStatus.SC_BAD_REQUEST); + } + + @Override + protected void tearDown() throws Exception { + Log.v(LOG_TAG, "Deleting remote fixture..."); + super.tearDown(); + Log.v(LOG_TAG, "Remote fixture delete."); + } + + + private void initAccessToServer(Context context) { + Log.v(LOG_TAG, "Setting up client instance to access OC server..."); + + mServerUri = context.getString(R.string.server_base_url); + mUser = context.getString(R.string.username); + mPass = context.getString(R.string.password); + + mClient = new OwnCloudClient( + Uri.parse(mServerUri), + NetworkUtils.getMultiThreadedConnManager() + ); + mClient.setDefaultTimeouts( + OwnCloudClientFactory.DEFAULT_DATA_TIMEOUT, + OwnCloudClientFactory.DEFAULT_CONNECTION_TIMEOUT); + mClient.setFollowRedirects(true); + mClient.setCredentials( + OwnCloudCredentialsFactory.newBasicCredentials( + mUser, + mPass + ) + ); + + Log.v(LOG_TAG, "Client instance set up."); + + } + + +} From 96825b43b93a0ee771649f6a8097ad722ab6cb82 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Thu, 29 Oct 2015 18:29:49 +0100 Subject: [PATCH 082/101] Updated test server --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8ccad6c8..fe5cb9c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,8 +20,8 @@ script: - ./gradlew clean build env: global: - - secure: HxHoqnC8mauCKi87zlo7pQcSsSw0W5MtW+iUcB8T11quwTBgUPWIOmycXv2FcmwpST0E43Ct+dhE+mttm+6P+5PSB33HQNLq00hfTVIJ4ttcb/5eWW8MnP7L+kPK8d0EtfDG6GQto7QktaybeG4+sNKKD336ZlFfM7xgPtPv+tg= - - secure: WQMw0ciloe8i2ApGhePhuTmmH8UgAV1Ri10C1qhUH9hVOJAr+/1X5A93VPYGrgJ2EH5MdiL6f2XMDCYAgb9efuvZIUKNE0J92xh8m/yRa8nAVWNBE0PBdS4+OycoHpIQfMcUghooERXjP4GUYd/ZwICvWA+sXdOYWDdKjODUgl4= - - secure: QPxKT8vC7sm1b/hYJcfkQkLgpwNRBvVKk8S8S0t43mmqPJfs94FJTQHH4kZaGSwOeuDkRQbGuKzYtXOnGOKX2hhUBqKJd1idpJnUID8id8Kqo6VutjG017+XxZQp0hPHmfmDxYkDvlaLeoZpP2NkpwZ1p4TL2MSCr2Ibl6uTWvc= + - secure: a21NrzTCQnkTKtRGo7B1lyF2WWbpBT2N64V2Tf+oUcRLOUx3XM/mDi60mAdGd0WXV9tHD8GGmu0tQ7LGZ2VsIxixVxjzEYwX4HRTodewYez6WxBMjVEHHy+3jmc1zU4k3AAqr+uW7L4BKa5r9tH+nq9ecJMDMgW8o9MKXuP7Vso= + - secure: UVnaC5Qzat2C8WlMMb8aycz1ChZKjP8Kz89qBbVcqYK+PLAGKpUNxFa39/2oA5jkMyyOcXYC9bX1ZYzHLH7nJ8LbQgaxXMT4gvgvN0l6KezjDavIW60idD9BbugkwzNj/cjoU/DdxBykPsTn4vSRaESVNTdEbM27YU4FBPzTANY= + - secure: XEQY8s7p65lWWOuKbVDdTh6ZJtRTJ74Zw3H/+2Ms6vjZhFZsdUJjGo66LW6YvlhmYDXgiPB9piYQGcrGgT3hXJwXoge6n1pdixnV250J0T0dIZMbXYTWTARxDsyq48+LgUuF3pgqvqDWhBcemrePWv48q7fs/mwzuFSOyc8QwLk= matrix: - ANDROID_TARGET=android-19 ANDROID_ABI=armeabi-v7a From b5074f4381217ff9acbc52cbbaba9c3331df3735 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Thu, 29 Oct 2015 18:52:14 +0100 Subject: [PATCH 083/101] Migrate Travis build to container-based infrastructure --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index fe5cb9c1..d12be4a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ +sudo: false language: android android: components: From 5c48817712be36262002605c25abd0b41d02fb80 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Mon, 2 Nov 2015 14:59:01 +0100 Subject: [PATCH 084/101] Update unit tests with cases for creating private shares --- .../test_project/test/CreateShareTest.java | 151 +++++++++++++++++- 1 file changed, 148 insertions(+), 3 deletions(-) diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CreateShareTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CreateShareTest.java index 782c06d8..8d08dd81 100644 --- a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CreateShareTest.java +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CreateShareTest.java @@ -31,6 +31,9 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCo import com.owncloud.android.lib.resources.shares.ShareType; import com.owncloud.android.lib.test_project.TestActivity; +/** + * Test Create Share: the server must support SHARE API + */ public class CreateShareTest extends RemoteTest { private static final String LOG_TAG = CreateShareTest.class.getCanonicalName(); @@ -38,15 +41,20 @@ public class CreateShareTest extends RemoteTest { /* File to share.*/ private static final String FILE_TO_SHARE = "/fileToShare.txt"; + /* Non-existent file*/ + private static final String NON_EXISTENT_FILE = "/nonExistentFile.txt"; + private TestActivity mActivity; private String mFullPath2FileToShare; + private String mFullPath2NonExistentFile; @Override protected void setUp() throws Exception { super.setUp(); setActivityInitialTouchMode(false); mActivity = getActivity(); - mFullPath2FileToShare = mBaseFolderPath + FILE_TO_SHARE; + mFullPath2FileToShare = mBaseFolderPath + FILE_TO_SHARE; + mFullPath2NonExistentFile = mBaseFolderPath + NON_EXISTENT_FILE; File textFile = mActivity.extractAsset(TestActivity.ASSETS__TEXT_FILE_NAME); RemoteOperationResult result = mActivity.uploadFile( @@ -57,11 +65,13 @@ public class CreateShareTest extends RemoteTest { Utils.logAndThrow(LOG_TAG, result); } } - + /** - * Test Create Share: the server must support SHARE API + * Test creation of public shares */ public void testCreatePublicShare() { + + /// Successful cases RemoteOperationResult result = mActivity.createShare( mFullPath2FileToShare, ShareType.PUBLIC_LINK, @@ -70,6 +80,141 @@ public class CreateShareTest extends RemoteTest { "", 1); assertTrue(result.isSuccess()); + + /// Failed cases + + // file doesn't exist + result = mActivity.createShare( + mFullPath2NonExistentFile, + ShareType.PUBLIC_LINK, + "", + false, + "", + 1); + assertFalse(result.isSuccess()); + assertEquals( + RemoteOperationResult.ResultCode.SHARE_NOT_FOUND, + result.getCode() + ); + assertTrue( // error message from server as part of the result + result.getData().size() == 1 && + result.getData().get(0) instanceof String + ); + + } + + + /** + * Test creation of private shares with groups + */ + public void testCreatePrivateShareWithUser() { + + /// Successful cases + RemoteOperationResult result = mActivity.createShare( + mFullPath2FileToShare, + ShareType.USER, + "admin", + false, + "", + 31); + assertTrue(result.isSuccess()); + + + /// Failed cases + + // sharee doesn't exist + result = mActivity.createShare( + mFullPath2FileToShare, + ShareType.USER, + "no_exist", + false, + "", + 31); + assertFalse(result.isSuccess()); + assertEquals( + RemoteOperationResult.ResultCode.SHARE_WRONG_PARAMETER, + result.getCode() + ); + assertTrue( // error message from server as part of the result + result.getData().size() == 1 && + result.getData().get(0) instanceof String + ); + + // file doesn't exist + result = mActivity.createShare( + mFullPath2NonExistentFile, + ShareType.USER, + "admin", + false, + "", + 31); + assertFalse(result.isSuccess()); + assertEquals( + RemoteOperationResult.ResultCode.SHARE_NOT_FOUND, + result.getCode() + ); + assertTrue( // error message from server as part of the result + result.getData().size() == 1 && + result.getData().get(0) instanceof String + ); + + } + + + /** + * Test creation of private shares with groups + */ + public void testCreatePrivateShareWithGroup() { + + /// Successful cases + RemoteOperationResult result = mActivity.createShare( + mFullPath2FileToShare, + ShareType.GROUP, + "admin", + false, + "", + 1); + assertTrue(result.isSuccess()); + + + /// Failed cases + + // sharee doesn't exist + result = mActivity.createShare( + mFullPath2FileToShare, + ShareType.GROUP, + "no_exist", + false, + "", + 31); + assertFalse(result.isSuccess()); + assertEquals( + RemoteOperationResult.ResultCode.SHARE_WRONG_PARAMETER, + result.getCode() + ); + assertTrue( // error message from server as part of the result + result.getData().size() == 1 && + result.getData().get(0) instanceof String + ); + + // file doesn't exist + result = mActivity.createShare( + mFullPath2NonExistentFile, + ShareType.GROUP, + "admin", + false, + "", + 31); + assertFalse(result.isSuccess()); + assertEquals( + RemoteOperationResult.ResultCode.SHARE_NOT_FOUND, + result.getCode() + ); + assertTrue( // error message from server as part of the result + result.getData().size() == 1 && + result.getData().get(0) instanceof String + ); + } From b89246a6566c56c9ec8895ca952d1326de223697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Tue, 10 Nov 2015 16:54:59 +0100 Subject: [PATCH 085/101] Enable push job only on master --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index d12be4a9..438c227e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,10 @@ android: components: - build-tools-22.0.1 - android-19 +branches: + only: + - master + before_install: - echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI -c 20M From 92b13d24140cb26e5a200b513e200a261b33ae00 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 4 Nov 2015 21:18:29 +0100 Subject: [PATCH 086/101] Run Coverity on library Limit to coverity_scan branch --- .travis.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.travis.yml b/.travis.yml index 438c227e..04831290 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,5 +28,18 @@ env: - secure: a21NrzTCQnkTKtRGo7B1lyF2WWbpBT2N64V2Tf+oUcRLOUx3XM/mDi60mAdGd0WXV9tHD8GGmu0tQ7LGZ2VsIxixVxjzEYwX4HRTodewYez6WxBMjVEHHy+3jmc1zU4k3AAqr+uW7L4BKa5r9tH+nq9ecJMDMgW8o9MKXuP7Vso= - secure: UVnaC5Qzat2C8WlMMb8aycz1ChZKjP8Kz89qBbVcqYK+PLAGKpUNxFa39/2oA5jkMyyOcXYC9bX1ZYzHLH7nJ8LbQgaxXMT4gvgvN0l6KezjDavIW60idD9BbugkwzNj/cjoU/DdxBykPsTn4vSRaESVNTdEbM27YU4FBPzTANY= - secure: XEQY8s7p65lWWOuKbVDdTh6ZJtRTJ74Zw3H/+2Ms6vjZhFZsdUJjGo66LW6YvlhmYDXgiPB9piYQGcrGgT3hXJwXoge6n1pdixnV250J0T0dIZMbXYTWTARxDsyq48+LgUuF3pgqvqDWhBcemrePWv48q7fs/mwzuFSOyc8QwLk= + # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created + # via the "travis encrypt" command using the project repo's public key + - secure: "epTZ0zZGDbHL3o6vSC9uNkZsi5j5SA6O/tvQBH7QW/dluuzIJxIjfhNbZHDyBReYDleirLzUFQpdWAUdvulCMLs/qZdIzFGlYXZSpxEnvPYMGQcilwADdJcxLw8L+3+ET5hSexxhjrTGw427IljkqGUpqQTxaLwFdFu98lDWSbc=" matrix: - ANDROID_TARGET=android-19 ANDROID_ABI=armeabi-v7a + +addons: + coverity_scan: + project: + name: "owncloud/android-library" + description: "Build submitted via Travis CI" + notification_email: lukas@owncloud.com + build_command_prepend: "gradle clean" + build_command: "gradle build" + branch_pattern: "coverity_scan" From 75581c18a4cecbd7a43d3adfbcc12670d661554c Mon Sep 17 00:00:00 2001 From: masensio Date: Fri, 30 Oct 2015 11:05:03 +0100 Subject: [PATCH 087/101] Read capabilities to show the Share Options --- .../common/operations/RemoteOperation.java | 4 +- .../shares/GetRemoteShareOperation.java | 1 - .../GetRemoteSharesForFileOperation.java | 1 - .../shares/GetRemoteSharesOperation.java | 2 - .../status/CapabilityBooleanType.java | 83 +++++ .../GetRemoteCapabilitiesOperation.java | 281 +++++++++++++++++ .../lib/resources/status/OCCapability.java | 291 ++++++++++++++++++ .../lib/resources/status/OwnCloudVersion.java | 6 + .../test/GetCapabilitiesTest.java | 145 +++++++++ 9 files changed, 808 insertions(+), 6 deletions(-) create mode 100644 src/com/owncloud/android/lib/resources/status/CapabilityBooleanType.java create mode 100644 src/com/owncloud/android/lib/resources/status/GetRemoteCapabilitiesOperation.java create mode 100644 src/com/owncloud/android/lib/resources/status/OCCapability.java create mode 100644 test_client/tests/src/com/owncloud/android/lib/test_project/test/GetCapabilitiesTest.java diff --git a/src/com/owncloud/android/lib/common/operations/RemoteOperation.java b/src/com/owncloud/android/lib/common/operations/RemoteOperation.java index c5aaeb14..cb0d6db4 100644 --- a/src/com/owncloud/android/lib/common/operations/RemoteOperation.java +++ b/src/com/owncloud/android/lib/common/operations/RemoteOperation.java @@ -24,8 +24,6 @@ package com.owncloud.android.lib.common.operations; -import java.io.IOException; - import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.AccountsException; @@ -42,6 +40,8 @@ import com.owncloud.android.lib.common.accounts.AccountUtils; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; +import java.io.IOException; + /** * Operation which execution involves one or several interactions with an ownCloud server. diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java index 9189b9f0..10d4cb1e 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java @@ -33,7 +33,6 @@ import com.owncloud.android.lib.common.utils.Log_OC; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.http.HttpStatus; - /** * Get the data about a Share resource, known its remote ID. */ diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java index 1381d272..8e9b2170 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java @@ -35,7 +35,6 @@ import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; - /** * Provide a list shares for a specific file. * The input is the full path of the desired file. diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java index acd8ca23..5681a60c 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesOperation.java @@ -34,7 +34,6 @@ import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; - /** * Get the data from the server about ALL the known shares owned by the requester. * @@ -72,7 +71,6 @@ public class GetRemoteSharesOperation extends RemoteOperation { parser.setOwnCloudVersion(client.getOwnCloudVersion()); parser.setServerBaseUri(client.getBaseUri()); result = parser.parse(response); - } else { result = new RemoteOperationResult(false, status, get.getResponseHeaders()); } diff --git a/src/com/owncloud/android/lib/resources/status/CapabilityBooleanType.java b/src/com/owncloud/android/lib/resources/status/CapabilityBooleanType.java new file mode 100644 index 00000000..55ad934e --- /dev/null +++ b/src/com/owncloud/android/lib/resources/status/CapabilityBooleanType.java @@ -0,0 +1,83 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2015 ownCloud Inc. + * @author masensio + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package com.owncloud.android.lib.resources.status; + +/** + * Enum for Boolean Type in OCCapability parameters, with values: + * -1 - Unknown + * 0 - False + * 1 - True + */ +public enum CapabilityBooleanType { + UNKNOWN (-1), + FALSE (0), + TRUE (1); + + private int value; + + CapabilityBooleanType(int value) + { + this.value = value; + } + + public int getValue() { + return value; + } + + public static CapabilityBooleanType fromValue(int value) + { + switch (value) + { + case -1: + return UNKNOWN; + case 0: + return FALSE; + case 1: + return TRUE; + } + return null; + } + + public static CapabilityBooleanType fromBooleanValue(boolean boolValue){ + if (boolValue){ + return TRUE; + } else { + return FALSE; + } + } + + public boolean isUnknown(){ + return getValue() == -1; + } + + public boolean isFalse(){ + return getValue() == 0; + } + + public boolean isTrue(){ + return getValue() == 1; + } + +}; \ No newline at end of file diff --git a/src/com/owncloud/android/lib/resources/status/GetRemoteCapabilitiesOperation.java b/src/com/owncloud/android/lib/resources/status/GetRemoteCapabilitiesOperation.java new file mode 100644 index 00000000..0b64dbf8 --- /dev/null +++ b/src/com/owncloud/android/lib/resources/status/GetRemoteCapabilitiesOperation.java @@ -0,0 +1,281 @@ +/* ownCloud Android Library is available under MIT license + * @author masensio + * Copyright (C) 2015 ownCloud Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.resources.status; + +import android.net.Uri; + +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.operations.RemoteOperation; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.utils.Log_OC; + +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.http.HttpStatus; +import org.json.JSONObject; + +import java.util.ArrayList; + +/** + * Get the Capabilities from the server + * + * Save in Result.getData in a OCCapability object + */ +public class GetRemoteCapabilitiesOperation extends RemoteOperation { + + private static final String TAG = GetRemoteCapabilitiesOperation.class.getSimpleName(); + + + // OCS Routes + private static final String OCS_ROUTE = "ocs/v1.php/cloud/capabilities"; + + // Arguments - names + private static final String PARAM_FORMAT = "format"; + + // Arguments - constant values + private static final String VALUE_FORMAT = "json"; + + // JSON Node names + private static final String NODE_OCS = "ocs"; + + private static final String NODE_META = "meta"; + + private static final String NODE_DATA = "data"; + private static final String NODE_VERSION = "version"; + + private static final String NODE_CAPABILITIES = "capabilities"; + private static final String NODE_CORE = "core"; + + private static final String NODE_FILES_SHARING = "files_sharing"; + private static final String NODE_PUBLIC = "public"; + private static final String NODE_PASSWORD = "password"; + private static final String NODE_EXPIRE_DATE = "expire_date"; + private static final String NODE_USER = "user"; + private static final String NODE_FEDERATION = "federation"; + private static final String NODE_FILES = "files"; + + private static final String PROPERTY_STATUS = "status"; + private static final String PROPERTY_STATUSCODE = "statuscode"; + private static final String PROPERTY_MESSAGE = "message"; + + private static final String PROPERTY_POLLINTERVAL = "pollinterval"; + + private static final String PROPERTY_MAJOR = "major"; + private static final String PROPERTY_MINOR = "minor"; + private static final String PROPERTY_MICRO = "micro"; + private static final String PROPERTY_STRING = "string"; + private static final String PROPERTY_EDITION = "edition"; + + private static final String PROPERTY_API_ENABLED = "api_enabled"; + private static final String PROPERTY_ENABLED = "enabled"; + private static final String PROPERTY_ENFORCED = "enforced"; + private static final String PROPERTY_DAYS = "days"; + private static final String PROPERTY_SEND_MAIL = "send_mail"; + private static final String PROPERTY_UPLOAD = "upload"; + private static final String PROPERTY_RESHARING = "resharing"; + private static final String PROPERTY_OUTGOING = "outgoing"; + private static final String PROPERTY_INCOMING = "incoming"; + + private static final String PROPERTY_BIGFILECHUNKING = "bigfilechunking"; + private static final String PROPERTY_UNDELETE = "undelete"; + private static final String PROPERTY_VERSIONING = "versioning"; + + + /** + * Constructor + * + */ + public GetRemoteCapabilitiesOperation() { + + } + + @Override + protected RemoteOperationResult run(OwnCloudClient client) { + RemoteOperationResult result = null; + int status; + GetMethod get = null; + + try { + Uri requestUri = client.getBaseUri(); + Uri.Builder uriBuilder = requestUri.buildUpon(); + uriBuilder.appendEncodedPath(OCS_ROUTE); // avoid starting "/" in this method + uriBuilder.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT); + + // Get Method + get = new GetMethod(uriBuilder.build().toString()); + get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); + + status = client.executeMethod(get); + + if(isSuccess(status)) { + String response = get.getResponseBodyAsString(); + Log_OC.d(TAG, "Successful response: " + response); + + // Parse the response + JSONObject respJSON = new JSONObject(response); + JSONObject respOCS = respJSON.getJSONObject(NODE_OCS); + JSONObject respMeta = respOCS.getJSONObject(NODE_META); + JSONObject respData = respOCS.getJSONObject(NODE_DATA); + + // Read meta + boolean statusProp = respMeta.getString(PROPERTY_STATUS).equalsIgnoreCase("ok"); + int statuscode = respMeta.getInt(PROPERTY_STATUSCODE); + String message = respMeta.getString(PROPERTY_MESSAGE); + + if (statusProp) { + ArrayList data = new ArrayList(); // For result data + OCCapability capability = new OCCapability(); + // Add Version + if (respData.has(NODE_VERSION)) { + JSONObject respVersion = respData.getJSONObject(NODE_VERSION); + capability.setVersionMayor(respVersion.getInt(PROPERTY_MAJOR)); + capability.setVersionMinor(respVersion.getInt(PROPERTY_MINOR)); + capability.setVersionMicro(respVersion.getInt(PROPERTY_MICRO)); + capability.setVersionString(respVersion.getString(PROPERTY_STRING)); + capability.setVersionEdition(respVersion.getString(PROPERTY_EDITION)); + Log_OC.d(TAG, "*** Added " + NODE_VERSION); + } + + // Capabilities Object + if (respData.has(NODE_CAPABILITIES)) { + JSONObject respCapabilities = respData.getJSONObject(NODE_CAPABILITIES); + + // Add Core: pollinterval + if (respCapabilities.has(NODE_CORE)) { + JSONObject respCore = respCapabilities.getJSONObject(NODE_CORE); + capability.setCorePollinterval(respCore.getInt(PROPERTY_POLLINTERVAL)); + Log_OC.d(TAG, "*** Added " + NODE_CORE); + } + + // Add files_sharing: public, user, resharing + if (respCapabilities.has(NODE_FILES_SHARING)) { + JSONObject respFilesSharing = respCapabilities.getJSONObject(NODE_FILES_SHARING); + if (respFilesSharing.has(PROPERTY_API_ENABLED)) { + capability.setFilesSharingApiEnabled(CapabilityBooleanType.fromBooleanValue( + respFilesSharing.getBoolean(PROPERTY_API_ENABLED))); + } + + if (respFilesSharing.has(NODE_PUBLIC)) { + JSONObject respPublic = respFilesSharing.getJSONObject(NODE_PUBLIC); + capability.setFilesSharingPublicEnabled(CapabilityBooleanType.fromBooleanValue( + respPublic.getBoolean(PROPERTY_ENABLED))); + if(respPublic.has(NODE_PASSWORD)) { + capability.setFilesSharingPublicPasswordEnforced( + CapabilityBooleanType.fromBooleanValue( + respPublic.getJSONObject(NODE_PASSWORD).getBoolean(PROPERTY_ENFORCED))); + } + if(respPublic.has(NODE_EXPIRE_DATE)){ + JSONObject respExpireDate = respPublic.getJSONObject(NODE_EXPIRE_DATE); + capability.setFilesSharingPublicExpireDateEnabled( + CapabilityBooleanType.fromBooleanValue( + respExpireDate.getBoolean(PROPERTY_ENABLED))); + if (respExpireDate.has(PROPERTY_DAYS)) { + capability.setFilesSharingPublicExpireDateDays( + respExpireDate.getInt(PROPERTY_DAYS)); + } + if (respExpireDate.has(PROPERTY_ENFORCED)) { + capability.setFilesSharingPublicExpireDateEnforced( + CapabilityBooleanType.fromBooleanValue( + respExpireDate.getBoolean(PROPERTY_ENFORCED))); + } + } + if (respPublic.has(PROPERTY_UPLOAD)){ + capability.setFilesSharingPublicUpload(CapabilityBooleanType.fromBooleanValue( + respPublic.getBoolean(PROPERTY_UPLOAD))); + } + } + + if (respFilesSharing.has(NODE_USER)) { + JSONObject respUser = respFilesSharing.getJSONObject(NODE_USER); + capability.setFilesSharingUserSendMail(CapabilityBooleanType.fromBooleanValue( + respUser.getBoolean(PROPERTY_SEND_MAIL))); + } + + capability.setFilesSharingResharing(CapabilityBooleanType.fromBooleanValue( + respFilesSharing.getBoolean(PROPERTY_RESHARING))); + if (respFilesSharing.has(NODE_FEDERATION)) { + JSONObject respFederation = respFilesSharing.getJSONObject(NODE_FEDERATION); + capability.setFilesSharingFederationOutgoing( + CapabilityBooleanType.fromBooleanValue(respFederation.getBoolean(PROPERTY_OUTGOING))); + capability.setFilesSharingFederationIncoming(CapabilityBooleanType.fromBooleanValue( + respFederation.getBoolean(PROPERTY_INCOMING))); + } + Log_OC.d(TAG, "*** Added " + NODE_FILES_SHARING); + } + + + if (respCapabilities.has(NODE_FILES)) { + JSONObject respFiles = respCapabilities.getJSONObject(NODE_FILES); + // Add files + capability.setFilesBigFileChuncking(CapabilityBooleanType.fromBooleanValue( + respFiles.getBoolean(PROPERTY_BIGFILECHUNKING))); + if (respFiles.has(PROPERTY_UNDELETE)) { + capability.setFilesUndelete(CapabilityBooleanType.fromBooleanValue( + respFiles.getBoolean(PROPERTY_UNDELETE))); + } + capability.setFilesVersioning(CapabilityBooleanType.fromBooleanValue( + respFiles.getBoolean(PROPERTY_VERSIONING))); + Log_OC.d(TAG, "*** Added " + NODE_FILES); + } + } + // Result + data.add(capability); + result = new RemoteOperationResult(true, status, get.getResponseHeaders()); + result.setData(data); + + Log_OC.d(TAG, "*** Get Capabilities completed "); + } else { + result = new RemoteOperationResult(statusProp, statuscode, null); + Log_OC.e(TAG, "Failed response while getting capabilities from the server "); + Log_OC.e(TAG, "*** status: " + statusProp + "; message: " + message); + } + + } else { + result = new RemoteOperationResult(false, status, get.getResponseHeaders()); + String response = get.getResponseBodyAsString(); + Log_OC.e(TAG, "Failed response while getting capabilities from the server "); + if (response != null) { + Log_OC.e(TAG, "*** status code: " + status + "; response message: " + response); + } else { + Log_OC.e(TAG, "*** status code: " + status); + } + } + + } catch (Exception e) { + result = new RemoteOperationResult(e); + Log_OC.e(TAG, "Exception while getting capabilities", e); + + } finally { + if (get != null) { + get.releaseConnection(); + } + } + return result; + } + + private boolean isSuccess(int status) { + return (status == HttpStatus.SC_OK); + } +} diff --git a/src/com/owncloud/android/lib/resources/status/OCCapability.java b/src/com/owncloud/android/lib/resources/status/OCCapability.java new file mode 100644 index 00000000..e69c1ce8 --- /dev/null +++ b/src/com/owncloud/android/lib/resources/status/OCCapability.java @@ -0,0 +1,291 @@ +/* ownCloud Android Library is available under MIT license + * @author masensio + * Copyright (C) 2015 ownCloud Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package com.owncloud.android.lib.resources.status; + +/** + * Contains data of the Capabilities for an account, from the Capabilities API + */ +public class OCCapability { + + private static final String TAG = OCCapability.class.getSimpleName(); + + private long mId; + private String mAccountName; + + // Server version + private int mVersionMayor; + private int mVersionMinor; + private int mVersionMicro; + private String mVersionString; + private String mVersionEdition; + + // Core PollInterval + private int mCorePollinterval; + + // Files Sharing + private CapabilityBooleanType mFilesSharingApiEnabled; + + private CapabilityBooleanType mFilesSharingPublicEnabled; + private CapabilityBooleanType mFilesSharingPublicPasswordEnforced; + private CapabilityBooleanType mFilesSharingPublicExpireDateEnabled; + private int mFilesSharingPublicExpireDateDays; + private CapabilityBooleanType mFilesSharingPublicExpireDateEnforced; + private CapabilityBooleanType mFilesSharingPublicSendMail; + private CapabilityBooleanType mFilesSharingPublicUpload; + + private CapabilityBooleanType mFilesSharingUserSendMail; + + private CapabilityBooleanType mFilesSharingResharing; + + private CapabilityBooleanType mFilesSharingFederationOutgoing; + private CapabilityBooleanType mFilesSharingFederationIncoming; + + // Files + private CapabilityBooleanType mFilesBigFileChuncking; + private CapabilityBooleanType mFilesUndelete; + private CapabilityBooleanType mFilesVersioning; + + public OCCapability(){ + mId = 0; + mAccountName = ""; + + mVersionMayor = 0; + mVersionMinor = 0; + mVersionMicro = 0; + mVersionString = ""; + mVersionString = ""; + + mCorePollinterval = 0; + + mFilesSharingApiEnabled = CapabilityBooleanType.UNKNOWN; + mFilesSharingPublicEnabled = CapabilityBooleanType.UNKNOWN; + mFilesSharingPublicPasswordEnforced = CapabilityBooleanType.UNKNOWN; + mFilesSharingPublicExpireDateEnabled = CapabilityBooleanType.UNKNOWN; + mFilesSharingPublicExpireDateDays = 0; + mFilesSharingPublicExpireDateEnforced = CapabilityBooleanType.UNKNOWN; + mFilesSharingPublicSendMail = CapabilityBooleanType.UNKNOWN; + mFilesSharingPublicUpload = CapabilityBooleanType.UNKNOWN; + mFilesSharingUserSendMail = CapabilityBooleanType.UNKNOWN; + mFilesSharingResharing = CapabilityBooleanType.UNKNOWN; + mFilesSharingFederationOutgoing = CapabilityBooleanType.UNKNOWN; + mFilesSharingFederationIncoming = CapabilityBooleanType.UNKNOWN; + + mFilesBigFileChuncking = CapabilityBooleanType.UNKNOWN; + mFilesUndelete = CapabilityBooleanType.UNKNOWN; + mFilesVersioning = CapabilityBooleanType.UNKNOWN; + } + + + // Getters and Setters + public String getAccountName() { + return mAccountName; + } + + public void setAccountName(String accountName) { + this.mAccountName = accountName; + } + + public long getId() { + return mId; + } + + public void setId(long id) { + this.mId = id; + } + + public int getVersionMayor() { + return mVersionMayor; + } + + public void setVersionMayor(int versionMayor) { + this.mVersionMayor = versionMayor; + } + + public int getVersionMinor() { + return mVersionMinor; + } + + public void setVersionMinor(int versionMinor) { + this.mVersionMinor = versionMinor; + } + + public int getVersionMicro() { + return mVersionMicro; + } + + public void setVersionMicro(int versionMicro) { + this.mVersionMicro = versionMicro; + } + + public String getVersionString() { + return mVersionString; + } + + public void setVersionString(String versionString) { + this.mVersionString = versionString; + } + + public String getVersionEdition() { + return mVersionEdition; + } + + public void setVersionEdition(String versionEdition) { + this.mVersionEdition = versionEdition; + } + + + public int getCorePollinterval() { + return mCorePollinterval; + } + + public void setCorePollinterval(int corePollinterval) { + this.mCorePollinterval = corePollinterval; + } + + public CapabilityBooleanType getFilesSharingApiEnabled() { + return mFilesSharingApiEnabled; + } + + public void setFilesSharingApiEnabled(CapabilityBooleanType filesSharingApiEnabled) { + this.mFilesSharingApiEnabled = filesSharingApiEnabled; + } + + public CapabilityBooleanType getFilesSharingPublicEnabled() { + return mFilesSharingPublicEnabled; + } + + public void setFilesSharingPublicEnabled(CapabilityBooleanType filesSharingPublicEnabled) { + this.mFilesSharingPublicEnabled = filesSharingPublicEnabled; + } + + public CapabilityBooleanType getFilesSharingPublicPasswordEnforced() { + return mFilesSharingPublicPasswordEnforced; + } + + public void setFilesSharingPublicPasswordEnforced(CapabilityBooleanType filesSharingPublicPasswordEnforced) { + this.mFilesSharingPublicPasswordEnforced = filesSharingPublicPasswordEnforced; + } + + public CapabilityBooleanType getFilesSharingPublicExpireDateEnabled() { + return mFilesSharingPublicExpireDateEnabled; + } + + public void setFilesSharingPublicExpireDateEnabled(CapabilityBooleanType filesSharingPublicExpireDateEnabled) { + this.mFilesSharingPublicExpireDateEnabled = filesSharingPublicExpireDateEnabled; + } + + public int getFilesSharingPublicExpireDateDays() { + return mFilesSharingPublicExpireDateDays; + } + + public void setFilesSharingPublicExpireDateDays(int filesSharingPublicExpireDateDays) { + this.mFilesSharingPublicExpireDateDays = filesSharingPublicExpireDateDays; + } + + public CapabilityBooleanType getFilesSharingPublicExpireDateEnforced() { + return mFilesSharingPublicExpireDateEnforced; + } + + public void setFilesSharingPublicExpireDateEnforced(CapabilityBooleanType filesSharingPublicExpireDateEnforced) { + this.mFilesSharingPublicExpireDateEnforced = filesSharingPublicExpireDateEnforced; + } + + + public CapabilityBooleanType getFilesSharingPublicSendMail() { + return mFilesSharingPublicSendMail; + } + + public void setFilesSharingPublicSendMail(CapabilityBooleanType filesSharingPublicSendMail) { + this.mFilesSharingPublicSendMail = filesSharingPublicSendMail; + } + + public CapabilityBooleanType getFilesSharingPublicUpload() { + return mFilesSharingPublicUpload; + } + + public void setFilesSharingPublicUpload(CapabilityBooleanType filesSharingPublicUpload) { + this.mFilesSharingPublicUpload = filesSharingPublicUpload; + } + + public CapabilityBooleanType getFilesSharingUserSendMail() { + return mFilesSharingUserSendMail; + } + + public void setFilesSharingUserSendMail(CapabilityBooleanType filesSharingUserSendMail) { + this.mFilesSharingUserSendMail = filesSharingUserSendMail; + } + + public CapabilityBooleanType getFilesSharingResharing() { + return mFilesSharingResharing; + } + + public void setFilesSharingResharing(CapabilityBooleanType filesSharingResharing) { + this.mFilesSharingResharing = filesSharingResharing; + } + + public CapabilityBooleanType getFilesSharingFederationOutgoing() { + return mFilesSharingFederationOutgoing; + } + + public void setFilesSharingFederationOutgoing(CapabilityBooleanType filesSharingFederationOutgoing) { + this.mFilesSharingFederationOutgoing = filesSharingFederationOutgoing; + } + + public CapabilityBooleanType getFilesSharingFederationIncoming() { + return mFilesSharingFederationIncoming; + } + + public void setFilesSharingFederationIncoming(CapabilityBooleanType filesSharingFederationIncoming) { + this.mFilesSharingFederationIncoming = filesSharingFederationIncoming; + } + + public CapabilityBooleanType getFilesBigFileChuncking() { + return mFilesBigFileChuncking; + } + + public void setFilesBigFileChuncking(CapabilityBooleanType filesBigFileChuncking) { + this.mFilesBigFileChuncking = filesBigFileChuncking; + } + + public CapabilityBooleanType getFilesUndelete() { + return mFilesUndelete; + } + + public void setFilesUndelete(CapabilityBooleanType filesUndelete) { + this.mFilesUndelete = filesUndelete; + } + + public CapabilityBooleanType getFilesVersioning() { + return mFilesVersioning; + } + + public void setFilesVersioning(CapabilityBooleanType filesVersioning) { + this.mFilesVersioning = filesVersioning; + } + + + + +} diff --git a/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java b/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java index 8c30c7ab..9607cdc9 100644 --- a/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java +++ b/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java @@ -46,6 +46,8 @@ public class OwnCloudVersion implements Comparable { public static final int MINIMUM_VERSION_FOR_SEARCHING_USERS = 0x08020000; //8.2 public static final int VERSION_8 = 0x08000000; // 8.0 + + public static final int MINIMUM_VERSION_CAPABILITIES_API = 0x08010000; // 8.1 private static final int MAX_DOTS = 3; @@ -144,6 +146,10 @@ public class OwnCloudVersion implements Comparable { public boolean isSearchUsersSupported() { return (mVersion >= MINIMUM_VERSION_FOR_SEARCHING_USERS); } + + public boolean isVersionWithCapabilitiesAPI(){ + return (mVersion>= MINIMUM_VERSION_CAPABILITIES_API); + } } diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/GetCapabilitiesTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/GetCapabilitiesTest.java new file mode 100644 index 00000000..b00435e1 --- /dev/null +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/GetCapabilitiesTest.java @@ -0,0 +1,145 @@ +/* ownCloud Android Library is available under MIT license + * @author masensio + * Copyright (C) 2015 ownCloud Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.test_project.test; + +import java.security.GeneralSecurityException; + +import junit.framework.AssertionFailedError; + +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; + +import android.content.Context; +import android.net.Uri; +import android.util.Log; + +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.OwnCloudClientFactory; +import com.owncloud.android.lib.common.OwnCloudCredentialsFactory; +import com.owncloud.android.lib.common.network.NetworkUtils; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.resources.status.GetRemoteCapabilitiesOperation; +import com.owncloud.android.lib.test_project.R; +import com.owncloud.android.lib.test_project.SelfSignedConfidentSslSocketFactory; + +/** + * Class to test GetRemoteCapabilitiesOperation + * + */ +public class GetCapabilitiesTest extends RemoteTest { + private static final String LOG_TAG = GetCapabilitiesTest.class.getCanonicalName(); + + String mServerUri, mUser, mPass; + OwnCloudClient mClient = null; + + public GetCapabilitiesTest() { + super(); + + Protocol pr = Protocol.getProtocol("https"); + if (pr == null || !(pr.getSocketFactory() instanceof SelfSignedConfidentSslSocketFactory)) { + try { + ProtocolSocketFactory psf = new SelfSignedConfidentSslSocketFactory(); + Protocol.registerProtocol( + "https", + new Protocol("https", psf, 443)); + + } catch (GeneralSecurityException e) { + throw new AssertionFailedError( + "Self-signed confident SSL context could not be loaded"); + } + } + + } + + + protected Context getContext() { + return getActivity(); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + // Next initialization cannot be done in the constructor because getContext() is not + // ready yet, returns NULL. + initAccessToServer(getContext()); + + Log.v(LOG_TAG, "Setting up the remote fixture..."); + + Log.v(LOG_TAG, "Remote fixture created."); + + } + + + // Tests + /** + * Test get capabilities + * + * Requires OC server 8.1 or later + */ + public void testGetRemoteCapabilitiesOperation() { + // get capabilities + GetRemoteCapabilitiesOperation getCapabilitiesOperation = new GetRemoteCapabilitiesOperation(); + RemoteOperationResult result = getCapabilitiesOperation.execute(mClient); + assertTrue(result.isSuccess()); + assertTrue(result.getData() != null && result.getData().size() == 1); + + } + + @Override + protected void tearDown() throws Exception { + Log.v(LOG_TAG, "Deleting remote fixture..."); + super.tearDown(); + Log.v(LOG_TAG, "Remote fixture delete."); + } + + + private void initAccessToServer(Context context) { + Log.v(LOG_TAG, "Setting up client instance to access OC server..."); + + mServerUri = context.getString(R.string.server_base_url); + mUser = context.getString(R.string.username); + mPass = context.getString(R.string.password); + + mClient = new OwnCloudClient( + Uri.parse(mServerUri), + NetworkUtils.getMultiThreadedConnManager() + ); + mClient.setDefaultTimeouts( + OwnCloudClientFactory.DEFAULT_DATA_TIMEOUT, + OwnCloudClientFactory.DEFAULT_CONNECTION_TIMEOUT); + mClient.setFollowRedirects(true); + mClient.setCredentials( + OwnCloudCredentialsFactory.newBasicCredentials( + mUser, + mPass + ) + ); + + Log.v(LOG_TAG, "Client instance set up."); + + } +} From 0238e51903d94a120ac5d56cf0adf68d0860eec3 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Tue, 3 Nov 2015 16:46:44 +0100 Subject: [PATCH 088/101] Prevent null values in OCShare members --- .../android/lib/resources/shares/OCShare.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/shares/OCShare.java b/src/com/owncloud/android/lib/resources/shares/OCShare.java index 644955cc..9135978e 100644 --- a/src/com/owncloud/android/lib/resources/shares/OCShare.java +++ b/src/com/owncloud/android/lib/resources/shares/OCShare.java @@ -86,17 +86,17 @@ public class OCShare implements Parcelable, Serializable { mFileSource = 0; mItemSource = 0; mShareType = ShareType.NO_SHARED; - mShareWith = null; - mPath = null; + mShareWith = ""; + mPath = ""; mPermissions = -1; mSharedDate = 0; mExpirationDate = 0; - mToken = null; - mSharedWithDisplayName = null; + mToken = ""; + mSharedWithDisplayName = ""; mIsFolder = false; mUserId = -1; mIdRemoteShared = -1; - mShareLink = null; + mShareLink = ""; } /// Getters and Setters @@ -138,7 +138,7 @@ public class OCShare implements Parcelable, Serializable { } public void setShareWith(String shareWith) { - this.mShareWith = shareWith; + this.mShareWith = (shareWith != null) ? shareWith : ""; } public String getPath() { @@ -146,7 +146,7 @@ public class OCShare implements Parcelable, Serializable { } public void setPath(String path) { - this.mPath = path; + this.mPath = (path != null) ? path : ""; } public int getPermissions() { @@ -178,7 +178,7 @@ public class OCShare implements Parcelable, Serializable { } public void setToken(String token) { - this.mToken = token; + this.mToken = (token != null) ? token : ""; } public String getSharedWithDisplayName() { @@ -186,7 +186,7 @@ public class OCShare implements Parcelable, Serializable { } public void setSharedWithDisplayName(String sharedWithDisplayName) { - this.mSharedWithDisplayName = sharedWithDisplayName; + this.mSharedWithDisplayName = (sharedWithDisplayName != null) ? sharedWithDisplayName : ""; } public boolean isFolder() { @@ -218,7 +218,7 @@ public class OCShare implements Parcelable, Serializable { } public void setShareLink(String shareLink) { - this.mShareLink = shareLink; + this.mShareLink = (shareLink != null) ? shareLink : ""; } /** From 90615fc4ab7399d1436e8d2a9df01c05b795a808 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Thu, 5 Nov 2015 13:10:58 +0100 Subject: [PATCH 089/101] Added operation to update properties of exising share via link --- .../shares/CreateRemoteShareOperation.java | 2 +- .../android/lib/resources/shares/OCShare.java | 20 ++- .../lib/resources/shares/ShareXMLParser.java | 4 +- .../shares/UpdateRemoteShareOperation.java | 153 ++++++++++++++++++ .../test_project/test/RemoveShareTest.java | 2 +- 5 files changed, 169 insertions(+), 12 deletions(-) create mode 100644 src/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.java diff --git a/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java index 21545222..39fab768 100644 --- a/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.java @@ -147,7 +147,7 @@ public class CreateRemoteShareOperation extends RemoteOperation { // retrieve more info - POST only returns the index of the new share OCShare emptyShare = (OCShare) result.getData().get(0); GetRemoteShareOperation getInfo = new GetRemoteShareOperation( - emptyShare.getIdRemoteShared() + emptyShare.getRemoteId() ); result = getInfo.execute(client); } diff --git a/src/com/owncloud/android/lib/resources/shares/OCShare.java b/src/com/owncloud/android/lib/resources/shares/OCShare.java index 9135978e..347bd1ae 100644 --- a/src/com/owncloud/android/lib/resources/shares/OCShare.java +++ b/src/com/owncloud/android/lib/resources/shares/OCShare.java @@ -61,7 +61,7 @@ public class OCShare implements Parcelable, Serializable { private String mSharedWithDisplayName; private boolean mIsFolder; private long mUserId; - private long mIdRemoteShared; + private long mRemoteId; private String mShareLink; public OCShare() { @@ -95,7 +95,7 @@ public class OCShare implements Parcelable, Serializable { mSharedWithDisplayName = ""; mIsFolder = false; mUserId = -1; - mIdRemoteShared = -1; + mRemoteId = -1; mShareLink = ""; } @@ -205,12 +205,12 @@ public class OCShare implements Parcelable, Serializable { this.mUserId = userId; } - public long getIdRemoteShared() { - return mIdRemoteShared; + public long getRemoteId() { + return mRemoteId; } - public void setIdRemoteShared(long idRemoteShared) { - this.mIdRemoteShared = idRemoteShared; + public void setIdRemoteShared(long remoteId) { + this.mRemoteId = remoteId; } public String getShareLink() { @@ -220,6 +220,10 @@ public class OCShare implements Parcelable, Serializable { public void setShareLink(String shareLink) { this.mShareLink = (shareLink != null) ? shareLink : ""; } + + public boolean isPasswordProtected() { + return ShareType.PUBLIC_LINK.equals(mShareType) && mShareWith.length() > 0; + } /** * Parcelable Methods @@ -264,7 +268,7 @@ public class OCShare implements Parcelable, Serializable { mSharedWithDisplayName = source.readString(); mIsFolder = source.readInt() == 0; mUserId = source.readLong(); - mIdRemoteShared = source.readLong(); + mRemoteId = source.readLong(); mShareLink = source.readString(); } @@ -290,7 +294,7 @@ public class OCShare implements Parcelable, Serializable { dest.writeString(mSharedWithDisplayName); dest.writeInt(mIsFolder ? 1 : 0); dest.writeLong(mUserId); - dest.writeLong(mIdRemoteShared); + dest.writeLong(mRemoteId); dest.writeString(mShareLink); } diff --git a/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java b/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java index e672deeb..f8b8cb00 100644 --- a/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java +++ b/src/com/owncloud/android/lib/resources/shares/ShareXMLParser.java @@ -82,7 +82,7 @@ public class ShareXMLParser { private static final String TYPE_FOLDER = "folder"; private static final int SUCCESS = 100; - private static final int ERROR_WRONG_PARAMETER = 403; + private static final int ERROR_WRONG_PARAMETER = 400; private static final int ERROR_FORBIDDEN = 403; private static final int ERROR_NOT_FOUND = 404; @@ -368,7 +368,7 @@ public class ShareXMLParser { } private boolean isValidShare(OCShare share) { - return (share.getIdRemoteShared() > -1); + return (share.getRemoteId() > -1); } private void fixPathForFolder(OCShare share) { diff --git a/src/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.java new file mode 100644 index 00000000..0d4fba1f --- /dev/null +++ b/src/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.java @@ -0,0 +1,153 @@ +/* ownCloud Android Library is available under MIT license + * @author David A. Velasco + * Copyright (C) 2015 ownCloud Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.resources.shares; + + import android.net.Uri; + import android.util.Pair; + + import com.owncloud.android.lib.common.OwnCloudClient; + import com.owncloud.android.lib.common.operations.RemoteOperation; + import com.owncloud.android.lib.common.operations.RemoteOperationResult; + import com.owncloud.android.lib.common.utils.Log_OC; + + import org.apache.commons.httpclient.methods.PutMethod; + import org.apache.commons.httpclient.methods.StringRequestEntity; + import org.apache.http.HttpStatus; + + import java.util.ArrayList; + import java.util.List; + + +/** + * Updates parameters of an existing Share resource, known its remote ID. + * + * Allow updating several parameters, triggering a request to the server per parameter. + */ + +public class UpdateRemoteShareOperation extends RemoteOperation { + + private static final String TAG = GetRemoteShareOperation.class.getSimpleName(); + + private long mRemoteId; + + private String mPassword; + + + public UpdateRemoteShareOperation(long remoteId) { + mRemoteId = remoteId; + mPassword = null; + } + + + @Override + protected RemoteOperationResult run(OwnCloudClient client) { + RemoteOperationResult result = null; + int status = -1; + + /// prepare array of parameters to update + List> parametersToUpdate = new ArrayList>(); + if (mPassword != null) { + parametersToUpdate.add(new Pair("password", mPassword)); + } + /* TODO complete rest of parameters + if (mPermissions > 0) { + parametersToUpdate.add(new Pair("permissions", Integer.toString(mPermissions))); + } + if (mPublicUpload != null) { + parametersToUpdate.add(new Pair("publicUpload", mPublicUpload.toString()); + } + + if (mExpireDate != null) { + parametersToUpdate.add(new Pair("expireData", mExpireData.toString())); + } + */ + + /// perform required PUT requests + PutMethod put = null; + + try{ + Uri requestUri = client.getBaseUri(); + Uri.Builder uriBuilder = requestUri.buildUpon(); + uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH.substring(1)); + uriBuilder.appendEncodedPath(Long.toString(mRemoteId)); + + for (Pair parameter : parametersToUpdate) { + if (put != null) { + put.releaseConnection(); + } + // TODO check if uriBuilder may be reused + String uriString = uriBuilder.build().toString(); + put = new PutMethod(uriString); + put.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); + put.setRequestEntity(new StringRequestEntity( + parameter.first + "=" + parameter.second, + "application/x-www-form-urlencoded", + "UTF-8" + )); + + status = client.executeMethod(put); + + if (status == HttpStatus.SC_OK) { + String response = put.getResponseBodyAsString(); + + // Parse xml response + ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser( + new ShareXMLParser() + ); + parser.setOwnCloudVersion(client.getOwnCloudVersion()); + parser.setServerBaseUri(client.getBaseUri()); + result = parser.parse(response); + + } else { + result = new RemoteOperationResult(false, status, put.getResponseHeaders()); + } + } + + } catch (Exception e) { + result = new RemoteOperationResult(e); + Log_OC.e(TAG, "Exception while updating remote share ", e); + if (put != null) { + put.releaseConnection(); + } + + } finally { + if (put != null) { + put.releaseConnection(); + } + } + return result; + } + + /** + * Set password to update in Share resource. + * + * @param password Password to set to the target share. The empty string clears the password. + * Null results in no update applied to the password. + */ + public void setPassword(String password) { + mPassword = password; + } +} diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/RemoveShareTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/RemoveShareTest.java index 61a5ecd0..64653861 100644 --- a/test_client/tests/src/com/owncloud/android/lib/test_project/test/RemoveShareTest.java +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/RemoveShareTest.java @@ -65,7 +65,7 @@ public class RemoveShareTest extends RemoteTest { Utils.logAndThrow(LOG_TAG, result); } else { OCShare created = (OCShare) result.getData().get(0); - mShareId = created.getIdRemoteShared(); + mShareId = created.getRemoteId(); } } From 206c7abf1052a02b37219d14e8cf6510a11637e1 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Fri, 6 Nov 2015 22:49:26 +0100 Subject: [PATCH 090/101] Fixed unit tests --- .../android/lib/test_project/test/CreateShareTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CreateShareTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CreateShareTest.java index 8d08dd81..ccc25089 100644 --- a/test_client/tests/src/com/owncloud/android/lib/test_project/test/CreateShareTest.java +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/CreateShareTest.java @@ -132,7 +132,7 @@ public class CreateShareTest extends RemoteTest { 31); assertFalse(result.isSuccess()); assertEquals( - RemoteOperationResult.ResultCode.SHARE_WRONG_PARAMETER, + RemoteOperationResult.ResultCode.SHARE_FORBIDDEN, result.getCode() ); assertTrue( // error message from server as part of the result @@ -189,7 +189,7 @@ public class CreateShareTest extends RemoteTest { 31); assertFalse(result.isSuccess()); assertEquals( - RemoteOperationResult.ResultCode.SHARE_WRONG_PARAMETER, + RemoteOperationResult.ResultCode.SHARE_FORBIDDEN, result.getCode() ); assertTrue( // error message from server as part of the result From f6bd45b2a78f4d18152d8ee272750505f5a29857 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Thu, 12 Nov 2015 14:39:05 +0100 Subject: [PATCH 091/101] Added support to update expiration date in an existing share --- .../shares/UpdateRemoteShareOperation.java | 85 ++++++++++++++----- 1 file changed, 66 insertions(+), 19 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.java index 0d4fba1f..aa6ae537 100644 --- a/src/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.java @@ -37,7 +37,10 @@ package com.owncloud.android.lib.resources.shares; import org.apache.commons.httpclient.methods.StringRequestEntity; import org.apache.http.HttpStatus; + import java.text.DateFormat; + import java.text.SimpleDateFormat; import java.util.ArrayList; + import java.util.Calendar; import java.util.List; @@ -51,14 +54,57 @@ public class UpdateRemoteShareOperation extends RemoteOperation { private static final String TAG = GetRemoteShareOperation.class.getSimpleName(); + private static final String PARAM_PASSWORD = "password"; + private static final String PARAM_EXPIRATION_DATE = "expireDate"; + private static final String FORMAT_EXPIRATION_DATE = "yyyy-MM-dd"; + private static final String ENTITY_CONTENT_TYPE = "application/x-www-form-urlencoded"; + private static final String ENTITY_CHARSET = "UTF-8"; + + + /** Identifier of the share to update */ private long mRemoteId; + /** Password to set for the public link */ private String mPassword; + /** Expiration date to set for the public link */ + private long mExpirationDateInMillis; + + /** + * Constructor. No update is initialized by default, need to be applied with setters below. + * + * @param remoteId Identifier of the share to update. + */ public UpdateRemoteShareOperation(long remoteId) { mRemoteId = remoteId; - mPassword = null; + mPassword = null; // no update + mExpirationDateInMillis = 0; // no update + } + + + /** + * Set password to update in Share resource. + * + * @param password Password to set to the target share. + * Empty string clears the current password. + * Null results in no update applied to the password. + */ + public void setPassword(String password) { + mPassword = password; + } + + + /** + * Set expiration date to update in Share resource. + * + * @param expirationDateInMillis Expiration date to set to the public link. + * A negative value clears the current expiration date. + * Zero value (start-of-epoch) results in no update done on + * the expiration date. + */ + public void setExpirationDate(long expirationDateInMillis) { + mExpirationDateInMillis = expirationDateInMillis; } @@ -70,8 +116,22 @@ public class UpdateRemoteShareOperation extends RemoteOperation { /// prepare array of parameters to update List> parametersToUpdate = new ArrayList>(); if (mPassword != null) { - parametersToUpdate.add(new Pair("password", mPassword)); + parametersToUpdate.add(new Pair(PARAM_PASSWORD, mPassword)); } + if (mExpirationDateInMillis < 0) { + // clear expiration date + parametersToUpdate.add(new Pair(PARAM_EXPIRATION_DATE, "")); + + } else if (mExpirationDateInMillis > 0) { + // set expiration date + DateFormat dateFormat = new SimpleDateFormat(FORMAT_EXPIRATION_DATE); + Calendar expirationDate = Calendar.getInstance(); + expirationDate.setTimeInMillis(mExpirationDateInMillis); + String formattedExpirationDate = dateFormat.format(expirationDate.getTime()); + parametersToUpdate.add(new Pair(PARAM_EXPIRATION_DATE, formattedExpirationDate)); + + } // else, ignore - no update + /* TODO complete rest of parameters if (mPermissions > 0) { parametersToUpdate.add(new Pair("permissions", Integer.toString(mPermissions))); @@ -79,33 +139,29 @@ public class UpdateRemoteShareOperation extends RemoteOperation { if (mPublicUpload != null) { parametersToUpdate.add(new Pair("publicUpload", mPublicUpload.toString()); } - - if (mExpireDate != null) { - parametersToUpdate.add(new Pair("expireData", mExpireData.toString())); - } */ /// perform required PUT requests PutMethod put = null; + String uriString = null; try{ Uri requestUri = client.getBaseUri(); Uri.Builder uriBuilder = requestUri.buildUpon(); uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH.substring(1)); uriBuilder.appendEncodedPath(Long.toString(mRemoteId)); + uriString = uriBuilder.build().toString(); for (Pair parameter : parametersToUpdate) { if (put != null) { put.releaseConnection(); } - // TODO check if uriBuilder may be reused - String uriString = uriBuilder.build().toString(); put = new PutMethod(uriString); put.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); put.setRequestEntity(new StringRequestEntity( parameter.first + "=" + parameter.second, - "application/x-www-form-urlencoded", - "UTF-8" + ENTITY_CONTENT_TYPE, + ENTITY_CHARSET )); status = client.executeMethod(put); @@ -141,13 +197,4 @@ public class UpdateRemoteShareOperation extends RemoteOperation { return result; } - /** - * Set password to update in Share resource. - * - * @param password Password to set to the target share. The empty string clears the password. - * Null results in no update applied to the password. - */ - public void setPassword(String password) { - mPassword = password; - } } From 1e3060633d2f792c07877f0621ab4301e9eee6d5 Mon Sep 17 00:00:00 2001 From: masensio Date: Thu, 19 Nov 2015 18:10:43 +0100 Subject: [PATCH 092/101] Add test for UpdateRemoteShareOperation --- .../test_project/test/UpdateShareTest.java | 241 ++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdateShareTest.java diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdateShareTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdateShareTest.java new file mode 100644 index 00000000..389146b5 --- /dev/null +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdateShareTest.java @@ -0,0 +1,241 @@ +/* ownCloud Android Library is available under MIT license + * @author masensio + * Copyright (C) 2015 ownCloud Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.test_project.test; + +import java.io.File; +import java.security.GeneralSecurityException; +import java.util.Calendar; + +import junit.framework.AssertionFailedError; + +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; + +import android.content.Context; +import android.net.Uri; +import android.util.Log; + +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.OwnCloudClientFactory; +import com.owncloud.android.lib.common.OwnCloudCredentialsFactory; +import com.owncloud.android.lib.common.network.NetworkUtils; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.lib.resources.shares.OCShare; +import com.owncloud.android.lib.resources.shares.RemoveRemoteShareOperation; +import com.owncloud.android.lib.resources.shares.ShareType; +import com.owncloud.android.lib.resources.shares.UpdateRemoteShareOperation; +import com.owncloud.android.lib.test_project.R; +import com.owncloud.android.lib.test_project.SelfSignedConfidentSslSocketFactory; +import com.owncloud.android.lib.test_project.TestActivity; + +/** + * Class to test UpdateRemoteShareOperation + * + */ +public class UpdateShareTest extends RemoteTest { + private static final String LOG_TAG = UpdateShareTest.class.getCanonicalName(); + + /* File to share and update.*/ + private static final String FILE_TO_SHARE = "/fileToShare.txt"; + + // Data for tests + private static final String PASSWORD = "password"; + private static final String PASS_SPECIAL_CHARS = "p@sswórd"; + + private String mFullPath2FileToShare; + + private OCShare mShare; + + String mServerUri, mUser, mPass; + OwnCloudClient mClient = null; + + public UpdateShareTest(){ + super(); + + Protocol pr = Protocol.getProtocol("https"); + if (pr == null || !(pr.getSocketFactory() instanceof SelfSignedConfidentSslSocketFactory)) { + try { + ProtocolSocketFactory psf = new SelfSignedConfidentSslSocketFactory(); + Protocol.registerProtocol( + "https", + new Protocol("https", psf, 443)); + + } catch (GeneralSecurityException e) { + throw new AssertionFailedError( + "Self-signed confident SSL context could not be loaded"); + } + } + } + + protected Context getContext() { + return getActivity(); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + // Next initialization cannot be done in the constructor because getContext() is not + // ready yet, returns NULL. + initAccessToServer(getContext()); + + Log.v(LOG_TAG, "Setting up the remote fixture..."); + + // Upload the files + mFullPath2FileToShare = mBaseFolderPath + FILE_TO_SHARE; + + File textFile = getActivity().extractAsset(TestActivity.ASSETS__TEXT_FILE_NAME); + RemoteOperationResult result = getActivity().uploadFile( + textFile.getAbsolutePath(), + mFullPath2FileToShare, + "txt/plain"); + if (!result.isSuccess()) { + Utils.logAndThrow(LOG_TAG, result); + } + + // Share the file + result = getActivity().createShare( + mFullPath2FileToShare, + ShareType.PUBLIC_LINK, + "", + false, + "", + 1); + + if (result.isSuccess()){ + mShare = (OCShare) result.getData().get(0); + } else{ + mShare = null; + } + + Log.v(LOG_TAG, "Remote fixture created."); + + } + + + public void testUpdateRemoteShareOperation() { + Log.v(LOG_TAG, "testUpdateShare in"); + + if (mShare != null) { + // successful tests + // Update Share with password + UpdateRemoteShareOperation updateShare = new UpdateRemoteShareOperation(mShare.getRemoteId()); + updateShare.setPassword(PASSWORD); + RemoteOperationResult result = updateShare.execute(mClient); + assertTrue(result.isSuccess()); + + // Update Share with password with special characters + updateShare = new UpdateRemoteShareOperation(mShare.getRemoteId()); + updateShare.setPassword(PASS_SPECIAL_CHARS); + result = updateShare.execute(mClient); + assertTrue(result.isSuccess()); + + // Update Share with expiration date + updateShare = new UpdateRemoteShareOperation(mShare.getRemoteId()); + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DAY_OF_MONTH, 7); + long expirationDateInMillis = calendar.getTimeInMillis() ; + updateShare.setExpirationDate(expirationDateInMillis); + result = updateShare.execute(mClient); + assertTrue(result.isSuccess()); + + // unsuccessful test + // Update Share with expiration date in the past + updateShare = new UpdateRemoteShareOperation(mShare.getRemoteId()); + calendar.set(Calendar.YEAR, 2014); + expirationDateInMillis = calendar.getTimeInMillis() ; + updateShare.setExpirationDate(expirationDateInMillis); + result = updateShare.execute(mClient); + assertFalse(result.isSuccess()); + + // Unshare the file before the unsuccessful tests + RemoveRemoteShareOperation unshare = new RemoveRemoteShareOperation((int) mShare.getRemoteId()); + result = unshare.execute(mClient); + + if (result.isSuccess()) { + // Update Share with password on unknown share + UpdateRemoteShareOperation updateNoShare = new UpdateRemoteShareOperation(mShare.getRemoteId()); + updateNoShare.setPassword(PASSWORD); + result = updateNoShare.execute(mClient); + assertFalse(result.isSuccess()); + + // Update Share with expiration date on unknown share + updateNoShare = new UpdateRemoteShareOperation(mShare.getRemoteId()); + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.DAY_OF_MONTH, 7); + expirationDateInMillis = cal.getTimeInMillis() ; + updateNoShare.setExpirationDate(expirationDateInMillis); + result = updateNoShare.execute(mClient); + assertFalse(result.isSuccess()); + + } + + } + + } + + @Override + protected void tearDown() throws Exception { + Log.v(LOG_TAG, "Deleting remote fixture..."); + if (mFullPath2FileToShare != null) { + RemoteOperationResult removeResult = getActivity().removeFile(mFullPath2FileToShare); + if (!removeResult.isSuccess() && removeResult.getCode() != ResultCode.TIMEOUT) { + Utils.logAndThrow(LOG_TAG, removeResult); + } + } + super.tearDown(); + Log.v(LOG_TAG, "Remote fixture delete."); + } + + + private void initAccessToServer(Context context) { + Log.v(LOG_TAG, "Setting up client instance to access OC server..."); + + mServerUri = context.getString(R.string.server_base_url); + mUser = context.getString(R.string.username); + mPass = context.getString(R.string.password); + + mClient = new OwnCloudClient( + Uri.parse(mServerUri), + NetworkUtils.getMultiThreadedConnManager() + ); + mClient.setDefaultTimeouts( + OwnCloudClientFactory.DEFAULT_DATA_TIMEOUT, + OwnCloudClientFactory.DEFAULT_CONNECTION_TIMEOUT); + mClient.setFollowRedirects(true); + mClient.setCredentials( + OwnCloudCredentialsFactory.newBasicCredentials( + mUser, + mPass + ) + ); + + Log.v(LOG_TAG, "Client instance set up."); + + } + +} From 9cf96a10ce8b3c79c5f386c258da80119ca81b7b Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Tue, 24 Nov 2015 13:44:42 +0100 Subject: [PATCH 093/101] Fixed lost of share link when token exists --- .../resources/shares/ShareToRemoteOperationResultParser.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/com/owncloud/android/lib/resources/shares/ShareToRemoteOperationResultParser.java b/src/com/owncloud/android/lib/resources/shares/ShareToRemoteOperationResultParser.java index c59ba8ed..8105f146 100644 --- a/src/com/owncloud/android/lib/resources/shares/ShareToRemoteOperationResultParser.java +++ b/src/com/owncloud/android/lib/resources/shares/ShareToRemoteOperationResultParser.java @@ -90,7 +90,8 @@ public class ShareToRemoteOperationResultParser { resultData.add(share); // build the share link if not in the response (only received when the share is created) if (share.getShareType() == ShareType.PUBLIC_LINK && - share.getShareLink() == null && + (share.getShareLink() == null || + share.getShareLink().length() <= 0) && share.getToken().length() > 0 ) { if (mServerBaseUri != null) { From 77c0d785c97233e327cfdeba8365b5ab116934c3 Mon Sep 17 00:00:00 2001 From: masensio Date: Thu, 26 Nov 2015 13:26:24 +0100 Subject: [PATCH 094/101] Fix bug related with sharee with special characters --- .../android/lib/resources/shares/GetRemoteShareesOperation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java index 132b017f..67ad558d 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.java @@ -125,7 +125,7 @@ public class GetRemoteShareesOperation extends RemoteOperation{ uriBuilder.appendEncodedPath(OCS_ROUTE); uriBuilder.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT); uriBuilder.appendQueryParameter(PARAM_ITEM_TYPE, VALUE_ITEM_TYPE); - uriBuilder.appendQueryParameter(PARAM_SEARCH, Uri.encode(mSearchString, "@")); + uriBuilder.appendQueryParameter(PARAM_SEARCH, mSearchString); uriBuilder.appendQueryParameter(PARAM_PAGE, String.valueOf(mPage)); uriBuilder.appendQueryParameter(PARAM_PER_PAGE, String.valueOf(mPerPage)); From 5c874143909b7bf2372f58b898266ecd4f732c6a Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 2 Jun 2015 17:29:57 +0200 Subject: [PATCH 095/101] Close resource in finally block I don't quite get the reason for `mBuf` here as in `com.owncloud.android.lib.common.utils.Log_OC#appendLog` anyways a new `BufferedWriter` is started but it might make sense to close this here as this will otherwise cause warnings in static code scanners. Didn't test this as I don't have a Java device and so it requires extensive testing. --- .../owncloud/android/lib/common/utils/Log_OC.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/com/owncloud/android/lib/common/utils/Log_OC.java b/src/com/owncloud/android/lib/common/utils/Log_OC.java index 4d4760e6..c99c5e59 100644 --- a/src/com/owncloud/android/lib/common/utils/Log_OC.java +++ b/src/com/owncloud/android/lib/common/utils/Log_OC.java @@ -60,7 +60,7 @@ public class Log_OC { } public static void w(String TAG, String message) { - Log.w(TAG,message); + Log.w(TAG, message); appendLog(TAG+" : "+ message); } @@ -99,8 +99,16 @@ public class Log_OC { } } catch (IOException e) { - e.printStackTrace(); - } + e.printStackTrace(); + } finally { + if(mBuf != null) { + try { + mBuf.close(); + } catch(IOException e) { + e.printStackTrace(); + } + } + } } /** From d39d26f842c7b997209986c034567fee97c38c84 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 3 Jun 2015 11:18:18 +0200 Subject: [PATCH 096/101] Close in finally block --- src/com/owncloud/android/lib/common/utils/Log_OC.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/com/owncloud/android/lib/common/utils/Log_OC.java b/src/com/owncloud/android/lib/common/utils/Log_OC.java index c99c5e59..2bef4fc9 100644 --- a/src/com/owncloud/android/lib/common/utils/Log_OC.java +++ b/src/com/owncloud/android/lib/common/utils/Log_OC.java @@ -167,10 +167,15 @@ public class Log_OC { mBuf.newLine(); mBuf.write(text); mBuf.newLine(); - mBuf.close(); } catch (IOException e) { e.printStackTrace(); - } + } finally { + try { + mBuf.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } // Check if current log file size is bigger than the max file size defined if (mLogFile.length() > MAX_FILE_SIZE) { From dad5cd115af2c1eb050599b6b14a0480dbb56721 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Thu, 10 Dec 2015 14:18:00 +0100 Subject: [PATCH 097/101] Added constants to analyze share permissions --- src/com/owncloud/android/lib/resources/shares/OCShare.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/com/owncloud/android/lib/resources/shares/OCShare.java b/src/com/owncloud/android/lib/resources/shares/OCShare.java index 347bd1ae..7bbb0724 100644 --- a/src/com/owncloud/android/lib/resources/shares/OCShare.java +++ b/src/com/owncloud/android/lib/resources/shares/OCShare.java @@ -47,6 +47,11 @@ public class OCShare implements Parcelable, Serializable { private static final String TAG = OCShare.class.getSimpleName(); public static final int DEFAULT_PERMISSION = -1; + public static final int READ_PERMISSION_FLAG = 1; + public static final int UPDATE_PERMISSION_FLAG = 2; + public static final int CREATE_PERMISSION_FLAG = 4; + public static final int DELETE_PERMISSION_FLAG = 8; + public static final int SHARE_PERMISSION_FLAG = 16; private long mId; private long mFileSource; From 249cb901ebd392373d0ef812b8f0a2489705c0ea Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Wed, 16 Dec 2015 16:32:48 +0100 Subject: [PATCH 098/101] Added support to update share permissions --- .../shares/SharePermissionsBuilder.java | 106 ++++++++++++++++++ .../shares/UpdateRemoteShareOperation.java | 23 +++- 2 files changed, 125 insertions(+), 4 deletions(-) create mode 100644 src/com/owncloud/android/lib/resources/shares/SharePermissionsBuilder.java diff --git a/src/com/owncloud/android/lib/resources/shares/SharePermissionsBuilder.java b/src/com/owncloud/android/lib/resources/shares/SharePermissionsBuilder.java new file mode 100644 index 00000000..85fcf7ff --- /dev/null +++ b/src/com/owncloud/android/lib/resources/shares/SharePermissionsBuilder.java @@ -0,0 +1,106 @@ +/* ownCloud Android Library is available under MIT license + * @author David A. Velasco + * Copyright (C) 2015 ownCloud Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.resources.shares; + + +/** + * Provides method to define a set of share permissions and calculate the appropiate + * int value representing it. + */ +public class SharePermissionsBuilder { + + /** Set of permissions */ + private int mPermissions = OCShare.READ_PERMISSION_FLAG; // READ is minimum permission + + /** + * Sets or clears permission to reshare a file or folder. + * + * @param enabled 'True' to set, 'false' to clear. + * @return Instance to builder itself, to allow consecutive calls to setters + */ + public SharePermissionsBuilder setSharePermission(boolean enabled) { + updatePermission(OCShare.SHARE_PERMISSION_FLAG, enabled); + return this; + } + + /** + * Sets or clears permission to update a folder or folder. + * + * @param enabled 'True' to set, 'false' to clear. + * @return Instance to builder itself, to allow consecutive calls to setters + */ + public SharePermissionsBuilder setUpdatePermission(boolean enabled) { + updatePermission(OCShare.UPDATE_PERMISSION_FLAG, enabled); + return this; + } + + /** + * Sets or clears permission to create files in share folder. + * + * @param enabled 'True' to set, 'false' to clear. + * @return Instance to builder itself, to allow consecutive calls to setters + */ + public SharePermissionsBuilder setCreatePermission(boolean enabled) { + updatePermission(OCShare.CREATE_PERMISSION_FLAG, enabled); + return this; + } + + /** + * Sets or clears permission to delete files in a shared folder. + * + * @param enabled 'True' to set, 'false' to clear. + * @return Instance to builder itself, to allow consecutive calls to setters + */ + public SharePermissionsBuilder setDeletePermission(boolean enabled) { + updatePermission(OCShare.DELETE_PERMISSION_FLAG, enabled); + return this; + } + + /** + * Common code to update the value of the set of permissions. + * + * @param permissionsFlag Flag for the permission to update. + * @param enable 'True' to set, 'false' to clear. + */ + private void updatePermission(int permissionsFlag, boolean enable) { + if (enable) { + // add permission + mPermissions |= permissionsFlag; + } else { + // delete permission + mPermissions &= ~permissionsFlag; + } + } + + /** + * 'Builds' the int value for the accumulated set of permissions. + * + * @return An int value representing the accumulated set of permissions. + */ + public int build() { + return mPermissions; + } +} diff --git a/src/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.java b/src/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.java index aa6ae537..00178ed8 100644 --- a/src/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.java @@ -56,6 +56,7 @@ public class UpdateRemoteShareOperation extends RemoteOperation { private static final String PARAM_PASSWORD = "password"; private static final String PARAM_EXPIRATION_DATE = "expireDate"; + private static final String PARAM_PERMISSIONS = "permissions"; private static final String FORMAT_EXPIRATION_DATE = "yyyy-MM-dd"; private static final String ENTITY_CONTENT_TYPE = "application/x-www-form-urlencoded"; private static final String ENTITY_CHARSET = "UTF-8"; @@ -70,6 +71,9 @@ public class UpdateRemoteShareOperation extends RemoteOperation { /** Expiration date to set for the public link */ private long mExpirationDateInMillis; + /** Access permissions for the file bound to the share */ + private int mPermissions; + /** * Constructor. No update is initialized by default, need to be applied with setters below. @@ -98,7 +102,7 @@ public class UpdateRemoteShareOperation extends RemoteOperation { /** * Set expiration date to update in Share resource. * - * @param expirationDateInMillis Expiration date to set to the public link. + * @param expirationDateInMillis Expiration date to set to the target share. * A negative value clears the current expiration date. * Zero value (start-of-epoch) results in no update done on * the expiration date. @@ -108,6 +112,16 @@ public class UpdateRemoteShareOperation extends RemoteOperation { } + /** + * Set permissions to update in Share resource. + * + * @param permissions Permissions date to set to the target share. + * Values <= 0 result in no update applied to the permissions. + */ + public void setPermissions(int permissions) { + mPermissions = permissions; + } + @Override protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; @@ -131,11 +145,12 @@ public class UpdateRemoteShareOperation extends RemoteOperation { parametersToUpdate.add(new Pair(PARAM_EXPIRATION_DATE, formattedExpirationDate)); } // else, ignore - no update + if (mPermissions > 0) { + // set permissions + parametersToUpdate.add(new Pair(PARAM_PERMISSIONS, Integer.toString(mPermissions))); + } /* TODO complete rest of parameters - if (mPermissions > 0) { - parametersToUpdate.add(new Pair("permissions", Integer.toString(mPermissions))); - } if (mPublicUpload != null) { parametersToUpdate.add(new Pair("publicUpload", mPublicUpload.toString()); } From 275c042f7884f8a56cb4b5cb94ef9be98884e698 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Mon, 18 Jan 2016 13:54:45 +0100 Subject: [PATCH 099/101] Added constants for maximum Share permissions --- .../shares/GetRemoteSharesForFileOperation.java | 6 +++--- .../owncloud/android/lib/resources/shares/OCShare.java | 10 ++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java index 8e9b2170..c2019f7a 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java @@ -56,9 +56,9 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation { * Constructor * * @param remoteFilePath Path to file or folder - * @param reshares If set to false (default), only shares from the current user are - * returned - * If set to true, all shares from the given file are returned + * @param reshares If set to false (default), only shares owned by the current user are + * returned. + * If set to true, shares owned by any user from the given file are returned. * @param subfiles If set to false (default), lists only the folder being shared * If set to true, all shared files within the folder are returned. */ diff --git a/src/com/owncloud/android/lib/resources/shares/OCShare.java b/src/com/owncloud/android/lib/resources/shares/OCShare.java index 7bbb0724..0fe3aeb2 100644 --- a/src/com/owncloud/android/lib/resources/shares/OCShare.java +++ b/src/com/owncloud/android/lib/resources/shares/OCShare.java @@ -52,6 +52,16 @@ public class OCShare implements Parcelable, Serializable { public static final int CREATE_PERMISSION_FLAG = 4; public static final int DELETE_PERMISSION_FLAG = 8; public static final int SHARE_PERMISSION_FLAG = 16; + public static final int MAXIMUM_PERMISSIONS_FOR_FILE = + READ_PERMISSION_FLAG + + UPDATE_PERMISSION_FLAG + + SHARE_PERMISSION_FLAG + ; + public static final int MAXIMUM_PERMISSIONS_FOR_FOLDER = + MAXIMUM_PERMISSIONS_FOR_FILE + + CREATE_PERMISSION_FLAG + + DELETE_PERMISSION_FLAG + ; private long mId; private long mFileSource; From b3535a3678018fc4ffd51865d53cb0d904b05112 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Tue, 26 Jan 2016 18:39:01 +0100 Subject: [PATCH 100/101] Updated automatic tests to cover share permissions updates --- .../test/UpdatePrivateShareTest.java | 252 ++++++++++++++++++ ...reTest.java => UpdatePublicShareTest.java} | 16 +- 2 files changed, 261 insertions(+), 7 deletions(-) create mode 100644 test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdatePrivateShareTest.java rename test_client/tests/src/com/owncloud/android/lib/test_project/test/{UpdateShareTest.java => UpdatePublicShareTest.java} (95%) diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdatePrivateShareTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdatePrivateShareTest.java new file mode 100644 index 00000000..60b1d141 --- /dev/null +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdatePrivateShareTest.java @@ -0,0 +1,252 @@ +/* ownCloud Android Library is available under MIT license + * @author masensio + * @author David A. Velasco + * Copyright (C) 2015 ownCloud Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +package com.owncloud.android.lib.test_project.test; + +import java.io.File; +import java.security.GeneralSecurityException; +import java.util.Calendar; + +import junit.framework.AssertionFailedError; + +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; + +import android.content.Context; +import android.net.Uri; +import android.util.Log; + +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.OwnCloudClientFactory; +import com.owncloud.android.lib.common.OwnCloudCredentialsFactory; +import com.owncloud.android.lib.common.network.NetworkUtils; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.lib.resources.shares.OCShare; +import com.owncloud.android.lib.resources.shares.RemoveRemoteShareOperation; +import com.owncloud.android.lib.resources.shares.ShareType; +import com.owncloud.android.lib.resources.shares.UpdateRemoteShareOperation; +import com.owncloud.android.lib.test_project.R; +import com.owncloud.android.lib.test_project.SelfSignedConfidentSslSocketFactory; +import com.owncloud.android.lib.test_project.TestActivity; + +/** + * Class to test UpdateRemoteShareOperation + * with private shares + * + */ +public class UpdatePrivateShareTest extends RemoteTest { + private static final String LOG_TAG = UpdatePrivateShareTest.class.getCanonicalName(); + + /* File to share and update */ + private static final String FILE_TO_SHARE = "/fileToShare.txt"; + + /* Folder to share and update */ + private static final String FOLDER_TO_SHARE = "/folderToShare"; + + /* Sharees */ + private static final String USER_SHAREE = "admin"; + private static final String GROUP_SHAREE = "admin"; + + private String mFullPath2FileToShare; + private String mFullPath2FolderToShare; + + private OCShare mFileShare; + private OCShare mFolderShare; + + String mServerUri, mUser, mPass; + OwnCloudClient mClient = null; + + public UpdatePrivateShareTest(){ + super(); + + Protocol pr = Protocol.getProtocol("https"); + if (pr == null || !(pr.getSocketFactory() instanceof SelfSignedConfidentSslSocketFactory)) { + try { + ProtocolSocketFactory psf = new SelfSignedConfidentSslSocketFactory(); + Protocol.registerProtocol( + "https", + new Protocol("https", psf, 443)); + + } catch (GeneralSecurityException e) { + throw new AssertionFailedError( + "Self-signed confident SSL context could not be loaded"); + } + } + } + + protected Context getContext() { + return getActivity(); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + // Next initialization cannot be done in the constructor because getContext() is not + // ready yet, returns NULL. + initAccessToServer(getContext()); + + Log.v(LOG_TAG, "Setting up the remote fixture..."); + + // Upload the file + mFullPath2FileToShare = mBaseFolderPath + FILE_TO_SHARE; + + File textFile = getActivity().extractAsset(TestActivity.ASSETS__TEXT_FILE_NAME); + RemoteOperationResult result = getActivity().uploadFile( + textFile.getAbsolutePath(), + mFullPath2FileToShare, + "txt/plain"); + if (!result.isSuccess()) { + Utils.logAndThrow(LOG_TAG, result); + } + + // Share the file privately with other user + result = getActivity().createShare( + mFullPath2FileToShare, + ShareType.USER, + USER_SHAREE, + false, + "", + OCShare.MAXIMUM_PERMISSIONS_FOR_FILE); + + if (result.isSuccess()){ + mFileShare = (OCShare) result.getData().get(0); + } else{ + mFileShare = null; + } + + // Create the folder + mFullPath2FolderToShare = mBaseFolderPath + FOLDER_TO_SHARE; + result = getActivity().createFolder( + mFullPath2FolderToShare, + true); + if (!result.isSuccess()) { + Utils.logAndThrow(LOG_TAG, result); + } + + // Share the folder privately with a group + result = getActivity().createShare( + mFullPath2FolderToShare, + ShareType.GROUP, + GROUP_SHAREE, + false, + "", + OCShare.MAXIMUM_PERMISSIONS_FOR_FOLDER); + + if (result.isSuccess()){ + mFolderShare = (OCShare) result.getData().get(0); + } else{ + mFolderShare = null; + } + + Log.v(LOG_TAG, "Remote fixture created."); + + } + + + public void testUpdateSharePermissions() { + Log.v(LOG_TAG, "testUpdateSharePermissions in"); + + if (mFileShare != null) { + /// successful tests + // Update Share permissions on a shared file + UpdateRemoteShareOperation updateShare = new UpdateRemoteShareOperation(mFileShare.getRemoteId()); + updateShare.setPermissions(OCShare.READ_PERMISSION_FLAG); // minimum permissions + RemoteOperationResult result = updateShare.execute(mClient); + assertTrue(result.isSuccess()); + + // Update Share permissions on a shared folder + updateShare = new UpdateRemoteShareOperation(mFolderShare.getRemoteId()); + updateShare.setPermissions(OCShare.READ_PERMISSION_FLAG + OCShare.DELETE_PERMISSION_FLAG); + result = updateShare.execute(mClient); + assertTrue(result.isSuccess()); + + + /// unsuccessful tests + // Update Share with invalid permissions + updateShare = new UpdateRemoteShareOperation(mFileShare.getRemoteId()); + updateShare.setPermissions(OCShare.MAXIMUM_PERMISSIONS_FOR_FOLDER + 1); // greater than maximum value + result = updateShare.execute(mClient); + assertFalse(result.isSuccess()); + + // Unshare the file before next unsuccessful tests + RemoveRemoteShareOperation unshare = new RemoveRemoteShareOperation((int) mFileShare.getRemoteId()); + result = unshare.execute(mClient); + + if (result.isSuccess()) { + // Update Share permissions on unknown share + UpdateRemoteShareOperation updateNoShare = new UpdateRemoteShareOperation(mFileShare.getRemoteId()); + updateShare.setPermissions(OCShare.READ_PERMISSION_FLAG); // minimum permissions + result = updateShare.execute(mClient); + assertFalse(result.isSuccess()); + } + + } + + } + + @Override + protected void tearDown() throws Exception { + Log.v(LOG_TAG, "Deleting remote fixture..."); + if (mFullPath2FileToShare != null) { + RemoteOperationResult removeResult = getActivity().removeFile(mFullPath2FileToShare); + if (!removeResult.isSuccess() && removeResult.getCode() != ResultCode.TIMEOUT) { + Utils.logAndThrow(LOG_TAG, removeResult); + } + } + super.tearDown(); + Log.v(LOG_TAG, "Remote fixture delete."); + } + + + private void initAccessToServer(Context context) { + Log.v(LOG_TAG, "Setting up client instance to access OC server..."); + + mServerUri = context.getString(R.string.server_base_url); + mUser = context.getString(R.string.username); + mPass = context.getString(R.string.password); + + mClient = new OwnCloudClient( + Uri.parse(mServerUri), + NetworkUtils.getMultiThreadedConnManager() + ); + mClient.setDefaultTimeouts( + OwnCloudClientFactory.DEFAULT_DATA_TIMEOUT, + OwnCloudClientFactory.DEFAULT_CONNECTION_TIMEOUT); + mClient.setFollowRedirects(true); + mClient.setCredentials( + OwnCloudCredentialsFactory.newBasicCredentials( + mUser, + mPass + ) + ); + + Log.v(LOG_TAG, "Client instance set up."); + + } + +} diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdateShareTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdatePublicShareTest.java similarity index 95% rename from test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdateShareTest.java rename to test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdatePublicShareTest.java index 389146b5..6bc9837f 100644 --- a/test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdateShareTest.java +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdatePublicShareTest.java @@ -1,5 +1,6 @@ /* ownCloud Android Library is available under MIT license * @author masensio + * @author David A. Velasco * Copyright (C) 2015 ownCloud Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -54,17 +55,18 @@ import com.owncloud.android.lib.test_project.TestActivity; /** * Class to test UpdateRemoteShareOperation + * with public shares * */ -public class UpdateShareTest extends RemoteTest { - private static final String LOG_TAG = UpdateShareTest.class.getCanonicalName(); +public class UpdatePublicShareTest extends RemoteTest { + private static final String LOG_TAG = UpdatePublicShareTest.class.getCanonicalName(); /* File to share and update.*/ private static final String FILE_TO_SHARE = "/fileToShare.txt"; // Data for tests private static final String PASSWORD = "password"; - private static final String PASS_SPECIAL_CHARS = "p@sswórd"; + private static final String PASS_SPECIAL_CHARS = "p@sswďż˝rd"; private String mFullPath2FileToShare; @@ -73,7 +75,7 @@ public class UpdateShareTest extends RemoteTest { String mServerUri, mUser, mPass; OwnCloudClient mClient = null; - public UpdateShareTest(){ + public UpdatePublicShareTest(){ super(); Protocol pr = Protocol.getProtocol("https"); @@ -117,7 +119,7 @@ public class UpdateShareTest extends RemoteTest { Utils.logAndThrow(LOG_TAG, result); } - // Share the file + // Share the file with a public link result = getActivity().createShare( mFullPath2FileToShare, ShareType.PUBLIC_LINK, @@ -137,8 +139,8 @@ public class UpdateShareTest extends RemoteTest { } - public void testUpdateRemoteShareOperation() { - Log.v(LOG_TAG, "testUpdateShare in"); + public void testUpdatePublicShare() { + Log.v(LOG_TAG, "testUpdatePublicShare in"); if (mShare != null) { // successful tests From ac9771ea3a58c5a423a1341f390c26c8e6ccba3e Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Wed, 27 Jan 2016 10:31:46 +0100 Subject: [PATCH 101/101] Migration to different test server --- .travis.yml | 28 +++++++++---------- .../GetRemoteSharesForFileOperation.java | 10 +++---- .../lib/test_project/test/GetShareesTest.java | 16 +++++------ .../test/UpdatePrivateShareTest.java | 15 +++++++--- 4 files changed, 38 insertions(+), 31 deletions(-) diff --git a/.travis.yml b/.travis.yml index 04831290..2598e3e7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,7 @@ android: - android-19 branches: only: - - master - + - master before_install: - echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI -c 20M @@ -25,21 +24,22 @@ script: - ./gradlew clean build env: global: - - secure: a21NrzTCQnkTKtRGo7B1lyF2WWbpBT2N64V2Tf+oUcRLOUx3XM/mDi60mAdGd0WXV9tHD8GGmu0tQ7LGZ2VsIxixVxjzEYwX4HRTodewYez6WxBMjVEHHy+3jmc1zU4k3AAqr+uW7L4BKa5r9tH+nq9ecJMDMgW8o9MKXuP7Vso= - - secure: UVnaC5Qzat2C8WlMMb8aycz1ChZKjP8Kz89qBbVcqYK+PLAGKpUNxFa39/2oA5jkMyyOcXYC9bX1ZYzHLH7nJ8LbQgaxXMT4gvgvN0l6KezjDavIW60idD9BbugkwzNj/cjoU/DdxBykPsTn4vSRaESVNTdEbM27YU4FBPzTANY= - - secure: XEQY8s7p65lWWOuKbVDdTh6ZJtRTJ74Zw3H/+2Ms6vjZhFZsdUJjGo66LW6YvlhmYDXgiPB9piYQGcrGgT3hXJwXoge6n1pdixnV250J0T0dIZMbXYTWTARxDsyq48+LgUuF3pgqvqDWhBcemrePWv48q7fs/mwzuFSOyc8QwLk= - # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created - # via the "travis encrypt" command using the project repo's public key - - secure: "epTZ0zZGDbHL3o6vSC9uNkZsi5j5SA6O/tvQBH7QW/dluuzIJxIjfhNbZHDyBReYDleirLzUFQpdWAUdvulCMLs/qZdIzFGlYXZSpxEnvPYMGQcilwADdJcxLw8L+3+ET5hSexxhjrTGw427IljkqGUpqQTxaLwFdFu98lDWSbc=" + # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created + # via the "travis encrypt" command using the project repo's public key + - secure: epTZ0zZGDbHL3o6vSC9uNkZsi5j5SA6O/tvQBH7QW/dluuzIJxIjfhNbZHDyBReYDleirLzUFQpdWAUdvulCMLs/qZdIzFGlYXZSpxEnvPYMGQcilwADdJcxLw8L+3+ET5hSexxhjrTGw427IljkqGUpqQTxaLwFdFu98lDWSbc= + # The next 3 declarations are the variables needed to access the test server, + # added via "travis encrypt", using the repo public key + - secure: gPCBnpGLA2sdSMtfhT+/InThmXNEU8XrrS54uuIP8iXBLvVe0yZrNl76GbMosV0ry3YtDngsmsbHwRjPPb0+3mTTdAqZ60HHzGaNPgEm6b5t0t4bpJ3LW9osLZsuf9jRsI2LD66zxblaMrK2+8hN/dUrj707ijsZHp3SPSQJ6g8= + - secure: AnxLVarfwM7IhJ7Sca35USyRlFHFvlcBhWTt2TVDcyQ+ldDyb+U6IWXFK0Yy82QP0ZH/RCLu7FnmHK/rKG0BHNRt1Ymco1VkTQql0MZcHXP+4IKgEvgJyUn1TqYj+hSVmM6lgTA+QUjZYGSfwU8mhUFiU7644ZTdTe6ALdqa+v8= + - secure: ezKyZbb3q1Phcv/vJntuJe0C2req+Hp4/C+tFZIWZ3o8wRO9jVI3bnED9TWQyQOOT0SoRYjJ5zqp0UcEOGCzPeWFO6bA7RWp+zA/R9sziLNcVWMVv3WXnuClQjPBHJeXRnP7YmNjxDmSfV97a14dk5d9LgJZYliTDepH4dLsxro= matrix: - ANDROID_TARGET=android-19 ANDROID_ABI=armeabi-v7a - addons: coverity_scan: project: - name: "owncloud/android-library" - description: "Build submitted via Travis CI" + name: owncloud/android-library + description: Build submitted via Travis CI notification_email: lukas@owncloud.com - build_command_prepend: "gradle clean" - build_command: "gradle build" - branch_pattern: "coverity_scan" + build_command_prepend: gradle clean + build_command: gradle build + branch_pattern: coverity_scan diff --git a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java index c2019f7a..6076b40f 100644 --- a/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java +++ b/src/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.java @@ -55,12 +55,12 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation { /** * Constructor * - * @param remoteFilePath Path to file or folder - * @param reshares If set to false (default), only shares owned by the current user are + * @param remoteFilePath Path to file or folder + * @param reshares If set to false (default), only shares owned by the current user are * returned. - * If set to true, shares owned by any user from the given file are returned. - * @param subfiles If set to false (default), lists only the folder being shared - * If set to true, all shared files within the folder are returned. + * If set to true, shares owned by any user from the given file are returned. + * @param subfiles If set to false (default), lists only the folder being shared + * If set to true, all shared files within the folder are returned. */ public GetRemoteSharesForFileOperation(String remoteFilePath, boolean reshares, boolean subfiles) { diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/GetShareesTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/GetShareesTest.java index 80bcd107..c80f805c 100644 --- a/test_client/tests/src/com/owncloud/android/lib/test_project/test/GetShareesTest.java +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/GetShareesTest.java @@ -127,9 +127,9 @@ public class GetShareesTest extends RemoteTest { JSONObject value; byte type; int userCount = 0, groupCount = 0; - assertTrue(result.isSuccess() && result.getData().size() == 3); + assertTrue(result.isSuccess() && result.getData().size() > 0); try { - for (int i=0; i<3; i++) { + for (int i=0; i 0); + assertTrue(groupCount > 0); } catch (JSONException e) { AssertionFailedError afe = new AssertionFailedError(e.getLocalizedMessage()); afe.setStackTrace(e.getStackTrace()); throw afe; } - - // search for sharees including "ad" + + // search for sharees including "ad" - expecting user "admin" & group "admin" getShareesOperation = new GetRemoteShareesOperation("ad", 1, 50); result = getShareesOperation.execute(mClient); assertTrue(result.isSuccess() && result.getData().size() == 2); @@ -172,8 +172,8 @@ public class GetShareesTest extends RemoteTest { } - // search for sharees including "b" - getShareesOperation = new GetRemoteShareesOperation("b", 1, 50); + // search for sharees including "bd" - expecting 0 results + getShareesOperation = new GetRemoteShareesOperation("bd", 1, 50); result = getShareesOperation.execute(mClient); assertTrue(result.isSuccess() && result.getData().size() == 0); diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdatePrivateShareTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdatePrivateShareTest.java index 60b1d141..d839530b 100644 --- a/test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdatePrivateShareTest.java +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/UpdatePrivateShareTest.java @@ -174,7 +174,9 @@ public class UpdatePrivateShareTest extends RemoteTest { if (mFileShare != null) { /// successful tests // Update Share permissions on a shared file - UpdateRemoteShareOperation updateShare = new UpdateRemoteShareOperation(mFileShare.getRemoteId()); + UpdateRemoteShareOperation updateShare = new UpdateRemoteShareOperation( + mFileShare.getRemoteId() + ); updateShare.setPermissions(OCShare.READ_PERMISSION_FLAG); // minimum permissions RemoteOperationResult result = updateShare.execute(mClient); assertTrue(result.isSuccess()); @@ -189,17 +191,22 @@ public class UpdatePrivateShareTest extends RemoteTest { /// unsuccessful tests // Update Share with invalid permissions updateShare = new UpdateRemoteShareOperation(mFileShare.getRemoteId()); - updateShare.setPermissions(OCShare.MAXIMUM_PERMISSIONS_FOR_FOLDER + 1); // greater than maximum value + // greater than maximum value + updateShare.setPermissions(OCShare.MAXIMUM_PERMISSIONS_FOR_FOLDER + 1); result = updateShare.execute(mClient); assertFalse(result.isSuccess()); // Unshare the file before next unsuccessful tests - RemoveRemoteShareOperation unshare = new RemoveRemoteShareOperation((int) mFileShare.getRemoteId()); + RemoveRemoteShareOperation unshare = new RemoveRemoteShareOperation( + (int) mFileShare.getRemoteId() + ); result = unshare.execute(mClient); if (result.isSuccess()) { // Update Share permissions on unknown share - UpdateRemoteShareOperation updateNoShare = new UpdateRemoteShareOperation(mFileShare.getRemoteId()); + UpdateRemoteShareOperation updateNoShare = new UpdateRemoteShareOperation( + mFileShare.getRemoteId() + ); updateShare.setPermissions(OCShare.READ_PERMISSION_FLAG); // minimum permissions result = updateShare.execute(mClient); assertFalse(result.isSuccess());