diff --git a/app/src/main/java/eu/faircode/email/EmailProvider.java b/app/src/main/java/eu/faircode/email/EmailProvider.java index 9c6791929c..3406ebf4be 100644 --- a/app/src/main/java/eu/faircode/email/EmailProvider.java +++ b/app/src/main/java/eu/faircode/email/EmailProvider.java @@ -57,6 +57,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -241,12 +242,12 @@ public class EmailProvider implements Parcelable { } @NonNull - static EmailProvider fromDomain(Context context, String domain, Discover discover) throws IOException { + static List fromDomain(Context context, String domain, Discover discover) throws IOException { return fromEmail(context, domain, discover); } @NonNull - static EmailProvider fromEmail(Context context, String email, Discover discover) throws IOException { + static List fromEmail(Context context, String email, Discover discover) throws IOException { int at = email.indexOf('@'); String domain = (at < 0 ? email : email.substring(at + 1)); if (at < 0) @@ -258,130 +259,133 @@ public class EmailProvider implements Parcelable { if (PROPRIETARY.contains(domain)) throw new IllegalArgumentException(context.getString(R.string.title_no_standard)); - if (BuildConfig.DEBUG && false) - try { - // Scan ports - EntityLog.log(context, "Provider from template domain=" + domain); - return fromTemplate(context, domain, discover); - } catch (Throwable ex) { - Log.w(ex); - throw new UnknownHostException(context.getString(R.string.title_setup_no_settings, domain)); - } - List providers = loadProfiles(context); for (EmailProvider provider : providers) if (provider.domain != null) for (String d : provider.domain) if (domain.toLowerCase(Locale.ROOT).matches(d)) { EntityLog.log(context, "Provider from domain=" + domain + " (" + d + ")"); - provider.log(context); - return provider; + return Arrays.asList(provider); } - EmailProvider autoconfig = null; + List result = new ArrayList<>(); + for (EmailProvider provider : _fromDomain(context, domain.toLowerCase(Locale.ROOT), email, discover)) + if (result.contains(provider)) + Log.i("Duplicate " + provider); + else + result.add(provider); + try { - autoconfig = _fromDomain(context, domain.toLowerCase(Locale.ROOT), email, discover); + DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, domain, "mx"); + + for (DnsHelper.DnsRecord record : records) + if (!TextUtils.isEmpty(record.name)) + for (EmailProvider provider : providers) { + if (provider.mx != null) + for (String mx : provider.mx) + if (record.name.toLowerCase(Locale.ROOT).matches(mx)) { + EntityLog.log(context, "Provider from mx=" + record.name + " domain=" + domain); + if (result.contains(provider)) + Log.i("Duplicate " + provider); + else + result.add(provider); + break; + } + + String mxparent = UriHelper.getParentDomain(context, record.name); + String pdomain = UriHelper.getParentDomain(context, provider.imap.host); + if (mxparent.equalsIgnoreCase(pdomain)) { + EntityLog.log(context, "Provider from mx=" + record.name + " host=" + provider.imap.host); + if (result.contains(provider)) + Log.i("Duplicate " + provider); + else + result.add(provider); + break; + } + } + + for (DnsHelper.DnsRecord record : records) { + String target = record.name; + while (result.size() == 0 && target != null && target.indexOf('.') > 0) { + try { + for (EmailProvider provider : _fromDomain(context, target.toLowerCase(Locale.ROOT), email, discover)) + if (result.contains(provider)) + Log.i("Duplicate " + provider); + else + result.add(provider); + } catch (Throwable ex) { + Log.w(ex); + int dot = target.indexOf('.'); + target = target.substring(dot + 1); + } + } + } + } catch (Throwable ex) { Log.w(ex); - - try { - // Retry at MX server addresses - DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, domain, "mx"); - - for (DnsHelper.DnsRecord record : records) - if (!TextUtils.isEmpty(record.name)) - for (EmailProvider provider : providers) { - if (provider.mx != null) - for (String mx : provider.mx) - if (record.name.toLowerCase(Locale.ROOT).matches(mx)) { - EntityLog.log(context, "Provider from mx=" + record.name + " domain=" + domain); - provider.log(context); - return provider; - } - - String mxparent = UriHelper.getParentDomain(context, record.name); - String pdomain = UriHelper.getParentDomain(context, provider.imap.host); - if (mxparent.equalsIgnoreCase(pdomain)) { - EntityLog.log(context, "Provider from mx=" + record.name + " host=" + provider.imap.host); - provider.log(context); - return provider; - } - } - - for (DnsHelper.DnsRecord record : records) { - String target = record.name; - while (autoconfig == null && target != null && target.indexOf('.') > 0) { - try { - autoconfig = _fromDomain(context, target.toLowerCase(Locale.ROOT), email, discover); - } catch (Throwable ex1) { - Log.w(ex1); - int dot = target.indexOf('.'); - target = target.substring(dot + 1); - } - } - if (autoconfig != null) - break; - } - } catch (Throwable ex1) { - Log.w(ex1); - } - - if (autoconfig == null) - throw ex; } - // Always prefer built-in profiles - // - ISPDB is not always correct - // - documentation links - for (EmailProvider provider : providers) - if (provider.imap.host.equals(autoconfig.imap.host) || - provider.smtp.host.equals(autoconfig.smtp.host)) { - EntityLog.log(context, "Replacing auto config by profile=" + provider.name); - provider.log(context); - return provider; + if (result.size() == 0) + throw new UnknownHostException(context.getString(R.string.title_setup_no_settings, domain)); + + for (EmailProvider autoconfig : result) + for (EmailProvider provider : providers) { + // Always prefer built-in profiles + // - ISPDB is not always correct + // - documentation links + if (provider.imap.host.equals(autoconfig.imap.host) || + provider.smtp.host.equals(autoconfig.smtp.host)) { + EntityLog.log(context, "Replacing auto config by profile=" + provider.name); + return Arrays.asList(provider); + } + + // https://help.dreamhost.com/hc/en-us/articles/214918038-Email-client-configuration-overview + if (autoconfig.imap.host != null && + autoconfig.imap.host.endsWith(".dreamhost.com")) + autoconfig.imap.host = "imap.dreamhost.com"; + + if (autoconfig.smtp.host != null && + autoconfig.smtp.host.endsWith(".dreamhost.com")) + autoconfig.smtp.host = "smtp.dreamhost.com"; + + // https://docs.aws.amazon.com/workmail/latest/userguide/using_IMAP_client.html + if (autoconfig.imap.host != null && + autoconfig.imap.host.endsWith(".awsapps.com")) + autoconfig.partial = false; } - // https://help.dreamhost.com/hc/en-us/articles/214918038-Email-client-configuration-overview - if (autoconfig.imap.host != null && - autoconfig.imap.host.endsWith(".dreamhost.com")) - autoconfig.imap.host = "imap.dreamhost.com"; - - if (autoconfig.smtp.host != null && - autoconfig.smtp.host.endsWith(".dreamhost.com")) - autoconfig.smtp.host = "smtp.dreamhost.com"; - - // https://docs.aws.amazon.com/workmail/latest/userguide/using_IMAP_client.html - if (autoconfig.imap.host != null && - autoconfig.imap.host.endsWith(".awsapps.com")) - autoconfig.partial = false; - - return autoconfig; + return result; } @NonNull - private static EmailProvider _fromDomain(Context context, String domain, String email, Discover discover) throws IOException { + private static List _fromDomain(Context context, String domain, String email, Discover discover) throws IOException { + List result = new ArrayList<>(); + try { // Assume the provider knows best Log.i("Provider from DNS domain=" + domain); - return fromDNS(context, domain, discover); + result.add(fromDNS(context, domain, discover)); } catch (Throwable ex) { Log.w(ex); - try { - // Check ISPDB - Log.i("Provider from ISPDB domain=" + domain); - return fromISPDB(context, domain, email); - } catch (Throwable ex1) { - Log.w(ex1); - try { - // Scan ports - Log.i("Provider from template domain=" + domain); - return fromTemplate(context, domain, discover); - } catch (Throwable ex2) { - Log.w(ex2); - throw new UnknownHostException(context.getString(R.string.title_setup_no_settings, domain)); - } - } } + + try { + // Check ISPDB + Log.i("Provider from ISPDB domain=" + domain); + result.add(fromISPDB(context, domain, email)); + } catch (Throwable ex) { + Log.w(ex); + } + + try { + // Scan ports + Log.i("Provider from template domain=" + domain); + result.add(fromScan(context, domain, discover)); + } catch (Throwable ex) { + Log.w(ex); + } + + return result; } @NonNull @@ -584,7 +588,6 @@ public class EmailProvider implements Parcelable { } provider.validate(); - provider.log(context); return provider; } finally { @@ -643,13 +646,12 @@ public class EmailProvider implements Parcelable { } provider.validate(); - provider.log(context); return provider; } @NonNull - private static EmailProvider fromTemplate(Context context, String domain, Discover discover) + private static EmailProvider fromScan(Context context, String domain, Discover discover) throws ExecutionException, InterruptedException, UnknownHostException { // https://tools.ietf.org/html/rfc8314 Server imap = null; @@ -731,7 +733,6 @@ public class EmailProvider implements Parcelable { if (smtp != null) provider.smtp = smtp; - provider.log(context); return provider; } @@ -744,11 +745,6 @@ public class EmailProvider implements Parcelable { provider.documentation.append("").append(title).append(""); } - private void log(Context context) { - EntityLog.log(context, "imap=" + imap); - EntityLog.log(context, "smtp=" + smtp); - } - protected EmailProvider(Parcel in) { if (in.readInt() == 0) imap = null; @@ -812,6 +808,21 @@ public class EmailProvider implements Parcelable { } }; + @Override + public boolean equals(Object obj) { + if (obj instanceof EmailProvider) { + EmailProvider other = (EmailProvider) obj; + return (Objects.equals(this.imap, other.imap) && + Objects.equals(this.smtp, other.smtp)); + } else + return false; + } + + @Override + public int hashCode() { + return Objects.hash(imap, smtp); + } + @NonNull @Override public String toString() { @@ -986,6 +997,22 @@ public class EmailProvider implements Parcelable { throw new SocketException("No STARTTLS"); } + @Override + public boolean equals(Object obj) { + if (obj instanceof Server) { + Server other = (Server) obj; + return (Objects.equals(this.host, other.host) && + this.port == other.port && + this.starttls == other.starttls); + } else + return false; + } + + @Override + public int hashCode() { + return Objects.hash(host, port, starttls); + } + @NonNull @Override public String toString() { diff --git a/app/src/main/java/eu/faircode/email/FragmentAccount.java b/app/src/main/java/eu/faircode/email/FragmentAccount.java index de70ddcdeb..2e6905259c 100644 --- a/app/src/main/java/eu/faircode/email/FragmentAccount.java +++ b/app/src/main/java/eu/faircode/email/FragmentAccount.java @@ -591,7 +591,9 @@ public class FragmentAccount extends FragmentBase { @Override protected EmailProvider onExecute(Context context, Bundle args) throws Throwable { String domain = args.getString("domain"); - return EmailProvider.fromDomain(context, domain, EmailProvider.Discover.IMAP); + return EmailProvider + .fromDomain(context, domain, EmailProvider.Discover.IMAP) + .get(0); } @Override diff --git a/app/src/main/java/eu/faircode/email/FragmentGmail.java b/app/src/main/java/eu/faircode/email/FragmentGmail.java index 4841174497..9b7ce2ed0b 100644 --- a/app/src/main/java/eu/faircode/email/FragmentGmail.java +++ b/app/src/main/java/eu/faircode/email/FragmentGmail.java @@ -413,7 +413,9 @@ public class FragmentGmail extends FragmentBase { int at = user.indexOf('@'); String username = user.substring(0, at); - EmailProvider provider = EmailProvider.fromDomain(context, "gmail.com", EmailProvider.Discover.ALL); + EmailProvider provider = EmailProvider + .fromDomain(context, "gmail.com", EmailProvider.Discover.ALL) + .get(0); List folders; diff --git a/app/src/main/java/eu/faircode/email/FragmentIdentity.java b/app/src/main/java/eu/faircode/email/FragmentIdentity.java index d04a49d4cf..2ade7cdefd 100644 --- a/app/src/main/java/eu/faircode/email/FragmentIdentity.java +++ b/app/src/main/java/eu/faircode/email/FragmentIdentity.java @@ -584,7 +584,9 @@ public class FragmentIdentity extends FragmentBase { @Override protected EmailProvider onExecute(Context context, Bundle args) throws Throwable { String domain = args.getString("domain"); - return EmailProvider.fromDomain(context, domain, EmailProvider.Discover.SMTP); + return EmailProvider + .fromDomain(context, domain, EmailProvider.Discover.SMTP) + .get(0); } @Override diff --git a/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java b/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java index bbd4ccc47b..994efc6611 100644 --- a/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java +++ b/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java @@ -277,208 +277,223 @@ public class FragmentQuickSetup extends FragmentBase { if (TextUtils.isEmpty(password)) throw new IllegalArgumentException(context.getString(R.string.title_no_password)); + int at = email.indexOf('@'); + String username = email.substring(0, at); + ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo ani = (cm == null ? null : cm.getActiveNetworkInfo()); if (ani == null || !ani.isConnected()) throw new IllegalArgumentException(context.getString(R.string.title_no_internet)); - EmailProvider provider = EmailProvider.fromEmail(context, email, EmailProvider.Discover.ALL); - args.putParcelable("provider", provider); - - int at = email.indexOf('@'); - String username = email.substring(0, at); - - String user = (provider.user == EmailProvider.UserType.EMAIL ? email : username); - Log.i("User type=" + provider.user + " name=" + user); - - List folders; - String imap_fingerprint = null; - String smtp_fingerprint = null; - X509Certificate imap_certificate = null; - X509Certificate smtp_certificate = null; - - String aprotocol = (provider.imap.starttls ? "imap" : "imaps"); - int aencryption = (provider.imap.starttls ? EmailService.ENCRYPTION_STARTTLS : EmailService.ENCRYPTION_SSL); - try (EmailService iservice = new EmailService( - context, aprotocol, null, aencryption, false, EmailService.PURPOSE_CHECK, true)) { + Throwable fail = null; + List providers = EmailProvider.fromEmail(context, email, EmailProvider.Discover.ALL); + for (EmailProvider provider : providers) try { - iservice.connect( - provider.imap.host, provider.imap.port, - AUTH_TYPE_PASSWORD, null, - user, password, - null, null); - } catch (EmailService.UntrustedException ex) { - imap_certificate = ex.getCertificate(); - String similar = EntityCertificate.getSimilarDnsName(imap_certificate, provider.imap.host); - if (similar == null) - imap_fingerprint = EntityCertificate.getKeyFingerprint(imap_certificate); - else - provider.imap.host = similar; - iservice.connect( - provider.imap.host, provider.imap.port, - AUTH_TYPE_PASSWORD, null, - user, password, - null, imap_fingerprint); - } catch (Throwable ex) { - Log.w(ex); - // Why not AuthenticationFailedException? - // Some providers terminate the connection with an invalid username - if (user.equals(username)) - throw ex; - else + EntityLog.log(context, "imap=" + provider.imap); + EntityLog.log(context, "smtp=" + provider.smtp); + + String user = (provider.user == EmailProvider.UserType.EMAIL ? email : username); + Log.i("User type=" + provider.user + " name=" + user); + + List folders; + String imap_fingerprint = null; + String smtp_fingerprint = null; + X509Certificate imap_certificate = null; + X509Certificate smtp_certificate = null; + + String aprotocol = (provider.imap.starttls ? "imap" : "imaps"); + int aencryption = (provider.imap.starttls ? EmailService.ENCRYPTION_STARTTLS : EmailService.ENCRYPTION_SSL); + try (EmailService iservice = new EmailService( + context, aprotocol, null, aencryption, false, EmailService.PURPOSE_CHECK, true)) { try { - user = username; - Log.i("Retry with user=" + user); iservice.connect( provider.imap.host, provider.imap.port, AUTH_TYPE_PASSWORD, null, user, password, null, null); - } catch (Throwable ex1) { - Log.w(ex1); - if (!(ex instanceof AuthenticationFailedException) && - ex1 instanceof AuthenticationFailedException) - throw ex1; + } catch (EmailService.UntrustedException ex) { + imap_certificate = ex.getCertificate(); + String similar = EntityCertificate.getSimilarDnsName(imap_certificate, provider.imap.host); + if (similar == null) + imap_fingerprint = EntityCertificate.getKeyFingerprint(imap_certificate); else + provider.imap.host = similar; + iservice.connect( + provider.imap.host, provider.imap.port, + AUTH_TYPE_PASSWORD, null, + user, password, + null, imap_fingerprint); + } catch (Throwable ex) { + Log.w(ex); + // Why not AuthenticationFailedException? + // Some providers terminate the connection with an invalid username + if (user.equals(username)) throw ex; + else + try { + user = username; + Log.i("Retry with user=" + user); + iservice.connect( + provider.imap.host, provider.imap.port, + AUTH_TYPE_PASSWORD, null, + user, password, + null, null); + } catch (Throwable ex1) { + Log.w(ex1); + if (!(ex instanceof AuthenticationFailedException) && + ex1 instanceof AuthenticationFailedException) + throw ex1; + else + throw ex; + } } - } - folders = iservice.getFolders(); - - if (folders.size() == 1 && - EntityFolder.INBOX.equals(folders.get(0).type)) - try { - Log.i("Creating system folders"); - Store istore = iservice.getStore(); - istore.getFolder(EntityFolder.DRAFTS).create(Folder.HOLDS_FOLDERS); - istore.getFolder(EntityFolder.SENT).create(Folder.HOLDS_FOLDERS); - istore.getFolder(EntityFolder.ARCHIVE).create(Folder.HOLDS_FOLDERS); - istore.getFolder(EntityFolder.TRASH).create(Folder.HOLDS_FOLDERS); - istore.getFolder(EntityFolder.JUNK).create(Folder.HOLDS_FOLDERS); folders = iservice.getFolders(); - } catch (Throwable ex) { - Log.e(ex); - } - } - Long max_size; - String iprotocol = (provider.smtp.starttls ? "smtp" : "smtps"); - int iencryption = (provider.smtp.starttls ? EmailService.ENCRYPTION_STARTTLS : EmailService.ENCRYPTION_SSL); - try (EmailService iservice = new EmailService( - context, iprotocol, null, iencryption, false, - EmailService.PURPOSE_CHECK, true)) { - iservice.setUseIp(provider.useip, null); - try { - iservice.connect( - provider.smtp.host, provider.smtp.port, - AUTH_TYPE_PASSWORD, null, - user, password, - null, null); - } catch (EmailService.UntrustedException ex) { - smtp_certificate = ex.getCertificate(); - String similar = EntityCertificate.getSimilarDnsName(smtp_certificate, provider.smtp.host); - if (similar == null) - smtp_fingerprint = EntityCertificate.getKeyFingerprint(smtp_certificate); - else - provider.smtp.host = similar; - iservice.connect( - provider.smtp.host, provider.smtp.port, - AUTH_TYPE_PASSWORD, null, - user, password, - null, smtp_fingerprint); + if (folders.size() == 1 && + EntityFolder.INBOX.equals(folders.get(0).type)) + try { + Log.i("Creating system folders"); + Store istore = iservice.getStore(); + istore.getFolder(EntityFolder.DRAFTS).create(Folder.HOLDS_FOLDERS); + istore.getFolder(EntityFolder.SENT).create(Folder.HOLDS_FOLDERS); + istore.getFolder(EntityFolder.ARCHIVE).create(Folder.HOLDS_FOLDERS); + istore.getFolder(EntityFolder.TRASH).create(Folder.HOLDS_FOLDERS); + istore.getFolder(EntityFolder.JUNK).create(Folder.HOLDS_FOLDERS); + folders = iservice.getFolders(); + } catch (Throwable ex) { + Log.e(ex); + } + } + + Long max_size; + String iprotocol = (provider.smtp.starttls ? "smtp" : "smtps"); + int iencryption = (provider.smtp.starttls ? EmailService.ENCRYPTION_STARTTLS : EmailService.ENCRYPTION_SSL); + try (EmailService iservice = new EmailService( + context, iprotocol, null, iencryption, false, + EmailService.PURPOSE_CHECK, true)) { + iservice.setUseIp(provider.useip, null); + try { + iservice.connect( + provider.smtp.host, provider.smtp.port, + AUTH_TYPE_PASSWORD, null, + user, password, + null, null); + } catch (EmailService.UntrustedException ex) { + smtp_certificate = ex.getCertificate(); + String similar = EntityCertificate.getSimilarDnsName(smtp_certificate, provider.smtp.host); + if (similar == null) + smtp_fingerprint = EntityCertificate.getKeyFingerprint(smtp_certificate); + else + provider.smtp.host = similar; + iservice.connect( + provider.smtp.host, provider.smtp.port, + AUTH_TYPE_PASSWORD, null, + user, password, + null, smtp_fingerprint); + } + + max_size = iservice.getMaxSize(); + } + + if (check) { + args.putParcelable("provider", provider); + args.putSerializable("imap_certificate", imap_certificate); + args.putSerializable("smtp_certificate", smtp_certificate); + return provider; + } + + DB db = DB.getInstance(context); + try { + db.beginTransaction(); + + EntityAccount primary = db.account().getPrimaryAccount(); + + // Create account + EntityAccount account = new EntityAccount(); + + account.host = provider.imap.host; + account.encryption = aencryption; + account.port = provider.imap.port; + account.auth_type = AUTH_TYPE_PASSWORD; + account.user = user; + account.password = password; + account.fingerprint = imap_fingerprint; + + account.name = provider.name + "/" + username; + + account.synchronize = true; + account.primary = (primary == null); + + if (provider.keepalive > 0) + account.poll_interval = provider.keepalive; + + account.partial_fetch = provider.partial; + + account.created = new Date().getTime(); + account.last_connected = account.created; + + account.id = db.account().insertAccount(account); + args.putLong("account", account.id); + EntityLog.log(context, "Quick added account=" + account.name); + + // Create folders + for (EntityFolder folder : folders) { + EntityFolder existing = db.folder().getFolderByName(account.id, folder.name); + if (existing == null) { + folder.account = account.id; + folder.setSpecials(account); + folder.id = db.folder().insertFolder(folder); + EntityLog.log(context, "Quick added folder=" + folder.name + " type=" + folder.type); + if (folder.synchronize) + EntityOperation.sync(context, folder.id, true); + } + } + + // Set swipe left/right folder + for (EntityFolder folder : folders) + if (EntityFolder.TRASH.equals(folder.type)) + account.swipe_left = folder.id; + else if (EntityFolder.ARCHIVE.equals(folder.type)) + account.swipe_right = folder.id; + + db.account().updateAccount(account); + + // Create identity + EntityIdentity identity = new EntityIdentity(); + identity.name = name; + identity.email = email; + identity.account = account.id; + + identity.host = provider.smtp.host; + identity.encryption = iencryption; + identity.port = provider.smtp.port; + identity.auth_type = AUTH_TYPE_PASSWORD; + identity.user = user; + identity.password = password; + identity.fingerprint = smtp_fingerprint; + identity.use_ip = provider.useip; + identity.synchronize = true; + identity.primary = true; + identity.max_size = max_size; + + identity.id = db.identity().insertIdentity(identity); + EntityLog.log(context, "Quick added identity=" + identity.name + " email=" + identity.email); + + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + + break; + } catch (Throwable ex) { + Log.w(ex); + if (fail == null) + fail = ex; } - max_size = iservice.getMaxSize(); - } - - if (check) { - args.putSerializable("imap_certificate", imap_certificate); - args.putSerializable("smtp_certificate", smtp_certificate); - return provider; - } - - DB db = DB.getInstance(context); - try { - db.beginTransaction(); - - EntityAccount primary = db.account().getPrimaryAccount(); - - // Create account - EntityAccount account = new EntityAccount(); - - account.host = provider.imap.host; - account.encryption = aencryption; - account.port = provider.imap.port; - account.auth_type = AUTH_TYPE_PASSWORD; - account.user = user; - account.password = password; - account.fingerprint = imap_fingerprint; - - account.name = provider.name + "/" + username; - - account.synchronize = true; - account.primary = (primary == null); - - if (provider.keepalive > 0) - account.poll_interval = provider.keepalive; - - account.partial_fetch = provider.partial; - - account.created = new Date().getTime(); - account.last_connected = account.created; - - account.id = db.account().insertAccount(account); - args.putLong("account", account.id); - EntityLog.log(context, "Quick added account=" + account.name); - - // Create folders - for (EntityFolder folder : folders) { - EntityFolder existing = db.folder().getFolderByName(account.id, folder.name); - if (existing == null) { - folder.account = account.id; - folder.setSpecials(account); - folder.id = db.folder().insertFolder(folder); - EntityLog.log(context, "Quick added folder=" + folder.name + " type=" + folder.type); - if (folder.synchronize) - EntityOperation.sync(context, folder.id, true); - } - } - - // Set swipe left/right folder - for (EntityFolder folder : folders) - if (EntityFolder.TRASH.equals(folder.type)) - account.swipe_left = folder.id; - else if (EntityFolder.ARCHIVE.equals(folder.type)) - account.swipe_right = folder.id; - - db.account().updateAccount(account); - - // Create identity - EntityIdentity identity = new EntityIdentity(); - identity.name = name; - identity.email = email; - identity.account = account.id; - - identity.host = provider.smtp.host; - identity.encryption = iencryption; - identity.port = provider.smtp.port; - identity.auth_type = AUTH_TYPE_PASSWORD; - identity.user = user; - identity.password = password; - identity.fingerprint = smtp_fingerprint; - identity.use_ip = provider.useip; - identity.synchronize = true; - identity.primary = true; - identity.max_size = max_size; - - identity.id = db.identity().insertIdentity(identity); - EntityLog.log(context, "Quick added identity=" + identity.name + " email=" + identity.email); - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } + if (fail != null) + throw fail; ServiceSynchronize.eval(context, "quick setup");