Refactor rate-limiting and name history queries.

Removed redundant rate-limit response headers and improved query methods for fetching punishment history. Refactored methods to handle cases where partial names are empty and added escaping for underscores in search names.
This commit is contained in:
Teriuihi 2025-04-18 18:33:47 +02:00
parent e3eaab708c
commit a01038e86c
2 changed files with 157 additions and 33 deletions

View File

@ -71,13 +71,6 @@ public class RateLimitAspect {
Duration nextResetTime = rateLimiterService.getNextResetTime(key, duration); Duration nextResetTime = rateLimiterService.getNextResetTime(key, duration);
if (response != null) {
response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
response.setHeader("X-Rate-Limit-Limit", String.valueOf(limit));
response.setHeader("X-Rate-Limit-Remaining", "0");
response.setHeader("Retry-After", String.valueOf(nextResetTime.getSeconds()));
}
return ResponseEntity return ResponseEntity
.status(HttpStatus.TOO_MANY_REQUESTS) .status(HttpStatus.TOO_MANY_REQUESTS)
.header("X-Rate-Limit-Limit", String.valueOf(limit)) .header("X-Rate-Limit-Limit", String.valueOf(limit))

View File

@ -36,18 +36,78 @@ public interface NameHistoryMapper {
@Result(property = "type", column = "type") @Result(property = "type", column = "type")
}) })
@Select(""" @Select("""
SELECT all_punishments.uuid, user_lookup.name AS punished_name, reason, banned_by_uuid, banned_by_name, SELECT all_punishments.uuid,
removed_by_name, time, until, removed_by_reason, type user_lookup.name AS punished_name,
reason,
banned_by_uuid,
banned_by_name,
removed_by_name,
time,
until,
removed_by_reason,
type
FROM all_punishments FROM all_punishments
INNER JOIN user_lookup INNER JOIN user_lookup
ON user_lookup.uuid = all_punishments.uuid ON user_lookup.uuid = all_punishments.uuid
WHERE ${name_column} LIKE #{partialName} WHERE ${name_column} LIKE #{partialName}
ORDER BY time DESC ORDER BY time DESC
LIMIT #{limit} OFFSET #{offset} LIMIT #{limit} OFFSET #{offset}
""") """)
List<HistoryRecord> getRecentAllHistory(@Param("partialName") String partialName, List<HistoryRecord> getRecentAllHistoryForName(@Param("partialName") String partialName,
@Param("name_column") String nameColumn, @Param("name_column") String nameColumn,
@Param("limit") int limit, @Param("limit") int limit,
@Param("offset") int offset);
/**
* Retrieves a list of all types of recent punishment history records sorted
* in descending time order. This result does NOT contain kicks history
*
* @param nameColumn the column name in the database indicating the name to use for filtering
* @param limit the maximum number of records to fetch
* @param offset the starting offset position of the result set
*
* @return a list of {@link HistoryRecord} objects that match the specified filters, ordered by time in descending
* order
*/
@Results({
@Result(property = "uuid", column = "uuid"),
@Result(property = "punishedName", column = "punished_name"),
@Result(property = "reason", column = "reason"),
@Result(property = "bannedByUuid", column = "banned_by_uuid"),
@Result(property = "bannedByName", column = "banned_by_name"),
@Result(property = "removedByName", column = "removed_by_name"),
@Result(property = "time", column = "time"),
@Result(property = "until", column = "until"),
@Result(property = "removedByReason", column = "removed_by_reason"),
@Result(property = "type", column = "type")
})
@Select("""
SELECT punishments.uuid,
user_lookup.name AS punished_name,
punishments.reason,
punishments.banned_by_uuid,
punishments.banned_by_name,
punishments.removed_by_name,
punishments.time,
punishments.until,
punishments.removed_by_reason,
punishments.type
FROM (SELECT uuid,
reason,
banned_by_uuid,
banned_by_name,
removed_by_name,
time,
until,
removed_by_reason,
type
FROM all_punishments
ORDER BY time DESC
LIMIT #{limit} OFFSET #{offset}) AS punishments
INNER JOIN user_lookup
ON user_lookup.uuid = punishments.uuid;
""")
List<HistoryRecord> getRecentAllHistory(@Param("limit") int limit,
@Param("offset") int offset); @Param("offset") int offset);
/** /**
@ -75,19 +135,80 @@ public interface NameHistoryMapper {
@Result(property = "removedByReason", column = "removed_by_reason") @Result(property = "removedByReason", column = "removed_by_reason")
}) })
@Select(""" @Select("""
SELECT punishment.uuid, user_lookup.name AS punished_name, reason, banned_by_uuid, banned_by_name, SELECT punishment.uuid,
removed_by_name, time, until, removed_by_reason user_lookup.name AS punished_name,
reason,
banned_by_uuid,
banned_by_name,
removed_by_name,
time,
until,
removed_by_reason
FROM ${tableName} AS punishment FROM ${tableName} AS punishment
INNER JOIN user_lookup ON user_lookup.uuid = punishment.uuid INNER JOIN user_lookup ON user_lookup.uuid = punishment.uuid
WHERE ${name_column} LIKE #{partialName} WHERE ${name_column} LIKE #{partialName}
ORDER BY time DESC ORDER BY time DESC
LIMIT #{limit} OFFSET #{offset} LIMIT #{limit} OFFSET #{offset}
""") """)
List<HistoryRecord> getRecentHistoryForName(@Param("tableName") String tableName,
@Param("partialName") String partialName,
@Param("name_column") String nameColumn,
@Param("limit") int limit,
@Param("offset") int offset);
/**
* Retrieves a list of a specific type of recent punishment history records filtered based on the provided
* parameters. The records are sorted in descending order by time and limited to a specified range.
*
* @param tableName the name of the database table to query the history records from
* @param partialName a partial or complete name of the user to filter the records, case-insensitive
* @param nameColumn the column name in the database indicating the name to use for filtering
* @param limit the maximum number of records to fetch
* @param offset the starting offset position of the result set
*
* @return a list of {@link HistoryRecord} objects that match the specified filters, sorted by time in descending
* order
*/
@Results({
@Result(property = "uuid", column = "uuid"),
@Result(property = "punishedName", column = "punished_name"),
@Result(property = "reason", column = "reason"),
@Result(property = "bannedByUuid", column = "banned_by_uuid"),
@Result(property = "bannedByName", column = "banned_by_name"),
@Result(property = "removedByName", column = "removed_by_name"),
@Result(property = "time", column = "time"),
@Result(property = "until", column = "until"),
@Result(property = "removedByReason", column = "removed_by_reason")
})
@Select("""
SELECT punishment.uuid,
user_lookup.name AS punished_name,
punishment.reason,
punishment.banned_by_uuid,
punishment.banned_by_name,
punishment.removed_by_name,
punishment.time,
punishment.until,
punishment.removed_by_reason
FROM (
SELECT uuid,
reason,
banned_by_uuid,
banned_by_name,
removed_by_name,
time,
until,
removed_by_reason
FROM ${tableName} AS punishment
WHERE ${name_column} LIKE #{partialName}
ORDER BY time DESC
LIMIT #{limit} OFFSET #{offset}
) AS punishment
INNER JOIN user_lookup ON user_lookup.uuid = punishment.uuid
""")
List<HistoryRecord> getRecentHistory(@Param("tableName") String tableName, List<HistoryRecord> getRecentHistory(@Param("tableName") String tableName,
@Param("partialName") String partialName, @Param("limit") int limit,
@Param("name_column") String nameColumn, @Param("offset") int offset);
@Param("limit") int limit,
@Param("offset") int offset);
default List<HistoryRecord> getRecent(HistoryType historyType, UserType userType, String partialName, default List<HistoryRecord> getRecent(HistoryType historyType, UserType userType, String partialName,
int page) { int page) {
@ -104,23 +225,33 @@ public interface NameHistoryMapper {
int page) { int page) {
int offset = page * PAGE_SIZE; int offset = page * PAGE_SIZE;
int limit = PAGE_SIZE; int limit = PAGE_SIZE;
return switch (userType) { if (partialName.isEmpty()) {
case PLAYER -> getRecentHistory(tableName, partialName.toLowerCase() + "%", "name", return getRecentHistory(tableName, limit, offset);
limit, offset); } else {
case STAFF -> getRecentHistory(tableName, partialName.toLowerCase() + "%", "banned_by_name", final String searchName = partialName.toLowerCase().replace("_", "\\_") + "%";
limit, offset); return switch (userType) {
}; case PLAYER -> getRecentHistoryForName(tableName, searchName, "name",
limit, offset);
case STAFF -> getRecentHistoryForName(tableName, searchName, "banned_by_name",
limit, offset);
};
}
} }
private List<HistoryRecord> getRecentAll(UserType userType, String partialName, int page) { private List<HistoryRecord> getRecentAll(UserType userType, String partialName, int page) {
int offset = page * PAGE_SIZE; int offset = page * PAGE_SIZE;
int limit = PAGE_SIZE; int limit = PAGE_SIZE;
return switch (userType) { if (partialName.isEmpty()) {
case PLAYER -> getRecentAllHistory(partialName.toLowerCase() + "%", "name", return getRecentAllHistory(limit, offset);
limit, offset); } else {
case STAFF -> getRecentAllHistory(partialName.toLowerCase() + "%", "banned_by_name", final String searchName = partialName.toLowerCase().replace("_", "\\_") + "%";
limit, offset); return switch (userType) {
}; case PLAYER -> getRecentAllHistoryForName(searchName, "name",
limit, offset);
case STAFF -> getRecentAllHistoryForName(searchName, "banned_by_name",
limit, offset);
};
}
} }
private List<HistoryRecord> getRecentBans(UserType userType, String partialName, int page) { private List<HistoryRecord> getRecentBans(UserType userType, String partialName, int page) {