Skip to content

Instantly share code, notes, and snippets.

@granoeste
Created September 28, 2011 12:53
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save granoeste/1247856 to your computer and use it in GitHub Desktop.
Save granoeste/1247856 to your computer and use it in GitHub Desktop.
[Android] Google Service Authenticate
public class GoogleServiceAuthenticator {
public static final String ACCOUNT_TYPE = "com.google";
public enum GOOGLE_ACCOUNT_TYPE {
APPENGINE { public String toString() { return "ah"; } },
}
public interface PostExecuteCallback {
void run(String acsid);
}
private Context context;
private AccountManager accountManager;
private String hostname;
private String appPath;
private PostExecuteCallback postExecuteCallback;
private DefaultHttpClient httpClient = new DefaultHttpClient();
public GoogleServiceAuthenticator(Context context) {
this.context = context;
}
public Account[] getGoogleAccounts() {
if (accountManager == null) {
accountManager = AccountManager.get(context);
}
return accountManager.getAccountsByType(ACCOUNT_TYPE);
}
public void execute(Account account, GOOGLE_ACCOUNT_TYPE type, PostExecuteCallback postExecuteCallback) throws Exception {
if (hostname == null) {
throw new Exception("hostname must not be null");
}
if (appPath == null) {
throw new Exception("appPath must not be null");
}
this.postExecuteCallback = postExecuteCallback;
// Gets an auth token of the specified type.
accountManager.getAuthToken(
account, // The account to fetch an auth token for
type.toString(), // The auth token type, an authenticator-dependent string token, must not be null
false, // True to add a notification to prompt the user for a password if necessary, false to leave that to the caller
new GetAuthTokenCallback(), // Callback to invoke when the request completes, null for no callback
null // Handler identifying the callback thread, null for the main thread
);
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
public void setAppPath(String appPath) {
this.appPath = appPath;
}
private String getLoginUrl(String hostname, String appPath, String authToken) {
return "https://" + hostname + "/_ah/login?continue=" + appPath + "&auth=" + authToken;
}
private class GetAuthTokenCallback implements AccountManagerCallback<Bundle> {
@Override
public void run(AccountManagerFuture<Bundle> result) {
Bundle bundle;
try {
bundle = result.getResult();
Intent intent = (Intent)bundle.get(AccountManager.KEY_INTENT);
if(intent != null) {
// User input required
context.startActivity(intent);
} else {
String acsid = getAuthToken(bundle);
// If authentication succeeds and gets the SACSID/ACSID, the post-process is called.
if (acsid != null) {
if (postExecuteCallback != null) {
postExecuteCallback.run(acsid);
}
}
}
} catch (OperationCanceledException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AuthenticatorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
private String getAuthToken(Bundle bundle) {
boolean validated = false;
int count = 3;
try {
while (!validated) {
String authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
httpClient.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);
String uri = getLoginUrl(hostname, appPath, authToken);
HttpGet httpGet = new HttpGet(uri);
HttpResponse httpResponse = httpClient.execute(httpGet);
int status = httpResponse.getStatusLine().getStatusCode();
if (status == HttpStatus.SC_INTERNAL_SERVER_ERROR) {
// Authenticate error (500)
try {
StringBuilder buf = new StringBuilder();
buf.append(String.format("Status:%d ", status));
InputStream in = httpResponse.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String l = null;
while ((l = reader.readLine()) != null) {
buf.append(l + "\n");
}
Log.w(TAG, buf.toString());
} catch (Exception e) {
}
// Removes an auth token from the AccountManager's cache.
String accountType = bundle.getString(AccountManager.KEY_ACCOUNT_TYPE);
accountManager.invalidateAuthToken(accountType, authToken);
} else {
// Authenticate success
validated = true;
break;
}
// retry count down
if (0 < count--) {
break;
}
}
// If authentication succeeds, get the SACSID/ACSID from the Cookie
if (validated) {
for (Cookie cookie : httpClient.getCookieStore().getCookies()) {
if ("SACSID".equals(cookie.getName()) || "ACSID".equals(cookie.getName())) {
return cookie.getName() + "=" + cookie.getValue();
}
}
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
public class GoogleServiceAuthExampleActivity extends ListActivity {
private static final String TAG = GoogleServiceAuthExampleActivity.class.getName();
GoogleServiceAuthenticator authenticator;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
authenticator = new GoogleServiceAuthenticator(this);
Account[] accounts = authenticator.getGoogleAccounts();
this.setListAdapter(new ArrayAdapter<Account>(this, android.R.layout.simple_list_item_1, accounts));
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Account account = (Account)getListView().getItemAtPosition(position);
authenticator.setHostname("yourappl.appspot.com");
authenticator.setAppPath("http://localhost/");
try {
authenticator.execute(account, GOOGLE_ACCOUNT_TYPE.APPENGINE,
new GoogleServiceAuthenticator.PostExecuteCallback() {
@Override
public void run(String acsid) {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://yourappl.appspot.com/sign");
HttpResponse httpResponse = null;
try {
List<BasicNameValuePair> parms = new ArrayList<BasicNameValuePair>();
parms.add(new BasicNameValuePair("content", "InputData=" + new SimpleDateFormat().format(new Date()) ));
httpPost.setEntity(new UrlEncodedFormEntity(parms, HTTP.UTF_8));
httpPost.setHeader("Cookie", acsid);
httpResponse = httpClient.execute(httpPost);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (httpResponse != null) {
int status = httpResponse.getStatusLine().getStatusCode();
StringBuilder buf = new StringBuilder();
buf.append(String.format("status:%d", status));
try {
InputStream in = httpResponse.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String l = null;
while((l = reader.readLine()) != null) {
buf.append(l + "\n");
}
if (status != HttpStatus.SC_OK) {
Log.e(TAG, buf.toString());
}
} catch(Exception e) {
e.printStackTrace();
}
(Toast.makeText(
GoogleServiceAuthExampleActivity.this,
buf.toString(),
Toast.LENGTH_LONG)).show();
Log.d(TAG, buf.toString());
}
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment