From 229a51016147c17e7306b29077a815971f8b5296 Mon Sep 17 00:00:00 2001 From: Daniel Graf Date: Fri, 2 Jan 2026 11:10:44 +0100 Subject: [PATCH] feat(607): add support for resolving secret properties from files (#612) --- .gitignore | 2 + .../reitti/ReittiApplication.java | 5 +- .../config/FilePropertySourceInitializer.java | 46 +++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/dedicatedcode/reitti/config/FilePropertySourceInitializer.java diff --git a/.gitignore b/.gitignore index 98c332c6..c42a91a2 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,5 @@ docker-compose.override.yml /e2e/node_modules/ /e2e/playwright-report/ /e2e/test-results/ + +/secrets/ diff --git a/src/main/java/com/dedicatedcode/reitti/ReittiApplication.java b/src/main/java/com/dedicatedcode/reitti/ReittiApplication.java index 5b33faec..40c8cbea 100644 --- a/src/main/java/com/dedicatedcode/reitti/ReittiApplication.java +++ b/src/main/java/com/dedicatedcode/reitti/ReittiApplication.java @@ -1,5 +1,6 @@ package com.dedicatedcode.reitti; +import com.dedicatedcode.reitti.config.FilePropertySourceInitializer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientAutoConfiguration; @@ -10,7 +11,9 @@ import org.springframework.scheduling.annotation.EnableAsync; public class ReittiApplication { static void main(String[] args) { - SpringApplication.run(ReittiApplication.class, args); + SpringApplication application = new SpringApplication(ReittiApplication.class); + application.addInitializers(new FilePropertySourceInitializer()); + application.run(args); } } diff --git a/src/main/java/com/dedicatedcode/reitti/config/FilePropertySourceInitializer.java b/src/main/java/com/dedicatedcode/reitti/config/FilePropertySourceInitializer.java new file mode 100644 index 00000000..feaa5291 --- /dev/null +++ b/src/main/java/com/dedicatedcode/reitti/config/FilePropertySourceInitializer.java @@ -0,0 +1,46 @@ +package com.dedicatedcode.reitti.config; + +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.MapPropertySource; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class FilePropertySourceInitializer implements ApplicationContextInitializer { + + @Override + public void initialize(ConfigurableApplicationContext applicationContext) { + Map properties = new HashMap<>(); + + // Iterate through all properties to find ones ending with _FILE + applicationContext.getEnvironment().getPropertySources().forEach(source -> { + if (source instanceof MapPropertySource) { + MapPropertySource cps = (MapPropertySource) source; + Arrays.stream(cps.getPropertyNames()).forEach(name -> { + if (name.endsWith("_FILE")) { + String filePath = Objects.requireNonNull(cps.getProperty(name)).toString(); + try { + String content = new String(Files.readAllBytes(Paths.get(filePath))).trim(); + // Create a new property name without the _FILE suffix + String baseName = name.substring(0, name.length() - 5); + properties.put(baseName, content); + } catch (Exception e) { + System.err.println("Error reading file for property " + name + ": " + e.getMessage()); + } + } + }); + } + }); + + if (!properties.isEmpty()) { + // Add the resolved properties to the environment with high precedence + MapPropertySource propertySource = new MapPropertySource("fileProperties", properties); + applicationContext.getEnvironment().getPropertySources().addFirst(propertySource); + } + } +} \ No newline at end of file