Loading k9mail/src/main/AndroidManifest.xml +2 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ android:normalScreens="true" android:smallScreens="true"/> <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.READ_CONTACTS"/> <uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/> Loading k9mail/src/main/java/io/eelo/mail/account/K9OAuth2TokenProvider.java +73 −8 Original line number Diff line number Diff line Loading @@ -3,19 +3,33 @@ package io.eelo.mail.account; import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.AccountManagerCallback; import android.accounts.AccountManagerFuture; import android.content.Context; import android.os.Bundle; import android.util.Log; import android.widget.Toast; import java.util.ArrayList; import java.util.concurrent.CountDownLatch; import io.eelo.mail.activity.Accounts; import io.eelo.mail.mail.AuthenticationFailedException; import io.eelo.mail.mail.OAuth2NeedUserPromptException; import io.eelo.mail.mail.oauth.OAuth2TokenProvider; import static io.eelo.mail.account.OAuthConstants.ACCOUNT_EMAIL_ID_KEY; import static io.eelo.mail.account.OAuthConstants.AUTH_TOKEN_TYPE; import static io.eelo.mail.account.OAuthConstants.EELO_ACCOUNT_TYPE; import static io.eelo.mail.account.OAuthConstants.GOOGLE_ACCOUNT_TYPE; public class K9OAuth2TokenProvider extends OAuth2TokenProvider { private static final String GOOGLE_ACCOUNT_TYPE = "com.google"; public class K9OAuth2TokenProvider extends OAuth2TokenProvider { private static final String OFFICIAL_GOOGLE_ACCOUNT_TYPE = "com.google"; private AccountManager accountManager; private String authToken = null; private AndroidAccountOAuth2TokenStore gmailTokenProviderWithAccountSystem; private K9OAuth2AuthorizationCodeFlowTokenProvider authorizationCodeFlowTokenProvider; Loading @@ -32,7 +46,7 @@ public class K9OAuth2TokenProvider extends OAuth2TokenProvider } private Account getAccountFromManager(String emailAddress) { android.accounts.Account[] accounts = accountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE); android.accounts.Account[] accounts = accountManager.getAccountsByType(OFFICIAL_GOOGLE_ACCOUNT_TYPE); for (android.accounts.Account account : accounts) { if (account.name.equals(emailAddress)) { return account; Loading @@ -41,13 +55,16 @@ public class K9OAuth2TokenProvider extends OAuth2TokenProvider return null; } @Override public String getToken(String email, long timeoutMillis) throws AuthenticationFailedException, OAuth2NeedUserPromptException { Account gmailAccount = getAccountFromManager(email); throws AuthenticationFailedException, OAuth2NeedUserPromptException { getTokenFromAccountManager(email); Log.i("OAuth token value", authToken); if (authToken != null) { return authToken; } Account gmailAccount = getAccountFromManager(email); if (gmailAccount != null) { return gmailTokenProviderWithAccountSystem.getToken(email, gmailAccount, timeoutMillis); } Loading @@ -55,6 +72,54 @@ public class K9OAuth2TokenProvider extends OAuth2TokenProvider return authorizationCodeFlowTokenProvider.getToken(email, timeoutMillis); } private void getTokenFromAccountManager(String emailId) { android.accounts.Account[] eeloAccounts = accountManager.getAccountsByType( EELO_ACCOUNT_TYPE); android.accounts.Account[] googleAccounts = accountManager.getAccountsByType( GOOGLE_ACCOUNT_TYPE); ArrayList<Account> accounts = new ArrayList<>(); for (Account eeloAccount : eeloAccounts) { accounts.add(eeloAccount); } for (Account googleAccount : googleAccounts) { accounts.add(googleAccount); } if (accounts.size() > 0) { for (Account account : accounts) { String accountEmailId = accountManager.getUserData(account, ACCOUNT_EMAIL_ID_KEY); if (emailId.equals(accountEmailId)) { final CountDownLatch countDownLatch = new CountDownLatch(1); accountManager.getAuthToken(account, AUTH_TOKEN_TYPE, new Bundle(), null, new AccountManagerCallback<Bundle>() { @Override public void run(AccountManagerFuture<Bundle> accountManagerFuture) { try { authToken = accountManagerFuture.getResult().getString( AccountManager.KEY_AUTHTOKEN); countDownLatch.countDown(); } catch (Exception e) { authToken = null; } } }, null); try { countDownLatch.await(); } catch (Exception e) { authToken = null; } } } } else { authToken = null; } } @Override public void invalidateToken(String email) { Account gmailAccount = getAccountFromManager(email); Loading k9mail/src/main/java/io/eelo/mail/account/OAuthConstants.java 0 → 100644 +8 −0 Original line number Diff line number Diff line package io.eelo.mail.account; public class OAuthConstants { public static final String EELO_ACCOUNT_TYPE = "bitfire.at.davdroid.eelo"; public static final String GOOGLE_ACCOUNT_TYPE = "bitfire.at.davdroid.google"; public static final String ACCOUNT_EMAIL_ID_KEY = "email_id"; public static final String AUTH_TOKEN_TYPE = "oauth2-access-token"; } k9mail/src/main/java/io/eelo/mail/activity/Accounts.java +44 −3 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import android.accounts.AccountManager; import android.app.ActionBar; import android.app.Activity; import android.app.AlertDialog; Loading Loading @@ -43,6 +44,7 @@ import io.eelo.mail.K9; import io.eelo.mail.Preferences; import io.eelo.mail.activity.misc.ExtendedAsyncTask; import io.eelo.mail.activity.misc.NonConfigurationInstance; import io.eelo.mail.activity.setup.GoogleAccountCreator; import io.eelo.mail.controller.MessagingController; import io.eelo.mail.mail.AuthType; import io.eelo.mail.mail.TransportUris; Loading Loading @@ -93,6 +95,10 @@ import io.eelo.mail.mailstore.StorageManager; import io.eelo.mail.preferences.SettingsExporter; import de.cketti.library.changelog.ChangeLog; import static io.eelo.mail.account.OAuthConstants.ACCOUNT_EMAIL_ID_KEY; import static io.eelo.mail.account.OAuthConstants.EELO_ACCOUNT_TYPE; import static io.eelo.mail.account.OAuthConstants.GOOGLE_ACCOUNT_TYPE; public class Accounts extends K9ListActivity implements OnItemClickListener { Loading Loading @@ -460,9 +466,44 @@ public class Accounts extends K9ListActivity implements OnItemClickListener } else if (accounts.size() < 1) { // Don't show the welcome message, proceed to account setup instead //WelcomeMessage.showWelcomeMessage(this); AccountManager accountManager = AccountManager.get(this); try { android.accounts.Account[] eeloAccounts = accountManager.getAccountsByType( EELO_ACCOUNT_TYPE); android.accounts.Account[] googleAccounts = accountManager.getAccountsByType( GOOGLE_ACCOUNT_TYPE); if (eeloAccounts.length > 0 || googleAccounts.length > 0) { for (android.accounts.Account eeloAccount : eeloAccounts) { String emailId = accountManager.getUserData(eeloAccount, ACCOUNT_EMAIL_ID_KEY); //TODO Add /e/ accounts } for (android.accounts.Account googleAccount : googleAccounts) { String emailId = accountManager.getUserData(googleAccount, ACCOUNT_EMAIL_ID_KEY); GoogleAccountCreator.createAccount(this, emailId); } Toast.makeText(this, "Found accounts signed-in on device", Toast.LENGTH_LONG).show(); Accounts.listAccounts(this); } else { AccountSetupActivity.actionNewAccount(this); } } catch (SecurityException e) { AccountSetupActivity.actionNewAccount(this); } finish(); return; } Loading k9mail/src/main/java/io/eelo/mail/activity/setup/GoogleAccountCreator.java 0 → 100644 +42 −0 Original line number Diff line number Diff line package io.eelo.mail.activity.setup; import android.content.Context; import io.eelo.mail.Account; import io.eelo.mail.K9; import io.eelo.mail.Preferences; import io.eelo.mail.controller.MessagingController; public class GoogleAccountCreator { public static void createAccount(Context context, String emailId) { Preferences preferences = Preferences.getPreferences(context); AccountConfigImpl accountConfig = new AccountConfigImpl(preferences); accountConfig.setEmail(emailId); accountConfig.setDescription(emailId); accountConfig.setTrashFolderName("[Gmail]/Trash"); accountConfig.setArchiveFolderName("[Gmail]/All Mail"); accountConfig.setDraftsFolderName("[Gmail]/Drafts"); accountConfig.setInboxFolderName("INBOX"); accountConfig.setSentFolderName("[Gmail]/Sent Mail"); accountConfig.setSpamFolderName("[Gmail]/Spam"); accountConfig.setAutoExpandFolderName("INBOX"); accountConfig.setStoreUri("imap+ssl+://XOAUTH2:" + emailId.substring(0, emailId.indexOf("@")) + "%40gmail.com:@imap.gmail.com"); accountConfig.setTransportUri("smtp+ssl+://" + emailId.substring(0, emailId.indexOf("@")) + "%40gmail.com::XOAUTH2@smtp.gmail.com"); Account account = preferences.newAccount(); account.loadConfig(accountConfig); MessagingController.getInstance(context).listFoldersSynchronous(account, true, null); MessagingController.getInstance(context) .synchronizeMailbox(account, account.getInboxFolderName(), null, null); account.save(preferences); preferences.setDefaultAccount(account); K9.setServicesEnabled(context); } } Loading
k9mail/src/main/AndroidManifest.xml +2 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ android:normalScreens="true" android:smallScreens="true"/> <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.READ_CONTACTS"/> <uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/> Loading
k9mail/src/main/java/io/eelo/mail/account/K9OAuth2TokenProvider.java +73 −8 Original line number Diff line number Diff line Loading @@ -3,19 +3,33 @@ package io.eelo.mail.account; import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.AccountManagerCallback; import android.accounts.AccountManagerFuture; import android.content.Context; import android.os.Bundle; import android.util.Log; import android.widget.Toast; import java.util.ArrayList; import java.util.concurrent.CountDownLatch; import io.eelo.mail.activity.Accounts; import io.eelo.mail.mail.AuthenticationFailedException; import io.eelo.mail.mail.OAuth2NeedUserPromptException; import io.eelo.mail.mail.oauth.OAuth2TokenProvider; import static io.eelo.mail.account.OAuthConstants.ACCOUNT_EMAIL_ID_KEY; import static io.eelo.mail.account.OAuthConstants.AUTH_TOKEN_TYPE; import static io.eelo.mail.account.OAuthConstants.EELO_ACCOUNT_TYPE; import static io.eelo.mail.account.OAuthConstants.GOOGLE_ACCOUNT_TYPE; public class K9OAuth2TokenProvider extends OAuth2TokenProvider { private static final String GOOGLE_ACCOUNT_TYPE = "com.google"; public class K9OAuth2TokenProvider extends OAuth2TokenProvider { private static final String OFFICIAL_GOOGLE_ACCOUNT_TYPE = "com.google"; private AccountManager accountManager; private String authToken = null; private AndroidAccountOAuth2TokenStore gmailTokenProviderWithAccountSystem; private K9OAuth2AuthorizationCodeFlowTokenProvider authorizationCodeFlowTokenProvider; Loading @@ -32,7 +46,7 @@ public class K9OAuth2TokenProvider extends OAuth2TokenProvider } private Account getAccountFromManager(String emailAddress) { android.accounts.Account[] accounts = accountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE); android.accounts.Account[] accounts = accountManager.getAccountsByType(OFFICIAL_GOOGLE_ACCOUNT_TYPE); for (android.accounts.Account account : accounts) { if (account.name.equals(emailAddress)) { return account; Loading @@ -41,13 +55,16 @@ public class K9OAuth2TokenProvider extends OAuth2TokenProvider return null; } @Override public String getToken(String email, long timeoutMillis) throws AuthenticationFailedException, OAuth2NeedUserPromptException { Account gmailAccount = getAccountFromManager(email); throws AuthenticationFailedException, OAuth2NeedUserPromptException { getTokenFromAccountManager(email); Log.i("OAuth token value", authToken); if (authToken != null) { return authToken; } Account gmailAccount = getAccountFromManager(email); if (gmailAccount != null) { return gmailTokenProviderWithAccountSystem.getToken(email, gmailAccount, timeoutMillis); } Loading @@ -55,6 +72,54 @@ public class K9OAuth2TokenProvider extends OAuth2TokenProvider return authorizationCodeFlowTokenProvider.getToken(email, timeoutMillis); } private void getTokenFromAccountManager(String emailId) { android.accounts.Account[] eeloAccounts = accountManager.getAccountsByType( EELO_ACCOUNT_TYPE); android.accounts.Account[] googleAccounts = accountManager.getAccountsByType( GOOGLE_ACCOUNT_TYPE); ArrayList<Account> accounts = new ArrayList<>(); for (Account eeloAccount : eeloAccounts) { accounts.add(eeloAccount); } for (Account googleAccount : googleAccounts) { accounts.add(googleAccount); } if (accounts.size() > 0) { for (Account account : accounts) { String accountEmailId = accountManager.getUserData(account, ACCOUNT_EMAIL_ID_KEY); if (emailId.equals(accountEmailId)) { final CountDownLatch countDownLatch = new CountDownLatch(1); accountManager.getAuthToken(account, AUTH_TOKEN_TYPE, new Bundle(), null, new AccountManagerCallback<Bundle>() { @Override public void run(AccountManagerFuture<Bundle> accountManagerFuture) { try { authToken = accountManagerFuture.getResult().getString( AccountManager.KEY_AUTHTOKEN); countDownLatch.countDown(); } catch (Exception e) { authToken = null; } } }, null); try { countDownLatch.await(); } catch (Exception e) { authToken = null; } } } } else { authToken = null; } } @Override public void invalidateToken(String email) { Account gmailAccount = getAccountFromManager(email); Loading
k9mail/src/main/java/io/eelo/mail/account/OAuthConstants.java 0 → 100644 +8 −0 Original line number Diff line number Diff line package io.eelo.mail.account; public class OAuthConstants { public static final String EELO_ACCOUNT_TYPE = "bitfire.at.davdroid.eelo"; public static final String GOOGLE_ACCOUNT_TYPE = "bitfire.at.davdroid.google"; public static final String ACCOUNT_EMAIL_ID_KEY = "email_id"; public static final String AUTH_TOKEN_TYPE = "oauth2-access-token"; }
k9mail/src/main/java/io/eelo/mail/activity/Accounts.java +44 −3 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import android.accounts.AccountManager; import android.app.ActionBar; import android.app.Activity; import android.app.AlertDialog; Loading Loading @@ -43,6 +44,7 @@ import io.eelo.mail.K9; import io.eelo.mail.Preferences; import io.eelo.mail.activity.misc.ExtendedAsyncTask; import io.eelo.mail.activity.misc.NonConfigurationInstance; import io.eelo.mail.activity.setup.GoogleAccountCreator; import io.eelo.mail.controller.MessagingController; import io.eelo.mail.mail.AuthType; import io.eelo.mail.mail.TransportUris; Loading Loading @@ -93,6 +95,10 @@ import io.eelo.mail.mailstore.StorageManager; import io.eelo.mail.preferences.SettingsExporter; import de.cketti.library.changelog.ChangeLog; import static io.eelo.mail.account.OAuthConstants.ACCOUNT_EMAIL_ID_KEY; import static io.eelo.mail.account.OAuthConstants.EELO_ACCOUNT_TYPE; import static io.eelo.mail.account.OAuthConstants.GOOGLE_ACCOUNT_TYPE; public class Accounts extends K9ListActivity implements OnItemClickListener { Loading Loading @@ -460,9 +466,44 @@ public class Accounts extends K9ListActivity implements OnItemClickListener } else if (accounts.size() < 1) { // Don't show the welcome message, proceed to account setup instead //WelcomeMessage.showWelcomeMessage(this); AccountManager accountManager = AccountManager.get(this); try { android.accounts.Account[] eeloAccounts = accountManager.getAccountsByType( EELO_ACCOUNT_TYPE); android.accounts.Account[] googleAccounts = accountManager.getAccountsByType( GOOGLE_ACCOUNT_TYPE); if (eeloAccounts.length > 0 || googleAccounts.length > 0) { for (android.accounts.Account eeloAccount : eeloAccounts) { String emailId = accountManager.getUserData(eeloAccount, ACCOUNT_EMAIL_ID_KEY); //TODO Add /e/ accounts } for (android.accounts.Account googleAccount : googleAccounts) { String emailId = accountManager.getUserData(googleAccount, ACCOUNT_EMAIL_ID_KEY); GoogleAccountCreator.createAccount(this, emailId); } Toast.makeText(this, "Found accounts signed-in on device", Toast.LENGTH_LONG).show(); Accounts.listAccounts(this); } else { AccountSetupActivity.actionNewAccount(this); } } catch (SecurityException e) { AccountSetupActivity.actionNewAccount(this); } finish(); return; } Loading
k9mail/src/main/java/io/eelo/mail/activity/setup/GoogleAccountCreator.java 0 → 100644 +42 −0 Original line number Diff line number Diff line package io.eelo.mail.activity.setup; import android.content.Context; import io.eelo.mail.Account; import io.eelo.mail.K9; import io.eelo.mail.Preferences; import io.eelo.mail.controller.MessagingController; public class GoogleAccountCreator { public static void createAccount(Context context, String emailId) { Preferences preferences = Preferences.getPreferences(context); AccountConfigImpl accountConfig = new AccountConfigImpl(preferences); accountConfig.setEmail(emailId); accountConfig.setDescription(emailId); accountConfig.setTrashFolderName("[Gmail]/Trash"); accountConfig.setArchiveFolderName("[Gmail]/All Mail"); accountConfig.setDraftsFolderName("[Gmail]/Drafts"); accountConfig.setInboxFolderName("INBOX"); accountConfig.setSentFolderName("[Gmail]/Sent Mail"); accountConfig.setSpamFolderName("[Gmail]/Spam"); accountConfig.setAutoExpandFolderName("INBOX"); accountConfig.setStoreUri("imap+ssl+://XOAUTH2:" + emailId.substring(0, emailId.indexOf("@")) + "%40gmail.com:@imap.gmail.com"); accountConfig.setTransportUri("smtp+ssl+://" + emailId.substring(0, emailId.indexOf("@")) + "%40gmail.com::XOAUTH2@smtp.gmail.com"); Account account = preferences.newAccount(); account.loadConfig(accountConfig); MessagingController.getInstance(context).listFoldersSynchronous(account, true, null); MessagingController.getInstance(context) .synchronizeMailbox(account, account.getInboxFolderName(), null, null); account.save(preferences); preferences.setDefaultAccount(account); K9.setServicesEnabled(context); } }