Ssl-error dialogs joint in a single one that uses different adapters to update its...
authorDavid A. Velasco <dvelasco@solidgear.es>
Tue, 11 Mar 2014 10:39:19 +0000 (11:39 +0100)
committerDavid A. Velasco <dvelasco@solidgear.es>
Tue, 11 Mar 2014 10:39:19 +0000 (11:39 +0100)
src/com/owncloud/android/authentication/AuthenticatorActivity.java
src/com/owncloud/android/authentication/SsoWebViewClient.java
src/com/owncloud/android/ui/activity/FileDisplayActivity.java
src/com/owncloud/android/ui/adapter/CertificateCombinedExceptionViewAdapter.java [new file with mode: 0644]
src/com/owncloud/android/ui/adapter/SslCertificateViewAdapter.java [new file with mode: 0644]
src/com/owncloud/android/ui/adapter/SslErrorViewAdapter.java [new file with mode: 0644]
src/com/owncloud/android/ui/adapter/X509CertificateViewAdapter.java [new file with mode: 0644]
src/com/owncloud/android/ui/dialog/SslUntrustedCertDialog.java
src/com/owncloud/android/ui/dialog/SslUntrustedCertDialogABSTRACT.java [deleted file]
src/com/owncloud/android/ui/dialog/SslUntrustedCertDialogForEmptySslError.java [deleted file]

index f18ff2a..2fabc33 100644 (file)
@@ -48,6 +48,7 @@ import android.view.View.OnFocusChangeListener;
 import android.view.View.OnTouchListener;\r
 import android.view.Window;\r
 import android.view.inputmethod.EditorInfo;\r
+import android.webkit.SslErrorHandler;\r
 import android.widget.Button;\r
 import android.widget.CheckBox;\r
 import android.widget.EditText;\r
@@ -64,6 +65,7 @@ import com.owncloud.android.lib.common.OwnCloudClientFactory;
 import com.owncloud.android.lib.common.OwnCloudClient;\r
 import com.owncloud.android.operations.OAuth2GetAccessToken;\r
 
+import com.owncloud.android.lib.common.network.CertificateCombinedException;\r
 import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;\r
 import com.owncloud.android.lib.resources.status.GetRemoteStatusOperation;\r
 import com.owncloud.android.lib.common.operations.RemoteOperation;\r
@@ -75,7 +77,6 @@ import com.owncloud.android.lib.resources.users.GetRemoteUserNameOperation;
 import com.owncloud.android.ui.dialog.SamlWebViewDialog;\r
 import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;\r
 import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.OnSslUntrustedCertListener;\r
-import com.owncloud.android.ui.dialog.SslValidatorDialog.OnSslValidatorListener;\r
 import com.owncloud.android.utils.Log_OC;\r
 import com.owncloud.android.lib.resources.status.OwnCloudVersion;\r
 \r
@@ -86,7 +87,7 @@ import com.owncloud.android.lib.resources.status.OwnCloudVersion;
  * @author David A. Velasco\r
  */\r
 public class AuthenticatorActivity extends AccountAuthenticatorActivity\r
-    implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeListener, OnEditorActionListener, \r
+    implements  OnRemoteOperationListener, OnFocusChangeListener, OnEditorActionListener, \r
     SsoWebViewClientListener, OnSslUntrustedCertListener {\r
 \r
     private static final String TAG = AuthenticatorActivity.class.getSimpleName();\r
@@ -1530,26 +1531,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
     }\r
     \r
     /**\r
-     * Called from SslValidatorDialog when a new server certificate was correctly saved.\r
-     */\r
-    public void onSavedCertificate() {\r
-        checkOcServer();\r
-        reloadWebView();\r
-        \r
-    }\r
-\r
-    /**\r
-     * Called from SslValidatorDialog when a new server certificate could not be saved \r
-     * when the user requested it.\r
-     */\r
-    @Override\r
-    public void onFailedSavingCertificate() {\r
-        showDialog(DIALOG_CERT_NOT_SAVED);\r
-        cancelWebView();\r
-    }\r
-\r
-\r
-    /**\r
      *  Called when the 'action' button in an IME is pressed ('enter' in software keyboard).\r
      * \r
      *  Used to trigger the authentication check when the user presses 'enter' after writing the password, \r
@@ -1665,40 +1646,20 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
     }\r
 \r
 \r
-\r
-    public void cancelWebView() {\r
-        Fragment fd = getSupportFragmentManager().findFragmentByTag(TAG_SAML_DIALOG);\r
-        if (fd != null && fd instanceof SherlockDialogFragment) {\r
-            Dialog d = ((SherlockDialogFragment)fd).getDialog();\r
-            if (d != null && d.isShowing()) {\r
-                d.dismiss();\r
-            }\r
-        }\r
-        \r
-    }\r
-\r
-    public void reloadWebView() {\r
-        Fragment fd = getSupportFragmentManager().findFragmentByTag(TAG_SAML_DIALOG);\r
-        if (fd != null && fd instanceof SamlWebViewDialog) {\r
-                ((SamlWebViewDialog) fd).reloadWebView();\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public void onCancelCertificate() {\r
-        cancelWebView();\r
-    }\r
-    \r
     /**\r
      * Show untrusted cert dialog \r
      */\r
