Skip to content

Commit

Permalink
MapUpload: Add validation for adaptive map files in zip
Browse files Browse the repository at this point in the history
  • Loading branch information
Brutus5000 committed Sep 8, 2019
1 parent fd6ed25 commit ec4913a
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 10 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ nocatchVersion=1.1
junitAddonsVersion=1.4
githubApiVersion=1.84
jgitVersionn=4.5.0.201609210915-r
fafCommonsVersion=1172e1b0
fafCommonsVersion=4ca1f756
h2Version=1.4.193
jacksonDatatypeJsr310Version=2.9.7
mockitoVersion=2.23.4
Expand Down
13 changes: 10 additions & 3 deletions src/main/java/com/faforever/api/map/MapLuaAccessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class MapLuaAccessor {
private static final String CONFIGURATION_STANDARD_TEAMS = "teams";
private static final String CONFIGURATION_STANDARD_TEAMS_NAME = "name";
private static final String CONFIGURATION_STANDARD_TEAMS_ARMIES = "armies";

private static final String ADAPTIVE_MAP = "AdaptiveMap";

private final LuaAccessor luaAccessor;

Expand Down Expand Up @@ -61,8 +61,12 @@ public OptionalInt getNoRushRadius() {
return luaAccessor.readVariableInt(NO_RUSH_RADIUS);
}

public boolean hasVariableMatching(String regex, String... names) {
return luaAccessor.hasVariableMatching(regex, names);
public Optional<Boolean> isAdaptive() {
return luaAccessor.readVariableBool(ADAPTIVE_MAP);
}

public boolean hasVariableMatchingIgnoreCase(String regex, String... names) {
return luaAccessor.hasVariableMatchingIgnoreCase(regex, names);
}

public Optional<LuaValue> getFirstTeam() {
Expand Down Expand Up @@ -106,4 +110,7 @@ public boolean hasInvalidTeam() {
return getFirstTeam().get();
}

public boolean isAdaptive$() {
return isAdaptive().get();
}
}
19 changes: 13 additions & 6 deletions src/main/java/com/faforever/api/map/MapService.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
import static com.faforever.api.map.MapService.ScenarioMapInfo.FILE_ENDING_SAVE;
import static com.faforever.api.map.MapService.ScenarioMapInfo.FILE_ENDING_SCENARIO;
import static com.faforever.api.map.MapService.ScenarioMapInfo.FILE_ENDING_SCRIPT;
import static com.faforever.api.map.MapService.ScenarioMapInfo.REQUIRED_FILES;
import static com.faforever.api.map.MapService.ScenarioMapInfo.MANDATORY_FILES;
import static com.github.nocatch.NoCatch.noCatch;
import static java.text.MessageFormat.format;

Expand Down Expand Up @@ -162,12 +162,18 @@ public void uploadMap(InputStream mapDataInputStream, String mapFilename, Player
try {
Path unzippedFileFolder = unzipToTemporaryDirectory(mapDataInputStream, rootTempFolder);
Path mapFolder = validateMapFolderStructure(unzippedFileFolder);
validateMandatoryFiles(mapFolder);
validateRequiredFiles(mapFolder, MANDATORY_FILES);

MapLuaAccessor mapLua = parseScenarioLua(mapFolder);
MapNameBuilder mapNameBuilder = new MapNameBuilder(mapLua.getName()
.orElseThrow(() -> ApiException.of(ErrorCode.MAP_NAME_MISSING)));

mapLua.isAdaptive().ifPresent(isAdaptive -> {
if (isAdaptive) {
validateRequiredFiles(mapFolder, ADAPTIVE_REQUIRED_FILES);
}
});

validateScenarioLua(mapLua, mapNameBuilder);

Optional<Map> existingMapOptional = validateMapMetadata(mapLua, mapNameBuilder, author);
Expand Down Expand Up @@ -223,13 +229,14 @@ private Path validateMapFolderStructure(Path zipContentFolder) throws IOExceptio
return mapFolder;
}

private void validateMandatoryFiles(Path mapFolder) throws IOException {
@SneakyThrows
private void validateRequiredFiles(Path mapFolder, String[] requiredFiles) {
try (Stream<Path> mapFileStream = Files.list(mapFolder)) {
List<String> fileNames = mapFileStream
.map(Path::toString)
.collect(Collectors.toList());

List<Error> errors = Arrays.stream(REQUIRED_FILES)
List<Error> errors = Arrays.stream(requiredFiles)
.filter(requiredEnding -> fileNames.stream().noneMatch(fileName -> fileName.endsWith(requiredEnding)))
.map(requiredEnding -> new Error(ErrorCode.MAP_FILE_INSIDE_ZIP_MISSING, requiredEnding))
.collect(Collectors.toList());
Expand Down Expand Up @@ -293,7 +300,7 @@ private Optional<Error> validateLuaPathVariable(MapLuaAccessor mapLua, String va
String regex = format("\\/maps\\/{0}(\\.v\\d{4})?\\/{1}",
mapFolderNameWithoutVersion, mapFileName);

if (!mapLua.hasVariableMatching(regex, variableName)) {
if (!mapLua.hasVariableMatchingIgnoreCase(regex, variableName)) {
return Optional.of(new Error(ErrorCode.MAP_SCRIPT_LINE_MISSING,
format("{0} = ''/maps/{1}/{2}''", variableName, mapFolderNameWithoutVersion, mapFileName)));
}
Expand Down Expand Up @@ -425,7 +432,7 @@ static class ScenarioMapInfo {
static final String FILE_DECLARATION_SCRIPT = "script";
static final String FILE_ENDING_SCRIPT = "_script.lua";

static final String[] REQUIRED_FILES = new String[]{
static final String[] MANDATORY_FILES = new String[]{
FILE_ENDING_SCENARIO,
FILE_ENDING_MAP,
FILE_ENDING_SAVE,
Expand Down
12 changes: 12 additions & 0 deletions src/test/java/com/faforever/api/map/MapServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,18 @@ void noMapName() {
verify(mapRepository, never()).save(any(com.faforever.api.data.domain.Map.class));
}

@Test
void adaptiveFilesMissing() {
String zipFilename = "adaptive_map_files_missing.zip";
InputStream mapData = loadMapAsInputSteam(zipFilename);
ApiException result = assertThrows(ApiException.class, () -> instance.uploadMap(mapData, zipFilename, author, true));
assertThat(result, hasErrorCodes(
ErrorCode.MAP_FILE_INSIDE_ZIP_MISSING,
ErrorCode.MAP_FILE_INSIDE_ZIP_MISSING
));
verify(mapRepository, never()).save(any(com.faforever.api.data.domain.Map.class));
}

@Test
void invalidScenario() {
String zipFilename = "invalid_scenario.zip";
Expand Down
Binary file not shown.

0 comments on commit ec4913a

Please sign in to comment.