Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf3e3ec3 authored by Nihar Thakkar's avatar Nihar Thakkar Committed by Sumit Pundir
Browse files

Fix bug causing an authentication error

parent f59fe81c
Loading
Loading
Loading
Loading
+114 −14
Original line number Diff line number Diff line
@@ -5,9 +5,10 @@ package io.eelo.mail.activity;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.EnumSet;
import java.util.HashSet;
@@ -32,12 +33,14 @@ import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.XmlResourceParser;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.text.Editable;
import android.text.TextWatcher;
import io.eelo.mail.activity.setup.AccountSetupActivity;
@@ -78,6 +81,7 @@ import io.eelo.mail.R;
import io.eelo.mail.activity.compose.MessageActions;
import io.eelo.mail.activity.misc.ExtendedAsyncTask;
import io.eelo.mail.activity.misc.NonConfigurationInstance;
import io.eelo.mail.activity.setup.AccountSetupPresenter;
import io.eelo.mail.activity.setup.EeloAccountCreator;
import io.eelo.mail.activity.setup.GoogleAccountCreator;
import io.eelo.mail.activity.setup.AccountSettings;
@@ -85,6 +89,8 @@ import io.eelo.mail.activity.setup.Prefs;
import io.eelo.mail.activity.setup.WelcomeMessage;
import io.eelo.mail.activity.setup.WelcomeMessage;
import io.eelo.mail.controller.MessagingController;
import io.eelo.mail.helper.EmailHelper;
import io.eelo.mail.helper.UrlEncodingHelper;
import io.eelo.mail.helper.SizeFormatter;
import io.eelo.mail.mail.AuthType;
import io.eelo.mail.mail.ServerSettings;
@@ -470,24 +476,118 @@ public class Accounts extends K9ListActivity implements OnItemClickListener {
                                                 String deviceAccountEmailId,
                                                 String deviceAccountPassword) {
        try {
            String deviceAccountStoreUri = "imap+ssl+://" +
                    URLEncoder.encode(deviceAccountEmailId, "UTF-8") + ":" +
                    URLEncoder.encode(deviceAccountPassword, "UTF-8") + "@mail.cloud.global";
            String deviceAccountTransportUri = "smtp+tls+://" +
                    URLEncoder.encode(deviceAccountEmailId, "UTF-8") + ":" +
                    URLEncoder.encode(deviceAccountPassword, "UTF-8") + "@mail.cloud.global";
            String[] emailParts = EmailHelper.splitEmail(deviceAccountEmailId);
            AccountSetupPresenter.Provider provider = findProviderForDomain(this, emailParts[1]);

            if (provider != null) {
                ArrayList<String> uris = getURIs(deviceAccountEmailId, deviceAccountPassword, provider);
                String deviceAccountStoreUri = uris.get(0);
                String deviceAccountTransportUri = uris.get(1);

                if (deviceAccountStoreUri.equals(account.getStoreUri()) &&
                        deviceAccountTransportUri.equals(account.getTransportUri())) {
                    return false;
                }

            }
        }
        catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            Timber.e(e, "Error while trying to initialise account configuration.");
	}
        return true;
    }

    private static AccountSetupPresenter.Provider findProviderForDomain(Context context,
                                                                        String domain) {
        try {
            XmlResourceParser xml = context.getResources().getXml(io.eelo.mail.R.xml.providers);
            int xmlEventType;
            AccountSetupPresenter.Provider provider = null;
            while ((xmlEventType = xml.next()) != XmlResourceParser.END_DOCUMENT) {
                if (xmlEventType == XmlResourceParser.START_TAG
                        && "provider".equals(xml.getName())
                        && domain.equalsIgnoreCase(getXmlAttribute(context, xml, "domain"))) {
                    provider = new AccountSetupPresenter.Provider();
                    provider.id = getXmlAttribute(context, xml, "id");
                    provider.label = getXmlAttribute(context, xml, "label");
                    provider.domain = getXmlAttribute(context, xml, "domain");
                    provider.note = getXmlAttribute(context, xml, "note");
                } else if (xmlEventType == XmlResourceParser.START_TAG
                        && "incoming".equals(xml.getName())
                        && provider != null) {
                    provider.incomingUriTemplate = new URI(getXmlAttribute(context, xml, "uri"));
                    provider.incomingUsernameTemplate = getXmlAttribute(context, xml, "username");
                } else if (xmlEventType == XmlResourceParser.START_TAG
                        && "outgoing".equals(xml.getName())
                        && provider != null) {
                    provider.outgoingUriTemplate = new URI(getXmlAttribute(context, xml, "uri"));
                    provider.outgoingUsernameTemplate = getXmlAttribute(context, xml, "username");
                } else if (xmlEventType == XmlResourceParser.END_TAG
                        && "provider".equals(xml.getName())
                        && provider != null) {
                    return provider;
                }
            }
        } catch (Exception e) {
            Timber.e(e, "Error while trying to load provider settings.");
        }
        return null;
    }

    private static String getXmlAttribute(Context context, XmlResourceParser xml, String name) {
        int resId = xml.getAttributeResourceValue(null, name, 0);
        if (resId == 0) {
            return xml.getAttributeValue(null, name);
        } else {
            return context.getString(resId);
        }
    }

    private ArrayList<String> getURIs(String email, String password,
                                      @NonNull AccountSetupPresenter.Provider provider)
            throws URISyntaxException {
        String[] emailParts = EmailHelper.splitEmail(email);
        String user = emailParts[0];
        String domain = emailParts[1];
        String userEnc = UrlEncodingHelper.encodeUtf8(user);
        String passwordEnc = UrlEncodingHelper.encodeUtf8(password);

        String incomingUsername = provider.incomingUsernameTemplate;
        incomingUsername = incomingUsername.replaceAll("\\$email", email);
        incomingUsername = incomingUsername.replaceAll("\\$user", userEnc);
        incomingUsername = incomingUsername.replaceAll("\\$domain", domain);

        URI incomingUriTemplate = provider.incomingUriTemplate;
        String incomingUserInfo = incomingUsername + ":" + passwordEnc;
        URI incomingUri = new URI(incomingUriTemplate.getScheme(), incomingUserInfo,
                incomingUriTemplate.getHost(), incomingUriTemplate.getPort(), null, null, null);

        String outgoingUsername = provider.outgoingUsernameTemplate;

        URI outgoingUriTemplate = provider.outgoingUriTemplate;


        URI outgoingUri;
        if (outgoingUsername != null) {
            outgoingUsername = outgoingUsername.replaceAll("\\$email", email);
            outgoingUsername = outgoingUsername.replaceAll("\\$user", userEnc);
            outgoingUsername = outgoingUsername.replaceAll("\\$domain", domain);

            String outgoingUserInfo = outgoingUsername + ":" + passwordEnc;
            outgoingUri = new URI(outgoingUriTemplate.getScheme(), outgoingUserInfo,
                    outgoingUriTemplate.getHost(), outgoingUriTemplate.getPort(), null,
                    null, null);

        } else {
            outgoingUri = new URI(outgoingUriTemplate.getScheme(),
                    null, outgoingUriTemplate.getHost(), outgoingUriTemplate.getPort(), null,
                    null, null);

        }

        return new ArrayList<>(Arrays.asList(incomingUri.toString(), outgoingUri.toString()));
    }

    private void checkSyncStatus(List<Account> accounts) {
        try {
            android.accounts.Account[] eeloAccounts = getEeloAccountsOnDevice();
+1 −1
Original line number Diff line number Diff line
@@ -1008,7 +1008,7 @@ public class AccountSetupPresenter implements AccountSetupContract.Presenter,
        }
    }

    private static class Provider implements Serializable {
    public static class Provider implements Serializable {
        private static final long serialVersionUID = 8511656164616538989L;

        public String id;
+137 −19
Original line number Diff line number Diff line
package io.eelo.mail.activity.setup;

import android.content.Context;
import android.util.Log;
import android.content.res.XmlResourceParser;
import android.support.annotation.NonNull;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Locale;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
@@ -9,31 +14,30 @@ import java.net.URLEncoder;
import io.eelo.mail.Account;
import io.eelo.mail.K9;
import io.eelo.mail.Preferences;
import io.eelo.mail.account.AccountCreator;
import io.eelo.mail.controller.MessagingController;
import io.eelo.mail.helper.EmailHelper;
import io.eelo.mail.helper.UrlEncodingHelper;
import io.eelo.mail.mail.ServerSettings;
import io.eelo.mail.mail.store.RemoteStore;
import timber.log.Timber;

public class EeloAccountCreator {
    private static AccountConfigImpl accountConfig;

    public static void createAccount(Context context, String emailId, String password) {
        Preferences preferences = Preferences.getPreferences(context);
	
        AccountConfigImpl accountConfig = new AccountConfigImpl(preferences);
        accountConfig.setEmail(emailId);
        accountConfig.setDescription(emailId);
        accountConfig.setTrashFolderName("Trash");
        accountConfig.setArchiveFolderName("Archive");
        accountConfig.setDraftsFolderName("Drafts");
        accountConfig.setInboxFolderName("INBOX");
        accountConfig.setSentFolderName("Sent");
        accountConfig.setSpamFolderName("Spam");
        accountConfig.setAutoExpandFolderName("INBOX");

	accountConfig = new AccountConfigImpl(preferences);
        try {
            accountConfig.setStoreUri("imap+ssl+://" + URLEncoder.encode(emailId, "UTF-8") +
                    ":" + URLEncoder.encode(password, "UTF-8") + "@mail.cloud.global");
            accountConfig.setTransportUri("smtp+tls+://" + URLEncoder.encode(emailId, "UTF-8") +
                    ":" + URLEncoder.encode(password, "UTF-8") + "@mail.cloud.global");
	    String[] emailParts = EmailHelper.splitEmail(emailId);
            AccountSetupPresenter.Provider provider = findProviderForDomain(context, emailParts[1]);
            if (provider != null) {
                modifyAccount(emailId, password, provider);
            }
        catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
	catch (Exception e) {
            Timber.e(e, "Error while trying to initialise account configuration.");
        }

        Account account = preferences.newAccount();
@@ -50,5 +54,119 @@ public class EeloAccountCreator {

        K9.setServicesEnabled(context);
    }

    private static void modifyAccount(String email, String password,
                                      @NonNull AccountSetupPresenter.Provider provider)
            throws URISyntaxException {
        accountConfig.init(email, password);
        accountConfig.setDescription(email);

        String[] emailParts = EmailHelper.splitEmail(email);
        String user = emailParts[0];
        String domain = emailParts[1];
        String userEnc = UrlEncodingHelper.encodeUtf8(user);
        String passwordEnc = UrlEncodingHelper.encodeUtf8(password);

        String incomingUsername = provider.incomingUsernameTemplate;
        incomingUsername = incomingUsername.replaceAll("\\$email", email);
        incomingUsername = incomingUsername.replaceAll("\\$user", userEnc);
        incomingUsername = incomingUsername.replaceAll("\\$domain", domain);

        URI incomingUriTemplate = provider.incomingUriTemplate;
        String incomingUserInfo = incomingUsername + ":" + passwordEnc;
        URI incomingUri = new URI(incomingUriTemplate.getScheme(), incomingUserInfo,
                incomingUriTemplate.getHost(), incomingUriTemplate.getPort(), null, null, null);

        String outgoingUsername = provider.outgoingUsernameTemplate;

        URI outgoingUriTemplate = provider.outgoingUriTemplate;


        URI outgoingUri;
        if (outgoingUsername != null) {
            outgoingUsername = outgoingUsername.replaceAll("\\$email", email);
            outgoingUsername = outgoingUsername.replaceAll("\\$user", userEnc);
            outgoingUsername = outgoingUsername.replaceAll("\\$domain", domain);

            String outgoingUserInfo = outgoingUsername + ":" + passwordEnc;
            outgoingUri = new URI(outgoingUriTemplate.getScheme(), outgoingUserInfo,
                    outgoingUriTemplate.getHost(), outgoingUriTemplate.getPort(), null,
                    null, null);

        } else {
            outgoingUri = new URI(outgoingUriTemplate.getScheme(),
                    null, outgoingUriTemplate.getHost(), outgoingUriTemplate.getPort(), null,
                    null, null);

        }

        accountConfig.setStoreUri(incomingUri.toString());
        accountConfig.setTransportUri(outgoingUri.toString());

        setupFolderNames(incomingUriTemplate.getHost().toLowerCase(Locale.US));

        ServerSettings incomingSettings = RemoteStore.decodeStoreUri(incomingUri.toString());
        accountConfig.setDeletePolicy(AccountCreator.getDefaultDeletePolicy(incomingSettings.type));
    }

    private static void setupFolderNames(String domain) {
        accountConfig.setDraftsFolderName(K9.getK9String(io.eelo.mail.R.string.special_mailbox_name_drafts));
        accountConfig.setTrashFolderName(K9.getK9String(io.eelo.mail.R.string.special_mailbox_name_trash));
        accountConfig.setSentFolderName(K9.getK9String(io.eelo.mail.R.string.special_mailbox_name_sent));
        accountConfig.setArchiveFolderName(K9.getK9String(io.eelo.mail.R.string.special_mailbox_name_archive));

        // Yahoo! has a special folder for Spam, called "Bulk Mail".
        if (domain.endsWith(".yahoo.com")) {
            accountConfig.setSpamFolderName("Bulk Mail");
        } else {
            accountConfig.setSpamFolderName(K9.getK9String(io.eelo.mail.R.string.special_mailbox_name_spam));
        }
    }

    private static AccountSetupPresenter.Provider findProviderForDomain(Context context,
                                                                        String domain) {
        try {
            XmlResourceParser xml = context.getResources().getXml(io.eelo.mail.R.xml.providers);
            int xmlEventType;
            AccountSetupPresenter.Provider provider = null;
            while ((xmlEventType = xml.next()) != XmlResourceParser.END_DOCUMENT) {
                if (xmlEventType == XmlResourceParser.START_TAG
                        && "provider".equals(xml.getName())
                        && domain.equalsIgnoreCase(getXmlAttribute(context, xml, "domain"))) {
                    provider = new AccountSetupPresenter.Provider();
                    provider.id = getXmlAttribute(context, xml, "id");
                    provider.label = getXmlAttribute(context, xml, "label");
                    provider.domain = getXmlAttribute(context, xml, "domain");
                    provider.note = getXmlAttribute(context, xml, "note");
                } else if (xmlEventType == XmlResourceParser.START_TAG
                        && "incoming".equals(xml.getName())
                        && provider != null) {
                    provider.incomingUriTemplate = new URI(getXmlAttribute(context, xml, "uri"));
                    provider.incomingUsernameTemplate = getXmlAttribute(context, xml, "username");
                } else if (xmlEventType == XmlResourceParser.START_TAG
                        && "outgoing".equals(xml.getName())
                        && provider != null) {
                    provider.outgoingUriTemplate = new URI(getXmlAttribute(context, xml, "uri"));
                    provider.outgoingUsernameTemplate = getXmlAttribute(context, xml, "username");
                } else if (xmlEventType == XmlResourceParser.END_TAG
                        && "provider".equals(xml.getName())
                        && provider != null) {
                    return provider;
                }
            }
        } catch (Exception e) {
            Timber.e(e, "Error while trying to load provider settings.");
        }
        return null;
    }

    private static String getXmlAttribute(Context context, XmlResourceParser xml, String name) {
        int resId = xml.getAttributeResourceValue(null, name, 0);
        if (resId == 0) {
            return xml.getAttributeValue(null, name);
        } else {
            return context.getString(resId);
        }
    }
}
+112 −13
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@ package io.eelo.mail.controller;

import java.io.CharArrayWriter;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.io.UnsupportedEncodingException;
@@ -35,6 +37,7 @@ import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.XmlResourceParser;
import android.content.pm.PackageInfo;
import android.database.Cursor;
import android.net.Uri;
@@ -59,6 +62,7 @@ import io.eelo.mail.Preferences;
import io.eelo.mail.R;
import io.eelo.mail.activity.ActivityListener;
import io.eelo.mail.activity.MessageReference;
import io.eelo.mail.activity.setup.AccountSetupPresenter;
import io.eelo.mail.activity.setup.CheckDirection;
import io.eelo.mail.activity.setup.AccountSetupCheckSettings.CheckDirection;
import io.eelo.mail.cache.EmailProviderCache;
@@ -72,6 +76,8 @@ import io.eelo.mail.controller.MessagingControllerCommands.PendingSetFlag;
import io.eelo.mail.controller.ProgressBodyFactory.ProgressListener;
import io.eelo.mail.controller.imap.ImapMessageStore;
import io.eelo.mail.helper.Contacts;
import io.eelo.mail.helper.EmailHelper;
import io.eelo.mail.helper.UrlEncodingHelper;
import io.eelo.mail.mail.Address;
import io.eelo.mail.mail.AuthenticationFailedException;
import io.eelo.mail.mail.BodyFactory;
@@ -3465,24 +3471,117 @@ public class MessagingController {
                                      String deviceAccountEmailId,
                                      String deviceAccountPassword) {
	try {
            String deviceAccountStoreUri = "imap+ssl+://" +
                    URLEncoder.encode(deviceAccountEmailId, "UTF-8") + ":" +
                    URLEncoder.encode(deviceAccountPassword, "UTF-8") + "@mail.ecloud.global";
            String deviceAccountTransportUri = "smtp+tls+://" +
                    URLEncoder.encode(deviceAccountEmailId, "UTF-8") + ":" +
                    URLEncoder.encode(deviceAccountPassword, "UTF-8") + "@mail.ecloud.global";
	    String[] emailParts = EmailHelper.splitEmail(deviceAccountEmailId);
            AccountSetupPresenter.Provider provider = findProviderForDomain(context, emailParts[1]);

            if (provider != null) {
                ArrayList<String> uris = getURIs(deviceAccountEmailId, deviceAccountPassword, provider);
                String deviceAccountStoreUri = uris.get(0);
                String deviceAccountTransportUri = uris.get(1);

                if (deviceAccountStoreUri.equals(account.getStoreUri()) &&
                        deviceAccountTransportUri.equals(account.getTransportUri())) {
                    return false;
                }
	    }
        catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
	catch (Exception e) {
            Timber.e(e, "Error while trying to initialise account configuration.");
	}
        return true;
    }

     private static AccountSetupPresenter.Provider findProviderForDomain(Context context,
                                                                        String domain) {
        try {
            XmlResourceParser xml = context.getResources().getXml(io.eelo.mail.R.xml.providers);
            int xmlEventType;
            AccountSetupPresenter.Provider provider = null;
            while ((xmlEventType = xml.next()) != XmlResourceParser.END_DOCUMENT) {
                if (xmlEventType == XmlResourceParser.START_TAG
                        && "provider".equals(xml.getName())
                        && domain.equalsIgnoreCase(getXmlAttribute(context, xml, "domain"))) {
                    provider = new AccountSetupPresenter.Provider();
                    provider.id = getXmlAttribute(context, xml, "id");
                    provider.label = getXmlAttribute(context, xml, "label");
                    provider.domain = getXmlAttribute(context, xml, "domain");
                    provider.note = getXmlAttribute(context, xml, "note");
                } else if (xmlEventType == XmlResourceParser.START_TAG
                        && "incoming".equals(xml.getName())
                        && provider != null) {
                    provider.incomingUriTemplate = new URI(getXmlAttribute(context, xml, "uri"));
                    provider.incomingUsernameTemplate = getXmlAttribute(context, xml, "username");
                } else if (xmlEventType == XmlResourceParser.START_TAG
                        && "outgoing".equals(xml.getName())
                        && provider != null) {
                    provider.outgoingUriTemplate = new URI(getXmlAttribute(context, xml, "uri"));
                    provider.outgoingUsernameTemplate = getXmlAttribute(context, xml, "username");
                } else if (xmlEventType == XmlResourceParser.END_TAG
                        && "provider".equals(xml.getName())
                        && provider != null) {
                    return provider;
                }
            }
        } catch (Exception e) {
            Timber.e(e, "Error while trying to load provider settings.");
        }
        return null;
    }

    private static String getXmlAttribute(Context context, XmlResourceParser xml, String name) {
        int resId = xml.getAttributeResourceValue(null, name, 0);
        if (resId == 0) {
            return xml.getAttributeValue(null, name);
        } else {
            return context.getString(resId);
        }
    }

    private ArrayList<String> getURIs(String email, String password,
                                      @NonNull AccountSetupPresenter.Provider provider)
            throws URISyntaxException {
        String[] emailParts = EmailHelper.splitEmail(email);
        String user = emailParts[0];
        String domain = emailParts[1];
        String userEnc = UrlEncodingHelper.encodeUtf8(user);
        String passwordEnc = UrlEncodingHelper.encodeUtf8(password);

        String incomingUsername = provider.incomingUsernameTemplate;
        incomingUsername = incomingUsername.replaceAll("\\$email", email);
        incomingUsername = incomingUsername.replaceAll("\\$user", userEnc);
        incomingUsername = incomingUsername.replaceAll("\\$domain", domain);

        URI incomingUriTemplate = provider.incomingUriTemplate;
        String incomingUserInfo = incomingUsername + ":" + passwordEnc;
        URI incomingUri = new URI(incomingUriTemplate.getScheme(), incomingUserInfo,
                incomingUriTemplate.getHost(), incomingUriTemplate.getPort(), null, null, null);

        String outgoingUsername = provider.outgoingUsernameTemplate;

        URI outgoingUriTemplate = provider.outgoingUriTemplate;


        URI outgoingUri;
        if (outgoingUsername != null) {
            outgoingUsername = outgoingUsername.replaceAll("\\$email", email);
            outgoingUsername = outgoingUsername.replaceAll("\\$user", userEnc);
            outgoingUsername = outgoingUsername.replaceAll("\\$domain", domain);

            String outgoingUserInfo = outgoingUsername + ":" + passwordEnc;
            outgoingUri = new URI(outgoingUriTemplate.getScheme(), outgoingUserInfo,
                    outgoingUriTemplate.getHost(), outgoingUriTemplate.getPort(), null,
                    null, null);

        } else {
            outgoingUri = new URI(outgoingUriTemplate.getScheme(),
                    null, outgoingUriTemplate.getHost(), outgoingUriTemplate.getPort(), null,
                    null, null);

        }

        return new ArrayList<>(Arrays.asList(incomingUri.toString(), outgoingUri.toString()));
    }

    private boolean isAccountSignedInOnDevice(AccountManager accountManager, Account account){
        try {
            android.accounts.Account[] eeloAccounts = getEeloAccountsOnDevice(accountManager);