1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 package com.example.android.samplesync.authenticator; 18 19 import android.accounts.AbstractAccountAuthenticator; 20 import android.accounts.Account; 21 import android.accounts.AccountAuthenticatorResponse; 22 import android.accounts.AccountManager; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.os.Bundle; 26 27 import com.example.android.samplesync.Constants; 28 import com.example.android.samplesync.R; 29 import com.example.android.samplesync.client.NetworkUtilities; 30 31 /** 32 * This class is an implementation of AbstractAccountAuthenticator for 33 * authenticating accounts in the com.example.android.samplesync domain. 34 */ 35 class Authenticator extends AbstractAccountAuthenticator { 36 // Authentication Service context 37 private final Context mContext; 38 39 public Authenticator(Context context) { 40 super(context); 41 mContext = context; 42 } 43 44 /** 45 * {@inheritDoc} 46 */ 47 @Override 48 public Bundle addAccount(AccountAuthenticatorResponse response, 49 String accountType, String authTokenType, String[] requiredFeatures, 50 Bundle options) { 51 final Intent intent = new Intent(mContext, AuthenticatorActivity.class); 52 intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, 53 authTokenType); 54 intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, 55 response); 56 final Bundle bundle = new Bundle(); 57 bundle.putParcelable(AccountManager.KEY_INTENT, intent); 58 return bundle; 59 } 60 61 /** 62 * {@inheritDoc} 63 */ 64 @Override 65 public Bundle confirmCredentials(AccountAuthenticatorResponse response, 66 Account account, Bundle options) { 67 if (options != null && options.containsKey(AccountManager.KEY_PASSWORD)) { 68 final String password = 69 options.getString(AccountManager.KEY_PASSWORD); 70 final boolean verified = 71 onlineConfirmPassword(account.name, password); 72 final Bundle result = new Bundle(); 73 result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, verified); 74 return result; 75 } 76 // Launch AuthenticatorActivity to confirm credentials 77 final Intent intent = new Intent(mContext, AuthenticatorActivity.class); 78 intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name); 79 intent.putExtra(AuthenticatorActivity.PARAM_CONFIRMCREDENTIALS, true); 80 intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, 81 response); 82 final Bundle bundle = new Bundle(); 83 bundle.putParcelable(AccountManager.KEY_INTENT, intent); 84 return bundle; 85 } 86 87 /** 88 * {@inheritDoc} 89 */ 90 @Override 91 public Bundle editProperties(AccountAuthenticatorResponse response, 92 String accountType) { 93 throw new UnsupportedOperationException(); 94 } 95 96 /** 97 * {@inheritDoc} 98 */ 99 @Override 100 public Bundle getAuthToken(AccountAuthenticatorResponse response, 101 Account account, String authTokenType, Bundle loginOptions) { 102 if (!authTokenType.equals(Constants.AUTHTOKEN_TYPE)) { 103 final Bundle result = new Bundle(); 104 result.putString(AccountManager.KEY_ERROR_MESSAGE, 105 "invalid authTokenType"); 106 return result; 107 } 108 final AccountManager am = AccountManager.get(mContext); 109 final String password = am.getPassword(account); 110 if (password != null) { 111 final boolean verified = 112 onlineConfirmPassword(account.name, password); 113 if (verified) { 114 final Bundle result = new Bundle(); 115 result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 116 result.putString(AccountManager.KEY_ACCOUNT_TYPE, 117 Constants.ACCOUNT_TYPE); 118 result.putString(AccountManager.KEY_AUTHTOKEN, password); 119 return result; 120 } 121 } 122 // the password was missing or incorrect, return an Intent to an 123 // Activity that will prompt the user for the password. 124 final Intent intent = new Intent(mContext, AuthenticatorActivity.class); 125 intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name); 126 intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, 127 authTokenType); 128 intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, 129 response); 130 final Bundle bundle = new Bundle(); 131 bundle.putParcelable(AccountManager.KEY_INTENT, intent); 132 return bundle; 133 } 134 135 /** 136 * {@inheritDoc} 137 */ 138 @Override 139 public String getAuthTokenLabel(String authTokenType) { 140 if (authTokenType.equals(Constants.AUTHTOKEN_TYPE)) { 141 return mContext.getString(R.string.label); 142 } 143 return null; 144 145 } 146 147 /** 148 * {@inheritDoc} 149 */ 150 @Override 151 public Bundle hasFeatures(AccountAuthenticatorResponse response, 152 Account account, String[] features) { 153 final Bundle result = new Bundle(); 154 result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false); 155 return result; 156 } 157 158 /** 159 * Validates user's password on the server 160 */ 161 private boolean onlineConfirmPassword(String username, String password) { 162 return NetworkUtilities.authenticate(username, password, 163 null/* Handler */, null/* Context */); 164 } 165 166 /** 167 * {@inheritDoc} 168 */ 169 @Override 170 public Bundle updateCredentials(AccountAuthenticatorResponse response, 171 Account account, String authTokenType, Bundle loginOptions) { 172 final Intent intent = new Intent(mContext, AuthenticatorActivity.class); 173 intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name); 174 intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, 175 authTokenType); 176 intent.putExtra(AuthenticatorActivity.PARAM_CONFIRMCREDENTIALS, false); 177 final Bundle bundle = new Bundle(); 178 bundle.putParcelable(AccountManager.KEY_INTENT, intent); 179 return bundle; 180 } 181 182 } 183