Move Shibboleth WebView to a big Dialog
authormasensio <masensio@solidgear.es>
Tue, 13 Aug 2013 11:28:45 +0000 (13:28 +0200)
committermasensio <masensio@solidgear.es>
Tue, 13 Aug 2013 11:28:45 +0000 (13:28 +0200)
1  2 
src/com/owncloud/android/authentication/AuthenticatorActivity.java
src/com/owncloud/android/ui/dialog/SamlWebViewDialog.java

  \r
  package com.owncloud.android.authentication;\r
  \r
 -import com.owncloud.android.Log_OC;\r
 -import com.owncloud.android.ui.dialog.SslValidatorDialog;\r
 -import com.owncloud.android.ui.dialog.SslValidatorDialog.OnSslValidatorListener;\r
 -import com.owncloud.android.utils.OwnCloudVersion;\r
 -import com.owncloud.android.authentication.SsoWebViewClient.SsoWebViewClientListener;\r
 -import com.owncloud.android.network.OwnCloudClientUtils;\r
 -import com.owncloud.android.operations.OwnCloudServerCheckOperation;\r
 -import com.owncloud.android.operations.ExistenceCheckOperation;\r
 -import com.owncloud.android.operations.OAuth2GetAccessToken;\r
 -import com.owncloud.android.operations.OnRemoteOperationListener;\r
 -import com.owncloud.android.operations.RemoteOperation;\r
 -import com.owncloud.android.operations.RemoteOperationResult;\r
 -import com.owncloud.android.operations.RemoteOperationResult.ResultCode;\r
 -\r
  import android.accounts.Account;\r
 -import android.accounts.AccountAuthenticatorActivity;\r
  import android.accounts.AccountManager;\r
 -import android.annotation.SuppressLint;\r
  import android.app.AlertDialog;\r
  import android.app.Dialog;\r
  import android.app.ProgressDialog;\r
@@@ -33,7 -49,6 +33,6 @@@ import android.net.Uri
  import android.os.Bundle;\r
  import android.os.Handler;\r
  import android.preference.PreferenceManager;\r
- import android.support.v4.app.FragmentManager;\r
  import android.text.Editable;\r
  import android.text.InputType;\r
  import android.text.TextWatcher;\r
@@@ -44,27 -59,17 +43,28 @@@ import android.view.View.OnFocusChangeL
  import android.view.View.OnTouchListener;\r
  import android.view.Window;\r
  import android.view.inputmethod.EditorInfo;\r
 -import android.webkit.CookieManager;\r
 -import android.webkit.WebSettings;\r
 -import android.webkit.WebView;\r
 +import android.widget.Button;\r
  import android.widget.CheckBox;\r
  import android.widget.EditText;\r
 -import android.widget.Button;\r
  import android.widget.TextView;\r
 -import android.widget.Toast;\r
  import android.widget.TextView.OnEditorActionListener;\r
 +import android.widget.Toast;\r
  \r
 +import com.owncloud.android.Log_OC;\r
  import com.owncloud.android.R;\r
++import com.owncloud.android.authentication.SsoWebViewClient.SsoWebViewClientListener;\r
 +import com.owncloud.android.network.OwnCloudClientUtils;\r
 +import com.owncloud.android.operations.ExistenceCheckOperation;\r
 +import com.owncloud.android.operations.OAuth2GetAccessToken;\r
 +import com.owncloud.android.operations.OnRemoteOperationListener;\r
 +import com.owncloud.android.operations.OwnCloudServerCheckOperation;\r
 +import com.owncloud.android.operations.RemoteOperation;\r
 +import com.owncloud.android.operations.RemoteOperationResult;\r
 +import com.owncloud.android.operations.RemoteOperationResult.ResultCode;\r
 +import com.owncloud.android.ui.dialog.SamlWebViewDialog;\r
 +import com.owncloud.android.ui.dialog.SslValidatorDialog;\r
 +import com.owncloud.android.ui.dialog.SslValidatorDialog.OnSslValidatorListener;\r
 +import com.owncloud.android.utils.OwnCloudVersion;\r
  \r
  import eu.alefzero.webdav.WebdavClient;\r
  \r
