1
0
mirror of https://github.com/owncloud/android-library.git synced 2025-06-08 00:16:09 +00:00

Extend chance of silent refresh of auth token in RemoteOperations that are run with execute(...) methods receiving OwnCloudClients

This commit is contained in:
David A. Velasco 2017-08-14 14:46:08 +02:00
parent c7ade613c6
commit dd2d3b8996
6 changed files with 86 additions and 42 deletions

View File

@ -33,7 +33,6 @@ import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HostConfiguration; import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager; import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpMethodBase; import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.HttpStatus;
@ -41,10 +40,10 @@ import org.apache.commons.httpclient.HttpVersion;
import org.apache.commons.httpclient.URI; import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException; import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.cookie.CookiePolicy; import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.params.HttpMethodParams; import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.params.HttpParams; import org.apache.commons.httpclient.params.HttpParams;
import android.content.Context;
import android.net.Uri; import android.net.Uri;
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
@ -52,7 +51,6 @@ import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials; import com.owncloud.android.lib.common.authentication.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.RedirectionPath;
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; import com.owncloud.android.lib.resources.status.OwnCloudVersion;
@ -75,6 +73,11 @@ public class OwnCloudClient extends HttpClient {
private OwnCloudVersion mVersion = null; private OwnCloudVersion mVersion = null;
/// next too attributes are a very ugly dependency, added to grant silent retry of OAuth token when needed ;
/// see {} for more details
private Context mContext;
private OwnCloudAccount mAccount;
/** /**
* Constructor * Constructor
*/ */
@ -448,4 +451,21 @@ public class OwnCloudClient extends HttpClient {
public OwnCloudVersion getOwnCloudVersion() { public OwnCloudVersion getOwnCloudVersion() {
return mVersion; return mVersion;
} }
public void setContext(Context context) {
this.mContext = context;
}
public Context getContext() {
return mContext;
}
public void setAccount(OwnCloudAccount account) {
this.mAccount = account;
}
public OwnCloudAccount getAccount() {
return mAccount;
}
} }

View File

@ -176,6 +176,7 @@ public class OwnCloudClientFactory {
OwnCloudClient client = new OwnCloudClient(uri, NetworkUtils.getMultiThreadedConnManager()); OwnCloudClient client = new OwnCloudClient(uri, NetworkUtils.getMultiThreadedConnManager());
client.setDefaultTimeouts(DEFAULT_DATA_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT); client.setDefaultTimeouts(DEFAULT_DATA_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT);
client.setFollowRedirects(followRedirects); client.setFollowRedirects(followRedirects);
client.setContext(context);
return client; return client;
} }

View File

@ -62,6 +62,7 @@ public class SimpleFactoryManager implements OwnCloudClientManager {
account.loadCredentials(context); account.loadCredentials(context);
} }
client.setCredentials(account.getCredentials()); client.setCredentials(account.getCredentials());
client.setAccount(account);
return client; return client;
} }

View File

@ -116,6 +116,7 @@ public class SingleSessionManager implements OwnCloudClientManager {
context.getApplicationContext(), context.getApplicationContext(),
true); // TODO remove dependency on OwnCloudClientFactory true); // TODO remove dependency on OwnCloudClientFactory
client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
client.setAccount(account);
// enable cookie tracking // enable cookie tracking
AccountUtils.restoreCookies(account.getSavedAccount(), client, context); AccountUtils.restoreCookies(account.getSavedAccount(), client, context);

View File

