Create dialog fragment for showing authentication dialog

This commit is contained in:
jabarros 2014-09-02 14:03:56 +02:00
parent 622523b3e3
commit 85f63a0ff4
3 changed files with 204 additions and 74 deletions

View file

@ -50,7 +50,9 @@ import android.view.View.OnFocusChangeListener;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.inputmethod.EditorInfo;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
@ -77,6 +79,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.dialog.CredentialsDialogFragment;
import com.owncloud.android.ui.dialog.IndeterminateProgressDialog;
import com.owncloud.android.ui.dialog.SamlWebViewDialog;
import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
@ -125,6 +128,8 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
private static final String UNTRUSTED_CERT_DIALOG_TAG = "UNTRUSTED_CERT_DIALOG";
private static final String SAML_DIALOG_TAG = "SAML_DIALOG";
private static final String WAIT_DIALOG_TAG = "WAIT_DIALOG";
private static final String CREDENTIALS_DIALOG_TAG = "CREDENTIALS_DIALOG";
private static final String KEY_AUTH_IS_FIRST_ATTEMPT_TAG = "KEY_AUTH_IS_FIRST_ATTEMPT";
/// parameters from EXTRAs in starter Intent
@ -170,6 +175,8 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
private String mAuthToken = "";
private boolean mIsFirstAuthAttempt;
/// Identifier of operation in progress which result shouldn't be lost
private long mWaitingForOpId = Long.MAX_VALUE;
@ -186,6 +193,8 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
mIsFirstAuthAttempt = true;
// bind to Operations Service
mOperationsServiceConnection = new OperationsServiceConnection();
if (!bindService(new Intent(this, OperationsService.class),
@ -210,6 +219,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
} else {
mAuthTokenType = savedInstanceState.getString(KEY_AUTH_TOKEN_TYPE);
mWaitingForOpId = savedInstanceState.getLong(KEY_WAITING_FOR_OP_ID);
mIsFirstAuthAttempt = savedInstanceState.getBoolean(KEY_AUTH_IS_FIRST_ATTEMPT_TAG);
}
/// load user interface
@ -556,6 +566,9 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
outState.putInt(KEY_AUTH_STATUS_TEXT, mAuthStatusText);
outState.putString(KEY_AUTH_TOKEN, mAuthToken);
/// authentication
outState.putBoolean(KEY_AUTH_IS_FIRST_ATTEMPT_TAG, mIsFirstAuthAttempt);
//Log_OC.wtf(TAG, "onSaveInstanceState end" );
}
@ -1684,6 +1697,15 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
dialog.show(ft, UNTRUSTED_CERT_DIALOG_TAG);
}
/**
* Show authentication dialog
*/
public void showAuthenticationDialog(WebView webView, HttpAuthHandler handler) {
// Show a dialog for the authentication
createAuthenticationDialog(webView, handler);
}
/**
* Show untrusted cert dialog
*/
@ -1774,5 +1796,33 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
}
}
/**
* Create dialog for request authentication to the user
* @param webView
* @param handler
*/
private void createAuthenticationDialog(WebView webView, HttpAuthHandler handler) {
// Show a dialog with the certificate info
CredentialsDialogFragment dialog = CredentialsDialogFragment.newInstanceForCredentials(webView, handler);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.addToBackStack(null);
dialog.setCancelable(false);
dialog.show(ft, CREDENTIALS_DIALOG_TAG);
if (!mIsFirstAuthAttempt) {
Toast.makeText(getApplicationContext(), getText(R.string.saml_authentication_wrong_pass), Toast.LENGTH_LONG).show();
} else {
mIsFirstAuthAttempt = false;
}
}
/**
* For retrieving the clicking on authentication cancel button
*/
public void doNegativeAuthenticatioDialogClick(){
mIsFirstAuthAttempt = true;
}
}

View file