@@@ -75,7 -80,7 +75,7 @@@
   * @author David A. Velasco\r
   */\r
  public class AuthenticatorActivity extends AccountAuthenticatorActivity\r
- implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeListener, OnEditorActionListener {\r
 -implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeListener, OnEditorActionListener, SsoWebViewClientListener {\r
++implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeListener, OnEditorActionListener, SsoWebViewClientListener{\r
  \r
      private static final String TAG = AuthenticatorActivity.class.getSimpleName();\r
  \r
      public static final byte ACTION_CREATE = 0;\r
      public static final byte ACTION_UPDATE_TOKEN = 1;\r
  \r
 +    private static final String TAG_SAML_DIALOG = "samlWebViewDialog";\r
 +    \r
      private String mHostBaseUrl;\r
      private OwnCloudVersion mDiscoveredVersion;\r
  \r
      private TextView mOAuthTokenEndpointText;\r
      \r
      private TextView mAccountNameInput;\r
 -    private WebView mSsoWebView;\r
 -    private SsoWebViewClient mWebViewClient;\r
 +    private SamlWebViewDialog mSamlDialog;\r
      \r
      private View mOkButton;\r
      \r
          mOAuthTokenEndpointText = (TextView)findViewById(R.id.oAuthEntryPoint_2);\r
          mOAuth2Check = (CheckBox) findViewById(R.id.oauth_onOff_check);\r
          mAccountNameInput = (EditText) findViewById(R.id.account_name);\r
 -        mSsoWebView = (WebView) findViewById(R.id.web_sso_view);\r
          mOkButton = findViewById(R.id.buttonOK);\r
          mAuthStatusLayout = (TextView) findViewById(R.id.auth_status_text); \r
          \r
                  mHostUrlInput.setText(mHostBaseUrl);\r
              }\r
              initAuthorizationMethod();  // checks intent and setup.xml to determine mCurrentAuthorizationMethod\r
-             mOAuth2Check.setChecked(mCurrentAuthTokenType == AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN);\r
              mJustCreated = true;\r
              \r
              if (mAction == ACTION_UPDATE_TOKEN || !mHostUrlInputEnabled) {\r
              mCurrentAuthTokenType = savedInstanceState.getString(AccountAuthenticator.KEY_AUTH_TOKEN_TYPE);\r
              if (mCurrentAuthTokenType == null) {\r
                  mCurrentAuthTokenType =  AccountAuthenticator.AUTH_TOKEN_TYPE_PASSWORD;\r
 -            } else if (AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(mCurrentAuthTokenType)) {\r
 -                restoreWebView(savedInstanceState);\r
+                 \r
              }\r
  \r
              // check if server check was interrupted by a configuration change\r
          if (mServerIsChecked && !mServerIsValid && refreshButtonEnabled) showRefreshButton();\r
          mOkButton.setEnabled(mServerIsValid); // state not automatically recovered in configuration changes\r
  \r
-         if (mCurrentAuthTokenType == AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE || \r
+         if (AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(mCurrentAuthTokenType) || \r
                  !AUTH_OPTIONAL.equals(getString(R.string.auth_method_oauth2))) {\r
              mOAuth2Check.setVisibility(View.GONE);\r
          }\r
              }\r
          });\r
          \r
- //        FragmentManager fm = getSupportFragmentManager();\r
- //\r
- //     // try to find searching by tag name\r
- //      mSamlDialog = (SamlWebViewDialog) fm.findFragmentByTag(TAG_SAML_DIALOG);\r
- //\r
- //     if (mSamlDialog != null) {\r
- //         mSamlDialog.show(fm, TAG_SAML_DIALOG);\r
- //         Log_OC.d(TAG_SAML_DIALOG,  "mSamlDialog not null");\r
- //     }\r
      }\r
      \r
 -    @SuppressLint("SetJavaScriptEnabled")\r
 -      private void initWebView() {\r
 -        CookieManager cookieManager = CookieManager.getInstance();\r
 -        cookieManager.setAcceptCookie(true);\r
 -        cookieManager.removeAllCookie();\r
 -\r
 -        mWebViewClient = new SsoWebViewClient(mHandler, this);\r
 -        mSsoWebView.setWebViewClient(mWebViewClient);\r
 -        WebSettings webSettings = mSsoWebView.getSettings();\r
 -        webSettings.setJavaScriptEnabled(true);\r
 -        webSettings.setBuiltInZoomControls(true);\r
 -        webSettings.setLoadWithOverviewMode(false);\r
 -        webSettings.setSavePassword(false);\r
 -        webSettings.setUserAgentString(WebdavClient.USER_AGENT);\r
 -    }\r
 -\r
 -    @SuppressLint("SetJavaScriptEnabled")\r
 -    private void restoreWebView(Bundle savedInstanceState) {\r
 -        mSsoWebView.restoreState(savedInstanceState);\r
 -        \r
 -        CookieManager cookieManager = CookieManager.getInstance();\r
 -        Log_OC.e(TAG, "Accept Cookie: " + cookieManager.acceptCookie());\r
 -\r
 -        mWebViewClient = new SsoWebViewClient(mHandler, this);\r
 -        mSsoWebView.setWebViewClient(mWebViewClient);\r
 -        mWebViewClient.setTargetUrl(mHostBaseUrl + AccountUtils.getWebdavPath(mDiscoveredVersion, mCurrentAuthTokenType));\r
 -        \r
 -        WebSettings webSettings = mSsoWebView.getSettings();\r
 -        webSettings.setJavaScriptEnabled(true);     // at least this one is not being kept by WebView#restoreState\r
 -        webSettings.setBuiltInZoomControls(true);\r
 -        webSettings.setLoadWithOverviewMode(false);\r
 -        webSettings.setSavePassword(false);\r
 -        webSettings.setUserAgentString(WebdavClient.USER_AGENT);\r
 -    }\r
