Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 32 additions & 19 deletions backend/src/main/java/edu/gcc/hallmonitor/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
public class User {
private String username;
private byte[] passwordHash;
private int id;
private int gradYear;
private Connection connection;

/**
* Basic constructor that sets the username and password hash. NOTE: YOU SHOULD USE THE authenticate() METHOD
* Basic constructor that sets the username and password hash. NOTE: YOU SHOULD USE THE login() or signUp() METHOD
* FOR CREATING NEW USERS WHICH IN TURN CALLS THIS FUNCTION. YOU SHOULD PRIMARILY USE THIS METHOD BY ITSELF
* FOR TESTING THE METHODS THAT GO INTO authenticate().
* FOR TESTING THE METHODS THAT GO INTO login() and signUp().
* @param username the username of the user
* @param password the password of the user
* @throws IllegalArgumentException if the username or password are empty
Expand Down Expand Up @@ -57,27 +58,26 @@ public void setGradYear(int gradYear) {
this.gradYear = gradYear;
}

/**
* Validate that the username and password are in the database. If they are not, validate that the username
* is not taken already. If it is not, add the user. The user object is then returned.
* @param username the username to authenticate
* @param password the password to authenticate
* @return an authenticated User object
* @throws IllegalArgumentException if the username or password are empty
* @throws SecurityException if the user cannot be authenticated
* @throws SQLException if there is an error with the database connection
*/
public static User authenticate(String username, String password) throws IllegalArgumentException, SecurityException, SQLException {
public static User login(String username, String password) throws SQLException {
User user = new User(username, password);

// If they are not a user and they can't successfully be added, throw an error
if (!user.isUser() && !user.addUser()) {
throw new SecurityException(
String.format("Unable to add user '%s'", username)
);
if (user.isUser()) {
user.id = user.getIdFromDatabase();
return user;
} else {
throw new SecurityException("Username and password not found");
}
}

return user;
public static User signup(String username, String password) throws SQLException {
User user = new User(username, password);

if (user.addUser()) {
user.id = user.getIdFromDatabase();
return user;
} else {
throw new SecurityException("Username and password are taken");
}
}

/**
Expand All @@ -99,6 +99,19 @@ public boolean isUser() throws SQLException {
return rs.next();
}

public int getIdFromDatabase() throws SQLException {
PreparedStatement prepStatement = connection.prepareStatement(
"SELECT id FROM public.\"users\"" +
"WHERE username = ? AND password_hash = ?"
);
prepStatement.setString(1, username);
prepStatement.setBytes(2, passwordHash);
ResultSet rs = prepStatement.executeQuery();
rs.next();

return rs.getInt(1);
}

/**
* Checks if the current username member variable is in use in the database
* @return if the username is already used
Expand Down
49 changes: 17 additions & 32 deletions backend/src/test/java/edu/gcc/hallmonitor/UserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -159,47 +159,32 @@ public void deleteUserTest() {
}

@Test
public void authenticateCurrentUser() {
try {
User.authenticate("testuser", "password");
} catch (IllegalArgumentException iae) {
fail(); // username and password aren't empty, so shouldn't happen
} catch (SecurityException se) {
fail(); // username and password should be in the database, so shouldn't happen
} catch (SQLException sqle) {
fail(sqle.getMessage());
}
public void loginUserInDatabase() throws SQLException {
User.login("testuser", "password");
}

@Test
public void authenticateNewUser() {
String username;
try {
username = getUnusedUsername();
User newUser = User.authenticate(username, "1234");

assertTrue(newUser.isUser());
public void loginUserNotInDatabase() {
assertThrows(SecurityException.class, () -> User.login("testuser", "notapassword"));
}

// Delete the user we added
PreparedStatement prepStatement = connection.prepareStatement(
"DELETE FROM public.\"users\" WHERE username = ? AND password_hash = ?"
);
prepStatement.setString(1, newUser.getUsername());
prepStatement.setBytes(2, newUser.getPasswordHash());
prepStatement.execute();
@Test
public void signUpUserNotInDatabase() throws SQLException {
User user = User.signup(getUnusedUsername(), "password");

} catch (SQLException sqle) {
fail(sqle.getMessage());
}
assertTrue(user.isUser());

PreparedStatement prepStatement = connection.prepareStatement(
"DELETE FROM public.\"users\" WHERE username = ? AND password_hash = ?"
);
prepStatement.setString(1, user.getUsername());
prepStatement.setBytes(2, user.getPasswordHash());
prepStatement.execute();
}

@Test
public void authenticateNewUserWithTakenUsername() throws SQLException {
String usedUsername = getUsedUsername();

assertThrows(SecurityException.class, () -> User.authenticate(usedUsername, "1234"));

public void signUpUserInDatabase() {
assertThrows(SecurityException.class, () -> User.signup("testuser", "notapassword"));
}

@Test
Expand Down
Loading