From: David A. Velasco Date: Tue, 1 Jul 2014 12:21:26 +0000 (+0200) Subject: Merge remote-tracking branch 'origin/develop' into add_cookie_based_session_support X-Git-Tag: oc-android-1.7.0_signed~264^2~1 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/dacc14a882be8b499c00ad2f75b68e10a42dee9e?hp=f773d58d86da535d4d0f451b5d8138338d731350 Merge remote-tracking branch 'origin/develop' into add_cookie_based_session_support --- diff --git a/owncloud-android-library b/owncloud-android-library index f323dda0..3c116514 160000 --- a/owncloud-android-library +++ b/owncloud-android-library @@ -1 +1 @@ -Subproject commit f323dda0445b455af638c7e8e4653c22959adb91 +Subproject commit 3c116514fb33992d050f7051e756b6c2244953b0 diff --git a/res/values/strings.xml b/res/values/strings.xml index 9992b18c..71436a86 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -97,6 +97,7 @@ Download failed, you need to relogin Choose account Synchronization failed + Synchronization failed, you need to relogin Synchronization of %1$s could not be completed Invalid password for %1$s Conflicts found diff --git a/src/com/owncloud/android/MainApp.java b/src/com/owncloud/android/MainApp.java index 85718ff6..08efe342 100644 --- a/src/com/owncloud/android/MainApp.java +++ b/src/com/owncloud/android/MainApp.java @@ -16,22 +16,44 @@ */ package com.owncloud.android; +import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; +import com.owncloud.android.lib.common.OwnCloudClientManagerFactory.Policy; + import android.app.Application; import android.content.Context; /** * Main Application of the project * - * Contains methods to build the "static" strings. These strings were before constants in different classes + * Contains methods to build the "static" strings. These strings were before constants in different + * classes * * @author masensio + * @author David A. Velasco */ public class MainApp extends Application { + + private static final String AUTH_ON = "on"; + + @SuppressWarnings("unused") + private static final String POLICY_SINGLE_SESSION_PER_ACCOUNT = "single session per account"; + @SuppressWarnings("unused") + private static final String POLICY_ALWAYS_NEW_CLIENT = "always new client"; private static Context mContext; - + public void onCreate(){ super.onCreate(); MainApp.mContext = getApplicationContext(); + + boolean isSamlAuth = AUTH_ON.equals(getString(R.string.auth_method_saml_web_sso)); + + if (isSamlAuth) { + OwnCloudClientManagerFactory.setDefaultPolicy(Policy.SINGLE_SESSION_PER_ACCOUNT); + + } else { + OwnCloudClientManagerFactory.setDefaultPolicy(Policy.ALWAYS_NEW_CLIENT); + } + } public static Context getAppContext() { @@ -78,4 +100,5 @@ public class MainApp extends Application { public static String getLogName() { return getAppContext().getResources().getString(R.string.log_name); } + } diff --git a/src/com/owncloud/android/authentication/AuthenticatorActivity.java b/src/com/owncloud/android/authentication/AuthenticatorActivity.java index 32bbcdcc..bc0ab54e 100644 --- a/src/com/owncloud/android/authentication/AuthenticatorActivity.java +++ b/src/com/owncloud/android/authentication/AuthenticatorActivity.java @@ -62,6 +62,9 @@ import com.actionbarsherlock.app.SherlockDialogFragment; import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.authentication.SsoWebViewClient.SsoWebViewClientListener; +import com.owncloud.android.lib.common.OwnCloudAccount; +import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; +import com.owncloud.android.lib.common.OwnCloudCredentialsFactory; import com.owncloud.android.lib.common.accounts.AccountTypeUtils; import com.owncloud.android.lib.common.accounts.AccountUtils.Constants; import com.owncloud.android.operations.DetectAuthenticationMethodOperation.AuthenticationMethod; @@ -723,9 +726,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { Intent getServerInfoIntent = new Intent(); getServerInfoIntent.setAction(OperationsService.ACTION_GET_SERVER_INFO); getServerInfoIntent.putExtra(OperationsService.EXTRA_SERVER_URL, uri); - getServerInfoIntent.putExtra(OperationsService.EXTRA_AUTH_TOKEN_TYPE, mAuthTokenType); if (mOperationsServiceBinder != null) { - //Log_OC.wtf(TAG, "checking server..." ); mWaitingForOpId = mOperationsServiceBinder.newOperation(getServerInfoIntent); } else { Log_OC.wtf(TAG, "Server check tried with OperationService unbound!" ); @@ -828,9 +829,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { * the root folder of the ownCloud server. */ private void checkBasicAuthorization() { - /// get the path to the root folder through WebDAV from the version server - String webdav_path = AccountUtils.getWebdavPath(mServerInfo.mVersion, mAuthTokenType); - /// get basic credentials entered by user String username = mUsernameInput.getText().toString(); String password = mPasswordInput.getText().toString(); @@ -840,26 +838,19 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { IndeterminateProgressDialog.newInstance(R.string.auth_trying_to_login, true); dialog.show(getSupportFragmentManager(), WAIT_DIALOG_TAG); - /// test credentials accessing the root folder - String remotePath =""; - boolean successIfAbsent = false; - boolean followRedirects = true; - startExistenceCheckRemoteOperation(remotePath, this, successIfAbsent, webdav_path, username, password, followRedirects); + /// validate credentials accessing the root folder + accessRootFolderRemoteOperation(username, password); } - private void startExistenceCheckRemoteOperation(String remotePath, Context context, boolean successIfAbsent, String webdav_path, - String username, String password, boolean followRedirects) { + private void accessRootFolderRemoteOperation(String username, String password) { Intent existenceCheckIntent = new Intent(); existenceCheckIntent.setAction(OperationsService.ACTION_EXISTENCE_CHECK); existenceCheckIntent.putExtra(OperationsService.EXTRA_SERVER_URL, mServerInfo.mBaseUrl); - existenceCheckIntent.putExtra(OperationsService.EXTRA_REMOTE_PATH, remotePath); - existenceCheckIntent.putExtra(OperationsService.EXTRA_SUCCESS_IF_ABSENT, successIfAbsent); - existenceCheckIntent.putExtra(OperationsService.EXTRA_WEBDAV_PATH, webdav_path); + existenceCheckIntent.putExtra(OperationsService.EXTRA_REMOTE_PATH, "/"); existenceCheckIntent.putExtra(OperationsService.EXTRA_USERNAME, username); existenceCheckIntent.putExtra(OperationsService.EXTRA_PASSWORD, password); existenceCheckIntent.putExtra(OperationsService.EXTRA_AUTH_TOKEN, mAuthToken); - existenceCheckIntent.putExtra(OperationsService.EXTRA_FOLLOW_REDIRECTS, followRedirects); if (mOperationsServiceBinder != null) { //Log_OC.wtf(TAG, "starting existenceCheckRemoteOperation..." ); @@ -904,14 +895,8 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { IndeterminateProgressDialog.newInstance(R.string.auth_trying_to_login, true); dialog.show(getSupportFragmentManager(), WAIT_DIALOG_TAG); - /// get the path to the root folder through WebDAV from the version server - String webdav_path = AccountUtils.getWebdavPath(mServerInfo.mVersion, mAuthTokenType); - - /// test credentials accessing the root folder - String remotePath =""; - boolean successIfAbsent = false; - boolean followRedirections = false; - startExistenceCheckRemoteOperation(remotePath, this, successIfAbsent, webdav_path, "", "", followRedirections); + /// validate credentials accessing the root folder + accessRootFolderRemoteOperation("", ""); } @@ -959,7 +944,15 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { if (!mUsernameInput.getText().toString().equals(username)) { // fail - not a new account, but an existing one; disallow - result = new RemoteOperationResult(ResultCode.ACCOUNT_NOT_THE_SAME); + result = new RemoteOperationResult(ResultCode.ACCOUNT_NOT_THE_SAME); + /* + OwnCloudClientManagerFactory.getDefaultSingleton().removeClientFor( + new OwnCloudAccount( + Uri.parse(mServerInfo.mBaseUrl), + OwnCloudCredentialsFactory.newSamlSsoCredentials(mAuthToken)) + ); + */ + mAuthToken = ""; updateAuthStatusIconAndText(result); showAuthStatus(); Log_OC.d(TAG, result.getLogMessage()); @@ -1284,8 +1277,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { mWaitingForOpId = Long.MAX_VALUE; dismissDialog(WAIT_DIALOG_TAG); - String webdav_path = AccountUtils.getWebdavPath(mServerInfo.mVersion, mAuthTokenType); - if (result.isSuccess() && webdav_path != null) { + if (result.isSuccess()) { /// be gentle with the user IndeterminateProgressDialog dialog = IndeterminateProgressDialog.newInstance(R.string.auth_trying_to_login, true); @@ -1298,10 +1290,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { //mAuthToken = ((OAuth2GetAccessToken)operation).getResultTokenMap().get(OAuth2Constants.KEY_ACCESS_TOKEN); Log_OC.d(TAG, "Got ACCESS TOKEN: " + mAuthToken); - String remotePath =""; - boolean successIfAbsent = false; - boolean followRedirects = true; - startExistenceCheckRemoteOperation(remotePath, this, successIfAbsent, webdav_path, "", "", followRedirects); + accessRootFolderRemoteOperation("", ""); } else { updateAuthStatusIconAndText(result); @@ -1417,11 +1406,9 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { String username = mUsernameInput.getText().toString().trim(); if (isOAuth) { username = "OAuth_user" + (new java.util.Random(System.currentTimeMillis())).nextLong(); - } - String accountName = username + "@" + uri.getHost(); - if (uri.getPort() >= 0) { - accountName += ":" + uri.getPort(); } + String accountName = com.owncloud.android.lib.common.accounts.AccountUtils. + buildAccountName(uri, username); Account newAccount = new Account(accountName, MainApp.getAccountType()); if (AccountUtils.exists(newAccount, getApplicationContext())) { // fail - not a new account, but an existing one; disallow @@ -1642,7 +1629,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { getUserNameIntent.setAction(OperationsService.ACTION_GET_USER_NAME); getUserNameIntent.putExtra(OperationsService.EXTRA_SERVER_URL, mServerInfo.mBaseUrl); getUserNameIntent.putExtra(OperationsService.EXTRA_COOKIE, sessionCookie); - getUserNameIntent.putExtra(OperationsService.EXTRA_FOLLOW_REDIRECTS, followRedirects); if (mOperationsServiceBinder != null) { //Log_OC.wtf(TAG, "starting getRemoteUserNameOperation..." ); diff --git a/src/com/owncloud/android/authentication/OwnCloudAccount.java b/src/com/owncloud/android/authentication/OwnCloudAccount.java deleted file mode 100644 index 51a9900b..00000000 --- a/src/com/owncloud/android/authentication/OwnCloudAccount.java +++ /dev/null @@ -1,75 +0,0 @@ -/* 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.authentication; - -import android.accounts.Account; -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Account with extra information specific for ownCloud accounts. - * - * TODO integrate in the main app - * - * @author David A. Velasco - */ -public class OwnCloudAccount extends Account { - - private String mAuthTokenType; - - public OwnCloudAccount(String name, String type, String authTokenType) { - super(name, type); - // TODO validate authTokentype as supported - mAuthTokenType = authTokenType; - } - - /** - * Reconstruct from parcel - * - * @param source The source parcel - */ - public OwnCloudAccount(Parcel source) { - super(source); - mAuthTokenType = source.readString(); - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeString(mAuthTokenType); - } - - - public String getAuthTokenType() { - return mAuthTokenType; - } - - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - @Override - public OwnCloudAccount createFromParcel(Parcel source) { - return new OwnCloudAccount(source); - } - - @Override - public OwnCloudAccount [] newArray(int size) { - return new OwnCloudAccount[size]; - } - }; - -} diff --git a/src/com/owncloud/android/files/services/FileDownloader.java b/src/com/owncloud/android/files/services/FileDownloader.java index 80d4a6dc..2e34a8b6 100644 --- a/src/com/owncloud/android/files/services/FileDownloader.java +++ b/src/com/owncloud/android/files/services/FileDownloader.java @@ -34,14 +34,15 @@ import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.lib.common.network.OnDatatransferProgressListener; -import com.owncloud.android.lib.common.OwnCloudClientFactory; +import com.owncloud.android.lib.common.OwnCloudAccount; import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; import com.owncloud.android.notifications.NotificationBuilderWithProgressBar; import com.owncloud.android.notifications.NotificationDelayer; -import com.owncloud.android.operations.DownloadFileOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.resources.files.FileUtils; +import com.owncloud.android.operations.DownloadFileOperation; import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.activity.FileDisplayActivity; import com.owncloud.android.ui.preview.PreviewImageActivity; @@ -347,8 +348,11 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis /// prepare client object to send the request to the ownCloud server if (mDownloadClient == null || !mLastAccount.equals(mCurrentDownload.getAccount())) { mLastAccount = mCurrentDownload.getAccount(); - mStorageManager = new FileDataStorageManager(mLastAccount, getContentResolver()); - mDownloadClient = OwnCloudClientFactory.createOwnCloudClient(mLastAccount, getApplicationContext()); + mStorageManager = + new FileDataStorageManager(mLastAccount, getContentResolver()); + OwnCloudAccount ocAccount = new OwnCloudAccount(mLastAccount, this); + mDownloadClient = OwnCloudClientManagerFactory.getDefaultSingleton(). + getClientFor(ocAccount, this); } /// perform the download @@ -466,9 +470,10 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis int tickerId = (downloadResult.isSuccess()) ? R.string.downloader_download_succeeded_ticker : R.string.downloader_download_failed_ticker; - boolean needsToUpdateCredentials = (downloadResult.getCode() == ResultCode.UNAUTHORIZED || - (downloadResult.isIdPRedirection() - && mDownloadClient.getCredentials() == null)); + boolean needsToUpdateCredentials = ( + downloadResult.getCode() == ResultCode.UNAUTHORIZED || + downloadResult.isIdPRedirection() + ); tickerId = (needsToUpdateCredentials) ? R.string.downloader_download_failed_credentials_error : tickerId; diff --git a/src/com/owncloud/android/files/services/FileUploader.java b/src/com/owncloud/android/files/services/FileUploader.java index e9d8d1b8..7a5f8de5 100644 --- a/src/com/owncloud/android/files/services/FileUploader.java +++ b/src/com/owncloud/android/files/services/FileUploader.java @@ -48,8 +48,9 @@ import com.owncloud.android.lib.resources.files.FileUtils; import com.owncloud.android.lib.resources.status.OwnCloudVersion; import com.owncloud.android.lib.common.accounts.AccountUtils.Constants; import com.owncloud.android.lib.common.network.OnDatatransferProgressListener; -import com.owncloud.android.lib.common.OwnCloudClientFactory; +import com.owncloud.android.lib.common.OwnCloudAccount; import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; import com.owncloud.android.ui.activity.FailedUploadActivity; import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.activity.FileDisplayActivity; @@ -486,8 +487,11 @@ public class FileUploader extends Service implements OnDatatransferProgressListe /// prepare client object to send requests to the ownCloud server if (mUploadClient == null || !mLastAccount.equals(mCurrentUpload.getAccount())) { mLastAccount = mCurrentUpload.getAccount(); - mStorageManager = new FileDataStorageManager(mLastAccount, getContentResolver()); - mUploadClient = OwnCloudClientFactory.createOwnCloudClient(mLastAccount, getApplicationContext()); + mStorageManager = + new FileDataStorageManager(mLastAccount, getContentResolver()); + OwnCloudAccount ocAccount = new OwnCloudAccount(mLastAccount, this); + mUploadClient = OwnCloudClientManagerFactory.getDefaultSingleton(). + getClientFor(ocAccount, this); } /// check the existence of the parent folder for the file to upload @@ -737,9 +741,10 @@ public class FileUploader extends Service implements OnDatatransferProgressListe String content = null; // check credentials error - boolean needsToUpdateCredentials = (uploadResult.getCode() == ResultCode.UNAUTHORIZED || - (uploadResult.isIdPRedirection() && - mUploadClient.getCredentials() == null)); + boolean needsToUpdateCredentials = ( + uploadResult.getCode() == ResultCode.UNAUTHORIZED || + uploadResult.isIdPRedirection() + ); tickerId = (needsToUpdateCredentials) ? R.string.uploader_upload_failed_credentials_error : tickerId; diff --git a/src/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java b/src/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java index b817e724..b90c25e9 100644 --- a/src/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java +++ b/src/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java @@ -64,7 +64,6 @@ public class DetectAuthenticationMethodOperation extends RemoteOperation { } private Context mContext; - private String mWebDavUrl; /** * Constructor @@ -72,9 +71,8 @@ public class DetectAuthenticationMethodOperation extends RemoteOperation { * @param context Android context of the caller. * @param webdavUrl */ - public DetectAuthenticationMethodOperation(Context context, String webdavUrl) { + public DetectAuthenticationMethodOperation(Context context) { mContext = context; - mWebDavUrl = webdavUrl; } @@ -93,15 +91,15 @@ public class DetectAuthenticationMethodOperation extends RemoteOperation { AuthenticationMethod authMethod = AuthenticationMethod.UNKNOWN; RemoteOperation operation = new ExistenceCheckRemoteOperation("", mContext, false); - client.setWebdavUri(Uri.parse(mWebDavUrl)); - client.setBasicCredentials("", ""); + client.clearCredentials(); client.setFollowRedirects(false); // try to access the root folder, following redirections but not SAML SSO redirections result = operation.execute(client); String redirectedLocation = result.getRedirectedLocation(); - while (redirectedLocation != null && redirectedLocation.length() > 0 && !result.isIdPRedirection()) { - client.setWebdavUri(Uri.parse(result.getRedirectedLocation())); + while (redirectedLocation != null && redirectedLocation.length() > 0 && + !result.isIdPRedirection()) { + client.setBaseUri(Uri.parse(result.getRedirectedLocation())); result = operation.execute(client); redirectedLocation = result.getRedirectedLocation(); } diff --git a/src/com/owncloud/android/operations/GetServerInfoOperation.java b/src/com/owncloud/android/operations/GetServerInfoOperation.java index 14f405ea..7d42886c 100644 --- a/src/com/owncloud/android/operations/GetServerInfoOperation.java +++ b/src/com/owncloud/android/operations/GetServerInfoOperation.java @@ -53,7 +53,6 @@ public class GetServerInfoOperation extends RemoteOperation { private static final String TAG = GetServerInfoOperation.class.getSimpleName(); private String mUrl; - private String mAuthTokenType; private Context mContext; private ServerInfo mResultData; @@ -62,14 +61,11 @@ public class GetServerInfoOperation extends RemoteOperation { * Constructor. * * @param url URL to an ownCloud server. - * @param authTokenType Identifies the authorization token supported by the caller; - * TODO ugly dependency, get rid of it. * @param context Android context; needed to check network state * TODO ugly dependency, get rid of it. */ - public GetServerInfoOperation(String url, String authTokenType, Context context) { + public GetServerInfoOperation(String url, Context context) { mUrl = trimWebdavSuffix(url); - mAuthTokenType = authTokenType; mContext = context; mResultData = new ServerInfo(); @@ -87,9 +83,9 @@ public class GetServerInfoOperation extends RemoteOperation { protected RemoteOperationResult run(OwnCloudClient client) { // first: check the status of the server (including its version) - GetRemoteStatusOperation getStatus = new GetRemoteStatusOperation(mUrl, mContext); + GetRemoteStatusOperation getStatus = new GetRemoteStatusOperation(mContext); RemoteOperationResult result = getStatus.execute(client); - + if (result.isSuccess()) { // second: get authentication method required by the server mResultData.mVersion = (OwnCloudVersion)(result.getData().get(0)); @@ -114,10 +110,8 @@ public class GetServerInfoOperation extends RemoteOperation { private RemoteOperationResult detectAuthorizationMethod(OwnCloudClient client) { Log_OC.d(TAG, "Trying empty authorization to detect authentication method"); - String webdav_path = AccountUtils.getWebdavPath(mResultData.mVersion, mAuthTokenType); - String webdav_url = mResultData.mBaseUrl + webdav_path; DetectAuthenticationMethodOperation operation = - new DetectAuthenticationMethodOperation(mContext, webdav_url); + new DetectAuthenticationMethodOperation(mContext); return operation.execute(client); } diff --git a/src/com/owncloud/android/operations/common/SyncOperation.java b/src/com/owncloud/android/operations/common/SyncOperation.java index e16530d8..8c5678b1 100644 --- a/src/com/owncloud/android/operations/common/SyncOperation.java +++ b/src/com/owncloud/android/operations/common/SyncOperation.java @@ -23,7 +23,6 @@ import com.owncloud.android.lib.common.operations.OnRemoteOperationListener; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import android.app.Activity; import android.content.Context; import android.os.Handler; @@ -97,6 +96,7 @@ public abstract class SyncOperation extends RemoteOperation { * @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(FileDataStorageManager storageManager, Context context, OnRemoteOperationListener listener, Handler listenerHandler, Activity callerActivity) { if (storageManager == null) { throw new IllegalArgumentException("Trying to execute a sync operation with a NULL storage manager"); @@ -107,6 +107,7 @@ public abstract class SyncOperation extends RemoteOperation { mStorageManager = storageManager; return super.execute(storageManager.getAccount(), context, listener, listenerHandler, callerActivity); } + */ /** diff --git a/src/com/owncloud/android/services/OperationsService.java b/src/com/owncloud/android/services/OperationsService.java index ce80b57e..2522749a 100644 --- a/src/com/owncloud/android/services/OperationsService.java +++ b/src/com/owncloud/android/services/OperationsService.java @@ -23,10 +23,15 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentMap; +import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.datamodel.FileDataStorageManager; -import com.owncloud.android.lib.common.OwnCloudClientFactory; +import com.owncloud.android.lib.common.OwnCloudAccount; import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; +import com.owncloud.android.lib.common.OwnCloudCredentials; +import com.owncloud.android.lib.common.OwnCloudCredentialsFactory; +import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; import com.owncloud.android.lib.common.operations.OnRemoteOperationListener; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; @@ -46,6 +51,8 @@ import com.owncloud.android.utils.Log_OC; import android.accounts.Account; import android.accounts.AccountsException; +import android.accounts.AuthenticatorException; +import android.accounts.OperationCanceledException; import android.app.Service; import android.content.Intent; import android.net.Uri; @@ -64,7 +71,6 @@ public class OperationsService extends Service { public static final String EXTRA_ACCOUNT = "ACCOUNT"; public static final String EXTRA_SERVER_URL = "SERVER_URL"; - public static final String EXTRA_AUTH_TOKEN_TYPE = "AUTH_TOKEN_TYPE"; public static final String EXTRA_OAUTH2_QUERY_PARAMETERS = "OAUTH2_QUERY_PARAMETERS"; public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH"; public static final String EXTRA_SEND_INTENT = "SEND_INTENT"; @@ -75,12 +81,10 @@ public class OperationsService extends Service { public static final String EXTRA_RESULT = "RESULT"; // TODO review if ALL OF THEM are necessary - public static final String EXTRA_WEBDAV_PATH = "WEBDAV_PATH"; public static final String EXTRA_SUCCESS_IF_ABSENT = "SUCCESS_IF_ABSENT"; public static final String EXTRA_USERNAME = "USERNAME"; public static final String EXTRA_PASSWORD = "PASSWORD"; public static final String EXTRA_AUTH_TOKEN = "AUTH_TOKEN"; - public static final String EXTRA_FOLLOW_REDIRECTS = "FOLLOW_REDIRECTS"; public static final String EXTRA_COOKIE = "COOKIE"; public static final String ACTION_CREATE_SHARE = "CREATE_SHARE"; @@ -107,22 +111,18 @@ public class OperationsService extends Service { private static class Target { public Uri mServerUrl = null; public Account mAccount = null; - public String mWebDavUrl = null; public String mUsername = null; public String mPassword = null; public String mAuthToken = null; - public boolean mFollowRedirects = true; public String mCookie = null; - public Target(Account account, Uri serverUrl, String webdavUrl, String username, String password, String authToken, - boolean followRedirects, String cookie) { + public Target(Account account, Uri serverUrl, String username, String password, String authToken, + String cookie) { mAccount = account; mServerUrl = serverUrl; - mWebDavUrl = webdavUrl; mUsername = username; mPassword = password; mAuthToken = authToken; - mFollowRedirects = followRedirects; mCookie = cookie; } } @@ -172,8 +172,25 @@ public class OperationsService extends Service { @Override public void onDestroy() { //Log_OC.wtf(TAG, "onDestroy init" ); + // Saving cookies + try { + OwnCloudClientManagerFactory.getDefaultSingleton(). + saveAllClients(this, MainApp.getAccountType()); + + // TODO - get rid of these exceptions + } catch (AccountNotFoundException e) { + e.printStackTrace(); + } catch (AuthenticatorException e) { + e.printStackTrace(); + } catch (OperationCanceledException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + //Log_OC.wtf(TAG, "Clear mUndispatchedFinisiedOperations" ); mUndispatchedFinishedOperations.clear(); + //Log_OC.wtf(TAG, "onDestroy end" ); super.onDestroy(); } @@ -281,21 +298,16 @@ public class OperationsService extends Service { } else { Account account = operationIntent.getParcelableExtra(EXTRA_ACCOUNT); String serverUrl = operationIntent.getStringExtra(EXTRA_SERVER_URL); - String webDavPath = operationIntent.getStringExtra(EXTRA_WEBDAV_PATH); - String webDavUrl = serverUrl + webDavPath; String username = operationIntent.getStringExtra(EXTRA_USERNAME); String password = operationIntent.getStringExtra(EXTRA_PASSWORD); String authToken = operationIntent.getStringExtra(EXTRA_AUTH_TOKEN); - boolean followRedirects = operationIntent.getBooleanExtra(EXTRA_FOLLOW_REDIRECTS, true); String cookie = operationIntent.getStringExtra(EXTRA_COOKIE); target = new Target( account, (serverUrl == null) ? null : Uri.parse(serverUrl), - ((webDavPath == null) || (serverUrl == null)) ? null : webDavUrl, username, password, authToken, - followRedirects, cookie ); @@ -318,10 +330,7 @@ public class OperationsService extends Service { } else if (action.equals(ACTION_GET_SERVER_INFO)) { // check OC server and get basic information from it - String authTokenType = - operationIntent.getStringExtra(EXTRA_AUTH_TOKEN_TYPE); - operation = new GetServerInfoOperation( - serverUrl, authTokenType, OperationsService.this); + operation = new GetServerInfoOperation(serverUrl, OperationsService.this); } else if (action.equals(ACTION_OAUTH2_GET_ACCESS_TOKEN)) { /// GET ACCESS TOKEN to the OAuth server @@ -336,7 +345,7 @@ public class OperationsService extends Service { } else if (action.equals(ACTION_EXISTENCE_CHECK)) { // Existence Check String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH); - boolean successIfAbsent = operationIntent.getBooleanExtra(EXTRA_SUCCESS_IF_ABSENT, true); + boolean successIfAbsent = operationIntent.getBooleanExtra(EXTRA_SUCCESS_IF_ABSENT, false); operation = new ExistenceCheckRemoteOperation(remotePath, OperationsService.this, successIfAbsent); } else if (action.equals(ACTION_GET_USER_NAME)) { @@ -453,21 +462,35 @@ public class OperationsService extends Service { if (mLastTarget == null || !mLastTarget.equals(next.first)) { mLastTarget = next.first; if (mLastTarget.mAccount != null) { - mOwnCloudClient = OwnCloudClientFactory.createOwnCloudClient(mLastTarget.mAccount, getApplicationContext()); - mStorageManager = new FileDataStorageManager(mLastTarget.mAccount, getContentResolver()); + OwnCloudAccount ocAccount = new OwnCloudAccount(mLastTarget.mAccount, this); + mOwnCloudClient = OwnCloudClientManagerFactory.getDefaultSingleton(). + getClientFor(ocAccount, this); + mStorageManager = + new FileDataStorageManager( + mLastTarget.mAccount, + getContentResolver()); } else { - mOwnCloudClient = OwnCloudClientFactory.createOwnCloudClient(mLastTarget.mServerUrl, getApplicationContext(), - mLastTarget.mFollowRedirects); // this is not good enough - if (mLastTarget.mWebDavUrl != null) { - mOwnCloudClient.setWebdavUri(Uri.parse(mLastTarget.mWebDavUrl)); - } - if (mLastTarget.mUsername != null && mLastTarget.mPassword != null) { - mOwnCloudClient.setBasicCredentials(mLastTarget.mUsername, mLastTarget.mPassword); - } else if (mLastTarget.mAuthToken != null) { - mOwnCloudClient.setBearerCredentials(mLastTarget.mAuthToken); - } else if (mLastTarget.mCookie != null) { - mOwnCloudClient.setSsoSessionCookie(mLastTarget.mCookie); + OwnCloudCredentials credentials = null; + if (mLastTarget.mUsername != null && + mLastTarget.mUsername.length() > 0) { + credentials = OwnCloudCredentialsFactory.newBasicCredentials( + mLastTarget.mUsername, + mLastTarget.mPassword); // basic + + } else if (mLastTarget.mAuthToken != null && + mLastTarget.mAuthToken.length() > 0) { + credentials = OwnCloudCredentialsFactory.newBearerCredentials( + mLastTarget.mAuthToken); // bearer token + + } else if (mLastTarget.mCookie != null && + mLastTarget.mCookie.length() > 0) { + credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials( + mLastTarget.mCookie); // SAML SSO } + OwnCloudAccount ocAccount = new OwnCloudAccount( + mLastTarget.mServerUrl, credentials); + mOwnCloudClient = OwnCloudClientManagerFactory.getDefaultSingleton(). + getClientFor(ocAccount, this); mStorageManager = null; } } diff --git a/src/com/owncloud/android/syncadapter/AbstractOwnCloudSyncAdapter.java b/src/com/owncloud/android/syncadapter/AbstractOwnCloudSyncAdapter.java index a9defc0b..28cfa54c 100644 --- a/src/com/owncloud/android/syncadapter/AbstractOwnCloudSyncAdapter.java +++ b/src/com/owncloud/android/syncadapter/AbstractOwnCloudSyncAdapter.java @@ -27,9 +27,9 @@ import org.apache.http.client.ClientProtocolException; import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.lib.common.accounts.AccountUtils; import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; -import com.owncloud.android.lib.common.OwnCloudClientFactory; +import com.owncloud.android.lib.common.OwnCloudAccount; import com.owncloud.android.lib.common.OwnCloudClient; - +import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; import android.accounts.Account; import android.accounts.AccountManager; @@ -102,7 +102,9 @@ public abstract class AbstractOwnCloudSyncAdapter extends protected void initClientForCurrentAccount() throws OperationCanceledException, AuthenticatorException, IOException, AccountNotFoundException { AccountUtils.constructFullURLForAccount(getContext(), account); - mClient = OwnCloudClientFactory.createOwnCloudClient(account, getContext()); + OwnCloudAccount ocAccount = new OwnCloudAccount(account, getContext()); + mClient = OwnCloudClientManagerFactory.getDefaultSingleton(). + getClientFor(ocAccount, getContext()); } protected OwnCloudClient getClient() { diff --git a/src/com/owncloud/android/syncadapter/FileSyncAdapter.java b/src/com/owncloud/android/syncadapter/FileSyncAdapter.java index 407ce1a2..2ac89835 100644 --- a/src/com/owncloud/android/syncadapter/FileSyncAdapter.java +++ b/src/com/owncloud/android/syncadapter/FileSyncAdapter.java @@ -292,10 +292,9 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { } else { // in failures, the statistics for the global result are updated - if (result.getCode() == RemoteOperationResult.ResultCode.UNAUTHORIZED || - ( result.isIdPRedirection() && - getClient().getCredentials() == null )) { - //MainApp.getAuthTokenTypeSamlSessionCookie().equals(getClient().getAuthTokenType()))) { + if ( result.getCode() == RemoteOperationResult.ResultCode.UNAUTHORIZED || + result.isIdPRedirection() + ) { mSyncResult.stats.numAuthExceptions++; } else if (result.getException() instanceof DavException) { @@ -383,16 +382,12 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { */ private void notifyFailedSynchronization() { NotificationCompat.Builder notificationBuilder = createNotificationBuilder(); - notificationBuilder.setTicker(i18n(R.string.sync_fail_ticker)); - boolean needsToUpdateCredentials = (mLastFailedResult != null && - ( mLastFailedResult.getCode() == ResultCode.UNAUTHORIZED || - ( mLastFailedResult.isIdPRedirection() && - getClient().getCredentials() == null ) - //MainApp.getAuthTokenTypeSamlSessionCookie().equals(getClient().getAuthTokenType())) - ) - ); - // TODO put something smart in the contentIntent below for all the possible errors - notificationBuilder.setContentTitle(i18n(R.string.sync_fail_ticker)); + boolean needsToUpdateCredentials = ( + mLastFailedResult != null && ( + mLastFailedResult.getCode() == ResultCode.UNAUTHORIZED || + mLastFailedResult.isIdPRedirection() + ) + ); if (needsToUpdateCredentials) { // let the user update credentials with one click Intent updateAccountCredentials = new Intent(getContext(), AuthenticatorActivity.class); @@ -402,12 +397,16 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND); notificationBuilder + .setTicker(i18n(R.string.sync_fail_ticker_unauthorized)) + .setContentTitle(i18n(R.string.sync_fail_ticker_unauthorized)) .setContentIntent(PendingIntent.getActivity( getContext(), (int)System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT )) .setContentText(i18n(R.string.sync_fail_content_unauthorized, getAccount().name)); } else { notificationBuilder + .setTicker(i18n(R.string.sync_fail_ticker)) + .setContentTitle(i18n(R.string.sync_fail_ticker)) .setContentText(i18n(R.string.sync_fail_content, getAccount().name)); } diff --git a/src/com/owncloud/android/ui/activity/FileActivity.java b/src/com/owncloud/android/ui/activity/FileActivity.java index 6b8fa43d..fced61b4 100644 --- a/src/com/owncloud/android/ui/activity/FileActivity.java +++ b/src/com/owncloud/android/ui/activity/FileActivity.java @@ -195,6 +195,7 @@ implements OnRemoteOperationListener, ComponentsGetter { @Override protected void onPause() { + if (mOperationsServiceBinder != null) { mOperationsServiceBinder.removeOperationListener(this); } @@ -464,7 +465,7 @@ implements OnRemoteOperationListener, ComponentsGetter { } } - private void requestCredentialsUpdate() { + protected void requestCredentialsUpdate() { Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class); updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, getAccount()); updateAccountCredentials.putExtra( diff --git a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java index f85a50a3..cb771309 100644 --- a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java @@ -19,8 +19,12 @@ package com.owncloud.android.ui.activity; import java.io.File; +import java.io.IOException; import android.accounts.Account; +import android.accounts.AccountManager; +import android.accounts.AuthenticatorException; +import android.accounts.OperationCanceledException; import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; @@ -68,6 +72,11 @@ import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; import com.owncloud.android.operations.CreateFolderOperation; +import com.owncloud.android.lib.common.OwnCloudAccount; +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; +import com.owncloud.android.lib.common.OwnCloudCredentials; +import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; import com.owncloud.android.lib.common.network.CertificateCombinedException; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; @@ -918,10 +927,54 @@ FileFragment.ContainerActivity, OnNavigationListener, OnSslUntrustedCertListener mSyncInProgress = (!FileSyncAdapter.EVENT_FULL_SYNC_END.equals(event) && !SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED.equals(event)); + if (SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED. + equals(event) && + /// TODO refactor and make common + synchResult != null && !synchResult.isSuccess() && + (synchResult.getCode() == ResultCode.UNAUTHORIZED || + synchResult.isIdPRedirection() || + (synchResult.isException() && synchResult.getException() + instanceof AuthenticatorException))) { + + OwnCloudClient client = null; + try { + OwnCloudAccount ocAccount = + new OwnCloudAccount(getAccount(), context); + client = (OwnCloudClientManagerFactory.getDefaultSingleton(). + removeClientFor(ocAccount)); + // TODO get rid of these exceptions + } catch (AccountNotFoundException e) { + e.printStackTrace(); + } catch (AuthenticatorException e) { + e.printStackTrace(); + } catch (OperationCanceledException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + if (client != null) { + OwnCloudCredentials cred = client.getCredentials(); + if (cred != null) { + AccountManager am = AccountManager.get(context); + if (cred.authTokenExpires()) { + am.invalidateAuthToken( + getAccount().type, + cred.getAuthToken() + ); + } else { + am.clearPassword(getAccount()); + } + } + } + + requestCredentialsUpdate(); + } - removeStickyBroadcast(intent); - Log_OC.d(TAG, "Setting progress visibility to " + mSyncInProgress); - setSupportProgressBarIndeterminateVisibility(mSyncInProgress /*|| mRefreshSharesInProgress*/); + } + removeStickyBroadcast(intent); + Log_OC.d(TAG, "Setting progress visibility to " + mSyncInProgress); + setSupportProgressBarIndeterminateVisibility(mSyncInProgress /*|| mRefreshSharesInProgress*/); } @@ -1478,7 +1531,7 @@ FileFragment.ContainerActivity, OnNavigationListener, OnSslUntrustedCertListener getAccount(), getApplicationContext() ); - synchFolderOp.execute(getAccount(), this, null, null, this); + synchFolderOp.execute(getAccount(), this, null, null); setSupportProgressBarIndeterminateVisibility(true); } diff --git a/src/com/owncloud/android/ui/activity/Uploader.java b/src/com/owncloud/android/ui/activity/Uploader.java index 07e6e959..16b32678 100644 --- a/src/com/owncloud/android/ui/activity/Uploader.java +++ b/src/com/owncloud/android/ui/activity/Uploader.java @@ -329,19 +329,10 @@ public class Uploader extends ListActivity implements OnItemClickListener, andro public void uploadFiles() { try { - //OwnCloudClient webdav = OwnCloudClientUtils.createOwnCloudClient(mAccount, getApplicationContext()); ArrayList local = new ArrayList(); ArrayList remote = new ArrayList(); - /* TODO - mCreateDir can never be true at this moment; we will replace wdc.createDirectory by CreateFolderOperation when that is fixed - OwnCloudClient wdc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getApplicationContext()); - // create last directory in path if necessary - if (mCreateDir) { - wdc.createDirectory(mUploadPath); - } - */ - // this checks the mimeType for (Parcelable mStream : mStreamsToUpload) {