@Override protected Boolean doInBackground(Void... params) { try { ContentResolver resolver = mContext.getContentResolver(); InputStream is = resolver.openInputStream(mUri); try { mImportContents = SettingsImporter.getImportStreamContents(is); } finally { try { is.close(); } catch (IOException e) { /* Ignore */ } } } catch (SettingsImportExportException e) { Timber.w(e, "Exception during export"); return false; } catch (FileNotFoundException e) { Timber.w("Couldn't read content from URI %s", mUri); return false; } return true; }
@Override protected Boolean doInBackground(Void... params) { try { InputStream is = mContext.getContentResolver().openInputStream(mUri); try { mImportResults = SettingsImporter.importSettings(mContext, is, mIncludeGlobals, mAccountUuids, mOverwrite); } finally { try { is.close(); } catch (IOException e) { /* Ignore */ } } } catch (SettingsImportExportException e) { Timber.w(e, "Exception during import"); return false; } catch (FileNotFoundException e) { Timber.w(e, "Couldn't open import file"); return false; } catch (Exception e) { Timber.w(e, "Unknown error"); return false; } return true; }
UUID.fromString(uuid); } catch (Exception e) { skipToEndTag(xpp, SettingsExporter.ACCOUNT_ELEMENT); Timber.w("Skipping account with invalid UUID %s", uuid); return null; String element = xpp.getName(); if (SettingsExporter.NAME_ELEMENT.equals(element)) { account.name = getText(xpp); } else if (SettingsExporter.INCOMING_SERVER_ELEMENT.equals(element)) { if (overview) { skipToEndTag(xpp, SettingsExporter.INCOMING_SERVER_ELEMENT); } else { account.incoming = parseServerSettings(xpp, SettingsExporter.INCOMING_SERVER_ELEMENT); skipToEndTag(xpp, SettingsExporter.OUTGOING_SERVER_ELEMENT); } else { account.outgoing = parseServerSettings(xpp, SettingsExporter.OUTGOING_SERVER_ELEMENT); skipToEndTag(xpp, SettingsExporter.SETTINGS_ELEMENT); } else { account.settings = parseSettings(xpp, SettingsExporter.SETTINGS_ELEMENT); account.identities = parseIdentities(xpp); } else if (SettingsExporter.FOLDERS_ELEMENT.equals(element)) { if (overview) { skipToEndTag(xpp, SettingsExporter.FOLDERS_ELEMENT); } else { account.folders = parseFolders(xpp);
private static ImportedIdentity parseIdentity(XmlPullParser xpp) throws XmlPullParserException, IOException { ImportedIdentity identity = new ImportedIdentity(); int eventType = xpp.next(); while (!(eventType == XmlPullParser.END_TAG && SettingsExporter.IDENTITY_ELEMENT.equals(xpp.getName()))) { if (eventType == XmlPullParser.START_TAG) { String element = xpp.getName(); if (SettingsExporter.NAME_ELEMENT.equals(element)) { identity.name = getText(xpp); } else if (SettingsExporter.EMAIL_ELEMENT.equals(element)) { identity.email = getText(xpp); } else if (SettingsExporter.DESCRIPTION_ELEMENT.equals(element)) { identity.description = getText(xpp); } else if (SettingsExporter.SETTINGS_ELEMENT.equals(element)) { identity.settings = parseSettings(xpp, SettingsExporter.SETTINGS_ELEMENT); } else { Timber.w("Unexpected start tag: %s", xpp.getName()); } } eventType = xpp.next(); } return identity; }
validateFileFormatVersion(fileFormatVersionString); result.contentVersion = validateContentVersion(contentVersionString); if (overview) { result.globalSettings = new ImportedSettings(); skipToEndTag(xpp, SettingsExporter.GLOBAL_ELEMENT); } else { result.globalSettings = parseSettings(xpp, SettingsExporter.GLOBAL_ELEMENT); skipToEndTag(xpp, SettingsExporter.GLOBAL_ELEMENT); Timber.w("More than one global settings element. Only using the first one!"); skipToEndTag(xpp, SettingsExporter.GLOBAL_ELEMENT); Timber.i("Skipping global settings"); result.accounts = parseAccounts(xpp, accountUuids, overview); } else { Timber.w("More than one accounts element. Only using the first one!");
List<AccountDescription> erroneousAccounts = new ArrayList<>(); Imported imported = parseSettings(inputStream, globalSettings, accountUuids, false); StorageEditor editor = preferences.createStorageEditor(); if (imported.globalSettings != null) { importGlobalSettings(storage, editor, imported.contentVersion, imported.globalSettings); } else { Timber.w("Was asked to import global settings but none found."); StorageEditor editor = preferences.createStorageEditor(); AccountDescriptionPair importResult = importAccount(context, editor, imported.contentVersion, account, overwrite); oldAccountUuids + "," + newUuid : newUuid; putString(editor, "accountUuids", newAccountUuids); putString(editor, "defaultAccountUuid", accountUuids.get(0));
if (isAccountNameUsed(accountName, accounts)) { if (!isAccountNameUsed(accountName, accounts)) { break; putString(editor, accountKeyPrefix + AccountPreferenceSerializer.ACCOUNT_DESCRIPTION_KEY, accountName); BackendManager backendManager = DI.get(BackendManager.class); String storeUri = backendManager.createStoreUri(incoming); putString(editor, accountKeyPrefix + AccountPreferenceSerializer.STORE_URI_KEY, Base64.encode(storeUri)); putString(editor, accountKeyPrefix + AccountPreferenceSerializer.TRANSPORT_URI_KEY, Base64.encode(transportUri)); String key = accountKeyPrefix + setting.getKey(); String value = setting.getValue(); putString(editor, key, value); putString(editor, accountKeyPrefix + "accountNumber", Integer.toString(newAccountNumber)); importIdentities(editor, contentVersion, uuid, account, overwrite, existingAccount, prefs); } else if (!mergeImportedAccount) { importFolder(editor, contentVersion, uuid, folder, mergeImportedAccount, prefs);
private static ImportedFolder parseFolder(XmlPullParser xpp) throws XmlPullParserException, IOException { ImportedFolder folder = new ImportedFolder(); folder.name = xpp.getAttributeValue(null, SettingsExporter.NAME_ATTRIBUTE); folder.settings = parseSettings(xpp, SettingsExporter.FOLDER_ELEMENT); return folder; }
Imported imported = parseSettings(inputStream, false, null, true); String accountName = getAccountDisplayName(account); accounts.add(new AccountDescription(accountName, account.uuid));
boolean mergeSettings = false; if (overwrite && existingIdentities.size() > 0) { int identityIndex = findIdentity(identity, existingIdentities); if (identityIndex != -1) { writeIdentityIndex = identityIndex; if (isIdentityDescriptionUsed(identityDescription, existingIdentities)) { if (!isIdentityDescriptionUsed(identityDescription, existingIdentities)) { break; putString(editor, accountKeyPrefix + AccountPreferenceSerializer.IDENTITY_NAME_KEY + identitySuffix, identityName); putString(editor, accountKeyPrefix + AccountPreferenceSerializer.IDENTITY_EMAIL_KEY + identitySuffix, identity.email); putString(editor, accountKeyPrefix + AccountPreferenceSerializer.IDENTITY_DESCRIPTION_KEY + identitySuffix, identityDescription); String key = accountKeyPrefix + setting.getKey() + identitySuffix; String value = setting.getValue(); putString(editor, key, value);
private static ImportedSettings parseSettings(XmlPullParser xpp, String endTag) throws XmlPullParserException, IOException { ImportedSettings result = null; int eventType = xpp.next(); while (!(eventType == XmlPullParser.END_TAG && endTag.equals(xpp.getName()))) { if (eventType == XmlPullParser.START_TAG) { String element = xpp.getName(); if (SettingsExporter.VALUE_ELEMENT.equals(element)) { String key = xpp.getAttributeValue(null, SettingsExporter.KEY_ATTRIBUTE); String value = getText(xpp); if (result == null) { result = new ImportedSettings(); } if (result.settings.containsKey(key)) { Timber.w("Already read key \"%s\". Ignoring value \"%s\"", key, value); } else { result.settings.put(key, value); } } else { Timber.w("Unexpected start tag: %s", xpp.getName()); } } eventType = xpp.next(); } return result; }
String element = xpp.getName(); if (SettingsExporter.HOST_ELEMENT.equals(element)) { server.host = getText(xpp); } else if (SettingsExporter.PORT_ELEMENT.equals(element)) { server.port = getText(xpp); } else if (SettingsExporter.CONNECTION_SECURITY_ELEMENT.equals(element)) { server.connectionSecurity = getText(xpp); } else if (SettingsExporter.AUTHENTICATION_TYPE_ELEMENT.equals(element)) { String text = getText(xpp); server.authenticationType = AuthType.valueOf(text); } else if (SettingsExporter.USERNAME_ELEMENT.equals(element)) { server.username = getText(xpp); } else if (SettingsExporter.CLIENT_CERTIFICATE_ALIAS_ELEMENT.equals(element)) { server.clientCertificateAlias = getText(xpp); } else if (SettingsExporter.PASSWORD_ELEMENT.equals(element)) { server.password = getText(xpp); } else if (SettingsExporter.EXTRA_ELEMENT.equals(element)) { server.extras = parseSettings(xpp, SettingsExporter.EXTRA_ELEMENT); } else { Timber.w("Unexpected start tag: %s", xpp.getName());
@Test public void parseSettings_account() throws SettingsImportExportException { String validUUID = UUID.randomUUID().toString(); InputStream inputStream = new StringInputStream("<k9settings format=\"1\" version=\"1\">" + "<accounts><account uuid=\"" + validUUID + "\"><name>Account</name></account></accounts></k9settings>"); List<String> accountUuids = new ArrayList<>(); accountUuids.add("1"); SettingsImporter.Imported results = SettingsImporter.parseSettings(inputStream, true, accountUuids, true); assertEquals(1, results.accounts.size()); assertEquals("Account", results.accounts.get(validUUID).name); assertEquals(validUUID, results.accounts.get(validUUID).uuid); }
@Test(expected = SettingsImportExportException.class) public void importSettings_throwsExceptionOnBlankFile() throws SettingsImportExportException { InputStream inputStream = new StringInputStream(""); List<String> accountUuids = new ArrayList<>(); SettingsImporter.importSettings(RuntimeEnvironment.application, inputStream, true, accountUuids, true); }
@Test public void parseSettings_account_cram_md5() throws SettingsImportExportException { String validUUID = UUID.randomUUID().toString(); InputStream inputStream = new StringInputStream("<k9settings format=\"1\" version=\"1\">" + "<accounts><account uuid=\"" + validUUID + "\"><name>Account</name>" + "<incoming-server><authentication-type>CRAM_MD5</authentication-type></incoming-server>" + "</account></accounts></k9settings>"); List<String> accountUuids = new ArrayList<>(); accountUuids.add(validUUID); SettingsImporter.Imported results = SettingsImporter.parseSettings(inputStream, true, accountUuids, false); assertEquals("Account", results.accounts.get(validUUID).name); assertEquals(validUUID, results.accounts.get(validUUID).uuid); assertEquals(AuthType.CRAM_MD5, results.accounts.get(validUUID).incoming.authenticationType); }
@Test public void getImportStreamContents_account() throws SettingsImportExportException { String validUUID = UUID.randomUUID().toString(); InputStream inputStream = new StringInputStream("<k9settings format=\"1\" version=\"1\">" + "<accounts>" + "<account uuid=\"" + validUUID + "\">" + "<name>Account</name>" + "<identities>" + "<identity>" + "<email>user@gmail.com</email>" + "</identity>" + "</identities>" + "</account>" + "</accounts></k9settings>"); SettingsImporter.ImportContents results = SettingsImporter.getImportStreamContents(inputStream); assertEquals(false, results.globalSettings); assertEquals(1, results.accounts.size()); assertEquals("Account", results.accounts.get(0).name); assertEquals(validUUID, results.accounts.get(0).uuid); }
@Test(expected = SettingsImportExportException.class) public void importSettings_throwsExceptionOnMissingFormat() throws SettingsImportExportException { InputStream inputStream = new StringInputStream("<k9settings version=\"1\"></k9settings>"); List<String> accountUuids = new ArrayList<>(); SettingsImporter.importSettings(RuntimeEnvironment.application, inputStream, true, accountUuids, true); }
@Test public void parseSettings_account_identities() throws SettingsImportExportException { String validUUID = UUID.randomUUID().toString(); InputStream inputStream = new StringInputStream("<k9settings format=\"1\" version=\"1\">" + "<accounts><account uuid=\"" + validUUID + "\"><name>Account</name>" + "<identities><identity><email>user@gmail.com</email></identity></identities>" + "</account></accounts></k9settings>"); List<String> accountUuids = new ArrayList<>(); accountUuids.add("1"); SettingsImporter.Imported results = SettingsImporter.parseSettings(inputStream, true, accountUuids, true); assertEquals(1, results.accounts.size()); assertEquals(validUUID, results.accounts.get(validUUID).uuid); assertEquals(1, results.accounts.get(validUUID).identities.size()); assertEquals("user@gmail.com", results.accounts.get(validUUID).identities.get(0).email); }
@Test public void getImportStreamContents_alternativeName() throws SettingsImportExportException { String validUUID = UUID.randomUUID().toString(); InputStream inputStream = new StringInputStream("<k9settings format=\"1\" version=\"1\">" + "<accounts>" + "<account uuid=\"" + validUUID + "\">" + "<name></name>" + "<identities>" + "<identity>" + "<email>user@gmail.com</email>" + "</identity>" + "</identities>" + "</account>" + "</accounts></k9settings>"); SettingsImporter.ImportContents results = SettingsImporter.getImportStreamContents(inputStream); assertEquals(false, results.globalSettings); assertEquals(1, results.accounts.size()); assertEquals("user@gmail.com", results.accounts.get(0).name); assertEquals(validUUID, results.accounts.get(0).uuid); } }
@Test(expected = SettingsImportExportException.class) public void importSettings_throwsExceptionOnMissingVersion() throws SettingsImportExportException { InputStream inputStream = new StringInputStream("<k9settings format=\"1\"></k9settings>"); List<String> accountUuids = new ArrayList<>(); SettingsImporter.importSettings(RuntimeEnvironment.application, inputStream, true, accountUuids, true); }