This is an automated email from the ASF dual-hosted git repository.

fmariani pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-spring-boot.git


The following commit(s) were added to refs/heads/main by this push:
     new 18116fc727d Decrypt properties earlier in the SB lifecycle
18116fc727d is described below

commit 18116fc727d747b3ecd63586f64d21b452deb03c
Author: Croway <[email protected]>
AuthorDate: Fri Sep 13 17:05:01 2024 +0200

    Decrypt properties earlier in the SB lifecycle
---
 .../camel-jasypt-starter/src/main/docs/jasypt.json |  7 ++
 .../JasyptEncryptedPropertiesConfiguration.java    | 16 +++++
 .../SpringBootJasyptPropertiesParser.java          | 78 ++++++++++++++++++++++
 .../src/main/resources/META-INF/spring.factories   |  2 +
 .../springboot/EarlyEncryptedPropertiesTest.java   | 15 +++++
 5 files changed, 118 insertions(+)

diff --git a/components-starter/camel-jasypt-starter/src/main/docs/jasypt.json 
b/components-starter/camel-jasypt-starter/src/main/docs/jasypt.json
index 120b69ccccf..d08601a3a00 100644
--- a/components-starter/camel-jasypt-starter/src/main/docs/jasypt.json
+++ b/components-starter/camel-jasypt-starter/src/main/docs/jasypt.json
@@ -14,6 +14,13 @@
       "sourceType": 
"org.apache.camel.component.jasypt.springboot.JasyptEncryptedPropertiesConfiguration",
       "defaultValue": "PBEWithMD5AndDES"
     },
