fix(rcon): validate grant requests

This commit is contained in:
simoleo89
2026-06-14 16:45:04 +02:00
parent 3cb24a5185
commit dba0337a7b
11 changed files with 237 additions and 1 deletions
@@ -20,5 +20,7 @@ class GiveCreditsContractTest {
"Offline RCON credit grants must inspect the affected row count");
assertTrue(source.contains("HABBO_NOT_FOUND"),
"Offline RCON credit grants must report missing users when the UPDATE changes no rows");
assertTrue(source.contains("RconGrantGuard.validatePositiveAmount"),
"RCON credit grants must reject zero, negative, and oversized grants");
}
}
@@ -20,5 +20,9 @@ class GivePixelsContractTest {
"Offline RCON pixel grants must create the users_currency type 0 row when it is missing");
assertTrue(source.contains("ON DUPLICATE KEY UPDATE"),
"Offline RCON pixel grants should increment existing rows with an upsert");
assertTrue(source.contains("RconGrantGuard.validatePositiveAmount"),
"RCON pixel grants must reject zero, negative, and oversized grants");
assertTrue(source.contains("RconUserLookup.userExists"),
"Offline RCON pixel grants must not create orphan currency rows for missing users");
}
}
@@ -0,0 +1,28 @@
package com.eu.habbo.messages.rcon;
import org.junit.jupiter.api.Test;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.jupiter.api.Assertions.assertTrue;
class GivePointsContractTest {
private static String givePointsSource() throws Exception {
return Files.readString(Path.of("src/main/java/com/eu/habbo/messages/rcon/GivePoints.java"));
}
@Test
void pointGrantsValidateAmountTypeAndOfflineUserExistence() throws Exception {
String source = givePointsSource();
assertTrue(source.contains("RconGrantGuard.validateCurrencyType"),
"RCON point grants must reject invalid currency types");
assertTrue(source.contains("RconGrantGuard.validatePositiveAmount"),
"RCON point grants must reject zero, negative, and oversized grants");
assertTrue(source.contains("RconUserLookup.userExists"),
"Offline RCON point grants must not create orphan currency rows for missing users");
assertTrue(source.contains("ON DUPLICATE KEY UPDATE"),
"Offline RCON point grants should increment existing rows with an upsert");
}
}
@@ -20,5 +20,9 @@ class GiveRespectContractTest {
"respects_given must be incremented with respect_given");
assertTrue(source.contains("statement.setInt(2, object.respect_received);"),
"respects_received must be incremented with respect_received");
assertTrue(source.contains("RconGrantGuard.validateNonNegativeAmount"),
"RCON respect grants must reject negative values");
assertTrue(source.contains("statement.executeUpdate() == 0"),
"Offline RCON respect grants must report missing users when the UPDATE changes no rows");
}
}
@@ -0,0 +1,38 @@
package com.eu.habbo.messages.rcon;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
class RconGrantGuardTest {
@Test
void validatesPositiveGrantAmounts() {
assertNull(RconGrantGuard.validatePositiveAmount(1, 100, "credits"));
assertEquals("invalid credits", RconGrantGuard.validatePositiveAmount(0, 100, "credits"));
assertEquals("invalid credits", RconGrantGuard.validatePositiveAmount(-1, 100, "credits"));
assertEquals("credits exceeds rcon grant ceiling", RconGrantGuard.validatePositiveAmount(101, 100, "credits"));
}
@Test
void validatesNonNegativeGrantAmounts() {
assertNull(RconGrantGuard.validateNonNegativeAmount(0, 100, "respect_given"));
assertEquals("invalid respect_given", RconGrantGuard.validateNonNegativeAmount(-1, 100, "respect_given"));
assertEquals("respect_given exceeds rcon grant ceiling", RconGrantGuard.validateNonNegativeAmount(101, 100, "respect_given"));
}
@Test
void validatesUserAndCurrencyIdentifiers() {
assertNull(RconGrantGuard.validateUserId(1));
assertEquals("invalid user", RconGrantGuard.validateUserId(0));
assertNull(RconGrantGuard.validateCurrencyType(0));
assertEquals("invalid currency type", RconGrantGuard.validateCurrencyType(-1));
}
@Test
void parsesInvalidGrantCeilingsAsDefault() {
assertEquals(RconGrantGuard.DEFAULT_MAX_AMOUNT, RconGrantGuard.parseMaxAmount(null));
assertEquals(RconGrantGuard.DEFAULT_MAX_AMOUNT, RconGrantGuard.parseMaxAmount("0"));
assertEquals(500, RconGrantGuard.parseMaxAmount("500"));
}
}