1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/fxa/authenticator/FxAccountAuthenticator.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,144 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +package org.mozilla.gecko.fxa.authenticator; 1.9 + 1.10 +import org.mozilla.gecko.background.common.log.Logger; 1.11 +import org.mozilla.gecko.fxa.FxAccountConstants; 1.12 +import org.mozilla.gecko.fxa.activities.FxAccountGetStartedActivity; 1.13 + 1.14 +import android.accounts.AbstractAccountAuthenticator; 1.15 +import android.accounts.Account; 1.16 +import android.accounts.AccountAuthenticatorResponse; 1.17 +import android.accounts.AccountManager; 1.18 +import android.accounts.NetworkErrorException; 1.19 +import android.content.Context; 1.20 +import android.content.Intent; 1.21 +import android.os.Bundle; 1.22 + 1.23 +public class FxAccountAuthenticator extends AbstractAccountAuthenticator { 1.24 + public static final String LOG_TAG = FxAccountAuthenticator.class.getSimpleName(); 1.25 + 1.26 + protected final Context context; 1.27 + protected final AccountManager accountManager; 1.28 + 1.29 + public FxAccountAuthenticator(Context context) { 1.30 + super(context); 1.31 + this.context = context; 1.32 + this.accountManager = AccountManager.get(context); 1.33 + } 1.34 + 1.35 + @Override 1.36 + public Bundle addAccount(AccountAuthenticatorResponse response, 1.37 + String accountType, String authTokenType, String[] requiredFeatures, 1.38 + Bundle options) 1.39 + throws NetworkErrorException { 1.40 + Logger.debug(LOG_TAG, "addAccount"); 1.41 + 1.42 + final Bundle res = new Bundle(); 1.43 + 1.44 + if (!FxAccountConstants.ACCOUNT_TYPE.equals(accountType)) { 1.45 + res.putInt(AccountManager.KEY_ERROR_CODE, -1); 1.46 + res.putString(AccountManager.KEY_ERROR_MESSAGE, "Not adding unknown account type."); 1.47 + return res; 1.48 + } 1.49 + 1.50 + Intent intent = new Intent(context, FxAccountGetStartedActivity.class); 1.51 + res.putParcelable(AccountManager.KEY_INTENT, intent); 1.52 + return res; 1.53 + } 1.54 + 1.55 + @Override 1.56 + public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) 1.57 + throws NetworkErrorException { 1.58 + Logger.debug(LOG_TAG, "confirmCredentials"); 1.59 + 1.60 + return null; 1.61 + } 1.62 + 1.63 + @Override 1.64 + public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) { 1.65 + Logger.debug(LOG_TAG, "editProperties"); 1.66 + 1.67 + return null; 1.68 + } 1.69 + 1.70 + @Override 1.71 + public Bundle getAuthToken(final AccountAuthenticatorResponse response, 1.72 + final Account account, final String authTokenType, final Bundle options) 1.73 + throws NetworkErrorException { 1.74 + Logger.debug(LOG_TAG, "getAuthToken"); 1.75 + 1.76 + Logger.warn(LOG_TAG, "Returning null bundle for getAuthToken."); 1.77 + 1.78 + return null; 1.79 + } 1.80 + 1.81 + @Override 1.82 + public String getAuthTokenLabel(String authTokenType) { 1.83 + Logger.debug(LOG_TAG, "getAuthTokenLabel"); 1.84 + 1.85 + return null; 1.86 + } 1.87 + 1.88 + @Override 1.89 + public Bundle hasFeatures(AccountAuthenticatorResponse response, 1.90 + Account account, String[] features) throws NetworkErrorException { 1.91 + Logger.debug(LOG_TAG, "hasFeatures"); 1.92 + 1.93 + return null; 1.94 + } 1.95 + 1.96 + @Override 1.97 + public Bundle updateCredentials(AccountAuthenticatorResponse response, 1.98 + Account account, String authTokenType, Bundle options) 1.99 + throws NetworkErrorException { 1.100 + Logger.debug(LOG_TAG, "updateCredentials"); 1.101 + 1.102 + return null; 1.103 + } 1.104 + 1.105 + /** 1.106 + * If the account is going to be removed, broadcast an "account deleted" 1.107 + * intent. This allows us to clean up the account. 1.108 + * <p> 1.109 + * It is preferable to receive Android's LOGIN_ACCOUNTS_CHANGED_ACTION broadcast 1.110 + * than to create our own hacky broadcast here, but that doesn't include enough 1.111 + * information about which Accounts changed to correctly identify whether a Sync 1.112 + * account has been removed (when some Firefox channels are installed on the SD 1.113 + * card). We can work around this by storing additional state but it's both messy 1.114 + * and expensive because the broadcast is noisy. 1.115 + * <p> 1.116 + * Note that this is <b>not</b> called when an Android Account is blown away 1.117 + * due to the SD card being unmounted. 1.118 + */ 1.119 + @Override 1.120 + public Bundle getAccountRemovalAllowed(final AccountAuthenticatorResponse response, Account account) 1.121 + throws NetworkErrorException { 1.122 + Bundle result = super.getAccountRemovalAllowed(response, account); 1.123 + 1.124 + if (result == null || 1.125 + !result.containsKey(AccountManager.KEY_BOOLEAN_RESULT) || 1.126 + result.containsKey(AccountManager.KEY_INTENT)) { 1.127 + return result; 1.128 + } 1.129 + 1.130 + final boolean removalAllowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT); 1.131 + if (!removalAllowed) { 1.132 + return result; 1.133 + } 1.134 + 1.135 + // Broadcast a message to all Firefox channels sharing this Android 1.136 + // Account type telling that this Firefox account has been deleted. 1.137 + // 1.138 + // Broadcast intents protected with permissions are secure, so it's okay 1.139 + // to include private information such as a password. 1.140 + final Intent intent = AndroidFxAccount.makeDeletedAccountIntent(context, account); 1.141 + Logger.info(LOG_TAG, "Account named " + account.name + " being removed; " + 1.142 + "broadcasting secure intent " + intent.getAction() + "."); 1.143 + context.sendBroadcast(intent, FxAccountConstants.PER_ACCOUNT_TYPE_PERMISSION); 1.144 + 1.145 + return result; 1.146 + } 1.147 +}