-    public void showUntrustedCertDialog(X509Certificate x509Certificate, SslError error) {\r
+    public void showUntrustedCertDialog(X509Certificate x509Certificate, SslError error, SslErrorHandler handler) {\r
         // Show a dialog with the certificate info\r
-        SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstance(x509Certificate, error);\r
+        SslUntrustedCertDialog dialog = null;\r
+        if (x509Certificate == null) {\r
+            dialog = SslUntrustedCertDialog.newInstanceForEmptySslError(error, handler);\r
+        } else {\r
+            dialog = SslUntrustedCertDialog.newInstanceForFullSslError(x509Certificate, error, handler);\r
+        }\r
         FragmentManager fm = getSupportFragmentManager();\r
         FragmentTransaction ft = fm.beginTransaction();\r
         dialog.show(ft, DIALOG_UNTRUSTED_CERT);\r
-        \r
     }\r
     \r
     /**\r
@@ -1706,7 +1667,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
      */\r
     public void showUntrustedCertDialog(RemoteOperationResult result) {\r
         // Show a dialog with the certificate info\r
-        SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstance(result, this);\r
+        SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstanceForFullSslError((CertificateCombinedException)result.getException());\r
         FragmentManager fm = getSupportFragmentManager();\r
         FragmentTransaction ft = fm.beginTransaction();\r
         dialog.show(ft, DIALOG_UNTRUSTED_CERT);\r
@@ -1717,11 +1678,57 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
      * Dismiss untrusted cert dialog\r
      */\r
     public void dismissUntrustedCertDialog(){\r
-        Fragment frag = getSupportFragmentManager().findFragmentByTag(DIALOG_UNTRUSTED_CERT);\r
+        /*Fragment frag = getSupportFragmentManager().findFragmentByTag(DIALOG_UNTRUSTED_CERT);\r
         if (frag != null) {\r
-            SslUntrustedCertDialog dialog = (SslUntrustedCertDialog) frag;\r
+            SslErrorViewAdapter dialog = (SslErrorViewAdapter) frag;\r
             dialog.dismiss();\r
         }\r
+        */\r
+    }\r
+    \r
+    /**\r
+     * Called from SslValidatorDialog when a new server certificate was correctly saved.\r
+     */\r
+    public void onSavedCertificate() {\r
+        Fragment fd = getSupportFragmentManager().findFragmentByTag(TAG_SAML_DIALOG);\r
+        if (fd == null) {\r
+            // if SAML dialog is not shown, the SslDialog was shown due to an SSL error in the server check\r
+            checkOcServer();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Called from SslValidatorDialog when a new server certificate could not be saved \r
+     * when the user requested it.\r
+     */\r
+    @Override\r
+    public void onFailedSavingCertificate() {\r
+        showDialog(DIALOG_CERT_NOT_SAVED);\r
+        cancelWebView();\r
+    }\r
+\r
+    @Override\r
+    public void onCancelCertificate() {\r
+        cancelWebView();\r
     }\r
     \r
+\r
+    public void cancelWebView() {\r
+        Fragment fd = getSupportFragmentManager().findFragmentByTag(TAG_SAML_DIALOG);\r
+        if (fd != null && fd instanceof SherlockDialogFragment) {\r
+            Dialog d = ((SherlockDialogFragment)fd).getDialog();\r
+            if (d != null && d.isShowing()) {\r
+                d.dismiss();\r
+            }\r
+        }\r
+        \r
+    }\r
+\r
+    public void reloadWebView() {\r
+        Fragment fd = getSupportFragmentManager().findFragmentByTag(TAG_SAML_DIALOG);\r
+        if (fd != null && fd instanceof SamlWebViewDialog) {\r
+                ((SamlWebViewDialog) fd).reloadWebView();\r
+        }\r
+    }\r
+\r
 }\r
index 89f66ef..27e1f5b 100644 (file)
@@ -25,8 +25,6 @@ import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 
 import com.owncloud.android.lib.common.network.NetworkUtils;
-import com.actionbarsherlock.app.SherlockFragmentActivity;
-import com.owncloud.android.ui.dialog.SslUntrustedCertDialogABSTRACT;
 import com.owncloud.android.utils.Log_OC;
 
 import android.content.Context;
@@ -36,8 +34,6 @@ import android.net.http.SslError;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentTransaction;
 import android.view.KeyEvent;
 import android.view.View;
 import android.webkit.CookieManager;
@@ -168,17 +164,8 @@ public class SsoWebViewClient extends WebViewClient {
         
          if (isKnownServer) {
              handler.proceed();
-         } else if (x509Certificate != null) {
-             // Show a dialog with the certificate info
-             ((AuthenticatorActivity)mContext).showUntrustedCertDialog(x509Certificate, error);
-             handler.cancel();
          } else {
-             // Show a dialog with the certificate information available in SslError (not full)
-             SslUntrustedCertDialogABSTRACT dialog = SslUntrustedCertDialogABSTRACT.newInstanceForEmptySslError(error, handler);
-             FragmentManager fm = ((SherlockFragmentActivity)mContext).getSupportFragmentManager();
-             FragmentTransaction ft = fm.beginTransaction();
-             dialog.show(ft, AuthenticatorActivity.DIALOG_UNTRUSTED_CERT);
-             // let's forward the handler, and see what happens...
+             ((AuthenticatorActivity)mContext).showUntrustedCertDialog(x509Certificate, error, handler);
          }
     }
     
index e246c4f..4593e3f 100644 (file)
@@ -67,6 +67,7 @@ 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.network.CertificateCombinedException;
 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;
@@ -78,6 +79,7 @@ import com.owncloud.android.operations.SynchronizeFolderOperation;
 import com.owncloud.android.operations.UnshareLinkOperation;
 import com.owncloud.android.services.OperationsService;
 import com.owncloud.android.syncadapter.FileSyncAdapter;
+import com.owncloud.android.ui.adapter.SslErrorViewAdapter;
 import com.owncloud.android.ui.dialog.EditNameDialog;
 import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
 import com.owncloud.android.ui.dialog.EditNameDialog.EditNameDialogListener;
@@ -1312,6 +1314,10 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
         showDialog(DIALOG_CERT_NOT_SAVED);
     }
 
+    @Override
+    public void onCancelCertificate() {
+        // nothing to do
+    }
 
     /**
      * Updates the view associated to the activity after the finish of some operation over files
@@ -1607,31 +1613,13 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
      */
     public void showUntrustedCertDialog(RemoteOperationResult result) {
         // Show a dialog with the certificate info
-        SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstance(result, this);
+        SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstanceForFullSslError((CertificateCombinedException)result.getException());
         FragmentManager fm = getSupportFragmentManager();
         FragmentTransaction ft = fm.beginTransaction();
         dialog.show(ft, DIALOG_UNTRUSTED_CERT);
-        
     }
     
     /**
-     * Dismiss untrusted cert dialog
-     */
-    public void dismissUntrustedCertDialog(){
-        Fragment frag = getSupportFragmentManager().findFragmentByTag(DIALOG_UNTRUSTED_CERT);
-        if (frag != null) {
-            SslUntrustedCertDialog dialog = (SslUntrustedCertDialog) frag;
-            dialog.dismiss();
-        }
-    }
-
-    @Override
-    public void onCancelCertificate() {
-        // TODO Auto-generated method stub
-        
-    }
-
-    /**
      * Requests the download of the received {@link OCFile} , updates the UI
      * to monitor the download progress and prepares the activity to send the file
      * when the download finishes.
diff --git a/src/com/owncloud/android/ui/adapter/CertificateCombinedExceptionViewAdapter.java b/src/com/owncloud/android/ui/adapter/CertificateCombinedExceptionViewAdapter.java
new file mode 100644 (file)
index 0000000..54fa8aa
--- /dev/null
@@ -0,0 +1,75 @@
+/* ownCloud Android client application
+ *   Copyright (C) 2012-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.adapter;
+
+import com.owncloud.android.R;
+import com.owncloud.android.lib.common.network.CertificateCombinedException;
+import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
+import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.ErrorViewAdapter;
+
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * TODO
+ * 
+ * @author masensio
+ * @author David A. Velasco
+ *
+ */
+public class CertificateCombinedExceptionViewAdapter implements SslUntrustedCertDialog.ErrorViewAdapter {
+    
+    //private final static String TAG = CertificateCombinedExceptionViewAdapter.class.getSimpleName();
+    
+    private CertificateCombinedException mSslException = null;
+    
+    public CertificateCombinedExceptionViewAdapter(CertificateCombinedException sslException) {
+        mSslException = sslException;
+    }
+    
+    @Override
+    public void updateErrorView(View dialogView) {
+        /// clean
+        dialogView.findViewById(R.id.reason_no_info_about_error).setVisibility(View.GONE);
+       
+        /// refresh
+        if (mSslException.getCertPathValidatorException() != null) {
+            ((TextView)dialogView.findViewById(R.id.reason_cert_not_trusted)).setVisibility(View.VISIBLE);
+        } else {
+            dialogView.findViewById(R.id.reason_cert_not_trusted).setVisibility(View.GONE);
+        }
+        
+        if (mSslException.getCertificateExpiredException() != null) {
+            ((TextView)dialogView.findViewById(R.id.reason_cert_expired)).setVisibility(View.VISIBLE);
+        } else {
+            dialogView.findViewById(R.id.reason_cert_expired).setVisibility(View.GONE);
+        }
+        
+        if (mSslException.getCertificateNotYetValidException() != null) {
+            ((TextView)dialogView.findViewById(R.id.reason_cert_not_yet_valid)).setVisibility(View.VISIBLE);
+        } else {
+            dialogView.findViewById(R.id.reason_cert_not_yet_valid).setVisibility(View.GONE);
+        }
+
+        if (mSslException.getSslPeerUnverifiedException() != null) {
+            ((TextView)dialogView.findViewById(R.id.reason_hostname_not_verified)).setVisibility(View.VISIBLE);
+        } else {
+            dialogView.findViewById(R.id.reason_hostname_not_verified).setVisibility(View.GONE);
+        }
+        
+    }
+}
diff --git a/src/com/owncloud/android/ui/adapter/SslCertificateViewAdapter.java b/src/com/owncloud/android/ui/adapter/SslCertificateViewAdapter.java
new file mode 100644 (file)
index 0000000..f470a60
--- /dev/null
@@ -0,0 +1,128 @@
+/* ownCloud Android client application
+ *   Copyright (C) 2012-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.adapter;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+import com.owncloud.android.R;
+import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
+import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.CertificateViewAdapter;
+
+import android.net.http.SslCertificate;
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * TODO
+ * 
+ * @author masensio
+ * @author David A. Velasco
+ */
+public class SslCertificateViewAdapter implements SslUntrustedCertDialog.CertificateViewAdapter {
+    
+    //private final static String TAG = SslCertificateViewAdapter.class.getSimpleName();
+    
+    private SslCertificate mCertificate;
+
+    
+    /**
+     * Constructor
+     * 
+     * @param 
+     */
+    public SslCertificateViewAdapter(SslCertificate certificate) {
+        mCertificate = certificate;
+    }
+
+    @Override
+    public void updateCertificateView(View dialogView) {
+        TextView nullCerView = (TextView) dialogView.findViewById(R.id.null_cert);
+        if (mCertificate != null) {
+            nullCerView.setVisibility(View.GONE);
+            showSubject(mCertificate.getIssuedTo(), dialogView);
+            showIssuer(mCertificate.getIssuedBy(), dialogView);
+            showValidity(mCertificate.getValidNotBeforeDate(), mCertificate.getValidNotAfterDate(), dialogView);
+            hideSignature(dialogView);
+            
+        } else {
+            nullCerView.setVisibility(View.VISIBLE);
+        }
+    }
+    
+    private void showValidity(Date notBefore, Date notAfter, View dialogView) {
+        TextView fromView = ((TextView)dialogView.findViewById(R.id.value_validity_from));
+        TextView toView = ((TextView)dialogView.findViewById(R.id.value_validity_to));
+        DateFormat dateFormat = DateFormat.getDateInstance();
+        fromView.setText(dateFormat.format(notBefore));
+        toView.setText(dateFormat.format(notAfter));
+    }
+
+    
+    private void showSubject(SslCertificate.DName subject, View dialogView) {
+        TextView cnView = ((TextView)dialogView.findViewById(R.id.value_subject_CN));
+        cnView.setText(subject.getCName());
+        cnView.setVisibility(View.VISIBLE);
+        
+        TextView oView = ((TextView)dialogView.findViewById(R.id.value_subject_O));
+        oView.setText(subject.getOName());
+        oView.setVisibility(View.VISIBLE);
+        
+        TextView ouView = ((TextView)dialogView.findViewById(R.id.value_subject_OU));
+        ouView.setText(subject.getUName());
+        ouView.setVisibility(View.VISIBLE);
+
+        // SslCertificates don't offer this information
+        ((TextView)dialogView.findViewById(R.id.value_subject_C)).setVisibility(View.GONE);
+        ((TextView)dialogView.findViewById(R.id.value_subject_ST)).setVisibility(View.GONE);
+        ((TextView)dialogView.findViewById(R.id.value_subject_L)).setVisibility(View.GONE);
+        ((TextView)dialogView.findViewById(R.id.label_subject_C)).setVisibility(View.GONE);
+        ((TextView)dialogView.findViewById(R.id.label_subject_ST)).setVisibility(View.GONE);
+        ((TextView)dialogView.findViewById(R.id.label_subject_L)).setVisibility(View.GONE);
+    }
+    
+    
+    private void showIssuer(SslCertificate.DName issuer, View dialogView) {
+        TextView cnView = ((TextView)dialogView.findViewById(R.id.value_issuer_CN));
+        cnView.setText(issuer.getCName());
+        cnView.setVisibility(View.VISIBLE);
+        
+        TextView oView = ((TextView)dialogView.findViewById(R.id.value_issuer_O));
+        oView.setText(issuer.getOName());
+        oView.setVisibility(View.VISIBLE);
+
+        TextView ouView = ((TextView)dialogView.findViewById(R.id.value_issuer_OU));
+        ouView.setText(issuer.getUName());
+        ouView.setVisibility(View.VISIBLE);
+        
+        // SslCertificates don't offer this information
+        ((TextView)dialogView.findViewById(R.id.value_issuer_C)).setVisibility(View.GONE);
+        ((TextView)dialogView.findViewById(R.id.value_issuer_ST)).setVisibility(View.GONE);
+        ((TextView)dialogView.findViewById(R.id.value_issuer_L)).setVisibility(View.GONE);
+        ((TextView)dialogView.findViewById(R.id.label_issuer_C)).setVisibility(View.GONE);
+        ((TextView)dialogView.findViewById(R.id.label_issuer_ST)).setVisibility(View.GONE);
+        ((TextView)dialogView.findViewById(R.id.label_issuer_L)).setVisibility(View.GONE);
+    }
+    
+    private void hideSignature(View dialogView) {
+        ((TextView)dialogView.findViewById(R.id.label_signature)).setVisibility(View.GONE);
+        ((TextView)dialogView.findViewById(R.id.label_signature_algorithm)).setVisibility(View.GONE);
+        ((TextView)dialogView.findViewById(R.id.value_signature_algorithm)).setVisibility(View.GONE);
+        ((TextView)dialogView.findViewById(R.id.value_signature)).setVisibility(View.GONE);
+    }
+
+}
diff --git a/src/com/owncloud/android/ui/adapter/SslErrorViewAdapter.java b/src/com/owncloud/android/ui/adapter/SslErrorViewAdapter.java
new file mode 100644 (file)
index 0000000..f0d5b2c
--- /dev/null
@@ -0,0 +1,75 @@
+/* ownCloud Android client application
+ *   Copyright (C) 2012-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.adapter;
+
+import com.owncloud.android.R;
+import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
+import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.ErrorViewAdapter;
+
+import android.net.http.SslError;
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * Dialog to show an Untrusted Certificate
+ * 
+ * @author masensio
+ * @author David A. Velasco
+ *
+ */
+public class SslErrorViewAdapter implements SslUntrustedCertDialog.ErrorViewAdapter {
+    
+    //private final static String TAG = SslErrorViewAdapter.class.getSimpleName();
+    
+    private SslError mSslError;
+    
+    public SslErrorViewAdapter(SslError sslError) {
+        mSslError = sslError;
+    }
+    
+    @Override
+    public void updateErrorView(View dialogView) {
+        /// clean
+        dialogView.findViewById(R.id.reason_no_info_about_error).setVisibility(View.GONE);
+        
+        /// refresh
+        if (mSslError.hasError(SslError.SSL_UNTRUSTED)) {
+            ((TextView)dialogView.findViewById(R.id.reason_cert_not_trusted)).setVisibility(View.VISIBLE);
+        } else {
+            dialogView.findViewById(R.id.reason_cert_not_trusted).setVisibility(View.GONE);
+        }
+        
+        if (mSslError.hasError(SslError.SSL_EXPIRED)) {
+            ((TextView)dialogView.findViewById(R.id.reason_cert_expired)).setVisibility(View.VISIBLE);
+        } else {
+            dialogView.findViewById(R.id.reason_cert_expired).setVisibility(View.GONE);
+        }
+        
+        if (mSslError.getPrimaryError() == SslError.SSL_NOTYETVALID) {
+            ((TextView)dialogView.findViewById(R.id.reason_cert_not_yet_valid)).setVisibility(View.VISIBLE);
+        } else {
+            dialogView.findViewById(R.id.reason_cert_not_yet_valid).setVisibility(View.GONE);
+        }
+        
+        if (mSslError.getPrimaryError() == SslError.SSL_IDMISMATCH) {
+            ((TextView)dialogView.findViewById(R.id.reason_hostname_not_verified)).setVisibility(View.VISIBLE);
+        } else {
+            dialogView.findViewById(R.id.reason_hostname_not_verified).setVisibility(View.GONE);
+        }
+    }
+
+}
diff --git a/src/com/owncloud/android/ui/adapter/X509CertificateViewAdapter.java b/src/com/owncloud/android/ui/adapter/X509CertificateViewAdapter.java
new file mode 100644 (file)
index 0000000..522f02f
--- /dev/null
@@ -0,0 +1,205 @@
+/* ownCloud Android client application
+ *   Copyright (C) 2012-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.adapter;
+
+import java.security.cert.X509Certificate;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.security.auth.x500.X500Principal;
+
+import com.owncloud.android.R;
+import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
+import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.CertificateViewAdapter;
+
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * 
+ * @author masensio
+ * @author David A. Velasco
+ *
+ */
+public class X509CertificateViewAdapter implements SslUntrustedCertDialog.CertificateViewAdapter {
+    
+    //private final static String TAG = X509CertificateViewAdapter.class.getSimpleName();
+    
+    private X509Certificate mCertificate = null;
+    
+    public X509CertificateViewAdapter(X509Certificate certificate) {
+        mCertificate = certificate;
+    }
+    
+    @Override
+    public void updateCertificateView(View dialogView) {
+        TextView nullCerView = (TextView) dialogView.findViewById(R.id.null_cert);
+        
+        if (mCertificate != null) {
+            nullCerView.setVisibility(View.GONE);
+            showSubject(mCertificate.getSubjectX500Principal(), dialogView);
+            showIssuer(mCertificate.getIssuerX500Principal(), dialogView);
+            showValidity(mCertificate.getNotBefore(), mCertificate.getNotAfter(), dialogView);
+            showSignature(dialogView);
+            
+        } else {
+            nullCerView.setVisibility(View.VISIBLE);
+        }
+    }
+
+    private void showSignature(View dialogView) {
+        TextView sigView = ((TextView)dialogView.findViewById(R.id.value_signature));
+        TextView algorithmView = ((TextView)dialogView.findViewById(R.id.value_signature_algorithm));
+        sigView.setText(getHex(mCertificate.getSignature()));
+        algorithmView.setText(mCertificate.getSigAlgName());
+    }
+    
+    public String getHex(final byte [] raw) {
+        if (raw == null) {
+           return null;
+        }
+        final StringBuilder hex = new StringBuilder(2 * raw.length);
+        for (final byte b : raw) {
+           final int hiVal = (b & 0xF0) >> 4;
+           final int loVal = b & 0x0F;
+           hex.append((char) ('0' + (hiVal + (hiVal / 10 * 7))));
+           hex.append((char) ('0' + (loVal + (loVal / 10 * 7))));
+        }
+        return hex.toString();
+     }    
+
+    private void showValidity(Date notBefore, Date notAfter, View dialogView) {
+        TextView fromView = ((TextView)dialogView.findViewById(R.id.value_validity_from));
+        TextView toView = ((TextView)dialogView.findViewById(R.id.value_validity_to));
+        DateFormat dateFormat = DateFormat.getDateInstance();
+        fromView.setText(dateFormat.format(notBefore));
+        toView.setText(dateFormat.format(notAfter));
+    }
+
+    private void showSubject(X500Principal subject, View dialogView) {
+        Map<String, String> s = parsePrincipal(subject);
+        TextView cnView = ((TextView)dialogView.findViewById(R.id.value_subject_CN));
+        TextView oView = ((TextView)dialogView.findViewById(R.id.value_subject_O));
+        TextView ouView = ((TextView)dialogView.findViewById(R.id.value_subject_OU));
+        TextView cView = ((TextView)dialogView.findViewById(R.id.value_subject_C));
+        TextView stView = ((TextView)dialogView.findViewById(R.id.value_subject_ST));
+        TextView lView = ((TextView)dialogView.findViewById(R.id.value_subject_L));
+        
+        if (s.get("CN") != null) {
+            cnView.setText(s.get("CN"));
+            cnView.setVisibility(View.VISIBLE);
+        } else {
+            cnView.setVisibility(View.GONE);
+        }
+        if (s.get("O") != null) {
+            oView.setText(s.get("O"));
+            oView.setVisibility(View.VISIBLE);
+        } else {
+            oView.setVisibility(View.GONE);
+        }
+        if (s.get("OU") != null) {
+            ouView.setText(s.get("OU"));
+            ouView.setVisibility(View.VISIBLE);
+        } else {
+            ouView.setVisibility(View.GONE);
+        }
+        if (s.get("C") != null) {
+            cView.setText(s.get("C"));
+            cView.setVisibility(View.VISIBLE);
+        } else {
+            cView.setVisibility(View.GONE);
+        }
+        if (s.get("ST") != null) {
+            stView.setText(s.get("ST"));
+            stView.setVisibility(View.VISIBLE);
+        } else {
+            stView.setVisibility(View.GONE);
+        }
+        if (s.get("L") != null) {
+            lView.setText(s.get("L"));
+            lView.setVisibility(View.VISIBLE);
+        } else {
+            lView.setVisibility(View.GONE);
+        }
+    }
+    
+    private void showIssuer(X500Principal issuer, View dialogView) {
+        Map<String, String> s = parsePrincipal(issuer);
+        TextView cnView = ((TextView)dialogView.findViewById(R.id.value_issuer_CN));
+        TextView oView = ((TextView)dialogView.findViewById(R.id.value_issuer_O));
+        TextView ouView = ((TextView)dialogView.findViewById(R.id.value_issuer_OU));
+        TextView cView = ((TextView)dialogView.findViewById(R.id.value_issuer_C));
+        TextView stView = ((TextView)dialogView.findViewById(R.id.value_issuer_ST));
+        TextView lView = ((TextView)dialogView.findViewById(R.id.value_issuer_L));
+        
+        if (s.get("CN") != null) {
+            cnView.setText(s.get("CN"));
+            cnView.setVisibility(View.VISIBLE);
+        } else {
+            cnView.setVisibility(View.GONE);
+        }
+        if (s.get("O") != null) {
+            oView.setText(s.get("O"));
+            oView.setVisibility(View.VISIBLE);
+        } else {
+            oView.setVisibility(View.GONE);
+        }
+        if (s.get("OU") != null) {
+            ouView.setText(s.get("OU"));
+            ouView.setVisibility(View.VISIBLE);
+        } else {
+            ouView.setVisibility(View.GONE);
+        }
+        if (s.get("C") != null) {
+            cView.setText(s.get("C"));
+            cView.setVisibility(View.VISIBLE);
+        } else {
+            cView.setVisibility(View.GONE);
+        }
+        if (s.get("ST") != null) {
+            stView.setText(s.get("ST"));
+            stView.setVisibility(View.VISIBLE);
+        } else {
+            stView.setVisibility(View.GONE);
+        }
+        if (s.get("L") != null) {
+            lView.setText(s.get("L"));
+            lView.setVisibility(View.VISIBLE);
+        } else {
+            lView.setVisibility(View.GONE);
+        }
+    }
+    
+
+    private Map<String, String> parsePrincipal(X500Principal principal) {
+        Map<String, String> result = new HashMap<String, String>();
+        String toParse = principal.getName();
+        String[] pieces = toParse.split(",");
+        String[] tokens = {"CN", "O", "OU", "C", "ST", "L"}; 
+        for (int i=0; i < pieces.length ; i++) {
+            for (int j=0; j<tokens.length; j++) {
+                if (pieces[i].startsWith(tokens[j] + "=")) {
+                    result.put(tokens[j], pieces[i].substring(tokens[j].length()+1));
+                }
+            }
+        }
+        return result;
+    }
+
+}
index 5a67e97..cb0b0ed 100644 (file)
@@ -18,22 +18,7 @@ package com.owncloud.android.ui.dialog;
 
 import java.io.IOException;
 import java.security.GeneralSecurityException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.security.auth.x500.X500Principal;
-
-import com.actionbarsherlock.app.SherlockActivity;
-import com.owncloud.android.R;
-import com.owncloud.android.lib.common.network.CertificateCombinedException;
-import com.owncloud.android.lib.common.network.NetworkUtils;
-import com.owncloud.android.lib.common.operations.RemoteOperationResult;
-import com.owncloud.android.utils.Log_OC;
 
 import android.app.Activity;
 import android.app.Dialog;
@@ -41,153 +26,124 @@ import android.net.http.SslError;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.view.Window;
+import android.view.View.OnClickListener;
+import android.webkit.SslErrorHandler;
 import android.widget.Button;
-import android.widget.TextView;
+
+import com.actionbarsherlock.app.SherlockDialogFragment;
+import com.owncloud.android.R;
+import com.owncloud.android.lib.common.network.CertificateCombinedException;
+import com.owncloud.android.lib.common.network.NetworkUtils;
+import com.owncloud.android.ui.adapter.CertificateCombinedExceptionViewAdapter;
+import com.owncloud.android.ui.adapter.SslCertificateViewAdapter;
+import com.owncloud.android.ui.adapter.SslErrorViewAdapter;
+import com.owncloud.android.ui.adapter.X509CertificateViewAdapter;
+import com.owncloud.android.utils.Log_OC;
 
 /**
- * Dialog to show an Untrusted Certificate
+ * Dialog to show information about an untrusted certificate and allow the user
+ * to decide trust on it or not.
+ * 
+ * Abstract implementation of common functionality for different dialogs that
+ * get the information about the error and the certificate from different classes. 
  * 
  * @author masensio
  * @author David A. Velasco
- *
  */
-public class SslUntrustedCertDialog extends SslUntrustedCertDialogABSTRACT {
+public class SslUntrustedCertDialog extends SherlockDialogFragment {
     
     private final static String TAG = SslUntrustedCertDialog.class.getSimpleName();
     
-    private X509Certificate mCertificate;
-    private View mView;
-    private OnSslUntrustedCertListener mListener;
-    private SslError mError;
-    private CertificateCombinedException mException = null;
-    
-    public SslUntrustedCertDialog() {
-    }
+    protected View mView = null;
+    protected SslErrorHandler mHandler = null;
+    protected X509Certificate m509Certificate = null;
+
+    private ErrorViewAdapter mErrorViewAdapter = null;
+    private CertificateViewAdapter mCertificateViewAdapter = null;
     
-    public SslUntrustedCertDialog(X509Certificate cert, SslError error) {
-        mCertificate = cert;
-        mError = error;
+    public static SslUntrustedCertDialog newInstanceForEmptySslError(SslError error, SslErrorHandler handler) {
+        if (error == null) {
+            throw new IllegalArgumentException("Trying to create instance with parameter error == null");
+        }
+        if (handler == null) {
+            throw new IllegalArgumentException("Trying to create instance with parameter handler == null");
+        }
+        SslUntrustedCertDialog dialog = new SslUntrustedCertDialog();
+        dialog.mHandler = handler;
+        dialog.mErrorViewAdapter = new SslErrorViewAdapter(error);
+        dialog.mCertificateViewAdapter = new SslCertificateViewAdapter(error.getCertificate());
+        return dialog;
     }
     
-    /**
-     * Private constructor. 
-     * 
-     * Instances have to be created through static {@link SslUntrustedCertDialog#newInstance}.
-     * 
-     * @param context       Android context where the dialog will live
-     * @param e             Exception causing the need of prompt the user about the server certificate.
-     * @param listener      Object to notice when the server certificate was added to the local certificates store.
-     */
-    private SslUntrustedCertDialog(RemoteOperationResult result, OnSslUntrustedCertListener listener) {
-        mListener = listener;
-        if (result.isSslRecoverableException()) {
-            mException = (CertificateCombinedException) result.getException();
-            mCertificate = mException.getServerCertificate();
+    public static SslUntrustedCertDialog newInstanceForFullSslError(CertificateCombinedException sslException) {
+        if (sslException == null) {
+            throw new IllegalArgumentException("Trying to create instance with parameter sslException == null");
         }
+        SslUntrustedCertDialog dialog = new SslUntrustedCertDialog();
+        dialog.m509Certificate = sslException.getServerCertificate();
+        dialog.mErrorViewAdapter = new CertificateCombinedExceptionViewAdapter(sslException);
+        dialog.mCertificateViewAdapter = new X509CertificateViewAdapter(sslException.getServerCertificate());
+        return dialog;
     }
     
-
-    public static SslUntrustedCertDialog newInstance(X509Certificate cert, SslError error) {
-        if (cert != null){
-            SslUntrustedCertDialog dialog = new SslUntrustedCertDialog(cert, error);
-            return dialog;
-        } else  { // TODO Review this case
-            SslUntrustedCertDialog dialog = new  SslUntrustedCertDialog();
-            return  dialog;
+    public static SslUntrustedCertDialog newInstanceForFullSslError(X509Certificate cert, SslError error, SslErrorHandler handler) {
+        if (cert == null) {
+            throw new IllegalArgumentException("Trying to create instance with parameter cert == null");
+        }
+        if (error == null) {
+            throw new IllegalArgumentException("Trying to create instance with parameter error == null");
         }
+        if (handler == null) {
+            throw new IllegalArgumentException("Trying to create instance with parameter handler == null");
+        }
+        SslUntrustedCertDialog dialog = new SslUntrustedCertDialog();
+        dialog.m509Certificate = cert;
+        dialog.mHandler = handler;
+        dialog.mErrorViewAdapter = new SslErrorViewAdapter(error);
+        dialog.mCertificateViewAdapter = new X509CertificateViewAdapter(cert);
+        return dialog;
     }
     
     
-    
-    /**
-     * Creates a new SslUntrustedCertDialog to ask the user if an untrusted certificate from a server should
-     * be trusted.
-     * 
-     * @param context       Android context where the dialog will live.
-     * @param result        Result of a failed remote operation.
-     * @param listener      Object to notice when the server certificate was added to the local certificates store.
-     * @return              A new SslUntrustedCertDialog instance. NULL if the operation can not be recovered
-     *                      by setting the certificate as reliable.
-     */
-    public static SslUntrustedCertDialog newInstance(RemoteOperationResult result, OnSslUntrustedCertListener listener) {
-        if (result != null && result.isSslRecoverableException()) {
-            SslUntrustedCertDialog dialog = new SslUntrustedCertDialog(result, listener);
-            return dialog;
-        } else {
-            return null;
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+        if (!(activity instanceof OnSslUntrustedCertListener)) {
+            throw new IllegalArgumentException("The host activity must implement " + OnSslUntrustedCertListener.class.getCanonicalName());
         }
     }
 
+    
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        setRetainInstance(true);
-        setCancelable(true);
-    }
-    
-    @Override
-    public void onAttach(Activity activity) {
-        super.onAttach(activity);
-        if (activity instanceof SherlockActivity) {
-            mListener = (OnSslUntrustedCertListener) activity;
-        }
+        setRetainInstance(true);    // force to keep the state of the fragment on configuration changes (such as device rotations)
+        setCancelable(false);
+        mView = null;
     }
     
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         // Create a view by inflating desired layout
-        mView = inflater.inflate(R.layout.ssl_untrusted_cert_layout, container,  false);
-        
-        updateMessageException(mException, mError);
+        if (mView == null) {
+            mView = inflater.inflate(R.layout.ssl_untrusted_cert_layout, container,  false);
+            mView.findViewById(R.id.details_scroll).setVisibility(View.GONE);
+            mErrorViewAdapter.updateErrorView(mView);
+        } else {
+            ((ViewGroup)mView.getParent()).removeView(mView);
+        }
         
         Button ok = (Button) mView.findViewById(R.id.ok);
-        ok.setOnClickListener(new OnClickListener() {
-            
-            @Override
-            public void onClick(View v) {
-                try {
-                  saveServerCert();
-                  dismiss();
-                  if (mListener != null) {
-                      mListener.onSavedCertificate();
-                  }
-                  else
-                      Log_OC.d(TAG, "Nobody there to notify the certificate was saved");
-                  
-              } catch (GeneralSecurityException e) {
-                  dismiss();
-                  if (mListener != null) {
-                      mListener.onFailedSavingCertificate();
-                  }
-                  Log_OC.e(TAG, "Server certificate could not be saved in the known servers trust store ", e);
-                  
-              } catch (IOException e) {
-                  dismiss();
-                  if (mListener != null) {
-                      mListener.onFailedSavingCertificate();
-                  }
-                  Log_OC.e(TAG, "Server certificate could not be saved in the known servers trust store ", e);
-              }
-                
-            }
-        });
+        ok.setOnClickListener(new OnCertificateTrusted());
         
         Button cancel = (Button) mView.findViewById(R.id.cancel);
-        cancel.setOnClickListener(new OnClickListener() {
-            
-            @Override
-            public void onClick(View v) {
-                getDialog().cancel();
-                mListener.onCancelCertificate();
-            }
-        });
+        cancel.setOnClickListener(new OnCertificateNotTrusted());
         
         Button details = (Button) mView.findViewById(R.id.details_btn);
         details.setOnClickListener(new OnClickListener() {
-            
+
             @Override
             public void onClick(View v) {
                 View detailsScroll = mView.findViewById(R.id.details_scroll);
@@ -198,21 +154,20 @@ public class SslUntrustedCertDialog extends SslUntrustedCertDialogABSTRACT {
                 } else {
                     detailsScroll.setVisibility(View.VISIBLE);
                     ((Button) v).setText(R.string.ssl_validator_btn_details_hide);
-                    
-                    showCertificateData(mCertificate);
+                    mCertificateViewAdapter.updateCertificateView(mView);
                 }
-                
             }
+
         });
         
         return mView;
     }
+    
 
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         final Dialog dialog = super.onCreateDialog(savedInstanceState);
         dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
-        
         return dialog;
     }
 
@@ -220,223 +175,62 @@ public class SslUntrustedCertDialog extends SslUntrustedCertDialogABSTRACT {
     public void onDestroyView() {
         if (getDialog() != null && getRetainInstance())
             getDialog().setDismissMessage(null);
-            super.onDestroyView();
+        super.onDestroyView();
     }
     
-    
-    private void updateMessageException(CertificateCombinedException exception, SslError error) {
-        
-        /// clean
-        mView.findViewById(R.id.reason_cert_not_trusted).setVisibility(View.GONE);
-        mView.findViewById(R.id.reason_cert_expired).setVisibility(View.GONE);
-        mView.findViewById(R.id.reason_cert_not_yet_valid).setVisibility(View.GONE);
-        mView.findViewById(R.id.reason_hostname_not_verified).setVisibility(View.GONE);
-        mView.findViewById(R.id.reason_no_info_about_error).setVisibility(View.GONE);
-        mView.findViewById(R.id.details_scroll).setVisibility(View.GONE);
+    private class OnCertificateNotTrusted implements OnClickListener {
         
-       
-        if (exception != null) {
-            
-            /// refresh
-            if (exception.getCertPathValidatorException() != null) {
-                ((TextView)mView.findViewById(R.id.reason_cert_not_trusted)).setVisibility(View.VISIBLE);
-            }
-            
-            if (exception.getCertificateExpiredException() != null) {
-                ((TextView)mView.findViewById(R.id.reason_cert_expired)).setVisibility(View.VISIBLE);
-            }
-            
-            if (exception.getCertificateNotYetValidException() != null) {
-                ((TextView)mView.findViewById(R.id.reason_cert_not_yet_valid)).setVisibility(View.VISIBLE);
-            } 
-
-            if (exception.getSslPeerUnverifiedException() != null) {
-                ((TextView)mView.findViewById(R.id.reason_hostname_not_verified)).setVisibility(View.VISIBLE);
-            }
-            
-        } else if ( error != null) {
-            /// refresh
-            if (error.getPrimaryError() == SslError.SSL_UNTRUSTED) {
-                ((TextView)mView.findViewById(R.id.reason_cert_not_trusted)).setVisibility(View.VISIBLE);
-                
-            } else if (error.getPrimaryError() == SslError.SSL_EXPIRED) {
-                ((TextView)mView.findViewById(R.id.reason_cert_expired)).setVisibility(View.VISIBLE);
-                
-            } else if (error.getPrimaryError() == SslError.SSL_NOTYETVALID) {
-                ((TextView)mView.findViewById(R.id.reason_cert_not_yet_valid)).setVisibility(View.VISIBLE);
-                
-            } else if (error.getPrimaryError() == SslError.SSL_IDMISMATCH) {
-                ((TextView)mView.findViewById(R.id.reason_hostname_not_verified)).setVisibility(View.VISIBLE);
+        @Override
+        public void onClick(View v) {
+            getDialog().cancel();
+            if (mHandler != null) {
+                mHandler.cancel();
             }
+            ((OnSslUntrustedCertListener)getSherlockActivity()).onCancelCertificate();
         }
-        
     }
     
-    private void showCertificateData(X509Certificate cert) {
-
-        TextView nullCerView = (TextView) mView.findViewById(R.id.null_cert);
-        
-        if (cert != null) {
-            nullCerView.setVisibility(View.GONE);
-            showSubject(cert.getSubjectX500Principal());
-            showIssuer(cert.getIssuerX500Principal());
-            showValidity(cert.getNotBefore(), cert.getNotAfter());
-            showSignature(cert);
-            
-        } else {
-            nullCerView.setVisibility(View.VISIBLE);
-        }
-    }
-
-    private void showSignature(X509Certificate cert) {
-        TextView sigView = ((TextView)mView.findViewById(R.id.value_signature));
-        TextView algorithmView = ((TextView)mView.findViewById(R.id.value_signature_algorithm));
-        sigView.setText(getHex(cert.getSignature()));
-        algorithmView.setText(cert.getSigAlgName());
-    }
     
-    public String getHex(final byte [] raw) {
-        if (raw == null) {
-           return null;
-        }
-        final StringBuilder hex = new StringBuilder(2 * raw.length);
-        for (final byte b : raw) {
-           final int hiVal = (b & 0xF0) >> 4;
-           final int loVal = b & 0x0F;
-           hex.append((char) ('0' + (hiVal + (hiVal / 10 * 7))));
-           hex.append((char) ('0' + (loVal + (loVal / 10 * 7))));
-        }
-        return hex.toString();
-     }    
+    private class OnCertificateTrusted implements OnClickListener {
 
-    @SuppressWarnings("deprecation")
-    private void showValidity(Date notBefore, Date notAfter) {
-        TextView fromView = ((TextView)mView.findViewById(R.id.value_validity_from));
-        TextView toView = ((TextView)mView.findViewById(R.id.value_validity_to));
-        fromView.setText(notBefore.toLocaleString());
-        toView.setText(notAfter.toLocaleString());
-    }
-
-    private void showSubject(X500Principal subject) {
-        Map<String, String> s = parsePrincipal(subject);
-        TextView cnView = ((TextView)mView.findViewById(R.id.value_subject_CN));
-        TextView oView = ((TextView)mView.findViewById(R.id.value_subject_O));
-        TextView ouView = ((TextView)mView.findViewById(R.id.value_subject_OU));
-        TextView cView = ((TextView)mView.findViewById(R.id.value_subject_C));
-        TextView stView = ((TextView)mView.findViewById(R.id.value_subject_ST));
-        TextView lView = ((TextView)mView.findViewById(R.id.value_subject_L));
-        
-        if (s.get("CN") != null) {
-            cnView.setText(s.get("CN"));
-            cnView.setVisibility(View.VISIBLE);
-        } else {
-            cnView.setVisibility(View.GONE);
-        }
-        if (s.get("O") != null) {
-            oView.setText(s.get("O"));
-            oView.setVisibility(View.VISIBLE);
-        } else {
-            oView.setVisibility(View.GONE);
-        }
-        if (s.get("OU") != null) {
-            ouView.setText(s.get("OU"));
-            ouView.setVisibility(View.VISIBLE);
-        } else {
-            ouView.setVisibility(View.GONE);
-        }
-        if (s.get("C") != null) {
-            cView.setText(s.get("C"));
-            cView.setVisibility(View.VISIBLE);
-        } else {
-            cView.setVisibility(View.GONE);
-        }
-        if (s.get("ST") != null) {
-            stView.setText(s.get("ST"));
-            stView.setVisibility(View.VISIBLE);
-        } else {
-            stView.setVisibility(View.GONE);
-        }
-        if (s.get("L") != null) {
-            lView.setText(s.get("L"));
-            lView.setVisibility(View.VISIBLE);
-        } else {
-            lView.setVisibility(View.GONE);
-        }
-    }
-    
-    private void showIssuer(X500Principal issuer) {
-        Map<String, String> s = parsePrincipal(issuer);
-        TextView cnView = ((TextView)mView.findViewById(R.id.value_issuer_CN));
-        TextView oView = ((TextView)mView.findViewById(R.id.value_issuer_O));
-        TextView ouView = ((TextView)mView.findViewById(R.id.value_issuer_OU));
-        TextView cView = ((TextView)mView.findViewById(R.id.value_issuer_C));
-        TextView stView = ((TextView)mView.findViewById(R.id.value_issuer_ST));
-        TextView lView = ((TextView)mView.findViewById(R.id.value_issuer_L));
-        
-        if (s.get("CN") != null) {
-            cnView.setText(s.get("CN"));
-            cnView.setVisibility(View.VISIBLE);
-        } else {
-            cnView.setVisibility(View.GONE);
-        }
-        if (s.get("O") != null) {
-            oView.setText(s.get("O"));
-            oView.setVisibility(View.VISIBLE);
-        } else {
-            oView.setVisibility(View.GONE);
-        }
-        if (s.get("OU") != null) {
-            ouView.setText(s.get("OU"));
-            ouView.setVisibility(View.VISIBLE);
-        } else {
-            ouView.setVisibility(View.GONE);
-        }
-        if (s.get("C") != null) {
-            cView.setText(s.get("C"));
-            cView.setVisibility(View.VISIBLE);
-        } else {
-            cView.setVisibility(View.GONE);
-        }
-        if (s.get("ST") != null) {
-            stView.setText(s.get("ST"));
-            stView.setVisibility(View.VISIBLE);
-        } else {
-            stView.setVisibility(View.GONE);
-        }
-        if (s.get("L") != null) {
-            lView.setText(s.get("L"));
-            lView.setVisibility(View.VISIBLE);
-        } else {
-            lView.setVisibility(View.GONE);
-        }
-    }
+        @Override
+        public void onClick(View v) {
+            dismiss();
+            if (mHandler != null) {
+                mHandler.proceed();
+            }
+            if (m509Certificate != null) {
+                Activity activity = getSherlockActivity();
+                try {
+                    NetworkUtils.addCertToKnownServersStore(m509Certificate, activity);   // TODO make this asynchronously, it can take some time
+                    ((OnSslUntrustedCertListener)activity).onSavedCertificate();
     
-
-    private Map<String, String> parsePrincipal(X500Principal principal) {
-        Map<String, String> result = new HashMap<String, String>();
-        String toParse = principal.getName();
-        String[] pieces = toParse.split(",");
-        String[] tokens = {"CN", "O", "OU", "C", "ST", "L"}; 
-        for (int i=0; i < pieces.length ; i++) {
-            for (int j=0; j<tokens.length; j++) {
-                if (pieces[i].startsWith(tokens[j] + "=")) {
-                    result.put(tokens[j], pieces[i].substring(tokens[j].length()+1));
+                } catch (GeneralSecurityException e) {
+                    ((OnSslUntrustedCertListener)activity).onFailedSavingCertificate();
+                    Log_OC.e(TAG, "Server certificate could not be saved in the known-servers trust store ", e);
+                  
+                } catch (IOException e) {
+                    ((OnSslUntrustedCertListener)activity).onFailedSavingCertificate();
+                    Log_OC.e(TAG, "Server certificate could not be saved in the known-servers trust store ", e);
                 }
             }
         }
-        return result;
-    }
-
-    private void saveServerCert() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
-        if (mCertificate != null) {
-            // TODO make this asynchronously, it can take some time
-            NetworkUtils.addCertToKnownServersStore(mCertificate, getSherlockActivity());
-        }
+        
     }
-
+    
+    
     public interface OnSslUntrustedCertListener {
         public void onSavedCertificate();
-        public void onCancelCertificate();
         public void onFailedSavingCertificate();
+        public void onCancelCertificate();
+    }
+    
+    public interface ErrorViewAdapter {
+        void updateErrorView(View mView);
     }
+    
+    public interface CertificateViewAdapter {
+        void updateCertificateView(View mView);
+    }
+    
 }
diff --git a/src/com/owncloud/android/ui/dialog/SslUntrustedCertDialogABSTRACT.java b/src/com/owncloud/android/ui/dialog/SslUntrustedCertDialogABSTRACT.java
deleted file mode 100644 (file)
index 26b097c..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-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 android.net.http.SslError;
-import android.webkit.SslErrorHandler;
-
-import com.actionbarsherlock.app.SherlockDialogFragment;
-
-/**
- * Dialog to show information about an untrusted certificate and allow the user
- * to decide trust on it or not.
- * 
- * Abstract implementation of common functionality for different dialogs that
- * get the information about the error and the certificate from different classes. 
- * 
- * @author masensio
- * @author David A. Velasco
- */
-public abstract class SslUntrustedCertDialogABSTRACT extends SherlockDialogFragment {
-    
-    //private final static String TAG = SslUntrustedCertDialogABSTRACT.class.getSimpleName();
-    
-    public static SslUntrustedCertDialogABSTRACT newInstanceForEmptySslError(SslError error, SslErrorHandler handler) {
-        if (error == null) {
-            throw new IllegalArgumentException("Trying to create instance with a parameter error == null");
-        }
-        return SslUntrustedCertDialogForEmptySslError.newInstance(error, handler);
-    }
-    
-    // TODO - complete when merged
-    /*
-    public static SslUntrustedCertDialogABSTRACT newInstanceForFullSslError(X509Certificate cert, SslError error, OnSslUntrustedCertListener listener, SslErrorHandler handler) {
-        if (cert == null) {
-            throw new IllegalArgumentException("Trying to create instance with a parameter error == null");
-        }
-        if (error == null) {
-            throw new IllegalArgumentException("Trying to create instance with a parameter error == null");
-        }
-        return new SslUntrustedCertDialog(cert, listener, handler);
-    }
-    */
-    
-    
-    public interface OnSslUntrustedCertListener {
-        public void onSavedCertificate();
-        public void onFailedSavingCertificate();
-    }
-
-}
diff --git a/src/com/owncloud/android/ui/dialog/SslUntrustedCertDialogForEmptySslError.java b/src/com/owncloud/android/ui/dialog/SslUntrustedCertDialogForEmptySslError.java
deleted file mode 100644 (file)
index d9173bb..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-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 java.text.DateFormat;
-import java.util.Date;
-
-import com.owncloud.android.R;
-import com.owncloud.android.authentication.AuthenticatorActivity;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.net.http.SslCertificate;
-import android.net.http.SslError;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.webkit.SslErrorHandler;
-import android.webkit.WebView;
-import android.widget.Button;
-import android.widget.TextView;
-
-/**
- * Dialog to show an Untrusted Certificate
- * 
- * @author masensio
- * @author David A. Velasco
- */
-public class SslUntrustedCertDialogForEmptySslError extends SslUntrustedCertDialogABSTRACT {
-    
-    //private final static String TAG = SslUntrustedCertDialogForEmptySslError.class.getSimpleName();
-    
-    private SslError mError;
-    private SslErrorHandler mHandler;
-    private View mView;
-
-    
-    /**
-     * Factory method.
-     * 
-     * @param error     Error occurred; details about it will be shown in the dialog.
-     * @param handler   Handler to indicate to the {@link WebView} where the error was found what to do next.
-     * @return          New dialog.
-     */
-    public static SslUntrustedCertDialogForEmptySslError newInstance(SslError error, SslErrorHandler handler) {
-        return new SslUntrustedCertDialogForEmptySslError(error, handler);
-    }
-    
-    
-    /**
-     * Empty constructor.
-     * 
-     * Required by Android framework. Never used, since the state is retained; see {@link #onCreate(Bundle)}  
-     */
-    public SslUntrustedCertDialogForEmptySslError() {}
-    
-
-    /**
-     * Private constructor.
-     * 
-     * Used by the factory method {@link #newInstance(SslError, SslErrorHandler)}.
-     * 
-     * @param error     Error occurred; details about it will be shown in the dialog.
-     * @param handler   Handler to indicate to the {@link WebView} where the error was found what to do next.
-     */
-    private SslUntrustedCertDialogForEmptySslError(SslError error, SslErrorHandler handler) {
-        mError = error;
-        mHandler = handler;
-    }
-
-    
-    @Override
-    public void onAttach(Activity activity) {
-        super.onAttach(activity);
-        /*if (!(activity instanceof OnSslUntrustedCertListener)) {
-            throw new IllegalArgumentException("Trying to attach to an Activity not implementing " + OnSslUntrustedCertListener.class.getCanonicalName());
-        }*/
-    }
-    
-    
-    // TODO try to move to the parent class ?
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setRetainInstance(true);    // force to keep the state of the fragment on configuration changes (such as device rotations)
-        setCancelable(false);
-        mView = null;
-    }
-    
-    // try to move to the parent class ?
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        // Create a view by inflating desired layout
-        if (mView == null) {
-            mView = inflater.inflate(R.layout.ssl_untrusted_cert_layout, container,  false);
-        } else {
-            ((ViewGroup)mView.getParent()).removeView(mView);
-        }
-        
-        showNoMessageError();
-        
-        Button ok = (Button) mView.findViewById(R.id.ok);
-        ok.setOnClickListener(new OnClickListener() {
-            
-            @Override
-            public void onClick(View v) {
-                //AuthenticatorActivity act = ((AuthenticatorActivity)getSherlockActivity());
-                mHandler.proceed();
-                dismiss();
-            }
-        });
-        
-        Button cancel = (Button) mView.findViewById(R.id.cancel);
-        cancel.setOnClickListener(new OnClickListener() {
-            
-            @Override
-            public void onClick(View v) {
-                AuthenticatorActivity act = ((AuthenticatorActivity)getSherlockActivity());
-                getDialog().cancel();
-                mHandler.cancel();
-                act.cancelWebView();
-            }
-        });
-        
-        Button details = (Button) mView.findViewById(R.id.details_btn);
-        details.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                View detailsScroll = mView.findViewById(R.id.details_scroll);
-                if (detailsScroll.getVisibility() == View.VISIBLE) {
-                    detailsScroll.setVisibility(View.GONE);
-                    ((Button) v).setText(R.string.ssl_validator_btn_details_see);
-
-                } else {
-                    detailsScroll.setVisibility(View.VISIBLE);
-                    ((Button) v).setText(R.string.ssl_validator_btn_details_hide);
-                    showCertificateData();
-                }
-            }
-        });
-        
-        return mView;
-    }
-
-    @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
-        final Dialog dialog = super.onCreateDialog(savedInstanceState);
-        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
-        return dialog;
-    }
-
-    @Override
-    public void onDestroyView() {
-        if (getDialog() != null && getRetainInstance())
-            getDialog().setDismissMessage(null);
-        super.onDestroyView();
-    }
-    
-    private void showCertificateData() {
-        TextView nullCerView = (TextView) mView.findViewById(R.id.null_cert);
-        SslCertificate cert = mError.getCertificate();
-        if (cert != null) {
-            nullCerView.setVisibility(View.GONE);
-            showSubject(cert.getIssuedTo());
-            showIssuer(cert.getIssuedBy());
-            showValidity(cert.getValidNotBeforeDate(), cert.getValidNotAfterDate());
-            hideSignature();
-            
-        } else {
-            nullCerView.setVisibility(View.VISIBLE);
-        }
-    }
-    
-    private void showValidity(Date notBefore, Date notAfter) {
-        TextView fromView = ((TextView)mView.findViewById(R.id.value_validity_from));
-        TextView toView = ((TextView)mView.findViewById(R.id.value_validity_to));
-        DateFormat dateFormat = DateFormat.getDateInstance();
-        fromView.setText(dateFormat.format(notBefore));
-        toView.setText(dateFormat.format(notAfter));
-    }
-
-    
-    private void showSubject(SslCertificate.DName subject) {
-        TextView cnView = ((TextView)mView.findViewById(R.id.value_subject_CN));
-        cnView.setText(subject.getCName());
-        cnView.setVisibility(View.VISIBLE);
-        
-        TextView oView = ((TextView)mView.findViewById(R.id.value_subject_O));
-        oView.setText(subject.getOName());
-        oView.setVisibility(View.VISIBLE);
-        
-        TextView ouView = ((TextView)mView.findViewById(R.id.value_subject_OU));
-        ouView.setText(subject.getUName());
-        ouView.setVisibility(View.VISIBLE);
-
-        // SslCertificates don't offer this information
-        ((TextView)mView.findViewById(R.id.value_subject_C)).setVisibility(View.GONE);
-        ((TextView)mView.findViewById(R.id.value_subject_ST)).setVisibility(View.GONE);
-        ((TextView)mView.findViewById(R.id.value_subject_L)).setVisibility(View.GONE);
-        ((TextView)mView.findViewById(R.id.label_subject_C)).setVisibility(View.GONE);
-        ((TextView)mView.findViewById(R.id.label_subject_ST)).setVisibility(View.GONE);
-        ((TextView)mView.findViewById(R.id.label_subject_L)).setVisibility(View.GONE);
-    }
-    
-    
-    private void showIssuer(SslCertificate.DName issuer) {
-        TextView cnView = ((TextView)mView.findViewById(R.id.value_issuer_CN));
-        cnView.setText(issuer.getCName());
-        cnView.setVisibility(View.VISIBLE);
-        
-        TextView oView = ((TextView)mView.findViewById(R.id.value_issuer_O));
-        oView.setText(issuer.getOName());
-        oView.setVisibility(View.VISIBLE);
-
-        TextView ouView = ((TextView)mView.findViewById(R.id.value_issuer_OU));
-        ouView.setText(issuer.getUName());
-        ouView.setVisibility(View.VISIBLE);
-        
-        // SslCertificates don't offer this information
-        ((TextView)mView.findViewById(R.id.value_issuer_C)).setVisibility(View.GONE);
-        ((TextView)mView.findViewById(R.id.value_issuer_ST)).setVisibility(View.GONE);
-        ((TextView)mView.findViewById(R.id.value_issuer_L)).setVisibility(View.GONE);
-        ((TextView)mView.findViewById(R.id.label_issuer_C)).setVisibility(View.GONE);
-        ((TextView)mView.findViewById(R.id.label_issuer_ST)).setVisibility(View.GONE);
-        ((TextView)mView.findViewById(R.id.label_issuer_L)).setVisibility(View.GONE);
-    }
-    
-    private void hideSignature() {
-        ((TextView)mView.findViewById(R.id.label_signature)).setVisibility(View.GONE);
-        ((TextView)mView.findViewById(R.id.label_signature_algorithm)).setVisibility(View.GONE);
-        ((TextView)mView.findViewById(R.id.value_signature_algorithm)).setVisibility(View.GONE);
-        ((TextView)mView.findViewById(R.id.value_signature)).setVisibility(View.GONE);
-    }
-
-    private void showNoMessageError() {
-        /// clean
-        mView.findViewById(R.id.reason_cert_not_trusted).setVisibility(View.GONE);
-        mView.findViewById(R.id.reason_cert_expired).setVisibility(View.GONE);
-        mView.findViewById(R.id.reason_cert_not_yet_valid).setVisibility(View.GONE);
-        mView.findViewById(R.id.reason_hostname_not_verified).setVisibility(View.GONE);
-        mView.findViewById(R.id.details_scroll).setVisibility(View.GONE);
-        
-        mView.findViewById(R.id.reason_no_info_about_error).setVisibility(View.VISIBLE);
-        
-    }
-}