1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-24 02:12:15 -05:00

Merge pull request #233 from maniac103/improve-cert-fail-notification

Improve certificate failure notifications.
This commit is contained in:
maniac103 2013-02-02 04:05:23 -08:00
commit 6c1369b734
14 changed files with 100 additions and 96 deletions

View File

@ -214,7 +214,7 @@ Um Fehler zu melden, neue Funktionen vorzuschlagen oder Fragen zu stellen, besuc
<string name="notification_action_read">Gelesen</string> <string name="notification_action_read">Gelesen</string>
<string name="notification_action_delete">Löschen</string> <string name="notification_action_delete">Löschen</string>
<string name="notification_certificate_error_title">Zertifikatsproblem</string> <string name="notification_certificate_error_title">Zertifikatsproblem (<xliff:g id="account">%s</xliff:g>)</string>
<string name="notification_certificate_error_text">Servereinstellungen überprüfen</string> <string name="notification_certificate_error_text">Servereinstellungen überprüfen</string>
<string name="notification_bg_sync_ticker">Neue Nachrichten in <xliff:g id="account">%s</xliff:g>:<xliff:g id="folder">%s</xliff:g> werden abgerufen</string> <string name="notification_bg_sync_ticker">Neue Nachrichten in <xliff:g id="account">%s</xliff:g>:<xliff:g id="folder">%s</xliff:g> werden abgerufen</string>

View File

@ -245,7 +245,7 @@ de plus</string>
<string name="notification_action_reply">Répondre</string> <string name="notification_action_reply">Répondre</string>
<string name="notification_action_read">Lire</string> <string name="notification_action_read">Lire</string>
<string name="notification_action_delete">Supprimer</string> <string name="notification_action_delete">Supprimer</string>
<string name="notification_certificate_error_title">Erreur de certificat</string> <string name="notification_certificate_error_title">Erreur de certificat (<xliff:g id="account">%s</xliff:g>)</string>
<string name="notification_certificate_error_text">Vérifier les paramètres serveur</string> <string name="notification_certificate_error_text">Vérifier les paramètres serveur</string>
<string name="notification_bg_sync_ticker">Vérification des messages\u00A0: <xliff:g id="account">%s</xliff:g>:<xliff:g id="folder">%s</xliff:g></string> <string name="notification_bg_sync_ticker">Vérification des messages\u00A0: <xliff:g id="account">%s</xliff:g>:<xliff:g id="folder">%s</xliff:g></string>

View File

@ -221,7 +221,7 @@ Please submit bug reports, contribute new features and ask questions at
<string name="notification_action_reply">Reply</string> <string name="notification_action_reply">Reply</string>
<string name="notification_action_read">Read</string> <string name="notification_action_read">Read</string>
<string name="notification_action_delete">Delete</string> <string name="notification_action_delete">Delete</string>
<string name="notification_certificate_error_title">Certificate error</string> <string name="notification_certificate_error_title">Certificate error for <xliff:g id="account">%s</xliff:g></string>
<string name="notification_certificate_error_text">Check your server settings</string> <string name="notification_certificate_error_text">Check your server settings</string>
<string name="notification_bg_sync_ticker">Checking mail: <xliff:g id="account">%s</xliff:g>:<xliff:g id="folder">%s</xliff:g></string> <string name="notification_bg_sync_ticker">Checking mail: <xliff:g id="account">%s</xliff:g>:<xliff:g id="folder">%s</xliff:g></string>

View File

