/** * @author Dr. Rob Hasker * 22-Oct-2013 * * An account class for a user with a pin code and a counter that locks * the user out when more than a specified number of failed attempts * occur. */ public class Account { private String user; private int failedAttempts = 0; private int pinCode; /** * Maximum number of failures; account locked when reach this number. */ public static final int MAX_FAILURES = 5; /** * Create account for given user, validated using given pin. * @param user User name for account. * @param pinCode Numeric code used to authenticate. */ public Account(String user, int pinCode) { this.user = user; this.pinCode = pinCode; } public Account(String user) { this(user, 0); } /** * Look up account owner. * @return User name */ public String getUser() { return user; } /** * Check if specified user and pin code match current account. * @param possible_user Username to check. * @param possible_pin Pin code to check. * @return true iff username and pin match and there have not * been more than MAX_FAILURES guesses since the last * check that was authenticated. * If pinCode is the default 0, does not authenticate but does * not count it as an error. */ public boolean isAuthenticated(String possible_user, int possible_pin) { if ( pinCode == 0 || failedAttempts >= MAX_FAILURES ) { return false; } else if ( user.equals(possible_user) && pinCode == possible_pin ) { resetFailures(); return true; } else { failedAttempts++; return false; } } /** * Reset number of failures to 0 to allow authentication. */ public void resetFailures() { failedAttempts = 0; } /** * Check if candidate would be a possible replacement PIN code using * the following rules: it cannot be the old pin, it must be greater * than 4 digits, and no digit is repeated. * @param candidate Posible new PIN code. * @return Whether or not the new pin can be used. */ public boolean isAcceptableNewPin(int candidate) { boolean ok = candidate != pinCode && candidate > 9999; String digits = "" + candidate; for(int char_to_check = 0; char_to_check < digits.length(); char_to_check++) { for(int remainder_ix = char_to_check + 1; remainder_ix < digits.length(); remainder_ix++) { if ( digits.charAt(char_to_check) == digits.charAt(remainder_ix) ) ok = false; } } return ok; } /** * Set new pin, first making sure acceptable * Abort program if not. */ public void setPin(int newPin) { if ( !isAcceptableNewPin(newPin) ) { System.err.println("Aborting: invalid new pin code"); System.exit(-1); } pinCode = newPin; } }