++   \r
  \r
      private void initAuthorizationMethod() {\r
          boolean oAuthRequired = false;\r
              String userName = mAccount.name.substring(0, mAccount.name.lastIndexOf('@'));\r
              mUsernameInput.setText(userName);\r
          }\r
 -        if (AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(mCurrentAuthTokenType)) {\r
 -            initWebView();\r
 -        }\r
+         \r
+         mOAuth2Check.setChecked(AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN.equals(mCurrentAuthTokenType));\r
+         \r
      }\r
  \r
      /**\r
              outState.putParcelable(KEY_ACCOUNT, mAccount);\r
          }\r
          outState.putString(AccountAuthenticator.KEY_AUTH_TOKEN_TYPE, mCurrentAuthTokenType);\r
 -        if (AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(mCurrentAuthTokenType)) {\r
 -            mSsoWebView.saveState(outState);\r
 -        }\r
          \r
          // refresh button enabled\r
          outState.putBoolean(KEY_REFRESH_BUTTON_ENABLED, (mRefreshButton.getVisibility() == View.VISIBLE));\r
 +        \r
  \r
      }\r
  \r
          }\r
  \r
          mJustCreated = false;\r
\r
-         // try to find searching by tag name\r
- //        FragmentManager fm = getSupportFragmentManager();\r
- //         mSamlDialog = (SamlWebViewDialog) fm.findFragmentByTag(TAG_SAML_DIALOG);\r
- //\r
- //        if (mSamlDialog != null) {\r
- //         //   mSamlDialog.show(fm, TAG_SAML_DIALOG);\r
- //            mSamlDialog.setRetainInstance(true);\r
- //        }\r
 +        \r
      }\r
  \r
  \r
          } catch (IllegalArgumentException e) {\r
              // NOTHING TO DO ; can't find out what situation that leads to the exception in this code, but user logs signal that it happens\r
          }\r
 -\r
 +        \r
          if (result.isTemporalRedirection()) {\r
              String url = result.getRedirectedLocation();\r
 -            mWebViewClient.setTargetUrl(mHostBaseUrl + AccountUtils.getWebdavPath(mDiscoveredVersion, mCurrentAuthTokenType));\r
 -            mSsoWebView.loadUrl(url);\r
 +            String targetUrl = mHostBaseUrl + AccountUtils.getWebdavPath(mDiscoveredVersion, mCurrentAuthTokenType);\r
 +            \r
 +            // Show dialog\r
-             mSamlDialog = SamlWebViewDialog.newInstance(mHandler, url, targetUrl);            \r
++            mSamlDialog = SamlWebViewDialog.newInstance(url, targetUrl);            \r
 +            mSamlDialog.show(getSupportFragmentManager(), TAG_SAML_DIALOG);\r
              \r
              mAuthStatusIcon = android.R.drawable.ic_secure;\r
              mAuthStatusText = R.string.auth_follow_auth_server;\r
              mUsernameInput.setVisibility(View.GONE);\r
              mPasswordInput.setVisibility(View.GONE);\r
              mAccountNameInput.setVisibility(View.GONE);\r
 -            mSsoWebView.setVisibility(View.GONE);\r
              \r
          } else if (AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(mCurrentAuthTokenType)) {\r
              // SAML-based web Single Sign On\r
              mUsernameInput.setVisibility(View.GONE);\r
              mPasswordInput.setVisibility(View.GONE);\r
              mAccountNameInput.setVisibility(View.VISIBLE);\r
 -            mSsoWebView.setVisibility(View.VISIBLE);\r
--            \r
          } else {\r
              // basic HTTP authorization\r
              mOAuthAuthEndpointText.setVisibility(View.GONE);\r
              mUsernameInput.setVisibility(View.VISIBLE);\r
              mPasswordInput.setVisibility(View.VISIBLE);\r
              mAccountNameInput.setVisibility(View.GONE);\r
 -            mSsoWebView.setVisibility(View.GONE);\r
          }\r
      }\r
      \r
      }\r
  \r
  \r
 -        \r
 +    public void onSamlDialogSuccess(String sessionCookie){\r
 +        mAuthToken = sessionCookie;\r
 +        \r
 +        if (sessionCookie != null && sessionCookie.length() > 0) {\r
 +          Log_OC.d(TAG, "Successful SSO - time to save the account");\r
 +          mAuthToken = sessionCookie;\r
 +          if (mAction == ACTION_CREATE) {\r
 +              createAccount();\r
 +\r
 +          } else {\r
 +              updateToken();\r
 +          }\r
 +\r
 +          finish();\r
 +\r
 +      }\r
 +    }\r
 +\r
++\r
++\r
+     @Override\r
+     public void onSsoFinished(String sessionCookie) {\r
+         //Toast.makeText(this, "got cookies: " + sessionCookie, Toast.LENGTH_LONG).show();\r
 -            mAuthToken = sessionCookie;\r
 -            if (mAction == ACTION_CREATE) {\r
 -                createAccount();\r
 -\r
 -            } else {\r
 -                updateToken();\r
 -            }\r
 -\r
++\r
+         if (sessionCookie != null && sessionCookie.length() > 0) {\r
+             Log_OC.d(TAG, "Successful SSO - time to save the account");\r
++            onSamlDialogSuccess(sessionCookie);\r
+             finish();\r
\r
+         } else { \r
+             // TODO - show fail\r
+             Log_OC.d(TAG, "SSO failed");\r
+         }\r
+     }\r
++    \r
++    \r
\r
  }\r
index 2d0ac94,0000000..17a1e13
mode 100644,000000..100644
--- /dev/null
@@@ -1,150 -1,0 +1,153 @@@
- import com.owncloud.android.authentication.AuthenticatorActivity;
 +package com.owncloud.android.ui.dialog;
 +
 +import android.annotation.SuppressLint;
++import android.app.Activity;
 +import android.app.AlertDialog;
 +import android.app.Dialog;
 +import android.os.Bundle;
 +import android.os.Handler;
 +import android.support.v4.app.DialogFragment;
 +import android.webkit.CookieManager;
 +import android.webkit.WebSettings;
 +import android.webkit.WebView;
 +
 +import com.owncloud.android.Log_OC;
-                                implements SsoWebViewClientListener{
 +import com.owncloud.android.authentication.SsoWebViewClient;
 +import com.owncloud.android.authentication.SsoWebViewClient.SsoWebViewClientListener;
 +
 +import eu.alefzero.webdav.WebdavClient;
 +
 +/**
 + * Dialog to show the WebView for SAML Authentication
 + * 
 + * @author Maria Asensio
 + */
 +public class SamlWebViewDialog extends DialogFragment