@ -361,9 +361,9 @@ public class K9 extends Application {
// Must not conflict with an account number // Must not conflict with an account number
public static final int FETCHING_EMAIL_NOTIFICATION = -5000; public static final int FETCHING_EMAIL_NOTIFICATION = -5000;
public static final int SEND_FAILED_NOTIFICATION = -1500; public static final int SEND_FAILED_NOTIFICATION = -1500;
public static final int CERTIFICATE_EXCEPTION_NOTIFICATION_INCOMING = -2000;
public static final int CERTIFICATE_EXCEPTION_NOTIFICATION_OUTGOING = -2500;
public static final int CONNECTIVITY_ID = -3; public static final int CONNECTIVITY_ID = -3;
public static final int CERTIFICATE_EXCEPTION_NOTIFICATION_INCOMING = -4;
public static final int CERTIFICATE_EXCEPTION_NOTIFICATION_OUTGOING = -5;
public static class Intents { public static class Intents {

View File

@ -108,7 +108,11 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
finish(); finish();
return; return;
} }
clearCertificateErrorNotifications();
final MessagingController ctrl = MessagingController.getInstance(getApplication());
ctrl.clearCertificateErrorNotifications(AccountSetupCheckSettings.this,
mAccount, mCheckIncoming, mCheckOutgoing);
if (mCheckIncoming) { if (mCheckIncoming) {
store = mAccount.getRemoteStore(); store = mAccount.getRemoteStore();
@ -199,19 +203,6 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
}); });
} }
private void clearCertificateErrorNotifications() {
final Application app = getApplication();
final NotificationManager notifMgr = (NotificationManager) app
.getSystemService(Context.NOTIFICATION_SERVICE);
final String uuid = mAccount.getUuid();
if (mCheckOutgoing){
notifMgr.cancel(uuid, K9.CERTIFICATE_EXCEPTION_NOTIFICATION_OUTGOING);
}
if (mCheckIncoming){
notifMgr.cancel(uuid, K9.CERTIFICATE_EXCEPTION_NOTIFICATION_INCOMING);
}
}
private void showErrorDialog(final int msgResId, final Object... args) { private void showErrorDialog(final int msgResId, final Object... args) {
mHandler.post(new Runnable() { mHandler.post(new Runnable() {
public void run() { public void run() {

View File

@ -2,6 +2,7 @@
package com.fsck.k9.activity.setup; package com.fsck.k9.activity.setup;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable; import android.text.Editable;
@ -33,7 +34,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class AccountSetupIncoming extends K9Activity implements OnClickListener { public class AccountSetupIncoming extends K9Activity implements OnClickListener {
public static final String EXTRA_ACCOUNT = "account"; private static final String EXTRA_ACCOUNT = "account";
private static final String EXTRA_MAKE_DEFAULT = "makeDefault"; private static final String EXTRA_MAKE_DEFAULT = "makeDefault";
private static final int[] POP3_PORTS = { private static final int[] POP3_PORTS = {
@ -90,10 +91,14 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
} }
public static void actionEditIncomingSettings(Activity context, Account account) { public static void actionEditIncomingSettings(Activity context, Account account) {
context.startActivity(intentActionEditIncomingSettings(context, account));
}
public static Intent intentActionEditIncomingSettings(Context context, Account account) {
Intent i = new Intent(context, AccountSetupIncoming.class); Intent i = new Intent(context, AccountSetupIncoming.class);
i.setAction(Intent.ACTION_EDIT); i.setAction(Intent.ACTION_EDIT);
i.putExtra(EXTRA_ACCOUNT, account.getUuid()); i.putExtra(EXTRA_ACCOUNT, account.getUuid());
context.startActivity(i); return i;
} }
@Override @Override

View File

@ -26,7 +26,7 @@ import java.net.URLEncoder;
public class AccountSetupOutgoing extends K9Activity implements OnClickListener, public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
OnCheckedChangeListener { OnCheckedChangeListener {
public static final String EXTRA_ACCOUNT = "account"; private static final String EXTRA_ACCOUNT = "account";
private static final String EXTRA_MAKE_DEFAULT = "makeDefault"; private static final String EXTRA_MAKE_DEFAULT = "makeDefault";
@ -74,10 +74,14 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
} }
public static void actionEditOutgoingSettings(Context context, Account account) { public static void actionEditOutgoingSettings(Context context, Account account) {
context.startActivity(intentActionEditOutgoingSettings(context, account));
}
public static Intent intentActionEditOutgoingSettings(Context context, Account account) {
Intent i = new Intent(context, AccountSetupOutgoing.class); Intent i = new Intent(context, AccountSetupOutgoing.class);
i.setAction(Intent.ACTION_EDIT); i.setAction(Intent.ACTION_EDIT);
i.putExtra(EXTRA_ACCOUNT, account.getUuid()); i.putExtra(EXTRA_ACCOUNT, account.getUuid());
context.startActivity(i); return i;
} }
@Override @Override

View File

@ -2,6 +2,8 @@ package com.fsck.k9.controller;
import java.io.CharArrayWriter; import java.io.CharArrayWriter;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -51,6 +53,8 @@ import com.fsck.k9.activity.FolderList;
import com.fsck.k9.activity.MessageList; import com.fsck.k9.activity.MessageList;
import com.fsck.k9.activity.MessageReference; import com.fsck.k9.activity.MessageReference;
import com.fsck.k9.activity.NotificationDeleteConfirmation; import com.fsck.k9.activity.NotificationDeleteConfirmation;
import com.fsck.k9.activity.setup.AccountSetupIncoming;
import com.fsck.k9.activity.setup.AccountSetupOutgoing;
import com.fsck.k9.helper.Contacts; import com.fsck.k9.helper.Contacts;
import com.fsck.k9.helper.power.TracingPowerManager; import com.fsck.k9.helper.power.TracingPowerManager;
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock; import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
@ -62,6 +66,7 @@ import com.fsck.k9.mail.Folder.FolderType;
import com.fsck.k9.mail.Folder.OpenMode; import com.fsck.k9.mail.Folder.OpenMode;
import com.fsck.k9.mail.Message; import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.Message.RecipientType; import com.fsck.k9.mail.Message.RecipientType;
import com.fsck.k9.mail.CertificateValidationException;
import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part; import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.PushReceiver; import com.fsck.k9.mail.PushReceiver;
@ -1151,6 +1156,7 @@ public class MessagingController implements Runnable {
for (MessagingListener l : getListeners(listener)) { for (MessagingListener l : getListeners(listener)) {
l.synchronizeMailboxFailed(account, folder, rootMessage); l.synchronizeMailboxFailed(account, folder, rootMessage);
} }
notifyUserIfCertificateProblem(mApplication, e, account, true);
addErrorMessage(account, null, e); addErrorMessage(account, null, e);
Log.e(K9.LOG_TAG, "Failed synchronizing folder " + account.getDescription() + ":" + folder + " @ " + new Date()); Log.e(K9.LOG_TAG, "Failed synchronizing folder " + account.getDescription() + ":" + folder + " @ " + new Date());
@ -1994,6 +2000,7 @@ public class MessagingController implements Runnable {
} }
} }
} catch (MessagingException me) { } catch (MessagingException me) {
notifyUserIfCertificateProblem(mApplication, me, account, true);
addErrorMessage(account, null, me); addErrorMessage(account, null, me);
Log.e(K9.LOG_TAG, "Could not process command '" + processingCommand + "'", me); Log.e(K9.LOG_TAG, "Could not process command '" + processingCommand + "'", me);
throw me; throw me;
@ -2602,6 +2609,60 @@ public class MessagingController implements Runnable {
} }
} }
private void notifyUserIfCertificateProblem(Context context, Exception e,
Account account, boolean incoming) {
if (!(e instanceof CertificateValidationException)) {
return;
}
CertificateValidationException cve = (CertificateValidationException) e;
if (!cve.needsUserAttention()) {
return;
}
final int id = incoming
? K9.CERTIFICATE_EXCEPTION_NOTIFICATION_INCOMING + account.getAccountNumber()
: K9.CERTIFICATE_EXCEPTION_NOTIFICATION_OUTGOING + account.getAccountNumber();
final Intent i = incoming
? AccountSetupIncoming.intentActionEditIncomingSettings(context, account)
: AccountSetupOutgoing.intentActionEditOutgoingSettings(context, account);
final PendingIntent pi = PendingIntent.getActivity(context,
account.getAccountNumber(), i, PendingIntent.FLAG_UPDATE_CURRENT);
final String title = context.getString(
R.string.notification_certificate_error_text, account.getName());
final NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(R.drawable.stat_notify_email_generic);
builder.setWhen(System.currentTimeMillis());
builder.setAutoCancel(true);
builder.setTicker(title);
builder.setContentTitle(title);
builder.setContentText(context.getString(R.string.notification_certificate_error_text));
builder.setContentIntent(pi);
configureNotification(builder, null, null,
K9.NOTIFICATION_LED_FAILURE_COLOR,
K9.NOTIFICATION_LED_BLINK_FAST, true);
final NotificationManager nm = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(null, id, builder.build());
}
public void clearCertificateErrorNotifications(Context context,
final Account account, boolean incoming, boolean outgoing) {
final NotificationManager nm = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
if (incoming) {
nm.cancel(null, K9.CERTIFICATE_EXCEPTION_NOTIFICATION_INCOMING + account.getAccountNumber());
}
if (outgoing) {
nm.cancel(null, K9.CERTIFICATE_EXCEPTION_NOTIFICATION_OUTGOING + account.getAccountNumber());
}
}
static long uidfill = 0; static long uidfill = 0;
static AtomicBoolean loopCatch = new AtomicBoolean(); static AtomicBoolean loopCatch = new AtomicBoolean();
public void addErrorMessage(Account account, String subject, Throwable t) { public void addErrorMessage(Account account, String subject, Throwable t) {
@ -2986,6 +3047,7 @@ public class MessagingController implements Runnable {
for (MessagingListener l : getListeners(listener)) { for (MessagingListener l : getListeners(listener)) {
l.loadMessageForViewFailed(account, folder, uid, e); l.loadMessageForViewFailed(account, folder, uid, e);
} }
notifyUserIfCertificateProblem(mApplication, e, account, true);
addErrorMessage(account, null, e); addErrorMessage(account, null, e);
return false; return false;
} finally { } finally {
@ -3134,6 +3196,7 @@ public class MessagingController implements Runnable {
for (MessagingListener l : getListeners(listener)) { for (MessagingListener l : getListeners(listener)) {
l.loadAttachmentFailed(account, message, part, tag, me.getMessage()); l.loadAttachmentFailed(account, message, part, tag, me.getMessage());
} }
notifyUserIfCertificateProblem(mApplication, me, account, true);
addErrorMessage(account, null, me); addErrorMessage(account, null, me);
} finally { } finally {
@ -3308,23 +3371,6 @@ public class MessagingController implements Runnable {
builder.build()); builder.build());
} }
public void notify(String tag, int id, String title, String text, PendingIntent pi) {
final NotificationManager notifMgr = (NotificationManager) mApplication
.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(mApplication);
builder.setSmallIcon(R.drawable.stat_notify_email_generic);
builder.setWhen(System.currentTimeMillis());
builder.setAutoCancel(true);
builder.setTicker(title);
builder.setContentTitle(title);
builder.setContentText(text);
builder.setContentIntent(pi);
configureNotification(builder, null, null,
K9.NOTIFICATION_LED_FAILURE_COLOR,
K9.NOTIFICATION_LED_BLINK_FAST, true);
notifMgr.notify(tag, id, builder.build());
}
/** /**
* Display an ongoing notification while checking for new messages on the server. * Display an ongoing notification while checking for new messages on the server.
* *
@ -3510,6 +3556,7 @@ public class MessagingController implements Runnable {
localFolder.moveMessages(new Message[] { message }, (LocalFolder) localStore.getFolder(account.getDraftsFolderName())); localFolder.moveMessages(new Message[] { message }, (LocalFolder) localStore.getFolder(account.getDraftsFolderName()));
} }
notifyUserIfCertificateProblem(mApplication, e, account, false);
message.setFlag(Flag.X_SEND_FAILED, true); message.setFlag(Flag.X_SEND_FAILED, true);
Log.e(K9.LOG_TAG, "Failed to send message", e); Log.e(K9.LOG_TAG, "Failed to send message", e);
for (MessagingListener l : getListeners()) { for (MessagingListener l : getListeners()) {
@ -4123,7 +4170,6 @@ public class MessagingController implements Runnable {
throw new UnavailableAccountException(e); throw new UnavailableAccountException(e);
} catch (Exception e) { } catch (Exception e) {
Log.e(K9.LOG_TAG, "emptyTrash failed", e); Log.e(K9.LOG_TAG, "emptyTrash failed", e);
addErrorMessage(account, null, e); addErrorMessage(account, null, e);
} finally { } finally {
closeFolder(localFolder); closeFolder(localFolder);

View File

@ -1,15 +1,6 @@
package com.fsck.k9.mail; package com.fsck.k9.mail;
import android.app.Application;
import android.app.PendingIntent;
import android.content.Intent;
import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.activity.setup.AccountSetupIncoming;
import com.fsck.k9.activity.setup.AccountSetupOutgoing;
import com.fsck.k9.controller.MessagingController;
import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
@ -20,44 +11,20 @@ public class CertificateValidationException extends MessagingException {
super(message); super(message);
} }
public CertificateValidationException(final String message, public CertificateValidationException(final String message, Throwable throwable) {
Throwable throwable, final Account account, final boolean incoming) {
super(message, throwable); super(message, throwable);
/* }
* We get here because of an SSLException. We are only interested in
* creating a notification if the underlying cause is certificate public boolean needsUserAttention() {
* related. Throwable throwable = getCause();
*/
/* user attention is required if the certificate was deemed invalid */
while (throwable != null while (throwable != null
&& !(throwable instanceof CertPathValidatorException) && !(throwable instanceof CertPathValidatorException)
&& !(throwable instanceof CertificateException)) { && !(throwable instanceof CertificateException)) {
throwable = throwable.getCause(); throwable = throwable.getCause();
} }
if (throwable == null)
return; return throwable != null;
final Application app = K9.app;
final String title = app
.getString(R.string.notification_certificate_error_title);
final String text = app
.getString(R.string.notification_certificate_error_text);
final Class<?> className;
final String extraName;
final int id;
if (incoming) {
className = AccountSetupIncoming.class;
extraName = AccountSetupIncoming.EXTRA_ACCOUNT;
id = K9.CERTIFICATE_EXCEPTION_NOTIFICATION_INCOMING;
} else {
className = AccountSetupOutgoing.class;
extraName = AccountSetupOutgoing.EXTRA_ACCOUNT;
id = K9.CERTIFICATE_EXCEPTION_NOTIFICATION_OUTGOING;
}
final Intent i = new Intent(app, className);
final String uuid = account.getUuid();
i.setAction(Intent.ACTION_EDIT);
i.putExtra(extraName, uuid);
final PendingIntent pi = PendingIntent.getActivity(app, 0, i, 0);
MessagingController controller = MessagingController.getInstance(app);
controller.notify(uuid, id, title, text, pi);
} }
} }

View File

@ -428,11 +428,6 @@ public class ImapStore extends Store {
public void setCombinedPrefix(String prefix) { public void setCombinedPrefix(String prefix) {
mCombinedPrefix = prefix; mCombinedPrefix = prefix;
} }
@Override
public Account getAccount() {
return mAccount;
}
} }
private static final SimpleDateFormat RFC3501_DATE = new SimpleDateFormat("dd-MMM-yyyy", Locale.US); private static final SimpleDateFormat RFC3501_DATE = new SimpleDateFormat("dd-MMM-yyyy", Locale.US);
@ -2627,7 +2622,7 @@ public class ImapStore extends Store {
} catch (SSLException e) { } catch (SSLException e) {
throw new CertificateValidationException(e.getMessage(), e, mSettings.getAccount(), true); throw new CertificateValidationException(e.getMessage(), e);
} catch (GeneralSecurityException gse) { } catch (GeneralSecurityException gse) {
throw new MessagingException( throw new MessagingException(
"Unable to open connection to IMAP server due to security error.", gse); "Unable to open connection to IMAP server due to security error.", gse);

View File

@ -391,7 +391,7 @@ public class Pop3Store extends Store {
mCapabilities = getCapabilities(); mCapabilities = getCapabilities();
} catch (SSLException e) { } catch (SSLException e) {
throw new CertificateValidationException(e.getMessage(), e, mAccount, true); throw new CertificateValidationException(e.getMessage(), e);
} catch (GeneralSecurityException gse) { } catch (GeneralSecurityException gse) {
throw new MessagingException( throw new MessagingException(
"Unable to open connection to POP server due to security error.", gse); "Unable to open connection to POP server due to security error.", gse);

View File

@ -848,7 +848,7 @@ public class WebDavStore extends Store {
response.getStatusLine().toString()); response.getStatusLine().toString());
} }
} catch (SSLException e) { } catch (SSLException e) {
throw new CertificateValidationException(e.getMessage(), e, mAccount, true); throw new CertificateValidationException(e.getMessage(), e);
} catch (IOException ioe) { } catch (IOException ioe) {
Log.e(K9.LOG_TAG, "IOException: " + ioe + "\nTrace: " + processException(ioe)); Log.e(K9.LOG_TAG, "IOException: " + ioe + "\nTrace: " + processException(ioe));
throw new MessagingException("IOException", ioe); throw new MessagingException("IOException", ioe);

View File

@ -389,7 +389,7 @@ public class SmtpTransport extends Transport {
} }
} }
} catch (SSLException e) { } catch (SSLException e) {
throw new CertificateValidationException(e.getMessage(), e, mAccount, false); throw new CertificateValidationException(e.getMessage(), e);
} catch (GeneralSecurityException gse) { } catch (GeneralSecurityException gse) {
throw new MessagingException( throw new MessagingException(
"Unable to open connection to SMTP server due to security error.", gse); "Unable to open connection to SMTP server due to security error.", gse);

View File

@ -1,6 +1,5 @@
package com.fsck.k9.mail.transport.imap; package com.fsck.k9.mail.transport.imap;
import com.fsck.k9.Account;
import com.fsck.k9.mail.store.ImapStore; import com.fsck.k9.mail.store.ImapStore;
import com.fsck.k9.mail.store.ImapStore.AuthType; import com.fsck.k9.mail.store.ImapStore.AuthType;
import com.fsck.k9.mail.store.ImapStore.ImapConnection; import com.fsck.k9.mail.store.ImapStore.ImapConnection;
@ -34,7 +33,4 @@ public interface ImapSettings {
String getCombinedPrefix(); String getCombinedPrefix();
void setCombinedPrefix(String prefix); void setCombinedPrefix(String prefix);
Account getAccount();
} }