diff --git a/password4j-1.6.3.jar b/password4j-1.6.3.jar new file mode 100644 index 0000000..4254563 Binary files /dev/null and b/password4j-1.6.3.jar differ diff --git a/src/be/jeffcheasey88/peeratcode/repository/DatabaseRepository.java b/src/be/jeffcheasey88/peeratcode/repository/DatabaseRepository.java index c5133b1..6143027 100644 --- a/src/be/jeffcheasey88/peeratcode/repository/DatabaseRepository.java +++ b/src/be/jeffcheasey88/peeratcode/repository/DatabaseRepository.java @@ -2,6 +2,8 @@ package be.jeffcheasey88.peeratcode.repository; import be.jeffcheasey88.peeratcode.model.Chapter; import be.jeffcheasey88.peeratcode.model.Puzzle; +import com.password4j.Hash; +import com.password4j.Password; import java.sql.Connection; import java.sql.PreparedStatement; @@ -10,12 +12,16 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; -public class DatabaseRepository { - +public class DatabaseRepo { private static final String SPECIFIC_PUZZLE_QUERY = "SELECT * FROM puzzles WHERE id_puzzle = ?"; private static final String SPECIFIC_CHAPTER_QUERY = "SELECT * FROM chapters WHERE id_chapter = ?"; private static final String PUZZLES_IN_CHAPTER_QUERY = "SELECT * FROM puzzles WHERE fk_chapter = ?"; private static final String ALL_CHAPTERS_QUERY = "SELECT * FROM chapters"; + private static final String CHECK_PSEUDO_AVAILABLE_QUERY = "SELECT * FROM players WHERE pseudo = ?"; + private static final String CHECK_EMAIL_AVAILABLE_QUERY = "SELECT * FROM players WHERE email = ?"; + private static final String REGISTER_QUERY = "INSERT INTO players (pseudo, email, passwd, firstname, lastname, description, sgroup, avatar) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; + private static final String PASSWORD_FOR_EMAIL_QUERY = "SELECT passwd FROM players WHERE pseudo = ?"; + private final Connection con; public DatabaseRepository(Connection con) { @@ -105,4 +111,91 @@ public class DatabaseRepository { } return null; } + + /** + * Check if a pseudo is available + * + * @param pseudo The pseudo to check + * @return True if the pseudo is available, false if it's already taken + */ + public boolean checkPseudoAvailability(String pseudo) { + return checkAvailability(pseudo, CHECK_PSEUDO_AVAILABLE_QUERY); + } + + /** + * Check if an email is available + * + * @param email The email to check + * @return True if the email is available, false if it's already taken + */ + public boolean checkEmailAvailability(String email) { + return checkAvailability(email, CHECK_EMAIL_AVAILABLE_QUERY); + } + + private boolean checkAvailability(String queriedString, String correspondingQuery) { + try { + PreparedStatement statement = con.prepareStatement(correspondingQuery); + statement.setString(1, queriedString); + ResultSet result = statement.executeQuery(); + return !result.next(); + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } + + /** + * Register a new user + * + * @param pseudo The pseudo of the user + * @param email The email of the user + * @param password The password of the user + * @param firstname The firstname of the user + * @param lastname The lastname of the user + * @param description The description of the user + * @param sgroup The group of the user + * @param avatar The avatar of the user + * @return True if the user was registered, false if an error occurred + */ + public boolean register(String pseudo, String email, String password, String firstname, String lastname, String description, String sgroup, String avatar) { + Hash hash = Password.hash(password).withArgon2(); + try { + PreparedStatement statement = con.prepareStatement(REGISTER_QUERY); + statement.setString(1, pseudo); + statement.setString(2, email); + statement.setString(3, hash.toString()); + statement.setString(4, firstname); + statement.setString(5, lastname); + statement.setString(6, description); + statement.setString(7, sgroup); + statement.setString(8, avatar); + return statement.executeUpdate() == 1; + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } + + /** + * Login a user + * + * @param email The email of the user + * @param password The password of the user + * @return True if the user's information are correct, false otherwise (or if an error occurred) + */ + public boolean login(String email, String password) { + try { + PreparedStatement statement = con.prepareStatement(PASSWORD_FOR_EMAIL_QUERY); + statement.setString(1, email); + statement.setString(2, password); + ResultSet result = statement.executeQuery(); + if (result.next()) { + String hashedPassword = result.getString("passwd"); + return Password.check(password, hashedPassword).withArgon2(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } } \ No newline at end of file diff --git a/src/be/jeffcheasey88/peeratcode/routes/Login.java b/src/be/jeffcheasey88/peeratcode/routes/Login.java index 145eb3e..47ba762 100644 --- a/src/be/jeffcheasey88/peeratcode/routes/Login.java +++ b/src/be/jeffcheasey88/peeratcode/routes/Login.java @@ -11,30 +11,38 @@ import be.jeffcheasey88.peeratcode.webserver.HttpUtil; import be.jeffcheasey88.peeratcode.webserver.HttpWriter; import be.jeffcheasey88.peeratcode.webserver.Response; -public class Login implements Response{ - - private DatabaseRepository repo; - - public Login(DatabaseRepository repo){ - this.repo = repo; +public class Login implements Response { + + private final DatabaseRepo databaseRepo; + + public Login(DatabaseRepo databaseRepo) { + this.databaseRepo = databaseRepo; } @Override public void exec(Matcher matcher, HttpReader reader, HttpWriter writer) throws Exception { HttpUtil.skipHeaders(reader); - JSONObject json = (JSONObject) HttpUtil.readJson(reader); - - HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *"); + JSONObject informations = (JSONObject) HttpUtil.readJson(reader); + if (informations != null) { + String pseudo = (String) informations.get("pseudo"); + String password = (String) informations.get("passwd"); + boolean wellLogged = databaseRepo.login(pseudo, password); + if (!wellLogged) { + HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *"); + } else { + HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *"); + } + } } @Override public Pattern getPattern() { return Pattern.compile("^\\/login$"); } - + @Override public String getType(){ return "POST"; } -} \ No newline at end of file +} diff --git a/src/be/jeffcheasey88/peeratcode/routes/Register.java b/src/be/jeffcheasey88/peeratcode/routes/Register.java index 75e52de..36c5556 100644 --- a/src/be/jeffcheasey88/peeratcode/routes/Register.java +++ b/src/be/jeffcheasey88/peeratcode/routes/Register.java @@ -11,20 +11,55 @@ import be.jeffcheasey88.peeratcode.webserver.HttpUtil; import be.jeffcheasey88.peeratcode.webserver.HttpWriter; import be.jeffcheasey88.peeratcode.webserver.Response; -public class Register implements Response{ - - private DatabaseRepository repo; - - public Register(DatabaseRepository repo){ - this.repo = repo; +public class Register implements Response { + + private final DatabaseRepo databaseRepo; + + public Register(DatabaseRepo databaseRepo) { + this.databaseRepo = databaseRepo; } @Override public void exec(Matcher matcher, HttpReader reader, HttpWriter writer) throws Exception { HttpUtil.skipHeaders(reader); - JSONObject json = (JSONObject) HttpUtil.readJson(reader); - - HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *"); + JSONObject informations = (JSONObject) HttpUtil.readJson(reader); + if (informations != null) { + boolean allFieldsFilled = informations.containsKey("pseudo") && informations.containsKey("email") + && informations.containsKey("passwd") && informations.containsKey("firstname") + && informations.containsKey("lastname") && informations.containsKey("description") + && informations.containsKey("sgroup") && informations.containsKey("avatar"); + if (!allFieldsFilled) { + HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *"); + return; + } + String pseudo = (String) informations.get("pseudo"); + String email = (String) informations.get("email"); + String password = (String) informations.get("passwd"); + String firstname = (String) informations.get("firstname"); + String lastname = (String) informations.get("lastname"); + String description = (String) informations.get("description"); + String group = (String) informations.get("sgroup"); + String avatar = (String) informations.get("avatar"); + + boolean pseudoAvailable = databaseRepo.checkPseudoAvailability(pseudo); + boolean emailAvailable = databaseRepo.checkEmailAvailability(email); + if (pseudoAvailable && emailAvailable) { + boolean wellRegistered = databaseRepo.register(pseudo, email, password, firstname, lastname, description, group, avatar); + if (!wellRegistered) { + HttpUtil.responseHeaders(writer, 400, "Access-Control-Allow-Origin: *"); + writer.write("Error while registering"); + } else { + HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *"); + writer.write("OK"); + } + } else { + HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *"); + JSONObject error = new JSONObject(); + error.put("username_valid", pseudoAvailable); + error.put("email_valid", emailAvailable); + writer.write(error.toJSONString()); + } + } } @Override