@ -24,17 +24,13 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.net.http.SslCertificate;
import android.net.http.SslError;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.CookieManager;
@ -43,11 +39,7 @@ import android.webkit.SslErrorHandler;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.owncloud.android.R;
import com.owncloud.android.lib.common.network.NetworkUtils;
import com.owncloud.android.utils.Log_OC;
@ -75,7 +67,6 @@ public class SsoWebViewClient extends WebViewClient {
private String mTargetUrl;
private String mLastReloadedUrlAtError;
private boolean mIsFirstAttempt;
public SsoWebViewClient (Context context, Handler listenerHandler, SsoWebViewClientListener listener) {
mContext = context;
@ -83,7 +74,6 @@ public class SsoWebViewClient extends WebViewClient {
mListenerRef = new WeakReference<SsoWebViewClient.SsoWebViewClientListener>(listener);
mTargetUrl = "fake://url.to.be.set";
mLastReloadedUrlAtError = null;
mIsFirstAttempt = true;
}
public String getTargetUrl() {
@ -207,13 +197,7 @@ public class SsoWebViewClient extends WebViewClient {
public void onReceivedHttpAuthRequest (WebView view, HttpAuthHandler handler, String host, String realm) {
Log_OC.d(TAG, "onReceivedHttpAuthRequest : " + host);
createAuthenticationDialog(view, handler);
if (!mIsFirstAttempt) {
Toast.makeText(mContext, mContext.getText(R.string.saml_authentication_wrong_pass), Toast.LENGTH_LONG).show();
} else {
mIsFirstAttempt = false;
}
((AuthenticatorActivity)mContext).showAuthenticationDialog(view, handler);
}
@Override
@ -248,60 +232,4 @@ public class SsoWebViewClient extends WebViewClient {
Log_OC.d(TAG, "shouldOverrideKeyEvent : " + event);
return false;
}
/**
* Create dialog for request authentication to the user
* @param webView
* @param handler
*/
private void createAuthenticationDialog(WebView webView, HttpAuthHandler handler) {
final WebView mWebView = webView;
final HttpAuthHandler mHandler = handler;
// Create field for username
final EditText usernameET = new EditText(mContext);
usernameET.setHint(mContext.getText(R.string.auth_username));
// Create field for password
final EditText passwordET = new EditText(mContext);
passwordET.setHint(mContext.getText(R.string.auth_password));
passwordET.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
// Prepare LinearLayout for dialog
LinearLayout ll = new LinearLayout(mContext);
ll.setOrientation(LinearLayout.VERTICAL);
ll.addView(usernameET);
ll.addView(passwordET);
Builder authDialog = new AlertDialog
.Builder(mContext)
.setTitle(mContext.getText(R.string.saml_authentication_required_text))
.setView(ll)
.setCancelable(false)
.setPositiveButton(mContext.getText(R.string.common_ok),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String username = usernameET.getText().toString().trim();
String password = passwordET.getText().toString().trim();
// Proceed with the authentication
mHandler.proceed(username, password);
dialog.dismiss();
}
})
.setNegativeButton(mContext.getText(R.string.common_cancel),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
mWebView.stopLoading();
mIsFirstAttempt = true;
}
});
if (mWebView!=null) {
authDialog.show();
}
}
}

View file

@ -0,0 +1,152 @@
/* 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 <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android.ui.dialog;
import com.actionbarsherlock.app.SherlockDialogFragment;
import com.owncloud.android.R;
import com.owncloud.android.authentication.AuthenticatorActivity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.InputType;
import android.view.WindowManager.LayoutParams;
import android.webkit.HttpAuthHandler;
import android.webkit.WebView;
import android.widget.EditText;
import android.widget.LinearLayout;
/**
* Dialog to input authentication credentials
*
*/
public class CredentialsDialogFragment extends SherlockDialogFragment
implements DialogInterface.OnClickListener {
private WebView mWebView = null;
private HttpAuthHandler mHandler = null;
private EditText mUsernameET;
private EditText mPasswordET;
private String mUsernameStr;
private String mPasswordStr;
/**
* Public factory method to create new CredentialsDialogFragment instances.
* @param webView WebView that is being loaded
* @param handler HttpAuthHandler
* @return Dialog ready to show
*/
public static CredentialsDialogFragment newInstanceForCredentials(WebView webView, HttpAuthHandler handler) {
if (handler == null) {
throw new IllegalArgumentException("Trying to create instance with parameter handler == null");
}
CredentialsDialogFragment frag = new CredentialsDialogFragment();
frag.mHandler = handler;
frag.mWebView = webView;
return frag;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Create field for username
mUsernameET = new EditText(getSherlockActivity());
mUsernameET.setHint(getSherlockActivity().getText(R.string.auth_username));
// Create field for password
mPasswordET = new EditText(getSherlockActivity());
mPasswordET.setHint(getSherlockActivity().getText(R.string.auth_password));
mPasswordET.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
// Prepare LinearLayout for dialog
LinearLayout ll = new LinearLayout(getSherlockActivity());
ll.setOrientation(LinearLayout.VERTICAL);
ll.addView(mUsernameET);
ll.addView(mPasswordET);
ll.requestFocus();
setRetainInstance(true);
Builder authDialog = new AlertDialog
.Builder(getSherlockActivity())
.setTitle(getSherlockActivity().getText(R.string.saml_authentication_required_text))
.setView(ll)
.setCancelable(false)
.setPositiveButton(R.string.common_ok, this)
.setNegativeButton(R.string.common_cancel, this);
Dialog d = authDialog.create();
d.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
return d;
}
@Override
public void onPause() {
super.onPause();
// Due to the use of setRetainInstance(true) for keep the dialog over the rest of dialogs,
// we need to save the inputs text for being injected in onResume()
mUsernameStr = mUsernameET.getText().toString();
mPasswordStr = mPasswordET.getText().toString();
}
@Override
public void onResume() {
super.onResume();
mUsernameET.setText(mUsernameStr);
mPasswordET.setText(mPasswordStr);
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == AlertDialog.BUTTON_POSITIVE) {
String username = mUsernameET.getText().toString().trim();
String password = mPasswordET.getText().toString().trim();
// Proceed with the authentication
mHandler.proceed(username, password);
dialog.dismiss();
} else if (which == AlertDialog.BUTTON_NEGATIVE) {
dialog.dismiss();
mWebView.stopLoading();
((AuthenticatorActivity)getActivity()).doNegativeAuthenticatioDialogClick();
}
}
@Override
public void onDestroyView() {
if (getDialog() != null && getRetainInstance())
getDialog().setDismissMessage(null);
super.onDestroyView();
}
}