fix(rcon): validate room ownership and clothing grants

This commit is contained in:
simoleo89
2026-06-14 17:31:42 +02:00
parent dba0337a7b
commit 4747699656
4 changed files with 159 additions and 8 deletions
@@ -0,0 +1,39 @@
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.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class ChangeRoomOwnerContractTest {
private static String source() throws Exception {
return Files.readString(Path.of("src/main/java/com/eu/habbo/messages/rcon/ChangeRoomOwner.java"));
}
@Test
void validatesRoomAndUserBeforeChangingOwnership() throws Exception {
String source = source();
assertTrue(source.contains("json.room_id <= 0 || json.user_id <= 0"),
"Room owner changes must reject invalid identifiers");
assertTrue(source.contains("getHabboInfo(json.user_id)"),
"Room owner changes must resolve the canonical user from storage");
assertTrue(source.contains("HABBO_NOT_FOUND"),
"Room owner changes must report missing target users");
assertTrue(source.contains("ROOM_NOT_FOUND"),
"Room owner changes must report missing rooms");
}
@Test
void doesNotTrustClientSuppliedOwnerNames() throws Exception {
String source = source();
assertTrue(source.contains("setOwnerName(owner.getUsername())"),
"Room owner changes must use the stored username");
assertFalse(source.contains("setOwnerName(json.username)"),
"Room owner changes must not trust JSON usernames");
}
}
@@ -0,0 +1,38 @@
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 GiveUserClothingContractTest {
private static String source() throws Exception {
return Files.readString(Path.of("src/main/java/com/eu/habbo/messages/rcon/GiveUserClothing.java"));
}
@Test
void validatesUsersAndClothingBeforeWritingInventoryRows() throws Exception {
String source = source();
assertTrue(source.contains("object.user_id <= 0 || object.clothing_id <= 0"),
"Clothing grants must reject invalid identifiers");
assertTrue(source.contains("userExists(object.user_id)"),
"Clothing grants must reject missing users before inserting rows");
assertTrue(source.contains("clothingExists(object.clothing_id)"),
"Clothing grants must reject catalog clothing ids that do not exist");
assertTrue(source.contains("catalog_clothing"),
"Clothing grants must validate against catalog_clothing");
}
@Test
void handlesDuplicateGrantsWithoutSurfacingSqlErrors() throws Exception {
String source = source();
assertTrue(source.contains("INSERT IGNORE INTO users_clothing"),
"Duplicate clothing grants should be idempotent");
assertTrue(source.contains("SYSTEM_ERROR"),
"Unexpected SQL failures must be surfaced to the RCON caller");
}
}