diff --git a/.travis.yml b/.travis.yml
index 9f906ec0..2920d050 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,9 +2,10 @@ language: java
jdk: oraclejdk7
before_install:
- sudo apt-get update -qq
-- sudo apt-get install -qq libstdc++6:i386 lib32z1
-- curl -3L https://raw.github.com/embarkmobile/android-sdk-installer/version-1/android-sdk-installer
- | bash /dev/stdin --install=$COMPONENTS
+- sudo apt-get install -qq libstdc++6:i386 lib32z1 expect
+- export LICENSES="android-sdk-license-5be876d5|android-sdk-license-598b93a6"
+- curl -3L https://raw.github.com/embarkmobile/android-sdk-installer/version-2/android-sdk-installer
+ | bash /dev/stdin --install=$COMPONENTS --accept=$LICENSES
- source ~/.android-sdk-installer/env
- 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 &
@@ -24,4 +25,4 @@ env:
- secure: aF4U20Xlu/rfrbxCmoJAiGh1doYTAZ10UEDmajuinT+ZGSJLivuqD7DDY/00sI6IXWg+J1vL+7jJm4JSYusHPg38UHZ4q92k6RmZycW2ATUzZnGT54O5FRnY67MfVwgVpIMK9UOL/6NEciBHEjlIOL0wbKQiJB++1YtBZOQLGL4=
- secure: N+ECSwNg8v2GsAFJ2y/tCiffauHDpN76zuFI2pDqf0fjmCtJZHu4BH5ArXBHjyHKmgn20a/8eZXcwJaH1HsJ80bo7vDJ2miShjGIQ90hPcdmUiB2XVJcew4f04CtvMDH5o7DRt4ykWArlbPL2rhVag0jotlSidolHBwRFnbDhDY=
matrix:
- - COMPONENTS=build-tools-19.0.3,android-19,sysimg-19 ANDROID_TARGET=android-19 ANDROID_ABI=armeabi-v7a
+ - COMPONENTS=build-tools-20.0.0,android-19,sys-img-armeabi-v7a-android-19 ANDROID_TARGET=android-19 ANDROID_ABI=armeabi-v7a
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 708f7893..eaa33e5e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -33,3 +33,4 @@
android:targetSdkVersion="19" />
+
diff --git a/sample_client/src/com/owncloud/android/lib/sampleclient/MainActivity.java b/sample_client/src/com/owncloud/android/lib/sampleclient/MainActivity.java
index 7383dc0a..8e24c15e 100644
--- a/sample_client/src/com/owncloud/android/lib/sampleclient/MainActivity.java
+++ b/sample_client/src/com/owncloud/android/lib/sampleclient/MainActivity.java
@@ -36,6 +36,7 @@ import com.owncloud.android.lib.common.accounts.AccountUtils;
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
import com.owncloud.android.lib.common.OwnCloudClientFactory;
import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;
import com.owncloud.android.lib.resources.files.RemoteFile;
import com.owncloud.android.lib.common.operations.RemoteOperation;
@@ -80,7 +81,12 @@ public class MainActivity extends Activity implements OnRemoteOperationListener,
Uri serverUri = Uri.parse(getString(R.string.server_base_url) + AccountUtils.WEBDAV_PATH_4_0);
mClient = OwnCloudClientFactory.createOwnCloudClient(serverUri, this, true);
- mClient.setBasicCredentials(getString(R.string.username), getString(R.string.password));
+ mClient.setCredentials(
+ OwnCloudCredentialsFactory.newBasicCredentials(
+ getString(R.string.username),
+ getString(R.string.password)
+ )
+ );
mFilesAdapter = new FilesArrayAdapter(this, R.layout.file_in_list);
((ListView)findViewById(R.id.list_view)).setAdapter(mFilesAdapter);
diff --git a/src/com/owncloud/android/lib/common/OwnCloudAccount.java b/src/com/owncloud/android/lib/common/OwnCloudAccount.java
new file mode 100644
index 00000000..339eb128
--- /dev/null
+++ b/src/com/owncloud/android/lib/common/OwnCloudAccount.java
@@ -0,0 +1,98 @@
+/* ownCloud Android client application
+ * Copyright (C) 2014 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.lib.common;
+
+
+import java.io.IOException;
+
+import com.owncloud.android.lib.common.accounts.AccountUtils;
+import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
+
+import android.accounts.Account;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.content.Context;
+import android.net.Uri;
+
+/**
+ * OwnCloud Account
+ *
+ * @author David A. Velasco
+ */
+public class OwnCloudAccount {
+
+ private Uri mBaseUri;
+
+ private OwnCloudCredentials mCredentials;
+
+ private String mSavedAccountName;
+
+
+ public OwnCloudAccount(Account savedAccount, Context context)
+ throws AccountNotFoundException, AuthenticatorException,
+ IOException, OperationCanceledException {
+
+ if (savedAccount == null) {
+ throw new IllegalArgumentException("Parameter 'savedAccount' cannot be null");
+ }
+ if (context == null) {
+ throw new IllegalArgumentException("Parameter 'context' cannot be null");
+ }
+
+ mSavedAccountName = savedAccount.name;
+ mBaseUri = Uri.parse(AccountUtils.getBaseUrlForAccount(context, savedAccount));
+ mCredentials = AccountUtils.getCredentialsForAccount(context, savedAccount);
+ if (mCredentials == null) {
+ mCredentials = OwnCloudCredentialsFactory.getAnonymousCredentials();
+ }
+ }
+
+
+ public OwnCloudAccount(Uri baseUri, OwnCloudCredentials credentials) {
+ if (baseUri == null) {
+ throw new IllegalArgumentException("Parameter 'baseUri' cannot be null");
+ }
+ mSavedAccountName = null;
+ mBaseUri = baseUri;
+ mCredentials = credentials != null ?
+ credentials : OwnCloudCredentialsFactory.getAnonymousCredentials();
+ String username = mCredentials.getUsername();
+ if (username != null) {
+ mSavedAccountName = AccountUtils.buildAccountName(mBaseUri, username);
+ }
+ }
+
+
+ public boolean isAnonymous() {
+ return (mCredentials == null);
+ }
+
+ public Uri getBaseUri() {
+ return mBaseUri;
+ }
+
+ public OwnCloudCredentials getCredentials() {
+ return mCredentials;
+ }
+
+ public String getName() {
+ return mSavedAccountName;
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/com/owncloud/android/lib/common/OwnCloudBasicCredentials.java b/src/com/owncloud/android/lib/common/OwnCloudBasicCredentials.java
new file mode 100644
index 00000000..6855cfc4
--- /dev/null
+++ b/src/com/owncloud/android/lib/common/OwnCloudBasicCredentials.java
@@ -0,0 +1,48 @@
+package com.owncloud.android.lib.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthPolicy;
+import org.apache.commons.httpclient.auth.AuthScope;
+
+public class OwnCloudBasicCredentials implements OwnCloudCredentials {
+
+ private String mUsername;
+ private String mPassword;
+
+ public OwnCloudBasicCredentials(String username, String password) {
+ mUsername = username != null ? username : "";
+ mPassword = password != null ? password : "";
+ }
+
+ @Override
+ public void applyTo(OwnCloudClient client) {
+ List authPrefs = new ArrayList(1);
+ authPrefs.add(AuthPolicy.BASIC);
+ client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
+
+ client.getParams().setAuthenticationPreemptive(true);
+ client.getState().setCredentials(
+ AuthScope.ANY,
+ new UsernamePasswordCredentials(mUsername, mPassword)
+ );
+ }
+
+ @Override
+ public String getUsername() {
+ return mUsername;
+ }
+
+ @Override
+ public String getAuthToken() {
+ return mPassword;
+ }
+
+ @Override
+ public boolean authTokenExpires() {
+ return false;
+ }
+
+}
diff --git a/src/com/owncloud/android/lib/common/OwnCloudBearerCredentials.java b/src/com/owncloud/android/lib/common/OwnCloudBearerCredentials.java
new file mode 100644
index 00000000..fb6f2018
--- /dev/null
+++ b/src/com/owncloud/android/lib/common/OwnCloudBearerCredentials.java
@@ -0,0 +1,51 @@
+package com.owncloud.android.lib.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.httpclient.auth.AuthPolicy;
+import org.apache.commons.httpclient.auth.AuthScope;
+
+import com.owncloud.android.lib.common.network.BearerAuthScheme;
+import com.owncloud.android.lib.common.network.BearerCredentials;
+
+public class OwnCloudBearerCredentials implements OwnCloudCredentials {
+
+ private String mAccessToken;
+
+ public OwnCloudBearerCredentials(String accessToken) {
+ mAccessToken = accessToken != null ? accessToken : "";
+ }
+
+ @Override
+ public void applyTo(OwnCloudClient client) {
+ AuthPolicy.registerAuthScheme(BearerAuthScheme.AUTH_POLICY, BearerAuthScheme.class);
+
+ List authPrefs = new ArrayList(1);
+ authPrefs.add(BearerAuthScheme.AUTH_POLICY);
+ client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
+
+ client.getParams().setAuthenticationPreemptive(true);
+ client.getState().setCredentials(
+ AuthScope.ANY,
+ new BearerCredentials(mAccessToken)
+ );
+ }
+
+ @Override
+ public String getUsername() {
+ // its unknown
+ return null;
+ }
+
+ @Override
+ public String getAuthToken() {
+ return mAccessToken;
+ }
+
+ @Override
+ public boolean authTokenExpires() {
+ return true;
+ }
+
+}
diff --git a/src/com/owncloud/android/lib/common/OwnCloudClient.java b/src/com/owncloud/android/lib/common/OwnCloudClient.java
index 14405326..7b48bbc0 100644
--- a/src/com/owncloud/android/lib/common/OwnCloudClient.java
+++ b/src/com/owncloud/android/lib/common/OwnCloudClient.java
@@ -27,10 +27,8 @@ package com.owncloud.android.lib.common;
import java.io.IOException;
import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.commons.httpclient.Credentials;
+import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
@@ -39,92 +37,96 @@ import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpVersion;
import org.apache.commons.httpclient.URI;
-import org.apache.commons.httpclient.UsernamePasswordCredentials;
-import org.apache.commons.httpclient.auth.AuthPolicy;
-import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.http.HttpStatus;
import org.apache.http.params.CoreProtocolPNames;
-import com.owncloud.android.lib.common.network.BearerAuthScheme;
-import com.owncloud.android.lib.common.network.BearerCredentials;
-import com.owncloud.android.lib.common.network.WebdavUtils;
-
-
import android.net.Uri;
import android.util.Log;
+import com.owncloud.android.lib.common.OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials;
+import com.owncloud.android.lib.common.accounts.AccountUtils;
+import com.owncloud.android.lib.common.network.WebdavUtils;
+
public class OwnCloudClient extends HttpClient {
- private static final int MAX_REDIRECTIONS_COUNT = 3;
-
- private Uri mUri;
- private Uri mWebdavUri;
- private Credentials mCredentials;
- private boolean mFollowRedirects;
- private String mSsoSessionCookie;
- final private static String TAG = OwnCloudClient.class.getSimpleName();
+
+ private static final String TAG = OwnCloudClient.class.getSimpleName();
public static final String USER_AGENT = "Android-ownCloud";
+ private static final int MAX_REDIRECTIONS_COUNT = 3;
+ private static final String PARAM_SINGLE_COOKIE_HEADER = "http.protocol.single-cookie-header";
+ private static final boolean PARAM_SINGLE_COOKIE_HEADER_VALUE = true;
- static private byte[] sExhaustBuffer = new byte[1024];
+ private static byte[] sExhaustBuffer = new byte[1024];
+
+ private static int sIntanceCounter = 0;
+ private boolean mFollowRedirects = true;
+ private OwnCloudCredentials mCredentials = null;
+ private int mInstanceNumber = 0;
+
+ private Uri mBaseUri;
/**
* Constructor
*/
- public OwnCloudClient(HttpConnectionManager connectionMgr) {
+ public OwnCloudClient(Uri baseUri, HttpConnectionManager connectionMgr) {
super(connectionMgr);
- Log.d(TAG, "Creating OwnCloudClient");
+
+ if (baseUri == null) {
+ throw new IllegalArgumentException("Parameter 'baseUri' cannot be NULL");
+ }
+ mBaseUri = baseUri;
+
+ mInstanceNumber = sIntanceCounter++;
+ Log.d(TAG + " #" + mInstanceNumber, "Creating OwnCloudClient");
+
getParams().setParameter(HttpMethodParams.USER_AGENT, USER_AGENT);
- getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
- mFollowRedirects = true;
- mSsoSessionCookie = null;
+ getParams().setParameter(
+ CoreProtocolPNames.PROTOCOL_VERSION,
+ HttpVersion.HTTP_1_1);
+
+ getParams().setCookiePolicy(
+ CookiePolicy.IGNORE_COOKIES);
+ getParams().setParameter(
+ PARAM_SINGLE_COOKIE_HEADER, // to avoid problems with some web servers
+ PARAM_SINGLE_COOKIE_HEADER_VALUE);
+
+ clearCredentials();
}
- public void setBearerCredentials(String accessToken) {
- AuthPolicy.registerAuthScheme(BearerAuthScheme.AUTH_POLICY, BearerAuthScheme.class);
-
- List authPrefs = new ArrayList(1);
- authPrefs.add(BearerAuthScheme.AUTH_POLICY);
- getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
-
- mCredentials = new BearerCredentials(accessToken);
- getState().setCredentials(AuthScope.ANY, mCredentials);
- mSsoSessionCookie = null;
- }
-
- public void setBasicCredentials(String username, String password) {
- List authPrefs = new ArrayList(1);
- authPrefs.add(AuthPolicy.BASIC);
- getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
-
- getParams().setAuthenticationPreemptive(true);
- mCredentials = new UsernamePasswordCredentials(username, password);
- getState().setCredentials(AuthScope.ANY, mCredentials);
- mSsoSessionCookie = null;
- }
-
- public void setSsoSessionCookie(String accessToken) {
- getParams().setAuthenticationPreemptive(false);
- getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
- mSsoSessionCookie = accessToken;
- mCredentials = null;
+
+ public void setCredentials(OwnCloudCredentials credentials) {
+ if (credentials != null) {
+ mCredentials = credentials;
+ mCredentials.applyTo(this);
+ } else {
+ clearCredentials();
+ }
}
+ public void clearCredentials() {
+ if (!(mCredentials instanceof OwnCloudAnonymousCredentials)) {
+ mCredentials = OwnCloudCredentialsFactory.getAnonymousCredentials();
+ }
+ mCredentials.applyTo(this);
+ }
/**
* Check if a file exists in the OC server
*
- * TODO replace with ExistenceOperation
+ * @deprecated Use ExistenceCheckOperation instead
*
- * @return 'true' if the file exists; 'false' it doesn't exist
- * @throws Exception When the existence could not be determined
+ * @return 'true' if the file exists; 'false' it doesn't exist
+ * @throws Exception When the existence could not be determined
*/
+ @Deprecated
public boolean existsFile(String path) throws IOException, HttpException {
- HeadMethod head = new HeadMethod(mWebdavUri.toString() + WebdavUtils.encodePath(path));
+ HeadMethod head = new HeadMethod(getWebdavUri() + WebdavUtils.encodePath(path));
try {
int status = executeMethod(head);
- Log.d(TAG, "HEAD to " + path + " finished with HTTP status " + status + ((status != HttpStatus.SC_OK)?"(FAIL)":""));
+ Log.d(TAG, "HEAD to " + path + " finished with HTTP status " + status +
+ ((status != HttpStatus.SC_OK)?"(FAIL)":""));
exhaustResponse(head.getResponseBodyAsStream());
return (status == HttpStatus.SC_OK);
@@ -140,19 +142,21 @@ public class OwnCloudClient extends HttpClient {
*
* Sets the socket and connection timeouts only for the method received.
*
- * The timeouts are both in milliseconds; 0 means 'infinite'; < 0 means 'do not change the default'
+ * The timeouts are both in milliseconds; 0 means 'infinite';
+ * < 0 means 'do not change the default'
*
* @param method HTTP method request.
* @param readTimeout Timeout to set for data reception
* @param conntionTimout Timeout to set for connection establishment
*/
- public int executeMethod(HttpMethodBase method, int readTimeout, int connectionTimeout) throws HttpException, IOException {
+ public int executeMethod(HttpMethodBase method, int readTimeout, int connectionTimeout)
+ throws HttpException, IOException {
int oldSoTimeout = getParams().getSoTimeout();
int oldConnectionTimeout = getHttpConnectionManager().getParams().getConnectionTimeout();
try {
if (readTimeout >= 0) {
method.getParams().setSoTimeout(readTimeout); // this should be enough...
- getParams().setSoTimeout(readTimeout); // ... but this looks like necessary for HTTPS
+ getParams().setSoTimeout(readTimeout); // ... but HTTPS needs this
}
if (connectionTimeout >= 0) {
getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout);
@@ -167,43 +171,72 @@ public class OwnCloudClient extends HttpClient {
@Override
public int executeMethod(HttpMethod method) throws IOException, HttpException {
- boolean customRedirectionNeeded = false;
- try {
- method.setFollowRedirects(mFollowRedirects);
- } catch (Exception e) {
- //if (mFollowRedirects) Log_OC.d(TAG, "setFollowRedirects failed for " + method.getName() + " method, custom redirection will be used if needed");
- customRedirectionNeeded = mFollowRedirects;
+ try { // just to log
+ boolean customRedirectionNeeded = false;
+
+ try {
+ method.setFollowRedirects(mFollowRedirects);
+ } catch (Exception e) {
+ /*
+ if (mFollowRedirects)
+ Log_OC.d(TAG, "setFollowRedirects failed for " + method.getName()
+ + " method, custom redirection will be used if needed");
+ */
+ customRedirectionNeeded = mFollowRedirects;
+ }
+
+ Log.d(TAG + " #" + mInstanceNumber, "REQUEST " +
+ method.getName() + " " + method.getPath());
+
+// logCookiesAtRequest(method.getRequestHeaders(), "before");
+// logCookiesAtState("before");
+
+ int status = super.executeMethod(method);
+
+ if (customRedirectionNeeded) {
+ status = patchRedirection(status, method);
+ }
+
+// logCookiesAtRequest(method.getRequestHeaders(), "after");
+// logCookiesAtState("after");
+// logSetCookiesAtResponse(method.getResponseHeaders());
+
+ return status;
+
+ } catch (IOException e) {
+ Log.d(TAG + " #" + mInstanceNumber, "Exception occured", e);
+ throw e;
}
- if (mSsoSessionCookie != null && mSsoSessionCookie.length() > 0) {
- method.addRequestHeader("Cookie", mSsoSessionCookie);
- }
- int status = super.executeMethod(method);
+ }
+
+ private int patchRedirection(int status, HttpMethod method) throws HttpException, IOException {
int redirectionsCount = 0;
- while (customRedirectionNeeded &&
- redirectionsCount < MAX_REDIRECTIONS_COUNT &&
+ while (redirectionsCount < MAX_REDIRECTIONS_COUNT &&
( status == HttpStatus.SC_MOVED_PERMANENTLY ||
status == HttpStatus.SC_MOVED_TEMPORARILY ||
status == HttpStatus.SC_TEMPORARY_REDIRECT)
) {
Header location = method.getResponseHeader("Location");
+ if (location == null) {
+ location = method.getResponseHeader("location");
+ }
if (location != null) {
- Log.d(TAG, "Location to redirect: " + location.getValue());
+ Log.d(TAG + " #" + mInstanceNumber,
+ "Location to redirect: " + location.getValue());
method.setURI(new URI(location.getValue(), true));
status = super.executeMethod(method);
redirectionsCount++;
} else {
- Log.d(TAG, "No location to redirect!");
+ Log.d(TAG + " #" + mInstanceNumber, "No location to redirect!");
status = HttpStatus.SC_NOT_FOUND;
}
}
-
return status;
- }
+ }
-
- /**
+ /**
* Exhausts a not interesting HTTP response. Encouraged by HttpClient documentation.
*
* @param responseBodyAsStream InputStream with the HTTP response to exhaust.
@@ -215,53 +248,137 @@ public class OwnCloudClient extends HttpClient {
responseBodyAsStream.close();
} catch (IOException io) {
- Log.e(TAG, "Unexpected exception while exhausting not interesting HTTP response; will be IGNORED", io);
+ Log.e(TAG, "Unexpected exception while exhausting not interesting HTTP response;" +
+ " will be IGNORED", io);
}
}
}
/**
- * Sets the connection and wait-for-data timeouts to be applied by default to the methods performed by this client.
+ * Sets the connection and wait-for-data timeouts to be applied by default to the methods
+ * performed by this client.
*/
public void setDefaultTimeouts(int defaultDataTimeout, int defaultConnectionTimeout) {
- getParams().setSoTimeout(defaultDataTimeout);
- getHttpConnectionManager().getParams().setConnectionTimeout(defaultConnectionTimeout);
- }
-
- /**
- * Sets the Webdav URI for the helper methods that receive paths as parameters, instead of full URLs
- * @param uri
- */
- public void setWebdavUri(Uri uri) {
- mWebdavUri = uri;
+ if (defaultDataTimeout >= 0) {
+ getParams().setSoTimeout(defaultDataTimeout);
+ }
+ if (defaultConnectionTimeout >= 0) {
+ getHttpConnectionManager().getParams().setConnectionTimeout(defaultConnectionTimeout);
+ }
}
public Uri getWebdavUri() {
- return mWebdavUri;
+ if (mCredentials instanceof OwnCloudBearerCredentials) {
+ return Uri.parse(mBaseUri + AccountUtils.ODAV_PATH);
+ } else {
+ return Uri.parse(mBaseUri + AccountUtils.WEBDAV_PATH_4_0);
+ }
}
/**
- * Sets the base URI for the helper methods that receive paths as parameters, instead of full URLs
+ * Sets the root URI to the ownCloud server.
+ *
+ * Use with care.
+ *
* @param uri
*/
public void setBaseUri(Uri uri) {
- mUri = uri;
+ if (uri == null) {
+ throw new IllegalArgumentException("URI cannot be NULL");
+ }
+ mBaseUri = uri;
}
public Uri getBaseUri() {
- return mUri;
+ return mBaseUri;
}
- public final Credentials getCredentials() {
+ public final OwnCloudCredentials getCredentials() {
return mCredentials;
}
- public final String getSsoSessionCookie() {
- return mSsoSessionCookie;
- }
-
public void setFollowRedirects(boolean followRedirects) {
mFollowRedirects = followRedirects;
}
+
+ private void logCookiesAtRequest(Header[] headers, String when) {
+ int counter = 0;
+ for (int i=0; i future = am.getAuthToken(account, AccountTypeUtils.getAuthTokenTypeAccessToken(account.type), null, currentActivity, null, null);
+ AccountManagerFuture future = am.getAuthToken(
+ account,
+ AccountTypeUtils.getAuthTokenTypeAccessToken(account.type),
+ null,
+ currentActivity,
+ null,
+ null);
+
Bundle result = future.getResult();
String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN);
if (accessToken == null) throw new AuthenticatorException("WTF!");
- client.setBearerCredentials(accessToken); // TODO not assume that the access token is a bearer token
+ client.setCredentials(
+ OwnCloudCredentialsFactory.newBearerCredentials(accessToken)
+ );
} else if (isSamlSso) { // TODO avoid a call to getUserData here
- AccountManagerFuture future = am.getAuthToken(account, AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(account.type), null, currentActivity, null, null);
+ AccountManagerFuture future = am.getAuthToken(
+ account,
+ AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(account.type),
+ null,
+ currentActivity,
+ null,
+ null);
+
Bundle result = future.getResult();
String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN);
if (accessToken == null) throw new AuthenticatorException("WTF!");
- client.setSsoSessionCookie(accessToken);
+ client.setCredentials(
+ OwnCloudCredentialsFactory.newSamlSsoCredentials(accessToken)
+ );
+
} else {
String username = account.name.substring(0, account.name.lastIndexOf('@'));
//String password = am.getPassword(account);
//String password = am.blockingGetAuthToken(account, MainApp.getAuthTokenTypePass(), false);
- AccountManagerFuture future = am.getAuthToken(account, AccountTypeUtils.getAuthTokenTypePass(account.type), null, currentActivity, null, null);
+ AccountManagerFuture future = am.getAuthToken(
+ account,
+ AccountTypeUtils.getAuthTokenTypePass(account.type),
+ null,
+ currentActivity,
+ null,
+ null);
+
Bundle result = future.getResult();
String password = result.getString(AccountManager.KEY_AUTHTOKEN);
- client.setBasicCredentials(username, password);
+ client.setCredentials(
+ OwnCloudCredentialsFactory.newBasicCredentials(username, password)
+ );
}
+ // Restore cookies
+ AccountUtils.restoreCookies(account, client, appContext);
+
return client;
}
/**
* Creates a OwnCloudClient to access a URL and sets the desired parameters for ownCloud client connections.
*
- * @param uri URL to the ownCloud server
+ * @param uri URL to the ownCloud server; BASE ENTRY POINT, not WebDavPATH
* @param context Android context where the OwnCloudClient is being created.
* @return A OwnCloudClient object ready to be used
*/
@@ -150,14 +198,12 @@ public class OwnCloudClientFactory {
Log.e(TAG, "The local server truststore could not be read. Default SSL management in the system will be used for HTTPS connections", e);
}
- OwnCloudClient client = new OwnCloudClient(NetworkUtils.getMultiThreadedConnManager());
-
+ OwnCloudClient client = new OwnCloudClient(uri, NetworkUtils.getMultiThreadedConnManager());
client.setDefaultTimeouts(DEFAULT_DATA_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT);
- client.setWebdavUri(uri);
client.setFollowRedirects(followRedirects);
return client;
}
-
+
}
diff --git a/src/com/owncloud/android/lib/common/OwnCloudClientManager.java b/src/com/owncloud/android/lib/common/OwnCloudClientManager.java
new file mode 100644
index 00000000..e54ae191
--- /dev/null
+++ b/src/com/owncloud/android/lib/common/OwnCloudClientManager.java
@@ -0,0 +1,53 @@
+/* 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.common;
+
+import java.io.IOException;
+
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.content.Context;
+
+import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
+
+
+/**
+ * Manager to create and reuse OwnCloudClient instances to access remote OC servers.
+ *
+ * @author David A. Velasco
+ * @author masensio
+ */
+
+public interface OwnCloudClientManager {
+
+ public OwnCloudClient getClientFor(OwnCloudAccount account, Context context);
+
+ public OwnCloudClient removeClientFor(OwnCloudAccount account);
+
+ public void saveAllClients(Context context, String accountType)
+ throws AccountNotFoundException, AuthenticatorException,
+ IOException, OperationCanceledException;
+
+}
diff --git a/src/com/owncloud/android/lib/common/OwnCloudClientManagerFactory.java b/src/com/owncloud/android/lib/common/OwnCloudClientManagerFactory.java
new file mode 100644
index 00000000..216e2e30
--- /dev/null
+++ b/src/com/owncloud/android/lib/common/OwnCloudClientManagerFactory.java
@@ -0,0 +1,67 @@
+package com.owncloud.android.lib.common;
+
+public class OwnCloudClientManagerFactory {
+
+ public static enum Policy {
+ ALWAYS_NEW_CLIENT,
+ SINGLE_SESSION_PER_ACCOUNT
+ }
+
+ private static Policy sDefaultPolicy = Policy.ALWAYS_NEW_CLIENT;
+
+ private static OwnCloudClientManager sDefaultSingleton;
+
+ public static OwnCloudClientManager newDefaultOwnCloudClientManager() {
+ return newOwnCloudClientManager(sDefaultPolicy);
+ }
+
+ public static OwnCloudClientManager newOwnCloudClientManager(Policy policy) {
+ switch (policy) {
+ case ALWAYS_NEW_CLIENT:
+ return new SimpleFactoryManager();
+
+ case SINGLE_SESSION_PER_ACCOUNT:
+ return new SingleSessionManager();
+
+ default:
+ throw new IllegalArgumentException("Unknown policy");
+ }
+ }
+
+ public static OwnCloudClientManager getDefaultSingleton() {
+ if (sDefaultSingleton == null) {
+ sDefaultSingleton = newDefaultOwnCloudClientManager();
+ }
+ return sDefaultSingleton;
+ }
+
+ public static Policy getDefaultPolicy() {
+ return sDefaultPolicy;
+ }
+
+ public static void setDefaultPolicy(Policy policy) {
+ if (policy == null) {
+ throw new IllegalArgumentException("Default policy cannot be NULL");
+ }
+ if (defaultSingletonMustBeUpdated(policy)) {
+ sDefaultSingleton = null;
+ }
+ sDefaultPolicy = policy;
+ }
+
+ private static boolean defaultSingletonMustBeUpdated(Policy policy) {
+ if (sDefaultSingleton == null) {
+ return false;
+ }
+ if (policy == Policy.ALWAYS_NEW_CLIENT &&
+ !(sDefaultSingleton instanceof SimpleFactoryManager)) {
+ return true;
+ }
+ if (policy == Policy.SINGLE_SESSION_PER_ACCOUNT &&
+ !(sDefaultSingleton instanceof SingleSessionManager)) {
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/src/com/owncloud/android/lib/common/OwnCloudCredentials.java b/src/com/owncloud/android/lib/common/OwnCloudCredentials.java
new file mode 100644
index 00000000..a3fff2eb
--- /dev/null
+++ b/src/com/owncloud/android/lib/common/OwnCloudCredentials.java
@@ -0,0 +1,30 @@
+/* ownCloud Android client application
+ * Copyright (C) 2014 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.lib.common;
+
+public interface OwnCloudCredentials {
+
+ public void applyTo(OwnCloudClient ownCloudClient);
+
+ public String getUsername();
+
+ public String getAuthToken();
+
+ public boolean authTokenExpires();
+
+}
diff --git a/src/com/owncloud/android/lib/common/OwnCloudCredentialsFactory.java b/src/com/owncloud/android/lib/common/OwnCloudCredentialsFactory.java
new file mode 100644
index 00000000..ee84859d
--- /dev/null
+++ b/src/com/owncloud/android/lib/common/OwnCloudCredentialsFactory.java
@@ -0,0 +1,54 @@
+package com.owncloud.android.lib.common;
+
+public class OwnCloudCredentialsFactory {
+
+ private static OwnCloudAnonymousCredentials sAnonymousCredentials;
+
+ public static OwnCloudCredentials newBasicCredentials(String username, String password) {
+ return new OwnCloudBasicCredentials(username, password);
+ }
+
+ public static OwnCloudCredentials newBearerCredentials(String authToken) {
+ return new OwnCloudBearerCredentials(authToken);
+ }
+
+ public static OwnCloudCredentials newSamlSsoCredentials(String sessionCookie) {
+ return new OwnCloudSamlSsoCredentials(sessionCookie);
+ }
+
+ public static final OwnCloudCredentials getAnonymousCredentials() {
+ if (sAnonymousCredentials == null) {
+ sAnonymousCredentials = new OwnCloudAnonymousCredentials();
+ }
+ return sAnonymousCredentials;
+ }
+
+ public static final class OwnCloudAnonymousCredentials implements OwnCloudCredentials {
+
+ protected OwnCloudAnonymousCredentials() {
+ }
+
+ @Override
+ public void applyTo(OwnCloudClient client) {
+ client.getState().clearCredentials();
+ client.getState().clearCookies();
+ }
+
+ @Override
+ public String getAuthToken() {
+ return "";
+ }
+
+ @Override
+ public boolean authTokenExpires() {
+ return false;
+ }
+
+ @Override
+ public String getUsername() {
+ // no user name
+ return null;
+ }
+ }
+
+}
diff --git a/src/com/owncloud/android/lib/common/OwnCloudSamlSsoCredentials.java b/src/com/owncloud/android/lib/common/OwnCloudSamlSsoCredentials.java
new file mode 100644
index 00000000..d59f5b0c
--- /dev/null
+++ b/src/com/owncloud/android/lib/common/OwnCloudSamlSsoCredentials.java
@@ -0,0 +1,57 @@
+package com.owncloud.android.lib.common;
+
+import org.apache.commons.httpclient.Cookie;
+import org.apache.commons.httpclient.cookie.CookiePolicy;
+
+import android.net.Uri;
+
+public class OwnCloudSamlSsoCredentials implements OwnCloudCredentials {
+
+ private String mSessionCookie;
+
+ public OwnCloudSamlSsoCredentials(String sessionCookie) {
+ mSessionCookie = sessionCookie != null ? sessionCookie : "";
+ }
+
+ @Override
+ public void applyTo(OwnCloudClient client) {
+ client.getParams().setAuthenticationPreemptive(false);
+ client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
+ client.setFollowRedirects(false);
+
+ Uri serverUri = client.getBaseUri();
+
+ String[] cookies = mSessionCookie.split(";");
+ if (cookies.length > 0) {
+ Cookie cookie = null;
+ for (int i=0; i= 0) {
+ cookie = new Cookie();
+ cookie.setName(cookies[i].substring(0, equalPos));
+ cookie.setValue(cookies[i].substring(equalPos + 1));
+ cookie.setDomain(serverUri.getHost()); // VERY IMPORTANT
+ cookie.setPath(serverUri.getPath()); // VERY IMPORTANT
+ client.getState().addCookie(cookie);
+ }
+ }
+ }
+ }
+
+ @Override
+ public String getUsername() {
+ // its unknown
+ return null;
+ }
+
+ @Override
+ public String getAuthToken() {
+ return mSessionCookie;
+ }
+
+ @Override
+ public boolean authTokenExpires() {
+ return true;
+ }
+
+}
diff --git a/src/com/owncloud/android/lib/common/SimpleFactoryManager.java b/src/com/owncloud/android/lib/common/SimpleFactoryManager.java
new file mode 100644
index 00000000..94918ec6
--- /dev/null
+++ b/src/com/owncloud/android/lib/common/SimpleFactoryManager.java
@@ -0,0 +1,68 @@
+/* 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.common;
+
+
+import com.owncloud.android.lib.common.accounts.AccountUtils;
+
+import android.content.Context;
+import android.util.Log;
+
+public class SimpleFactoryManager implements OwnCloudClientManager {
+
+ private static final String TAG = SimpleFactoryManager.class.getSimpleName();
+
+ @Override
+ public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) {
+ Log.d(TAG, "getClientFor(OwnCloudAccount ... : ");
+ OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient(
+ account.getBaseUri(),
+ context.getApplicationContext(),
+ true);
+
+ Log.d(TAG, " new client {" +
+ (account.getName() != null ?
+ account.getName() :
+ AccountUtils.buildAccountName(
+ account.getBaseUri(),
+ account.getCredentials().getAuthToken())) +
+ ", " + client.hashCode() + "}");
+
+ client.setCredentials(account.getCredentials());
+ return client;
+ }
+
+ @Override
+ public OwnCloudClient removeClientFor(OwnCloudAccount account) {
+ // nothing to do - not taking care of tracking instances!
+ return null;
+ }
+
+ @Override
+ public void saveAllClients(Context context, String accountType) {
+ // nothing to do - not taking care of tracking instances!
+ }
+
+}
diff --git a/src/com/owncloud/android/lib/common/SingleSessionManager.java b/src/com/owncloud/android/lib/common/SingleSessionManager.java
new file mode 100644
index 00000000..638362f6
--- /dev/null
+++ b/src/com/owncloud/android/lib/common/SingleSessionManager.java
@@ -0,0 +1,209 @@
+/* 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.common;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.httpclient.cookie.CookiePolicy;
+
+import android.accounts.Account;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+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.accounts.AccountUtils;
+import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
+
+/**
+ * Implementation of {@link OwnCloudClientManager}
+ *
+ * TODO check multithreading safety
+ *
+ * @author David A. Velasco
+ * @author masensio
+ */
+
+public class SingleSessionManager implements OwnCloudClientManager {
+
+ private static final String TAG = SingleSessionManager.class.getSimpleName();
+
+ private Map mClientsWithKnownUsername =
+ new HashMap();
+
+ private Map mClientsWithUnknownUsername =
+ new HashMap();
+
+
+ @Override
+ public synchronized OwnCloudClient getClientFor(OwnCloudAccount account, Context context) {
+ Log.d(TAG, "getClientFor(OwnCloudAccount ... : ");
+ if (account == null) {
+ throw new IllegalArgumentException("Cannot get an OwnCloudClient for a null account");
+ }
+
+ OwnCloudClient client = null;
+ String accountName = account.getName();
+ String sessionName = AccountUtils.buildAccountName(
+ account.getBaseUri(),
+ account.getCredentials().getAuthToken());
+
+ if (accountName != null) {
+ client = mClientsWithKnownUsername.get(accountName);
+ }
+ boolean reusingKnown = false; // just for logs
+ if (client == null) {
+ if (accountName != null) {
+ client = mClientsWithUnknownUsername.remove(sessionName);
+ if (client != null) {
+ Log.d(TAG, " reusing client {" + sessionName + ", " +
+ client.hashCode() + "}");
+ mClientsWithKnownUsername.put(accountName, client);
+ Log.d(TAG, " moved client to {" + accountName + ", " +
+ client.hashCode() + "}");
+ }
+ } else {
+ client = mClientsWithUnknownUsername.get(sessionName);
+ }
+ } else {
+ Log.d(TAG, " reusing client {" + accountName + ", " + client.hashCode() + "}");
+ reusingKnown = true;
+ }
+
+ if (client == null) {
+ // no client to reuse - create a new one
+ client = OwnCloudClientFactory.createOwnCloudClient(
+ account.getBaseUri(),
+ context.getApplicationContext(),
+ true); // TODO remove dependency on OwnCloudClientFactory
+ client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
+ // enable cookie tracking
+
+
+ // Restore Cookies ??
+ AccountUtils.restoreCookies(accountName, client, context);
+
+ client.setCredentials(account.getCredentials());
+ if (accountName != null) {
+ mClientsWithKnownUsername.put(accountName, client);
+ Log.d(TAG, " new client {" + accountName + ", " + client.hashCode() + "}");
+
+ } else {
+ mClientsWithUnknownUsername.put(sessionName, client);
+ Log.d(TAG, " new client {" + sessionName + ", " + client.hashCode() + "}");
+ }
+ } else {
+ if (!reusingKnown) {
+ Log.d(TAG, " reusing client {" + sessionName + ", " + client.hashCode() + "}");
+ }
+ keepCredentialsUpdated(account, client);
+ keepUriUpdated(account, client);
+ }
+
+ return client;
+ }
+
+
+ @Override
+ public OwnCloudClient removeClientFor(OwnCloudAccount account) {
+
+ if (account == null) {
+ return null;
+ }
+
+ OwnCloudClient client = null;
+ String accountName = account.getName();
+ if (accountName != null) {
+ client = mClientsWithKnownUsername.remove(accountName);
+ if (client != null) {
+ Log.d(TAG, "Removed client {" + accountName + ", " + client.hashCode() + "}");
+ return client;
+ } else {
+ Log.d(TAG, "No client tracked for {" + accountName + "}");
+ }
+ }
+
+ String sessionName = AccountUtils.buildAccountName(
+ account.getBaseUri(),
+ account.getCredentials().getAuthToken());
+ client = mClientsWithUnknownUsername.remove(sessionName);
+ if (client != null) {
+ Log.d(TAG, "Removed client {" + sessionName + ", " + client.hashCode() + "}");
+ return client;
+ }
+ Log.d(TAG, "No client tracked for {" + sessionName + "}");
+
+ Log.d(TAG, "No client removed");
+ return null;
+
+ }
+
+
+ @Override
+ public synchronized void saveAllClients(Context context, String accountType)
+ throws AccountNotFoundException, AuthenticatorException, IOException,
+ OperationCanceledException {
+
+ Iterator accountNames = mClientsWithKnownUsername.keySet().iterator();
+ String accountName = null;
+ Account account = null;
+ while (accountNames.hasNext()) {
+ accountName = accountNames.next();
+ account = new Account(accountName, accountType);
+ AccountUtils.saveClient(
+ mClientsWithKnownUsername.get(accountName),
+ account,
+ context);
+ }
+ }
+
+
+ private void keepCredentialsUpdated(OwnCloudAccount account, OwnCloudClient reusedClient) {
+ OwnCloudCredentials recentCredentials = account.getCredentials();
+ if (!recentCredentials.getAuthToken().equals(
+ reusedClient.getCredentials().getAuthToken())) {
+ reusedClient.setCredentials(recentCredentials);
+ }
+
+ }
+
+ // this method is just a patch; we need to distinguish accounts in the same host but
+ // different paths; but that requires updating the accountNames for apps upgrading
+ private void keepUriUpdated(OwnCloudAccount account, OwnCloudClient reusedClient) {
+ Uri recentUri = account.getBaseUri();
+ if (!recentUri.equals(reusedClient.getBaseUri())) {
+ reusedClient.setBaseUri(recentUri);
+ }
+
+ }
+
+
+}
diff --git a/src/com/owncloud/android/lib/common/accounts/AccountUtils.java b/src/com/owncloud/android/lib/common/accounts/AccountUtils.java
index 7f0cd351..591f93f7 100644
--- a/src/com/owncloud/android/lib/common/accounts/AccountUtils.java
+++ b/src/com/owncloud/android/lib/common/accounts/AccountUtils.java
@@ -25,18 +25,32 @@
package com.owncloud.android.lib.common.accounts;
-import com.owncloud.android.lib.resources.status.OwnCloudVersion;
+import java.io.IOException;
+
+import org.apache.commons.httpclient.Cookie;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountsException;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
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.OwnCloudCredentials;
+import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
+import com.owncloud.android.lib.resources.status.OwnCloudVersion;
public class AccountUtils {
+
+ private static final String TAG = AccountUtils.class.getSimpleName();
+
public static final String WEBDAV_PATH_1_2 = "/webdav/owncloud.php";
public static final String WEBDAV_PATH_2_0 = "/files/webdav.php";
public static final String WEBDAV_PATH_4_0 = "/remote.php/webdav";
- private static final String ODAV_PATH = "/remote.php/odav";
+ public static final String ODAV_PATH = "/remote.php/odav";
private static final String SAML_SSO_PATH = "/remote.php/webdav";
public static final String CARDDAV_PATH_2_0 = "/apps/contacts/carddav.php";
public static final String CARDDAV_PATH_4_0 = "/remote/carddav.php";
@@ -72,11 +86,15 @@ public class AccountUtils {
/**
* Constructs full url to host and webdav resource basing on host version
+ *
+ * @deprecated To be removed in release 1.0.
+ *
* @param context
* @param account
* @return url or null on failure
* @throws AccountNotFoundException When 'account' is unknown for the AccountManager
*/
+ @Deprecated
public static String constructFullURLForAccount(Context context, Account account) throws AccountNotFoundException {
AccountManager ama = AccountManager.get(context);
String baseurl = ama.getUserData(account, Constants.KEY_OC_BASE_URL);
@@ -94,13 +112,32 @@ public class AccountUtils {
/**
* Extracts url server from the account
+ *
+ * @deprecated This method will be removed in version 1.0.
+ * Use {@link #getBaseUrlForAccount(Context, Account)}
+ * instead.
+ *
* @param context
* @param account
* @return url server or null on failure
* @throws AccountNotFoundException When 'account' is unknown for the AccountManager
*/
- public static String constructBasicURLForAccount(Context context, Account account) throws AccountNotFoundException {
- AccountManager ama = AccountManager.get(context);
+ @Deprecated
+ public static String constructBasicURLForAccount(Context context, Account account)
+ throws AccountNotFoundException {
+ return getBaseUrlForAccount(context, account);
+ }
+
+ /**
+ * Extracts url server from the account
+ * @param context
+ * @param account
+ * @return url server or null on failure
+ * @throws AccountNotFoundException When 'account' is unknown for the AccountManager
+ */
+ public static String getBaseUrlForAccount(Context context, Account account)
+ throws AccountNotFoundException {
+ AccountManager ama = AccountManager.get(context.getApplicationContext());
String baseurl = ama.getUserData(account, Constants.KEY_OC_BASE_URL);
if (baseurl == null )
@@ -109,7 +146,148 @@ public class AccountUtils {
return baseurl;
}
+
+ /**
+ *
+ * @return
+ * @throws IOException
+ * @throws AuthenticatorException
+ * @throws OperationCanceledException
+ */
+ public static OwnCloudCredentials getCredentialsForAccount(Context context, Account account)
+ throws OperationCanceledException, AuthenticatorException, IOException {
+
+ OwnCloudCredentials credentials = null;
+ AccountManager am = AccountManager.get(context);
+
+ boolean isOauth2 = am.getUserData(
+ account,
+ AccountUtils.Constants.KEY_SUPPORTS_OAUTH2) != null;
+
+ boolean isSamlSso = am.getUserData(
+ account,
+ AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null;
+
+ if (isOauth2) {
+ String accessToken = am.blockingGetAuthToken(
+ account,
+ AccountTypeUtils.getAuthTokenTypeAccessToken(account.type),
+ false);
+
+ credentials = OwnCloudCredentialsFactory.newBearerCredentials(accessToken);
+
+ } else if (isSamlSso) {
+ String accessToken = am.blockingGetAuthToken(
+ account,
+ AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(account.type),
+ false);
+
+ credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials(accessToken);
+
+ } else {
+ String username = account.name.substring(0, account.name.lastIndexOf('@'));
+ String password = am.blockingGetAuthToken(
+ account,
+ AccountTypeUtils.getAuthTokenTypePass(account.type),
+ false);
+
+ credentials = OwnCloudCredentialsFactory.newBasicCredentials(username, password);
+ }
+
+ return credentials;
+
+ }
+
+
+ public static String buildAccountName(Uri serverBaseUrl, String username) {
+ if (serverBaseUrl.getScheme() == null) {
+ serverBaseUrl = Uri.parse("https://" + serverBaseUrl.toString());
+ }
+ String accountName = username + "@" + serverBaseUrl.getHost();
+ if (serverBaseUrl.getPort() >= 0) {
+ accountName += ":" + serverBaseUrl.getPort();
+ }
+ return accountName;
+ }
+
+ public static void saveClient(OwnCloudClient client, Account savedAccount, Context context) {
+
+ // Account Manager
+ AccountManager ac = AccountManager.get(context.getApplicationContext());
+
+ if (client != null) {
+ String cookiesString = client.getCookiesString();
+ if (cookiesString != "") {
+ ac.setUserData(savedAccount, Constants.KEY_COOKIES, cookiesString);
+ // Log.d(TAG, "Saving Cookies: "+ cookiesString );
+ }
+ }
+
+ }
+
+
+ /**
+ * Restore the client cookies
+ * @param account
+ * @param client
+ * @param context
+ */
+ public static void restoreCookies(Account account, OwnCloudClient client, Context context) {
+
+ Log.d(TAG, "Restoring cookies for " + account.name);
+
+ // Account Manager
+ AccountManager am = AccountManager.get(context.getApplicationContext());
+
+ Uri serverUri = (client.getBaseUri() != null)? client.getBaseUri() : client.getWebdavUri();
+
+ String cookiesString = am.getUserData(account, Constants.KEY_COOKIES);
+ if (cookiesString !=null) {
+ String[] cookies = cookiesString.split(";");
+ if (cookies.length > 0) {
+ for (int i=0; i< cookies.length; i++) {
+ Cookie cookie = new Cookie();
+ int equalPos = cookies[i].indexOf('=');
+ cookie.setName(cookies[i].substring(0, equalPos));
+ cookie.setValue(cookies[i].substring(equalPos + 1));
+ cookie.setDomain(serverUri.getHost()); // VERY IMPORTANT
+ cookie.setPath(serverUri.getPath()); // VERY IMPORTANT
+
+ client.getState().addCookie(cookie);
+ }
+ }
+ }
+ }
+
+ /**
+ * Restore the client cookies from accountName
+ * @param accountName
+ * @param client
+ * @param context
+ */
+ public static void restoreCookies(String accountName, OwnCloudClient client, Context context) {
+ Log.d(TAG, "Restoring cookies for " + accountName);
+
+ // Account Manager
+ AccountManager am = AccountManager.get(context.getApplicationContext());
+
+ // Get account
+ Account account = null;
+ Account accounts[] = am.getAccounts();
+ for (Account a : accounts) {
+ if (a.name.equals(accountName)) {
+ account = a;
+ break;
+ }
+ }
+
+ // Restoring cookies
+ if (account != null) {
+ restoreCookies(account, client, context);
+ }
+ }
+
public static class AccountNotFoundException extends AccountsException {
/** Generated - should be refreshed every time the class changes!! */
@@ -160,5 +338,10 @@ public class AccountUtils {
* Flag signaling if the ownCloud server supports Share API"
*/
public static final String KEY_SUPPORTS_SHARE_API = "oc_supports_share_api";
+ /**
+ * OC accout cookies
+ */
+ public static final String KEY_COOKIES = "oc_account_cookies";
}
+
}
diff --git a/src/com/owncloud/android/lib/common/network/WebdavEntry.java b/src/com/owncloud/android/lib/common/network/WebdavEntry.java
index b7ac35b5..d6fe7a54 100644
--- a/src/com/owncloud/android/lib/common/network/WebdavEntry.java
+++ b/src/com/owncloud/android/lib/common/network/WebdavEntry.java
@@ -30,18 +30,20 @@ import org.apache.jackrabbit.webdav.MultiStatusResponse;
import org.apache.jackrabbit.webdav.property.DavProperty;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.DavPropertySet;
-
-
-
+import org.apache.jackrabbit.webdav.xml.Namespace;
import android.net.Uri;
import android.util.Log;
public class WebdavEntry {
- private String mName, mPath, mUri, mContentType, mEtag;
- private long mContentLength, mCreateTimestamp, mModifiedTimestamp;
+ private static final String NAMESPACE_OC = "http://owncloud.org/ns";
+ private static final String EXTENDED_PROPERTY_NAME_PERMISSIONS = "permissions";
+ private static final String EXTENDED_PROPERTY_NAME_REMOTE_ID = "id";
- public WebdavEntry(MultiStatusResponse ms, String splitElement) {
+ private String mName, mPath, mUri, mContentType, mEtag, mPermissions, mRemoteId;
+ private long mContentLength, mCreateTimestamp, mModifiedTimestamp;
+
+ public WebdavEntry(MultiStatusResponse ms, String splitElement) {
resetData();
if (ms.getStatus().length != 0) {
mUri = ms.getHref();
@@ -106,6 +108,22 @@ public class WebdavEntry {
mEtag = mEtag.substring(1, mEtag.length()-1);
}
+ // OC permissions property
+ prop = propSet.get(
+ EXTENDED_PROPERTY_NAME_PERMISSIONS, Namespace.getNamespace(NAMESPACE_OC)
+ );
+ if (prop != null) {
+ mPermissions = prop.getValue().toString();
+ }
+
+ // OC remote id property
+ prop = propSet.get(
+ EXTENDED_PROPERTY_NAME_REMOTE_ID, Namespace.getNamespace(NAMESPACE_OC)
+ );
+ if (prop != null) {
+ mRemoteId = prop.getValue().toString();
+ }
+
} else {
Log.e("WebdavEntry",
"General fuckup, no status for webdav response");
@@ -152,8 +170,16 @@ public class WebdavEntry {
return mEtag;
}
+ public String permissions() {
+ return mPermissions;
+ }
+
+ public String remoteId() {
+ return mRemoteId;
+ }
+
private void resetData() {
- mName = mUri = mContentType = null;
+ mName = mUri = mContentType = mPermissions = null; mRemoteId = null;
mContentLength = mCreateTimestamp = mModifiedTimestamp = 0;
}
}
diff --git a/src/com/owncloud/android/lib/common/network/WebdavUtils.java b/src/com/owncloud/android/lib/common/network/WebdavUtils.java
index d64042bf..c701e45e 100644
--- a/src/com/owncloud/android/lib/common/network/WebdavUtils.java
+++ b/src/com/owncloud/android/lib/common/network/WebdavUtils.java
@@ -35,32 +35,30 @@ import android.net.Uri;
public class WebdavUtils {
public static final SimpleDateFormat DISPLAY_DATE_FORMAT = new SimpleDateFormat(
"dd.MM.yyyy hh:mm");
+
private static final SimpleDateFormat DATETIME_FORMATS[] = {
- new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US),
- new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
- new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", Locale.US),
- new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US),
- new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US),
- new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
- new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US) ,
- new SimpleDateFormat("yyyy-MM-dd hh:mm:ss") };
-
- public static String prepareXmlForPropFind() {
- String ret = "";
- return ret;
- }
-
- public static String prepareXmlForPatch() {
- return "";
- }
+ new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US),
+ new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
+ new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", Locale.US),
+ new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US),
+ new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US),
+ new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
+ new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US),
+ new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.US)
+ };
public static Date parseResponseDate(String date) {
Date returnDate = null;
+ SimpleDateFormat format = null;
for (int i = 0; i < DATETIME_FORMATS.length; ++i) {
try {
- returnDate = DATETIME_FORMATS[i].parse(date);
+ format = DATETIME_FORMATS[i];
+ synchronized(format) {
+ returnDate = format.parse(date);
+ }
return returnDate;
} catch (ParseException e) {
+ // this is not the format
}
}
return null;
diff --git a/src/com/owncloud/android/lib/common/operations/RemoteOperation.java b/src/com/owncloud/android/lib/common/operations/RemoteOperation.java
index 9d453090..bef4b86c 100644
--- a/src/com/owncloud/android/lib/common/operations/RemoteOperation.java
+++ b/src/com/owncloud/android/lib/common/operations/RemoteOperation.java
@@ -26,11 +26,12 @@ package com.owncloud.android.lib.common.operations;
import java.io.IOException;
-import org.apache.commons.httpclient.Credentials;
-
+import com.owncloud.android.lib.common.OwnCloudAccount;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.OwnCloudClientFactory;
-import com.owncloud.android.lib.common.network.BearerCredentials;
+import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
+import com.owncloud.android.lib.common.OwnCloudCredentials;
+import com.owncloud.android.lib.common.accounts.AccountUtils;
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
@@ -105,7 +106,9 @@ public abstract class RemoteOperation implements Runnable {
mAccount = account;
mContext = context.getApplicationContext();
try {
- mClient = OwnCloudClientFactory.createOwnCloudClient(mAccount, mContext);
+ OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, mContext);
+ mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
+ getClientFor(ocAccount, mContext);
} catch (Exception e) {
Log.e(TAG, "Error while trying to access to " + mAccount.name, e);
return new RemoteOperationResult(e);
@@ -135,12 +138,17 @@ public abstract class RemoteOperation implements Runnable {
*
* This method should be used whenever an ownCloud account is available, instead of {@link #execute(OwnCloudClient)}.
*
+ * @deprecated This method will be removed in version 1.0.
+ * Use {@link #execute(Account, Context, OnRemoteOperationListener, Handler)}
+ * instead.
+ *
* @param account ownCloud account in remote ownCloud server to reach during the execution of the operation.
* @param context Android context for the component calling the method.
* @param listener Listener to be notified about the execution of the operation.
* @param listenerHandler Handler associated to the thread where the methods of the listener objects must be called.
* @return Thread were the remote operation is executed.
*/
+ @Deprecated
public Thread execute(Account account, Context context, OnRemoteOperationListener listener, Handler listenerHandler, Activity callerActivity) {
if (account == null)
throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Account");
@@ -161,6 +169,42 @@ public abstract class RemoteOperation implements Runnable {
}
+ /**
+ * Asynchronously executes the remote operation
+ *
+ * This method should be used whenever an ownCloud account is available,
+ * instead of {@link #execute(OwnCloudClient, OnRemoteOperationListener, Handler))}.
+ *
+ * @param account ownCloud account in remote ownCloud server to reach during the
+ * execution of the operation.
+ * @param context Android context for the component calling the method.
+ * @param listener Listener to be notified about the execution of the operation.
+ * @param listenerHandler Handler associated to the thread where the methods of the listener
+ * objects must be called.
+ * @return Thread were the remote operation is executed.
+ */
+ public Thread execute(Account account, Context context, OnRemoteOperationListener listener,
+ Handler listenerHandler) {
+
+ if (account == null)
+ throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Account");
+ if (context == null)
+ throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Context");
+ mAccount = account;
+ mContext = context.getApplicationContext();
+ mCallerActivity = null;
+ mClient = null; // the client instance will be created from mAccount and mContext in the runnerThread to create below
+
+ mListener = listener;
+
+ mListenerHandler = listenerHandler;
+
+ Thread runnerThread = new Thread(this);
+ runnerThread.start();
+ return runnerThread;
+ }
+
+
/**
* Asynchronously executes the remote operation
*
@@ -205,11 +249,17 @@ public abstract class RemoteOperation implements Runnable {
try{
if (mClient == null) {
if (mAccount != null && mContext != null) {
+ /** DEPRECATED BLOCK - will be removed at version 1.0 */
if (mCallerActivity != null) {
- mClient = OwnCloudClientFactory.createOwnCloudClient(mAccount, mContext, mCallerActivity);
+ mClient = OwnCloudClientFactory.createOwnCloudClient(
+ mAccount, mContext, mCallerActivity);
} else {
- mClient = OwnCloudClientFactory.createOwnCloudClient(mAccount, mContext);
+ /** EOF DEPRECATED */
+ OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, mContext);
+ mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
+ getClientFor(ocAccount, mContext);
}
+
} else {
throw new IllegalStateException("Trying to run a remote operation asynchronously with no client instance or account");
}
@@ -228,21 +278,20 @@ public abstract class RemoteOperation implements Runnable {
result = run(mClient);
repeat = false;
+ /** DEPRECATED BLOCK - will be removed at version 1.0 ; don't trust in this code
+ * to trigger authentication update */
if (mCallerActivity != null && mAccount != null && mContext != null && !result.isSuccess() &&
-// (result.getCode() == ResultCode.UNAUTHORIZED || (result.isTemporalRedirection() && result.isIdPRedirection()))) {
(result.getCode() == ResultCode.UNAUTHORIZED || result.isIdPRedirection())) {
/// possible fail due to lack of authorization in an operation performed in foreground
- Credentials cred = mClient.getCredentials();
- String ssoSessionCookie = mClient.getSsoSessionCookie();
- if (cred != null || ssoSessionCookie != null) {
+ OwnCloudCredentials cred = mClient.getCredentials();
+ if (cred != null) {
/// confirmed : unauthorized operation
AccountManager am = AccountManager.get(mContext);
- boolean bearerAuthorization = (cred != null && cred instanceof BearerCredentials);
- boolean samlBasedSsoAuthorization = (cred == null && ssoSessionCookie != null);
- if (bearerAuthorization) {
- am.invalidateAuthToken(mAccount.type, ((BearerCredentials)cred).getAccessToken());
- } else if (samlBasedSsoAuthorization ) {
- am.invalidateAuthToken(mAccount.type, ssoSessionCookie);
+ if (cred.authTokenExpires()) {
+ am.invalidateAuthToken(
+ mAccount.type,
+ cred.getAuthToken()
+ );
} else {
am.clearPassword(mAccount);
}
@@ -251,8 +300,14 @@ public abstract class RemoteOperation implements Runnable {
result = null;
}
}
+ /** EOF DEPRECATED BLOCK **/
} while (repeat);
+ if (mAccount != null && mContext != null) {
+ // Save Client Cookies
+ AccountUtils.saveClient(mClient, mAccount, mContext);
+ }
+
final RemoteOperationResult resultToSend = result;
if (mListenerHandler != null && mListener != null) {
mListenerHandler.post(new Runnable() {
diff --git a/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java b/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java
index 4a1c33a6..922b7c9f 100644
--- a/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java
+++ b/src/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java
@@ -163,6 +163,8 @@ public class ReadRemoteFolderOperation extends RemoteOperation {
file.setMimeType(we.contentType());
file.setModifiedTimestamp(we.modifiedTimestamp());
file.setEtag(we.etag());
+ file.setPermissions(we.permissions());
+ file.setRemoteId(we.remoteId());
return file;
}
}
diff --git a/src/com/owncloud/android/lib/resources/files/RemoteFile.java b/src/com/owncloud/android/lib/resources/files/RemoteFile.java
index 0b96584c..0db4e591 100644
--- a/src/com/owncloud/android/lib/resources/files/RemoteFile.java
+++ b/src/com/owncloud/android/lib/resources/files/RemoteFile.java
@@ -48,7 +48,9 @@ public class RemoteFile implements Parcelable, Serializable {
private long mCreationTimestamp;
private long mModifiedTimestamp;
private String mEtag;
-
+ private String mPermissions;
+ private String mRemoteId;
+
/**
* Getters and Setters
*/
@@ -101,6 +103,22 @@ public class RemoteFile implements Parcelable, Serializable {
this.mEtag = etag;
}
+ public String getPermissions() {
+ return mPermissions;
+ }
+
+ public void setPermissions(String permissions) {
+ this.mPermissions = permissions;
+ }
+
+ public String getRemoteId() {
+ return mRemoteId;
+ }
+
+ public void setRemoteId(String remoteId) {
+ this.mRemoteId = remoteId;
+ }
+
public RemoteFile() {
resetData();
}
@@ -127,6 +145,8 @@ public class RemoteFile implements Parcelable, Serializable {
this.setMimeType(we.contentType());
this.setModifiedTimestamp(we.modifiedTimestamp());
this.setEtag(we.etag());
+ this.setPermissions(we.permissions());
+ this.setRemoteId(we.remoteId());
}
/**
@@ -139,6 +159,8 @@ public class RemoteFile implements Parcelable, Serializable {
mCreationTimestamp = 0;
mModifiedTimestamp = 0;
mEtag = null;
+ mPermissions = null;
+ mRemoteId = null;
}
/**
@@ -173,6 +195,8 @@ public class RemoteFile implements Parcelable, Serializable {
mCreationTimestamp = source.readLong();
mModifiedTimestamp = source.readLong();
mEtag = source.readString();
+ mPermissions= source.readString();
+ mRemoteId = source.readString();
}
@Override
@@ -187,7 +211,9 @@ public class RemoteFile implements Parcelable, Serializable {
dest.writeLong(mLength);
dest.writeLong(mCreationTimestamp);
dest.writeLong(mModifiedTimestamp);
- dest.writeString(mEtag);
+ dest.writeString(mEtag);
+ dest.writeString(mPermissions);
+ dest.writeString(mRemoteId);
}
diff --git a/src/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.java b/src/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.java
index 9a675587..458a91d3 100644
--- a/src/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.java
+++ b/src/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.java
@@ -59,37 +59,39 @@ public class GetRemoteStatusOperation extends RemoteOperation {
private static final String NODE_INSTALLED = "installed";
private static final String NODE_VERSION = "version";
- private String mUrl;
private RemoteOperationResult mLatestResult;
private Context mContext;
- public GetRemoteStatusOperation(String url, Context context) {
- mUrl = url;
+ public GetRemoteStatusOperation(Context context) {
mContext = context;
}
- private boolean tryConnection(OwnCloudClient wc, String urlSt) {
+ private boolean tryConnection(OwnCloudClient client) {
boolean retval = false;
GetMethod get = null;
+ String baseUrlSt = client.getBaseUri().toString();
try {
- get = new GetMethod(urlSt);
- int status = wc.executeMethod(get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT);
+ get = new GetMethod(baseUrlSt + AccountUtils.STATUS_PATH);
+ int status = client.executeMethod(get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT);
String response = get.getResponseBodyAsString();
if (status == HttpStatus.SC_OK) {
JSONObject json = new JSONObject(response);
if (!json.getBoolean(NODE_INSTALLED)) {
- mLatestResult = new RemoteOperationResult(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED);
+ mLatestResult = new RemoteOperationResult(
+ RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED);
} else {
String version = json.getString(NODE_VERSION);
OwnCloudVersion ocVersion = new OwnCloudVersion(version);
if (!ocVersion.isVersionValid()) {
- mLatestResult = new RemoteOperationResult(RemoteOperationResult.ResultCode.BAD_OC_VERSION);
+ mLatestResult = new RemoteOperationResult(
+ RemoteOperationResult.ResultCode.BAD_OC_VERSION);
} else {
- mLatestResult = new RemoteOperationResult(urlSt.startsWith("https://") ?
- RemoteOperationResult.ResultCode.OK_SSL :
- RemoteOperationResult.ResultCode.OK_NO_SSL
- );
+ mLatestResult = new RemoteOperationResult(
+ baseUrlSt.startsWith("https://") ?
+ RemoteOperationResult.ResultCode.OK_SSL :
+ RemoteOperationResult.ResultCode.OK_NO_SSL
+ );
ArrayList