Files
INSServer/frontend/utils/UserDao.java
UnlegitDqrk 64ce55ea7b Finished
2026-02-11 23:22:20 +01:00

154 lines
5.0 KiB
Java

package ins.frontend.utils;
import org.openautonomousconnection.webserver.utils.Sha256;
import java.sql.*;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
/**
* DAO for users table:
* users(id, uid(uuid string), username(sha256 hex or plain), password(pbkdf2...))
*/
public final class UserDao {
private final DataSourceProvider dataSource;
/**
* Creates a UserDao.
*
* @param dataSource connection provider
*/
public UserDao(DataSourceProvider dataSource) {
this.dataSource = Objects.requireNonNull(dataSource, "dataSource");
}
/**
* Finds a user by username.
*
* @param uid exact uid match
* @return optional row
* @throws SQLException on SQL errors
*/
public Optional<UserRow> findByUid(UUID uid) throws SQLException {
if (uid == null) return Optional.empty();
String sql = "SELECT id, uid, username, password FROM users WHERE uid = ? LIMIT 1";
try (Connection c = dataSource.getConnection();
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, uid.toString());
try (ResultSet rs = ps.executeQuery()) {
if (!rs.next()) return Optional.empty();
return Optional.of(new UserRow(
rs.getInt("id"),
rs.getString("uid"),
rs.getString("username"),
rs.getString("password")
));
}
}
}
/**
* Creates a new user.
*
* @param uid uuid string (36 chars)
* @param username username string (your choice: raw or sha256 hex)
* @param passwordEncoded encoded password
* @return generated users.id
* @throws SQLException on SQL errors
*/
public int createUser(String uid, String username, String passwordEncoded) throws SQLException {
if (uid == null || uid.isBlank()) throw new IllegalArgumentException("uid must not be blank");
if (username == null || username.isBlank()) throw new IllegalArgumentException("username must not be blank");
if (passwordEncoded == null || passwordEncoded.isBlank())
throw new IllegalArgumentException("passwordEncoded must not be blank");
String sql = "INSERT INTO users (uid, username, password) VALUES (?, ?, ?)";
try (Connection c = dataSource.getConnection();
PreparedStatement ps = c.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
ps.setString(1, uid);
ps.setString(2, Sha256.hex(username));
ps.setString(3, passwordEncoded);
ps.executeUpdate();
try (ResultSet rs = ps.getGeneratedKeys()) {
if (rs.next()) return rs.getInt(1);
}
}
throw new SQLException("No generated key returned for users.id");
}
/**
* Convenience: creates a user with a new random UUID.
*
* @param username username
* @param passwordEncoded encoded password
* @return generated users.id
* @throws SQLException on SQL errors
*/
public int createUserWithNewUuid(String username, String passwordEncoded) throws SQLException {
UUID uuid = UUID.randomUUID();
while (findByUid(uuid).isPresent()) uuid = UUID.randomUUID();
return createUser(uuid.toString(), username, passwordEncoded);
}
/**
* Finds a user by username.
*
* @param username exact username match
* @return optional row
* @throws SQLException on SQL errors
*/
public Optional<UserRow> findByUsername(String username) throws SQLException {
if (username == null || username.isBlank()) return Optional.empty();
username = Sha256.hex(username);
String sql = "SELECT id, uid, username, password FROM users WHERE username = ? LIMIT 1";
try (Connection c = dataSource.getConnection();
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, username);
try (ResultSet rs = ps.executeQuery()) {
if (!rs.next()) return Optional.empty();
return Optional.of(new UserRow(
rs.getInt("id"),
rs.getString("uid"),
rs.getString("username"),
rs.getString("password")
));
}
}
}
/**
* Connection provider abstraction.
*/
public interface DataSourceProvider {
/**
* @return open SQL connection
* @throws SQLException on errors
*/
Connection getConnection() throws SQLException;
}
/**
* User row.
*
* @param id users.id
* @param uid users.uid (uuid)
* @param username users.username
* @param passwordEncoded users.password
*/
public record UserRow(int id, String uid, String username, String passwordEncoded) {
}
}