-     private static Handler mHandler;
++                              {
 +
 +    public final String SAML_DIALOG_TAG = "SamlWebViewDialog";
 +    
 +    private final static String TAG =  SamlWebViewDialog.class.getSimpleName();
 +    
 +    private WebView mSsoWebView;
 +    private SsoWebViewClient mWebViewClient;
 +    
 +    private static String mUrl;
 +    private static String mTargetUrl;
 +    
-     public static SamlWebViewDialog newInstance(Handler handler,String url, String targetUrl) {
++    private Handler mHandler;
++
++    private SsoWebViewClientListener mSsoWebViewClientListener;
 +    
 +
 +    /**
 +     * Public factory method to get dialog instances.
 +     * 
 +     * @param handler
 +     * @param Url           Url to open at WebView
 +     * @param targetURL     mHostBaseUrl + AccountUtils.getWebdavPath(mDiscoveredVersion, mCurrentAuthTokenType)
 +     * @return              New dialog instance, ready to show.
 +     */
-         mHandler = handler;
++    public static SamlWebViewDialog newInstance(String url, String targetUrl) {
 +        SamlWebViewDialog fragment = new SamlWebViewDialog();
-     @Override
++        
 +        mUrl = url;
 +        mTargetUrl = targetUrl;
 +        return fragment;
 +    }
 +    
 +    
 +    @Override
 +    public void onSaveInstanceState(Bundle outState) {
 +        super.onSaveInstanceState(outState);
 +        
 +        // Save the state of the WebView
 +        mSsoWebView.saveState(outState);
 +    }
 +
-         /// load the dialog
-         initWebView(savedInstanceState);
-         setRetainInstance(true);
-         /// build the dialog
-         AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
++    @SuppressLint("SetJavaScriptEnabled")
++      @Override
 +    public Dialog onCreateDialog(Bundle savedInstanceState) {
 +        Log_OC.d(TAG, "On Create Dialog");
 +
-     
++        mHandler = new Handler();
++        
++        mSsoWebView = new WebView(getActivity()) {
++            @Override
++            public boolean onCheckIsTextEditor() {
++                return true; 
++            }            
++        };
++
++        
++        mWebViewClient = new SsoWebViewClient(mHandler, mSsoWebViewClientListener);
++        mSsoWebView.setWebViewClient(mWebViewClient);
++        mWebViewClient.setTargetUrl(mTargetUrl);
++        
++        mSsoWebView.setFocusable(true);
++        mSsoWebView.setFocusableInTouchMode(true);
++        mSsoWebView.setClickable(true);
++        
++        WebSettings webSettings = mSsoWebView.getSettings();
++        webSettings.setJavaScriptEnabled(true);
++        webSettings.setBuiltInZoomControls(true);
++        webSettings.setLoadWithOverviewMode(false);
++        webSettings.setSavePassword(false);
++        webSettings.setUserAgentString(WebdavClient.USER_AGENT);
++        
++        // load the dialog
++        if (savedInstanceState == null) {            
++            initWebView();
++        }
++        else  {
++            restoreWebView(savedInstanceState);
++        }
 +        
++        // build the dialog
++        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
 +        Dialog dialog = builder.setView(mSsoWebView).create();
 +        
 +        return dialog;
 +    }
 +
-     private void initWebView(Bundle savedInstanceState) {
 +    @SuppressLint("SetJavaScriptEnabled")
-         //cookieManager.removeSessionCookie();        
++    private void initWebView() {
 +        CookieManager cookieManager = CookieManager.getInstance();
 +        cookieManager.setAcceptCookie(true);
-         mWebViewClient = new SsoWebViewClient(mHandler, this);
-         mWebViewClient.setTargetUrl(mTargetUrl);
-         if (savedInstanceState == null) {
-             
-             Log_OC.d(TAG, "Saved Instance State NULL");
-             mSsoWebView = new WebView(getActivity()) {
-                 @Override
-                 public boolean onCheckIsTextEditor() {
-                     return true; 
-                 }            
-             };
-             
-             mSsoWebView.setWebViewClient(mWebViewClient);
-             mSsoWebView.setFocusable(true);
-             mSsoWebView.setFocusableInTouchMode(true);
-             mSsoWebView.setClickable(true);
-             
-             WebSettings webSettings = mSsoWebView.getSettings();
-             webSettings.setJavaScriptEnabled(true);
-             webSettings.setBuiltInZoomControls(true);
-             webSettings.setLoadWithOverviewMode(false);
-             webSettings.setSavePassword(false);
-             webSettings.setUserAgentString(WebdavClient.USER_AGENT);
-             
-             mSsoWebView.loadUrl(mUrl);
-         }
-         else {
-             Log_OC.d(TAG, "Saved Instance State NOT NULL");
-             
-             mSsoWebView.restoreState(savedInstanceState);
-         }
-         
++        cookieManager.removeAllCookie();
 +
-     public void onSsoFinished(String sessionCookie) {
-         //Toast.makeText(this, "got cookies: " + sessionCookie, Toast.LENGTH_LONG).show();
-         if (sessionCookie != null && sessionCookie.length() > 0) {
-             Log_OC.d(TAG, "Successful SSO - time to save the account");
-             ((AuthenticatorActivity) getActivity()).onSamlDialogSuccess(sessionCookie);
-             dismiss();
-         } else { 
-             // TODO - show fail
-             Log_OC.d(TAG, "SSO failed");
++        mSsoWebView.loadUrl(mUrl);
 +    }
 +
++    @SuppressLint("SetJavaScriptEnabled")
++    private void restoreWebView(Bundle savedInstanceState) {
++        mSsoWebView.restoreState(savedInstanceState);
++        
++        CookieManager cookieManager = CookieManager.getInstance();
++        Log_OC.e(TAG, "Accept Cookie: " + cookieManager.acceptCookie());
++    }
++    
++    
 +    @Override
 +    public void onDestroyView() {
 +        Dialog dialog = getDialog();
 +        Log_OC.d(TAG, "On Destroy");
 +        // Work around bug: http://code.google.com/p/android/issues/detail?id=17423
 +        if ((dialog != null) && getRetainInstance())
 +            getDialog().setOnDismissListener(null);
 +
 +        super.onDestroyView();
 +    }
 +
 +
 +    @Override
-     
++    public void onAttach(Activity activity) {
++        super.onAttach(activity);
++        Log_OC.e(TAG, "onAttach");
++        try {
++            mSsoWebViewClientListener = (SsoWebViewClientListener) activity;
++        } catch (ClassCastException e) {
++            throw new ClassCastException(activity.toString() + " must implement " + SsoWebViewClientListener.class.getSimpleName());
 +        }
 +    }
 +}