package dev.peerat.backend.repository; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import com.password4j.Password; import dev.peerat.backend.Configuration; public class DatabaseAuthRepository extends BaseDatabaseQuery{ private static enum Query{ // REGISTER CHECK_PSEUDO_AVAILABLE_QUERY("SELECT * FROM players WHERE pseudo = ?"), CHECK_EMAIL_AVAILABLE_QUERY("SELECT * FROM players WHERE email = ?"), REGISTER_QUERY( "INSERT INTO players (pseudo, email, passwd, firstname, lastname, description, avatar) VALUES (?, ?, ?, ?, ?, ?, ?)"), REGISTER_PLAYER_IN_EXISTING_GROUP( "INSERT INTO containsGroups (fk_player, fk_group) VALUES (?, (SELECT id_group FROM groups WHERE name = ?));"), // LOGIN CHECK_PASSWORD("SELECT id_player, passwd FROM players WHERE pseudo=?"); private String request; Query(Query parent, String request) { this.request = parent.request + request; } Query(String request) { this.request = request; } public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException { return base.prepare(this.request); } @Override public String toString() { return this.request; } } private Configuration config; public DatabaseAuthRepository(Connection con, Configuration config){ super(con, config); this.config = config; } /** * 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, Query.CHECK_PSEUDO_AVAILABLE_QUERY.toString()); } /** * 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, Query.CHECK_EMAIL_AVAILABLE_QUERY.toString()); } private boolean checkAvailability(String queriedString, String correspondingQuery) { try { ensureConnection(); 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 int register(String pseudo, String email, String password, String firstname, String lastname, String description, String sgroup, String avatar) { try { String pass = Password.hash(password).withArgon2().getResult(); System.out.println("pass("+pass.length()+") "+pass); ensureConnection(); con.setAutoCommit(false); try (PreparedStatement playerStatement = con.prepareStatement(Query.REGISTER_QUERY.toString(), Statement.RETURN_GENERATED_KEYS)) { playerStatement.setString(1, pseudo); playerStatement.setString(2, email); playerStatement.setString(3, Password.hash(password).withArgon2().getResult()); playerStatement.setString(4, firstname); playerStatement.setString(5, lastname); playerStatement.setString(6, description); playerStatement.setString(7, avatar); if (playerStatement.executeUpdate() == 1) { ResultSet inserted = playerStatement.getGeneratedKeys(); if (inserted.next()) { int newPlayerId = inserted.getInt(1); if (!sgroup.isEmpty()) { try (PreparedStatement containsGroupsStatement = con .prepareStatement(Query.REGISTER_PLAYER_IN_EXISTING_GROUP.toString())) { containsGroupsStatement.setInt(1, newPlayerId); containsGroupsStatement.setString(2, sgroup); containsGroupsStatement.executeUpdate(); } } con.commit(); con.setAutoCommit(true); return newPlayerId; } } } catch (SQLException e) { con.rollback(); con.setAutoCommit(true); e.printStackTrace(); } } catch (SQLException e) { e.printStackTrace(); } return -1; } /** * Login a user * * @param username The username of the user * @param password The password of the user * @return id the id of the user, -1 if not login successefuly */ public int login(String username, String password) { try { ensureConnection(); PreparedStatement statement = con.prepareStatement(Query.CHECK_PASSWORD.toString()); statement.setString(1, username); ResultSet result = statement.executeQuery(); if (result.next()) { String hashedPassword = result.getString("passwd"); if (Password.check(password, hashedPassword).withArgon2()) return result.getInt("id_player"); } } catch (SQLException e) { } return -1; } }