Search in sources :

Example 16 with ServerSettings

use of com.fsck.k9.mail.ServerSettings in project k-9 by k9mail.

the class ImapStoreUriDecoder method decode.

/**
     * Decodes an ImapStore URI.
     *
     * <p>Possible forms:</p>
     * <pre>
     * imap://auth:user:password@server:port ConnectionSecurity.NONE
     * imap+tls+://auth:user:password@server:port ConnectionSecurity.STARTTLS_REQUIRED
     * imap+ssl+://auth:user:password@server:port ConnectionSecurity.SSL_TLS_REQUIRED
     * </pre>
     *
     * NOTE: this method expects the userinfo part of the uri to be encoded twice, due to a bug in
     * {@link ImapStoreUriCreator#create(ServerSettings)}.
     *
     * @param uri the store uri.
     */
public static ImapStoreSettings decode(String uri) {
    String host;
    int port;
    ConnectionSecurity connectionSecurity;
    AuthType authenticationType = null;
    String username = null;
    String password = null;
    String clientCertificateAlias = null;
    String pathPrefix = null;
    boolean autoDetectNamespace = true;
    URI imapUri;
    try {
        imapUri = new URI(uri);
    } catch (URISyntaxException use) {
        throw new IllegalArgumentException("Invalid ImapStore URI", use);
    }
    String scheme = imapUri.getScheme();
    /*
         * Currently available schemes are:
         * imap
         * imap+tls+
         * imap+ssl+
         *
         * The following are obsolete schemes that may be found in pre-existing
         * settings from earlier versions or that may be found when imported. We
         * continue to recognize them and re-map them appropriately:
         * imap+tls
         * imap+ssl
         */
    if (scheme.equals("imap")) {
        connectionSecurity = ConnectionSecurity.NONE;
        port = Type.IMAP.defaultPort;
    } else if (scheme.startsWith("imap+tls")) {
        connectionSecurity = ConnectionSecurity.STARTTLS_REQUIRED;
        port = Type.IMAP.defaultPort;
    } else if (scheme.startsWith("imap+ssl")) {
        connectionSecurity = ConnectionSecurity.SSL_TLS_REQUIRED;
        port = Type.IMAP.defaultTlsPort;
    } else {
        throw new IllegalArgumentException("Unsupported protocol (" + scheme + ")");
    }
    host = imapUri.getHost();
    if (imapUri.getPort() != -1) {
        port = imapUri.getPort();
    }
    if (imapUri.getUserInfo() != null) {
        String userinfo = imapUri.getUserInfo();
        String[] userInfoParts = userinfo.split(":");
        if (userinfo.endsWith(":")) {
            // Or XOAUTH2 where it's a valid config - XOAUTH:username:
            if (userInfoParts.length > 1) {
                authenticationType = AuthType.valueOf(userInfoParts[0]);
                username = decodeUtf8(userInfoParts[1]);
            } else {
                authenticationType = AuthType.PLAIN;
                username = decodeUtf8(userInfoParts[0]);
            }
        } else if (userInfoParts.length == 2) {
            // Old/standard style of encoding - PLAIN auth only:
            // username:password
            authenticationType = AuthType.PLAIN;
            username = decodeUtf8(userInfoParts[0]);
            password = decodeUtf8(userInfoParts[1]);
        } else if (userInfoParts.length == 3) {
            // Standard encoding
            // PLAIN:username:password
            // EXTERNAL:username:certAlias
            authenticationType = AuthType.valueOf(userInfoParts[0]);
            username = decodeUtf8(userInfoParts[1]);
            if (AuthType.EXTERNAL == authenticationType) {
                clientCertificateAlias = decodeUtf8(userInfoParts[2]);
            } else {
                password = decodeUtf8(userInfoParts[2]);
            }
        }
    }
    String path = imapUri.getPath();
    if (path != null && path.length() > 1) {
        // Strip off the leading "/"
        String cleanPath = path.substring(1);
        if (cleanPath.length() >= 2 && cleanPath.charAt(1) == '|') {
            autoDetectNamespace = cleanPath.charAt(0) == '1';
            if (!autoDetectNamespace) {
                pathPrefix = cleanPath.substring(2);
            }
        } else {
            if (cleanPath.length() > 0) {
                pathPrefix = cleanPath;
                autoDetectNamespace = false;
            }
        }
    }
    return new ImapStoreSettings(host, port, connectionSecurity, authenticationType, username, password, clientCertificateAlias, autoDetectNamespace, pathPrefix);
}
Also used : ConnectionSecurity(com.fsck.k9.mail.ConnectionSecurity) AuthType(com.fsck.k9.mail.AuthType) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI)

Example 17 with ServerSettings

use of com.fsck.k9.mail.ServerSettings in project k-9 by k9mail.

the class SettingsExporter method writeAccount.

