Commit 1cd8c4e2 authored by CONGRANLI's avatar CONGRANLI

add mutant

parent 8448ca41
Pipeline #6661 failed with stages
in 20 seconds
package swen90006.passbook;
public class AlreadyLoggedInException extends Exception
{
public AlreadyLoggedInException(String username)
{
super("Username already logged in: " + username);
}
}
package swen90006.passbook;
public class DuplicateUserException extends Exception
{
public DuplicateUserException(String username)
{
super("Username already exists: " + username);
}
}
package swen90006.passbook;
public class IncorrectPassphraseException extends Exception
{
public IncorrectPassphraseException(String username, String passphrase)
{
super("Incorrect passphrase: " + passphrase + " for user " + username);
}
}
package swen90006.passbook;
public class InvalidSessionIDException extends Exception
{
public InvalidSessionIDException(Integer sessionID)
{
super("Invalid session ID: " + sessionID);
}
}
package swen90006.passbook;
import java.net.URL;
public class NoSuchURLException extends Exception
{
public NoSuchURLException (String username, URL url)
{
super("User " + username + " does not have password for URL " + url.toString());
}
}
package swen90006.passbook;
public class NoSuchUserException extends Exception
{
public NoSuchUserException (String username)
{
super("Username does not exist: " + username);
}
}
package swen90006.passbook;
/**
* A pair of objects.
*/
public class Pair<X, Y>
{
private X first;
private Y second;
public Pair(X first, Y second)
{
this.first = first;
this.second = second;
}
public X getFirst()
{
return this.first;
}
public Y getSecond()
{
return this.second;
}
public boolean equals(Pair<X, Y> other)
{
return first.equals(other.first) && second.equals(other.second);
}
}
package swen90006.passbook;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Random;
import java.util.Arrays;
/**
* PassBook is a (fictional) online password manager. A password
* manager is a software application that generates, stores, and
* retrieves login details for users.
*
* A user has an account with PassBook. This account is protected by a
* master password, or passphrase. Each user can store login details
* for multiple websites, identified by their URL. A user can add a
* login details for a given website. The passphrase is used to
* encrypt all passwords, but for this implementation, we have ignored
* encryption.
*
* The PassBook passphrase must conform to the following requirements:
* Must be at least eight characters long and contain at
* least one digit (range 0-9), one letter in the range 'a'-'z', and
* one letter in the range 'A'-'Z'.
*
* Username and passwords for stored URLs have no password
* requirements.
*
* When a user logs into PassBook, they are given a session ID. This
* session ID is used to identify them for all transactions until they
* log out.
*/
public class PassBook
{
/** The minimum length of a passphrase */
public final static int MINIMUM_PASSPHRASE_LENGTH = 8;
/** Valid URL protocols for the passbook */
public final static String [] VALID_URL_PROTOCOLS = {"http", "https"};
//The passphrases (master passwords) for all users
private Map<String, String> passphrases;
//The login details for all users and the URLs they have stored
private Map<String, PasswordTable> details;
//Mapping from session IDs to usernames
private Map<Integer, String> userIDs;
//Mapping from usernames to sessionIDs
private Map<String, Integer> sessionIDs;
/**
* Constructs an empty passbook.
*/
public PassBook()
{
passphrases = new HashMap<String, String>();
details = new HashMap<String, PasswordTable>();
userIDs = new HashMap<Integer, String>();
sessionIDs = new HashMap<String, Integer>();
}
/**
* Adds a new user to the passbook.
*
* @param passbookUsername the username for the user to be added
* @param passphrase the passphrase (master password) for the user
* @throws DuplicateUserException if the username is already in the passbook
* @throws WeakPassphraseException if the password does not fit the passphrase
rules (see class documentation)
*
* Assumption: passbookUsername and passphrase are non-null
*/
public void addUser(String passbookUsername, String passphrase)
throws DuplicateUserException, WeakPassphraseException
{
//Check if this user exists
if (passphrases.containsKey(passbookUsername)) {
throw new DuplicateUserException(passbookUsername);
}
//check the passphrase strength
else {
if (passphrase.length() < MINIMUM_PASSPHRASE_LENGTH) {
throw new WeakPassphraseException(passphrase);
}
boolean containsLowerCase = false;
boolean containsUpperCase = false;
boolean containsNumber = false;
for (int i = 0; i < passphrase.length(); i++) {
if ('a' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'z') {
containsLowerCase = true;
}
else if ('A' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'Z') {
containsUpperCase = true;
}
else if ('0' <= passphrase.charAt(i) && passphrase.charAt(i) <= '9') {
containsNumber = true;
}
}
if (!containsLowerCase || !containsUpperCase || !containsNumber) {
throw new WeakPassphraseException(passphrase);
}
}
passphrases.put(passbookUsername, passphrase);
PasswordTable pt = new PasswordTable();
details.put(passbookUsername, pt);
}
/**
* Checks if a user exists
* @param passbookUsername the passbookUsername
* @return true if and only if this user is in the passbook
*
* Assumption: passbookUsername is non-null
*/
public boolean isUser(String passbookUsername)
{
return passphrases.containsKey(passbookUsername);
}
/**
* Logs a user into the passbook.
*
* @param passbookUsername the passbookUsername for the user
* @param passphrase the passphrase (master password) for the user
* @returns a session ID greater than or equal to 0
* @throws NoSuchUserException if the user does not exist in the passbook
* @throws AlreadyLoggedInException if the user is already logged in
* @throws IncorrectPassphraseException if the passphrase is incorrect for this user
*
* Assumption: passbookUsername and passphrase are non-null
*/
public int loginUser(String passbookUsername, String passphrase)
throws NoSuchUserException, AlreadyLoggedInException, IncorrectPassphraseException
{
//check that the user exists
if (!passphrases.containsKey(passbookUsername)) {
throw new NoSuchUserException(passbookUsername);
}
else if (sessionIDs.get(passbookUsername) != null) {
throw new AlreadyLoggedInException(passbookUsername);
}
else if (!passphrases.get(passbookUsername).equals(passphrase)) {
throw new IncorrectPassphraseException(passbookUsername, passphrase);
}
//generate a random session ID that is not already taken
int sessionID = new Random().nextInt(Integer.MAX_VALUE);
while (userIDs.containsKey(sessionID)) {
sessionID = new Random().nextInt(Integer.MAX_VALUE);
}
//add the session ID
sessionIDs.put(passbookUsername, sessionID);
userIDs.put(sessionID, passbookUsername);
return sessionID;
}
/**
* Logs out a user based on session ID. Has no affect if the session ID does not exist.
*
* @param sessionID the session ID to be terminated
*
* Assumption: session ID is non-null
*/
public void logoutUser(Integer sessionID)
{
sessionIDs.remove(userIDs.get(sessionID));
userIDs.remove(sessionID);
}
/**
* Updates the login details for a URL of a user. If the url
* username or password are null, the login details for this URL
* must be removed.
*
* @param sessionID the session ID for the logged-in user
* @param urlUsername the username for the user to be added
* @param url the URL for the username/password pair
* @param urlPassword the password to be add
* @throws InvalidSessionIDException if the session ID does not exists
* @throws MalformedURLException if the protocol is not 'http' or 'https'
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public void updateDetails(Integer sessionID, URL url, String urlUsername, String urlPassword)
throws InvalidSessionIDException, MalformedURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
if (urlUsername == null || urlPassword == null) {
pt.remove(url);
}
else {
pt.put(url, new Pair<String, String> (urlUsername, urlPassword));
details.put(passbookUsername, pt);
}
}
/**
* Retrieves login details for a given URL and user.
*
* @param sessionID the session ID
* @param url the URL for the password being retrieved.
* @returns the username and password for a given url for the corresponding user
* @throws NoSuchUserException if the username does not exist in the passbook
* @throws MalformedURLException if the syntax is invalid (see class documentation)
* @throws NoSuchURLException if user does not have login for this URL
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public Pair<String, String> retrieveDetails(Integer sessionID, URL url)
throws InvalidSessionIDException, MalformedURLException, NoSuchURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
//if this returned nothing, the user has no details for any url
if (pt == null) {
throw new NoSuchURLException(passbookUsername, url);
}
Pair<String, String> pair = pt.get(url);
//if this returned nothing, the user does not have a login for this url
if (pair == null) {
throw new NoSuchURLException(passbookUsername, url);
}
return pair;
}
//A simple label to improve code readability
private class PasswordTable extends HashMap<URL, Pair<String, String>> {}
}
package swen90006.passbook;
public class WeakPassphraseException extends Exception
{
public WeakPassphraseException (String passphrase)
{
super("Passphrase does not comply with the PassBook rules\n" +
"\t- must contains at least " +
PassBook.MINIMUM_PASSPHRASE_LENGTH + " characters\n" +
"\t- must contain at least one numeric character\n" +
"\t- must contain at least one lower case letter\n" +
"\t- must contain at least one upper case letter\n");
}
}
package swen90006.passbook;
public class AlreadyLoggedInException extends Exception
{
public AlreadyLoggedInException(String username)
{
super("Username already logged in: " + username);
}
}
package swen90006.passbook;
public class DuplicateUserException extends Exception
{
public DuplicateUserException(String username)
{
super("Username already exists: " + username);
}
}
package swen90006.passbook;
public class IncorrectPassphraseException extends Exception
{
public IncorrectPassphraseException(String username, String passphrase)
{
super("Incorrect passphrase: " + passphrase + " for user " + username);
}
}
package swen90006.passbook;
public class InvalidSessionIDException extends Exception
{
public InvalidSessionIDException(Integer sessionID)
{
super("Invalid session ID: " + sessionID);
}
}
package swen90006.passbook;
import java.net.URL;
public class NoSuchURLException extends Exception
{
public NoSuchURLException (String username, URL url)
{
super("User " + username + " does not have password for URL " + url.toString());
}
}
package swen90006.passbook;
public class NoSuchUserException extends Exception
{
public NoSuchUserException (String username)
{
super("Username does not exist: " + username);
}
}
package swen90006.passbook;
/**
* A pair of objects.
*/
public class Pair<X, Y>
{
private X first;
private Y second;
public Pair(X first, Y second)
{
this.first = first;
this.second = second;
}
public X getFirst()
{
return this.first;
}
public Y getSecond()
{
return this.second;
}
public boolean equals(Pair<X, Y> other)
{
return first.equals(other.first) && second.equals(other.second);
}
}
package swen90006.passbook;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Random;
import java.util.Arrays;
/**
* PassBook is a (fictional) online password manager. A password
* manager is a software application that generates, stores, and
* retrieves login details for users.
*
* A user has an account with PassBook. This account is protected by a
* master password, or passphrase. Each user can store login details
* for multiple websites, identified by their URL. A user can add a
* login details for a given website. The passphrase is used to
* encrypt all passwords, but for this implementation, we have ignored
* encryption.
*
* The PassBook passphrase must conform to the following requirements:
* Must be at least eight characters long and contain at
* least one digit (range 0-9), one letter in the range 'a'-'z', and
* one letter in the range 'A'-'Z'.
*
* Username and passwords for stored URLs have no password
* requirements.
*
* When a user logs into PassBook, they are given a session ID. This
* session ID is used to identify them for all transactions until they
* log out.
*/
public class PassBook
{
/** The minimum length of a passphrase */
public final static int MINIMUM_PASSPHRASE_LENGTH = 8;
/** Valid URL protocols for the passbook */
public final static String [] VALID_URL_PROTOCOLS = {"http", "https"};
//The passphrases (master passwords) for all users
private Map<String, String> passphrases;
//The login details for all users and the URLs they have stored
private Map<String, PasswordTable> details;
//Mapping from session IDs to usernames
private Map<Integer, String> userIDs;
//Mapping from usernames to sessionIDs
private Map<String, Integer> sessionIDs;
/**
* Constructs an empty passbook.
*/
public PassBook()
{
passphrases = new HashMap<String, String>();
details = new HashMap<String, PasswordTable>();
userIDs = new HashMap<Integer, String>();
sessionIDs = new HashMap<String, Integer>();
}
/**
* Adds a new user to the passbook.
*
* @param passbookUsername the username for the user to be added
* @param passphrase the passphrase (master password) for the user
* @throws DuplicateUserException if the username is already in the passbook
* @throws WeakPassphraseException if the password does not fit the passphrase
rules (see class documentation)
*
* Assumption: passbookUsername and passphrase are non-null
*/
public void addUser(String passbookUsername, String passphrase)
throws DuplicateUserException, WeakPassphraseException
{
//Check if this user exists
if (passphrases.containsKey(passbookUsername)) {
throw new DuplicateUserException(passbookUsername);
}
//check the passphrase strength
else {
if (passphrase.length() < MINIMUM_PASSPHRASE_LENGTH) {
throw new WeakPassphraseException(passphrase);
}
boolean containsLowerCase = false;
boolean containsUpperCase = false;
boolean containsNumber = false;
for (int i = 0; i < passphrase.length(); i++) {
if ('a' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'z') {
containsLowerCase = true;
}
else if ('A' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'Z') {
containsUpperCase = true;
}
else if ('0' <= passphrase.charAt(i) && passphrase.charAt(i) <= '9') {
containsNumber = true;
}
}
if (!containsLowerCase || !containsUpperCase || !containsNumber) {
throw new WeakPassphraseException(passphrase);
}
}
passphrases.put(passbookUsername, passphrase);
PasswordTable pt = new PasswordTable();
details.put(passbookUsername, pt);
}
/**
* Checks if a user exists
* @param passbookUsername the passbookUsername
* @return true if and only if this user is in the passbook
*
* Assumption: passbookUsername is non-null
*/
public boolean isUser(String passbookUsername)
{
return passphrases.containsKey(passbookUsername);
}
/**
* Logs a user into the passbook.
*
* @param passbookUsername the passbookUsername for the user
* @param passphrase the passphrase (master password) for the user
* @returns a session ID greater than or equal to 0
* @throws NoSuchUserException if the user does not exist in the passbook
* @throws AlreadyLoggedInException if the user is already logged in
* @throws IncorrectPassphraseException if the passphrase is incorrect for this user
*
* Assumption: passbookUsername and passphrase are non-null
*/
public int loginUser(String passbookUsername, String passphrase)
throws NoSuchUserException, AlreadyLoggedInException, IncorrectPassphraseException
{
//check that the user exists
if (!passphrases.containsKey(passbookUsername)) {
throw new NoSuchUserException(passbookUsername);
}
else if (sessionIDs.get(passbookUsername) != null) {
throw new AlreadyLoggedInException(passbookUsername);
}
else if (!passphrases.get(passbookUsername).equals(passphrase)) {
throw new IncorrectPassphraseException(passbookUsername, passphrase);
}
//generate a random session ID that is not already taken
int sessionID = new Random().nextInt(Integer.MAX_VALUE);
while (userIDs.containsKey(sessionID)) {
sessionID = new Random().nextInt(Integer.MAX_VALUE);
}
//add the session ID
sessionIDs.put(passbookUsername, sessionID);
userIDs.put(sessionID, passbookUsername);
return sessionID;
}
/**
* Logs out a user based on session ID. Has no affect if the session ID does not exist.
*
* @param sessionID the session ID to be terminated
*
* Assumption: session ID is non-null
*/
public void logoutUser(Integer sessionID)
{
sessionIDs.remove(userIDs.get(sessionID));
userIDs.remove(sessionID);
}
/**
* Updates the login details for a URL of a user. If the url
* username or password are null, the login details for this URL
* must be removed.
*
* @param sessionID the session ID for the logged-in user
* @param urlUsername the username for the user to be added
* @param url the URL for the username/password pair
* @param urlPassword the password to be add
* @throws InvalidSessionIDException if the session ID does not exists
* @throws MalformedURLException if the protocol is not 'http' or 'https'
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public void updateDetails(Integer sessionID, URL url, String urlUsername, String urlPassword)
throws InvalidSessionIDException, MalformedURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
if (urlUsername == null || urlPassword == null) {
pt.remove(url);
}
else {
pt.put(url, new Pair<String, String> (urlUsername, urlPassword));
details.put(passbookUsername, pt);
}
}
/**
* Retrieves login details for a given URL and user.
*
* @param sessionID the session ID
* @param url the URL for the password being retrieved.
* @returns the username and password for a given url for the corresponding user
* @throws NoSuchUserException if the username does not exist in the passbook
* @throws MalformedURLException if the syntax is invalid (see class documentation)
* @throws NoSuchURLException if user does not have login for this URL
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public Pair<String, String> retrieveDetails(Integer sessionID, URL url)
throws InvalidSessionIDException, MalformedURLException, NoSuchURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
//if this returned nothing, the user has no details for any url
if (pt == null) {
throw new NoSuchURLException(passbookUsername, url);
}
Pair<String, String> pair = pt.get(url);
//if this returned nothing, the user does not have a login for this url
if (pair == null) {
throw new NoSuchURLException(passbookUsername, url);
}
return pair;
}
//A simple label to improve code readability
private class PasswordTable extends HashMap<URL, Pair<String, String>> {}
}
package swen90006.passbook;
public class WeakPassphraseException extends Exception
{
public WeakPassphraseException (String passphrase)
{
super("Passphrase does not comply with the PassBook rules\n" +
"\t- must contains at least " +
PassBook.MINIMUM_PASSPHRASE_LENGTH + " characters\n" +
"\t- must contain at least one numeric character\n" +
"\t- must contain at least one lower case letter\n" +
"\t- must contain at least one upper case letter\n");
}
}
package swen90006.passbook;
public class AlreadyLoggedInException extends Exception
{
public AlreadyLoggedInException(String username)
{
super("Username already logged in: " + username);
}
}
package swen90006.passbook;
public class DuplicateUserException extends Exception
{
public DuplicateUserException(String username)
{
super("Username already exists: " + username);
}
}
package swen90006.passbook;
public class IncorrectPassphraseException extends Exception
{
public IncorrectPassphraseException(String username, String passphrase)
{
super("Incorrect passphrase: " + passphrase + " for user " + username);
}
}
package swen90006.passbook;
public class InvalidSessionIDException extends Exception
{
public InvalidSessionIDException(Integer sessionID)
{
super("Invalid session ID: " + sessionID);
}
}
package swen90006.passbook;
import java.net.URL;
public class NoSuchURLException extends Exception
{
public NoSuchURLException (String username, URL url)
{
super("User " + username + " does not have password for URL " + url.toString());
}
}
package swen90006.passbook;
public class NoSuchUserException extends Exception
{
public NoSuchUserException (String username)
{
super("Username does not exist: " + username);
}
}
package swen90006.passbook;
/**
* A pair of objects.
*/
public class Pair<X, Y>
{
private X first;
private Y second;
public Pair(X first, Y second)
{
this.first = first;
this.second = second;
}
public X getFirst()
{
return this.first;
}
public Y getSecond()
{
return this.second;
}
public boolean equals(Pair<X, Y> other)
{
return first.equals(other.first) && second.equals(other.second);
}
}
package swen90006.passbook;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Random;
import java.util.Arrays;
/**
* PassBook is a (fictional) online password manager. A password
* manager is a software application that generates, stores, and
* retrieves login details for users.
*
* A user has an account with PassBook. This account is protected by a
* master password, or passphrase. Each user can store login details
* for multiple websites, identified by their URL. A user can add a
* login details for a given website. The passphrase is used to
* encrypt all passwords, but for this implementation, we have ignored
* encryption.
*
* The PassBook passphrase must conform to the following requirements:
* Must be at least eight characters long and contain at
* least one digit (range 0-9), one letter in the range 'a'-'z', and
* one letter in the range 'A'-'Z'.
*
* Username and passwords for stored URLs have no password
* requirements.
*
* When a user logs into PassBook, they are given a session ID. This
* session ID is used to identify them for all transactions until they
* log out.
*/
public class PassBook
{
/** The minimum length of a passphrase */
public final static int MINIMUM_PASSPHRASE_LENGTH = 8;
/** Valid URL protocols for the passbook */
public final static String [] VALID_URL_PROTOCOLS = {"http", "https"};
//The passphrases (master passwords) for all users
private Map<String, String> passphrases;
//The login details for all users and the URLs they have stored
private Map<String, PasswordTable> details;
//Mapping from session IDs to usernames
private Map<Integer, String> userIDs;
//Mapping from usernames to sessionIDs
private Map<String, Integer> sessionIDs;
/**
* Constructs an empty passbook.
*/
public PassBook()
{
passphrases = new HashMap<String, String>();
details = new HashMap<String, PasswordTable>();
userIDs = new HashMap<Integer, String>();
sessionIDs = new HashMap<String, Integer>();
}
/**
* Adds a new user to the passbook.
*
* @param passbookUsername the username for the user to be added
* @param passphrase the passphrase (master password) for the user
* @throws DuplicateUserException if the username is already in the passbook
* @throws WeakPassphraseException if the password does not fit the passphrase
rules (see class documentation)
*
* Assumption: passbookUsername and passphrase are non-null
*/
public void addUser(String passbookUsername, String passphrase)
throws DuplicateUserException, WeakPassphraseException
{
//Check if this user exists
if (passphrases.containsKey(passbookUsername)) {
throw new DuplicateUserException(passbookUsername);
}
//check the passphrase strength
else {
if (passphrase.length() < MINIMUM_PASSPHRASE_LENGTH) {
throw new WeakPassphraseException(passphrase);
}
boolean containsLowerCase = false;
boolean containsUpperCase = false;
boolean containsNumber = false;
for (int i = 0; i < passphrase.length(); i++) {
if ('a' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'z') {
containsLowerCase = true;
}
else if ('A' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'Z') {
containsUpperCase = true;
}
else if ('0' <= passphrase.charAt(i) && passphrase.charAt(i) <= '9') {
containsNumber = true;
}
}
if (!containsLowerCase || !containsUpperCase || !containsNumber) {
throw new WeakPassphraseException(passphrase);
}
}
passphrases.put(passbookUsername, passphrase);
PasswordTable pt = new PasswordTable();
details.put(passbookUsername, pt);
}
/**
* Checks if a user exists
* @param passbookUsername the passbookUsername
* @return true if and only if this user is in the passbook
*
* Assumption: passbookUsername is non-null
*/
public boolean isUser(String passbookUsername)
{
return passphrases.containsKey(passbookUsername);
}
/**
* Logs a user into the passbook.
*
* @param passbookUsername the passbookUsername for the user
* @param passphrase the passphrase (master password) for the user
* @returns a session ID greater than or equal to 0
* @throws NoSuchUserException if the user does not exist in the passbook
* @throws AlreadyLoggedInException if the user is already logged in
* @throws IncorrectPassphraseException if the passphrase is incorrect for this user
*
* Assumption: passbookUsername and passphrase are non-null
*/
public int loginUser(String passbookUsername, String passphrase)
throws NoSuchUserException, AlreadyLoggedInException, IncorrectPassphraseException
{
//check that the user exists
if (!passphrases.containsKey(passbookUsername)) {
throw new NoSuchUserException(passbookUsername);
}
else if (sessionIDs.get(passbookUsername) != null) {
throw new AlreadyLoggedInException(passbookUsername);
}
else if (!passphrases.get(passbookUsername).equals(passphrase)) {
throw new IncorrectPassphraseException(passbookUsername, passphrase);
}
//generate a random session ID that is not already taken
int sessionID = new Random().nextInt(Integer.MAX_VALUE);
while (userIDs.containsKey(sessionID)) {
sessionID = new Random().nextInt(Integer.MAX_VALUE);
}
//add the session ID
sessionIDs.put(passbookUsername, sessionID);
userIDs.put(sessionID, passbookUsername);
return sessionID;
}
/**
* Logs out a user based on session ID. Has no affect if the session ID does not exist.
*
* @param sessionID the session ID to be terminated
*
* Assumption: session ID is non-null
*/
public void logoutUser(Integer sessionID)
{
sessionIDs.remove(userIDs.get(sessionID));
userIDs.remove(sessionID);
}
/**
* Updates the login details for a URL of a user. If the url
* username or password are null, the login details for this URL
* must be removed.
*
* @param sessionID the session ID for the logged-in user
* @param urlUsername the username for the user to be added
* @param url the URL for the username/password pair
* @param urlPassword the password to be add
* @throws InvalidSessionIDException if the session ID does not exists
* @throws MalformedURLException if the protocol is not 'http' or 'https'
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public void updateDetails(Integer sessionID, URL url, String urlUsername, String urlPassword)
throws InvalidSessionIDException, MalformedURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
if (urlUsername == null || urlPassword == null) {
pt.remove(url);
}
else {
pt.put(url, new Pair<String, String> (urlUsername, urlPassword));
details.put(passbookUsername, pt);
}
}
/**
* Retrieves login details for a given URL and user.
*
* @param sessionID the session ID
* @param url the URL for the password being retrieved.
* @returns the username and password for a given url for the corresponding user
* @throws NoSuchUserException if the username does not exist in the passbook
* @throws MalformedURLException if the syntax is invalid (see class documentation)
* @throws NoSuchURLException if user does not have login for this URL
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public Pair<String, String> retrieveDetails(Integer sessionID, URL url)
throws InvalidSessionIDException, MalformedURLException, NoSuchURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
//if this returned nothing, the user has no details for any url
if (pt == null) {
throw new NoSuchURLException(passbookUsername, url);
}
Pair<String, String> pair = pt.get(url);
//if this returned nothing, the user does not have a login for this url
if (pair == null) {
throw new NoSuchURLException(passbookUsername, url);
}
return pair;
}
//A simple label to improve code readability
private class PasswordTable extends HashMap<URL, Pair<String, String>> {}
}
package swen90006.passbook;
public class WeakPassphraseException extends Exception
{
public WeakPassphraseException (String passphrase)
{
super("Passphrase does not comply with the PassBook rules\n" +
"\t- must contains at least " +
PassBook.MINIMUM_PASSPHRASE_LENGTH + " characters\n" +
"\t- must contain at least one numeric character\n" +
"\t- must contain at least one lower case letter\n" +
"\t- must contain at least one upper case letter\n");
}
}
package swen90006.passbook;
public class AlreadyLoggedInException extends Exception
{
public AlreadyLoggedInException(String username)
{
super("Username already logged in: " + username);
}
}
package swen90006.passbook;
public class DuplicateUserException extends Exception
{
public DuplicateUserException(String username)
{
super("Username already exists: " + username);
}
}
package swen90006.passbook;
public class IncorrectPassphraseException extends Exception
{
public IncorrectPassphraseException(String username, String passphrase)
{
super("Incorrect passphrase: " + passphrase + " for user " + username);
}
}
package swen90006.passbook;
public class InvalidSessionIDException extends Exception
{
public InvalidSessionIDException(Integer sessionID)
{
super("Invalid session ID: " + sessionID);
}
}
package swen90006.passbook;
import java.net.URL;
public class NoSuchURLException extends Exception
{
public NoSuchURLException (String username, URL url)
{
super("User " + username + " does not have password for URL " + url.toString());
}
}
package swen90006.passbook;
public class NoSuchUserException extends Exception
{
public NoSuchUserException (String username)
{
super("Username does not exist: " + username);
}
}
package swen90006.passbook;
/**
* A pair of objects.
*/
public class Pair<X, Y>
{
private X first;
private Y second;
public Pair(X first, Y second)
{
this.first = first;
this.second = second;
}
public X getFirst()
{
return this.first;
}
public Y getSecond()
{
return this.second;
}
public boolean equals(Pair<X, Y> other)
{
return first.equals(other.first) && second.equals(other.second);
}
}
package swen90006.passbook;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Random;
import java.util.Arrays;
/**
* PassBook is a (fictional) online password manager. A password
* manager is a software application that generates, stores, and
* retrieves login details for users.
*
* A user has an account with PassBook. This account is protected by a
* master password, or passphrase. Each user can store login details
* for multiple websites, identified by their URL. A user can add a
* login details for a given website. The passphrase is used to
* encrypt all passwords, but for this implementation, we have ignored
* encryption.
*
* The PassBook passphrase must conform to the following requirements:
* Must be at least eight characters long and contain at
* least one digit (range 0-9), one letter in the range 'a'-'z', and
* one letter in the range 'A'-'Z'.
*
* Username and passwords for stored URLs have no password
* requirements.
*
* When a user logs into PassBook, they are given a session ID. This
* session ID is used to identify them for all transactions until they
* log out.
*/
public class PassBook
{
/** The minimum length of a passphrase */
public final static int MINIMUM_PASSPHRASE_LENGTH = 8;
/** Valid URL protocols for the passbook */
public final static String [] VALID_URL_PROTOCOLS = {"http", "https"};
//The passphrases (master passwords) for all users
private Map<String, String> passphrases;
//The login details for all users and the URLs they have stored
private Map<String, PasswordTable> details;
//Mapping from session IDs to usernames
private Map<Integer, String> userIDs;
//Mapping from usernames to sessionIDs
private Map<String, Integer> sessionIDs;
/**
* Constructs an empty passbook.
*/
public PassBook()
{
passphrases = new HashMap<String, String>();
details = new HashMap<String, PasswordTable>();
userIDs = new HashMap<Integer, String>();
sessionIDs = new HashMap<String, Integer>();
}
/**
* Adds a new user to the passbook.
*
* @param passbookUsername the username for the user to be added
* @param passphrase the passphrase (master password) for the user
* @throws DuplicateUserException if the username is already in the passbook
* @throws WeakPassphraseException if the password does not fit the passphrase
rules (see class documentation)
*
* Assumption: passbookUsername and passphrase are non-null
*/
public void addUser(String passbookUsername, String passphrase)
throws DuplicateUserException, WeakPassphraseException
{
//Check if this user exists
if (passphrases.containsKey(passbookUsername)) {
throw new DuplicateUserException(passbookUsername);
}
//check the passphrase strength
else {
if (passphrase.length() < MINIMUM_PASSPHRASE_LENGTH) {
throw new WeakPassphraseException(passphrase);
}
boolean containsLowerCase = false;
boolean containsUpperCase = false;
boolean containsNumber = false;
for (int i = 0; i < passphrase.length(); i++) {
if ('a' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'z') {
containsLowerCase = true;
}
else if ('A' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'Z') {
containsUpperCase = true;
}
else if ('/' <= passphrase.charAt(i) && passphrase.charAt(i) <= '9') {
containsNumber = true;
}
}
if (!containsLowerCase || !containsUpperCase || !containsNumber) {
throw new WeakPassphraseException(passphrase);
}
}
passphrases.put(passbookUsername, passphrase);
PasswordTable pt = new PasswordTable();
details.put(passbookUsername, pt);
}
/**
* Checks if a user exists
* @param passbookUsername the passbookUsername
* @return true if and only if this user is in the passbook
*
* Assumption: passbookUsername is non-null
*/
public boolean isUser(String passbookUsername)
{
return passphrases.containsKey(passbookUsername);
}
/**
* Logs a user into the passbook.
*
* @param passbookUsername the passbookUsername for the user
* @param passphrase the passphrase (master password) for the user
* @returns a session ID greater than or equal to 0
* @throws NoSuchUserException if the user does not exist in the passbook
* @throws AlreadyLoggedInException if the user is already logged in
* @throws IncorrectPassphraseException if the passphrase is incorrect for this user
*
* Assumption: passbookUsername and passphrase are non-null
*/
public int loginUser(String passbookUsername, String passphrase)
throws NoSuchUserException, AlreadyLoggedInException, IncorrectPassphraseException
{
//check that the user exists
if (!passphrases.containsKey(passbookUsername)) {
throw new NoSuchUserException(passbookUsername);
}
else if (sessionIDs.get(passbookUsername) != null) {
throw new AlreadyLoggedInException(passbookUsername);
}
else if (!passphrases.get(passbookUsername).equals(passphrase)) {
throw new IncorrectPassphraseException(passbookUsername, passphrase);
}
//generate a random session ID that is not already taken
int sessionID = new Random().nextInt(Integer.MAX_VALUE);
while (userIDs.containsKey(sessionID)) {
sessionID = new Random().nextInt(Integer.MAX_VALUE);
}
//add the session ID
sessionIDs.put(passbookUsername, sessionID);
userIDs.put(sessionID, passbookUsername);
return sessionID;
}
/**
* Logs out a user based on session ID. Has no affect if the session ID does not exist.
*
* @param sessionID the session ID to be terminated
*
* Assumption: session ID is non-null
*/
public void logoutUser(Integer sessionID)
{
sessionIDs.remove(userIDs.get(sessionID));
userIDs.remove(sessionID);
}
/**
* Updates the login details for a URL of a user. If the url
* username or password are null, the login details for this URL
* must be removed.
*
* @param sessionID the session ID for the logged-in user
* @param urlUsername the username for the user to be added
* @param url the URL for the username/password pair
* @param urlPassword the password to be add
* @throws InvalidSessionIDException if the session ID does not exists
* @throws MalformedURLException if the protocol is not 'http' or 'https'
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public void updateDetails(Integer sessionID, URL url, String urlUsername, String urlPassword)
throws InvalidSessionIDException, MalformedURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
if (urlUsername == null || urlPassword == null) {
pt.remove(url);
}
else {
pt.put(url, new Pair<String, String> (urlUsername, urlPassword));
details.put(passbookUsername, pt);
}
}
/**
* Retrieves login details for a given URL and user.
*
* @param sessionID the session ID
* @param url the URL for the password being retrieved.
* @returns the username and password for a given url for the corresponding user
* @throws NoSuchUserException if the username does not exist in the passbook
* @throws MalformedURLException if the syntax is invalid (see class documentation)
* @throws NoSuchURLException if user does not have login for this URL
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public Pair<String, String> retrieveDetails(Integer sessionID, URL url)
throws InvalidSessionIDException, MalformedURLException, NoSuchURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
//if this returned nothing, the user has no details for any url
if (pt == null) {
throw new NoSuchURLException(passbookUsername, url);
}
Pair<String, String> pair = pt.get(url);
//if this returned nothing, the user does not have a login for this url
if (pair == null) {
throw new NoSuchURLException(passbookUsername, url);
}
return pair;
}
//A simple label to improve code readability
private class PasswordTable extends HashMap<URL, Pair<String, String>> {}
}
package swen90006.passbook;
public class WeakPassphraseException extends Exception
{
public WeakPassphraseException (String passphrase)
{
super("Passphrase does not comply with the PassBook rules\n" +
"\t- must contains at least " +
PassBook.MINIMUM_PASSPHRASE_LENGTH + " characters\n" +
"\t- must contain at least one numeric character\n" +
"\t- must contain at least one lower case letter\n" +
"\t- must contain at least one upper case letter\n");
}
}
package swen90006.passbook;
public class AlreadyLoggedInException extends Exception
{
public AlreadyLoggedInException(String username)
{
super("Username already logged in: " + username);
}
}
package swen90006.passbook;
public class DuplicateUserException extends Exception
{
public DuplicateUserException(String username)
{
super("Username already exists: " + username);
}
}
package swen90006.passbook;
public class IncorrectPassphraseException extends Exception
{
public IncorrectPassphraseException(String username, String passphrase)
{
super("Incorrect passphrase: " + passphrase + " for user " + username);
}
}
package swen90006.passbook;
public class InvalidSessionIDException extends Exception
{
public InvalidSessionIDException(Integer sessionID)
{
super("Invalid session ID: " + sessionID);
}
}
package swen90006.passbook;
import java.net.URL;
public class NoSuchURLException extends Exception
{
public NoSuchURLException (String username, URL url)
{
super("User " + username + " does not have password for URL " + url.toString());
}
}
package swen90006.passbook;
public class NoSuchUserException extends Exception
{
public NoSuchUserException (String username)
{
super("Username does not exist: " + username);
}
}
package swen90006.passbook;
/**
* A pair of objects.
*/
public class Pair<X, Y>
{
private X first;
private Y second;
public Pair(X first, Y second)
{
this.first = first;
this.second = second;
}
public X getFirst()
{
return this.first;
}
public Y getSecond()
{
return this.second;
}
public boolean equals(Pair<X, Y> other)
{
return first.equals(other.first) && second.equals(other.second);
}
}
package swen90006.passbook;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Random;
import java.util.Arrays;
/**
* PassBook is a (fictional) online password manager. A password
* manager is a software application that generates, stores, and
* retrieves login details for users.
*
* A user has an account with PassBook. This account is protected by a
* master password, or passphrase. Each user can store login details
* for multiple websites, identified by their URL. A user can add a
* login details for a given website. The passphrase is used to
* encrypt all passwords, but for this implementation, we have ignored
* encryption.
*
* The PassBook passphrase must conform to the following requirements:
* Must be at least eight characters long and contain at
* least one digit (range 0-9), one letter in the range 'a'-'z', and
* one letter in the range 'A'-'Z'.
*
* Username and passwords for stored URLs have no password
* requirements.
*
* When a user logs into PassBook, they are given a session ID. This
* session ID is used to identify them for all transactions until they
* log out.
*/
public class PassBook
{
/** The minimum length of a passphrase */
public final static int MINIMUM_PASSPHRASE_LENGTH = 8;
/** Valid URL protocols for the passbook */
public final static String [] VALID_URL_PROTOCOLS = {"http", "https"};
//The passphrases (master passwords) for all users
private Map<String, String> passphrases;
//The login details for all users and the URLs they have stored
private Map<String, PasswordTable> details;
//Mapping from session IDs to usernames
private Map<Integer, String> userIDs;
//Mapping from usernames to sessionIDs
private Map<String, Integer> sessionIDs;
/**
* Constructs an empty passbook.
*/
public PassBook()
{
passphrases = new HashMap<String, String>();
details = new HashMap<String, PasswordTable>();
userIDs = new HashMap<Integer, String>();
sessionIDs = new HashMap<String, Integer>();
}
/**
* Adds a new user to the passbook.
*
* @param passbookUsername the username for the user to be added
* @param passphrase the passphrase (master password) for the user
* @throws DuplicateUserException if the username is already in the passbook
* @throws WeakPassphraseException if the password does not fit the passphrase
rules (see class documentation)
*
* Assumption: passbookUsername and passphrase are non-null
*/
public void addUser(String passbookUsername, String passphrase)
throws DuplicateUserException, WeakPassphraseException
{
//Check if this user exists
if (passphrases.containsKey(passbookUsername)) {
throw new DuplicateUserException(passbookUsername);
}
//check the passphrase strength
else {
if (passphrase.length() < MINIMUM_PASSPHRASE_LENGTH) {
throw new WeakPassphraseException(passphrase);
}
boolean containsLowerCase = false;
boolean containsUpperCase = false;
boolean containsNumber = false;
for (int i = 0; i < passphrase.length(); i++) {
if ('a' <= passphrase.charAt(i) || passphrase.charAt(i) <= 'z') {
containsLowerCase = true;
}
else if ('A' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'Z') {
containsUpperCase = true;
}
else if ('0' <= passphrase.charAt(i) && passphrase.charAt(i) <= '9') {
containsNumber = true;
}
}
if (!containsLowerCase || !containsUpperCase || !containsNumber) {
throw new WeakPassphraseException(passphrase);
}
}
passphrases.put(passbookUsername, passphrase);
PasswordTable pt = new PasswordTable();
details.put(passbookUsername, pt);
}
/**
* Checks if a user exists
* @param passbookUsername the passbookUsername
* @return true if and only if this user is in the passbook
*
* Assumption: passbookUsername is non-null
*/
public boolean isUser(String passbookUsername)
{
return passphrases.containsKey(passbookUsername);
}
/**
* Logs a user into the passbook.
*
* @param passbookUsername the passbookUsername for the user
* @param passphrase the passphrase (master password) for the user
* @returns a session ID greater than or equal to 0
* @throws NoSuchUserException if the user does not exist in the passbook
* @throws AlreadyLoggedInException if the user is already logged in
* @throws IncorrectPassphraseException if the passphrase is incorrect for this user
*
* Assumption: passbookUsername and passphrase are non-null
*/
public int loginUser(String passbookUsername, String passphrase)
throws NoSuchUserException, AlreadyLoggedInException, IncorrectPassphraseException
{
//check that the user exists
if (!passphrases.containsKey(passbookUsername)) {
throw new NoSuchUserException(passbookUsername);
}
else if (sessionIDs.get(passbookUsername) != null) {
throw new AlreadyLoggedInException(passbookUsername);
}
else if (!passphrases.get(passbookUsername).equals(passphrase)) {
throw new IncorrectPassphraseException(passbookUsername, passphrase);
}
//generate a random session ID that is not already taken
int sessionID = new Random().nextInt(Integer.MAX_VALUE);
while (userIDs.containsKey(sessionID)) {
sessionID = new Random().nextInt(Integer.MAX_VALUE);
}
//add the session ID
sessionIDs.put(passbookUsername, sessionID);
userIDs.put(sessionID, passbookUsername);
return sessionID;
}
/**
* Logs out a user based on session ID. Has no affect if the session ID does not exist.
*
* @param sessionID the session ID to be terminated
*
* Assumption: session ID is non-null
*/
public void logoutUser(Integer sessionID)
{
sessionIDs.remove(userIDs.get(sessionID));
userIDs.remove(sessionID);
}
/**
* Updates the login details for a URL of a user. If the url
* username or password are null, the login details for this URL
* must be removed.
*
* @param sessionID the session ID for the logged-in user
* @param urlUsername the username for the user to be added
* @param url the URL for the username/password pair
* @param urlPassword the password to be add
* @throws InvalidSessionIDException if the session ID does not exists
* @throws MalformedURLException if the protocol is not 'http' or 'https'
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public void updateDetails(Integer sessionID, URL url, String urlUsername, String urlPassword)
throws InvalidSessionIDException, MalformedURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
if (urlUsername == null && urlPassword == null) {
pt.remove(url);
}
else {
pt.put(url, new Pair<String, String> (urlUsername, urlPassword));
details.put(passbookUsername, pt);
}
}
/**
* Retrieves login details for a given URL and user.
*
* @param sessionID the session ID
* @param url the URL for the password being retrieved.
* @returns the username and password for a given url for the corresponding user
* @throws NoSuchUserException if the username does not exist in the passbook
* @throws MalformedURLException if the syntax is invalid (see class documentation)
* @throws NoSuchURLException if user does not have login for this URL
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public Pair<String, String> retrieveDetails(Integer sessionID, URL url)
throws InvalidSessionIDException, MalformedURLException, NoSuchURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
//if this returned nothing, the user has no details for any url
if (pt == null) {
throw new NoSuchURLException(passbookUsername, url);
}
Pair<String, String> pair = pt.get(url);
//if this returned nothing, the user does not have a login for this url
if (pair == null) {
throw new NoSuchURLException(passbookUsername, url);
}
return pair;
}
//A simple label to improve code readability
private class PasswordTable extends HashMap<URL, Pair<String, String>> {}
}
package swen90006.passbook;
public class WeakPassphraseException extends Exception
{
public WeakPassphraseException (String passphrase)
{
super("Passphrase does not comply with the PassBook rules\n" +
"\t- must contains at least " +
PassBook.MINIMUM_PASSPHRASE_LENGTH + " characters\n" +
"\t- must contain at least one numeric character\n" +
"\t- must contain at least one lower case letter\n" +
"\t- must contain at least one upper case letter\n");
}
}
package swen90006.passbook;
public class AlreadyLoggedInException extends Exception
{
public AlreadyLoggedInException(String username)
{
super("Username already logged in: " + username);
}
}
package swen90006.passbook;
public class DuplicateUserException extends Exception
{
public DuplicateUserException(String username)
{
super("Username already exists: " + username);
}
}
package swen90006.passbook;
public class IncorrectPassphraseException extends Exception
{
public IncorrectPassphraseException(String username, String passphrase)
{
super("Incorrect passphrase: " + passphrase + " for user " + username);
}
}
package swen90006.passbook;
public class InvalidSessionIDException extends Exception
{
public InvalidSessionIDException(Integer sessionID)
{
super("Invalid session ID: " + sessionID);
}
}
package swen90006.passbook;
import java.net.URL;
public class NoSuchURLException extends Exception
{
public NoSuchURLException (String username, URL url)
{
super("User " + username + " does not have password for URL " + url.toString());
}
}
package swen90006.passbook;
public class NoSuchUserException extends Exception
{
public NoSuchUserException (String username)
{
super("Username does not exist: " + username);
}
}
package swen90006.passbook;
/**
* A pair of objects.
*/
public class Pair<X, Y>
{
private X first;
private Y second;
public Pair(X first, Y second)
{
this.first = first;
this.second = second;
}
public X getFirst()
{
return this.first;
}
public Y getSecond()
{
return this.second;
}
public boolean equals(Pair<X, Y> other)
{
return first.equals(other.first) && second.equals(other.second);
}
}
package swen90006.passbook;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Random;
import java.util.Arrays;
/**
* PassBook is a (fictional) online password manager. A password
* manager is a software application that generates, stores, and
* retrieves login details for users.
*
* A user has an account with PassBook. This account is protected by a
* master password, or passphrase. Each user can store login details
* for multiple websites, identified by their URL. A user can add a
* login details for a given website. The passphrase is used to
* encrypt all passwords, but for this implementation, we have ignored
* encryption.
*
* The PassBook passphrase must conform to the following requirements:
* Must be at least eight characters long and contain at
* least one digit (range 0-9), one letter in the range 'a'-'z', and
* one letter in the range 'A'-'Z'.
*
* Username and passwords for stored URLs have no password
* requirements.
*
* When a user logs into PassBook, they are given a session ID. This
* session ID is used to identify them for all transactions until they
* log out.
*/
public class PassBook
{
/** The minimum length of a passphrase */
public final static int MINIMUM_PASSPHRASE_LENGTH = 8;
/** Valid URL protocols for the passbook */
public final static String [] VALID_URL_PROTOCOLS = {"http", "https"};
//The passphrases (master passwords) for all users
private Map<String, String> passphrases;
//The login details for all users and the URLs they have stored
private Map<String, PasswordTable> details;
//Mapping from session IDs to usernames
private Map<Integer, String> userIDs;
//Mapping from usernames to sessionIDs
private Map<String, Integer> sessionIDs;
/**
* Constructs an empty passbook.
*/
public PassBook()
{
passphrases = new HashMap<String, String>();
details = new HashMap<String, PasswordTable>();
userIDs = new HashMap<Integer, String>();
sessionIDs = new HashMap<String, Integer>();
}
/**
* Adds a new user to the passbook.
*
* @param passbookUsername the username for the user to be added
* @param passphrase the passphrase (master password) for the user
* @throws DuplicateUserException if the username is already in the passbook
* @throws WeakPassphraseException if the password does not fit the passphrase
rules (see class documentation)
*
* Assumption: passbookUsername and passphrase are non-null
*/
public void addUser(String passbookUsername, String passphrase)
throws DuplicateUserException, WeakPassphraseException
{
//Check if this user exists
if (passphrases.containsKey(passbookUsername)) {
throw new DuplicateUserException(passbookUsername);
}
//check the passphrase strength
else {
if (passphrase.length() < MINIMUM_PASSPHRASE_LENGTH) {
throw new WeakPassphraseException(passphrase);
}
boolean containsLowerCase = false;
boolean containsUpperCase = false;
boolean containsNumber = false;
for (int i = 0; i < passphrase.length(); i++) {
if ('a' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'z') {
containsLowerCase = true;
}
else if ('A' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'Z') {
containsUpperCase = true;
}
else if ('0' <= passphrase.charAt(i) && passphrase.charAt(i) <= '9') {
containsNumber = true;
}
}
if (!containsLowerCase || !containsUpperCase || !containsNumber) {
throw new WeakPassphraseException(passphrase);
}
}
passphrases.put(passbookUsername, passphrase);
PasswordTable pt = new PasswordTable();
details.put(passbookUsername, pt);
}
/**
* Checks if a user exists
* @param passbookUsername the passbookUsername
* @return true if and only if this user is in the passbook
*
* Assumption: passbookUsername is non-null
*/
public boolean isUser(String passbookUsername)
{
return passphrases.containsKey(passbookUsername);
}
/**
* Logs a user into the passbook.
*
* @param passbookUsername the passbookUsername for the user
* @param passphrase the passphrase (master password) for the user
* @returns a session ID greater than or equal to 0
* @throws NoSuchUserException if the user does not exist in the passbook
* @throws AlreadyLoggedInException if the user is already logged in
* @throws IncorrectPassphraseException if the passphrase is incorrect for this user
*
* Assumption: passbookUsername and passphrase are non-null
*/
public int loginUser(String passbookUsername, String passphrase)
throws NoSuchUserException, AlreadyLoggedInException, IncorrectPassphraseException
{
//check that the user exists
if (!passphrases.containsKey(passbookUsername)) {
throw new NoSuchUserException(passbookUsername);
}
else if (sessionIDs.get(passbookUsername) != null) {
throw new AlreadyLoggedInException(passbookUsername);
}
else if (!passphrases.get(passbookUsername).equals(passphrase)) {
throw new IncorrectPassphraseException(passbookUsername, passphrase);
}
//generate a random session ID that is not already taken
int sessionID = new Random().nextInt(Integer.MAX_VALUE);
while (userIDs.containsKey(sessionID)) {
sessionID = new Random().nextInt(Integer.MAX_VALUE);
}
//add the session ID
sessionIDs.put(passbookUsername, sessionID);
userIDs.put(sessionID, passbookUsername);
return sessionID;
}
/**
* Logs out a user based on session ID. Has no affect if the session ID does not exist.
*
* @param sessionID the session ID to be terminated
*
* Assumption: session ID is non-null
*/
public void logoutUser(Integer sessionID)
{
sessionIDs.remove(userIDs.get(sessionID));
userIDs.remove(sessionID);
}
/**
* Updates the login details for a URL of a user. If the url
* username or password are null, the login details for this URL
* must be removed.
*
* @param sessionID the session ID for the logged-in user
* @param urlUsername the username for the user to be added
* @param url the URL for the username/password pair
* @param urlPassword the password to be add
* @throws InvalidSessionIDException if the session ID does not exists
* @throws MalformedURLException if the protocol is not 'http' or 'https'
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public void updateDetails(Integer sessionID, URL url, String urlUsername, String urlPassword)
throws InvalidSessionIDException, MalformedURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
if (urlUsername == null || urlPassword == null) {
pt.remove(url);
}
else {
pt.put(url, new Pair<String, String> (urlUsername, urlPassword));
details.put(passbookUsername, pt);
}
}
/**
* Retrieves login details for a given URL and user.
*
* @param sessionID the session ID
* @param url the URL for the password being retrieved.
* @returns the username and password for a given url for the corresponding user
* @throws NoSuchUserException if the username does not exist in the passbook
* @throws MalformedURLException if the syntax is invalid (see class documentation)
* @throws NoSuchURLException if user does not have login for this URL
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public Pair<String, String> retrieveDetails(Integer sessionID, URL url)
throws InvalidSessionIDException, MalformedURLException, NoSuchURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
//if this returned nothing, the user has no details for any url
if (pt == null) {
throw new NoSuchURLException(passbookUsername, url);
}
Pair<String, String> pair = pt.get(url);
//if this returned nothing, the user does not have a login for this url
if (pair == null) {
throw new NoSuchURLException(passbookUsername, url);
}
return pair;
}
//A simple label to improve code readability
private class PasswordTable extends HashMap<URL, Pair<String, String>> {}
}
package swen90006.passbook;
public class WeakPassphraseException extends Exception
{
public WeakPassphraseException (String passphrase)
{
super("Passphrase does not comply with the PassBook rules\n" +
"\t- must contains at least " +
PassBook.MINIMUM_PASSPHRASE_LENGTH + " characters\n" +
"\t- must contain at least one numeric character\n" +
"\t- must contain at least one lower case letter\n" +
"\t- must contain at least one upper case letter\n");
}
}
package swen90006.passbook;
public class AlreadyLoggedInException extends Exception
{
public AlreadyLoggedInException(String username)
{
super("Username already logged in: " + username);
}
}
package swen90006.passbook;
public class DuplicateUserException extends Exception
{
public DuplicateUserException(String username)
{
super("Username already exists: " + username);
}
}
package swen90006.passbook;
public class IncorrectPassphraseException extends Exception
{
public IncorrectPassphraseException(String username, String passphrase)
{
super("Incorrect passphrase: " + passphrase + " for user " + username);
}
}
package swen90006.passbook;
public class InvalidSessionIDException extends Exception
{
public InvalidSessionIDException(Integer sessionID)
{
super("Invalid session ID: " + sessionID);
}
}
package swen90006.passbook;
import java.net.URL;
public class NoSuchURLException extends Exception
{
public NoSuchURLException (String username, URL url)
{
super("User " + username + " does not have password for URL " + url.toString());
}
}
package swen90006.passbook;
public class NoSuchUserException extends Exception
{
public NoSuchUserException (String username)
{
super("Username does not exist: " + username);
}
}
package swen90006.passbook;
/**
* A pair of objects.
*/
public class Pair<X, Y>
{
private X first;
private Y second;
public Pair(X first, Y second)
{
this.first = first;
this.second = second;
}
public X getFirst()
{
return this.first;
}
public Y getSecond()
{
return this.second;
}
public boolean equals(Pair<X, Y> other)
{
return first.equals(other.first) && second.equals(other.second);
}
}
package swen90006.passbook;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Random;
import java.util.Arrays;
/**
* PassBook is a (fictional) online password manager. A password
* manager is a software application that generates, stores, and
* retrieves login details for users.
*
* A user has an account with PassBook. This account is protected by a
* master password, or passphrase. Each user can store login details
* for multiple websites, identified by their URL. A user can add a
* login details for a given website. The passphrase is used to
* encrypt all passwords, but for this implementation, we have ignored
* encryption.
*
* The PassBook passphrase must conform to the following requirements:
* Must be at least eight characters long and contain at
* least one digit (range 0-9), one letter in the range 'a'-'z', and
* one letter in the range 'A'-'Z'.
*
* Username and passwords for stored URLs have no password
* requirements.
*
* When a user logs into PassBook, they are given a session ID. This
* session ID is used to identify them for all transactions until they
* log out.
*/
public class PassBook
{
/** The minimum length of a passphrase */
public final static int MINIMUM_PASSPHRASE_LENGTH = 8;
/** Valid URL protocols for the passbook */
public final static String [] VALID_URL_PROTOCOLS = {"http", "https"};
//The passphrases (master passwords) for all users
private Map<String, String> passphrases;
//The login details for all users and the URLs they have stored
private Map<String, PasswordTable> details;
//Mapping from session IDs to usernames
private Map<Integer, String> userIDs;
//Mapping from usernames to sessionIDs
private Map<String, Integer> sessionIDs;
/**
* Constructs an empty passbook.
*/
public PassBook()
{
passphrases = new HashMap<String, String>();
details = new HashMap<String, PasswordTable>();
userIDs = new HashMap<Integer, String>();
sessionIDs = new HashMap<String, Integer>();
}
/**
* Adds a new user to the passbook.
*
* @param passbookUsername the username for the user to be added
* @param passphrase the passphrase (master password) for the user
* @throws DuplicateUserException if the username is already in the passbook
* @throws WeakPassphraseException if the password does not fit the passphrase
rules (see class documentation)
*
* Assumption: passbookUsername and passphrase are non-null
*/
public void addUser(String passbookUsername, String passphrase)
throws DuplicateUserException, WeakPassphraseException
{
//Check if this user exists
if (passphrases.containsKey(passbookUsername)) {
throw new DuplicateUserException(passbookUsername);
}
//check the passphrase strength
else {
if (passphrase.length() < MINIMUM_PASSPHRASE_LENGTH) {
throw new WeakPassphraseException(passphrase);
}
boolean containsLowerCase = false;
boolean containsUpperCase = false;
boolean containsNumber = false;
for (int i = 0; i < passphrase.length(); i++) {
if ('a' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'z') {
containsLowerCase = true;
}
else if ('A' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'Z') {
containsUpperCase = true;
}
else if ('0' <= passphrase.charAt(i) && passphrase.charAt(i) <= '9') {
containsNumber = true;
}
}
if (!containsLowerCase || !containsUpperCase || !containsNumber) {
throw new WeakPassphraseException(passphrase);
}
}
passphrases.put(passbookUsername, passphrase);
PasswordTable pt = new PasswordTable();
details.put(passbookUsername, pt);
}
/**
* Checks if a user exists
* @param passbookUsername the passbookUsername
* @return true if and only if this user is in the passbook
*
* Assumption: passbookUsername is non-null
*/
public boolean isUser(String passbookUsername)
{
return passphrases.containsKey(passbookUsername);
}
/**
* Logs a user into the passbook.
*
* @param passbookUsername the passbookUsername for the user
* @param passphrase the passphrase (master password) for the user
* @returns a session ID greater than or equal to 0
* @throws NoSuchUserException if the user does not exist in the passbook
* @throws AlreadyLoggedInException if the user is already logged in
* @throws IncorrectPassphraseException if the passphrase is incorrect for this user
*
* Assumption: passbookUsername and passphrase are non-null
*/
public int loginUser(String passbookUsername, String passphrase)
throws NoSuchUserException, AlreadyLoggedInException, IncorrectPassphraseException
{
//check that the user exists
if (!passphrases.containsKey(passbookUsername)) {
throw new NoSuchUserException(passbookUsername);
}
else if (sessionIDs.get(passbookUsername) != null) {
throw new AlreadyLoggedInException(passbookUsername);
}
else if (!passphrases.get(passbookUsername).equals(passphrase)) {
throw new IncorrectPassphraseException(passbookUsername, passphrase);
}
//generate a random session ID that is not already taken
int sessionID = new Random().nextInt(Integer.MAX_VALUE);
while (userIDs.containsKey(sessionID)) {
sessionID = new Random().nextInt(Integer.MAX_VALUE);
}
//add the session ID
sessionIDs.put(passbookUsername, sessionID);
userIDs.put(sessionID, passbookUsername);
return sessionID;
}
/**
* Logs out a user based on session ID. Has no affect if the session ID does not exist.
*
* @param sessionID the session ID to be terminated
*
* Assumption: session ID is non-null
*/
public void logoutUser(Integer sessionID)
{
sessionIDs.remove(userIDs.get(sessionID));
userIDs.remove(sessionID);
}
/**
* Updates the login details for a URL of a user. If the url
* username or password are null, the login details for this URL
* must be removed.
*
* @param sessionID the session ID for the logged-in user
* @param urlUsername the username for the user to be added
* @param url the URL for the username/password pair
* @param urlPassword the password to be add
* @throws InvalidSessionIDException if the session ID does not exists
* @throws MalformedURLException if the protocol is not 'http' or 'https'
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public void updateDetails(Integer sessionID, URL url, String urlUsername, String urlPassword)
throws InvalidSessionIDException, MalformedURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
if (urlUsername == null || urlPassword == null) {
pt.remove(url);
}
else {
pt.put(url, new Pair<String, String> (urlUsername, urlPassword));
details.put(passbookUsername, pt);
}
}
/**
* Retrieves login details for a given URL and user.
*
* @param sessionID the session ID
* @param url the URL for the password being retrieved.
* @returns the username and password for a given url for the corresponding user
* @throws NoSuchUserException if the username does not exist in the passbook
* @throws MalformedURLException if the syntax is invalid (see class documentation)
* @throws NoSuchURLException if user does not have login for this URL
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public Pair<String, String> retrieveDetails(Integer sessionID, URL url)
throws InvalidSessionIDException, MalformedURLException, NoSuchURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
//if this returned nothing, the user has no details for any url
if (pt == null) {
throw new NoSuchURLException(passbookUsername, url);
}
Pair<String, String> pair = pt.get(url);
//if this returned nothing, the user does not have a login for this url
if (pair == null) {
throw new NoSuchURLException(passbookUsername, url);
}
return pair;
}
//A simple label to improve code readability
private class PasswordTable extends HashMap<URL, Pair<String, String>> {}
}
package swen90006.passbook;
public class WeakPassphraseException extends Exception
{
public WeakPassphraseException (String passphrase)
{
super("Passphrase does not comply with the PassBook rules\n" +
"\t- must contains at least " +
PassBook.MINIMUM_PASSPHRASE_LENGTH + " characters\n" +
"\t- must contain at least one numeric character\n" +
"\t- must contain at least one lower case letter\n" +
"\t- must contain at least one upper case letter\n");
}
}
package swen90006.passbook;
public class AlreadyLoggedInException extends Exception
{
public AlreadyLoggedInException(String username)
{
super("Username already logged in: " + username);
}
}
package swen90006.passbook;
public class DuplicateUserException extends Exception
{
public DuplicateUserException(String username)
{
super("Username already exists: " + username);
}
}
package swen90006.passbook;
public class IncorrectPassphraseException extends Exception
{
public IncorrectPassphraseException(String username, String passphrase)
{
super("Incorrect passphrase: " + passphrase + " for user " + username);
}
}
package swen90006.passbook;
public class InvalidSessionIDException extends Exception
{
public InvalidSessionIDException(Integer sessionID)
{
super("Invalid session ID: " + sessionID);
}
}
package swen90006.passbook;
import java.net.URL;
public class NoSuchURLException extends Exception
{
public NoSuchURLException (String username, URL url)
{
super("User " + username + " does not have password for URL " + url.toString());
}
}
package swen90006.passbook;
public class NoSuchUserException extends Exception
{
public NoSuchUserException (String username)
{
super("Username does not exist: " + username);
}
}
package swen90006.passbook;
/**
* A pair of objects.
*/
public class Pair<X, Y>
{
private X first;
private Y second;
public Pair(X first, Y second)
{
this.first = first;
this.second = second;
}
public X getFirst()
{
return this.first;
}
public Y getSecond()
{
return this.second;
}
public boolean equals(Pair<X, Y> other)
{
return first.equals(other.first) && second.equals(other.second);
}
}
package swen90006.passbook;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Random;
import java.util.Arrays;
/**
* PassBook is a (fictional) online password manager. A password
* manager is a software application that generates, stores, and
* retrieves login details for users.
*
* A user has an account with PassBook. This account is protected by a
* master password, or passphrase. Each user can store login details
* for multiple websites, identified by their URL. A user can add a
* login details for a given website. The passphrase is used to
* encrypt all passwords, but for this implementation, we have ignored
* encryption.
*
* The PassBook passphrase must conform to the following requirements:
* Must be at least eight characters long and contain at
* least one digit (range 0-9), one letter in the range 'a'-'z', and
* one letter in the range 'A'-'Z'.
*
* Username and passwords for stored URLs have no password
* requirements.
*
* When a user logs into PassBook, they are given a session ID. This
* session ID is used to identify them for all transactions until they
* log out.
*/
public class PassBook
{
/** The minimum length of a passphrase */
public final static int MINIMUM_PASSPHRASE_LENGTH = 8;
/** Valid URL protocols for the passbook */
public final static String [] VALID_URL_PROTOCOLS = {"http", "https"};
//The passphrases (master passwords) for all users
private Map<String, String> passphrases;
//The login details for all users and the URLs they have stored
private Map<String, PasswordTable> details;
//Mapping from session IDs to usernames
private Map<Integer, String> userIDs;
//Mapping from usernames to sessionIDs
private Map<String, Integer> sessionIDs;
/**
* Constructs an empty passbook.
*/
public PassBook()
{
passphrases = new HashMap<String, String>();
details = new HashMap<String, PasswordTable>();
userIDs = new HashMap<Integer, String>();
sessionIDs = new HashMap<String, Integer>();
}
/**
* Adds a new user to the passbook.
*
* @param passbookUsername the username for the user to be added
* @param passphrase the passphrase (master password) for the user
* @throws DuplicateUserException if the username is already in the passbook
* @throws WeakPassphraseException if the password does not fit the passphrase
rules (see class documentation)
*
* Assumption: passbookUsername and passphrase are non-null
*/
public void addUser(String passbookUsername, String passphrase)
throws DuplicateUserException, WeakPassphraseException
{
//Check if this user exists
if (passphrases.containsKey(passbookUsername)) {
throw new DuplicateUserException(passbookUsername);
}
//check the passphrase strength
else {
if (passphrase.length() < MINIMUM_PASSPHRASE_LENGTH) {
throw new WeakPassphraseException(passphrase);
}
boolean containsLowerCase = false;
boolean containsUpperCase = false;
boolean containsNumber = false;
//---------------mutant--------------
for (int i = 1; i < passphrase.length(); i++) {
if ('a' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'z') {
containsLowerCase = true;
}
else if ('A' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'Z') {
containsUpperCase = true;
}
else if ('0' <= passphrase.charAt(i) && passphrase.charAt(i) <= '9') {
containsNumber = true;
}
}
if (!containsLowerCase || !containsUpperCase || !containsNumber) {
throw new WeakPassphraseException(passphrase);
}
}
passphrases.put(passbookUsername, passphrase);
PasswordTable pt = new PasswordTable();
details.put(passbookUsername, pt);
}
/**
* Checks if a user exists
* @param passbookUsername the passbookUsername
* @return true if and only if this user is in the passbook
*
* Assumption: passbookUsername is non-null
*/
public boolean isUser(String passbookUsername)
{
return passphrases.containsKey(passbookUsername);
}
/**
* Logs a user into the passbook.
*
* @param passbookUsername the passbookUsername for the user
* @param passphrase the passphrase (master password) for the user
* @returns a session ID greater than or equal to 0
* @throws NoSuchUserException if the user does not exist in the passbook
* @throws AlreadyLoggedInException if the user is already logged in
* @throws IncorrectPassphraseException if the passphrase is incorrect for this user
*
* Assumption: passbookUsername and passphrase are non-null
*/
public int loginUser(String passbookUsername, String passphrase)
throws NoSuchUserException, AlreadyLoggedInException, IncorrectPassphraseException
{
//check that the user exists
if (!passphrases.containsKey(passbookUsername)) {
throw new NoSuchUserException(passbookUsername);
}
else if (sessionIDs.get(passbookUsername) != null) {
throw new AlreadyLoggedInException(passbookUsername);
}
else if (!passphrases.get(passbookUsername).equals(passphrase)) {
throw new IncorrectPassphraseException(passbookUsername, passphrase);
}
//generate a random session ID that is not already taken
int sessionID = new Random().nextInt(Integer.MAX_VALUE);
while (userIDs.containsKey(sessionID)) {
sessionID = new Random().nextInt(Integer.MAX_VALUE);
}
//add the session ID
sessionIDs.put(passbookUsername, sessionID);
userIDs.put(sessionID, passbookUsername);
return sessionID;
}
/**
* Logs out a user based on session ID. Has no affect if the session ID does not exist.
*
* @param sessionID the session ID to be terminated
*
* Assumption: session ID is non-null
*/
public void logoutUser(Integer sessionID)
{
sessionIDs.remove(userIDs.get(sessionID));
userIDs.remove(sessionID);
}
/**
* Updates the login details for a URL of a user. If the url
* username or password are null, the login details for this URL
* must be removed.
*
* @param sessionID the session ID for the logged-in user
* @param urlUsername the username for the user to be added
* @param url the URL for the username/password pair
* @param urlPassword the password to be add
* @throws InvalidSessionIDException if the session ID does not exists
* @throws MalformedURLException if the protocol is not 'http' or 'https'
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public void updateDetails(Integer sessionID, URL url, String urlUsername, String urlPassword)
throws InvalidSessionIDException, MalformedURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
if (urlUsername == null || urlPassword == null) {
pt.remove(url);
}
else {
pt.put(url, new Pair<String, String> (urlUsername, urlPassword));
details.put(passbookUsername, pt);
}
}
/**
* Retrieves login details for a given URL and user.
*
* @param sessionID the session ID
* @param url the URL for the password being retrieved.
* @returns the username and password for a given url for the corresponding user
* @throws NoSuchUserException if the username does not exist in the passbook
* @throws MalformedURLException if the syntax is invalid (see class documentation)
* @throws NoSuchURLException if user does not have login for this URL
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public Pair<String, String> retrieveDetails(Integer sessionID, URL url)
throws InvalidSessionIDException, MalformedURLException, NoSuchURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
//if this returned nothing, the user has no details for any url
if (pt == null) {
throw new NoSuchURLException(passbookUsername, url);
}
Pair<String, String> pair = pt.get(url);
//if this returned nothing, the user does not have a login for this url
if (pair == null) {
throw new NoSuchURLException(passbookUsername, url);
}
return pair;
}
//A simple label to improve code readability
private class PasswordTable extends HashMap<URL, Pair<String, String>> {}
}
package swen90006.passbook;
public class WeakPassphraseException extends Exception
{
public WeakPassphraseException (String passphrase)
{
super("Passphrase does not comply with the PassBook rules\n" +
"\t- must contains at least " +
PassBook.MINIMUM_PASSPHRASE_LENGTH + " characters\n" +
"\t- must contain at least one numeric character\n" +
"\t- must contain at least one lower case letter\n" +
"\t- must contain at least one upper case letter\n");
}
}
package swen90006.passbook;
public class AlreadyLoggedInException extends Exception
{
public AlreadyLoggedInException(String username)
{
super("Username already logged in: " + username);
}
}
package swen90006.passbook;
public class DuplicateUserException extends Exception
{
public DuplicateUserException(String username)
{
super("Username already exists: " + username);
}
}
package swen90006.passbook;
public class IncorrectPassphraseException extends Exception
{
public IncorrectPassphraseException(String username, String passphrase)
{
super("Incorrect passphrase: " + passphrase + " for user " + username);
}
}
package swen90006.passbook;
public class InvalidSessionIDException extends Exception
{
public InvalidSessionIDException(Integer sessionID)
{
super("Invalid session ID: " + sessionID);
}
}
package swen90006.passbook;
import java.net.URL;
public class NoSuchURLException extends Exception
{
public NoSuchURLException (String username, URL url)
{
super("User " + username + " does not have password for URL " + url.toString());
}
}
package swen90006.passbook;
public class NoSuchUserException extends Exception
{
public NoSuchUserException (String username)
{
super("Username does not exist: " + username);
}
}
package swen90006.passbook;
/**
* A pair of objects.
*/
public class Pair<X, Y>
{
private X first;
private Y second;
public Pair(X first, Y second)
{
this.first = first;
this.second = second;
}
public X getFirst()
{
return this.first;
}
public Y getSecond()
{
return this.second;
}
public boolean equals(Pair<X, Y> other)
{
return first.equals(other.first) && second.equals(other.second);
}
}
package swen90006.passbook;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Random;
import java.util.Arrays;
/**
* PassBook is a (fictional) online password manager. A password
* manager is a software application that generates, stores, and
* retrieves login details for users.
*
* A user has an account with PassBook. This account is protected by a
* master password, or passphrase. Each user can store login details
* for multiple websites, identified by their URL. A user can add a
* login details for a given website. The passphrase is used to
* encrypt all passwords, but for this implementation, we have ignored
* encryption.
*
* The PassBook passphrase must conform to the following requirements:
* Must be at least eight characters long and contain at
* least one digit (range 0-9), one letter in the range 'a'-'z', and
* one letter in the range 'A'-'Z'.
*
* Username and passwords for stored URLs have no password
* requirements.
*
* When a user logs into PassBook, they are given a session ID. This
* session ID is used to identify them for all transactions until they
* log out.
*/
public class PassBook
{
/** The minimum length of a passphrase */
public final static int MINIMUM_PASSPHRASE_LENGTH = 8;
/** Valid URL protocols for the passbook */
public final static String [] VALID_URL_PROTOCOLS = {"http", "https"};
//The passphrases (master passwords) for all users
private Map<String, String> passphrases;
//The login details for all users and the URLs they have stored
private Map<String, PasswordTable> details;
//Mapping from session IDs to usernames
private Map<Integer, String> userIDs;
//Mapping from usernames to sessionIDs
private Map<String, Integer> sessionIDs;
/**
* Constructs an empty passbook.
*/
public PassBook()
{
passphrases = new HashMap<String, String>();
details = new HashMap<String, PasswordTable>();
userIDs = new HashMap<Integer, String>();
sessionIDs = new HashMap<String, Integer>();
}
/**
* Adds a new user to the passbook.
*
* @param passbookUsername the username for the user to be added
* @param passphrase the passphrase (master password) for the user
* @throws DuplicateUserException if the username is already in the passbook
* @throws WeakPassphraseException if the password does not fit the passphrase
rules (see class documentation)
*
* Assumption: passbookUsername and passphrase are non-null
*/
public void addUser(String passbookUsername, String passphrase)
throws DuplicateUserException, WeakPassphraseException
{
//Check if this user exists
if (passphrases.containsKey(passbookUsername)) {
throw new DuplicateUserException(passbookUsername);
}
//check the passphrase strength
else {
if (passphrase.length() < MINIMUM_PASSPHRASE_LENGTH) {
throw new WeakPassphraseException(passphrase);
}
boolean containsLowerCase = false;
boolean containsUpperCase = false;
boolean containsNumber = false;
for (int i = 0; i < passphrase.length(); i++) {
if ('a' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'z') {
containsLowerCase = true;
}
else if ('A' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'Z') {
containsUpperCase = true;
}
else if ('/' <= passphrase.charAt(i) && passphrase.charAt(i) <= '9') {
containsNumber = true;
}
}
if (!containsLowerCase || !containsUpperCase || !containsNumber) {
throw new WeakPassphraseException(passphrase);
}
}
passphrases.put(passbookUsername, passphrase);
PasswordTable pt = new PasswordTable();
details.put(passbookUsername, pt);
}
/**
* Checks if a user exists
* @param passbookUsername the passbookUsername
* @return true if and only if this user is in the passbook
*
* Assumption: passbookUsername is non-null
*/
public boolean isUser(String passbookUsername)
{
return passphrases.containsKey(passbookUsername);
}
/**
* Logs a user into the passbook.
*
* @param passbookUsername the passbookUsername for the user
* @param passphrase the passphrase (master password) for the user
* @returns a session ID greater than or equal to 0
* @throws NoSuchUserException if the user does not exist in the passbook
* @throws AlreadyLoggedInException if the user is already logged in
* @throws IncorrectPassphraseException if the passphrase is incorrect for this user
*
* Assumption: passbookUsername and passphrase are non-null
*/
public int loginUser(String passbookUsername, String passphrase)
throws NoSuchUserException, AlreadyLoggedInException, IncorrectPassphraseException
{
//check that the user exists
if (!passphrases.containsKey(passbookUsername)) {
throw new NoSuchUserException(passbookUsername);
}
else if (sessionIDs.get(passbookUsername) != null) {
throw new AlreadyLoggedInException(passbookUsername);
}
else if (!passphrases.get(passbookUsername).equals(passphrase)) {
throw new IncorrectPassphraseException(passbookUsername, passphrase);
}
//generate a random session ID that is not already taken
int sessionID = new Random().nextInt(Integer.MAX_VALUE);
while (userIDs.containsKey(sessionID)) {
sessionID = new Random().nextInt(Integer.MAX_VALUE);
}
//add the session ID
sessionIDs.put(passbookUsername, sessionID);
userIDs.put(sessionID, passbookUsername);
return sessionID;
}
/**
* Logs out a user based on session ID. Has no affect if the session ID does not exist.
*
* @param sessionID the session ID to be terminated
*
* Assumption: session ID is non-null
*/
public void logoutUser(Integer sessionID)
{
sessionIDs.remove(userIDs.get(sessionID));
userIDs.remove(sessionID);
}
/**
* Updates the login details for a URL of a user. If the url
* username or password are null, the login details for this URL
* must be removed.
*
* @param sessionID the session ID for the logged-in user
* @param urlUsername the username for the user to be added
* @param url the URL for the username/password pair
* @param urlPassword the password to be add
* @throws InvalidSessionIDException if the session ID does not exists
* @throws MalformedURLException if the protocol is not 'http' or 'https'
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public void updateDetails(Integer sessionID, URL url, String urlUsername, String urlPassword)
throws InvalidSessionIDException, MalformedURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
if (urlUsername == null || urlPassword == null) {
pt.remove(url);
}
else {
pt.put(url, new Pair<String, String> (urlUsername, urlPassword));
details.put(passbookUsername, pt);
}
}
/**
* Retrieves login details for a given URL and user.
*
* @param sessionID the session ID
* @param url the URL for the password being retrieved.
* @returns the username and password for a given url for the corresponding user
* @throws NoSuchUserException if the username does not exist in the passbook
* @throws MalformedURLException if the syntax is invalid (see class documentation)
* @throws NoSuchURLException if user does not have login for this URL
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public Pair<String, String> retrieveDetails(Integer sessionID, URL url)
throws InvalidSessionIDException, MalformedURLException, NoSuchURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
//if this returned nothing, the user has no details for any url
if (pt == null) {
throw new NoSuchURLException(passbookUsername, url);
}
Pair<String, String> pair = pt.get(url);
//if this returned nothing, the user does not have a login for this url
if (pair == null) {
throw new NoSuchURLException(passbookUsername, url);
}
return pair;
}
//A simple label to improve code readability
private class PasswordTable extends HashMap<URL, Pair<String, String>> {}
}
package swen90006.passbook;
public class WeakPassphraseException extends Exception
{
public WeakPassphraseException (String passphrase)
{
super("Passphrase does not comply with the PassBook rules\n" +
"\t- must contains at least " +
PassBook.MINIMUM_PASSPHRASE_LENGTH + " characters\n" +
"\t- must contain at least one numeric character\n" +
"\t- must contain at least one lower case letter\n" +
"\t- must contain at least one upper case letter\n");
}
}
package swen90006.passbook;
public class AlreadyLoggedInException extends Exception
{
public AlreadyLoggedInException(String username)
{
super("Username already logged in: " + username);
}
}
package swen90006.passbook;
public class DuplicateUserException extends Exception
{
public DuplicateUserException(String username)
{
super("Username already exists: " + username);
}
}
package swen90006.passbook;
public class IncorrectPassphraseException extends Exception
{
public IncorrectPassphraseException(String username, String passphrase)
{
super("Incorrect passphrase: " + passphrase + " for user " + username);
}
}
package swen90006.passbook;
public class InvalidSessionIDException extends Exception
{
public InvalidSessionIDException(Integer sessionID)
{
super("Invalid session ID: " + sessionID);
}
}
package swen90006.passbook;
import java.net.URL;
public class NoSuchURLException extends Exception
{
public NoSuchURLException (String username, URL url)
{
super("User " + username + " does not have password for URL " + url.toString());
}
}
package swen90006.passbook;
public class NoSuchUserException extends Exception
{
public NoSuchUserException (String username)
{
super("Username does not exist: " + username);
}
}
package swen90006.passbook;
/**
* A pair of objects.
*/
public class Pair<X, Y>
{
private X first;
private Y second;
public Pair(X first, Y second)
{
this.first = first;
this.second = second;
}
public X getFirst()
{
return this.first;
}
public Y getSecond()
{
return this.second;
}
public boolean equals(Pair<X, Y> other)
{
return first.equals(other.first) && second.equals(other.second);
}
}
package swen90006.passbook;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Random;
import java.util.Arrays;
/**
* PassBook is a (fictional) online password manager. A password
* manager is a software application that generates, stores, and
* retrieves login details for users.
*
* A user has an account with PassBook. This account is protected by a
* master password, or passphrase. Each user can store login details
* for multiple websites, identified by their URL. A user can add a
* login details for a given website. The passphrase is used to
* encrypt all passwords, but for this implementation, we have ignored
* encryption.
*
* The PassBook passphrase must conform to the following requirements:
* Must be at least eight characters long and contain at
* least one digit (range 0-9), one letter in the range 'a'-'z', and
* one letter in the range 'A'-'Z'.
*
* Username and passwords for stored URLs have no password
* requirements.
*
* When a user logs into PassBook, they are given a session ID. This
* session ID is used to identify them for all transactions until they
* log out.
*/
public class PassBook
{
/** The minimum length of a passphrase */
public final static int MINIMUM_PASSPHRASE_LENGTH = 8;
/** Valid URL protocols for the passbook */
public final static String [] VALID_URL_PROTOCOLS = {"http", "https"};
//The passphrases (master passwords) for all users
private Map<String, String> passphrases;
//The login details for all users and the URLs they have stored
private Map<String, PasswordTable> details;
//Mapping from session IDs to usernames
private Map<Integer, String> userIDs;
//Mapping from usernames to sessionIDs
private Map<String, Integer> sessionIDs;
/**
* Constructs an empty passbook.
*/
public PassBook()
{
passphrases = new HashMap<String, String>();
details = new HashMap<String, PasswordTable>();
userIDs = new HashMap<Integer, String>();
sessionIDs = new HashMap<String, Integer>();
}
/**
* Adds a new user to the passbook.
*
* @param passbookUsername the username for the user to be added
* @param passphrase the passphrase (master password) for the user
* @throws DuplicateUserException if the username is already in the passbook
* @throws WeakPassphraseException if the password does not fit the passphrase
rules (see class documentation)
*
* Assumption: passbookUsername and passphrase are non-null
*/
public void addUser(String passbookUsername, String passphrase)
throws DuplicateUserException, WeakPassphraseException
{
//Check if this user exists
if (passphrases.containsKey(passbookUsername)) {
throw new DuplicateUserException(passbookUsername);
}
//check the passphrase strength
else {
if (passphrase.length() < MINIMUM_PASSPHRASE_LENGTH) {
throw new WeakPassphraseException(passphrase);
}
boolean containsLowerCase = false;
boolean containsUpperCase = false;
boolean containsNumber = false;
for (int i = 0; i < passphrase.length(); i++) {
if ('a' <= passphrase.charAt(i) || passphrase.charAt(i) <= 'z') {
containsLowerCase = true;
}
else if ('A' <= passphrase.charAt(i) && passphrase.charAt(i) <= 'Z') {
containsUpperCase = true;
}
else if ('0' <= passphrase.charAt(i) && passphrase.charAt(i) <= '9') {
containsNumber = true;
}
}
if (!containsLowerCase || !containsUpperCase || !containsNumber) {
throw new WeakPassphraseException(passphrase);
}
}
passphrases.put(passbookUsername, passphrase);
PasswordTable pt = new PasswordTable();
details.put(passbookUsername, pt);
}
/**
* Checks if a user exists
* @param passbookUsername the passbookUsername
* @return true if and only if this user is in the passbook
*
* Assumption: passbookUsername is non-null
*/
public boolean isUser(String passbookUsername)
{
return passphrases.containsKey(passbookUsername);
}
/**
* Logs a user into the passbook.
*
* @param passbookUsername the passbookUsername for the user
* @param passphrase the passphrase (master password) for the user
* @returns a session ID greater than or equal to 0
* @throws NoSuchUserException if the user does not exist in the passbook
* @throws AlreadyLoggedInException if the user is already logged in
* @throws IncorrectPassphraseException if the passphrase is incorrect for this user
*
* Assumption: passbookUsername and passphrase are non-null
*/
public int loginUser(String passbookUsername, String passphrase)
throws NoSuchUserException, AlreadyLoggedInException, IncorrectPassphraseException
{
//check that the user exists
if (!passphrases.containsKey(passbookUsername)) {
throw new NoSuchUserException(passbookUsername);
}
else if (sessionIDs.get(passbookUsername) != null) {
throw new AlreadyLoggedInException(passbookUsername);
}
else if (!passphrases.get(passbookUsername).equals(passphrase)) {
throw new IncorrectPassphraseException(passbookUsername, passphrase);
}
//generate a random session ID that is not already taken
int sessionID = new Random().nextInt(Integer.MAX_VALUE);
while (userIDs.containsKey(sessionID)) {
sessionID = new Random().nextInt(Integer.MAX_VALUE);
}
//add the session ID
sessionIDs.put(passbookUsername, sessionID);
userIDs.put(sessionID, passbookUsername);
return sessionID;
}
/**
* Logs out a user based on session ID. Has no affect if the session ID does not exist.
*
* @param sessionID the session ID to be terminated
*
* Assumption: session ID is non-null
*/
public void logoutUser(Integer sessionID)
{
sessionIDs.remove(userIDs.get(sessionID));
userIDs.remove(sessionID);
}
/**
* Updates the login details for a URL of a user. If the url
* username or password are null, the login details for this URL
* must be removed.
*
* @param sessionID the session ID for the logged-in user
* @param urlUsername the username for the user to be added
* @param url the URL for the username/password pair
* @param urlPassword the password to be add
* @throws InvalidSessionIDException if the session ID does not exists
* @throws MalformedURLException if the protocol is not 'http' or 'https'
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public void updateDetails(Integer sessionID, URL url, String urlUsername, String urlPassword)
throws InvalidSessionIDException, MalformedURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
if (urlUsername == null && urlPassword == null) {
pt.remove(url);
}
else {
pt.put(url, new Pair<String, String> (urlUsername, urlPassword));
details.put(passbookUsername, pt);
}
}
/**
* Retrieves login details for a given URL and user.
*
* @param sessionID the session ID
* @param url the URL for the password being retrieved.
* @returns the username and password for a given url for the corresponding user
* @throws NoSuchUserException if the username does not exist in the passbook
* @throws MalformedURLException if the syntax is invalid (see class documentation)
* @throws NoSuchURLException if user does not have login for this URL
*
* Assumption: url is non-null and a valid URL object
* Assumption: sessionID is non-null
*/
public Pair<String, String> retrieveDetails(Integer sessionID, URL url)
throws InvalidSessionIDException, MalformedURLException, NoSuchURLException
{
//check that the session ID exists
String passbookUsername = userIDs.get(sessionID);
if (passbookUsername == null) {
throw new InvalidSessionIDException(sessionID);
}
else if (!Arrays.asList(VALID_URL_PROTOCOLS).contains(url.getProtocol())) {
throw new MalformedURLException(passbookUsername);
}
PasswordTable pt = details.get(passbookUsername);
//if this returned nothing, the user has no details for any url
if (pt == null) {
throw new NoSuchURLException(passbookUsername, url);
}
Pair<String, String> pair = pt.get(url);
//if this returned nothing, the user does not have a login for this url
if (pair == null) {
throw new NoSuchURLException(passbookUsername, url);
}
return pair;
}
//A simple label to improve code readability
private class PasswordTable extends HashMap<URL, Pair<String, String>> {}
}
package swen90006.passbook;
public class WeakPassphraseException extends Exception
{
public WeakPassphraseException (String passphrase)
{
super("Passphrase does not comply with the PassBook rules\n" +
"\t- must contains at least " +
PassBook.MINIMUM_PASSPHRASE_LENGTH + " characters\n" +
"\t- must contain at least one numeric character\n" +
"\t- must contain at least one lower case letter\n" +
"\t- must contain at least one upper case letter\n");
}
}
......@@ -69,164 +69,7 @@ public class PartitioningTests
assertTrue(WeakPassphraseException);
}
/* //Passphrase = 8
@Test public void WeakPassphraseException2() throws DuplicateUserException{
boolean WeakPassphraseException = false;
String passbookUsername = "AlexTina";
String passbookphrase = "Ab23sda2";
try{
pb.addUser(passbookUsername,passbookphrase);
}
catch (WeakPassphraseException e){
WeakPassphraseException = true;
}
assertFalse(WeakPassphraseException);
}
//Passphrase > 8
@Test public void WeakPassphraseException3() throws DuplicateUserException{
boolean WeakPassphraseException = false;
String passbookUsername = "AlexTina";
String passbookphrase = "Ab23sda2dsaldaskljdkasl";
try{
pb.addUser(passbookUsername,passbookphrase);
}
catch (WeakPassphraseException e){
WeakPassphraseException = true;
}
assertFalse(WeakPassphraseException);
}
// passphrase.length = 8 && passphrase only contain one kind factory in Lower, Upper and Number
@Test public void Contains() throws DuplicateUserException
{
boolean WeakPassphraseException = false;
String passbookUsername = "AlexTina";
String passbookphrase = "AAAABBBC";
try{
pb.addUser(passbookUsername,passbookphrase);
}
catch (WeakPassphraseException e){
WeakPassphraseException = true;
}
assertTrue(WeakPassphraseException);
}
// passphrase.length = 8 && passphrase only contain two kind factory in Lower, Upper and Number
@Test public void Contains2() throws DuplicateUserException
{
boolean WeakPassphraseException = false;
String passbookUsername = "AlexTina";
String passbookphrase = "AAA2232C";
try{
pb.addUser(passbookUsername,passbookphrase);
}
catch (WeakPassphraseException e){
WeakPassphraseException = true;
}
assertTrue(WeakPassphraseException);
}
// passphrase.length = 8 && passphrase contain no kind factory in Lower, Upper and Number
@Test public void Contains3() throws DuplicateUserException
{
boolean WeakPassphraseException = false;
String passbookUsername = "AlexTina";
String passbookphrase = "'{@[/:Cd";
try{
pb.addUser(passbookUsername,passbookphrase);
}
catch (WeakPassphraseException e){
WeakPassphraseException = true;
}
assertTrue(WeakPassphraseException);
}
// passphrase.length = 8 && passphrase contain all kinds factory in Lower, Upper and Number
@Test public void Contains4() throws DuplicateUserException
{
boolean WeakPassphraseException = false;
String passbookUsername = "AlexTina";
String passbookphrase = "Ab23cd54";
try{
pb.addUser(passbookUsername,passbookphrase);
}
catch (WeakPassphraseException e){
WeakPassphraseException = true;
}
assertFalse(WeakPassphraseException);
}
// passphrase.length > 8 && passphrase only contain one kind factory in Lower, Upper and Number
@Test public void Contains5() throws DuplicateUserException
{
boolean WeakPassphraseException = false;
String passbookUsername = "AlexTina";
String passbookphrase = "123456789212";
try{
pb.addUser(passbookUsername,passbookphrase);
}
catch (WeakPassphraseException e){
WeakPassphraseException = true;
}
assertTrue(WeakPassphraseException);
}
// passphrase.length > 8 && passphrase only contain two kind factory in Lower, Upper and Number
@Test public void Contains6() throws DuplicateUserException
{
boolean WeakPassphraseException = false;
String passbookUsername = "AlexTina";
String passbookphrase = "AAA223293289312C";
try{
pb.addUser(passbookUsername,passbookphrase);
}
catch (WeakPassphraseException e){
WeakPassphraseException = true;
}
assertTrue(WeakPassphraseException);
}
// passphrase.length > 8 && passphrase contain no kind factory in Lower, Upper and Number
@Test public void Contains7() throws DuplicateUserException
{
boolean WeakPassphraseException = false;
String passbookUsername = "AlexTina";
String passbookphrase = "^&*($%@#%^&*(";
try{
pb.addUser(passbookUsername,passbookphrase);
}
catch (WeakPassphraseException e){
WeakPassphraseException = true;
}
assertTrue(WeakPassphraseException);
}
// passphrase.length > 8 && passphrase contain all kinds factory in Lower, Upper and Number
@Test public void Contains8() throws DuplicateUserException
{
boolean WeakPassphraseException = false;
String passbookUsername = "AlexTina";
String passbookphrase = "Ab23cd54vhuy67";
try{
pb.addUser(passbookUsername,passbookphrase);
}
catch (WeakPassphraseException e){
WeakPassphraseException = true;
}
assertFalse(WeakPassphraseException);
}
*/
//passphrase.length >=8 not containsLowerCase
@Test public void NocontainLowerCase() throws DuplicateUserException {
boolean WeakPassphraseException = false;
......@@ -318,12 +161,11 @@ public class PartitioningTests
boolean AlreadyLoggedInException = false;
String passbookUsername = "AlexTina";
String passbookphrase = "Abc234hg";
String passbookUsername2 = "AlexTina";
String passbookphrase2 = "Abc234hg";
try{
pb.addUser(passbookUsername,passbookphrase);
pb.loginUser(passbookUsername,passbookphrase);
pb.loginUser(passbookUsername2,passbookphrase2);
pb.loginUser(passbookUsername,passbookphrase);
}
catch (AlreadyLoggedInException e){
AlreadyLoggedInException = true;
......@@ -331,26 +173,7 @@ public class PartitioningTests
assertTrue(AlreadyLoggedInException);
}
/* //user has not login
@Test public void AlreadyLoggedInException2() throws NoSuchUserException, IncorrectPassphraseException, WeakPassphraseException, DuplicateUserException {
boolean AlreadyLoggedInException = false;
String passbookUsername = "AlexTina";
String passbookphrase = "Abc234hg";
try{
pb.addUser(passbookUsername,passbookphrase);
pb.loginUser(passbookUsername,passbookphrase);
}
catch (AlreadyLoggedInException e){
AlreadyLoggedInException = true;
}
assertFalse(AlreadyLoggedInException);
}
*/
//passphrase is not equale to the saved one
@Test public void IncorrectPassphraseException() throws WeakPassphraseException, DuplicateUserException, AlreadyLoggedInException, IncorrectPassphraseException, NoSuchUserException {
boolean IncorrectPassphraseException = false;
......@@ -419,28 +242,7 @@ public class PartitioningTests
//MalformedURLException
/*
//Protocol = [http,https]
@Test public void MalformedURLException() throws MalformedURLException, WeakPassphraseException, DuplicateUserException, NoSuchUserException, AlreadyLoggedInException, IncorrectPassphraseException, InvalidSessionIDException {
boolean MalformedURLException = false;
Integer sessionID ;
String Username = "AlexTina";
String Password = "Abc234hg";
String urlUsername = "AlexTina";
String urlPassword = "Abc234hg";
pb.addUser(Username,Password);
sessionID = pb.loginUser(Username,Password);
try{
URL url = new URL ("http:AlexTinaAbc234hg");
pb.updateDetails(sessionID,url,urlUsername,urlPassword);
}catch (MalformedURLException e){
MalformedURLException = true;
}
assertFalse(MalformedURLException);
}
*/
//Protocol != [http,https]
@Test public void MalformedURLException2() throws MalformedURLException, WeakPassphraseException, DuplicateUserException, NoSuchUserException, AlreadyLoggedInException, IncorrectPassphraseException, InvalidSessionIDException {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment