dimanche 29 novembre 2015

Puling info from/using documents in Couchbase lite

I'm working on an android app and am trying to do the following:The user creates an account. Their password is hashed and stored in the database. When the user attempts to login, the hash of the password they entered is checked against the hash of their real password (retrieved from the database).
If the hashes match, the user is granted access. If not, the user is told they entered invalid login credentials. So far, I have managed to create a salt and a hash for the user and have it stored to the DB. My question is how can I retrieve them to validate the user's credentials to allow them access to the account. I plan on using the check method from the Authenticator class, just not sure how to pull the hash from the DB. I removed the import statements to make the code easier to read. The code I have so far:

**Create account class**

package cse280.fitfastapp;

/**
* An account creation screen that offers login via username/password.
*/

public class CreateAccount extends AppCompatActivity {

SharedPreferences sPref;
private final String PREFS = "SharedPreferences";
private final String genderKey = "gender";
private final String activityKey = "activity_level";
private final String timeKey = "time_frame";
private final String nameKey = "name";
private final String ageKey = "age";
private final String heightKey = "height";
private final String weightKey = "weight";
private final String goalKey = "target";
private final String passwordKey = "password";
private final String desiredWorkoutsKey = "desired_workouts";
private final String hashKey = "accounthash";
private final String saltKey = "accountsalt";

private Context mContext;
private Manager manager;
private Database db;

RadioButton male;
RadioButton female;
RadioButton one;
RadioButton two;
RadioButton three;

@override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_account);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

sPref = getSharedPreferences(PREFS, Context.MODE_PRIVATE);

male = (RadioButton) findViewById(R.id.male);
female = (RadioButton) findViewById(R.id.female);
one = (RadioButton) findViewById(R.id.one);
two = (RadioButton) findViewById(R.id.three);
three = (RadioButton) findViewById(R.id.six);

}

@override
public void onResume(){
super.onResume();
mContext = getApplicationContext();
try {
manager = new Manager(new AndroidContext(mContext), Manager.DEFAULT_OPTIONS);
db = manager.getDatabase("accounts");
} catch (IOException io) {
Log.e("Manager Error:", "Cannot create Manager instance");
} catch (CouchbaseLiteException ce) {
Log.e("Couchbase Error:","Cannot open database");
}
}

public void onRadioButtonClicked(View view) {
boolean checked = ((RadioButton) view).isChecked();
SharedPreferences.Editor editor = sPref.edit();
switch(view.getId()) {
case R.id.male:
if (checked)
editor.putString(genderKey,"Male");
break;
case R.id.female:
if (checked)
editor.putString(genderKey, "Female");
break;

case R.id.one:
if (checked)
editor.putString(timeKey,"3");
break;
case R.id.three:
if (checked)
editor.putString(timeKey,"6");
break;
case R.id.six:
if (checked)
editor.putString(timeKey,"12");
break;
}
editor.commit();
}

@TargetApi(21)
public void genderRed(){

male.setButtonTintList(android.content.res.ColorStateList.valueOf(Color.RED));
female.setButtonTintList(android.content.res.ColorStateList.valueOf(Color.RED));
}

@TargetApi(21)
public void timeRed(){

one.setButtonTintList(android.content.res.ColorStateList.valueOf(Color.RED));
two.setButtonTintList(android.content.res.ColorStateList.valueOf(Color.RED));
three.setButtonTintList(android.content.res.ColorStateList.valueOf(Color.RED));
}

@TargetApi(21)
public void clearRed(){
male.setButtonTintList(android.content.res.ColorStateList.valueOf(Color.DKGRAY));
female.setButtonTintList(android.content.res.ColorStateList.valueOf(Color.DKGRAY));
one.setButtonTintList(android.content.res.ColorStateList.valueOf(Color.DKGRAY));
two.setButtonTintList(android.content.res.ColorStateList.valueOf(Color.DKGRAY));
three.setButtonTintList(android.content.res.ColorStateList.valueOf(Color.DKGRAY));

}