private static void writeAccount(XmlSerializer serializer, Account account, Map<String, Object> prefs) throws IOException {
    Set<Integer> identities = new HashSet<>();
    Set<String> folders = new HashSet<>();
    String accountUuid = account.getUuid();
    serializer.startTag(null, ACCOUNT_ELEMENT);
    serializer.attribute(null, UUID_ATTRIBUTE, accountUuid);
    String name = (String) prefs.get(accountUuid + "." + Account.ACCOUNT_DESCRIPTION_KEY);
    if (name != null) {
        serializer.startTag(null, NAME_ELEMENT);
        serializer.text(name);
        serializer.endTag(null, NAME_ELEMENT);
    }
    // Write incoming server settings
    ServerSettings incoming = RemoteStore.decodeStoreUri(account.getStoreUri());
    serializer.startTag(null, INCOMING_SERVER_ELEMENT);
    serializer.attribute(null, TYPE_ATTRIBUTE, incoming.type.name());
    writeElement(serializer, HOST_ELEMENT, incoming.host);
    if (incoming.port != -1) {
        writeElement(serializer, PORT_ELEMENT, Integer.toString(incoming.port));
    }
    if (incoming.connectionSecurity != null) {
        writeElement(serializer, CONNECTION_SECURITY_ELEMENT, incoming.connectionSecurity.name());
    }
    if (incoming.authenticationType != null) {
        writeElement(serializer, AUTHENTICATION_TYPE_ELEMENT, incoming.authenticationType.name());
    }
    writeElement(serializer, USERNAME_ELEMENT, incoming.username);
    writeElement(serializer, CLIENT_CERTIFICATE_ALIAS_ELEMENT, incoming.clientCertificateAlias);
    // XXX For now we don't export the password
    //writeElement(serializer, PASSWORD_ELEMENT, incoming.password);
    Map<String, String> extras = incoming.getExtra();
    if (extras != null && extras.size() > 0) {
        serializer.startTag(null, EXTRA_ELEMENT);
        for (Entry<String, String> extra : extras.entrySet()) {
            writeKeyAndPrettyValueFromSetting(serializer, extra.getKey(), extra.getValue());
        }
        serializer.endTag(null, EXTRA_ELEMENT);
    }
    serializer.endTag(null, INCOMING_SERVER_ELEMENT);
    // Write outgoing server settings
    ServerSettings outgoing = Transport.decodeTransportUri(account.getTransportUri());
    serializer.startTag(null, OUTGOING_SERVER_ELEMENT);
    serializer.attribute(null, TYPE_ATTRIBUTE, outgoing.type.name());
    writeElement(serializer, HOST_ELEMENT, outgoing.host);
    if (outgoing.port != -1) {
        writeElement(serializer, PORT_ELEMENT, Integer.toString(outgoing.port));
    }
    if (outgoing.connectionSecurity != null) {
        writeElement(serializer, CONNECTION_SECURITY_ELEMENT, outgoing.connectionSecurity.name());
    }
    if (outgoing.authenticationType != null) {
        writeElement(serializer, AUTHENTICATION_TYPE_ELEMENT, outgoing.authenticationType.name());
    }
    writeElement(serializer, USERNAME_ELEMENT, outgoing.username);
    writeElement(serializer, CLIENT_CERTIFICATE_ALIAS_ELEMENT, outgoing.clientCertificateAlias);
    // XXX For now we don't export the password
    //writeElement(serializer, PASSWORD_ELEMENT, outgoing.password);
    extras = outgoing.getExtra();
    if (extras != null && extras.size() > 0) {
        serializer.startTag(null, EXTRA_ELEMENT);
        for (Entry<String, String> extra : extras.entrySet()) {
            writeKeyAndPrettyValueFromSetting(serializer, extra.getKey(), extra.getValue());
        }
        serializer.endTag(null, EXTRA_ELEMENT);
    }
    serializer.endTag(null, OUTGOING_SERVER_ELEMENT);
    // Write account settings
    serializer.startTag(null, SETTINGS_ELEMENT);
    for (Map.Entry<String, Object> entry : prefs.entrySet()) {
        String key = entry.getKey();
        String valueString = entry.getValue().toString();
        String[] comps = key.split("\\.", 2);
        if (comps.length < 2) {
            // Skip global settings
            continue;
        }
        String keyUuid = comps[0];
        String keyPart = comps[1];
        if (!keyUuid.equals(accountUuid)) {
            // Setting doesn't belong to the account we're currently writing.
            continue;
        }
        int indexOfLastDot = keyPart.lastIndexOf(".");
        boolean hasThirdPart = indexOfLastDot != -1 && indexOfLastDot < keyPart.length() - 1;
        if (hasThirdPart) {
            String secondPart = keyPart.substring(0, indexOfLastDot);
            String thirdPart = keyPart.substring(indexOfLastDot + 1);
            if (Account.IDENTITY_DESCRIPTION_KEY.equals(secondPart)) {
                // This is an identity key. Save identity index for later...
                try {
                    identities.add(Integer.parseInt(thirdPart));
                } catch (NumberFormatException e) {
                /* ignore */
                }
                // ... but don't write it now.
                continue;
            }
            if (FolderSettings.SETTINGS.containsKey(thirdPart)) {
                // This is a folder key. Save folder name for later...
                folders.add(secondPart);
                // ... but don't write it now.
                continue;
            }
        }
        TreeMap<Integer, SettingsDescription> versionedSetting = AccountSettings.SETTINGS.get(keyPart);
        if (versionedSetting != null) {
            Integer highestVersion = versionedSetting.lastKey();
            SettingsDescription setting = versionedSetting.get(highestVersion);
            if (setting != null) {
                // Only export account settings that can be found in AccountSettings.SETTINGS
                try {
                    writeKeyAndPrettyValueFromSetting(serializer, keyPart, setting, valueString);
                } catch (InvalidSettingValueException e) {
                    Timber.w("Account setting \"%s\" (%s) has invalid value \"%s\" in preference storage. " + "This shouldn't happen!", keyPart, account.getDescription(), valueString);
                }
            }
        }
    }
    serializer.endTag(null, SETTINGS_ELEMENT);
    if (identities.size() > 0) {
        serializer.startTag(null, IDENTITIES_ELEMENT);
        // Sort identity indices (that's why we store them as Integers)
        List<Integer> sortedIdentities = new ArrayList<>(identities);
        Collections.sort(sortedIdentities);
        for (Integer identityIndex : sortedIdentities) {
            writeIdentity(serializer, accountUuid, identityIndex.toString(), prefs);
        }
        serializer.endTag(null, IDENTITIES_ELEMENT);
    }
    if (folders.size() > 0) {
        serializer.startTag(null, FOLDERS_ELEMENT);
        for (String folder : folders) {
            writeFolder(serializer, accountUuid, folder, prefs);
        }
        serializer.endTag(null, FOLDERS_ELEMENT);
    }
    serializer.endTag(null, ACCOUNT_ELEMENT);
}
Also used : ArrayList(java.util.ArrayList) SettingsDescription(com.fsck.k9.preferences.Settings.SettingsDescription) InvalidSettingValueException(com.fsck.k9.preferences.Settings.InvalidSettingValueException) ServerSettings(com.fsck.k9.mail.ServerSettings) Map(java.util.Map) TreeMap(java.util.TreeMap) HashSet(java.util.HashSet)

