|
16 | 16 |
|
17 | 17 | package org.springframework.cloud.bootstrap.encrypt;
|
18 | 18 |
|
19 |
| -import java.util.ArrayList; |
20 |
| -import java.util.Collections; |
21 |
| -import java.util.LinkedHashMap; |
22 |
| -import java.util.List; |
23 | 19 | import java.util.Map;
|
24 |
| -import java.util.regex.Pattern; |
25 |
| - |
26 |
| -import org.apache.commons.logging.Log; |
27 |
| -import org.apache.commons.logging.LogFactory; |
28 | 20 |
|
29 | 21 | import org.springframework.boot.SpringApplication;
|
30 | 22 | import org.springframework.boot.context.properties.bind.Binder;
|
|
33 | 25 | import org.springframework.cloud.bootstrap.TextEncryptorConfigBootstrapper.FailsafeTextEncryptor;
|
34 | 26 | import org.springframework.cloud.context.encrypt.EncryptorFactory;
|
35 | 27 | import org.springframework.core.Ordered;
|
36 |
| -import org.springframework.core.env.CompositePropertySource; |
37 | 28 | import org.springframework.core.env.ConfigurableEnvironment;
|
38 |
| -import org.springframework.core.env.EnumerablePropertySource; |
39 | 29 | import org.springframework.core.env.MutablePropertySources;
|
40 |
| -import org.springframework.core.env.PropertySource; |
41 |
| -import org.springframework.core.env.PropertySources; |
42 | 30 | import org.springframework.core.env.SystemEnvironmentPropertySource;
|
43 | 31 | import org.springframework.security.crypto.encrypt.TextEncryptor;
|
44 | 32 | import org.springframework.util.ClassUtils;
|
|
54 | 42 | * @author Dave Syer
|
55 | 43 | * @author Tim Ysewyn
|
56 | 44 | */
|
57 |
| -public class DecryptEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered { |
58 |
| - |
59 |
| - /** |
60 |
| - * Name of the decrypted property source. |
61 |
| - */ |
62 |
| - public static final String DECRYPTED_PROPERTY_SOURCE_NAME = "decrypted"; |
63 |
| - |
64 |
| - /** |
65 |
| - * Prefix indicating an encrypted value. |
66 |
| - */ |
67 |
| - public static final String ENCRYPTED_PROPERTY_PREFIX = "{cipher}"; |
68 |
| - |
69 |
| - private static final Pattern COLLECTION_PROPERTY = Pattern.compile("(\\S+)?\\[(\\d+)\\](\\.\\S+)?"); |
70 |
| - |
71 |
| - private static Log logger = LogFactory.getLog(DecryptEnvironmentPostProcessor.class); |
| 45 | +public class DecryptEnvironmentPostProcessor extends AbstractEnvironmentDecrypt implements EnvironmentPostProcessor, Ordered { |
72 | 46 |
|
73 | 47 | private int order = Ordered.LOWEST_PRECEDENCE;
|
74 | 48 |
|
75 |
| - private boolean failOnError = true; |
76 |
| - |
77 |
| - /** |
78 |
| - * Strategy to determine how to handle exceptions during decryption. |
79 |
| - * @param failOnError the flag value (default true) |
80 |
| - */ |
81 |
| - public void setFailOnError(boolean failOnError) { |
82 |
| - this.failOnError = failOnError; |
83 |
| - } |
84 |
| - |
85 | 49 | @Override
|
86 | 50 | public int getOrder() {
|
87 | 51 | return this.order;
|
@@ -128,101 +92,5 @@ protected TextEncryptor getTextEncryptor(ConfigurableEnvironment environment) {
|
128 | 92 | return new FailsafeTextEncryptor();
|
129 | 93 | }
|
130 | 94 |
|
131 |
| - public Map<String, Object> decrypt(TextEncryptor encryptor, PropertySources propertySources) { |
132 |
| - Map<String, Object> properties = merge(propertySources); |
133 |
| - decrypt(encryptor, properties); |
134 |
| - return properties; |
135 |
| - } |
136 |
| - |
137 |
| - private Map<String, Object> merge(PropertySources propertySources) { |
138 |
| - Map<String, Object> properties = new LinkedHashMap<>(); |
139 |
| - List<PropertySource<?>> sources = new ArrayList<>(); |
140 |
| - for (PropertySource<?> source : propertySources) { |
141 |
| - sources.add(0, source); |
142 |
| - } |
143 |
| - for (PropertySource<?> source : sources) { |
144 |
| - merge(source, properties); |
145 |
| - } |
146 |
| - return properties; |
147 |
| - } |
148 |
| - |
149 |
| - private void merge(PropertySource<?> source, Map<String, Object> properties) { |
150 |
| - if (source instanceof CompositePropertySource) { |
151 |
| - |
152 |
| - List<PropertySource<?>> sources = new ArrayList<>(((CompositePropertySource) source).getPropertySources()); |
153 |
| - Collections.reverse(sources); |
154 |
| - |
155 |
| - for (PropertySource<?> nested : sources) { |
156 |
| - merge(nested, properties); |
157 |
| - } |
158 |
| - |
159 |
| - } |
160 |
| - else if (source instanceof EnumerablePropertySource) { |
161 |
| - Map<String, Object> otherCollectionProperties = new LinkedHashMap<>(); |
162 |
| - boolean sourceHasDecryptedCollection = false; |
163 |
| - |
164 |
| - EnumerablePropertySource<?> enumerable = (EnumerablePropertySource<?>) source; |
165 |
| - for (String key : enumerable.getPropertyNames()) { |
166 |
| - Object property = source.getProperty(key); |
167 |
| - if (property != null) { |
168 |
| - String value = property.toString(); |
169 |
| - if (value.startsWith(ENCRYPTED_PROPERTY_PREFIX)) { |
170 |
| - properties.put(key, value); |
171 |
| - if (COLLECTION_PROPERTY.matcher(key).matches()) { |
172 |
| - sourceHasDecryptedCollection = true; |
173 |
| - } |
174 |
| - } |
175 |
| - else if (COLLECTION_PROPERTY.matcher(key).matches()) { |
176 |
| - // put non-encrypted properties so merging of index properties |
177 |
| - // happens correctly |
178 |
| - otherCollectionProperties.put(key, value); |
179 |
| - } |
180 |
| - else { |
181 |
| - // override previously encrypted with non-encrypted property |
182 |
| - properties.remove(key); |
183 |
| - } |
184 |
| - } |
185 |
| - } |
186 |
| - // copy all indexed properties even if not encrypted |
187 |
| - if (sourceHasDecryptedCollection && !otherCollectionProperties.isEmpty()) { |
188 |
| - properties.putAll(otherCollectionProperties); |
189 |
| - } |
190 |
| - |
191 |
| - } |
192 |
| - } |
193 |
| - |
194 |
| - private void decrypt(TextEncryptor encryptor, Map<String, Object> properties) { |
195 |
| - properties.replaceAll((key, value) -> { |
196 |
| - String valueString = value.toString(); |
197 |
| - if (!valueString.startsWith(ENCRYPTED_PROPERTY_PREFIX)) { |
198 |
| - return value; |
199 |
| - } |
200 |
| - return decrypt(encryptor, key, valueString); |
201 |
| - }); |
202 |
| - } |
203 |
| - |
204 |
| - private String decrypt(TextEncryptor encryptor, String key, String original) { |
205 |
| - String value = original.substring(ENCRYPTED_PROPERTY_PREFIX.length()); |
206 |
| - try { |
207 |
| - value = encryptor.decrypt(value); |
208 |
| - if (logger.isDebugEnabled()) { |
209 |
| - logger.debug("Decrypted: key=" + key); |
210 |
| - } |
211 |
| - return value; |
212 |
| - } |
213 |
| - catch (Exception e) { |
214 |
| - String message = "Cannot decrypt: key=" + key; |
215 |
| - if (logger.isDebugEnabled()) { |
216 |
| - logger.warn(message, e); |
217 |
| - } |
218 |
| - else { |
219 |
| - logger.warn(message); |
220 |
| - } |
221 |
| - if (this.failOnError) { |
222 |
| - throw new IllegalStateException(message, e); |
223 |
| - } |
224 |
| - return ""; |
225 |
| - } |
226 |
| - } |
227 | 95 |
|
228 | 96 | }
|
0 commit comments