package com.quinn.githubknife.account; import android.accounts.AbstractAccountAuthenticator; import android.accounts.Account; import android.accounts.AccountAuthenticatorResponse; import android.accounts.AccountManager; import android.accounts.NetworkErrorException; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; import com.quinn.githubknife.GithubApplication; import com.quinn.githubknife.model.GithubService; import com.quinn.githubknife.model.RetrofitUtil; import com.quinn.githubknife.ui.activity.LoginActivity; import com.quinn.httpknife.github.AuthError; import com.quinn.httpknife.github.Github; import com.quinn.httpknife.github.GithubError; import com.quinn.httpknife.github.GithubImpl; import com.quinn.httpknife.github.OverAuthError; import retrofit.Retrofit; /** * Created by Quinn on 7/10/15. */ public class Authenticator extends AbstractAccountAuthenticator { private static final String TAG = Authenticator.class.getSimpleName(); private Context context; public final static String PARAM_USER_PASS = "USER_PASS"; public final static String ARG_ACCOUNT_TYPE = "ACCOUNT_TYPE"; public final static String ARG_AUTH_TYPE = "AUTH_TYPE"; public final static String ARG_ACCOUNT_NAME = "ACCOUNT_NAME"; public final static String ARG_IS_ADDING_NEW_ACCOUNT = "IS_ADDING_ACCOUNT"; public final static String AUTHTOKEN_TYPE_FULL_ACCESS = "Full access"; private GithubApplication app; private Retrofit retrofit; private GithubService service; public Authenticator(Context context) { super(context); this.context = context; this.app = (GithubApplication) context.getApplicationContext(); this.retrofit = RetrofitUtil.getRetrofitWithoutTokenInstance(context); this.service = retrofit.create(GithubService.class); } @Override public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) { return null; } @Override public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException { final Intent intent = new Intent(context, LoginActivity.class); intent.putExtra(ARG_ACCOUNT_TYPE, accountType); intent.putExtra(ARG_AUTH_TYPE, authTokenType); intent.putExtra(ARG_IS_ADDING_NEW_ACCOUNT, true); intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); final Bundle bundle = new Bundle(); bundle.putParcelable(AccountManager.KEY_INTENT, intent); return bundle; } @Override public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) throws NetworkErrorException { return null; } @Override public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { final AccountManager am = AccountManager.get(context); String authToken = am.peekAuthToken(account, authTokenType); if (TextUtils.isEmpty(authToken)) { final String password = am.getPassword(account); if (password != null) { Github github = new GithubImpl(context); try { //Get token from server authToken = github.createToken(account.name,password); } catch (GithubError githubError) { githubError.printStackTrace(); authToken = ""; } catch (AuthError authError) { authError.printStackTrace(); authToken = ""; } catch (OverAuthError overAuthError) { overAuthError.printStackTrace(); authToken = ""; } }else { //If u fail to get local token,check if there is a token saved in application. if(!app.getToken().isEmpty()){ final Bundle result = new Bundle(); result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); result.putString(AccountManager.KEY_AUTHTOKEN, app.getToken()); return result; } } } if (!TextUtils.isEmpty(authToken)) { //After generating app.setToken(authToken); final Bundle result = new Bundle(); result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); result.putString(AccountManager.KEY_AUTHTOKEN, authToken); return result; } // If we get here, then we couldn't access the user's password - so we // need to re-prompt them for their credentials. We do that by creating // an intent to display our AuthenticatorActivity. final Intent intent = new Intent(context, LoginActivity.class); intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); intent.putExtra(ARG_ACCOUNT_TYPE, account.type); intent.putExtra(ARG_AUTH_TYPE, authTokenType); final Bundle bundle = new Bundle(); bundle.putParcelable(AccountManager.KEY_INTENT, intent); return bundle; } @Override public String getAuthTokenLabel(String authTokenType) { return null; } @Override public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { return null; } @Override public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException { return null; } }