Java tutorial
/******************************************************************************* * Copyright 2012-2013 Trento RISE * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package eu.trentorise.smartcampus.ac.authenticator; import java.io.IOException; import org.json.JSONException; import org.json.JSONObject; import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.AccountManagerCallback; import android.accounts.AccountManagerFuture; import android.accounts.AuthenticatorException; import android.accounts.OperationCanceledException; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.IntentSender; import android.content.IntentSender.SendIntentException; import android.os.Bundle; import eu.trentorise.smartcampus.ac.Constants; import eu.trentorise.smartcampus.ac.SCAccessProvider; import eu.trentorise.smartcampus.ac.model.UserData; /** * Implementation of the {@link SCAccessProvider} interface relying on the token * stored {@link AccountManager} and using the {@link AuthenticatorActivity} activity. * @author raman * */ public class AMSCAccessProvider implements SCAccessProvider { private class Callback implements AccountManagerCallback<Bundle> { private String authority; private Activity activity; /** * @param authority * @param activity */ public Callback(String authority, Activity activity) { super(); this.authority = authority; this.activity = activity; } @Override public void run(AccountManagerFuture<Bundle> result) { Bundle bundle = null; try { bundle = result.getResult(); Intent launch = (Intent) bundle.get(AccountManager.KEY_INTENT); if (launch != null) { launch.putExtra(Constants.KEY_AUTHORITY, authority); activity.startActivityForResult(launch, SC_AUTH_ACTIVITY_REQUEST_CODE); } } catch (Exception e) { return; } } } @Override public String readToken(Context ctx, String inAuthority) { final String authority = inAuthority == null ? Constants.AUTHORITY_DEFAULT : inAuthority; AccountManager am = AccountManager.get(ctx); return am.peekAuthToken(new Account(Constants.getAccountName(ctx), Constants.getAccountType(ctx)), authority); } @Override public String getAuthToken(Context ctx, String inAuthority) throws OperationCanceledException, AuthenticatorException, IOException { final String authority = inAuthority == null ? Constants.AUTHORITY_DEFAULT : inAuthority; AccountManager am = AccountManager.get(ctx); AccountManagerFuture<Bundle> future = am.getAuthToken( new Account(Constants.getAccountName(ctx), Constants.getAccountType(ctx)), authority, true, null, null); String token = null; if (future.isDone()) { token = future.getResult().getString(AccountManager.KEY_AUTHTOKEN); } return token; } @Override public String getAuthToken(final Activity activity, String inAuthority) throws OperationCanceledException, AuthenticatorException, IOException { final String authority = inAuthority == null ? Constants.AUTHORITY_DEFAULT : inAuthority; final AccountManager am = AccountManager.get(activity); String token = am.peekAuthToken( new Account(Constants.getAccountName(activity), Constants.getAccountType(activity)), authority); if (token == null) { final Account a = new Account(Constants.getAccountName(activity), Constants.getAccountType(activity)); Account[] accounts = am.getAccountsByType(Constants.getAccountType(activity)); if (accounts == null || accounts.length == 0) { am.addAccount(Constants.getAccountType(activity), authority, null, null, null, new Callback(authority, activity), null); } else { am.getAuthToken(a, authority, null, null, new Callback(authority, activity), null); } return null; } return token; } @Override public String getAuthToken(Context ctx, String inAuthority, IntentSender intentSender) throws OperationCanceledException, AuthenticatorException, IOException { final String authority = inAuthority == null ? Constants.AUTHORITY_DEFAULT : inAuthority; AccountManager am = AccountManager.get(ctx); AccountManagerFuture<Bundle> future = am.getAuthToken( new Account(Constants.getAccountName(ctx), Constants.getAccountType(ctx)), authority, false, new OnTokenAcquired(ctx, authority, intentSender), null); String token = null; if (future.isDone()) { token = future.getResult().getString(AccountManager.KEY_AUTHTOKEN); } return token; } private class OnTokenAcquired implements AccountManagerCallback<Bundle> { private Context context; private String authority; private IntentSender intentSender; public OnTokenAcquired(Context context, String authority, IntentSender intentSender) { super(); this.context = context; this.authority = authority; this.intentSender = intentSender; } @Override public void run(AccountManagerFuture<Bundle> result) { Bundle bundle = null; String token = null; try { bundle = result.getResult(); } catch (Exception e) { return; } token = bundle.getString(AccountManager.KEY_AUTHTOKEN); if (token != null) { if (intentSender != null) { try { Intent add = new Intent(); add.putExtra(AccountManager.KEY_AUTHTOKEN, token); intentSender.sendIntent(context, SC_AUTH_ACTIVITY_REQUEST_CODE, add, null, null); } catch (SendIntentException e) { return; } } return; } Intent launch = (Intent) bundle.get(AccountManager.KEY_INTENT); if (launch != null) { if (context != null) { launch.putExtra(Constants.KEY_AUTHORITY, authority); launch.putExtra(Constants.CALLBACK_INTENT, intentSender); context.startActivity(launch); } return; } } } @Override public void invalidateToken(Context context, String inAuthority) { // final String authority = inAuthority == null ? Constants.AUTHORITY_DEFAULT : inAuthority; AccountManager am = AccountManager.get(context); am.invalidateAuthToken(Constants.getAccountType(context), readToken(context, inAuthority)); // am.removeAccount(new Account(Constants.getAccountName(context), Constants.getAccountType(context)), null, null); } @Override public String promote(final Activity activity, String inAuthority, final String token) { final String authority = inAuthority == null ? Constants.AUTHORITY_DEFAULT : inAuthority; final AccountManager am = AccountManager.get(activity); // Bundle options = new Bundle(); // if (token != null) { // options.putString(Constants.PROMOTION_TOKEN, token); // } final Account a = new Account(Constants.getAccountName(activity), Constants.getAccountType(activity)); final String userDataString = am.getUserData(a, AccountManager.KEY_USERDATA); invalidateToken(activity, authority); am.getAuthToken(new Account(Constants.getAccountName(activity), Constants.getAccountType(activity)), authority, null, null, new AccountManagerCallback<Bundle>() { @Override public void run(AccountManagerFuture<Bundle> result) { Bundle bundle = null; try { bundle = result.getResult(); Intent launch = (Intent) bundle.get(AccountManager.KEY_INTENT); if (launch != null) { launch.putExtra(Constants.KEY_AUTHORITY, authority); launch.putExtra(Constants.PROMOTION_TOKEN, token); launch.putExtra(Constants.OLD_DATA, userDataString); activity.startActivityForResult(launch, SC_AUTH_ACTIVITY_REQUEST_CODE); } else if (bundle.getString(AccountManager.KEY_AUTHTOKEN) != null) { // am.setAuthToken(a, authority, bundle.getString(AccountManager.KEY_AUTHTOKEN)); // am.addAccountExplicitly(a, null, null); // no token acquired } else { storeAnonymousToken(token, authority, am, a); } } catch (Exception e) { // revert the invalidated token storeAnonymousToken(token, authority, am, a); return; } } }, null); return null; } private void storeAnonymousToken(final String token, final String authority, final AccountManager am, final Account a) { if (token == null) return; am.setAuthToken(a, authority, token); am.setAuthToken(a, Constants.TOKEN_TYPE_ANONYMOUS, token); am.addAccountExplicitly(a, null, null); } @Override public UserData readUserData(Context ctx, String inAuthority) { AccountManager am = AccountManager.get(ctx); Account account = new Account(Constants.getAccountName(ctx), Constants.getAccountType(ctx)); // final String authority = inAuthority == null ? Constants.AUTHORITY_DEFAULT : inAuthority; // String token = am.peekAuthToken(account, authority); // if (token == null) return null; String userDataString = am.getUserData(account, AccountManager.KEY_USERDATA); if (userDataString == null) return null; try { return UserData.valueOf(new JSONObject(userDataString)); } catch (JSONException e) { return null; } } @Override public boolean isUserAnonymous(Context ctx) { AccountManager am = AccountManager.get(ctx); Account account = new Account(Constants.getAccountName(ctx), Constants.getAccountType(ctx)); String authority = am.getUserData(account, Constants.KEY_AUTHORITY); return Constants.TOKEN_TYPE_ANONYMOUS.equals(authority); } }