feat: validate runtimeType and customArgs on container config save

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-12 13:08:52 +02:00
parent e941256e6e
commit d5b611cc32
2 changed files with 44 additions and 2 deletions

View File

@@ -3,6 +3,7 @@ package com.cameleer3.server.app.controller;
import com.cameleer3.server.core.runtime.App;
import com.cameleer3.server.core.runtime.AppService;
import com.cameleer3.server.core.runtime.AppVersion;
import com.cameleer3.server.core.runtime.RuntimeType;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -117,18 +118,38 @@ public class AppController {
}
}
private static final java.util.regex.Pattern CUSTOM_ARGS_PATTERN =
java.util.regex.Pattern.compile("^[-a-zA-Z0-9_.=:/\\s+\"']*$");
private void validateContainerConfig(Map<String, Object> config) {
Object customArgs = config.get("customArgs");
if (customArgs instanceof String s && !s.isBlank() && !CUSTOM_ARGS_PATTERN.matcher(s).matches()) {
throw new IllegalArgumentException("customArgs contains invalid characters. Only JVM-style arguments are allowed.");
}
Object runtimeType = config.get("runtimeType");
if (runtimeType instanceof String s && !s.isBlank() && RuntimeType.fromString(s) == null) {
throw new IllegalArgumentException("Invalid runtimeType: " + s +
". Must be one of: auto, spring-boot, quarkus, plain-java, native");
}
}
@PutMapping("/{appSlug}/container-config")
@Operation(summary = "Update container config for an app")
@ApiResponse(responseCode = "200", description = "Container config updated")
@ApiResponse(responseCode = "400", description = "Invalid configuration")
@ApiResponse(responseCode = "404", description = "App not found")
public ResponseEntity<App> updateContainerConfig(@PathVariable String appSlug,
@RequestBody Map<String, Object> containerConfig) {
try {
validateContainerConfig(containerConfig);
App app = appService.getBySlug(appSlug);
appService.updateContainerConfig(app.id(), containerConfig);
return ResponseEntity.ok(appService.getById(app.id()));
} catch (IllegalArgumentException e) {
return ResponseEntity.notFound().build();
if (e.getMessage().contains("not found")) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.badRequest().build();
}
}

View File

@@ -2,6 +2,7 @@ package com.cameleer3.server.app.controller;
import com.cameleer3.server.core.runtime.Environment;
import com.cameleer3.server.core.runtime.EnvironmentService;
import com.cameleer3.server.core.runtime.RuntimeType;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -90,17 +91,37 @@ public class EnvironmentAdminController {
}
}
private static final java.util.regex.Pattern CUSTOM_ARGS_PATTERN =
java.util.regex.Pattern.compile("^[-a-zA-Z0-9_.=:/\\s+\"']*$");
private void validateContainerConfig(Map<String, Object> config) {
Object customArgs = config.get("customArgs");
if (customArgs instanceof String s && !s.isBlank() && !CUSTOM_ARGS_PATTERN.matcher(s).matches()) {
throw new IllegalArgumentException("customArgs contains invalid characters. Only JVM-style arguments are allowed.");
}
Object runtimeType = config.get("runtimeType");
if (runtimeType instanceof String s && !s.isBlank() && RuntimeType.fromString(s) == null) {
throw new IllegalArgumentException("Invalid runtimeType: " + s +
". Must be one of: auto, spring-boot, quarkus, plain-java, native");
}
}
@PutMapping("/{id}/default-container-config")
@Operation(summary = "Update default container config for an environment")
@ApiResponse(responseCode = "200", description = "Default container config updated")
@ApiResponse(responseCode = "400", description = "Invalid configuration")
@ApiResponse(responseCode = "404", description = "Environment not found")
public ResponseEntity<?> updateDefaultContainerConfig(@PathVariable UUID id,
@RequestBody Map<String, Object> defaultContainerConfig) {
try {
validateContainerConfig(defaultContainerConfig);
environmentService.updateDefaultContainerConfig(id, defaultContainerConfig);
return ResponseEntity.ok(environmentService.getById(id));
} catch (IllegalArgumentException e) {
return ResponseEntity.notFound().build();
if (e.getMessage().contains("not found")) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
}
}