package com.rogoapp.auth;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import com.rogoapp.CacheClient;
import com.rogoapp.MainScreenActivity;
import com.rogoapp.R;
import com.rogoapp.ServerClient;
import com.rogoapp.auth.EmailValidator;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorActivity;
import android.accounts.AccountManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
public class RogoAuthenticatorActivity extends AccountAuthenticatorActivity {
public static final String PARAM_AUTHTOKEN_TYPE = "com.rogoapp";
public static final String PARAM_CREATE = "create";
public static final String PARAM_USERNAME = "username";
public static final String OPEN_MAIN = "open main";
public static final String PARAM_CONFIRMCREDENTIALS = "server confirmation";
public static boolean createToken;
public boolean openMain;
private CheckBox rememberMe;
private EditText tvUsername;
private EditText tvPassword;
private Button register;
private Button login;
private String username;
private String password;
final Context context = this;
private CacheClient cache;
private static AccountManager am;
@Override
protected void onCreate(Bundle icicle) {
// recreates from saved state -- icicle is the same as savedInstanceState
super.onCreate(icicle);
//creates a view from the login.xml file
this.setContentView(R.layout.login);
am = AccountManager.get(this);
cache = new CacheClient(this);
//set variables and aesthetic changes
rememberMe = (CheckBox)this.findViewById(R.id.remember_me_check);
tvUsername = (EditText) this.findViewById(R.id.auth_txt_username);
tvPassword = (EditText) this.findViewById(R.id.auth_txt_pswd);
username = tvUsername.getText().toString();
password = tvPassword.getText().toString();
login = (Button) this.findViewById(R.id.btnLogin);
register = (Button) this.findViewById(R.id.link_to_register);
register.setBackgroundColor(Color.WHITE);
if(createToken)
login.setText("Remember Login");
openMain = getIntent().getBooleanExtra(OPEN_MAIN, false);
Account[] accounts = am.getAccountsByType(PARAM_AUTHTOKEN_TYPE);
if(accounts.length != 0){
String username = accounts[0].name;
tvUsername.setText(username);
tvUsername.setFocusable(false);
register.setText("Not " + username + "?");
// sString pass = am.getPassword(accounts[0]);
// String token = am.peekAuthToken(accounts[0], RogoAuthenticatorActivity.PARAM_AUTHTOKEN_TYPE);
// if(token == null || token == "")
// am.setAuthToken(accounts[0], PARAM_AUTHTOKEN_TYPE, "Hello token!");
}
// if(accounts.length >= 1){
// String pass = am.getPassword(accounts[1]);
// String token = am.peekAuthToken(accounts[1], RogoAuthenticatorActivity.PARAM_AUTHTOKEN_TYPE);
// if(token == null || token == "")
// am.setAuthToken(accounts[1], PARAM_AUTHTOKEN_TYPE, "Hello token!");
// }
}
@Override
protected void onNewIntent(Intent intent){
//when this intent is returned to, any data entered into it previously is reset
super.onNewIntent(intent);
if(intent.getBooleanExtra("reset", false)){
tvUsername.setText("");
tvPassword.setText("");
if(createToken){
rememberMe.performClick();
}
}
}
private boolean getToken(){
return createToken;
}
private void setToken(boolean Token){
createToken = Token;
}
public void onCancelClick(View v) {
this.finish();
}
public void openRegisterScreen(View v){
String check = (String) register.getText();
if(check.equals("Register")){
//opens the registration form
Intent intent = new Intent(context, RegisterActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
}
else{
tvUsername.setText("");
tvUsername.setFocusableInTouchMode(true);
register.setText(R.string.register);
logout();
}
}
public void onRememberMe(View V){
//When the user has chosen to be remembered, sets the Login to store an auth-token
//and changes the Login button appropriately to reflect their choice
if(getToken()){
this.setToken(false);
}
else this.setToken(true);
if(getToken()){
login.setText("Remember Login");
}
else login.setText("Login");
}
public static void logout(){
Account account = am.getAccountsByType(PARAM_AUTHTOKEN_TYPE)[0];
//clears the stored password and invalidates the current auth-token if one exists
String authToken = am.peekAuthToken(account, PARAM_AUTHTOKEN_TYPE);
am.clearPassword(account);
am.invalidateAuthToken(account.type, authToken);
am.removeAccount(account, null, null);
}
public void onSaveClick(View v) {
//check for network
if(!ServerClient.isNetworkAvailable()){
showMessage("No Network Connection");
return;
}
//checks for any errors within the form
//if errors are found, the login exits
if(hasErrors())
return;
else{
// Now that we have done some simple "client side" validation it
// is time to check with the server
this.password = AccountAuthenticator.hashPassword(password);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("email", username));
nameValuePairs.add(new BasicNameValuePair("password", password));
JSONObject json = ServerClient.genericPostRequest("login", nameValuePairs);
String toHash = "";
try {
String check = json.getString("data");
if(check.equals("Email or password is incorrect!")){
tvPassword.setText("");
Toast.makeText(context, check, Toast.LENGTH_LONG).show();
return;
}
else{
JSONObject data = json.getJSONObject("data");
String session = data.getString("session");
String secret = data.getString("secret");
cache.saveFile(CacheClient.SESSION_CACHE, session);
toHash = secret;
}
} catch (JSONException e) {
e.printStackTrace();
System.out.println("Json did not return");
showMessage("Server error: Corrupted Response");
return;
}
// finished
String accountType = this.getIntent().getStringExtra(PARAM_AUTHTOKEN_TYPE);
if (accountType == null) {
accountType = AccountAuthenticator.ACCOUNT_TYPE;
}
Account[] accounts = am.getAccountsByType(PARAM_AUTHTOKEN_TYPE);
if(accounts.length != 0 && !accounts[0].name.equalsIgnoreCase(username)){
showMessage("Only one user is allowed on this phone.\nPlease log out before continuing.");
return;
}
else if(accounts.length == 1 && accounts[0].name.equalsIgnoreCase(username)){
username = accounts[0].name;
}
// This is the magic that adds the account to the Android Account Manager
final Account account = new Account(username, accountType);
am.addAccountExplicitly(account, password, null);
// am.addAccount(PARAM_AUTHTOKEN_TYPE, PARAM_AUTHTOKEN_TYPE, null, null, this, null, null);
// Now we tell our caller, could be the Android Account Manager or even our own application
// that the process was successful
final Intent intent = new Intent();
intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, username);
intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountType);
intent.putExtra(AccountManager.KEY_PASSWORD, password);
if(getToken()){
intent.putExtra(AccountManager.KEY_AUTHTOKEN, toHash);
am.setAuthToken(account, PARAM_AUTHTOKEN_TYPE, toHash);
}
this.setAccountAuthenticatorResult(intent.getExtras());
this.setResult(RESULT_OK, intent);
//after setting the account, close the login activity and open the MainScreenActivity
if(openMain){
final Intent start = new Intent(context, MainScreenActivity.class);
start.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(start);
}
this.finish();
}
}
private Boolean hasErrors(){
EmailValidator validate = new EmailValidator();
this.username = tvUsername.getText().toString();
this.password = tvPassword.getText().toString();
if (!validate.validate(username)) {
showMessage("Invalid Email");
return true;
}
else if (password.length() < 6) {
showMessage("Invalid Password");
return true;
}
return false;
}
private void showMessage(final String msg) {
if (TextUtils.isEmpty(msg))
return;
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
}
});
}
}