mirror of
https://github.com/owncloud/android-library.git
synced 2025-06-08 00:16:09 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
31836d3f4a
37
.travis.yml
37
.travis.yml
@ -1,21 +1,18 @@
|
|||||||
|
sudo: false
|
||||||
language: android
|
language: android
|
||||||
android:
|
android:
|
||||||
components:
|
components:
|
||||||
- build-tools-20.0.0
|
- build-tools-22.0.1
|
||||||
- android-19
|
- android-19
|
||||||
- android-17
|
branches:
|
||||||
- android-14
|
only:
|
||||||
- extra-android-support
|
- master
|
||||||
licenses:
|
|
||||||
- 'android-sdk-license-5be876d5'
|
|
||||||
- 'android-sdk-license-598b93a6'
|
|
||||||
jdk: oraclejdk7
|
|
||||||
before_install:
|
before_install:
|
||||||
- echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI -c 20M
|
- 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 &
|
- emulator -avd test -no-skin -no-audio -no-window &
|
||||||
- rm pom.xml
|
- rm pom.xml
|
||||||
- android update project -p .
|
- android update project -p .
|
||||||
before_script:
|
|
||||||
- chmod +x ./wait_for_emulator.sh
|
- chmod +x ./wait_for_emulator.sh
|
||||||
- ./wait_for_emulator.sh
|
- ./wait_for_emulator.sh
|
||||||
script:
|
script:
|
||||||
@ -27,8 +24,22 @@ script:
|
|||||||
- ./gradlew clean build
|
- ./gradlew clean build
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- secure: f4Kms/mzkYRG4Kp8k6hsvG3Y0ztbJnA2J79OBw3VdqJOKVTzwsxMd1Yh325YDYO7I4HeHxGXy0H4p3rAPzIWr/nrOJ4wmcDwQYDQtVjF7S1ARWsX51FrCEV6A9ec2LAqNCQ8ZC0SoGb+HsmpFCE3uKAxRQt+B5MzOZvKNcvYpMA=
|
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
||||||
- secure: aF4U20Xlu/rfrbxCmoJAiGh1doYTAZ10UEDmajuinT+ZGSJLivuqD7DDY/00sI6IXWg+J1vL+7jJm4JSYusHPg38UHZ4q92k6RmZycW2ATUzZnGT54O5FRnY67MfVwgVpIMK9UOL/6NEciBHEjlIOL0wbKQiJB++1YtBZOQLGL4=
|
# via the "travis encrypt" command using the project repo's public key
|
||||||
- secure: N+ECSwNg8v2GsAFJ2y/tCiffauHDpN76zuFI2pDqf0fjmCtJZHu4BH5ArXBHjyHKmgn20a/8eZXcwJaH1HsJ80bo7vDJ2miShjGIQ90hPcdmUiB2XVJcew4f04CtvMDH5o7DRt4ykWArlbPL2rhVag0jotlSidolHBwRFnbDhDY=
|
- 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:
|
matrix:
|
||||||
- ANDROID_TARGET=android-19 ANDROID_ABI=armeabi-v7a
|
- 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
|
||||||
|
11
README.md
11
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:
|
The repository holds two main branches with an infinite lifetime:
|
||||||
|
|
||||||
|
- stable
|
||||||
- master
|
- master
|
||||||
- develop
|
|
||||||
|
|
||||||
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.
|
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,9 +35,8 @@ The different types of branches we may use are:
|
|||||||
- Branch __perNewFeature__
|
- Branch __perNewFeature__
|
||||||
- Branch __releaseBranches__
|
- 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
|
|
||||||
|
|
||||||
### License
|
### License
|
||||||
|
|
||||||
|
@ -3,9 +3,10 @@ buildscript {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:1.0.0'
|
classpath 'com.android.tools.build:gradle:1.2.3'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
@ -13,14 +14,12 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile 'commons-httpclient:commons-httpclient:3.1'
|
compile 'org.apache.jackrabbit:jackrabbit-webdav:2.10.1'
|
||||||
compile 'org.apache.jackrabbit:jackrabbit-webdav:2.7.2'
|
|
||||||
compile 'org.slf4j:slf4j-api:1.7.5'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 19
|
compileSdkVersion 19
|
||||||
buildToolsVersion "20.0.0"
|
buildToolsVersion "22.0.1"
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main {
|
main {
|
||||||
|
Binary file not shown.
@ -10,7 +10,7 @@ dependencies {
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 19
|
compileSdkVersion 19
|
||||||
buildToolsVersion "20.0.0"
|
buildToolsVersion "22.0.1"
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main {
|
main {
|
||||||
@ -43,4 +43,9 @@ android {
|
|||||||
packagingOptions {
|
packagingOptions {
|
||||||
exclude 'META-INF/LICENSE.txt'
|
exclude 'META-INF/LICENSE.txt'
|
||||||
}
|
}
|
||||||
|
android {
|
||||||
|
lintOptions {
|
||||||
|
abortOnError false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,13 +49,15 @@ import android.net.Uri;
|
|||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials;
|
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials;
|
||||||
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
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.network.WebdavUtils;
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||||
|
|
||||||
public class OwnCloudClient extends HttpClient {
|
public class OwnCloudClient extends HttpClient {
|
||||||
|
|
||||||
private static final String TAG = OwnCloudClient.class.getSimpleName();
|
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 String PARAM_SINGLE_COOKIE_HEADER = "http.protocol.single-cookie-header";
|
||||||
private static final boolean PARAM_SINGLE_COOKIE_HEADER_VALUE = true;
|
private static final boolean PARAM_SINGLE_COOKIE_HEADER_VALUE = true;
|
||||||
|
|
||||||
@ -68,6 +70,8 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
|
|
||||||
private Uri mBaseUri;
|
private Uri mBaseUri;
|
||||||
|
|
||||||
|
private OwnCloudVersion mVersion = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
@ -173,8 +177,8 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
* @param readTimeout Timeout to set for data reception
|
* @param readTimeout Timeout to set for data reception
|
||||||
* @param connectionTimeout Timeout to set for connection establishment
|
* @param connectionTimeout Timeout to set for connection establishment
|
||||||
*/
|
*/
|
||||||
public int executeMethod(HttpMethodBase method, int readTimeout, int connectionTimeout)
|
public int executeMethod(HttpMethodBase method, int readTimeout, int connectionTimeout) throws IOException {
|
||||||
throws HttpException, IOException {
|
|
||||||
int oldSoTimeout = getParams().getSoTimeout();
|
int oldSoTimeout = getParams().getSoTimeout();
|
||||||
int oldConnectionTimeout = getHttpConnectionManager().getParams().getConnectionTimeout();
|
int oldConnectionTimeout = getHttpConnectionManager().getParams().getConnectionTimeout();
|
||||||
try {
|
try {
|
||||||
@ -193,22 +197,16 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public int executeMethod(HttpMethod method) throws IOException, HttpException {
|
* Requests the received method.
|
||||||
try { // just to log
|
*
|
||||||
boolean customRedirectionNeeded = false;
|
* Executes the method through the inherited HttpClient.executedMethod(method).
|
||||||
|
*
|
||||||
try {
|
* @param method HTTP method request.
|
||||||
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;
|
@Override
|
||||||
}
|
public int executeMethod(HttpMethod method) throws IOException {
|
||||||
|
try {
|
||||||
// Update User Agent
|
// Update User Agent
|
||||||
HttpParams params = method.getParams();
|
HttpParams params = method.getParams();
|
||||||
String userAgent = OwnCloudClientManagerFactory.getUserAgent();
|
String userAgent = OwnCloudClientManagerFactory.getUserAgent();
|
||||||
@ -219,11 +217,12 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
|
|
||||||
// logCookiesAtRequest(method.getRequestHeaders(), "before");
|
// logCookiesAtRequest(method.getRequestHeaders(), "before");
|
||||||
// logCookiesAtState("before");
|
// logCookiesAtState("before");
|
||||||
|
method.setFollowRedirects(false);
|
||||||
|
|
||||||
int status = super.executeMethod(method);
|
int status = super.executeMethod(method);
|
||||||
|
|
||||||
if (customRedirectionNeeded) {
|
if (mFollowRedirects) {
|
||||||
status = patchRedirection(status, method);
|
status = followRedirection(method).getLastStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
// logCookiesAtRequest(method.getRequestHeaders(), "after");
|
// logCookiesAtRequest(method.getRequestHeaders(), "after");
|
||||||
@ -233,13 +232,16 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
return status;
|
return status;
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log_OC.d(TAG + " #" + mInstanceNumber, "Exception occurred", e);
|
//Log_OC.d(TAG + " #" + mInstanceNumber, "Exception occurred", e);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int patchRedirection(int status, HttpMethod method) throws HttpException, IOException {
|
|
||||||
|
public RedirectionPath followRedirection(HttpMethod method) throws IOException {
|
||||||
int redirectionsCount = 0;
|
int redirectionsCount = 0;
|
||||||
|
int status = method.getStatusCode();
|
||||||
|
RedirectionPath result = new RedirectionPath(status, MAX_REDIRECTIONS_COUNT);
|
||||||
while (redirectionsCount < MAX_REDIRECTIONS_COUNT &&
|
while (redirectionsCount < MAX_REDIRECTIONS_COUNT &&
|
||||||
( status == HttpStatus.SC_MOVED_PERMANENTLY ||
|
( status == HttpStatus.SC_MOVED_PERMANENTLY ||
|
||||||
status == HttpStatus.SC_MOVED_TEMPORARILY ||
|
status == HttpStatus.SC_MOVED_TEMPORARILY ||
|
||||||
@ -254,18 +256,20 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
Log_OC.d(TAG + " #" + mInstanceNumber,
|
Log_OC.d(TAG + " #" + mInstanceNumber,
|
||||||
"Location to redirect: " + location.getValue());
|
"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
|
// Release the connection to avoid reach the max number of connections per host
|
||||||
// due to it will be set a different url
|
// due to it will be set a different url
|
||||||
exhaustResponse(method.getResponseBodyAsStream());
|
exhaustResponse(method.getResponseBodyAsStream());
|
||||||
method.releaseConnection();
|
method.releaseConnection();
|
||||||
|
|
||||||
method.setURI(new URI(location.getValue(), true));
|
method.setURI(new URI(locationStr, true));
|
||||||
Header destination = method.getRequestHeader("Destination");
|
Header destination = method.getRequestHeader("Destination");
|
||||||
if (destination == null) {
|
if (destination == null) {
|
||||||
destination = method.getRequestHeader("destination");
|
destination = method.getRequestHeader("destination");
|
||||||
}
|
}
|
||||||
if (destination != null) {
|
if (destination != null) {
|
||||||
String locationStr = location.getValue();
|
|
||||||
int suffixIndex = locationStr.lastIndexOf(
|
int suffixIndex = locationStr.lastIndexOf(
|
||||||
(mCredentials instanceof OwnCloudBearerCredentials) ?
|
(mCredentials instanceof OwnCloudBearerCredentials) ?
|
||||||
AccountUtils.ODAV_PATH :
|
AccountUtils.ODAV_PATH :
|
||||||
@ -281,6 +285,7 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
method.setRequestHeader(destination);
|
method.setRequestHeader(destination);
|
||||||
}
|
}
|
||||||
status = super.executeMethod(method);
|
status = super.executeMethod(method);
|
||||||
|
result.addStatus(status);
|
||||||
redirectionsCount++;
|
redirectionsCount++;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -288,7 +293,7 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
status = HttpStatus.SC_NOT_FOUND;
|
status = HttpStatus.SC_NOT_FOUND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -356,6 +361,9 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
mFollowRedirects = followRedirects;
|
mFollowRedirects = followRedirects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getFollowRedirects() {
|
||||||
|
return mFollowRedirects;
|
||||||
|
}
|
||||||
|
|
||||||
private void logCookiesAtRequest(Header[] headers, String when) {
|
private void logCookiesAtRequest(Header[] headers, String when) {
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
@ -436,4 +444,11 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setOwnCloudVersion(OwnCloudVersion version){
|
||||||
|
mVersion = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OwnCloudVersion getOwnCloudVersion(){
|
||||||
|
return mVersion;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,7 @@ public class OwnCloudClientFactory {
|
|||||||
am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null;
|
am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null;
|
||||||
OwnCloudClient client = createOwnCloudClient(baseUri, appContext, !isSamlSso);
|
OwnCloudClient client = createOwnCloudClient(baseUri, appContext, !isSamlSso);
|
||||||
|
|
||||||
|
String username = account.name.substring(0, account.name.lastIndexOf('@'));
|
||||||
if (isOauth2) {
|
if (isOauth2) {
|
||||||
String accessToken = am.blockingGetAuthToken(
|
String accessToken = am.blockingGetAuthToken(
|
||||||
account,
|
account,
|
||||||
@ -100,11 +101,10 @@ public class OwnCloudClientFactory {
|
|||||||
false);
|
false);
|
||||||
|
|
||||||
client.setCredentials(
|
client.setCredentials(
|
||||||
OwnCloudCredentialsFactory.newSamlSsoCredentials(accessToken)
|
OwnCloudCredentialsFactory.newSamlSsoCredentials(username, accessToken)
|
||||||
);
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
String username = account.name.substring(0, account.name.lastIndexOf('@'));
|
|
||||||
//String password = am.getPassword(account);
|
//String password = am.getPassword(account);
|
||||||
String password = am.blockingGetAuthToken(
|
String password = am.blockingGetAuthToken(
|
||||||
account,
|
account,
|
||||||
@ -137,6 +137,7 @@ public class OwnCloudClientFactory {
|
|||||||
am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null;
|
am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null;
|
||||||
OwnCloudClient client = createOwnCloudClient(baseUri, appContext, !isSamlSso);
|
OwnCloudClient client = createOwnCloudClient(baseUri, appContext, !isSamlSso);
|
||||||
|
|
||||||
|
String username = account.name.substring(0, account.name.lastIndexOf('@'));
|
||||||
if (isOauth2) { // TODO avoid a call to getUserData here
|
if (isOauth2) { // TODO avoid a call to getUserData here
|
||||||
AccountManagerFuture<Bundle> future = am.getAuthToken(
|
AccountManagerFuture<Bundle> future = am.getAuthToken(
|
||||||
account,
|
account,
|
||||||
@ -166,12 +167,11 @@ public class OwnCloudClientFactory {
|
|||||||
String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN);
|
String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN);
|
||||||
if (accessToken == null) throw new AuthenticatorException("WTF!");
|
if (accessToken == null) throw new AuthenticatorException("WTF!");
|
||||||
client.setCredentials(
|
client.setCredentials(
|
||||||
OwnCloudCredentialsFactory.newSamlSsoCredentials(accessToken)
|
OwnCloudCredentialsFactory.newSamlSsoCredentials(username, accessToken)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
String username = account.name.substring(0, account.name.lastIndexOf('@'));
|
|
||||||
//String password = am.getPassword(account);
|
//String password = am.getPassword(account);
|
||||||
//String password = am.blockingGetAuthToken(account, MainApp.getAuthTokenTypePass(),
|
//String password = am.blockingGetAuthToken(account, MainApp.getAuthTokenTypePass(),
|
||||||
// false);
|
// false);
|
||||||
|
@ -36,8 +36,8 @@ public class OwnCloudCredentialsFactory {
|
|||||||
return new OwnCloudBearerCredentials(authToken);
|
return new OwnCloudBearerCredentials(authToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OwnCloudCredentials newSamlSsoCredentials(String sessionCookie) {
|
public static OwnCloudCredentials newSamlSsoCredentials(String username, String sessionCookie) {
|
||||||
return new OwnCloudSamlSsoCredentials(sessionCookie);
|
return new OwnCloudSamlSsoCredentials(username, sessionCookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final OwnCloudCredentials getAnonymousCredentials() {
|
public static final OwnCloudCredentials getAnonymousCredentials() {
|
||||||
|
@ -30,9 +30,11 @@ import android.net.Uri;
|
|||||||
|
|
||||||
public class OwnCloudSamlSsoCredentials implements OwnCloudCredentials {
|
public class OwnCloudSamlSsoCredentials implements OwnCloudCredentials {
|
||||||
|
|
||||||
|
private String mUsername;
|
||||||
private String mSessionCookie;
|
private String mSessionCookie;
|
||||||
|
|
||||||
public OwnCloudSamlSsoCredentials(String sessionCookie) {
|
public OwnCloudSamlSsoCredentials(String username, String sessionCookie) {
|
||||||
|
mUsername = username != null ? username : "";
|
||||||
mSessionCookie = sessionCookie != null ? sessionCookie : "";
|
mSessionCookie = sessionCookie != null ? sessionCookie : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,8 +65,8 @@ public class OwnCloudSamlSsoCredentials implements OwnCloudCredentials {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
// its unknown
|
// not relevant for authentication, but relevant for informational purposes
|
||||||
return null;
|
return mUsername;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -168,6 +168,8 @@ public class AccountUtils {
|
|||||||
account,
|
account,
|
||||||
AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null;
|
AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null;
|
||||||
|
|
||||||
|
String username = account.name.substring(0, account.name.lastIndexOf('@'));
|
||||||
|
|
||||||
if (isOauth2) {
|
if (isOauth2) {
|
||||||
String accessToken = am.blockingGetAuthToken(
|
String accessToken = am.blockingGetAuthToken(
|
||||||
account,
|
account,
|
||||||
@ -182,10 +184,9 @@ public class AccountUtils {
|
|||||||
AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(account.type),
|
AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(account.type),
|
||||||
false);
|
false);
|
||||||
|
|
||||||
credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials(accessToken);
|
credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials(username, accessToken);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
String username = account.name.substring(0, account.name.lastIndexOf('@'));
|
|
||||||
String password = am.blockingGetAuthToken(
|
String password = am.blockingGetAuthToken(
|
||||||
account,
|
account,
|
||||||
AccountTypeUtils.getAuthTokenTypePass(account.type),
|
AccountTypeUtils.getAuthTokenTypePass(account.type),
|
||||||
@ -199,7 +200,7 @@ public class AccountUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String buildAccountName(Uri serverBaseUrl, String username) {
|
public static String buildAccountNameOld(Uri serverBaseUrl, String username) {
|
||||||
if (serverBaseUrl.getScheme() == null) {
|
if (serverBaseUrl.getScheme() == null) {
|
||||||
serverBaseUrl = Uri.parse("https://" + serverBaseUrl.toString());
|
serverBaseUrl = Uri.parse("https://" + serverBaseUrl.toString());
|
||||||
}
|
}
|
||||||
@ -210,6 +211,20 @@ public class AccountUtils {
|
|||||||
return accountName;
|
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) {
|
public static void saveClient(OwnCloudClient client, Account savedAccount, Context context) {
|
||||||
|
|
||||||
@ -336,12 +351,18 @@ public class AccountUtils {
|
|||||||
public static final String KEY_SUPPORTS_SAML_WEB_SSO = "oc_supports_saml_web_sso";
|
public static final String KEY_SUPPORTS_SAML_WEB_SSO = "oc_supports_saml_web_sso";
|
||||||
/**
|
/**
|
||||||
* Flag signaling if the ownCloud server supports Share API"
|
* Flag signaling if the ownCloud server supports Share API"
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public static final String KEY_SUPPORTS_SHARE_API = "oc_supports_share_api";
|
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";
|
public static final String KEY_COOKIES = "oc_account_cookies";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OC account version
|
||||||
|
*/
|
||||||
|
public static final String KEY_OC_ACCOUNT_VERSION = "oc_account_version";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
127
src/com/owncloud/android/lib/common/network/RedirectionPath.java
Normal file
127
src/com/owncloud/android/lib/common/network/RedirectionPath.java
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
/* 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.common.network;
|
||||||
|
|
||||||
|
import org.apache.http.HttpStatus;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aggregate saving the list of URLs followed in a sequence of redirections during the exceution of a
|
||||||
|
* {@link com.owncloud.android.lib.common.operations.RemoteOperation}, and the status codes corresponding to all
|
||||||
|
* of them.
|
||||||
|
*
|
||||||
|
* The last status code saved corresponds to the first response not being a redirection, unless the sequence exceeds
|
||||||
|
* the maximum length of redirections allowed by the {@link com.owncloud.android.lib.common.OwnCloudClient} instance
|
||||||
|
* that ran the operation.
|
||||||
|
*
|
||||||
|
* If no redirection was followed, the last (and first) status code contained corresponds to the original URL in the
|
||||||
|
* request.
|
||||||
|
*/
|
||||||
|
public class RedirectionPath {
|
||||||
|
|
||||||
|
private int[] mStatuses = null;
|
||||||
|
|
||||||
|
private int mLastStatus = -1;
|
||||||
|
|
||||||
|
private String[] mLocations = null;
|
||||||
|
|
||||||
|
private int mLastLocation = -1;
|
||||||
|
private int maxRedirections;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public constructor.
|
||||||
|
*
|
||||||
|
* @param status Status code resulting of executing a request on the original URL.
|
||||||
|
* @param maxRedirections Maximum number of redirections that will be contained.
|
||||||
|
* @throws IllegalArgumentException If 'maxRedirections' is < 0
|
||||||
|
*/
|
||||||
|
public RedirectionPath(int status, int maxRedirections) {
|
||||||
|
if (maxRedirections < 0) {
|
||||||
|
throw new IllegalArgumentException("maxRedirections MUST BE zero or greater");
|
||||||
|
}
|
||||||
|
mStatuses = new int[maxRedirections + 1];
|
||||||
|
Arrays.fill(mStatuses, -1);
|
||||||
|
mStatuses[++mLastStatus] = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new location URL to the list of followed redirections.
|
||||||
|
*
|
||||||
|
* @param location URL extracted from a 'Location' header in a redirection.
|
||||||
|
*/
|
||||||
|
public void addLocation(String location) {
|
||||||
|
if (mLocations == null) {
|
||||||
|
mLocations = new String[mStatuses.length - 1];
|
||||||
|
}
|
||||||
|
if (mLastLocation < mLocations.length - 1) {
|
||||||
|
mLocations[++mLastLocation] = location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new status code to the list of status corresponding to followed redirections.
|
||||||
|
*
|
||||||
|
* @param status Status code from the response of another followed redirection.
|
||||||
|
*/
|
||||||
|
public void addStatus(int status) {
|
||||||
|
if (mLastStatus < mStatuses.length - 1) {
|
||||||
|
mStatuses[++mLastStatus] = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Last status code saved.
|
||||||
|
*/
|
||||||
|
public int getLastStatus() {
|
||||||
|
return mStatuses[mLastStatus];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Last location followed corresponding to a permanent redirection (status code 301).
|
||||||
|
*/
|
||||||
|
public String getLastPermanentLocation() {
|
||||||
|
for (int i = mLastStatus; 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.common.network;
|
package com.owncloud.android.lib.common.network;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import org.apache.jackrabbit.webdav.MultiStatusResponse;
|
import org.apache.jackrabbit.webdav.MultiStatusResponse;
|
||||||
@ -37,6 +38,9 @@ import android.net.Uri;
|
|||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
|
|
||||||
public class WebdavEntry {
|
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 NAMESPACE_OC = "http://owncloud.org/ns";
|
||||||
public static final String EXTENDED_PROPERTY_NAME_PERMISSIONS = "permissions";
|
public static final String EXTENDED_PROPERTY_NAME_PERMISSIONS = "permissions";
|
||||||
public static final String EXTENDED_PROPERTY_NAME_REMOTE_ID = "id";
|
public static final String EXTENDED_PROPERTY_NAME_REMOTE_ID = "id";
|
||||||
@ -49,7 +53,7 @@ public class WebdavEntry {
|
|||||||
|
|
||||||
private String mName, mPath, mUri, mContentType, mEtag, mPermissions, mRemoteId;
|
private String mName, mPath, mUri, mContentType, mEtag, mPermissions, mRemoteId;
|
||||||
private long mContentLength, mCreateTimestamp, mModifiedTimestamp, mSize;
|
private long mContentLength, mCreateTimestamp, mModifiedTimestamp, mSize;
|
||||||
private long mQuotaUsedBytes, mQuotaAvailableBytes;
|
private BigDecimal mQuotaUsedBytes, mQuotaAvailableBytes;
|
||||||
|
|
||||||
public WebdavEntry(MultiStatusResponse ms, String splitElement) {
|
public WebdavEntry(MultiStatusResponse ms, String splitElement) {
|
||||||
resetData();
|
resetData();
|
||||||
@ -125,20 +129,37 @@ public class WebdavEntry {
|
|||||||
prop = propSet.get(DavPropertyName.GETETAG);
|
prop = propSet.get(DavPropertyName.GETETAG);
|
||||||
if (prop != null) {
|
if (prop != null) {
|
||||||
mEtag = (String) prop.getValue();
|
mEtag = (String) prop.getValue();
|
||||||
mEtag = mEtag.substring(1, mEtag.length()-1);
|
mEtag = WebdavUtils.parseEtag(mEtag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// {DAV:}quota-used-bytes
|
// {DAV:}quota-used-bytes
|
||||||
prop = propSet.get(DavPropertyName.create(PROPERTY_QUOTA_USED_BYTES));
|
prop = propSet.get(DavPropertyName.create(PROPERTY_QUOTA_USED_BYTES));
|
||||||
if (prop != null) {
|
if (prop != null) {
|
||||||
mQuotaUsedBytes = Long.parseLong((String) prop.getValue());
|
String quotaUsedBytesSt = (String) prop.getValue();
|
||||||
|
try {
|
||||||
|
mQuotaUsedBytes = new BigDecimal(quotaUsedBytesSt);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// {DAV:}quota-available-bytes
|
// {DAV:}quota-available-bytes
|
||||||
prop = propSet.get(DavPropertyName.create(PROPERTY_QUOTA_AVAILABLE_BYTES));
|
prop = propSet.get(DavPropertyName.create(PROPERTY_QUOTA_AVAILABLE_BYTES));
|
||||||
if (prop != null) {
|
if (prop != null) {
|
||||||
mQuotaAvailableBytes = Long.parseLong((String) prop.getValue());
|
String quotaAvailableBytesSt = (String) prop.getValue();
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
// OC permissions property <oc:permissions>
|
// OC permissions property <oc:permissions>
|
||||||
prop = propSet.get(
|
prop = propSet.get(
|
||||||
EXTENDED_PROPERTY_NAME_PERMISSIONS, Namespace.getNamespace(NAMESPACE_OC)
|
EXTENDED_PROPERTY_NAME_PERMISSIONS, Namespace.getNamespace(NAMESPACE_OC)
|
||||||
@ -222,11 +243,11 @@ public class WebdavEntry {
|
|||||||
return mSize;
|
return mSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long quotaUsedBytes() {
|
public BigDecimal quotaUsedBytes() {
|
||||||
return mQuotaUsedBytes;
|
return mQuotaUsedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long quotaAvailableBytes() {
|
public BigDecimal quotaAvailableBytes() {
|
||||||
return mQuotaAvailableBytes;
|
return mQuotaAvailableBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +255,7 @@ public class WebdavEntry {
|
|||||||
mName = mUri = mContentType = mPermissions = null; mRemoteId = null;
|
mName = mUri = mContentType = mPermissions = null; mRemoteId = null;
|
||||||
mContentLength = mCreateTimestamp = mModifiedTimestamp = 0;
|
mContentLength = mCreateTimestamp = mModifiedTimestamp = 0;
|
||||||
mSize = 0;
|
mSize = 0;
|
||||||
mQuotaUsedBytes = 0;
|
mQuotaUsedBytes = null;
|
||||||
mQuotaAvailableBytes = 0;
|
mQuotaAvailableBytes = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,8 @@ import java.util.Locale;
|
|||||||
|
|
||||||
import android.net.Uri;
|
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.DavPropertyName;
|
||||||
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
|
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
|
||||||
import org.apache.jackrabbit.webdav.xml.Namespace;
|
import org.apache.jackrabbit.webdav.xml.Namespace;
|
||||||
@ -131,4 +133,47 @@ public class WebdavUtils {
|
|||||||
|
|
||||||
return propSet;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,146 @@
|
|||||||
|
|
||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Nodes for XML Parser
|
||||||
|
private static final String NODE_ERROR = "d:error";
|
||||||
|
private static final String NODE_EXCEPTION = "s:exception";
|
||||||
|
/**
|
||||||
|
* Parse is as an Invalid Path Exception
|
||||||
|
* @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) ||
|
||||||
|
exception.equalsIgnoreCase(EXCEPTION_UPLOAD_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;
|
||||||
|
}
|
||||||
|
}
|
@ -24,8 +24,6 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.common.operations;
|
package com.owncloud.android.lib.common.operations;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.accounts.AccountManager;
|
import android.accounts.AccountManager;
|
||||||
import android.accounts.AccountsException;
|
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.operations.RemoteOperationResult.ResultCode;
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
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.
|
* Operation which execution involves one or several interactions with an ownCloud server.
|
||||||
|
@ -24,15 +24,21 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.common.operations;
|
package com.owncloud.android.lib.common.operations;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.ArrayList;
|
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.ConnectTimeoutException;
|
||||||
import org.apache.commons.httpclient.Header;
|
import org.apache.commons.httpclient.Header;
|
||||||
@ -41,17 +47,12 @@ import org.apache.commons.httpclient.HttpStatus;
|
|||||||
import org.apache.jackrabbit.webdav.DavException;
|
import org.apache.jackrabbit.webdav.DavException;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import javax.net.ssl.SSLException;
|
||||||
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;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The result of a remote operation required to an ownCloud server.
|
* The result of a remote operation required to an ownCloud server.
|
||||||
*
|
* <p/>
|
||||||
* Provides a common classification of remote operation results for all the
|
* Provides a common classification of remote operation results for all the
|
||||||
* application.
|
* application.
|
||||||
*
|
*
|
||||||
@ -60,9 +61,9 @@ import com.owncloud.android.lib.common.utils.Log_OC;
|
|||||||
public class RemoteOperationResult implements Serializable {
|
public class RemoteOperationResult implements Serializable {
|
||||||
|
|
||||||
/** Generated - should be refreshed every time the class changes!! */;
|
/** Generated - should be refreshed every time the class changes!! */;
|
||||||
private static final long serialVersionUID = -9003837206000993465L;
|
private static final long serialVersionUID = 1129130415603799707L;
|
||||||
|
|
||||||
private static final String TAG = "RemoteOperationResult";
|
private static final String TAG = RemoteOperationResult.class.getSimpleName();
|
||||||
|
|
||||||
public enum ResultCode {
|
public enum ResultCode {
|
||||||
OK,
|
OK,
|
||||||
@ -103,7 +104,11 @@ public class RemoteOperationResult implements Serializable {
|
|||||||
SHARE_FORBIDDEN,
|
SHARE_FORBIDDEN,
|
||||||
OK_REDIRECT_TO_NON_SECURE_CONNECTION,
|
OK_REDIRECT_TO_NON_SECURE_CONNECTION,
|
||||||
INVALID_MOVE_INTO_DESCENDANT,
|
INVALID_MOVE_INTO_DESCENDANT,
|
||||||
PARTIAL_MOVE_DONE
|
INVALID_COPY_INTO_DESCENDANT,
|
||||||
|
PARTIAL_MOVE_DONE,
|
||||||
|
PARTIAL_COPY_DONE,
|
||||||
|
SHARE_WRONG_PARAMETER,
|
||||||
|
WRONG_SERVER_RESPONSE, INVALID_CHARACTER_DETECT_IN_SERVER
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean mSuccess = false;
|
private boolean mSuccess = false;
|
||||||
@ -112,12 +117,15 @@ public class RemoteOperationResult implements Serializable {
|
|||||||
private ResultCode mCode = ResultCode.UNKNOWN_ERROR;
|
private ResultCode mCode = ResultCode.UNKNOWN_ERROR;
|
||||||
private String mRedirectedLocation;
|
private String mRedirectedLocation;
|
||||||
private String mAuthenticate;
|
private String mAuthenticate;
|
||||||
|
private String mLastPermanentLocation = null;
|
||||||
|
|
||||||
private ArrayList<Object> mData;
|
private ArrayList<Object> mData;
|
||||||
|
|
||||||
public RemoteOperationResult(ResultCode code) {
|
public RemoteOperationResult(ResultCode code) {
|
||||||
mCode = 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;
|
mData = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +158,8 @@ public class RemoteOperationResult implements Serializable {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mCode = ResultCode.UNHANDLED_HTTP_CODE;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,6 +182,37 @@ 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) {
|
public RemoteOperationResult(Exception e) {
|
||||||
mException = e;
|
mException = e;
|
||||||
|
|
||||||
@ -264,7 +304,8 @@ public class RemoteOperationResult implements Serializable {
|
|||||||
}
|
}
|
||||||
Throwable cause = mException.getCause();
|
Throwable cause = mException.getCause();
|
||||||
Throwable previousCause = null;
|
Throwable previousCause = null;
|
||||||
while (cause != null && cause != previousCause && !(cause instanceof CertificateCombinedException)) {
|
while (cause != null && cause != previousCause &&
|
||||||
|
!(cause instanceof CertificateCombinedException)) {
|
||||||
previousCause = cause;
|
previousCause = cause;
|
||||||
cause = cause.getCause();
|
cause = cause.getCause();
|
||||||
}
|
}
|
||||||
@ -314,8 +355,10 @@ public class RemoteOperationResult implements Serializable {
|
|||||||
return "Unrecovered transport exception";
|
return "Unrecovered transport exception";
|
||||||
|
|
||||||
} else if (mException instanceof AccountNotFoundException) {
|
} else if (mException instanceof AccountNotFoundException) {
|
||||||
Account failedAccount = ((AccountNotFoundException)mException).getFailedAccount();
|
Account failedAccount =
|
||||||
return mException.getMessage() + " (" + (failedAccount != null ? failedAccount.name : "NULL") + ")";
|
((AccountNotFoundException)mException).getFailedAccount();
|
||||||
|
return mException.getMessage() + " (" +
|
||||||
|
(failedAccount != null ? failedAccount.name : "NULL") + ")";
|
||||||
|
|
||||||
} else if (mException instanceof AccountsException) {
|
} else if (mException instanceof AccountsException) {
|
||||||
return "Exception while using account";
|
return "Exception while using account";
|
||||||
@ -348,13 +391,19 @@ public class RemoteOperationResult implements Serializable {
|
|||||||
|
|
||||||
} else if (mCode == ResultCode.ACCOUNT_NOT_THE_SAME) {
|
} else if (mCode == ResultCode.ACCOUNT_NOT_THE_SAME) {
|
||||||
return "Authenticated with a different account than the one updating";
|
return "Authenticated with a different account than the one updating";
|
||||||
|
|
||||||
} else if (mCode == ResultCode.INVALID_CHARACTER_IN_NAME) {
|
} else if (mCode == ResultCode.INVALID_CHARACTER_IN_NAME) {
|
||||||
return "The file name contains an forbidden character";
|
return "The file name contains an forbidden character";
|
||||||
|
|
||||||
} else if (mCode == ResultCode.FILE_NOT_FOUND) {
|
} 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") + ")";
|
return "Operation finished with HTTP status code " + mHttpCode + " (" +
|
||||||
|
(isSuccess() ? "success" : "fail") + ")";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,4 +442,12 @@ public class RemoteOperationResult implements Serializable {
|
|||||||
return mAuthenticate;
|
return mAuthenticate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getLastPermanentLocation() {
|
||||||
|
return mLastPermanentLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastPermanentLocation(String lastPermanentLocation) {
|
||||||
|
mLastPermanentLocation = lastPermanentLocation;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,7 @@ public class Log_OC {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void i(String TAG, String message){
|
public static void i(String TAG, String message){
|
||||||
|
Log.i(TAG, message);
|
||||||
// Write the log message to the file
|
|
||||||
appendLog(TAG+" : "+ message);
|
appendLog(TAG+" : "+ message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,6 +100,14 @@ public class Log_OC {
|
|||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if(mBuf != null) {
|
||||||
|
try {
|
||||||
|
mBuf.close();
|
||||||
|
} catch(IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,10 +167,15 @@ public class Log_OC {
|
|||||||
mBuf.newLine();
|
mBuf.newLine();
|
||||||
mBuf.write(text);
|
mBuf.write(text);
|
||||||
mBuf.newLine();
|
mBuf.newLine();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
mBuf.close();
|
mBuf.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if current log file size is bigger than the max file size defined
|
// Check if current log file size is bigger than the max file size defined
|
||||||
if (mLogFile.length() > MAX_FILE_SIZE) {
|
if (mLogFile.length() > MAX_FILE_SIZE) {
|
||||||
|
@ -24,19 +24,21 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.resources.files;
|
package com.owncloud.android.lib.resources.files;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import org.apache.commons.httpclient.HttpException;
|
|
||||||
import org.apache.commons.httpclient.methods.PutMethod;
|
import org.apache.commons.httpclient.methods.PutMethod;
|
||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.network.ChunkFromFileChannelRequestEntity;
|
import com.owncloud.android.lib.common.network.ChunkFromFileChannelRequestEntity;
|
||||||
import com.owncloud.android.lib.common.network.ProgressiveDataTransferer;
|
import com.owncloud.android.lib.common.network.ProgressiveDataTransferer;
|
||||||
import com.owncloud.android.lib.common.network.WebdavUtils;
|
import com.owncloud.android.lib.common.network.WebdavUtils;
|
||||||
|
import com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser;
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
|
|
||||||
|
|
||||||
@ -44,14 +46,21 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation
|
|||||||
|
|
||||||
public static final long CHUNK_SIZE = 1024000;
|
public static final long CHUNK_SIZE = 1024000;
|
||||||
private static final String OC_CHUNKED_HEADER = "OC-Chunked";
|
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();
|
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);
|
super(storagePath, remotePath, mimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ChunkedUploadRemoteFileOperation(
|
||||||
|
String storagePath, String remotePath, String mimeType, String requiredEtag
|
||||||
|
){
|
||||||
|
super(storagePath, remotePath, mimeType, requiredEtag);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int uploadFile(OwnCloudClient client) throws HttpException, IOException {
|
protected int uploadFile(OwnCloudClient client) throws IOException {
|
||||||
int status = -1;
|
int status = -1;
|
||||||
|
|
||||||
FileChannel channel = null;
|
FileChannel channel = null;
|
||||||
@ -61,25 +70,60 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation
|
|||||||
raf = new RandomAccessFile(file, "r");
|
raf = new RandomAccessFile(file, "r");
|
||||||
channel = raf.getChannel();
|
channel = raf.getChannel();
|
||||||
mEntity = new ChunkFromFileChannelRequestEntity(channel, mMimeType, CHUNK_SIZE, file);
|
mEntity = new ChunkFromFileChannelRequestEntity(channel, mMimeType, CHUNK_SIZE, file);
|
||||||
//((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(getDataTransferListeners());
|
|
||||||
synchronized (mDataTransferListeners) {
|
synchronized (mDataTransferListeners) {
|
||||||
((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(mDataTransferListeners);
|
((ProgressiveDataTransferer)mEntity)
|
||||||
|
.addDatatransferProgressListeners(mDataTransferListeners);
|
||||||
}
|
}
|
||||||
|
|
||||||
long offset = 0;
|
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) +
|
||||||
long chunkCount = (long) Math.ceil((double)file.length() / CHUNK_SIZE);
|
"-chunking-" + Math.abs((new Random()).nextInt(9000)+1000) + "-" ;
|
||||||
|
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) {
|
for (int chunkIndex = 0; chunkIndex < chunkCount ; chunkIndex++, offset += CHUNK_SIZE) {
|
||||||
|
if (chunkIndex == chunkCount - 1) {
|
||||||
|
chunkSizeStr = String.valueOf(CHUNK_SIZE * chunkCount - totalLength);
|
||||||
|
}
|
||||||
if (mPutMethod != null) {
|
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 = 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_CHUNKED_HEADER, OC_CHUNKED_HEADER);
|
||||||
|
mPutMethod.addRequestHeader(OC_CHUNK_SIZE_HEADER, chunkSizeStr);
|
||||||
|
mPutMethod.addRequestHeader(OC_TOTAL_LENGTH_HEADER, totalLengthStr);
|
||||||
((ChunkFromFileChannelRequestEntity) mEntity).setOffset(offset);
|
((ChunkFromFileChannelRequestEntity) mEntity).setOffset(offset);
|
||||||
mPutMethod.setRequestEntity(mEntity);
|
mPutMethod.setRequestEntity(mEntity);
|
||||||
|
if (mCancellationRequested.get()) {
|
||||||
|
mPutMethod.abort();
|
||||||
|
// next method will throw an exception
|
||||||
|
}
|
||||||
status = client.executeMethod(mPutMethod);
|
status = client.executeMethod(mPutMethod);
|
||||||
|
|
||||||
|
if (status == 400) {
|
||||||
|
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());
|
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))
|
if (!isSuccess(status))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
* <p/>
|
||||||
|
* 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.
|
||||||
|
* <p/>
|
||||||
|
* 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_COPY_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 if (status == 400) {
|
||||||
|
result = new RemoteOperationResult(copyMethod.succeeded(),
|
||||||
|
copyMethod.getResponseBodyAsString(), status);
|
||||||
|
} 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.
|
||||||
|
* <p/>
|
||||||
|
* In WebDAV, a COPY request on collections (folders) can be PARTIALLY successful: some
|
||||||
|
* children are copied, some other aren't.
|
||||||
|
* <p/>
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.resources.files;
|
package com.owncloud.android.lib.resources.files;
|
||||||
|
|
||||||
import org.apache.commons.httpclient.HttpStatus;
|
|
||||||
import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
|
import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
|
||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
@ -33,7 +32,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;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
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
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param remotePath Full path to the new directory to create in the remote server.
|
* @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) {
|
public CreateRemoteFolderOperation(String remotePath, boolean createFullPath) {
|
||||||
mRemotePath = remotePath;
|
mRemotePath = remotePath;
|
||||||
@ -73,7 +73,10 @@ public class CreateRemoteFolderOperation extends RemoteOperation {
|
|||||||
@Override
|
@Override
|
||||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||||
RemoteOperationResult result = null;
|
RemoteOperationResult result = null;
|
||||||
boolean noInvalidChars = FileUtils.isValidPath(mRemotePath);
|
OwnCloudVersion version = client.getOwnCloudVersion();
|
||||||
|
boolean versionWithForbiddenChars =
|
||||||
|
(version != null && version.isVersionWithForbiddenCharacters());
|
||||||
|
boolean noInvalidChars = FileUtils.isValidPath(mRemotePath, versionWithForbiddenChars);
|
||||||
if (noInvalidChars) {
|
if (noInvalidChars) {
|
||||||
result = createFolder(client);
|
result = createFolder(client);
|
||||||
if (!result.isSuccess() && mCreateFullPath &&
|
if (!result.isSuccess() && mCreateFullPath &&
|
||||||
@ -98,8 +101,16 @@ public class CreateRemoteFolderOperation extends RemoteOperation {
|
|||||||
try {
|
try {
|
||||||
mkcol = new MkColMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
|
mkcol = new MkColMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
|
||||||
int status = client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT);
|
int status = client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT);
|
||||||
result = new RemoteOperationResult(mkcol.succeeded(), status, mkcol.getResponseHeaders());
|
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());
|
Log_OC.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage());
|
||||||
|
}
|
||||||
client.exhaustResponse(mkcol.getResponseBodyAsStream());
|
client.exhaustResponse(mkcol.getResponseBodyAsStream());
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -61,6 +61,7 @@ public class DownloadRemoteFileOperation extends RemoteOperation {
|
|||||||
private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
|
private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
|
||||||
private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
|
private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
|
||||||
private long mModificationTimestamp = 0;
|
private long mModificationTimestamp = 0;
|
||||||
|
private String mEtag = "";
|
||||||
private GetMethod mGet;
|
private GetMethod mGet;
|
||||||
|
|
||||||
private String mRemotePath;
|
private String mRemotePath;
|
||||||
@ -140,12 +141,24 @@ public class DownloadRemoteFileOperation extends RemoteOperation {
|
|||||||
if (transferred == totalToTransfer) { // Check if the file is completed
|
if (transferred == totalToTransfer) { // Check if the file is completed
|
||||||
savedFile = true;
|
savedFile = true;
|
||||||
Header modificationTime = mGet.getResponseHeader("Last-Modified");
|
Header modificationTime = mGet.getResponseHeader("Last-Modified");
|
||||||
|
if (modificationTime == null) {
|
||||||
|
modificationTime = mGet.getResponseHeader("last-modified");
|
||||||
|
}
|
||||||
if (modificationTime != null) {
|
if (modificationTime != null) {
|
||||||
Date d = WebdavUtils.parseResponseDate((String) modificationTime.getValue());
|
Date d = WebdavUtils.parseResponseDate((String) modificationTime.getValue());
|
||||||
mModificationTimestamp = (d != null) ? d.getTime() : 0;
|
mModificationTimestamp = (d != null) ? d.getTime() : 0;
|
||||||
|
} else {
|
||||||
|
Log_OC.e(TAG, "Could not read modification time from response downloading " + mRemotePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mEtag = WebdavUtils.getEtagFromResponse(mGet);
|
||||||
|
if (mEtag.length() == 0) {
|
||||||
|
Log_OC.e(TAG, "Could not read eTag from response downloading " + mRemotePath);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
client.exhaustResponse(mGet.getResponseBodyAsStream());
|
client.exhaustResponse(mGet.getResponseBodyAsStream());
|
||||||
|
// TODO some kind of error control!
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -190,4 +203,7 @@ public class DownloadRemoteFileOperation extends RemoteOperation {
|
|||||||
return mModificationTimestamp;
|
return mModificationTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getEtag() {
|
||||||
|
return mEtag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,9 @@ import org.apache.commons.httpclient.HttpStatus;
|
|||||||
import org.apache.commons.httpclient.methods.HeadMethod;
|
import org.apache.commons.httpclient.methods.HeadMethod;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
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.network.WebdavUtils;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||||
@ -49,9 +49,23 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation {
|
|||||||
private static final String TAG = ExistenceCheckRemoteOperation.class.getSimpleName();
|
private static final String TAG = ExistenceCheckRemoteOperation.class.getSimpleName();
|
||||||
|
|
||||||
private String mPath;
|
private String mPath;
|
||||||
private Context mContext;
|
|
||||||
private boolean mSuccessIfAbsent;
|
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.
|
||||||
|
*
|
||||||
|
* @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, boolean successIfAbsent) {
|
||||||
|
mPath = (remotePath != null) ? remotePath : "";
|
||||||
|
mSuccessIfAbsent = successIfAbsent;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Full constructor. Success of the operation will depend upon the value of successIfAbsent.
|
* Full constructor. Success of the operation will depend upon the value of successIfAbsent.
|
||||||
@ -60,24 +74,25 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation {
|
|||||||
* @param context Android application context.
|
* @param context Android application context.
|
||||||
* @param successIfAbsent When 'true', the operation finishes in success if the path does
|
* @param successIfAbsent When 'true', the operation finishes in success if the path does
|
||||||
* NOT exist in the remote server (HTTP 404).
|
* NOT exist in the remote server (HTTP 404).
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public ExistenceCheckRemoteOperation(String remotePath, Context context, boolean successIfAbsent) {
|
public ExistenceCheckRemoteOperation(String remotePath, Context context, boolean successIfAbsent) {
|
||||||
mPath = (remotePath != null) ? remotePath : "";
|
this(remotePath, successIfAbsent);
|
||||||
mContext = context;
|
|
||||||
mSuccessIfAbsent = successIfAbsent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||||
if (!isOnline()) {
|
|
||||||
return new RemoteOperationResult(RemoteOperationResult.ResultCode.NO_NETWORK_CONNECTION);
|
|
||||||
}
|
|
||||||
RemoteOperationResult result = null;
|
RemoteOperationResult result = null;
|
||||||
HeadMethod head = null;
|
HeadMethod head = null;
|
||||||
|
boolean previousFollowRedirects = client.getFollowRedirects();
|
||||||
try {
|
try {
|
||||||
head = new HeadMethod(client.getWebdavUri() + WebdavUtils.encodePath(mPath));
|
head = new HeadMethod(client.getWebdavUri() + WebdavUtils.encodePath(mPath));
|
||||||
|
client.setFollowRedirects(false);
|
||||||
int status = client.executeMethod(head, TIMEOUT, TIMEOUT);
|
int status = client.executeMethod(head, TIMEOUT, TIMEOUT);
|
||||||
|
if (previousFollowRedirects) {
|
||||||
|
mRedirectionPath = client.followRedirection(head);
|
||||||
|
status = mRedirectionPath.getLastStatus();
|
||||||
|
}
|
||||||
client.exhaustResponse(head.getResponseBodyAsStream());
|
client.exhaustResponse(head.getResponseBodyAsStream());
|
||||||
boolean success = (status == HttpStatus.SC_OK && !mSuccessIfAbsent) ||
|
boolean success = (status == HttpStatus.SC_OK && !mSuccessIfAbsent) ||
|
||||||
(status == HttpStatus.SC_NOT_FOUND && mSuccessIfAbsent);
|
(status == HttpStatus.SC_NOT_FOUND && mSuccessIfAbsent);
|
||||||
@ -97,16 +112,25 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation {
|
|||||||
} finally {
|
} finally {
|
||||||
if (head != null)
|
if (head != null)
|
||||||
head.releaseConnection();
|
head.releaseConnection();
|
||||||
|
client.setFollowRedirects(previousFollowRedirects);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isOnline() {
|
|
||||||
ConnectivityManager cm = (ConnectivityManager) mContext
|
/**
|
||||||
.getSystemService(Context.CONNECTIVITY_SERVICE);
|
* Gets the sequence of redirections followed during the execution of the operation.
|
||||||
return cm != null && cm.getActiveNetworkInfo() != null
|
*
|
||||||
&& cm.getActiveNetworkInfo().isConnectedOrConnecting();
|
* @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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,12 @@ package com.owncloud.android.lib.resources.files;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||||
|
|
||||||
public class FileUtils {
|
public class FileUtils {
|
||||||
|
|
||||||
|
private static final String TAG = FileUtils.class.getSimpleName();
|
||||||
|
|
||||||
public static final String PATH_SEPARATOR = "/";
|
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 fileName
|
||||||
|
* @param versionSupportsForbiddenChars
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static boolean isValidName(String fileName) {
|
public static boolean isValidName(String fileName, boolean versionSupportsForbiddenChars) {
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
|
|
||||||
Log_OC.d("FileUtils", "fileName =======" + fileName);
|
Log_OC.d(TAG, "fileName =======" + fileName);
|
||||||
if (fileName.contains(PATH_SEPARATOR) ||
|
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("?") || fileName.contains("*")) {
|
fileName.contains("?") || fileName.contains("*") ) ) ) {
|
||||||
|
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate the path to detect if contains any forbidden character: \ , < , > , : , " , | , ? , *
|
* Validate the path to detect if contains any forbidden character: \ , < , > , : , " , | ,
|
||||||
|
* ? , *
|
||||||
* @param path
|
* @param path
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static boolean isValidPath(String path) {
|
public static boolean isValidPath(String path, boolean versionSupportsForbidenChars) {
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
|
|
||||||
Log_OC.d("FileUtils", "path ....... " + path);
|
Log_OC.d(TAG, "path ....... " + path);
|
||||||
if (path.contains("\\") || path.contains("<") || path.contains(">") ||
|
if (!versionSupportsForbidenChars &&
|
||||||
|
(path.contains("\\") || path.contains("<") || path.contains(">") ||
|
||||||
path.contains(":") || path.contains("\"") || path.contains("|") ||
|
path.contains(":") || path.contains("\"") || path.contains("|") ||
|
||||||
path.contains("?") || path.contains("*")) {
|
path.contains("?") || path.contains("*") ) ){
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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.RemoteOperation;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
||||||
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,8 +89,12 @@ public class MoveRemoteFileOperation extends RemoteOperation {
|
|||||||
@Override
|
@Override
|
||||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||||
|
|
||||||
|
OwnCloudVersion version = client.getOwnCloudVersion();
|
||||||
|
boolean versionWithForbiddenChars =
|
||||||
|
(version != null && version.isVersionWithForbiddenCharacters());
|
||||||
|
|
||||||
/// check parameters
|
/// check parameters
|
||||||
if (!FileUtils.isValidPath(mTargetRemotePath)) {
|
if (!FileUtils.isValidPath(mTargetRemotePath, versionWithForbiddenChars)) {
|
||||||
return new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME);
|
return new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,8 +133,10 @@ public class MoveRemoteFileOperation extends RemoteOperation {
|
|||||||
/// for other errors that could be explicitly handled, check first:
|
/// for other errors that could be explicitly handled, check first:
|
||||||
/// http://www.webdav.org/specs/rfc4918.html#rfc.section.9.9.4
|
/// http://www.webdav.org/specs/rfc4918.html#rfc.section.9.9.4
|
||||||
|
|
||||||
|
} else if (status == 400) {
|
||||||
|
result = new RemoteOperationResult(move.succeeded(),
|
||||||
|
move.getResponseBodyAsString(), status);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
result = new RemoteOperationResult(
|
result = new RemoteOperationResult(
|
||||||
isSuccess(status), // move.succeeded()? trustful?
|
isSuccess(status), // move.succeeded()? trustful?
|
||||||
status,
|
status,
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
package com.owncloud.android.lib.resources.files;
|
package com.owncloud.android.lib.resources.files;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
@ -51,8 +52,8 @@ public class RemoteFile implements Parcelable, Serializable {
|
|||||||
private String mPermissions;
|
private String mPermissions;
|
||||||
private String mRemoteId;
|
private String mRemoteId;
|
||||||
private long mSize;
|
private long mSize;
|
||||||
private long mQuotaUsedBytes;
|
private BigDecimal mQuotaUsedBytes;
|
||||||
private long mQuotaAvailableBytes;
|
private BigDecimal mQuotaAvailableBytes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getters and Setters
|
* Getters and Setters
|
||||||
@ -130,11 +131,11 @@ public class RemoteFile implements Parcelable, Serializable {
|
|||||||
mSize = size;
|
mSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setQuotaUsedBytes (long quotaUsedBytes) {
|
public void setQuotaUsedBytes (BigDecimal quotaUsedBytes) {
|
||||||
mQuotaUsedBytes = quotaUsedBytes;
|
mQuotaUsedBytes = quotaUsedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setQuotaAvailableBytes (long quotaAvailableBytes) {
|
public void setQuotaAvailableBytes (BigDecimal quotaAvailableBytes) {
|
||||||
mQuotaAvailableBytes = quotaAvailableBytes;
|
mQuotaAvailableBytes = quotaAvailableBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,8 +185,8 @@ public class RemoteFile implements Parcelable, Serializable {
|
|||||||
mPermissions = null;
|
mPermissions = null;
|
||||||
mRemoteId = null;
|
mRemoteId = null;
|
||||||
mSize = 0;
|
mSize = 0;
|
||||||
mQuotaUsedBytes = 0;
|
mQuotaUsedBytes = null;
|
||||||
mQuotaAvailableBytes = 0;
|
mQuotaAvailableBytes = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -223,8 +224,8 @@ public class RemoteFile implements Parcelable, Serializable {
|
|||||||
mPermissions= source.readString();
|
mPermissions= source.readString();
|
||||||
mRemoteId = source.readString();
|
mRemoteId = source.readString();
|
||||||
mSize = source.readLong();
|
mSize = source.readLong();
|
||||||
mQuotaUsedBytes = source.readLong();
|
mQuotaUsedBytes = (BigDecimal) source.readSerializable();
|
||||||
mQuotaAvailableBytes = source.readLong();
|
mQuotaAvailableBytes = (BigDecimal) source.readSerializable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -243,8 +244,8 @@ public class RemoteFile implements Parcelable, Serializable {
|
|||||||
dest.writeString(mPermissions);
|
dest.writeString(mPermissions);
|
||||||
dest.writeString(mRemoteId);
|
dest.writeString(mRemoteId);
|
||||||
dest.writeLong(mSize);
|
dest.writeLong(mSize);
|
||||||
dest.writeLong(mQuotaUsedBytes);
|
dest.writeSerializable(mQuotaUsedBytes);
|
||||||
dest.writeLong(mQuotaAvailableBytes);
|
dest.writeSerializable(mQuotaAvailableBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,16 +90,17 @@ public class RenameRemoteFileOperation extends RemoteOperation {
|
|||||||
|
|
||||||
LocalMoveMethod move = null;
|
LocalMoveMethod move = null;
|
||||||
|
|
||||||
boolean noInvalidChars = FileUtils.isValidPath(mNewRemotePath);
|
OwnCloudVersion version = client.getOwnCloudVersion();
|
||||||
|
boolean versionWithForbiddenChars =
|
||||||
|
(version != null && version.isVersionWithForbiddenCharacters());
|
||||||
|
boolean noInvalidChars = FileUtils.isValidPath(mNewRemotePath, versionWithForbiddenChars);
|
||||||
|
|
||||||
if (noInvalidChars) {
|
if (noInvalidChars) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (mNewName.equals(mOldName)) {
|
if (mNewName.equals(mOldName)) {
|
||||||
return new RemoteOperationResult(ResultCode.OK);
|
return new RemoteOperationResult(ResultCode.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// check if a file with the new name already exists
|
// check if a file with the new name already exists
|
||||||
if (client.existsFile(mNewRemotePath)) {
|
if (client.existsFile(mNewRemotePath)) {
|
||||||
return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE);
|
return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE);
|
||||||
@ -107,13 +109,21 @@ public class RenameRemoteFileOperation extends RemoteOperation {
|
|||||||
move = new LocalMoveMethod( client.getWebdavUri() +
|
move = new LocalMoveMethod( client.getWebdavUri() +
|
||||||
WebdavUtils.encodePath(mOldRemotePath),
|
WebdavUtils.encodePath(mOldRemotePath),
|
||||||
client.getWebdavUri() + WebdavUtils.encodePath(mNewRemotePath));
|
client.getWebdavUri() + WebdavUtils.encodePath(mNewRemotePath));
|
||||||
int status = client.executeMethod(move, RENAME_READ_TIMEOUT, RENAME_CONNECTION_TIMEOUT);
|
int status = client.executeMethod(move, RENAME_READ_TIMEOUT,
|
||||||
|
RENAME_CONNECTION_TIMEOUT);
|
||||||
|
|
||||||
move.getResponseBodyAsString(); // exhaust response, although not interesting
|
if (status == 400) {
|
||||||
result = new RemoteOperationResult(move.succeeded(), status, move.getResponseHeaders());
|
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 + ": " +
|
Log_OC.i(TAG, "Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " +
|
||||||
result.getLogMessage());
|
result.getLogMessage());
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
result = new RemoteOperationResult(e);
|
result = new RemoteOperationResult(e);
|
||||||
Log_OC.e(TAG, "Rename " + mOldRemotePath + " to " +
|
Log_OC.e(TAG, "Rename " + mOldRemotePath + " to " +
|
||||||
@ -124,6 +134,7 @@ public class RenameRemoteFileOperation extends RemoteOperation {
|
|||||||
if (move != null)
|
if (move != null)
|
||||||
move.releaseConnection();
|
move.releaseConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
result = new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME);
|
result = new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME);
|
||||||
}
|
}
|
||||||
|
@ -24,13 +24,14 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.resources.files;
|
package com.owncloud.android.lib.resources.files;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
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.PutMethod;
|
||||||
import org.apache.commons.httpclient.methods.RequestEntity;
|
import org.apache.commons.httpclient.methods.RequestEntity;
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
@ -40,9 +41,11 @@ import com.owncloud.android.lib.common.network.FileRequestEntity;
|
|||||||
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
|
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
|
||||||
import com.owncloud.android.lib.common.network.ProgressiveDataTransferer;
|
import com.owncloud.android.lib.common.network.ProgressiveDataTransferer;
|
||||||
import com.owncloud.android.lib.common.network.WebdavUtils;
|
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.OperationCancelledException;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
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.
|
* Remote operation performing the upload of a remote file to the ownCloud server.
|
||||||
@ -53,13 +56,19 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
|||||||
|
|
||||||
public class UploadRemoteFileOperation extends RemoteOperation {
|
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 mLocalPath;
|
||||||
protected String mRemotePath;
|
protected String mRemotePath;
|
||||||
protected String mMimeType;
|
protected String mMimeType;
|
||||||
protected PutMethod mPutMethod = null;
|
protected PutMethod mPutMethod = null;
|
||||||
|
protected boolean mForbiddenCharsInServer = false;
|
||||||
|
protected String mRequiredEtag = null;
|
||||||
|
|
||||||
private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
|
protected final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
|
||||||
protected Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
|
protected Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
|
||||||
|
|
||||||
protected RequestEntity mEntity = null;
|
protected RequestEntity mEntity = null;
|
||||||
@ -70,30 +79,38 @@ public class UploadRemoteFileOperation extends RemoteOperation {
|
|||||||
mMimeType = mimeType;
|
mMimeType = mimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UploadRemoteFileOperation(String localPath, String remotePath, String mimeType, String requiredEtag) {
|
||||||
|
this(localPath, remotePath, mimeType);
|
||||||
|
mRequiredEtag = requiredEtag;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||||
RemoteOperationResult result = null;
|
RemoteOperationResult result = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// / perform the upload
|
mPutMethod = new PutMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
|
||||||
synchronized (mCancellationRequested) {
|
|
||||||
if (mCancellationRequested.get()) {
|
if (mCancellationRequested.get()) {
|
||||||
throw new OperationCancelledException();
|
// the operation was cancelled before getting it's turn to be executed in the queue of uploads
|
||||||
|
result = new RemoteOperationResult(new OperationCancelledException());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
mPutMethod = new PutMethod(client.getWebdavUri() +
|
// perform the upload
|
||||||
WebdavUtils.encodePath(mRemotePath));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int status = uploadFile(client);
|
int status = uploadFile(client);
|
||||||
|
if (mForbiddenCharsInServer){
|
||||||
|
result = new RemoteOperationResult(
|
||||||
|
RemoteOperationResult.ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER);
|
||||||
|
} else {
|
||||||
result = new RemoteOperationResult(isSuccess(status), status,
|
result = new RemoteOperationResult(isSuccess(status), status,
|
||||||
(mPutMethod != null ? mPutMethod.getResponseHeaders() : null));
|
(mPutMethod != null ? mPutMethod.getResponseHeaders() : null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// TODO something cleaner with cancellations
|
if (mPutMethod != null && mPutMethod.isAborted()) {
|
||||||
if (mCancellationRequested.get()) {
|
|
||||||
result = new RemoteOperationResult(new OperationCancelledException());
|
result = new RemoteOperationResult(new OperationCancelledException());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
result = new RemoteOperationResult(e);
|
result = new RemoteOperationResult(e);
|
||||||
}
|
}
|
||||||
@ -106,8 +123,7 @@ public class UploadRemoteFileOperation extends RemoteOperation {
|
|||||||
status == HttpStatus.SC_NO_CONTENT));
|
status == HttpStatus.SC_NO_CONTENT));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int uploadFile(OwnCloudClient client) throws HttpException, IOException,
|
protected int uploadFile(OwnCloudClient client) throws IOException {
|
||||||
OperationCancelledException {
|
|
||||||
int status = -1;
|
int status = -1;
|
||||||
try {
|
try {
|
||||||
File f = new File(mLocalPath);
|
File f = new File(mLocalPath);
|
||||||
@ -116,8 +132,26 @@ public class UploadRemoteFileOperation extends RemoteOperation {
|
|||||||
((ProgressiveDataTransferer)mEntity)
|
((ProgressiveDataTransferer)mEntity)
|
||||||
.addDatatransferProgressListeners(mDataTransferListeners);
|
.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);
|
mPutMethod.setRequestEntity(mEntity);
|
||||||
status = client.executeMethod(mPutMethod);
|
status = client.executeMethod(mPutMethod);
|
||||||
|
|
||||||
|
if (status == 400) {
|
||||||
|
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());
|
client.exhaustResponse(mPutMethod.getResponseBodyAsStream());
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
/* ownCloud Android Library is available under MIT license
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
* @author masensio
|
||||||
|
* @author David A. Velasco
|
||||||
* Copyright (C) 2015 ownCloud Inc.
|
* Copyright (C) 2015 ownCloud Inc.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
@ -24,24 +26,16 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.resources.shares;
|
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.commons.httpclient.methods.PostMethod;
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
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.common.utils.Log_OC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new share. This allows sharing with a user or group or as a link.
|
* Creates a new share. This allows sharing with a user or group or as a link.
|
||||||
*
|
|
||||||
* @author masensio
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class CreateRemoteShareOperation extends RemoteOperation {
|
public class CreateRemoteShareOperation extends RemoteOperation {
|
||||||
|
|
||||||
@ -54,20 +48,20 @@ public class CreateRemoteShareOperation extends RemoteOperation {
|
|||||||
private static final String PARAM_PASSWORD = "password";
|
private static final String PARAM_PASSWORD = "password";
|
||||||
private static final String PARAM_PERMISSIONS = "permissions";
|
private static final String PARAM_PERMISSIONS = "permissions";
|
||||||
|
|
||||||
private ArrayList<OCShare> mShares; // List of shares for result, one share in this case
|
|
||||||
|
|
||||||
private String mRemoteFilePath;
|
private String mRemoteFilePath;
|
||||||
private ShareType mShareType;
|
private ShareType mShareType;
|
||||||
private String mShareWith;
|
private String mShareWith;
|
||||||
private boolean mPublicUpload;
|
private boolean mPublicUpload;
|
||||||
private String mPassword;
|
private String mPassword;
|
||||||
private int mPermissions;
|
private int mPermissions;
|
||||||
|
private boolean mGetShareDetails;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param remoteFilePath Full path of the file/folder being shared. Mandatory argument
|
* @param remoteFilePath Full path of the file/folder being shared. Mandatory argument
|
||||||
* @param shareType 0 = user, 1 = group, 3 = Public link. 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.
|
* @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
|
* 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
|
* @param password Password to protect a public link share. Only available for public link shares
|
||||||
@ -81,8 +75,14 @@ public class CreateRemoteShareOperation extends RemoteOperation {
|
|||||||
* To obtain combinations, add the desired values together.
|
* To obtain combinations, add the desired values together.
|
||||||
* For instance, for Re-Share, delete, read, update, add 16+8+2+1 = 27.
|
* For instance, for Re-Share, delete, read, update, add 16+8+2+1 = 27.
|
||||||
*/
|
*/
|
||||||
public CreateRemoteShareOperation(String remoteFilePath, ShareType shareType, String shareWith, boolean publicUpload,
|
public CreateRemoteShareOperation(
|
||||||
String password, int permissions) {
|
String remoteFilePath,
|
||||||
|
ShareType shareType,
|
||||||
|
String shareWith,
|
||||||
|
boolean publicUpload,
|
||||||
|
String password,
|
||||||
|
int permissions
|
||||||
|
) {
|
||||||
|
|
||||||
mRemoteFilePath = remoteFilePath;
|
mRemoteFilePath = remoteFilePath;
|
||||||
mShareType = shareType;
|
mShareType = shareType;
|
||||||
@ -90,6 +90,15 @@ public class CreateRemoteShareOperation extends RemoteOperation {
|
|||||||
mPublicUpload = publicUpload;
|
mPublicUpload = publicUpload;
|
||||||
mPassword = password;
|
mPassword = password;
|
||||||
mPermissions = permissions;
|
mPermissions = permissions;
|
||||||
|
mGetShareDetails = false; // defaults to false for backwards compatibility
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGettingShareDetails () {
|
||||||
|
return mGetShareDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGetShareDetails(boolean set) {
|
||||||
|
mGetShareDetails = set;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -102,7 +111,6 @@ public class CreateRemoteShareOperation extends RemoteOperation {
|
|||||||
try {
|
try {
|
||||||
// Post Method
|
// Post Method
|
||||||
post = new PostMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH);
|
post = new PostMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH);
|
||||||
//Log_OC.d(TAG, "URL ------> " + client.getBaseUri() + ShareUtils.SHARING_API_PATH);
|
|
||||||
|
|
||||||
post.setRequestHeader( "Content-Type",
|
post.setRequestHeader( "Content-Type",
|
||||||
"application/x-www-form-urlencoded; charset=utf-8"); // necessary for special characters
|
"application/x-www-form-urlencoded; charset=utf-8"); // necessary for special characters
|
||||||
@ -110,11 +118,15 @@ public class CreateRemoteShareOperation extends RemoteOperation {
|
|||||||
post.addParameter(PARAM_PATH, mRemoteFilePath);
|
post.addParameter(PARAM_PATH, mRemoteFilePath);
|
||||||
post.addParameter(PARAM_SHARE_TYPE, Integer.toString(mShareType.getValue()));
|
post.addParameter(PARAM_SHARE_TYPE, Integer.toString(mShareType.getValue()));
|
||||||
post.addParameter(PARAM_SHARE_WITH, mShareWith);
|
post.addParameter(PARAM_SHARE_WITH, mShareWith);
|
||||||
post.addParameter(PARAM_PUBLIC_UPLOAD, Boolean.toString(mPublicUpload));
|
if (mPublicUpload) {
|
||||||
|
post.addParameter(PARAM_PUBLIC_UPLOAD, Boolean.toString(true));
|
||||||
|
}
|
||||||
if (mPassword != null && mPassword.length() > 0) {
|
if (mPassword != null && mPassword.length() > 0) {
|
||||||
post.addParameter(PARAM_PASSWORD, mPassword);
|
post.addParameter(PARAM_PASSWORD, mPassword);
|
||||||
}
|
}
|
||||||
|
if (OCShare.DEFAULT_PERMISSION != mPermissions) {
|
||||||
post.addParameter(PARAM_PERMISSIONS, Integer.toString(mPermissions));
|
post.addParameter(PARAM_PERMISSIONS, Integer.toString(mPermissions));
|
||||||
|
}
|
||||||
|
|
||||||
post.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
|
post.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
|
||||||
|
|
||||||
@ -123,31 +135,21 @@ public class CreateRemoteShareOperation extends RemoteOperation {
|
|||||||
if(isSuccess(status)) {
|
if(isSuccess(status)) {
|
||||||
String response = post.getResponseBodyAsString();
|
String response = post.getResponseBodyAsString();
|
||||||
|
|
||||||
result = new RemoteOperationResult(ResultCode.OK);
|
ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
|
||||||
|
new ShareXMLParser()
|
||||||
|
);
|
||||||
|
parser.setOneOrMoreSharesRequired(true);
|
||||||
|
parser.setOwnCloudVersion(client.getOwnCloudVersion());
|
||||||
|
parser.setServerBaseUri(client.getBaseUri());
|
||||||
|
result = parser.parse(response);
|
||||||
|
|
||||||
// Parse xml response --> obtain the response in ShareFiles ArrayList
|
if (result.isSuccess() && mGetShareDetails) {
|
||||||
// convert String into InputStream
|
// retrieve more info - POST only returns the index of the new share
|
||||||
InputStream is = new ByteArrayInputStream(response.getBytes());
|
OCShare emptyShare = (OCShare) result.getData().get(0);
|
||||||
ShareXMLParser xmlParser = new ShareXMLParser();
|
GetRemoteShareOperation getInfo = new GetRemoteShareOperation(
|
||||||
mShares = xmlParser.parseXMLResponse(is);
|
emptyShare.getRemoteId()
|
||||||
if (xmlParser.isSuccess()) {
|
);
|
||||||
if (mShares != null) {
|
result = getInfo.execute(client);
|
||||||
Log_OC.d(TAG, "Created " + mShares.size() + " share(s)");
|
|
||||||
result = new RemoteOperationResult(ResultCode.OK);
|
|
||||||
ArrayList<Object> sharesObjects = new ArrayList<Object>();
|
|
||||||
for (OCShare share: mShares) {
|
|
||||||
sharesObjects.add(share);
|
|
||||||
}
|
|
||||||
result.setData(sharesObjects);
|
|
||||||
}
|
|
||||||
} else if (xmlParser.isFileNotFound()){
|
|
||||||
result = new RemoteOperationResult(ResultCode.SHARE_NOT_FOUND);
|
|
||||||
|
|
||||||
} else if (xmlParser.isFailure()) {
|
|
||||||
result = new RemoteOperationResult(ResultCode.SHARE_FORBIDDEN);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
result = new RemoteOperationResult(false, status, post.getResponseHeaders());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
/* 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 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,199 @@
|
|||||||
|
/* 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.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.utils.Log_OC;
|
||||||
|
|
||||||
|
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 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 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 GetRemoteShareesOperation extends RemoteOperation{
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
// 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_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";
|
||||||
|
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;
|
||||||
|
public static final Byte GROUP_TYPE = 1;
|
||||||
|
|
||||||
|
private String mSearchString;
|
||||||
|
private int mPage;
|
||||||
|
private int mPerPage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param searchString string for searching users, optional
|
||||||
|
* @param page page index in the list of results; beginning in 1
|
||||||
|
* @param perPage maximum number of results in a single page
|
||||||
|
*/
|
||||||
|
public GetRemoteShareesOperation(String searchString, int page, int perPage) {
|
||||||
|
mSearchString = searchString;
|
||||||
|
mPage = page;
|
||||||
|
mPerPage = perPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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);
|
||||||
|
uriBuilder.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT);
|
||||||
|
uriBuilder.appendQueryParameter(PARAM_ITEM_TYPE, VALUE_ITEM_TYPE);
|
||||||
|
uriBuilder.appendQueryParameter(PARAM_SEARCH, mSearchString);
|
||||||
|
uriBuilder.appendQueryParameter(PARAM_PAGE, String.valueOf(mPage));
|
||||||
|
uriBuilder.appendQueryParameter(PARAM_PER_PAGE, String.valueOf(mPerPage));
|
||||||
|
|
||||||
|
// 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 respData = respOCS.getJSONObject(NODE_DATA);
|
||||||
|
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<Object> data = new ArrayList<Object>(); // For result data
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
for(int j=0; j< jsonResults[i].length(); j++){
|
||||||
|
JSONObject jsonResult = jsonResults[i].getJSONObject(j);
|
||||||
|
data.add(jsonResult);
|
||||||
|
Log_OC.d(TAG, "*** Added item: " + jsonResult.getString(PROPERTY_LABEL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result
|
||||||
|
result = new RemoteOperationResult(true, status, get.getResponseHeaders());
|
||||||
|
result.setData(data);
|
||||||
|
|
||||||
|
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/groups 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/groups", e);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (get != null) {
|
||||||
|
get.releaseConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSuccess(int status) {
|
||||||
|
return (status == HttpStatus.SC_OK);
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,6 @@
|
|||||||
/* ownCloud Android Library is available under MIT license
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
* @author masensio
|
||||||
|
* @author David A. Velasco
|
||||||
* Copyright (C) 2015 ownCloud Inc.
|
* Copyright (C) 2015 ownCloud Inc.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
@ -24,10 +26,6 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.resources.shares;
|
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.NameValuePair;
|
||||||
import org.apache.commons.httpclient.methods.GetMethod;
|
import org.apache.commons.httpclient.methods.GetMethod;
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
@ -35,18 +33,13 @@ import org.apache.http.HttpStatus;
|
|||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
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.common.utils.Log_OC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide a list shares for a specific file.
|
* Provide a list shares for a specific file.
|
||||||
* The input is the full path of the desired 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.
|
* The output is a list of everyone who has the file shared with them.
|
||||||
*
|
|
||||||
* @author masensio
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class GetRemoteSharesForFileOperation extends RemoteOperation {
|
public class GetRemoteSharesForFileOperation extends RemoteOperation {
|
||||||
|
|
||||||
private static final String TAG = GetRemoteSharesForFileOperation.class.getSimpleName();
|
private static final String TAG = GetRemoteSharesForFileOperation.class.getSimpleName();
|
||||||
@ -55,8 +48,6 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation {
|
|||||||
private static final String PARAM_RESHARES = "reshares";
|
private static final String PARAM_RESHARES = "reshares";
|
||||||
private static final String PARAM_SUBFILES = "subfiles";
|
private static final String PARAM_SUBFILES = "subfiles";
|
||||||
|
|
||||||
private ArrayList<OCShare> mShares; // List of shares for result, one share in this case
|
|
||||||
|
|
||||||
private String mRemoteFilePath;
|
private String mRemoteFilePath;
|
||||||
private boolean mReshares;
|
private boolean mReshares;
|
||||||
private boolean mSubfiles;
|
private boolean mSubfiles;
|
||||||
@ -65,12 +56,14 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation {
|
|||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param remoteFilePath Path to file or folder
|
* @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 owned by the current user are
|
||||||
* If set to true, all shares from the given file are returned
|
* 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
|
* @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, 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;
|
mRemoteFilePath = remoteFilePath;
|
||||||
mReshares = reshares;
|
mReshares = reshares;
|
||||||
mSubfiles = subfiles;
|
mSubfiles = subfiles;
|
||||||
@ -101,25 +94,16 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation {
|
|||||||
if(isSuccess(status)) {
|
if(isSuccess(status)) {
|
||||||
String response = get.getResponseBodyAsString();
|
String response = get.getResponseBodyAsString();
|
||||||
|
|
||||||
result = new RemoteOperationResult(ResultCode.OK);
|
// 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);
|
||||||
|
|
||||||
// Parse xml response --> obtain the response in ShareFiles ArrayList
|
if (result.isSuccess()) {
|
||||||
// convert String into InputStream
|
Log_OC.d(TAG, "Got " + result.getData().size() + " shares");
|
||||||
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<Object> sharesObjects = new ArrayList<Object>();
|
|
||||||
for (OCShare share: mShares) {
|
|
||||||
// Build the link
|
|
||||||
if (share.getToken().length() > 0) {
|
|
||||||
share.setShareLink(client.getBaseUri() + ShareUtils.SHARING_LINK_TOKEN + share.getToken());
|
|
||||||
}
|
|
||||||
sharesObjects.add(share);
|
|
||||||
}
|
|
||||||
result.setData(sharesObjects);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
/* ownCloud Android Library is available under MIT license
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
* @author masensio
|
||||||
|
* @author David A. Velasco
|
||||||
* Copyright (C) 2015 ownCloud Inc.
|
* Copyright (C) 2015 ownCloud Inc.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
@ -24,24 +26,16 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.resources.shares;
|
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.commons.httpclient.methods.GetMethod;
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
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.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
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -49,8 +43,6 @@ public class GetRemoteSharesOperation extends RemoteOperation {
|
|||||||
|
|
||||||
private static final String TAG = GetRemoteSharesOperation.class.getSimpleName();
|
private static final String TAG = GetRemoteSharesOperation.class.getSimpleName();
|
||||||
|
|
||||||
private ArrayList<OCShare> mShares; // List of shares for result
|
|
||||||
|
|
||||||
|
|
||||||
public GetRemoteSharesOperation() {
|
public GetRemoteSharesOperation() {
|
||||||
}
|
}
|
||||||
@ -68,23 +60,17 @@ public class GetRemoteSharesOperation extends RemoteOperation {
|
|||||||
get = new GetMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH);
|
get = new GetMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH);
|
||||||
get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
|
get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
|
||||||
status = client.executeMethod(get);
|
status = client.executeMethod(get);
|
||||||
|
|
||||||
if(isSuccess(status)) {
|
if(isSuccess(status)) {
|
||||||
String response = get.getResponseBodyAsString();
|
String response = get.getResponseBodyAsString();
|
||||||
|
|
||||||
// Parse xml response --> obtain the response in ShareFiles ArrayList
|
// Parse xml response and obtain the list of shares
|
||||||
// convert String into InputStream
|
ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
|
||||||
InputStream is = new ByteArrayInputStream(response.getBytes());
|
new ShareXMLParser()
|
||||||
ShareXMLParser xmlParser = new ShareXMLParser();
|
);
|
||||||
mShares = xmlParser.parseXMLResponse(is);
|
parser.setOwnCloudVersion(client.getOwnCloudVersion());
|
||||||
if (mShares != null) {
|
parser.setServerBaseUri(client.getBaseUri());
|
||||||
Log_OC.d(TAG, "Got " + mShares.size() + " shares");
|
result = parser.parse(response);
|
||||||
result = new RemoteOperationResult(ResultCode.OK);
|
|
||||||
ArrayList<Object> sharesObjects = new ArrayList<Object>();
|
|
||||||
for (OCShare share: mShares) {
|
|
||||||
sharesObjects.add(share);
|
|
||||||
}
|
|
||||||
result.setData(sharesObjects);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
result = new RemoteOperationResult(false, status, get.getResponseHeaders());
|
result = new RemoteOperationResult(false, status, get.getResponseHeaders());
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,23 @@ public class OCShare implements Parcelable, Serializable {
|
|||||||
|
|
||||||
private static final String TAG = OCShare.class.getSimpleName();
|
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;
|
||||||
|
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 mId;
|
||||||
private long mFileSource;
|
private long mFileSource;
|
||||||
private long mItemSource;
|
private long mItemSource;
|
||||||
@ -59,7 +76,7 @@ public class OCShare implements Parcelable, Serializable {
|
|||||||
private String mSharedWithDisplayName;
|
private String mSharedWithDisplayName;
|
||||||
private boolean mIsFolder;
|
private boolean mIsFolder;
|
||||||
private long mUserId;
|
private long mUserId;
|
||||||
private long mIdRemoteShared;
|
private long mRemoteId;
|
||||||
private String mShareLink;
|
private String mShareLink;
|
||||||
|
|
||||||
public OCShare() {
|
public OCShare() {
|
||||||
@ -84,17 +101,17 @@ public class OCShare implements Parcelable, Serializable {
|
|||||||
mFileSource = 0;
|
mFileSource = 0;
|
||||||
mItemSource = 0;
|
mItemSource = 0;
|
||||||
mShareType = ShareType.NO_SHARED;
|
mShareType = ShareType.NO_SHARED;
|
||||||
mShareWith = null;
|
mShareWith = "";
|
||||||
mPath = null;
|
mPath = "";
|
||||||
mPermissions = -1;
|
mPermissions = -1;
|
||||||
mSharedDate = 0;
|
mSharedDate = 0;
|
||||||
mExpirationDate = 0;
|
mExpirationDate = 0;
|
||||||
mToken = null;
|
mToken = "";
|
||||||
mSharedWithDisplayName = null;
|
mSharedWithDisplayName = "";
|
||||||
mIsFolder = false;
|
mIsFolder = false;
|
||||||
mUserId = -1;
|
mUserId = -1;
|
||||||
mIdRemoteShared = -1;
|
mRemoteId = -1;
|
||||||
mShareLink = null;
|
mShareLink = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Getters and Setters
|
/// Getters and Setters
|
||||||
@ -136,7 +153,7 @@ public class OCShare implements Parcelable, Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setShareWith(String shareWith) {
|
public void setShareWith(String shareWith) {
|
||||||
this.mShareWith = shareWith;
|
this.mShareWith = (shareWith != null) ? shareWith : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
@ -144,7 +161,7 @@ public class OCShare implements Parcelable, Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setPath(String path) {
|
public void setPath(String path) {
|
||||||
this.mPath = path;
|
this.mPath = (path != null) ? path : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPermissions() {
|
public int getPermissions() {
|
||||||
@ -176,7 +193,7 @@ public class OCShare implements Parcelable, Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setToken(String token) {
|
public void setToken(String token) {
|
||||||
this.mToken = token;
|
this.mToken = (token != null) ? token : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSharedWithDisplayName() {
|
public String getSharedWithDisplayName() {
|
||||||
@ -184,7 +201,7 @@ public class OCShare implements Parcelable, Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setSharedWithDisplayName(String sharedWithDisplayName) {
|
public void setSharedWithDisplayName(String sharedWithDisplayName) {
|
||||||
this.mSharedWithDisplayName = sharedWithDisplayName;
|
this.mSharedWithDisplayName = (sharedWithDisplayName != null) ? sharedWithDisplayName : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFolder() {
|
public boolean isFolder() {
|
||||||
@ -203,12 +220,12 @@ public class OCShare implements Parcelable, Serializable {
|
|||||||
this.mUserId = userId;
|
this.mUserId = userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getIdRemoteShared() {
|
public long getRemoteId() {
|
||||||
return mIdRemoteShared;
|
return mRemoteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIdRemoteShared(long idRemoteShared) {
|
public void setIdRemoteShared(long remoteId) {
|
||||||
this.mIdRemoteShared = idRemoteShared;
|
this.mRemoteId = remoteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getShareLink() {
|
public String getShareLink() {
|
||||||
@ -216,7 +233,11 @@ public class OCShare implements Parcelable, Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setShareLink(String shareLink) {
|
public void setShareLink(String shareLink) {
|
||||||
this.mShareLink = shareLink;
|
this.mShareLink = (shareLink != null) ? shareLink : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPasswordProtected() {
|
||||||
|
return ShareType.PUBLIC_LINK.equals(mShareType) && mShareWith.length() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -262,7 +283,7 @@ public class OCShare implements Parcelable, Serializable {
|
|||||||
mSharedWithDisplayName = source.readString();
|
mSharedWithDisplayName = source.readString();
|
||||||
mIsFolder = source.readInt() == 0;
|
mIsFolder = source.readInt() == 0;
|
||||||
mUserId = source.readLong();
|
mUserId = source.readLong();
|
||||||
mIdRemoteShared = source.readLong();
|
mRemoteId = source.readLong();
|
||||||
mShareLink = source.readString();
|
mShareLink = source.readString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,7 +309,7 @@ public class OCShare implements Parcelable, Serializable {
|
|||||||
dest.writeString(mSharedWithDisplayName);
|
dest.writeString(mSharedWithDisplayName);
|
||||||
dest.writeInt(mIsFolder ? 1 : 0);
|
dest.writeInt(mIsFolder ? 1 : 0);
|
||||||
dest.writeLong(mUserId);
|
dest.writeLong(mUserId);
|
||||||
dest.writeLong(mIdRemoteShared);
|
dest.writeLong(mRemoteId);
|
||||||
dest.writeString(mShareLink);
|
dest.writeString(mShareLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
/* ownCloud Android Library is available under MIT license
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
* @author masensio
|
||||||
|
* @author David A. Velasco
|
||||||
* Copyright (C) 2015 ownCloud Inc.
|
* Copyright (C) 2015 ownCloud Inc.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
@ -24,23 +26,16 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.resources.shares;
|
package com.owncloud.android.lib.resources.shares;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import org.apache.commons.httpclient.HttpStatus;
|
import org.apache.commons.httpclient.HttpStatus;
|
||||||
import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
|
import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
|
||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
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.common.utils.Log_OC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a share
|
* Remove a share
|
||||||
*
|
|
||||||
* @author masensio
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class RemoveRemoteShareOperation extends RemoteOperation {
|
public class RemoveRemoteShareOperation extends RemoteOperation {
|
||||||
@ -78,22 +73,14 @@ public class RemoveRemoteShareOperation extends RemoteOperation {
|
|||||||
if(isSuccess(status)) {
|
if(isSuccess(status)) {
|
||||||
String response = delete.getResponseBodyAsString();
|
String response = delete.getResponseBodyAsString();
|
||||||
|
|
||||||
result = new RemoteOperationResult(ResultCode.OK);
|
// Parse xml response and obtain the list of shares
|
||||||
|
ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
|
||||||
// Parse xml response
|
new ShareXMLParser()
|
||||||
// convert String into InputStream
|
);
|
||||||
InputStream is = new ByteArrayInputStream(response.getBytes());
|
result = parser.parse(response);
|
||||||
ShareXMLParser xmlParser = new ShareXMLParser();
|
|
||||||
xmlParser.parseXMLResponse(is);
|
|
||||||
if (xmlParser.isSuccess()) {
|
|
||||||
result = new RemoteOperationResult(ResultCode.OK);
|
|
||||||
} else if (xmlParser.isFileNotFound()){
|
|
||||||
result = new RemoteOperationResult(ResultCode.SHARE_NOT_FOUND);
|
|
||||||
} else {
|
|
||||||
result = new RemoteOperationResult(false, status, delete.getResponseHeaders());
|
|
||||||
}
|
|
||||||
|
|
||||||
Log_OC.d(TAG, "Unshare " + id + ": " + result.getLogMessage());
|
Log_OC.d(TAG, "Unshare " + id + ": " + result.getLogMessage());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
result = new RemoteOperationResult(false, status, delete.getResponseHeaders());
|
result = new RemoteOperationResult(false, status, delete.getResponseHeaders());
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,145 @@
|
|||||||
|
/* 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<Object> resultData = new ArrayList<Object>();
|
||||||
|
|
||||||
|
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<OCShare> 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.getShareLink().length() <= 0) &&
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.resources.shares;
|
package com.owncloud.android.lib.resources.shares;
|
||||||
|
|
||||||
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains Constants for Share Operation
|
* Contains Constants for Share Operation
|
||||||
*
|
*
|
||||||
@ -36,7 +38,16 @@ public class ShareUtils {
|
|||||||
// OCS Route
|
// OCS Route
|
||||||
public static final String SHARING_API_PATH ="/ocs/v1.php/apps/files_sharing/api/v1/shares";
|
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
|
// String to build the link with the token of a share:
|
||||||
public static final String SHARING_LINK_TOKEN = "/public.php?service=files&t=";
|
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 getSharingLinkPath(OwnCloudVersion version){
|
||||||
|
if (version!= null && version.isAfter8Version()){
|
||||||
|
return SHARING_LINK_PATH_AFTER_VERSION_8;
|
||||||
|
} else {
|
||||||
|
return SHARING_LINK_PATH_BEFORE_VERSION_8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ public class ShareXMLParser {
|
|||||||
private static final String NODE_META = "meta";
|
private static final String NODE_META = "meta";
|
||||||
private static final String NODE_STATUS = "status";
|
private static final String NODE_STATUS = "status";
|
||||||
private static final String NODE_STATUS_CODE = "statuscode";
|
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_DATA = "data";
|
||||||
private static final String NODE_ELEMENT = "element";
|
private static final String NODE_ELEMENT = "element";
|
||||||
@ -75,18 +75,20 @@ public class ShareXMLParser {
|
|||||||
private static final String NODE_TOKEN = "token";
|
private static final String NODE_TOKEN = "token";
|
||||||
private static final String NODE_STORAGE = "storage";
|
private static final String NODE_STORAGE = "storage";
|
||||||
private static final String NODE_MAIL_SEND = "mail_send";
|
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";
|
private static final String NODE_URL = "url";
|
||||||
|
|
||||||
private static final String TYPE_FOLDER = "folder";
|
private static final String TYPE_FOLDER = "folder";
|
||||||
|
|
||||||
private static final int SUCCESS = 100;
|
private static final int SUCCESS = 100;
|
||||||
private static final int FAILURE = 403;
|
private static final int ERROR_WRONG_PARAMETER = 400;
|
||||||
private static final int FILE_NOT_FOUND = 404;
|
private static final int ERROR_FORBIDDEN = 403;
|
||||||
|
private static final int ERROR_NOT_FOUND = 404;
|
||||||
|
|
||||||
private String mStatus;
|
private String mStatus;
|
||||||
private int mStatusCode;
|
private int mStatusCode;
|
||||||
|
private String mMessage;
|
||||||
|
|
||||||
// Getters and Setters
|
// Getters and Setters
|
||||||
public String getStatus() {
|
public String getStatus() {
|
||||||
@ -104,19 +106,34 @@ public class ShareXMLParser {
|
|||||||
public void setStatusCode(int statusCode) {
|
public void setStatusCode(int statusCode) {
|
||||||
this.mStatusCode = statusCode;
|
this.mStatusCode = statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return mMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.mMessage = message;
|
||||||
|
}
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
public ShareXMLParser() {
|
public ShareXMLParser() {
|
||||||
mStatusCode = 100;
|
mStatusCode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSuccess() {
|
public boolean isSuccess() {
|
||||||
return mStatusCode == SUCCESS;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,7 +143,8 @@ public class ShareXMLParser {
|
|||||||
* @throws XmlPullParserException
|
* @throws XmlPullParserException
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public ArrayList<OCShare> parseXMLResponse(InputStream is) throws XmlPullParserException, IOException {
|
public ArrayList<OCShare> parseXMLResponse(InputStream is) throws XmlPullParserException,
|
||||||
|
IOException {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// XMLPullParser
|
// XMLPullParser
|
||||||
@ -151,7 +169,8 @@ public class ShareXMLParser {
|
|||||||
* @throws XmlPullParserException
|
* @throws XmlPullParserException
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
private ArrayList<OCShare> readOCS (XmlPullParser parser) throws XmlPullParserException, IOException {
|
private ArrayList<OCShare> readOCS (XmlPullParser parser) throws XmlPullParserException,
|
||||||
|
IOException {
|
||||||
ArrayList<OCShare> shares = new ArrayList<OCShare>();
|
ArrayList<OCShare> shares = new ArrayList<OCShare>();
|
||||||
parser.require(XmlPullParser.START_TAG, ns , NODE_OCS);
|
parser.require(XmlPullParser.START_TAG, ns , NODE_OCS);
|
||||||
while (parser.next() != XmlPullParser.END_TAG) {
|
while (parser.next() != XmlPullParser.END_TAG) {
|
||||||
@ -195,6 +214,9 @@ public class ShareXMLParser {
|
|||||||
} else if (name.equalsIgnoreCase(NODE_STATUS_CODE)) {
|
} else if (name.equalsIgnoreCase(NODE_STATUS_CODE)) {
|
||||||
setStatusCode(Integer.parseInt(readNode(parser, NODE_STATUS_CODE)));
|
setStatusCode(Integer.parseInt(readNode(parser, NODE_STATUS_CODE)));
|
||||||
|
|
||||||
|
} else if (name.equalsIgnoreCase(NODE_MESSAGE)) {
|
||||||
|
setMessage(readNode(parser, NODE_MESSAGE));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
skip(parser);
|
skip(parser);
|
||||||
}
|
}
|
||||||
@ -209,7 +231,8 @@ public class ShareXMLParser {
|
|||||||
* @throws XmlPullParserException
|
* @throws XmlPullParserException
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
private ArrayList<OCShare> readData(XmlPullParser parser) throws XmlPullParserException, IOException {
|
private ArrayList<OCShare> readData(XmlPullParser parser) throws XmlPullParserException,
|
||||||
|
IOException {
|
||||||
ArrayList<OCShare> shares = new ArrayList<OCShare>();
|
ArrayList<OCShare> shares = new ArrayList<OCShare>();
|
||||||
OCShare share = null;
|
OCShare share = null;
|
||||||
|
|
||||||
@ -259,7 +282,8 @@ public class ShareXMLParser {
|
|||||||
* @throws XmlPullParserException
|
* @throws XmlPullParserException
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
private void readElement(XmlPullParser parser, ArrayList<OCShare> shares) throws XmlPullParserException, IOException {
|
private void readElement(XmlPullParser parser, ArrayList<OCShare> shares)
|
||||||
|
throws XmlPullParserException, IOException {
|
||||||
parser.require(XmlPullParser.START_TAG, ns, NODE_ELEMENT);
|
parser.require(XmlPullParser.START_TAG, ns, NODE_ELEMENT);
|
||||||
|
|
||||||
OCShare share = new OCShare();
|
OCShare share = new OCShare();
|
||||||
@ -273,7 +297,8 @@ public class ShareXMLParser {
|
|||||||
String name = parser.getName();
|
String name = parser.getName();
|
||||||
|
|
||||||
if (name.equalsIgnoreCase(NODE_ELEMENT)) {
|
if (name.equalsIgnoreCase(NODE_ELEMENT)) {
|
||||||
// patch to work around servers responding with extra <element> surrounding all the shares on the same file before
|
// patch to work around servers responding with extra <element> surrounding all
|
||||||
|
// the shares on the same file before
|
||||||
// https://github.com/owncloud/core/issues/6992 was fixed
|
// https://github.com/owncloud/core/issues/6992 was fixed
|
||||||
readElement(parser, shares);
|
readElement(parser, shares);
|
||||||
|
|
||||||
@ -327,6 +352,11 @@ public class ShareXMLParser {
|
|||||||
} else if (name.equalsIgnoreCase(NODE_SHARE_WITH_DISPLAY_NAME)) {
|
} else if (name.equalsIgnoreCase(NODE_SHARE_WITH_DISPLAY_NAME)) {
|
||||||
share.setSharedWithDisplayName(readNode(parser, 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 {
|
} else {
|
||||||
skip(parser);
|
skip(parser);
|
||||||
}
|
}
|
||||||
@ -338,13 +368,12 @@ public class ShareXMLParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isValidShare(OCShare share) {
|
private boolean isValidShare(OCShare share) {
|
||||||
return ((share.getIdRemoteShared() > -1) &&
|
return (share.getRemoteId() > -1);
|
||||||
(share.getShareType() == ShareType.PUBLIC_LINK) // at this moment we only care about public shares
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fixPathForFolder(OCShare share) {
|
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);
|
share.setPath(share.getPath() + FileUtils.PATH_SEPARATOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -357,7 +386,8 @@ public class ShareXMLParser {
|
|||||||
* @throws XmlPullParserException
|
* @throws XmlPullParserException
|
||||||
* @throws IOException
|
* @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);
|
parser.require(XmlPullParser.START_TAG, ns, node);
|
||||||
String value = readText(parser);
|
String value = readText(parser);
|
||||||
//Log_OC.d(TAG, "node= " + node + ", value= " + value);
|
//Log_OC.d(TAG, "node= " + node + ", value= " + value);
|
||||||
|
@ -0,0 +1,215 @@
|
|||||||
|
/* 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.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
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 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";
|
||||||
|
|
||||||
|
|
||||||
|
/** 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;
|
||||||
|
|
||||||
|
/** 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.
|
||||||
|
*
|
||||||
|
* @param remoteId Identifier of the share to update.
|
||||||
|
*/
|
||||||
|
public UpdateRemoteShareOperation(long remoteId) {
|
||||||
|
mRemoteId = remoteId;
|
||||||
|
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 target share.
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
int status = -1;
|
||||||
|
|
||||||
|
/// prepare array of parameters to update
|
||||||
|
List<Pair<String, String>> parametersToUpdate = new ArrayList<Pair<String, String>>();
|
||||||
|
if (mPassword != null) {
|
||||||
|
parametersToUpdate.add(new Pair<String, String>(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
|
||||||
|
if (mPermissions > 0) {
|
||||||
|
// set permissions
|
||||||
|
parametersToUpdate.add(new Pair(PARAM_PERMISSIONS, Integer.toString(mPermissions)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO complete rest of parameters
|
||||||
|
if (mPublicUpload != null) {
|
||||||
|
parametersToUpdate.add(new Pair("publicUpload", mPublicUpload.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<String, String> parameter : parametersToUpdate) {
|
||||||
|
if (put != null) {
|
||||||
|
put.releaseConnection();
|
||||||
|
}
|
||||||
|
put = new PutMethod(uriString);
|
||||||
|
put.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
|
||||||
|
put.setRequestEntity(new StringRequestEntity(
|
||||||
|
parameter.first + "=" + parameter.second,
|
||||||
|
ENTITY_CONTENT_TYPE,
|
||||||
|
ENTITY_CHARSET
|
||||||
|
));
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
@ -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<Object> data = new ArrayList<Object>(); // 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);
|
||||||
|
}
|
||||||
|
}
|
@ -103,9 +103,7 @@ public class GetRemoteStatusOperation extends RemoteOperation {
|
|||||||
);
|
);
|
||||||
get.releaseConnection();
|
get.releaseConnection();
|
||||||
get = new GetMethod(redirectedLocation);
|
get = new GetMethod(redirectedLocation);
|
||||||
status = client.executeMethod(
|
status = client.executeMethod(get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT);
|
||||||
get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT
|
|
||||||
);
|
|
||||||
mLatestResult = new RemoteOperationResult(
|
mLatestResult = new RemoteOperationResult(
|
||||||
(status == HttpStatus.SC_OK),
|
(status == HttpStatus.SC_OK),
|
||||||
status,
|
status,
|
||||||
|
291
src/com/owncloud/android/lib/resources/status/OCCapability.java
Normal file
291
src/com/owncloud/android/lib/resources/status/OCCapability.java
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -39,6 +39,16 @@ public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
|
|||||||
|
|
||||||
public static final int MINIMUM_VERSION_FOR_SHARING_API = 0x05001B00; // 5.0.27
|
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
|
||||||
|
|
||||||
|
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;
|
private static final int MAX_DOTS = 3;
|
||||||
|
|
||||||
// format is in version
|
// format is in version
|
||||||
@ -121,5 +131,25 @@ public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
|
|||||||
return (mVersion >= MINIMUM_VERSION_FOR_SHARING_API);
|
return (mVersion >= MINIMUM_VERSION_FOR_SHARING_API);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isVersionWithForbiddenCharacters() {
|
||||||
|
return (mVersion >= MINIMUM_VERSION_WITH_FORBIDDEN_CHARS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsRemoteThumbnails() {
|
||||||
|
return (mVersion >= MINIMUM_SERVER_VERSION_FOR_REMOTE_THUMBNAILS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAfter8Version(){
|
||||||
|
return (mVersion >= VERSION_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSearchUsersSupported() {
|
||||||
|
return (mVersion >= MINIMUM_VERSION_FOR_SEARCHING_USERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVersionWithCapabilitiesAPI(){
|
||||||
|
return (mVersion>= MINIMUM_VERSION_CAPABILITIES_API);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ dependencies {
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 19
|
compileSdkVersion 19
|
||||||
buildToolsVersion "20.0.0"
|
buildToolsVersion "22.0.1"
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main {
|
main {
|
||||||
@ -45,4 +45,9 @@ android {
|
|||||||
packagingOptions {
|
packagingOptions {
|
||||||
exclude 'META-INF/LICENSE.txt'
|
exclude 'META-INF/LICENSE.txt'
|
||||||
}
|
}
|
||||||
|
android {
|
||||||
|
lintOptions {
|
||||||
|
abortOnError false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,458 @@
|
|||||||
|
/* 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
|
||||||
|
* <p/>
|
||||||
|
* With this TestCase we are experimenting a bit to improve the test suite design, in two aspects:
|
||||||
|
* <p/>
|
||||||
|
* - 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.
|
||||||
|
* <p/>
|
||||||
|
* - 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<TestActivity> {
|
||||||
|
|
||||||
|
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_1,
|
||||||
|
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.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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.resources.shares.ShareType;
|
||||||
import com.owncloud.android.lib.test_project.TestActivity;
|
import com.owncloud.android.lib.test_project.TestActivity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Create Share: the server must support SHARE API
|
||||||
|
*/
|
||||||
public class CreateShareTest extends RemoteTest {
|
public class CreateShareTest extends RemoteTest {
|
||||||
|
|
||||||
private static final String LOG_TAG = CreateShareTest.class.getCanonicalName();
|
private static final String LOG_TAG = CreateShareTest.class.getCanonicalName();
|
||||||
@ -38,8 +41,12 @@ public class CreateShareTest extends RemoteTest {
|
|||||||
/* File to share.*/
|
/* File to share.*/
|
||||||
private static final String FILE_TO_SHARE = "/fileToShare.txt";
|
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 TestActivity mActivity;
|
||||||
private String mFullPath2FileToShare;
|
private String mFullPath2FileToShare;
|
||||||
|
private String mFullPath2NonExistentFile;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
@ -47,6 +54,7 @@ public class CreateShareTest extends RemoteTest {
|
|||||||
setActivityInitialTouchMode(false);
|
setActivityInitialTouchMode(false);
|
||||||
mActivity = getActivity();
|
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);
|
File textFile = mActivity.extractAsset(TestActivity.ASSETS__TEXT_FILE_NAME);
|
||||||
RemoteOperationResult result = mActivity.uploadFile(
|
RemoteOperationResult result = mActivity.uploadFile(
|
||||||
@ -59,9 +67,11 @@ public class CreateShareTest extends RemoteTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test Create Share: the server must support SHARE API
|
* Test creation of public shares
|
||||||
*/
|
*/
|
||||||
public void testCreatePublicShare() {
|
public void testCreatePublicShare() {
|
||||||
|
|
||||||
|
/// Successful cases
|
||||||
RemoteOperationResult result = mActivity.createShare(
|
RemoteOperationResult result = mActivity.createShare(
|
||||||
mFullPath2FileToShare,
|
mFullPath2FileToShare,
|
||||||
ShareType.PUBLIC_LINK,
|
ShareType.PUBLIC_LINK,
|
||||||
@ -70,6 +80,141 @@ public class CreateShareTest extends RemoteTest {
|
|||||||
"",
|
"",
|
||||||
1);
|
1);
|
||||||
assertTrue(result.isSuccess());
|
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_FORBIDDEN,
|
||||||
|
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_FORBIDDEN,
|
||||||
|
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
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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.");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -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() > 0);
|
||||||
|
try {
|
||||||
|
for (int i=0; i<result.getData().size(); 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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue(userCount > 0);
|
||||||
|
assertTrue(groupCount > 0);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
AssertionFailedError afe = new AssertionFailedError(e.getLocalizedMessage());
|
||||||
|
afe.setStackTrace(e.getStackTrace());
|
||||||
|
throw afe;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
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 "bd" - expecting 0 results
|
||||||
|
getShareesOperation = new GetRemoteShareesOperation("bd", 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.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -135,7 +135,7 @@ public class OwnCloudClientTest extends AndroidTestCase {
|
|||||||
client.setCredentials(credentials);
|
client.setCredentials(credentials);
|
||||||
assertEquals("Bearer credentials not set", credentials, client.getCredentials());
|
assertEquals("Bearer credentials not set", credentials, client.getCredentials());
|
||||||
|
|
||||||
credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials("samlSessionCookie=124");
|
credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials("user", "samlSessionCookie=124");
|
||||||
client.setCredentials(credentials);
|
client.setCredentials(credentials);
|
||||||
assertEquals("SAML2 session credentials not set", credentials, client.getCredentials());
|
assertEquals("SAML2 session credentials not set", credentials, client.getCredentials());
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ public class RemoveShareTest extends RemoteTest {
|
|||||||
Utils.logAndThrow(LOG_TAG, result);
|
Utils.logAndThrow(LOG_TAG, result);
|
||||||
} else {
|
} else {
|
||||||
OCShare created = (OCShare) result.getData().get(0);
|
OCShare created = (OCShare) result.getData().get(0);
|
||||||
mShareId = created.getIdRemoteShared();
|
mShareId = created.getRemoteId();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,259 @@
|
|||||||
|
/* 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());
|
||||||
|
// 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()
|
||||||
|
);
|
||||||
|
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.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,243 @@
|
|||||||
|
/* 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 public shares
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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<73>rd";
|
||||||
|
|
||||||
|
private String mFullPath2FileToShare;
|
||||||
|
|
||||||
|
private OCShare mShare;
|
||||||
|
|
||||||
|
String mServerUri, mUser, mPass;
|
||||||
|
OwnCloudClient mClient = null;
|
||||||
|
|
||||||
|
public UpdatePublicShareTest(){
|
||||||
|
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 with a public link
|
||||||
|
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 testUpdatePublicShare() {
|
||||||
|
Log.v(LOG_TAG, "testUpdatePublicShare 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.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user