X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/281212045672b8439f09e50896d90a1f5c7524f1..08aa08ce603e65a51f0dea6976b4b8d3a1f5f3a2:/src/com/owncloud/android/authentication/AuthenticatorActivity.java diff --git a/src/com/owncloud/android/authentication/AuthenticatorActivity.java b/src/com/owncloud/android/authentication/AuthenticatorActivity.java index cf768833..d9e1bea5 100644 --- a/src/com/owncloud/android/authentication/AuthenticatorActivity.java +++ b/src/com/owncloud/android/authentication/AuthenticatorActivity.java @@ -68,13 +68,12 @@ import com.owncloud.android.lib.common.accounts.AccountTypeUtils; import com.owncloud.android.lib.common.accounts.AccountUtils.Constants; import com.owncloud.android.lib.common.OwnCloudClientFactory; import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.operations.DetectAuthenticationMethodOperation; import com.owncloud.android.operations.DetectAuthenticationMethodOperation.AuthenticationMethod; +import com.owncloud.android.operations.GetServerInfoOperation; import com.owncloud.android.operations.OAuth2GetAccessToken; import com.owncloud.android.lib.common.network.CertificateCombinedException; import com.owncloud.android.lib.common.operations.OnRemoteOperationListener; -import com.owncloud.android.lib.resources.status.GetRemoteStatusOperation; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; @@ -124,6 +123,9 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { private static final String KEY_AUTH_STATUS_ICON = "AUTH_STATUS_ICON"; private static final String KEY_REFRESH_BUTTON_ENABLED = "KEY_REFRESH_BUTTON_ENABLED"; //private static final String KEY_IS_SHARED_SUPPORTED = "KEY_IS_SHARE_SUPPORTED"; + private static final String KEY_SERVER_AUTH_METHOD = "KEY_SERVER_AUTH_METHOD"; + private static final String KEY_DETECT_AUTH_OP_ID = "KEY_DETECT_AUTH_OP_ID"; + private static final String AUTH_ON = "on"; private static final String AUTH_OFF = "off"; @@ -138,21 +140,22 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { private static final String TAG_SAML_DIALOG = "samlWebViewDialog"; - private String mHostBaseUrl; - private OwnCloudVersion mDiscoveredVersion; + private String mHostBaseUrl; // TODO remove + private OwnCloudVersion mDiscoveredVersion; // TODO remove private String mAuthMessageText; private int mAuthMessageVisibility, mServerStatusText, mServerStatusIcon; private boolean mServerIsChecked, mServerIsValid, mIsSslConn; + private AuthenticationMethod mServerAuthMethod = AuthenticationMethod.UNKNOWN; + private int mGetServerInfoOpId = -1; + private int mAuthStatusText, mAuthStatusIcon; private TextView mAuthStatusLayout; - private ServiceConnection mOperationsConnection = null; - private OperationsServiceBinder mOperationsBinder = null; - private final Handler mHandler = new Handler(); private Thread mOperationThread; - private GetRemoteStatusOperation mOcServerChkOperation; + //private GetRemoteStatusOperation mOcServerChkOperation; + private GetServerInfoOperation mServerInfoOperation; private ExistenceCheckRemoteOperation mAuthCheckOperation; private Uri mNewCapturedUriFromOAuth2Redirection; @@ -192,6 +195,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { private OperationsServiceBinder mOperationsServiceBinder = null; + private GetServerInfoOperation.ServerInfo mServerInfo; /** * {@inheritDoc} @@ -204,31 +208,17 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { getWindow().requestFeature(Window.FEATURE_NO_TITLE); // bind to Operations Service - mOperationsConnection = new ServiceConnection() { - - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - Log_OC.d(TAG, "Operations service connected"); - mOperationsBinder = (OperationsServiceBinder) service; - } - - @Override - public void onServiceDisconnected(ComponentName name) { - Log_OC.d(TAG, "Operations service crashed"); - mOperationsBinder = null; - } - - }; + mOperationsServiceConnection = new OperationsServiceConnection(); if (!bindService(new Intent(this, OperationsService.class), - mOperationsConnection, - Context.BIND_AUTO_CREATE)) { + mOperationsServiceConnection, + Context.BIND_AUTO_CREATE)) { Toast.makeText(this, R.string.error_cant_bind_to_operations_service, Toast.LENGTH_LONG) .show(); finish(); } - + /// set view and get references to view elements setContentView(R.layout.account_setup); mAuthMessage = (TextView) findViewById(R.id.auth_message); @@ -347,6 +337,10 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { refreshButtonEnabled = savedInstanceState.getBoolean(KEY_REFRESH_BUTTON_ENABLED); + mServerAuthMethod = AuthenticationMethod.valueOf( + savedInstanceState.getString(KEY_SERVER_AUTH_METHOD)); + mGetServerInfoOpId = savedInstanceState.getInt(KEY_DETECT_AUTH_OP_ID); + } if (mAuthMessageVisibility== View.VISIBLE) { @@ -368,8 +362,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { mOAuth2Check.setVisibility(View.GONE); } - //if (mServerIsChecked && !mServerIsValid && mRefreshButtonEnabled) showRefreshButton(); - if (mServerIsChecked && !mServerIsValid && refreshButtonEnabled) showRefreshButton(); + showRefreshButton(mServerIsChecked && !mServerIsValid && refreshButtonEnabled); mOkButton.setEnabled(mServerIsValid); // state not automatically recovered in configuration changes if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(mAuthTokenType) || @@ -433,8 +426,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { } }); - mOperationsServiceConnection = new OperationsServiceConnection(); - bindService(new Intent(this, OperationsService.class), mOperationsServiceConnection, Context.BIND_AUTO_CREATE); } @@ -487,6 +478,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { */ @Override protected void onSaveInstanceState(Bundle outState) { + //Log.wtf(TAG, "onSaveInstanceState init" ); super.onSaveInstanceState(outState); /// connection state and info @@ -496,7 +488,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { outState.putInt(KEY_SERVER_STATUS_ICON, mServerStatusIcon); outState.putBoolean(KEY_SERVER_VALID, mServerIsValid); outState.putBoolean(KEY_SERVER_CHECKED, mServerIsChecked); - outState.putBoolean(KEY_SERVER_CHECK_IN_PROGRESS, (!mServerIsValid && mOcServerChkOperation != null)); + outState.putBoolean(KEY_SERVER_CHECK_IN_PROGRESS, (!mServerIsValid && mServerInfoOperation != null)); outState.putBoolean(KEY_IS_SSL_CONN, mIsSslConn); outState.putBoolean(KEY_PASSWORD_VISIBLE, isPasswordVisible()); outState.putInt(KEY_AUTH_STATUS_ICON, mAuthStatusIcon); @@ -517,7 +509,10 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { // refresh button enabled outState.putBoolean(KEY_REFRESH_BUTTON_ENABLED, (mRefreshButton.getVisibility() == View.VISIBLE)); - + + outState.putString(KEY_SERVER_AUTH_METHOD, mServerAuthMethod.name()); + outState.putInt(KEY_DETECT_AUTH_OP_ID, mGetServerInfoOpId); + //Log.wtf(TAG, "onSaveInstanceState end" ); } @@ -537,13 +532,16 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { } } + /** * The redirection triggered by the OAuth authentication server as response to the GET AUTHORIZATION, and * deferred in {@link #onNewIntent(Intent)}, is processed here. */ @Override protected void onResume() { + //Log.wtf(TAG, "onResume init" ); super.onResume(); + if (mAction == ACTION_UPDATE_TOKEN && mJustCreated && getIntent().getBooleanExtra(EXTRA_ENFORCED_UPDATE, false)) { if (AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType()).equals(mAuthTokenType)) { //Toast.makeText(this, R.string.auth_expired_oauth_token_toast, Toast.LENGTH_LONG).show(); @@ -560,17 +558,33 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { if (mNewCapturedUriFromOAuth2Redirection != null) { getOAuth2AccessTokenFromCapturedRedirection(); } - + mJustCreated = false; + if (mOperationsServiceBinder != null) { + doOnResumeAndBound(); + } + + //Log.wtf(TAG, "onResume end" ); } + + @Override + protected void onPause() { + //Log.wtf(TAG, "onPause init" ); + if (mOperationsServiceBinder != null) { + //Log.wtf(TAG, "unregistering to listen for operation callbacks" ); + mOperationsServiceBinder.removeOperationListener(this); + } + super.onPause(); + //Log.wtf(TAG, "onPause end" ); + } @Override protected void onDestroy() { - if (mOperationsConnection != null) { - unbindService(mOperationsConnection); - mOperationsBinder = null; + if (mOperationsServiceConnection != null) { + unbindService(mOperationsServiceConnection); + mOperationsServiceBinder = null; } super.onDestroy(); } @@ -609,7 +623,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { onUrlInputFocusLost((TextView) view); } else { - hideRefreshButton(); + showRefreshButton(false); } } else if (view.getId() == R.id.account_password) { @@ -634,32 +648,45 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { checkOcServer(); } else { mOkButton.setEnabled(mServerIsValid); - if (!mServerIsValid) { - showRefreshButton(); - } + showRefreshButton(!mServerIsValid); } } private void checkOcServer() { - String uri = trimUrlWebdav(mHostUrlInput.getText().toString().trim()); + String uri = mHostUrlInput.getText().toString().trim(); if (!mHostUrlInputEnabled){ - uri = getString(R.string.server_url); + uri = getString(R.string.server_url).trim(); } mServerIsValid = false; mServerIsChecked = false; mOkButton.setEnabled(false); mDiscoveredVersion = null; - hideRefreshButton(); + mServerAuthMethod = AuthenticationMethod.UNKNOWN; + showRefreshButton(false); + if (uri.length() != 0) { mServerStatusText = R.string.auth_testing_connection; mServerStatusIcon = R.drawable.progress_small; showServerStatus(); - mOcServerChkOperation = new GetRemoteStatusOperation(uri, this); + + /* + mServerInfoOperation = new GetServerInfoOperation(uri, mAuthTokenType, this); OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient(Uri.parse(uri), this, true); - mOperationThread = mOcServerChkOperation.execute(client, this, mHandler); + mServerInfoOperation.execute(client, this, mHandler); + */ + + 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.wtf(TAG, "checking server..." ); + mGetServerInfoOpId = mOperationsServiceBinder.newOperation(getServerInfoIntent); + } + } else { mServerStatusText = 0; mServerStatusIcon = 0; @@ -847,8 +874,11 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { @Override public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) { - if (operation instanceof GetRemoteStatusOperation) { - onOcServerCheckFinish((GetRemoteStatusOperation) operation, result); + if (operation instanceof GetServerInfoOperation) { + if (operation.hashCode() == mGetServerInfoOpId) { + onGetServerInfoFinish(result); + } // else nothing ; only the last check operation is considered; + // multiple can be started if the user amends a URL quickly } else if (operation instanceof OAuth2GetAccessToken) { onGetOAuthAccessTokenFinish((OAuth2GetAccessToken)operation, result); @@ -863,42 +893,10 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { } else if (operation instanceof GetRemoteUserNameOperation) { onGetUserNameFinish((GetRemoteUserNameOperation) operation, result); - } else if (operation instanceof DetectAuthenticationMethodOperation) { - onDetectAutheticationFinish((DetectAuthenticationMethodOperation) operation, result); } } - private void onDetectAutheticationFinish(DetectAuthenticationMethodOperation operation, RemoteOperationResult result) { - // Read authentication method - if (result.getData().size() > 0) { - AuthenticationMethod authMethod = (AuthenticationMethod) result.getData().get(0); - String basic = AccountTypeUtils.getAuthTokenTypePass(MainApp.getAccountType()); - String oAuth = AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType()); - String saml = AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()); - - if ( ( mAuthTokenType.equals(basic) && !authMethod.equals(AuthenticationMethod.BASIC_HTTP_AUTH) ) || - ( mAuthTokenType.equals(oAuth) && !authMethod.equals(AuthenticationMethod.BEARER_TOKEN) ) || - ( mAuthTokenType.equals(saml) && !authMethod.equals(AuthenticationMethod.SAML_WEB_SSO) ) ) { - - mOkButton.setEnabled(false); - mServerIsValid = false; - //show an alert message ( Server Status ) - updateServerStatusIconNoRegularAuth(); - showServerStatus(); - - } else { - mOkButton.setEnabled(true); - - // Show server status - showServerStatus(); - } - - } - } - - - private void onGetUserNameFinish(GetRemoteUserNameOperation operation, RemoteOperationResult result) { if (result.isSuccess()) { @@ -967,63 +965,68 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { * @param operation Server check performed. * @param result Result of the check. */ - private void onOcServerCheckFinish(GetRemoteStatusOperation operation, RemoteOperationResult result) { - if (operation.equals(mOcServerChkOperation)) { - /// save result state - mServerIsChecked = true; - mServerIsValid = result.isSuccess(); - mIsSslConn = (result.getCode() == ResultCode.OK_SSL); - mOcServerChkOperation = null; - - - /// retrieve discovered version and normalize server URL - mDiscoveredVersion = operation.getDiscoveredVersion(); - mHostBaseUrl = normalizeUrl(mHostUrlInput.getText().toString()); + private void onGetServerInfoFinish(RemoteOperationResult result) { + /// update activity state + mServerIsChecked = true; + mIsSslConn = (result.getCode() == ResultCode.OK_SSL); + mServerInfoOperation = null; + mGetServerInfoOpId = -1; + + // update server status, but don't show it yet + updateServerStatusIconAndText(result); - // Refresh server status, but don't show it - updateServerStatusIconAndText(result); + if (result.isSuccess()) { + /// SUCCESS means: + // 1. connection succeeded, and we know if it's SSL or not + // 2. server is installed + // 3. we got the server version + // 4. we got the authentication method required by the server + mServerInfo = (GetServerInfoOperation.ServerInfo) (result.getData().get(0)); + mDiscoveredVersion = mServerInfo.mVersion; + mHostBaseUrl = mServerInfo.mBaseUrl; + mServerAuthMethod = mServerInfo.mAuthMethod; + + if (!authSupported(mServerAuthMethod)) { + + updateServerStatusIconNoRegularAuth(); // overrides updateServerStatusIconAndText() + mServerIsValid = false; - /// update status icon and text - if (mServerIsValid) { - hideRefreshButton(); - // Try to create an account with user and pass "", to know if it is a regular server - // Update connect button in the answer of this method - detectAuthorizationMethod(); } else { - showRefreshButton(); - // Show server status - showServerStatus(); - } - - /// very special case (TODO: move to a common place for all the remote operations) - if (result.getCode() == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) { - showUntrustedCertDialog(result); + mServerIsValid = true; } + + } else { + mServerIsValid = false; + } - - } // else nothing ; only the last check operation is considered; - // multiple can be triggered if the user amends a URL before a previous check can be triggered + // refresh UI + showRefreshButton(!mServerIsValid); + showServerStatus(); + mOkButton.setEnabled(mServerIsValid); + + /// very special case (TODO: move to a common place for all the remote operations) + if (result.getCode() == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) { + showUntrustedCertDialog(result); + } } - /** - * Try to access with user/pass ""/"", to know if it is a regular server - */ - private void detectAuthorizationMethod() { - - Log_OC.d(TAG, "Trying empty authorization to detect authentication method"); + private boolean authSupported(AuthenticationMethod authMethod) { + String basic = AccountTypeUtils.getAuthTokenTypePass(MainApp.getAccountType()); + String oAuth = AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType()); + String saml = AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()); - String webdav_path = AccountUtils.getWebdavPath(mDiscoveredVersion, mAuthTokenType); - - /// test credentials - Intent service = new Intent(this, OperationsService.class); - service.setAction(OperationsService.ACTION_DETECT_AUTHENTICATION_METHOD); - service.putExtra(OperationsService.EXTRA_SERVER_URL, mHostBaseUrl); - service.putExtra(OperationsService.EXTRA_WEBDAV_PATH, webdav_path); - startService(service); + return (( mAuthTokenType.equals(basic) && + authMethod.equals(AuthenticationMethod.BASIC_HTTP_AUTH) ) || + ( mAuthTokenType.equals(oAuth) && + authMethod.equals(AuthenticationMethod.BEARER_TOKEN)) || + ( mAuthTokenType.equals(saml) && + authMethod.equals(AuthenticationMethod.SAML_WEB_SSO)) + ); } + // TODO remove, if possible private String normalizeUrl(String url) { if (url != null && url.length() > 0) { url = url.trim(); @@ -1048,6 +1051,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { } + // TODO remove, if possible private String trimUrlWebdav(String url){ if(url.toLowerCase().endsWith(AccountUtils.WEBDAV_PATH_4_0)){ url = url.substring(0, url.length() - AccountUtils.WEBDAV_PATH_4_0.length()); @@ -1301,7 +1305,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { mServerIsChecked = true; mServerIsValid = false; mIsSslConn = false; - mOcServerChkOperation = null; + mServerInfoOperation = null; mDiscoveredVersion = null; mHostBaseUrl = normalizeUrl(mHostUrlInput.getText().toString()); @@ -1313,7 +1317,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { showAuthStatus(); // update input controls state - showRefreshButton(); + showRefreshButton(true); mOkButton.setEnabled(false); // very special case (TODO: move to a common place for all the remote operations) (dangerous here?) @@ -1568,12 +1572,12 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { } - private void showRefreshButton() { - mRefreshButton.setVisibility(View.VISIBLE); - } - - private void hideRefreshButton() { - mRefreshButton.setVisibility(View.GONE); + private void showRefreshButton (boolean show) { + if (show) { + mRefreshButton.setVisibility(View.VISIBLE); + } else { + mRefreshButton.setVisibility(View.GONE); + } } /** @@ -1845,18 +1849,35 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { } } - + + + private void doOnResumeAndBound() { + //Log.wtf(TAG, "registering to listen for operation callbacks" ); + mOperationsServiceBinder.addOperationListener(AuthenticatorActivity.this, mHandler); + + if (mGetServerInfoOpId != -1) { + RemoteOperationResult result = + mOperationsServiceBinder.getOperationResultIfFinished(mGetServerInfoOpId); + if (result != null) { + //Log.wtf(TAG, "found result of operation finished while rotating"); + onGetServerInfoFinish(result); + } + } + } + /** - * Implements callback methods for service binding. Passed as a parameter to { + * Implements callback methods for service binding. */ private class OperationsServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName component, IBinder service) { if (component.equals(new ComponentName(AuthenticatorActivity.this, OperationsService.class))) { - Log_OC.d(TAG, "Operations service connected"); + //Log_OC.wtf(TAG, "Operations service connected"); mOperationsServiceBinder = (OperationsServiceBinder) service; - mOperationsServiceBinder.addOperationListener(AuthenticatorActivity.this, mHandler); + + doOnResumeAndBound(); + } else { return; } @@ -1866,11 +1887,11 @@ SsoWebViewClientListener, OnSslUntrustedCertListener { @Override public void onServiceDisconnected(ComponentName component) { if (component.equals(new ComponentName(AuthenticatorActivity.this, OperationsService.class))) { - Log_OC.d(TAG, "Operations service disconnected"); + Log_OC.e(TAG, "Operations service crashed"); mOperationsServiceBinder = null; - // TODO whatever could be waiting for the service is unbound } } } + }