Add rate limiting functionality
Introduces a new 'rate_limit' table to track request counts by IP and email. Adds `RateLimitQuery` class for querying and inserting rate limits, and `RateLimitEntryDTO` for passing rate limit data.
This commit is contained in:
parent
4f3db5ae8b
commit
f0c84e809f
|
|
@ -12,8 +12,35 @@ public class Database {
|
|||
|
||||
public static void createTables() {
|
||||
String[] createTables = {
|
||||
"CREATE TABLE IF NOT EXISTS verify_form (e_mail VARCHAR(256), verification_code INT, formId INT, PRIMARY KEY(e_mail, verification_code))",
|
||||
"CREATE TABLE IF NOT EXISTS form (formId INT AUTO_INCREMENT, creation_date BIGINT, form_json TEXT, form_class VARCHAR(64), PRIMARY KEY(formId))"
|
||||
// language=SQL
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS verify_form(
|
||||
e_mail VARCHAR(256),
|
||||
verification_code INT,
|
||||
formId INT,
|
||||
PRIMARY KEY(e_mail, verification_code)
|
||||
)
|
||||
""",
|
||||
// language=SQL
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS form(
|
||||
formId INT AUTO_INCREMENT,
|
||||
creation_date BIGINT,
|
||||
form_json TEXT,
|
||||
form_class VARCHAR(64),
|
||||
PRIMARY KEY(formId)
|
||||
)
|
||||
""",
|
||||
// language=SQL
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS rate_limit(
|
||||
id INT AUTO_INCREMENT,
|
||||
time TIMESTAMP,
|
||||
ip VARCHAR(45),
|
||||
mail VARCHAR(256),
|
||||
PRIMARY KEY(id)
|
||||
)
|
||||
"""
|
||||
};
|
||||
Connection connection = DatabaseConnection.getConnection();
|
||||
for (String query : createTables) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
package com.alttd.forms.mail.rate_limitter;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public record RateLimitEntryDTO(Instant time, String ip, String mail) {
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package com.alttd.forms.mail.rate_limitter;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.*;
|
||||
import java.time.Instant;
|
||||
|
||||
public class RateLimitQuery {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(RateLimitQuery.class);
|
||||
|
||||
public int getIpHits(Connection connection, String ip, Instant after) throws SQLException {
|
||||
String sql = "SELECT COUNT(*) AS hits FROM rate_limit WHERE ip = ? AND time > ?";
|
||||
try (PreparedStatement stmt = connection.prepareStatement(sql)) {
|
||||
stmt.setString(1, ip);
|
||||
stmt.setTimestamp(2, Timestamp.from(after));
|
||||
ResultSet resultSet = stmt.executeQuery();
|
||||
if (!resultSet.next()) {
|
||||
return 0;
|
||||
}
|
||||
return resultSet.getInt("hits");
|
||||
} catch (SQLException e) {
|
||||
logger.error("Failed get ip hits query for ip: {}", ip, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public int getMailHits(Connection connection, String mail, Instant after) throws SQLException {
|
||||
String sql = "SELECT COUNT(*) AS hits FROM rate_limit WHERE mail = ? AND time > ?";
|
||||
try (PreparedStatement stmt = connection.prepareStatement(sql)) {
|
||||
stmt.setString(1, mail);
|
||||
stmt.setTimestamp(2, Timestamp.from(after));
|
||||
ResultSet resultSet = stmt.executeQuery();
|
||||
if (!resultSet.next()) {
|
||||
return 0;
|
||||
}
|
||||
return resultSet.getInt("hits");
|
||||
} catch (SQLException e) {
|
||||
logger.error("Failed get mail hits query for ip: {}", mail, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean insertRateLimitEntry(Connection connection, RateLimitEntryDTO entry) throws SQLException {
|
||||
String sql = "INSERT INTO rate_limit (time, ip, mail) VALUES (?, ?, ?)";
|
||||
try {
|
||||
PreparedStatement stmt = connection.prepareStatement(sql);
|
||||
stmt.setTimestamp(1, Timestamp.from(entry.time()));
|
||||
stmt.setString(2, entry.ip());
|
||||
stmt.setString(3, entry.mail());
|
||||
return stmt.executeUpdate() > 0;
|
||||
} catch (SQLException e) {
|
||||
logger.error("Failed to store rate limit for ip: {}, mail: {}, time: {}", entry.ip(), entry.mail(), entry.time(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user