Example 18 with ServerSettings

use of com.fsck.k9.mail.ServerSettings in project k-9 by k9mail.

the class SmtpTransportUriTest method decodeUri_canDecodePassword.

@Test
public void decodeUri_canDecodePassword() {
    String storeUri = "smtp://user:password:PLAIN@server:123456";
    ServerSettings result = SmtpTransport.decodeUri(storeUri);
    assertEquals("password", result.password);
}
Also used : ServerSettings(com.fsck.k9.mail.ServerSettings) Test(org.junit.Test)

Example 19 with ServerSettings

use of com.fsck.k9.mail.ServerSettings in project k-9 by k9mail.

the class SmtpTransportUriTest method decodeUri_canDecodeUsername_withNoPasswordOrAuthType.

@Test
public void decodeUri_canDecodeUsername_withNoPasswordOrAuthType() {
    String storeUri = "smtp://user@server:123456";
    ServerSettings result = SmtpTransport.decodeUri(storeUri);
    assertEquals("user", result.username);
}
Also used : ServerSettings(com.fsck.k9.mail.ServerSettings) Test(org.junit.Test)

Example 20 with ServerSettings

use of com.fsck.k9.mail.ServerSettings in project k-9 by k9mail.

the class SmtpTransportUriTest method decodeUri_canDecodeUsername_withNoAuthType.

@Test
public void decodeUri_canDecodeUsername_withNoAuthType() {
    String storeUri = "smtp://user:password@server:123456";
    ServerSettings result = SmtpTransport.decodeUri(storeUri);
    assertEquals("user", result.username);
}
Also used : ServerSettings(com.fsck.k9.mail.ServerSettings) Test(org.junit.Test)

Aggregations

ServerSettings (com.fsck.k9.mail.ServerSettings)45 Test (org.junit.Test)34 URISyntaxException (java.net.URISyntaxException)9 AuthType (com.fsck.k9.mail.AuthType)8 URI (java.net.URI)7 HashMap (java.util.HashMap)5 ConnectionSecurity (com.fsck.k9.mail.ConnectionSecurity)4 InvalidSettingValueException (com.fsck.k9.preferences.Settings.InvalidSettingValueException)2 Map (java.util.Map)2 SharedPreferences (android.content.SharedPreferences)1 OnCheckedChangeListener (android.widget.CompoundButton.OnCheckedChangeListener)1 Account (com.fsck.k9.Account)1 Preferences (com.fsck.k9.Preferences)1 Store (com.fsck.k9.mail.Store)1 RemoteStore (com.fsck.k9.mail.store.RemoteStore)1 StoreConfig (com.fsck.k9.mail.store.StoreConfig)1 ImapStoreSettings (com.fsck.k9.mail.store.imap.ImapStoreSettings)1 WebDavStoreSettings (com.fsck.k9.mail.store.webdav.WebDavStoreSettings)1 SettingsDescription (com.fsck.k9.preferences.Settings.SettingsDescription)1 ArrayList (java.util.ArrayList)1