+    {
+      "name": "camel.component.jasypt.early-decryption-enabled",
+      "type": "java.lang.Boolean",
+      "description": "Enable the early properties decryption during Spring 
Start Up",
+      "sourceType": 
"org.apache.camel.component.jasypt.springboot.JasyptEncryptedPropertiesConfiguration",
+      "defaultValue": false
+    },
     {
       "name": "camel.component.jasypt.enabled",
       "type": "java.lang.Boolean",
diff --git 
a/components-starter/camel-jasypt-starter/src/main/java/org/apache/camel/component/jasypt/springboot/JasyptEncryptedPropertiesConfiguration.java
 
b/components-starter/camel-jasypt-starter/src/main/java/org/apache/camel/component/jasypt/springboot/JasyptEncryptedPropertiesConfiguration.java
index ccfa179c9bb..e721dfad164 100644
--- 
a/components-starter/camel-jasypt-starter/src/main/java/org/apache/camel/component/jasypt/springboot/JasyptEncryptedPropertiesConfiguration.java
+++ 
b/components-starter/camel-jasypt-starter/src/main/java/org/apache/camel/component/jasypt/springboot/JasyptEncryptedPropertiesConfiguration.java
@@ -28,6 +28,14 @@ public class JasyptEncryptedPropertiesConfiguration {
      */
     private boolean enabled;
 
+    /**
+     * Enable the early properties decryption during Spring Start Up.
+     * Enabling this feature, encrypted properties can be decrypted before the 
Spring Boot AutoConfiguration
+     * kicks in, for example, 
server.port=ENC(oBpQDDUvFY0c4WNAG0o4LIS5bWqmlxYlUUDTW2iXJIAZFYvM+3vOredaMcVfL4xW)
+     * will be decrypted to 8082, and the application will start using that 
port.
+     */
+    private boolean earlyDecryptionEnabled;
+
     /**
      * The algorithm to be used for decryption. Default: PBEWithMD5AndDES
      */
@@ -73,6 +81,14 @@ public class JasyptEncryptedPropertiesConfiguration {
         this.enabled = enabled;
     }
 
+    public boolean isEarlyDecryptionEnabled() {
+        return earlyDecryptionEnabled;
+    }
+
+    public void setEarlyDecryptionEnabled(boolean earlyDecryptionEnabled) {
+        this.earlyDecryptionEnabled = earlyDecryptionEnabled;
+    }
+
     public String getAlgorithm() {
         return algorithm;
     }
diff --git 
a/components-starter/camel-jasypt-starter/src/main/java/org/apache/camel/component/jasypt/springboot/SpringBootJasyptPropertiesParser.java
 
b/components-starter/camel-jasypt-starter/src/main/java/org/apache/camel/component/jasypt/springboot/SpringBootJasyptPropertiesParser.java
new file mode 100644
index 00000000000..d4d5b95df97
--- /dev/null
+++ 
b/components-starter/camel-jasypt-starter/src/main/java/org/apache/camel/component/jasypt/springboot/SpringBootJasyptPropertiesParser.java
@@ -0,0 +1,78 @@
+package org.apache.camel.component.jasypt.springboot;
+
+import org.apache.camel.component.jasypt.JasyptPropertiesParser;
+import org.apache.camel.component.properties.PropertiesParser;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
+import org.jasypt.encryption.StringEncryptor;
+import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import 
org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
+import org.springframework.boot.origin.OriginTrackedValue;
+import org.springframework.context.ApplicationListener;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.MapPropertySource;
+import org.springframework.core.env.PropertiesPropertySource;
+import org.springframework.core.env.PropertySource;
+
+import java.util.Properties;
+
+public class SpringBootJasyptPropertiesParser implements 
ApplicationListener<ApplicationEnvironmentPreparedEvent> {
+    private static final Logger LOG = 
LoggerFactory.getLogger(SpringBootJasyptPropertiesParser.class);
+
+    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
+        ConfigurableEnvironment environment = event.getEnvironment();
+
+        // Manual Autoconfigure jasypt component
+        JasyptEncryptedPropertiesAutoconfiguration 
jasyptEncryptedPropertiesAutoconfiguration = new 
JasyptEncryptedPropertiesAutoconfiguration();
+        JasyptEncryptedPropertiesConfiguration 
jasyptEncryptedPropertiesConfiguration =
+                
jasyptEncryptedPropertiesAutoconfiguration.JasyptEncryptedPropertiesAutoconfiguration(event.getEnvironment());
+
+        if (jasyptEncryptedPropertiesConfiguration != null && 
jasyptEncryptedPropertiesConfiguration.isEarlyDecryptionEnabled()) {
+            // Too early in the lifecycle, the property has to be resolved 
manually
+            String password = 
jasyptEncryptedPropertiesConfiguration.getPassword();
+            if (password.startsWith("sysenv:")) {
+                password = System.getenv(StringHelper.after(password, 
"sysenv:"));
+            }
+            if (ObjectHelper.isNotEmpty(password) && 
password.startsWith("sys:")) {
+                password = System.getProperty(StringHelper.after(password, 
"sys:"));
+            }
+            jasyptEncryptedPropertiesConfiguration.setPassword(password);
+
+            EnvironmentStringPBEConfig environmentStringPBEConfig =
+                    
jasyptEncryptedPropertiesAutoconfiguration.environmentVariablesConfiguration(jasyptEncryptedPropertiesConfiguration);
+            StringEncryptor stringEncryptor =
+                    
jasyptEncryptedPropertiesAutoconfiguration.stringEncryptor(environmentStringPBEConfig);
+            EncryptablePropertySourcesPlaceholderConfigurer 
encryptablePropertySourcesPlaceholderConfigurer =
+                    
jasyptEncryptedPropertiesAutoconfiguration.propertyConfigurer(stringEncryptor);
+            PropertiesParser propertiesParser = 
jasyptEncryptedPropertiesAutoconfiguration.encryptedPropertiesParser(environment,
+                    stringEncryptor,
+                    environment);
+
+            final Properties props = new Properties();
+            for (PropertySource mutablePropertySources : 
event.getEnvironment().getPropertySources()) {
+                if (mutablePropertySources instanceof MapPropertySource 
mapPropertySource) {
+                    mapPropertySource.getSource().forEach((key, value) -> {
+                        if (value instanceof OriginTrackedValue 
originTrackedValue &&
+                                originTrackedValue.getValue() instanceof 
String stringValue &&
+                                
stringValue.startsWith(JasyptPropertiesParser.JASYPT_PREFIX_TOKEN) &&
+                                
stringValue.endsWith(JasyptPropertiesParser.JASYPT_SUFFIX_TOKEN)) {
+
+                            LOG.debug("decrypting and overriding property {}", 
key);
+                            try {
+                                props.put(key, 
propertiesParser.parseProperty(key.toString(), stringValue, null));
+                            } catch (Exception e) {
+                                // Log and do nothing
+                                LOG.debug("failed to parse property {}", key, 
e);
+                            }
+                        }
+                    });
+                }
+            }
+
+            environment.getPropertySources().addFirst(new 
PropertiesPropertySource("overridden-camel-jasypt-properties", props));
+        }
+    }
+}
+
diff --git 
a/components-starter/camel-jasypt-starter/src/main/resources/META-INF/spring.factories
 
b/components-starter/camel-jasypt-starter/src/main/resources/META-INF/spring.factories
new file mode 100644
index 00000000000..300e703c138
--- /dev/null
+++ 
b/components-starter/camel-jasypt-starter/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.context.ApplicationListener=\
+  org.apache.camel.component.jasypt.springboot.SpringBootJasyptPropertiesParser
\ No newline at end of file
diff --git 
a/components-starter/camel-jasypt-starter/src/test/java/org/apache/camel/component/jasypt/springboot/EarlyEncryptedPropertiesTest.java
 
b/components-starter/camel-jasypt-starter/src/test/java/org/apache/camel/component/jasypt/springboot/EarlyEncryptedPropertiesTest.java
new file mode 100644
index 00000000000..be072ad0e2e
--- /dev/null
+++ 
b/components-starter/camel-jasypt-starter/src/test/java/org/apache/camel/component/jasypt/springboot/EarlyEncryptedPropertiesTest.java
@@ -0,0 +1,15 @@
+package org.apache.camel.component.jasypt.springboot;
+
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.DirtiesContext;
+
+@CamelSpringBootTest
+@DirtiesContext
+@SpringBootApplication
+@SpringBootTest(
+        classes = { EncryptedPropertiesTest.TestConfiguration.class },
+        properties = { "camel.component.jasypt.early-decryption-enabled=true" 
})
+public class EarlyEncryptedPropertiesTest extends EncryptedPropertiesTest {
+}

Reply via email to