Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
S
SWEN90006-A1-2019
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Tim Miller
SWEN90006-A1-2019
Merge requests
!17
Update PassBook.java
Code
Review changes
Check out branch
Download
Patches
Plain diff
Open
Update PassBook.java
XCC2/swen90006-a1-2019:patch-7
into
master
Overview
0
Commits
1
Pipelines
0
Changes
1
Open
Xi Chen
requested to merge
XCC2/swen90006-a1-2019:patch-7
into
master
5 years ago
Overview
0
Commits
1
Pipelines
0
Changes
1
Expand
0
0
Merge request reports
Compare
master
master (HEAD)
and
latest version
latest version
66b76c88
1 commit,
5 years ago
1 file
+
207
−
222
Inline
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
programs/mutant-4/swen90006/passbook/PassBook.java
+
207
−
222
Options
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.
net.URL
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Random
;
/**
* PassBook is a (fictional) online password manager. A password
*
manager is a
software application that generates, stores, and
*
retrieves login details for
users.
* 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.
* 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'.
* 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.
* 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.
* 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
;
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
;
/** Valid URL protocols for the passbook */
public
final
static
String
[]
VALID_URL_PROTOCOLS
=
{
"http"
,
"https"
};
//Mapping from session IDs to
user
name
s
private
Map
<
Integer
,
String
>
userID
s
;
// The passphrases (master passwords) for all
users
private
Map
<
String
,
String
>
passphrase
s
;
//Mapping from usernames to sessionIDs
private
Map
<
String
,
Integer
>
sessionID
s
;
// The login details for all users and the URLs they have stored
private
Map
<
String
,
PasswordTable
>
detail
s
;
/**
* 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
>();
}
// Mapping from session IDs to usernames
private
Map
<
Integer
,
String
>
userIDs
;
/**
* 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
);
// 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
>();
}
//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
;
/**
* 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
);
}
else
if
(
'0'
<=
passphrase
.
charAt
(
i
)
&&
passphrase
.
charAt
(
i
)
<=
'9'
)
{
containsNumber
=
true
;
// 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
);
}
}
}
if
(!
containsLowerCase
||
!
containsUpperCase
||
!
containsNumber
)
{
throw
new
WeakPassphraseException
(
passphrase
);
}
passphrases
.
put
(
passbookUsername
,
passphrase
);
PasswordTable
pt
=
new
PasswordTable
(
);
details
.
put
(
passbookUsername
,
pt
);
}
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
);
/**
* 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
);
}
//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
);
}
/**
* 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
);
}
//add the session ID
sessionIDs
.
put
(
passbookUsername
,
sessionID
);
userIDs
.
put
(
sessionID
,
passbookUsername
);
return
sessionID
;
}
// 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
);
}
/**
* 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
);
}
// add the session ID
sessionIDs
.
put
(
passbookUsername
,
sessionID
);
userIDs
.
put
(
sessionID
,
passbookUsername
);
/**
* 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
);
return
sessionID
;
}
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
);
/**
* 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
);
}
/**
* 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
(
urlUsername
==
null
&&
urlPassword
==
null
)
{
pt
.
remove
(
url
);
}
else
{
pt
.
put
(
url
,
new
Pair
<
String
,
String
>(
urlUsername
,
urlPassword
));
details
.
put
(
passbookUsername
,
pt
);
}
}
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
);
}
/**
* 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
);
}
Pair
<
String
,
String
>
pair
=
pt
.
get
(
url
);
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
);
}
//if this returned nothing, the user does not have a login for this url
if
(
pair
==
null
)
{
throw
new
NoSuchURLException
(
passbookUsername
,
url
);
}
Pair
<
String
,
String
>
pair
=
pt
.
get
(
url
);
return
pair
;
}
// if this returned nothing, the user does not have a login for this url
if
(
pair
==
null
)
{
throw
new
NoSuchURLException
(
passbookUsername
,
url
);
}
//A simple label to improve code readability
private
class
PasswordTable
extends
HashMap
<
URL
,
Pair
<
String
,
String
>>
{}
return
pair
;
}
// A simple label to improve code readability
private
class
PasswordTable
extends
HashMap
<
URL
,
Pair
<
String
,
String
>>
{
}
}
Loading