1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package net.brabenetz.lib.securedproperties;
21
22 import net.brabenetz.lib.securedproperties.test.TestUtils;
23 import net.brabenetz.lib.securedproperties.utils.SecuredPropertiesUtils;
24 import org.apache.commons.io.FileUtils;
25 import org.apache.commons.lang3.StringUtils;
26 import org.junit.Assert;
27 import org.junit.Before;
28 import org.junit.Test;
29
30 import java.io.File;
31 import java.io.IOException;
32 import java.nio.charset.StandardCharsets;
33 import java.util.Arrays;
34 import java.util.Map;
35 import java.util.Properties;
36
37 import static org.hamcrest.CoreMatchers.containsString;
38 import static org.hamcrest.MatcherAssert.assertThat;
39 import static org.hamcrest.Matchers.is;
40 import static org.hamcrest.Matchers.not;
41 import static org.hamcrest.Matchers.nullValue;
42
43 public class SecuredPropertiesTest {
44
45 @Before
46 public void before() throws Exception {
47 System.clearProperty("mySecretPassword");
48 if (getTestPropertyFile().exists()) {
49 FileUtils.forceDelete(getTestPropertyFile());
50 }
51 if (getTestSecretFile().exists()) {
52 FileUtils.forceDelete(getTestSecretFile());
53 }
54
55 }
56
57 @Test
58 public void testUtilityPattern() {
59
60 Assert.assertTrue(TestUtils.isDefaultConstructorHidden(SecuredProperties.class));
61 }
62
63 @Test
64 public void testGetSecretValue_withMultipleFiles_shouldIgnoreNotExistingOnes() throws Exception {
65
66 final String secretValue = SecuredProperties.getSecretValue(
67 new SecuredPropertiesConfig().withSecretFile(getSecretFileExample()),
68 new File[] {
69 new File("./conf-abc/application.properties"),
70 new File("./src/test/data/TestProperties-Valid.properties"),
71 new File("./conf-xyz/application.properties"),
72 },
73 "mySecretPassword");
74
75
76 assertThat(secretValue, is("test"));
77
78 }
79
80 @Test
81 public void testGetSecretValue_withSecretFileFromProperty() throws Exception {
82
83 final String secretValue = SecuredProperties.getSecretValue(
84 new SecuredPropertiesConfig().withSecretFile(getSecretFileExample()),
85 new File("./src/test/data/TestProperties-Valid.properties"), "mySecretPassword");
86
87
88 assertThat(secretValue, is("test"));
89
90 }
91
92 @Test
93 public void testGetSecretValue_fromEncryptedPropertyFile() throws Exception {
94
95 writeProperties(getTestPropertyFile(), "mySecretPassword={buMkr+yZH9RclafjETtlSQ==}");
96
97
98 final String secretValue = SecuredProperties.getSecretValue(
99 new SecuredPropertiesConfig().withSecretFile(getSecretFileExample()),
100 getTestPropertyFile(), "mySecretPassword");
101
102
103 assertThat(secretValue, is("test"));
104
105
106 final Properties props = SecuredPropertiesUtils.readProperties(getTestPropertyFile());
107 assertThat(props.get("mySecretPassword"), is("{buMkr+yZH9RclafjETtlSQ==}"));
108
109 }
110
111 @Test
112 public void testGetSecretValue_notDefinedProperty_shouldReturnNull() throws Exception {
113
114 writeProperties(getTestPropertyFile(), "title=Some Test");
115
116
117 final String secretValue = SecuredProperties.getSecretValue(
118 new SecuredPropertiesConfig().withSecretFile(getSecretFileExample()),
119 getTestPropertyFile(), "mySecretPassword");
120
121 assertThat(secretValue, is(nullValue()));
122
123 }
124
125 @Test
126 public void testManualExampleEncryptAndDecrypt_fromEncryptedSystemProperty() throws Exception {
127
128 System.setProperty("mySecretPassword", "{buMkr+yZH9RclafjETtlSQ==}");
129
130
131 final SecuredPropertiesConfig config = new SecuredPropertiesConfig().withSecretFile(getSecretFileExample());
132
133 final String encryptedValue = checkSystemProperties(config, "mySecretPassword");
134
135
136 assertThat(encryptedValue, is("test"));
137
138 }
139
140 @Test
141 public void testManualExampleEncryptAndDecrypt_fromUnencryptedSystemProperty_shouldLogInfoMessage() throws Exception {
142
143 System.setProperty("mySecretPassword", "test");
144
145
146 final SecuredPropertiesConfig config = new SecuredPropertiesConfig().withSecretFile(getSecretFileExample());
147 final String encryptedValue = checkSystemProperties(config, "mySecretPassword");
148
149
150 assertThat(encryptedValue, is("test"));
151
152
153 }
154
155 @Test
156 public void testGetSecretValue_fromUnencryptedPropertyFile_shouldNotReplaceProperty() throws Exception {
157
158 writeProperties(getTestPropertyFile(), "mySecretPassword=test");
159
160
161 final String secretValue = SecuredProperties.getSecretValue(
162 new SecuredPropertiesConfig().withSecretFile(getSecretFileExample()),
163 getTestPropertyFile(), "mySecretPassword");
164
165 assertThat(secretValue, is("test"));
166
167
168 final Properties props = SecuredPropertiesUtils.readProperties(getTestPropertyFile());
169 final String newPasswordValue = props.getProperty("mySecretPassword");
170 assertThat(newPasswordValue, is("test"));
171
172 }
173
174 @Test
175 public void testGetSecretValue_withoutSecretFile_shouldCreateSecretFile() throws Exception {
176
177 writeProperties(getTestPropertyFile(), "mySecretPassword=test");
178
179
180 final SecuredPropertiesConfig config = new SecuredPropertiesConfig().withSecretFile(getTestSecretFile());
181
182 final String secretValue = SecuredProperties.getSecretValue(config, getTestPropertyFile(), "mySecretPassword");
183 assertThat(secretValue, is("test"));
184
185
186 final Properties props = SecuredPropertiesUtils.readProperties(getTestPropertyFile());
187 final String newPasswordValue = props.getProperty("mySecretPassword");
188 assertThat(newPasswordValue, is("test"));
189 assertThat(SecuredProperties.isEncryptedValue(newPasswordValue), is(false));
190 assertThat(getTestSecretFile().exists(), is(true));
191
192 }
193
194 @Test
195 public void testEncryptNonEncryptedValues_withMultipleFiles_shouldIgnoreNotExistingOnes() throws Exception {
196 writeProperties(getTestPropertyFile(), "pwd1=test");
197
198 final SecuredPropertiesConfig config = new SecuredPropertiesConfig().withSecretFile(getSecretFileExample());
199 SecuredProperties.encryptNonEncryptedValues(
200 config,
201 new File[] {
202 new File("./conf-abc/application.properties"),
203 getTestPropertyFile(),
204 new File("./conf-xyz/application.properties"),
205 },
206 "pwd1", "pwd2", "pwd3");
207
208
209 final String secretValue = SecuredProperties.getSecretValue(
210 config, getTestPropertyFile(), "pwd1");
211 assertThat(secretValue, is("test"));
212
213
214 final Properties props = SecuredPropertiesUtils.readProperties(getTestPropertyFile());
215 assertThat(props.getProperty("pwd1"), is(not("test")));
216 assertThat(SecuredProperties.isEncryptedValue(props.getProperty("pwd1")), is(true));
217
218 }
219
220 @Test
221 public void testEncryptNonEncryptedValues_multipleValues_shouldReplaceUnencryptedProperties() throws Exception {
222
223 writeProperties(getTestPropertyFile(), "pwd1=test", "pwd2={buMkr+yZH9RclafjETtlSQ==}", "pwd3=test");
224
225
226 final SecuredPropertiesConfig config = new SecuredPropertiesConfig().withSecretFile(getSecretFileExample());
227 SecuredProperties.encryptNonEncryptedValues(
228 config, getTestPropertyFile(), "pwd1", "pwd2", "pwd3", "pwd99");
229 final Map<String, String> secretValues = SecuredProperties.getSecretValues(
230 config, getTestPropertyFile(), "pwd1", "pwd2", "pwd3", "pwd99");
231
232 assertThat(secretValues.get("pwd1"), is("test"));
233 assertThat(secretValues.get("pwd2"), is("test"));
234 assertThat(secretValues.get("pwd3"), is("test"));
235 assertThat(secretValues.get("pwd99"), is(nullValue()));
236
237
238 final Properties props = SecuredPropertiesUtils.readProperties(getTestPropertyFile());
239 assertThat(props.getProperty("pwd1"), is(not("test")));
240 assertThat(props.getProperty("pwd2"), is("{buMkr+yZH9RclafjETtlSQ==}"));
241 assertThat(props.getProperty("pwd3"), is(not("test")));
242 assertThat(SecuredProperties.isEncryptedValue(props.getProperty("pwd1")), is(true));
243 assertThat(SecuredProperties.isEncryptedValue(props.getProperty("pwd2")), is(true));
244 assertThat(SecuredProperties.isEncryptedValue(props.getProperty("pwd3")), is(true));
245
246 }
247
248 @Test
249 public void testEncryptNonEncryptedValues_fromUnencryptedPropertyFileWithoutSalt_shouldReplacePropertyWithAlwaysSameValue()
250 throws Exception {
251
252 writeProperties(getTestPropertyFile(), "mySecretPassword=test");
253
254
255 final SecuredPropertiesConfig config = new SecuredPropertiesConfig().withSecretFile(getSecretFileExample()).withSaltLength(0);
256 SecuredProperties.encryptNonEncryptedValues(config, getTestPropertyFile(), "mySecretPassword");
257
258
259 final String secretValue = SecuredProperties.getSecretValue(config, getTestPropertyFile(), "mySecretPassword");
260 assertThat(secretValue, is("test"));
261
262
263 final Properties props = SecuredPropertiesUtils.readProperties(getTestPropertyFile());
264 final String newPasswordValue = props.getProperty("mySecretPassword");
265 assertThat(newPasswordValue, is("{wNnuFmepE9cAN6GpaULDZw==}"));
266
267 }
268
269 @Test
270 public void testEncryptNonEncryptedValues_withoutSecretFile_shouldCreateSecretFile() throws Exception {
271
272 writeProperties(getTestPropertyFile(), "mySecretPassword=test");
273
274
275 final SecuredPropertiesConfig config = new SecuredPropertiesConfig().withSecretFile(getTestSecretFile());
276 SecuredProperties.encryptNonEncryptedValues(config, getTestPropertyFile(), "mySecretPassword");
277 assertThat(getTestSecretFile().exists(), is(true));
278
279
280 final String secretValue = SecuredProperties.getSecretValue(config, getTestPropertyFile(), "mySecretPassword");
281 assertThat(secretValue, is("test"));
282
283
284 final Properties props = SecuredPropertiesUtils.readProperties(getTestPropertyFile());
285 final String newPasswordValue = props.getProperty("mySecretPassword");
286 assertThat(newPasswordValue, is(not("test")));
287 assertThat(SecuredProperties.isEncryptedValue(newPasswordValue), is(true));
288 assertThat(getTestSecretFile().exists(), is(true));
289
290 }
291
292 @Test
293 public void testEncryptNonEncryptedValues_withoutSecretFile_shouldNotCreateSecretFile() throws Exception {
294
295 writeProperties(getTestPropertyFile(), "mySecretPassword=test");
296
297
298 final SecuredPropertiesConfig config = new SecuredPropertiesConfig()
299 .withSecretFile(getTestSecretFile())
300 .withAutoCreateSecretKey(false);
301 final Exception expectException = TestUtils.expectException(
302 () -> SecuredProperties.encryptNonEncryptedValues(config, getTestPropertyFile(), "mySecretPassword"));
303
304 assertThat(expectException.getMessage(), containsString("test.key"));
305 assertThat(expectException.getMessage(), containsString("doesn't exist, and auto create is off"));
306
307
308 assertThat(getTestSecretFile().exists(), is(false));
309
310 }
311
312 private String checkSystemProperties(final SecuredPropertiesConfig config, final String key) {
313
314 final String systemPropPassword = System.getProperty(key);
315 if (SecuredProperties.isEncryptedValue(systemPropPassword)) {
316 return SecuredProperties.decrypt(config, systemPropPassword);
317 } else if (StringUtils.isNotEmpty(systemPropPassword)) {
318 System.out.println(String.format("you could now use the following encrypted password: -D%s=%s", key,
319 SecuredProperties.encrypt(config, systemPropPassword)));
320 return systemPropPassword;
321 } else {
322 return null;
323 }
324 }
325
326 private File getTestSecretFile() {
327 return new File("./target/tests/test.key");
328 }
329
330 private void writeProperties(final File testPropertyFile, final String... line) throws IOException {
331 FileUtils.writeLines(testPropertyFile, StandardCharsets.ISO_8859_1.name(), Arrays.asList(line));
332 }
333
334 private File getTestPropertyFile() {
335 return new File("./target/tests/test.properties");
336 }
337
338 private File getSecretFileExample() {
339 return new File("./src/test/data/secretFileExample.key");
340 }
341
342 }