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;
}
}