writer.write(name.replaceAll("\\|","\\\\|").toLowerCase()+"|"//so that the delimiter is unique even if people use it in usernames; case insensitive
+makePassword(pw,confirm)+"|"//encrypt password with salted MD5; using $ as delimiter because hex strings will not contain it
+"0|"//score
+"0\n");//answered (to compute accuracy)
writer.close();
out.close();
returnnewUser(name,pw);//redundant login; but still a good check
}
/**
* Generates a salted and hashed password with MD5 for storage in the database.
* <p>
* Third-party programs are not expected to utilize this method, but they should access this method through reflection if they have to edit the database manually.
* @param pw the password which should include both upper case and lower case letters, along with at least one number
* @param confirm a matching password for confirmation
if(!pw.matches("(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).*"))thrownewIllegalArgumentException("The password entered is not strong enough!\nIt needs to have at least 1 lower case letter, 1 upper case letter and 1 number.");
if(pw.equals(confirm)){
Stringsalt=generateSalt(8);//TODO make salt length configurable?
returnsalt+"$"+hash(pw+salt);
}else{
thrownewIllegalArgumentException("Passwords does not match!");
}
}
/**
* Compares the hashed password with the password provided.
return(score*getAccuracyRaw()-levels.floorKey(score*getAccuracyRaw()))/(levels.ceilingKey(score*getAccuracyRaw())-levels.floorKey(score*getAccuracyRaw()));//so its the actual range not the whole range
}else{
returnDouble.POSITIVE_INFINITY;
}
}
/**
* Saves the user object into the user database.
* @throws IOException if the user database is not accessible
*/
publicvoidsave()throwsIOException{//NOTE: SAVING IS NOT THREAD SAFE!
editData(this.name.replaceAll("\\|","\\\\|").toLowerCase()+"|"//so that the delimiter is unique even if people use it in usernames; case insensitive
+searchData(this.name)[1]+"|"//encrypt password with salted MD5; using $ as delimiter because hex strings will not contain it
+this.score+"|"//score
+this.answered);//answered (to compute accuracy)
}
/**
* Updates the user's password.<br>
* This function is currently unused in the main arithmetic trainer, however third-party programs are free to utilize this method.
* @param oldPw the original password of the user
* @param newPw the new password of the user, see {@link User#makePassword(String, String)}
* @param confirm a matching password for confirmation
* @throws IOException if the user database is not accessible
thrownewIllegalStateException("Invalid level!");//as score * acc will never go down to 0, and the lowest key is 0, reaching this means something has gone wrong