public void done(View view) throws NoSuchAlgorithmException, InvalidKeySpecException {

SharedPreferences.Editor editor = sPref.edit();
EditText editDesiredWorkouts = (EditText) findViewById(R.id.set_desired_workouts);
EditText editName = (EditText) findViewById(R.id.set_name);
EditText editAge = (EditText) findViewById(R.id.set_age);
EditText editActivityLevel = (EditText) findViewById(R.id.set_activity_level);
EditText editHeight = (EditText) findViewById(R.id.set_height);
EditText editWeight = (EditText) findViewById(R.id.set_weight);
EditText editGoal = (EditText) findViewById(R.id.set_goal);
EditText editPassword = (EditText) findViewById(R.id.set_password);
int errors = 0;
String error = "";
String name = editName.getText().toString().toLowerCase().trim();
String password = editPassword.getText().toString().trim();
byte[] userSalt = Authenticator.generateSalt();
byte[] userHash = Authenticator.generateHash(password,userSalt);

clearRed();

if(!male.isChecked() && !female.isChecked()){
errors += 1;
error = "Please select a gender";
genderRed();

}

if(!one.isChecked() && !three.isChecked() && !two.isChecked()){
errors += 1;
error = "Please select a timeframe";
timeRed();
}

try {
if (1 > Integer.parseInt(editDesiredWorkouts.getText().toString()) || Integer.parseInt(editDesiredWorkouts.getText().toString()) > 14) {
errors +=1;
error = "Please enter a desired # of workouts between 1 and 14";
editDesiredWorkouts.setText(null);
editDesiredWorkouts.setHintTextColor(Color.RED);

}
}
catch(Exception e){
errors +=1;
error = "Please enter a desired # of workouts between 1 and 14";
editDesiredWorkouts.setText(null);
editDesiredWorkouts.setHintTextColor(Color.RED);
}

try {
if (editName.getText().toString().length() > 10 || editName.getText().toString().equals("")) {
errors +=1;
error = "Please enter a name between 1 and 10 charecters long";
editName.setText(null);
editName.setHintTextColor(Color.RED);
}
}
catch(Exception e){
errors +=1;
error = "Please enter a name between 1 and 10 charecters long";
editName.setText(null);
editName.setHintTextColor(Color.RED);
}

try {
if (1 > Integer.parseInt(editAge.getText().toString()) || Integer.parseInt(editAge.getText().toString()) > 120) {
errors +=1;
error = "Please enter a valid age";
editAge.setText(null);
editAge.setHintTextColor(Color.RED);
}
}
catch(Exception e){
errors +=1;
error = "Please enter a valid age";
editAge.setText(null);
editAge.setHintTextColor(Color.RED);
}

try {
if (1 > Integer.parseInt(editActivityLevel.getText().toString()) || Integer.parseInt(editActivityLevel.getText().toString()) > 5) {
errors +=1;
error = "Please enter an activity level between 1 and 5";
editActivityLevel.setText(null);
editActivityLevel.setHintTextColor(Color.RED);
}
}
catch(Exception e){
errors +=1;
error = "Please enter an activity level between 1 and 5";
editActivityLevel.setText(null);
editActivityLevel.setHintTextColor(Color.RED);
}

try {
if (1 > Integer.parseInt(editHeight.getText().toString()) || Integer.parseInt(editHeight.getText().toString()) > 120) {
errors +=1;
error = "Please enter a valid height";
editHeight.setText(null);
editHeight.setHintTextColor(Color.RED);
}
}
catch(Exception e){
errors +=1;
error = "Please enter a valid height";
editHeight.setText(null);
editHeight.setHintTextColor(Color.RED);
}

try {
if (1 > Integer.parseInt(editWeight.getText().toString()) || Integer.parseInt(editWeight.getText().toString()) > 999) {
errors +=1;
error = "Please enter a valid weight";
editWeight.setText(null);
editWeight.setHintTextColor(Color.RED);
}
}
catch(Exception e){
errors +=1;
error = "Please enter a valid weight";
editWeight.setText(null);
editWeight.setHintTextColor(Color.RED);
}

try {
if (1 > Integer.parseInt(editGoal.getText().toString()) || Integer.parseInt(editGoal.getText().toString()) > 999) {
errors +=1;
error = "Please enter a valid goal weight";
editGoal.setText(null);
editGoal.setHintTextColor(Color.RED);
}
}
catch(Exception e){
errors +=1;
error = "Please enter a valid goal weight";
editGoal.setText(null);
editGoal.setHintTextColor(Color.RED);
}

try {
if (editPassword.getText().toString().length() > 16 || editPassword.getText().toString().length() < 1) {
errors +=1;
error = "Please enter a password between 1 and 16 characters";
editPassword.setText(null);
editPassword.setHintTextColor(Color.RED);
}
}
catch(Exception e){
errors +=1;
error = "Please enter a password between 1 and 16 characters";
editPassword.setText(null);
editPassword.setHintTextColor(Color.RED);
}

if(errors > 0){
if(errors < 2){
Toast.makeText(mContext, error, Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(mContext, "Please correct the fields marked in red", Toast.LENGTH_LONG).show();
}
}

else{

Document doc = db.getDocument(name);
Map<String, Object> properties = new HashMap<>();
try {
properties.put(hashKey, userHash);
properties.put(saltKey, userSalt);

try {
doc.putProperties(properties);
Toast.makeText(mContext, String.format("Added user %s", name), Toast.LENGTH_LONG).show();

editor.clear();
editor.putString(nameKey, editName.getText().toString());
editor.putString(ageKey, editAge.getText().toString());
editor.putString(activityKey, editActivityLevel.getText().toString());
editor.putString(heightKey, editHeight.getText().toString());
editor.putString(weightKey, editWeight.getText().toString());
editor.putString(goalKey, editGoal.getText().toString());
editor.putString(passwordKey, editPassword.getText().toString());
editor.putString(desiredWorkoutsKey, editDesiredWorkouts.getText().toString());
} catch (CouchbaseLiteException ce) {
Log.e("Couchbase Error:", "Error updating field for user :" + name);
}
} catch (NullPointerException e) {
Toast.makeText(mContext, "Null pointer, whatever that means",
Toast.LENGTH_LONG).show();
}

editor.commit();

Intent intent = new Intent();
setResult(RESULT_OK, intent);
finish();
}
}

**Login class**

package cse280.fitfastapp;

import fitfast.*;

/**
* A login screen that offers login via username/password.
*/
public class LoginActivity extends AppCompatActivity {

EditText mEmailView, mPasswordView;
Button loginButton, accountButton;
private final String PREFS = "SharedPreferences";
private SharedPreferences sPref;
private Manager manager;
private Database db;
private static Context mContext;

@override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);

mContext = getApplicationContext();
try {
manager = new Manager(new AndroidContext(mContext), Manager.DEFAULT_OPTIONS);
db = manager.getDatabase("accounts");
} catch (IOException io) {
Log.e("Manager Error:","Cannot create Manager instance");
return;
} catch (CouchbaseLiteException ce) {
Log.e("Couchbase Error:","Cannot open database");
}

sPref = getSharedPreferences(PREFS, Context.MODE_PRIVATE);
// Get Views from Login activity
mEmailView = (EditText) findViewById(R.id.userName);
mPasswordView = (EditText) findViewById(R.id.password);
loginButton = (Button) findViewById(R.id.email_sign_in_button);
accountButton = (Button) findViewById(R.id.create_an_account);

Map<String, Object> properties = new HashMap<>();
properties.put("type", "user");
properties.put("password", "pass1234");
properties.put("exists", true);
properties.put("encrypted", true);
Document document = db.getDocument("scensorECHO".toLowerCase());
try {
document.putProperties(properties);
} catch( CouchbaseLiteException ce ) {
Log.e("Couchbase Error: ","Cannot submit document to database");
}

}

public void createNew(View view){
Intent intent = new Intent(this, CreateAccount.class);
startActivityForResult(intent, RESULT_OK);
}

public void login(View view) {
Intent intent = new Intent(this, DashBoard.class);
String loginString = mEmailView.getText().toString().trim();
String passString = mPasswordView.getText().toString().trim();

SharedPreferences.Editor editor = sPref.edit();
editor.putString("login",loginString);
editor.putString("password",passString);
editor.commit();

Document login = db.getDocument(loginString.toLowerCase());
try {
if (passString.equals(login.getProperty("password"))) {
startActivity(intent);

} else {
Toast.makeText(mContext, "Invalid login credentials entered",
Toast.LENGTH_LONG).show();
}
} catch (NullPointerException e) {
Log.e("Document Error: ","No properties to retrieve");
Toast.makeText(mContext, "That user does not exist in our system",
Toast.LENGTH_LONG).show();
}
}
}

**Hashing/salt utility class**

package fitfast.security;

public final class Authenticator {

private static final int length = 512;
private static final int iterations = 60000;

public static byte[] generateHash(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
String algorithm = "PBKDF2WithHmacSHA512";
KeySpec sp = new PBEKeySpec(password.toCharArray(), salt, iterations, length);
SecretKeyFactory kf = SecretKeyFactory.getInstance(algorithm);
return kf.generateSecret(sp).getEncoded();
}

public static byte[] generateSalt() throws NoSuchAlgorithmException {
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
byte[] salt = new byte[8];
sr.nextBytes(salt);
return salt;
}

public static boolean check(byte[] hash, String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {

return Arrays.equals(hash, generateHash(password,salt));
}
}

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.



Puling info from/using documents in Couchbase lite

Aucun commentaire:

Enregistrer un commentaire