@ -287,7 +287,9 @@ public class AccountUtils {
should &= (client.getCredentials() != null && // real credentials should &= (client.getCredentials() != null && // real credentials
!(client.getCredentials() instanceof OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials)); !(client.getCredentials() instanceof OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials));
should &= (account != null && context != null); // have all the needed to effectively invalidate // test if have all the needed to effectively invalidate ...
should &= ((account != null && context != null) || // ... either directly, or ...
client.getAccount() != null && client.getContext() != null) ; // ... indirectly
return should; return should;
} }
@ -310,16 +312,25 @@ public class AccountUtils {
Account account, Account account,
Context context Context context
) { ) {
Account checkedAccount = (account == null) ? client.getAccount().getSavedAccount() : account;
if (checkedAccount == null) {
throw new IllegalArgumentException("Account cannot be null both in parameter and in client");
}
Context checkedContext = (context == null) ? client.getContext() : context;
if (checkedContext == null) {
throw new IllegalArgumentException("Context cannot be null both in parameter and in client");
}
try { try {
OwnCloudAccount ocAccount = new OwnCloudAccount(account, context); OwnCloudAccount ocAccount = new OwnCloudAccount(checkedAccount, checkedContext);
OwnCloudClientManagerFactory.getDefaultSingleton(). OwnCloudClientManagerFactory.getDefaultSingleton().
removeClientFor(ocAccount); // to prevent nobody else is provided this client removeClientFor(ocAccount); // to prevent nobody else is provided this client
AccountManager am = AccountManager.get(context); AccountManager am = AccountManager.get(checkedContext);
am.invalidateAuthToken( am.invalidateAuthToken(
account.type, checkedAccount.type,
client.getCredentials().getAuthToken() client.getCredentials().getAuthToken()
); );
am.clearPassword(account); // being strict, only needed for Basic Auth credentials am.clearPassword(checkedAccount); // being strict, only needed for Basic Auth credentials
return true; return true;
} catch (AccountUtils.AccountNotFoundException e) { } catch (AccountUtils.AccountNotFoundException e) {

View File

@ -90,10 +90,14 @@ public abstract class RemoteOperation implements Runnable {
/** /**
* When 'true', the operation tries to silently refresh credentials if fails due to lack of authorization. * When 'true', the operation tries to silently refresh credentials if fails due to lack of authorization.
* *
* Valid for 'execute methods' receiving an {@link Account} instance as parameter, but not for those * Valid for 'execute methods' receiving an {@link Account} instance as parameter, out of the box:
* receiving an {@link OwnCloudClient}. This is, valid for:
* -- {@link RemoteOperation#execute(Account, Context)} * -- {@link RemoteOperation#execute(Account, Context)}
* -- {@link RemoteOperation#execute(Account, Context, OnRemoteOperationListener, Handler)} * -- {@link RemoteOperation#execute(Account, Context, OnRemoteOperationListener, Handler)}
*
* Valid for 'execute methods' receiving an {@link OwnCloudClient}, as long as it returns non null values
* to its methods {@link OwnCloudClient#getContext()} && {@link OwnCloudClient#getAccount()}:
* -- {@link RemoteOperation#execute(OwnCloudClient)}
* -- {@link RemoteOperation#execute(OwnCloudClient, OnRemoteOperationListener, Handler)}
*/ */
private boolean mSilentRefreshOfAccountCredentials = false; private boolean mSilentRefreshOfAccountCredentials = false;
@ -160,7 +164,10 @@ public abstract class RemoteOperation implements Runnable {
throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " + throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " +
"OwnCloudClient"); "OwnCloudClient");
mClient = client; mClient = client;
mSilentRefreshOfAccountCredentials = false; if (client.getAccount() != null) {
mAccount = client.getAccount().getSavedAccount();
}
mContext = client.getContext();
return runOperation(); return runOperation();
} }
@ -221,6 +228,10 @@ public abstract class RemoteOperation implements Runnable {
("Trying to execute a remote operation with a NULL OwnCloudClient"); ("Trying to execute a remote operation with a NULL OwnCloudClient");
} }
mClient = client; mClient = client;
if (client.getAccount() != null) {
mAccount = client.getAccount().getSavedAccount();
}
mContext = client.getContext();
if (listener == null) { if (listener == null) {
throw new IllegalArgumentException throw new IllegalArgumentException
@ -233,8 +244,6 @@ public abstract class RemoteOperation implements Runnable {
mListenerHandler = listenerHandler; mListenerHandler = listenerHandler;
} }
mSilentRefreshOfAccountCredentials = false;
Thread runnerThread = new Thread(this); Thread runnerThread = new Thread(this);
runnerThread.start(); runnerThread.start();
return runnerThread; return runnerThread;
@ -359,7 +368,7 @@ public abstract class RemoteOperation implements Runnable {
/** /**
* Enables or disables silent refresh of credentials, if supported by credentials itself. * Enables or disables silent refresh of credentials, if supported by credentials itself.
* *
* Will have effect if called before: * Will have effect if called before in all cases:
* -- {@link RemoteOperation#execute(Account, Context)} * -- {@link RemoteOperation#execute(Account, Context)}
* -- {@link RemoteOperation#execute(Account, Context, OnRemoteOperationListener, Handler)} * -- {@link RemoteOperation#execute(Account, Context, OnRemoteOperationListener, Handler)}
* *
@ -367,7 +376,8 @@ public abstract class RemoteOperation implements Runnable {
* -- {@link RemoteOperation#execute(OwnCloudClient)} * -- {@link RemoteOperation#execute(OwnCloudClient)}
* -- {@link RemoteOperation#execute(OwnCloudClient, OnRemoteOperationListener, Handler)} * -- {@link RemoteOperation#execute(OwnCloudClient, OnRemoteOperationListener, Handler)}
* *
* @param silentRefreshOfAccountCredentials 'True' enables silent refresh, 'false' disables it. * ... UNLESS the passed {@link OwnCloudClient} returns non-NULL values for
* {@link OwnCloudClient#getAccount()} && {@link OwnCloudClient#getContext()}
*/ */
public void setSilentRefreshOfAccountCredentials(boolean silentRefreshOfAccountCredentials) { public void setSilentRefreshOfAccountCredentials(boolean silentRefreshOfAccountCredentials) {
mSilentRefreshOfAccountCredentials = silentRefreshOfAccountCredentials; mSilentRefreshOfAccountCredentials = silentRefreshOfAccountCredentials;