mirror of
https://github.com/nextcloud/android.git
synced 2024-11-27 17:46:37 +03:00
Redirect app to login screen when operations in file details view fail due to bad credentials
This commit is contained in:
parent
11b88e0fcc
commit
73f8797b75
7 changed files with 99 additions and 32 deletions
|
@ -44,10 +44,13 @@ import eu.alefzero.webdav.WebdavClient;
|
|||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.AccountManagerFuture;
|
||||
import android.accounts.AuthenticatorException;
|
||||
import android.accounts.OperationCanceledException;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
public class OwnCloudClientUtils {
|
||||
|
@ -103,6 +106,31 @@ public class OwnCloudClientUtils {
|
|||
}
|
||||
|
||||
|
||||
public static WebdavClient createOwnCloudClient (Account account, Context appContext, Activity currentActivity) throws OperationCanceledException, AuthenticatorException, IOException {
|
||||
Uri uri = Uri.parse(AccountUtils.constructFullURLForAccount(appContext, account));
|
||||
WebdavClient client = createOwnCloudClient(uri, appContext);
|
||||
AccountManager am = AccountManager.get(appContext);
|
||||
if (am.getUserData(account, AccountAuthenticator.KEY_SUPPORTS_OAUTH2) != null) { // TODO avoid a call to getUserData here
|
||||
AccountManagerFuture<Bundle> future = am.getAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN, null, currentActivity, null, null);
|
||||
Bundle result = future.getResult();
|
||||
String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN);
|
||||
//String accessToken = am.blockingGetAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN, false);
|
||||
if (accessToken == null) throw new AuthenticatorException("WTF!");
|
||||
client.setBearerCredentials(accessToken); // TODO not assume that the access token is a bearer token
|
||||
|
||||
} else {
|
||||
String username = account.name.substring(0, account.name.lastIndexOf('@'));
|
||||
//String password = am.getPassword(account);
|
||||
//String password = am.blockingGetAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE_PASSWORD, false);
|
||||
AccountManagerFuture<Bundle> future = am.getAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE_PASSWORD, null, currentActivity, null, null);
|
||||
Bundle result = future.getResult();
|
||||
String password = result.getString(AccountManager.KEY_AUTHTOKEN);
|
||||
client.setBasicCredentials(username, password);
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a WebdavClient to try a new account before saving it
|
||||
*
|
||||
|
|
|
@ -23,8 +23,7 @@ import com.owncloud.android.network.OwnCloudClientUtils;
|
|||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountsException;
|
||||
import android.accounts.AuthenticatorException;
|
||||
import android.accounts.OperationCanceledException;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
@ -57,6 +56,9 @@ public abstract class RemoteOperation implements Runnable {
|
|||
/** Handler to the thread where mListener methods will be called */
|
||||
private Handler mListenerHandler = null;
|
||||
|
||||
/** Activity */
|
||||
private Activity mCallerActivity;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract method to implement the operation in derived classes.
|
||||
|
@ -119,13 +121,14 @@ public abstract class RemoteOperation implements Runnable {
|
|||
* @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 final Thread execute(Account account, Context context, OnRemoteOperationListener listener, Handler listenerHandler) {
|
||||
public final 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");
|
||||
if (context == null)
|
||||
throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Context");
|
||||
mAccount = account;
|
||||
mContext = context.getApplicationContext();
|
||||
mCallerActivity = callerActivity;
|
||||
mClient = null; // the client instance will be created from mAccount and mContext in the runnerThread to create below
|
||||
|
||||
if (listener == null) {
|
||||
|
@ -207,15 +210,18 @@ public abstract class RemoteOperation implements Runnable {
|
|||
try{
|
||||
if (mClient == null) {
|
||||
if (mAccount != null && mContext != null) {
|
||||
mClient = OwnCloudClientUtils.createOwnCloudClient(mAccount, mContext);
|
||||
if (mCallerActivity != null) {
|
||||
mClient = OwnCloudClientUtils.createOwnCloudClient(mAccount, mContext, mCallerActivity);
|
||||
} else {
|
||||
mClient = OwnCloudClientUtils.createOwnCloudClient(mAccount, mContext);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Trying to run a remote operation asynchronously with no client instance or account");
|
||||
}
|
||||
}
|
||||
result = run(mClient);
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Error while trying to access to " + mAccount.name, e);
|
||||
Log.e(TAG, "Error while trying to access to " + mAccount.name, new AccountsException("I/O exception while trying to authorize the account", e));
|
||||
result = new RemoteOperationResult(e);
|
||||
|
||||
} catch (AccountsException e) {
|
||||
|
@ -223,6 +229,9 @@ public abstract class RemoteOperation implements Runnable {
|
|||
result = new RemoteOperationResult(e);
|
||||
}
|
||||
|
||||
if (result == null)
|
||||
result = run(mClient);
|
||||
|
||||
final RemoteOperationResult resultToSend = result;
|
||||
if (mListenerHandler != null && mListener != null) {
|
||||
mListenerHandler.post(new Runnable() {
|
||||
|
@ -233,6 +242,15 @@ public abstract class RemoteOperation implements Runnable {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current client instance to access the remote server.
|
||||
*
|
||||
* @return Current client instance to access the remote server.
|
||||
*/
|
||||
public final WebdavClient getClient() {
|
||||
return mClient;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -112,6 +112,8 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|||
private boolean mStatusCorrect, mIsSslConn;
|
||||
private RemoteOperationResult mLastSslUntrustedServerResult;
|
||||
|
||||
public static final String PARAM_ACCOUNTNAME = "param_Accountname";
|
||||
|
||||
public static final String PARAM_USERNAME = "param_Username";
|
||||
public static final String PARAM_HOSTNAME = "param_Hostname";
|
||||
|
||||
|
@ -196,6 +198,19 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|||
mStatusText = mStatusIcon = 0;
|
||||
mStatusCorrect = false;
|
||||
mIsSslConn = false;
|
||||
|
||||
String accountName = getIntent().getExtras().getString(PARAM_ACCOUNTNAME);
|
||||
String tokenType = getIntent().getExtras().getString(AccountAuthenticator.KEY_AUTH_TOKEN_TYPE);
|
||||
if (AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN.equals(tokenType)) {
|
||||
CheckBox oAuth2Check = (CheckBox) findViewById(R.id.oauth_onOff_check);
|
||||
oAuth2Check.setChecked(true);
|
||||
changeViewByOAuth2Check(true);
|
||||
}
|
||||
|
||||
if (accountName != null) {
|
||||
((TextView) findViewById(R.id.account_username)).setText(accountName.substring(0, accountName.lastIndexOf('@')));
|
||||
tv.setText(accountName.substring(accountName.lastIndexOf('@') + 1));
|
||||
}
|
||||
}
|
||||
iv.setOnClickListener(this);
|
||||
iv2.setOnClickListener(this);
|
||||
|
|
|
@ -658,7 +658,8 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
|
|||
operation.execute( AccountUtils.getCurrentOwnCloudAccount(FileDisplayActivity.this),
|
||||
FileDisplayActivity.this,
|
||||
FileDisplayActivity.this,
|
||||
mHandler);
|
||||
mHandler,
|
||||
FileDisplayActivity.this);
|
||||
|
||||
dialog.dismiss();
|
||||
|
||||
|
|
|
@ -18,20 +18,9 @@
|
|||
package com.owncloud.android.ui.fragment;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
import org.apache.commons.httpclient.methods.StringRequestEntity;
|
||||
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.utils.URLEncodedUtils;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
|
||||
import org.json.JSONObject;
|
||||
import org.apache.commons.httpclient.Credentials;
|
||||
import org.apache.commons.httpclient.UsernamePasswordCredentials;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
|
@ -66,7 +55,6 @@ import android.widget.TextView;
|
|||
import android.widget.Toast;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockFragment;
|
||||
import com.owncloud.android.AccountUtils;
|
||||
import com.owncloud.android.DisplayUtils;
|
||||
import com.owncloud.android.authenticator.AccountAuthenticator;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
|
@ -76,6 +64,7 @@ import com.owncloud.android.files.services.FileObserverService;
|
|||
import com.owncloud.android.files.services.FileUploader;
|
||||
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
|
||||
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
|
||||
import com.owncloud.android.network.BearerCredentials;
|
||||
import com.owncloud.android.network.OwnCloudClientUtils;
|
||||
import com.owncloud.android.operations.OnRemoteOperationListener;
|
||||
import com.owncloud.android.operations.RemoteOperation;
|
||||
|
@ -90,10 +79,8 @@ import com.owncloud.android.ui.activity.FileDisplayActivity;
|
|||
import com.owncloud.android.ui.activity.TransferServiceGetter;
|
||||
import com.owncloud.android.ui.dialog.EditNameDialog;
|
||||
import com.owncloud.android.ui.dialog.EditNameDialog.EditNameDialogListener;
|
||||
import com.owncloud.android.utils.OwnCloudVersion;
|
||||
|
||||
import com.owncloud.android.R;
|
||||
import eu.alefzero.webdav.WebdavClient;
|
||||
import eu.alefzero.webdav.WebdavUtils;
|
||||
|
||||
/**
|
||||
|
@ -308,7 +295,7 @@ public class FileDetailFragment extends SherlockFragment implements
|
|||
|
||||
} else {
|
||||
mLastRemoteOperation = new SynchronizeFileOperation(mFile, null, mStorageManager, mAccount, true, false, getActivity());
|
||||
mLastRemoteOperation.execute(mAccount, getSherlockActivity(), this, mHandler);
|
||||
mLastRemoteOperation.execute(mAccount, getSherlockActivity(), this, mHandler, getSherlockActivity());
|
||||
|
||||
// update ui
|
||||
boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
|
||||
|
@ -422,7 +409,7 @@ public class FileDetailFragment extends SherlockFragment implements
|
|||
mLastRemoteOperation = new RemoveFileOperation( mFile,
|
||||
true,
|
||||
mStorageManager);
|
||||
mLastRemoteOperation.execute(mAccount, getSherlockActivity(), this, mHandler);
|
||||
mLastRemoteOperation.execute(mAccount, getSherlockActivity(), this, mHandler, getSherlockActivity());
|
||||
|
||||
boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
|
||||
getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
|
||||
|
@ -863,7 +850,7 @@ public class FileDetailFragment extends SherlockFragment implements
|
|||
mAccount,
|
||||
newFilename,
|
||||
new FileDataStorageManager(mAccount, getActivity().getContentResolver()));
|
||||
mLastRemoteOperation.execute(mAccount, getSherlockActivity(), this, mHandler);
|
||||
mLastRemoteOperation.execute(mAccount, getSherlockActivity(), this, mHandler, getSherlockActivity());
|
||||
boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;
|
||||
getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);
|
||||
}
|
||||
|
@ -949,7 +936,19 @@ public class FileDetailFragment extends SherlockFragment implements
|
|||
*/
|
||||
@Override
|
||||
public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
|
||||
if (operation.equals(mLastRemoteOperation)) {
|
||||
if (!result.isSuccess() && result.getCode() == ResultCode.UNAUTHORIZED) {
|
||||
AccountManager am = AccountManager.get(getSherlockActivity());
|
||||
//am.invalidateAuthToken(AccountAuthenticator.ACCOUNT_TYPE, OwnCloudClientUtils.getAuthorizationTokenType(operation.getClient().getCredentials()));
|
||||
Credentials cred = operation.getClient().getCredentials();
|
||||
if (cred instanceof BearerCredentials) {
|
||||
am.invalidateAuthToken(AccountAuthenticator.ACCOUNT_TYPE, ((BearerCredentials)cred).getAccessToken());
|
||||
} else {
|
||||
am.clearPassword(mAccount);
|
||||
}
|
||||
operation.execute(mAccount, getSherlockActivity(), this, mHandler, getSherlockActivity()); // need a new client instance, so avoid retry()
|
||||
// TODO si el usuario no se autoriza de nuevo, esto genera un bucle infinito; o un error en la creación del objecto cliente
|
||||
|
||||
} else {
|
||||
if (operation instanceof RemoveFileOperation) {
|
||||
onRemoveFileOperationFinish((RemoveFileOperation)operation, result);
|
||||
|
||||
|
|
|
@ -316,7 +316,7 @@ public class OCFileListFragment extends FragmentListView implements EditNameDial
|
|||
case R.id.download_file_item: {
|
||||
Account account = AccountUtils.getCurrentOwnCloudAccount(getSherlockActivity());
|
||||
RemoteOperation operation = new SynchronizeFileOperation(mTargetFile, null, mContainerActivity.getStorageManager(), account, true, false, getSherlockActivity());
|
||||
operation.execute(account, getSherlockActivity(), mContainerActivity, mHandler);
|
||||
operation.execute(account, getSherlockActivity(), mContainerActivity, mHandler, getSherlockActivity());
|
||||
getSherlockActivity().showDialog(FileDisplayActivity.DIALOG_SHORT_WAIT);
|
||||
return true;
|
||||
}
|
||||
|
@ -478,7 +478,7 @@ public class OCFileListFragment extends FragmentListView implements EditNameDial
|
|||
AccountUtils.getCurrentOwnCloudAccount(getActivity()),
|
||||
newFilename,
|
||||
mContainerActivity.getStorageManager());
|
||||
operation.execute(AccountUtils.getCurrentOwnCloudAccount(getSherlockActivity()), getSherlockActivity(), mContainerActivity, mHandler);
|
||||
operation.execute(AccountUtils.getCurrentOwnCloudAccount(getSherlockActivity()), getSherlockActivity(), mContainerActivity, mHandler, getSherlockActivity());
|
||||
getActivity().showDialog(FileDisplayActivity.DIALOG_SHORT_WAIT);
|
||||
}
|
||||
}
|
||||
|
@ -491,7 +491,7 @@ public class OCFileListFragment extends FragmentListView implements EditNameDial
|
|||
RemoteOperation operation = new RemoveFileOperation( mTargetFile,
|
||||
true,
|
||||
mContainerActivity.getStorageManager());
|
||||
operation.execute(AccountUtils.getCurrentOwnCloudAccount(getSherlockActivity()), getSherlockActivity(), mContainerActivity, mHandler);
|
||||
operation.execute(AccountUtils.getCurrentOwnCloudAccount(getSherlockActivity()), getSherlockActivity(), mContainerActivity, mHandler, getSherlockActivity());
|
||||
|
||||
getActivity().showDialog(FileDisplayActivity.DIALOG_SHORT_WAIT);
|
||||
}
|
||||
|
|
|
@ -335,4 +335,10 @@ public class WebdavClient extends HttpClient {
|
|||
}
|
||||
return super.executeMethod(hostconfig, method, state);
|
||||
}
|
||||
|
||||
|
||||
public final Credentials getCredentials() {
|
||||
return mCredentials;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue