AI2 Component  (Version nb184)
OAuth2Helper.java
Go to the documentation of this file.
1 package com.google.appinventor.components.runtime.util;
2 
3 import java.io.IOException;
4 
5 import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
6 import com.google.api.client.googleapis.extensions.android2.auth.GoogleAccountManager;
7 
8 import android.accounts.Account;
9 import android.accounts.AccountManager;
10 import android.accounts.AccountManagerFuture;
11 import android.accounts.AuthenticatorException;
12 import android.accounts.OperationCanceledException;
13 import android.app.Activity;
14 import android.content.SharedPreferences;
15 
16 import android.os.Bundle;
17 import android.os.Looper;
18 import android.util.Log;
19 
20 
71 public class OAuth2Helper {
72 
73  public static final String TAG = "OAuthHelper";
74  public static final String PREF_AUTH_TOKEN = "authToken";
75  public static final String PREF_ACCOUNT_NAME = "accountName";
76 
77  private static String errorMessage = "Error during OAuth";
78 
79  public OAuth2Helper () {}
80 
88  public String getRefreshedAuthToken(Activity activity, String authTokenType) {
89  Log.i(TAG, "getRefreshedAuthToken()");
90 
91  if (isUiThread())
92  throw new IllegalArgumentException("Can't get authtoken from UI thread");
93 
94  // Get the saved account name, possibly null
95  SharedPreferences settings = activity.getPreferences(Activity.MODE_PRIVATE);
96  String accountName = settings.getString(PREF_ACCOUNT_NAME, null);
97 
98  // Get the saved authToken, possibly null. We save even though we refresh it every time
99  String authToken = settings.getString(PREF_AUTH_TOKEN, null);
100 
101  // Initialize credential with the saved authToken.
102  GoogleCredential credential = new GoogleCredential();
103  credential.setAccessToken(authToken);
104 
105  // Tell AccountManager to get the authToken and user account name. This is
106  // where all the details of the OAuth flow are hidden.
107  AccountManagerFuture<Bundle> future =
108  getAccountManagerResult(activity, credential, authTokenType, accountName);
109 
110  // Extract and save the authToken and account name
111  try {
112 
113  Bundle authTokenBundle = future.getResult();
114  authToken = authTokenBundle.get(AccountManager.KEY_AUTHTOKEN).toString();
115 
116  persistCredentials(settings,
117  authTokenBundle.getString(AccountManager.KEY_ACCOUNT_NAME),
118  authToken);
119  } catch (OperationCanceledException e) {
120  e.printStackTrace();
122  errorMessage = "Error: operation cancelled";
123  } catch (AuthenticatorException e) {
124  e.printStackTrace();
125  errorMessage = "Error: Authenticator error";
126  } catch (IOException e) {
127  e.printStackTrace();
128  errorMessage = "Error: I/O error";
129  }
130 
131  // Return the authToken or null
132  return authToken;
133  }
134 
145  private AccountManagerFuture<Bundle> getAccountManagerResult(Activity activity,
146  GoogleCredential credential,
147  String authTokenType,
148  String accountName) {
149 
150  AccountManagerFuture<Bundle> future = null;
151  GoogleAccountManager accountManager = new GoogleAccountManager(activity);
152 
153  // Force the return of fresh token by invalidating the current token
154  // Doing this on every OAuth request, avoids the need to determine whether the
155  // authToken has expired, usually after 1 hour, and then getting
156  // another one using the refresh token.
157 
158  accountManager.invalidateAuthToken(credential.getAccessToken());
159  AccountManager.get(activity).invalidateAuthToken(authTokenType, null);
160 
161  // Try to get the user's account by account name. Might return null
162 
163  Account account = accountManager.getAccountByName(accountName);
164 
165  // Here is where AccountManager may prompt user to select an account
166  if (account != null) {
167 
168  // We have the user's account at this point, so AccountManager simply returns the token
169  Log.i(TAG, "Getting token by account");
170  future = accountManager.getAccountManager().getAuthToken(account, authTokenType, true, null, null);
171 
172  } else {
173 
174  // AccountManager uses 'features' to get the authToken, possibly prompting the user to choose an account
175  Log.i(TAG, "Getting token by features, possibly prompting user to select an account");
176  future = accountManager.getAccountManager().getAuthTokenByFeatures(GoogleAccountManager.ACCOUNT_TYPE,
177  authTokenType, null, activity, null, null, null, null);
178  }
179 
180  // Return the whole bundle containing the authToken, account name, and other data.
181  return future;
182  }
183 
187  private boolean isUiThread() {
188  return Looper.getMainLooper().getThread().equals(Thread.currentThread());
189  }
190 
191 
197  private void persistCredentials(SharedPreferences settings, String accountName, String authToken) {
198  Log.i(TAG, "Persisting credentials, acct =" + accountName);
199  SharedPreferences.Editor editor = settings.edit();
200  editor.putString(PREF_ACCOUNT_NAME, accountName);
201  editor.putString(PREF_AUTH_TOKEN, authToken);
202  editor.commit();
203  }
204 
211  public static void resetAccountCredential(Activity activity) {
212  Log.i(TAG, "Reset credentials");
213  SharedPreferences settings = activity.getPreferences(Activity.MODE_PRIVATE);
214  SharedPreferences.Editor editor2 = settings.edit();
215  editor2.remove(PREF_AUTH_TOKEN);
216  editor2.remove(PREF_ACCOUNT_NAME);
217  editor2.commit();
218  }
219 
224  public static String getErrorMessage() {
225  Log.i(TAG, "getErrorMessage = " + errorMessage);
226  return errorMessage;
227  }
228 }
com.google.appinventor.components.runtime.util.OAuth2Helper.PREF_ACCOUNT_NAME
static final String PREF_ACCOUNT_NAME
Definition: OAuth2Helper.java:75
com.google.appinventor.components.runtime.util.OAuth2Helper.OAuth2Helper
OAuth2Helper()
Definition: OAuth2Helper.java:79
com.google.appinventor.components.runtime.util.OAuth2Helper.TAG
static final String TAG
Definition: OAuth2Helper.java:73
com.google.appinventor.components.runtime.util.OAuth2Helper.PREF_AUTH_TOKEN
static final String PREF_AUTH_TOKEN
Definition: OAuth2Helper.java:74
com.google.appinventor.components.runtime.util.OAuth2Helper
Definition: OAuth2Helper.java:71
com.google.appinventor.components.runtime.util.OAuth2Helper.getErrorMessage
static String getErrorMessage()
Definition: OAuth2Helper.java:224
com.google.appinventor.components.runtime.util.OAuth2Helper.getRefreshedAuthToken
String getRefreshedAuthToken(Activity activity, String authTokenType)
Definition: OAuth2Helper.java:88
com.google.appinventor.components.runtime.util.OAuth2Helper.resetAccountCredential
static void resetAccountCredential(Activity activity)
Definition: OAuth2Helper.java:211
com.google
com