|
@@ -4,8 +4,10 @@
|
|
|
* @author Bartek Przybylski
|
|
|
* @author David A. Velasco
|
|
|
* @author masensio
|
|
|
+ * @author Mario Danic
|
|
|
* Copyright (C) 2012 Bartek Przybylski
|
|
|
* Copyright (C) 2015 ownCloud Inc.
|
|
|
+ * Copyright (C) 2017 Mario Danic
|
|
|
*
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
* it under the terms of the GNU General Public License version 2,
|
|
@@ -18,6 +20,22 @@
|
|
|
*
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
+ *
|
|
|
+ * All changes by Mario Danic are distributed under the following terms:
|
|
|
+ *
|
|
|
+ * This program is free software: you can redistribute it and/or modify
|
|
|
+ * it under the terms of the GNU Affero General Public License as published by
|
|
|
+ * the Free Software Foundation, either version 3 of the License, or
|
|
|
+ * at your option) any later version.
|
|
|
+ *
|
|
|
+ * 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 Affero General Public License for more details.
|
|
|
+ *
|
|
|
+ * You should have received a copy of the GNU Affero General Public License
|
|
|
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
+ *
|
|
|
*/
|
|
|
|
|
|
package com.owncloud.android.authentication;
|
|
@@ -30,6 +48,7 @@ import android.content.Context;
|
|
|
import android.content.Intent;
|
|
|
import android.content.ServiceConnection;
|
|
|
import android.content.SharedPreferences;
|
|
|
+import android.content.pm.ActivityInfo;
|
|
|
import android.graphics.Rect;
|
|
|
import android.graphics.drawable.Drawable;
|
|
|
import android.net.Uri;
|
|
@@ -38,12 +57,14 @@ import android.os.Bundle;
|
|
|
import android.os.Handler;
|
|
|
import android.os.IBinder;
|
|
|
import android.preference.PreferenceManager;
|
|
|
+import android.support.annotation.Nullable;
|
|
|
import android.support.v4.app.DialogFragment;
|
|
|
import android.support.v4.app.Fragment;
|
|
|
import android.support.v4.app.FragmentManager;
|
|
|
import android.support.v4.app.FragmentTransaction;
|
|
|
import android.text.Editable;
|
|
|
import android.text.InputType;
|
|
|
+import android.text.TextUtils;
|
|
|
import android.text.TextWatcher;
|
|
|
import android.view.KeyEvent;
|
|
|
import android.view.MotionEvent;
|
|
@@ -54,6 +75,7 @@ import android.view.inputmethod.EditorInfo;
|
|
|
import android.webkit.HttpAuthHandler;
|
|
|
import android.webkit.SslErrorHandler;
|
|
|
import android.webkit.WebView;
|
|
|
+import android.webkit.WebViewClient;
|
|
|
import android.widget.Button;
|
|
|
import android.widget.CheckBox;
|
|
|
import android.widget.EditText;
|
|
@@ -85,6 +107,7 @@ import com.owncloud.android.operations.GetServerInfoOperation;
|
|
|
import com.owncloud.android.operations.OAuth2GetAccessToken;
|
|
|
import com.owncloud.android.services.OperationsService;
|
|
|
import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
|
|
|
+import com.owncloud.android.ui.components.CustomEditText;
|
|
|
import com.owncloud.android.ui.dialog.CredentialsDialogFragment;
|
|
|
import com.owncloud.android.ui.dialog.IndeterminateProgressDialog;
|
|
|
import com.owncloud.android.ui.dialog.SamlWebViewDialog;
|
|
@@ -107,6 +130,8 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
|
|
|
private static final String TAG = AuthenticatorActivity.class.getSimpleName();
|
|
|
|
|
|
+ private static final String SCREEN_NAME = "Login";
|
|
|
+
|
|
|
public static final String EXTRA_ACTION = "ACTION";
|
|
|
public static final String EXTRA_ACCOUNT = "ACCOUNT";
|
|
|
|
|
@@ -144,8 +169,12 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
private static final String KEY_ASYNC_TASK_IN_PROGRESS = "AUTH_IN_PROGRESS";
|
|
|
public static final String PROTOCOL_SUFFIX = "://";
|
|
|
public static final String LOGIN_URL_DATA_KEY_VALUE_SEPARATOR = ":";
|
|
|
- private static final String HTTPS_PROTOCOL = "https://";
|
|
|
- private static final String HTTP_PROTOCOL = "http://";
|
|
|
+ public static final String HTTPS_PROTOCOL = "https://";
|
|
|
+ public static final String HTTP_PROTOCOL = "http://";
|
|
|
+
|
|
|
+ public static final String REGULAR_SERVER_INPUT_TYPE = "regular";
|
|
|
+ public static final String SUBDOMAIN_SERVER_INPUT_TYPE = "prefix";
|
|
|
+ public static final String DIRECTORY_SERVER_INPUT_TYPE = "suffix";
|
|
|
|
|
|
/// parameters from EXTRAs in starter Intent
|
|
|
private byte mAction;
|
|
@@ -162,7 +191,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
|
|
|
|
|
|
/// Server PRE-Fragment elements
|
|
|
- private EditText mHostUrlInput;
|
|
|
+ private CustomEditText mHostUrlInput;
|
|
|
private View mRefreshButton;
|
|
|
private TextView mServerStatusView;
|
|
|
|
|
@@ -184,6 +213,8 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
private View mOkButton;
|
|
|
private TextView mAuthStatusView;
|
|
|
|
|
|
+ private WebView mLoginWebView;
|
|
|
+
|
|
|
private int mAuthStatusText = 0, mAuthStatusIcon = 0;
|
|
|
|
|
|
private String mAuthToken = "";
|
|
@@ -198,6 +229,10 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
private final String OAUTH_TOKEN_TYPE = AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType());
|
|
|
private final String SAML_TOKEN_TYPE = AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType());
|
|
|
|
|
|
+ private boolean webViewLoginMethod;
|
|
|
+ private String webViewUser;
|
|
|
+ private String webViewPassword;
|
|
|
+
|
|
|
/**
|
|
|
* {@inheritDoc}
|
|
|
*
|
|
@@ -235,42 +270,86 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
mIsFirstAuthAttempt = savedInstanceState.getBoolean(KEY_AUTH_IS_FIRST_ATTEMPT_TAG);
|
|
|
}
|
|
|
|
|
|
+ webViewLoginMethod = !TextUtils.isEmpty(getResources().getString(R.string.webview_login_url));
|
|
|
+
|
|
|
+ if (webViewLoginMethod) {
|
|
|
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
|
|
+ }
|
|
|
+
|
|
|
/// load user interface
|
|
|
- setContentView(R.layout.account_setup);
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ setContentView(R.layout.account_setup);
|
|
|
|
|
|
- /// initialize general UI elements
|
|
|
- initOverallUi();
|
|
|
+ /// initialize general UI elements
|
|
|
+ initOverallUi();
|
|
|
|
|
|
- mOkButton = findViewById(R.id.buttonOK);
|
|
|
- mOkButton.setOnClickListener(new View.OnClickListener() {
|
|
|
+ mOkButton = findViewById(R.id.buttonOK);
|
|
|
+ mOkButton.setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
|
- @Override
|
|
|
- public void onClick(View v) {
|
|
|
- onOkClick();
|
|
|
- }
|
|
|
- });
|
|
|
+ @Override
|
|
|
+ public void onClick(View v) {
|
|
|
+ onOkClick();
|
|
|
+ }
|
|
|
+ });
|
|
|
|
|
|
- findViewById(R.id.centeredRefreshButton).setOnClickListener(new View.OnClickListener() {
|
|
|
+ findViewById(R.id.centeredRefreshButton).setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
|
- @Override
|
|
|
- public void onClick(View v) {
|
|
|
- checkOcServer();
|
|
|
- }
|
|
|
- });
|
|
|
+ @Override
|
|
|
+ public void onClick(View v) {
|
|
|
+ checkOcServer();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ findViewById(R.id.embeddedRefreshButton).setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
|
- findViewById(R.id.embeddedRefreshButton).setOnClickListener(new View.OnClickListener() {
|
|
|
+ @Override
|
|
|
+ public void onClick(View v) {
|
|
|
+ checkOcServer();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ /// initialize block to be moved to single Fragment to check server and get info about it
|
|
|
+
|
|
|
+ /// initialize block to be moved to single Fragment to retrieve and validate credentials
|
|
|
+ initAuthorizationPreFragment(savedInstanceState);
|
|
|
+
|
|
|
+ } else {
|
|
|
+ setContentView(R.layout.account_setup_webview);
|
|
|
+ mLoginWebView = (WebView) findViewById(R.id.login_webview);
|
|
|
+ initWebViewLogin();
|
|
|
+ }
|
|
|
+
|
|
|
+ initServerPreFragment(savedInstanceState);
|
|
|
+ }
|
|
|
|
|
|
+ private void initWebViewLogin() {
|
|
|
+ mLoginWebView.getSettings().setAllowFileAccess(false);
|
|
|
+ mLoginWebView.getSettings().setJavaScriptEnabled(true);
|
|
|
+ mLoginWebView.getSettings().setUserAgentString(MainApp.getUserAgent());
|
|
|
+ mLoginWebView.loadUrl(getResources().getString(R.string.webview_login_url));
|
|
|
+ mLoginWebView.setWebViewClient(new WebViewClient() {
|
|
|
@Override
|
|
|
- public void onClick(View v) {
|
|
|
- checkOcServer();
|
|
|
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
|
|
+ if (url.startsWith(getString(R.string.login_data_own_scheme) + PROTOCOL_SUFFIX + "login/")) {
|
|
|
+ parseAndLoginFromWebView(url);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
}
|
|
|
});
|
|
|
+ }
|
|
|
|
|
|
- /// initialize block to be moved to single Fragment to check server and get info about it
|
|
|
- initServerPreFragment(savedInstanceState);
|
|
|
+ private void parseAndLoginFromWebView(String dataString) {
|
|
|
+ String prefix = getString(R.string.login_data_own_scheme) + PROTOCOL_SUFFIX + "login/";
|
|
|
+ LoginUrlInfo loginUrlInfo = parseLoginDataUrl(prefix, dataString);
|
|
|
+
|
|
|
+ if (loginUrlInfo != null) {
|
|
|
+ mServerInfo.mBaseUrl = normalizeUrlSuffix(loginUrlInfo.serverAddress);
|
|
|
+ webViewUser = loginUrlInfo.username;
|
|
|
+ webViewPassword = loginUrlInfo.password;
|
|
|
+ checkOcServer();
|
|
|
+ }
|
|
|
|
|
|
- /// initialize block to be moved to single Fragment to retrieve and validate credentials
|
|
|
- initAuthorizationPreFragment(savedInstanceState);
|
|
|
}
|
|
|
|
|
|
private void populateLoginFields(String dataString) throws IllegalArgumentException {
|
|
@@ -294,7 +373,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
/**
|
|
|
* parses a URI string and returns a login data object with the information from the URI string.
|
|
|
*
|
|
|
- * @param prefix URI beginning, e.g. cloud://login/
|
|
|
+ * @param prefix URI beginning, e.g. cloud://login/
|
|
|
* @param dataString the complete URI
|
|
|
* @return login data
|
|
|
* @throws IllegalArgumentException when
|
|
@@ -413,7 +492,11 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
mServerInfo.mIsSslConn = mServerInfo.mBaseUrl.startsWith(HTTPS_PROTOCOL);
|
|
|
mServerInfo.mVersion = AccountUtils.getServerVersion(mAccount);
|
|
|
} else {
|
|
|
- mServerInfo.mBaseUrl = getString(R.string.server_url).trim();
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ mServerInfo.mBaseUrl = getString(R.string.server_url).trim();
|
|
|
+ } else {
|
|
|
+ mServerInfo.mBaseUrl = getString(R.string.webview_login_url).trim();
|
|
|
+ }
|
|
|
mServerInfo.mIsSslConn = mServerInfo.mBaseUrl.startsWith(HTTPS_PROTOCOL);
|
|
|
}
|
|
|
} else {
|
|
@@ -435,72 +518,74 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
|
|
|
}
|
|
|
|
|
|
- /// step 2 - set properties of UI elements (text, visibility, enabled...)
|
|
|
- mHostUrlInput = (EditText) findViewById(R.id.hostUrlInput);
|
|
|
- // Convert IDN to Unicode
|
|
|
- mHostUrlInput.setText(DisplayUtils.convertIdn(mServerInfo.mBaseUrl, false));
|
|
|
- if (mAction != ACTION_CREATE) {
|
|
|
- /// lock things that should not change
|
|
|
- mHostUrlInput.setEnabled(false);
|
|
|
- mHostUrlInput.setFocusable(false);
|
|
|
- }
|
|
|
- if (isUrlInputAllowed) {
|
|
|
- mRefreshButton = findViewById(R.id.embeddedRefreshButton);
|
|
|
- } else {
|
|
|
- findViewById(R.id.hostUrlFrame).setVisibility(View.GONE);
|
|
|
- mRefreshButton = findViewById(R.id.centeredRefreshButton);
|
|
|
- }
|
|
|
- showRefreshButton(mServerIsChecked && !mServerIsValid &&
|
|
|
- mWaitingForOpId > Integer.MAX_VALUE);
|
|
|
- mServerStatusView = (TextView) findViewById(R.id.server_status_text);
|
|
|
- showServerStatus();
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ /// step 2 - set properties of UI elements (text, visibility, enabled...)
|
|
|
+ mHostUrlInput = (CustomEditText) findViewById(R.id.hostUrlInput);
|
|
|
+ // Convert IDN to Unicode
|
|
|
+ mHostUrlInput.setText(DisplayUtils.convertIdn(mServerInfo.mBaseUrl, false));
|
|
|
+ if (mAction != ACTION_CREATE) {
|
|
|
+ /// lock things that should not change
|
|
|
+ mHostUrlInput.setEnabled(false);
|
|
|
+ mHostUrlInput.setFocusable(false);
|
|
|
+ }
|
|
|
+ if (isUrlInputAllowed) {
|
|
|
+ mRefreshButton = findViewById(R.id.embeddedRefreshButton);
|
|
|
+ } else {
|
|
|
+ findViewById(R.id.hostUrlFrame).setVisibility(View.GONE);
|
|
|
+ mRefreshButton = findViewById(R.id.centeredRefreshButton);
|
|
|
+ }
|
|
|
+ showRefreshButton(mServerIsChecked && !mServerIsValid &&
|
|
|
+ mWaitingForOpId > Integer.MAX_VALUE);
|
|
|
+ mServerStatusView = (TextView) findViewById(R.id.server_status_text);
|
|
|
+ showServerStatus();
|
|
|
|
|
|
- /// step 3 - bind some listeners and options
|
|
|
- mHostUrlInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
|
|
|
- mHostUrlInput.setOnEditorActionListener(this);
|
|
|
+ /// step 3 - bind some listeners and options
|
|
|
+ mHostUrlInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
|
|
|
+ mHostUrlInput.setOnEditorActionListener(this);
|
|
|
|
|
|
- /// step 4 - create listeners that will be bound at onResume
|
|
|
- mHostUrlInputWatcher = new TextWatcher() {
|
|
|
+ /// step 4 - create listeners that will be bound at onResume
|
|
|
+ mHostUrlInputWatcher = new TextWatcher() {
|
|
|
|
|
|
- @Override
|
|
|
- public void afterTextChanged(Editable s) {
|
|
|
- if (mOkButton.isEnabled() &&
|
|
|
- !mServerInfo.mBaseUrl.equals(
|
|
|
- normalizeUrl(s.toString(), mServerInfo.mIsSslConn))) {
|
|
|
- mOkButton.setEnabled(false);
|
|
|
+ @Override
|
|
|
+ public void afterTextChanged(Editable s) {
|
|
|
+ if (mOkButton.isEnabled() &&
|
|
|
+ !mServerInfo.mBaseUrl.equals(
|
|
|
+ normalizeUrl(s.toString(), mServerInfo.mIsSslConn))) {
|
|
|
+ mOkButton.setEnabled(false);
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- @Override
|
|
|
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onTextChanged(CharSequence s, int start, int before, int count) {
|
|
|
- if (mAuthStatusIcon != 0) {
|
|
|
- Log_OC.d(TAG, "onTextChanged: hiding authentication status");
|
|
|
- mAuthStatusIcon = 0;
|
|
|
- mAuthStatusText = 0;
|
|
|
- showAuthStatus();
|
|
|
+ @Override
|
|
|
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
|
|
}
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
|
|
|
- // TODO find out if this is really necessary, or if it can done in a different way
|
|
|
- findViewById(R.id.scroll).setOnTouchListener(new OnTouchListener() {
|
|
|
- @Override
|
|
|
- public boolean onTouch(View view, MotionEvent event) {
|
|
|
- if (event.getAction() == MotionEvent.ACTION_DOWN &&
|
|
|
- AccountTypeUtils
|
|
|
- .getAuthTokenTypeSamlSessionCookie(MainApp
|
|
|
- .getAccountType()).equals(mAuthTokenType) &&
|
|
|
- mHostUrlInput.hasFocus()) {
|
|
|
- checkOcServer();
|
|
|
+ @Override
|
|
|
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
|
|
|
+ if (mAuthStatusIcon != 0) {
|
|
|
+ Log_OC.d(TAG, "onTextChanged: hiding authentication status");
|
|
|
+ mAuthStatusIcon = 0;
|
|
|
+ mAuthStatusText = 0;
|
|
|
+ showAuthStatus();
|
|
|
+ }
|
|
|
}
|
|
|
- return false;
|
|
|
- }
|
|
|
- });
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ // TODO find out if this is really necessary, or if it can done in a different way
|
|
|
+ findViewById(R.id.scroll).setOnTouchListener(new OnTouchListener() {
|
|
|
+ @Override
|
|
|
+ public boolean onTouch(View view, MotionEvent event) {
|
|
|
+ if (event.getAction() == MotionEvent.ACTION_DOWN &&
|
|
|
+ AccountTypeUtils
|
|
|
+ .getAuthTokenTypeSamlSessionCookie(MainApp
|
|
|
+ .getAccountType()).equals(mAuthTokenType) &&
|
|
|
+ mHostUrlInput.hasFocus()) {
|
|
|
+ checkOcServer();
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -629,11 +714,20 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
outState.putString(KEY_AUTH_TOKEN_TYPE, mAuthTokenType);
|
|
|
outState.putLong(KEY_WAITING_FOR_OP_ID, mWaitingForOpId);
|
|
|
|
|
|
- /// Server PRE-fragment state
|
|
|
- outState.putInt(KEY_SERVER_STATUS_TEXT, mServerStatusText);
|
|
|
- outState.putInt(KEY_SERVER_STATUS_ICON, mServerStatusIcon);
|
|
|
- outState.putBoolean(KEY_SERVER_CHECKED, mServerIsChecked);
|
|
|
- outState.putBoolean(KEY_SERVER_VALID, mServerIsValid);
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ /// Server PRE-fragment state
|
|
|
+ outState.putInt(KEY_SERVER_STATUS_TEXT, mServerStatusText);
|
|
|
+ outState.putInt(KEY_SERVER_STATUS_ICON, mServerStatusIcon);
|
|
|
+ outState.putBoolean(KEY_SERVER_CHECKED, mServerIsChecked);
|
|
|
+ outState.putBoolean(KEY_SERVER_VALID, mServerIsValid);
|
|
|
+
|
|
|
+ /// Authentication PRE-fragment state
|
|
|
+ outState.putBoolean(KEY_PASSWORD_EXPOSED, isPasswordVisible());
|
|
|
+ outState.putInt(KEY_AUTH_STATUS_ICON, mAuthStatusIcon);
|
|
|
+ outState.putInt(KEY_AUTH_STATUS_TEXT, mAuthStatusText);
|
|
|
+ outState.putString(KEY_AUTH_TOKEN, mAuthToken);
|
|
|
+ }
|
|
|
+
|
|
|
outState.putBoolean(KEY_IS_SSL_CONN, mServerInfo.mIsSslConn);
|
|
|
outState.putString(KEY_HOST_URL_TEXT, mServerInfo.mBaseUrl);
|
|
|
if (mServerInfo.mVersion != null) {
|
|
@@ -641,18 +735,14 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
}
|
|
|
outState.putString(KEY_SERVER_AUTH_METHOD, mServerInfo.mAuthMethod.name());
|
|
|
|
|
|
- /// Authentication PRE-fragment state
|
|
|
- outState.putBoolean(KEY_PASSWORD_EXPOSED, isPasswordVisible());
|
|
|
- outState.putInt(KEY_AUTH_STATUS_ICON, mAuthStatusIcon);
|
|
|
- outState.putInt(KEY_AUTH_STATUS_TEXT, mAuthStatusText);
|
|
|
- outState.putString(KEY_AUTH_TOKEN, mAuthToken);
|
|
|
-
|
|
|
/// authentication
|
|
|
outState.putBoolean(KEY_AUTH_IS_FIRST_ATTEMPT_TAG, mIsFirstAuthAttempt);
|
|
|
|
|
|
/// AsyncTask (User and password)
|
|
|
- outState.putString(KEY_USERNAME, mUsernameInput.getText().toString().trim());
|
|
|
- outState.putString(KEY_PASSWORD, mPasswordInput.getText().toString());
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ outState.putString(KEY_USERNAME, mUsernameInput.getText().toString().trim());
|
|
|
+ outState.putString(KEY_PASSWORD, mPasswordInput.getText().toString());
|
|
|
+ }
|
|
|
|
|
|
if (mAsyncTask != null) {
|
|
|
mAsyncTask.cancel(true);
|
|
@@ -714,21 +804,23 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
protected void onResume() {
|
|
|
super.onResume();
|
|
|
|
|
|
- // bound here to avoid spurious changes triggered by Android on device rotations
|
|
|
- mHostUrlInput.setOnFocusChangeListener(this);
|
|
|
- mHostUrlInput.addTextChangedListener(mHostUrlInputWatcher);
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ // bound here to avoid spurious changes triggered by Android on device rotations
|
|
|
+ mHostUrlInput.setOnFocusChangeListener(this);
|
|
|
+ mHostUrlInput.addTextChangedListener(mHostUrlInputWatcher);
|
|
|
|
|
|
- if (mNewCapturedUriFromOAuth2Redirection != null) {
|
|
|
- getOAuth2AccessTokenFromCapturedRedirection();
|
|
|
- }
|
|
|
+ if (mNewCapturedUriFromOAuth2Redirection != null) {
|
|
|
+ getOAuth2AccessTokenFromCapturedRedirection();
|
|
|
+ }
|
|
|
|
|
|
- String dataString = getIntent().getDataString();
|
|
|
- if (dataString != null) {
|
|
|
- try {
|
|
|
- populateLoginFields(dataString);
|
|
|
- } catch (IllegalArgumentException e) {
|
|
|
- Toast.makeText(this, "Illegal login data URL used", Toast.LENGTH_SHORT).show();
|
|
|
- Log_OC.e(TAG, "Illegal login data URL used, no Login pre-fill!", e);
|
|
|
+ String dataString = getIntent().getDataString();
|
|
|
+ if (dataString != null) {
|
|
|
+ try {
|
|
|
+ populateLoginFields(dataString);
|
|
|
+ } catch (IllegalArgumentException e) {
|
|
|
+ Toast.makeText(this, "Illegal login data URL used", Toast.LENGTH_SHORT).show();
|
|
|
+ Log_OC.e(TAG, "Illegal login data URL used, no Login pre-fill!", e);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -756,8 +848,10 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
mOperationsServiceBinder.removeOperationListener(this);
|
|
|
}
|
|
|
|
|
|
- mHostUrlInput.removeTextChangedListener(mHostUrlInputWatcher);
|
|
|
- mHostUrlInput.setOnFocusChangeListener(null);
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ mHostUrlInput.removeTextChangedListener(mHostUrlInputWatcher);
|
|
|
+ mHostUrlInput.setOnFocusChangeListener(null);
|
|
|
+ }
|
|
|
|
|
|
super.onPause();
|
|
|
}
|
|
@@ -771,10 +865,14 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
unbindService(mOperationsServiceConnection);
|
|
|
mOperationsServiceBinder = null;
|
|
|
}
|
|
|
+
|
|
|
+ if (webViewLoginMethod) {
|
|
|
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
|
|
|
+ }
|
|
|
+
|
|
|
super.onDestroy();
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* Parses the redirection with the response to the GET AUTHORIZATION request to the
|
|
|
* oAuth server and requests for the access token (GET ACCESS TOKEN)
|
|
@@ -847,15 +945,23 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
|
|
|
|
|
|
private void checkOcServer() {
|
|
|
- String uri = mHostUrlInput.getText().toString().trim();
|
|
|
+ String uri;
|
|
|
+ if (mHostUrlInput != null) {
|
|
|
+ uri = mHostUrlInput.getText().toString().trim();
|
|
|
+ mOkButton.setEnabled(false);
|
|
|
+ showRefreshButton(false);
|
|
|
+ } else {
|
|
|
+ uri = mServerInfo.mBaseUrl;
|
|
|
+ }
|
|
|
+
|
|
|
mServerIsValid = false;
|
|
|
mServerIsChecked = false;
|
|
|
- mOkButton.setEnabled(false);
|
|
|
mServerInfo = new GetServerInfoOperation.ServerInfo();
|
|
|
- showRefreshButton(false);
|
|
|
|
|
|
if (uri.length() != 0) {
|
|
|
- uri = stripIndexPhpOrAppsFiles(uri, mHostUrlInput);
|
|
|
+ if (mHostUrlInput != null) {
|
|
|
+ uri = stripIndexPhpOrAppsFiles(uri, mHostUrlInput);
|
|
|
+ }
|
|
|
|
|
|
// Handle internationalized domain names
|
|
|
try {
|
|
@@ -864,9 +970,11 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
// Let Owncloud library check the error of the malformed URI
|
|
|
}
|
|
|
|
|
|
- mServerStatusText = R.string.auth_testing_connection;
|
|
|
- mServerStatusIcon = R.drawable.progress_small;
|
|
|
- showServerStatus();
|
|
|
+ if (mHostUrlInput != null) {
|
|
|
+ mServerStatusText = R.string.auth_testing_connection;
|
|
|
+ mServerStatusIcon = R.drawable.progress_small;
|
|
|
+ showServerStatus();
|
|
|
+ }
|
|
|
|
|
|
Intent getServerInfoIntent = new Intent();
|
|
|
getServerInfoIntent.setAction(OperationsService.ACTION_GET_SERVER_INFO);
|
|
@@ -874,6 +982,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
OperationsService.EXTRA_SERVER_URL,
|
|
|
normalizeUrlSuffix(uri)
|
|
|
);
|
|
|
+
|
|
|
if (mOperationsServiceBinder != null) {
|
|
|
mWaitingForOpId = mOperationsServiceBinder.queueNewOperation(getServerInfoIntent);
|
|
|
} else {
|
|
@@ -883,7 +992,9 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
} else {
|
|
|
mServerStatusText = 0;
|
|
|
mServerStatusIcon = 0;
|
|
|
- showServerStatus();
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ showServerStatus();
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -897,6 +1008,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
*
|
|
|
* @param hasFocus 'True' if focus is received, 'false' if is lost
|
|
|
*/
|
|
|
+
|
|
|
private void onPasswordFocusChanged(boolean hasFocus) {
|
|
|
if (hasFocus) {
|
|
|
showViewPasswordButton();
|
|
@@ -976,7 +1088,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
|
|
|
startSamlBasedFederatedSingleSignOnAuthorization();
|
|
|
} else {
|
|
|
- checkBasicAuthorization();
|
|
|
+ checkBasicAuthorization(null, null);
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -986,10 +1098,17 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
* Tests the credentials entered by the user performing a check of existence on
|
|
|
* the root folder of the ownCloud server.
|
|
|
*/
|
|
|
- private void checkBasicAuthorization() {
|
|
|
+ private void checkBasicAuthorization(@Nullable String webViewUsername, @Nullable String webViewPassword) {
|
|
|
/// get basic credentials entered by user
|
|
|
- String username = mUsernameInput.getText().toString().trim();
|
|
|
- String password = mPasswordInput.getText().toString();
|
|
|
+ String username;
|
|
|
+ String password;
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ username = mUsernameInput.getText().toString().trim();
|
|
|
+ password = mPasswordInput.getText().toString();
|
|
|
+ } else {
|
|
|
+ username = webViewUsername;
|
|
|
+ password = webViewPassword;
|
|
|
+ }
|
|
|
|
|
|
/// be gentle with the user
|
|
|
IndeterminateProgressDialog dialog =
|
|
@@ -1093,11 +1212,13 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
}
|
|
|
|
|
|
if (mAction == ACTION_CREATE) {
|
|
|
- mUsernameInput.setText(username);
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ mUsernameInput.setText(username);
|
|
|
+ }
|
|
|
success = createAccount(result);
|
|
|
} else {
|
|
|
|
|
|
- if (!mUsernameInput.getText().toString().trim().equals(username)) {
|
|
|
+ if (!webViewLoginMethod && !mUsernameInput.getText().toString().trim().equals(username)) {
|
|
|
// fail - not a new account, but an existing one; disallow
|
|
|
result = new RemoteOperationResult(ResultCode.ACCOUNT_NOT_THE_SAME);
|
|
|
mAuthToken = "";
|
|
@@ -1122,8 +1243,10 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
finish();
|
|
|
}
|
|
|
} else {
|
|
|
- updateStatusIconFailUserName();
|
|
|
- showAuthStatus();
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ updateStatusIconFailUserName();
|
|
|
+ showAuthStatus();
|
|
|
+ }
|
|
|
Log_OC.e(TAG, "Access to user name failed: " + result.getLogMessage());
|
|
|
}
|
|
|
|
|
@@ -1141,7 +1264,9 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
mWaitingForOpId = Long.MAX_VALUE;
|
|
|
|
|
|
// update server status, but don't show it yet
|
|
|
- updateServerStatusIconAndText(result);
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ updateServerStatusIconAndText(result);
|
|
|
+ }
|
|
|
|
|
|
if (result.isSuccess()) {
|
|
|
/// SUCCESS means:
|
|
@@ -1151,9 +1276,16 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
// 4. we got the authentication method required by the server
|
|
|
mServerInfo = (GetServerInfoOperation.ServerInfo) (result.getData().get(0));
|
|
|
|
|
|
+ if (webViewLoginMethod) {
|
|
|
+ checkBasicAuthorization(webViewUser, webViewPassword);
|
|
|
+ }
|
|
|
+
|
|
|
if (!authSupported(mServerInfo.mAuthMethod)) {
|
|
|
|
|
|
- updateServerStatusIconNoRegularAuth(); // overrides updateServerStatusIconAndText()
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ // overrides updateServerStatusIconAndText()
|
|
|
+ updateServerStatusIconNoRegularAuth();
|
|
|
+ }
|
|
|
mServerIsValid = false;
|
|
|
|
|
|
} else {
|
|
@@ -1165,9 +1297,11 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
}
|
|
|
|
|
|
// refresh UI
|
|
|
- showRefreshButton(!mServerIsValid);
|
|
|
- showServerStatus();
|
|
|
- mOkButton.setEnabled(mServerIsValid);
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ 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) {
|
|
@@ -1495,11 +1629,13 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
showServerStatus();
|
|
|
mAuthStatusIcon = 0;
|
|
|
mAuthStatusText = 0;
|
|
|
- showAuthStatus();
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ showAuthStatus();
|
|
|
|
|
|
- // update input controls state
|
|
|
- showRefreshButton(true);
|
|
|
- mOkButton.setEnabled(false);
|
|
|
+ // update input controls state
|
|
|
+ showRefreshButton(true);
|
|
|
+ mOkButton.setEnabled(false);
|
|
|
+ }
|
|
|
|
|
|
// very special case (TODO: move to a common place for all the remote operations)
|
|
|
if (result.getCode() == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) {
|
|
@@ -1507,8 +1643,10 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
}
|
|
|
|
|
|
} else { // authorization fail due to client side - probably wrong credentials
|
|
|
- updateAuthStatusIconAndText(result);
|
|
|
- showAuthStatus();
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ updateAuthStatusIconAndText(result);
|
|
|
+ showAuthStatus();
|
|
|
+ }
|
|
|
Log_OC.d(TAG, "Access failed: " + result.getLogMessage());
|
|
|
}
|
|
|
}
|
|
@@ -1546,8 +1684,13 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);
|
|
|
|
|
|
} else {
|
|
|
- response.putString(AccountManager.KEY_AUTHTOKEN, mPasswordInput.getText().toString());
|
|
|
- mAccountMgr.setPassword(mAccount, mPasswordInput.getText().toString());
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ response.putString(AccountManager.KEY_AUTHTOKEN, mPasswordInput.getText().toString());
|
|
|
+ mAccountMgr.setPassword(mAccount, mPasswordInput.getText().toString());
|
|
|
+ } else {
|
|
|
+ response.putString(AccountManager.KEY_AUTHTOKEN, webViewPassword);
|
|
|
+ mAccountMgr.setPassword(mAccount, webViewPassword);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// remove managed clients for this account to enforce creation with fresh credentials
|
|
@@ -1583,7 +1726,12 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
}
|
|
|
|
|
|
Uri uri = Uri.parse(mServerInfo.mBaseUrl);
|
|
|
- String username = mUsernameInput.getText().toString().trim();
|
|
|
+ String username;
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ username = mUsernameInput.getText().toString().trim();
|
|
|
+ } else {
|
|
|
+ username = webViewUser;
|
|
|
+ }
|
|
|
if (isOAuth) {
|
|
|
username = "OAuth_user" + (new java.util.Random(System.currentTimeMillis())).nextLong();
|
|
|
}
|
|
@@ -1593,8 +1741,10 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
if (AccountUtils.exists(newAccount, getApplicationContext())) {
|
|
|
// fail - not a new account, but an existing one; disallow
|
|
|
RemoteOperationResult result = new RemoteOperationResult(ResultCode.ACCOUNT_NOT_NEW);
|
|
|
- updateAuthStatusIconAndText(result);
|
|
|
- showAuthStatus();
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ updateAuthStatusIconAndText(result);
|
|
|
+ showAuthStatus();
|
|
|
+ }
|
|
|
Log_OC.d(TAG, result.getLogMessage());
|
|
|
return false;
|
|
|
|
|
@@ -1605,9 +1755,15 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
// with external authorizations, the password is never input in the app
|
|
|
mAccountMgr.addAccountExplicitly(mAccount, "", null);
|
|
|
} else {
|
|
|
- mAccountMgr.addAccountExplicitly(
|
|
|
- mAccount, mPasswordInput.getText().toString(), null
|
|
|
- );
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ mAccountMgr.addAccountExplicitly(
|
|
|
+ mAccount, mPasswordInput.getText().toString(), null
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ mAccountMgr.addAccountExplicitly(
|
|
|
+ mAccount, webViewPassword, null
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// include account version with the new account
|
|
@@ -1690,15 +1846,16 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
* to the last check on the ownCloud server.
|
|
|
*/
|
|
|
private void showServerStatus() {
|
|
|
- if (mServerStatusIcon == 0 && mServerStatusText == 0) {
|
|
|
- mServerStatusView.setVisibility(View.INVISIBLE);
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ if (mServerStatusIcon == 0 && mServerStatusText == 0) {
|
|
|
+ mServerStatusView.setVisibility(View.INVISIBLE);
|
|
|
|
|
|
- } else {
|
|
|
- mServerStatusView.setText(mServerStatusText);
|
|
|
- mServerStatusView.setCompoundDrawablesWithIntrinsicBounds(mServerStatusIcon, 0, 0, 0);
|
|
|
- mServerStatusView.setVisibility(View.VISIBLE);
|
|
|
+ } else {
|
|
|
+ mServerStatusView.setText(mServerStatusText);
|
|
|
+ mServerStatusView.setCompoundDrawablesWithIntrinsicBounds(mServerStatusIcon, 0, 0, 0);
|
|
|
+ mServerStatusView.setVisibility(View.VISIBLE);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1707,22 +1864,26 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
* to the interactions with the OAuth authorization server.
|
|
|
*/
|
|
|
private void showAuthStatus() {
|
|
|
- if (mAuthStatusIcon == 0 && mAuthStatusText == 0) {
|
|
|
- mAuthStatusView.setVisibility(View.INVISIBLE);
|
|
|
+ if (!webViewLoginMethod) {
|
|
|
+ if (mAuthStatusIcon == 0 && mAuthStatusText == 0) {
|
|
|
+ mAuthStatusView.setVisibility(View.INVISIBLE);
|
|
|
|
|
|
- } else {
|
|
|
- mAuthStatusView.setText(mAuthStatusText);
|
|
|
- mAuthStatusView.setCompoundDrawablesWithIntrinsicBounds(mAuthStatusIcon, 0, 0, 0);
|
|
|
- mAuthStatusView.setVisibility(View.VISIBLE);
|
|
|
+ } else {
|
|
|
+ mAuthStatusView.setText(mAuthStatusText);
|
|
|
+ mAuthStatusView.setCompoundDrawablesWithIntrinsicBounds(mAuthStatusIcon, 0, 0, 0);
|
|
|
+ mAuthStatusView.setVisibility(View.VISIBLE);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
private void showRefreshButton(boolean show) {
|
|
|
- if (show) {
|
|
|
- mRefreshButton.setVisibility(View.VISIBLE);
|
|
|
- } else {
|
|
|
- mRefreshButton.setVisibility(View.GONE);
|
|
|
+ if (webViewLoginMethod) {
|
|
|
+ if (show) {
|
|
|
+ mRefreshButton.setVisibility(View.VISIBLE);
|
|
|
+ } else {
|
|
|
+ mRefreshButton.setVisibility(View.GONE);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1779,7 +1940,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
inputField.equals(mHostUrlInput) &&
|
|
|
AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).
|
|
|
equals(mAuthTokenType)) {
|
|
|
- checkOcServer();
|
|
|
+ checkOcServer();
|
|
|
}
|
|
|
return false; // always return false to grant that the software keyboard is hidden anyway
|
|
|
}
|
|
@@ -1935,7 +2096,8 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|
|
mOperationsServiceBinder.dispatchResultIfFinished((int) mWaitingForOpId, this);
|
|
|
}
|
|
|
|
|
|
- if (mHostUrlInput.getText() != null && mHostUrlInput.getText().length() > 0 && !mServerIsChecked) {
|
|
|
+ if (!webViewLoginMethod && mHostUrlInput.getText() != null && mHostUrlInput.getText().length() > 0
|
|
|
+ && !mServerIsChecked) {
|
|
|
checkOcServer();
|
|
|
}
|
|
|
}
|