|
21 | 21 |
|
22 | 22 | import org.junit.jupiter.api.BeforeEach;
|
23 | 23 | import org.junit.jupiter.api.Test;
|
| 24 | +import org.mockito.ArgumentCaptor; |
24 | 25 |
|
| 26 | +import org.springframework.beans.factory.support.InstanceSupplier; |
| 27 | +import org.springframework.boot.BootstrapRegistry; |
25 | 28 | import org.springframework.boot.ConfigurableBootstrapContext;
|
26 | 29 | import org.springframework.boot.context.config.ConfigDataLocation;
|
27 | 30 | import org.springframework.boot.context.config.ConfigDataLocationResolverContext;
|
28 | 31 | import org.springframework.boot.context.config.Profiles;
|
| 32 | +import org.springframework.boot.context.properties.bind.BindHandler; |
29 | 33 | import org.springframework.boot.context.properties.bind.Binder;
|
30 | 34 | import org.springframework.boot.logging.DeferredLog;
|
| 35 | +import org.springframework.cloud.bootstrap.TextEncryptorBindHandler; |
| 36 | +import org.springframework.cloud.bootstrap.encrypt.KeyProperties; |
| 37 | +import org.springframework.cloud.bootstrap.encrypt.TextEncryptorUtils; |
| 38 | +import org.springframework.cloud.context.encrypt.EncryptorFactory; |
31 | 39 | import org.springframework.mock.env.MockEnvironment;
|
| 40 | +import org.springframework.security.crypto.encrypt.TextEncryptor; |
32 | 41 |
|
33 | 42 | import static org.assertj.core.api.Assertions.assertThat;
|
34 | 43 | import static org.mockito.Mockito.eq;
|
@@ -205,6 +214,65 @@ void multipleImportEntriesDoesNotShareSameURIs() {
|
205 | 214 | assertThat(resource2.getProperties().getUri()).isEqualTo(new String[] { "http://urlNo2" });
|
206 | 215 | }
|
207 | 216 |
|
| 217 | + @Test |
| 218 | + void setFailsafeDelegateKeysNotConfigured() { |
| 219 | + ConfigurableBootstrapContext bootstrapContext = mock(ConfigurableBootstrapContext.class); |
| 220 | + when(bootstrapContext.isRegistered(eq(ConfigClientProperties.class))).thenReturn(true); |
| 221 | + KeyProperties keyProperties = new KeyProperties(); |
| 222 | + ConfigClientProperties configClientProperties = new ConfigClientProperties(); |
| 223 | + configClientProperties.setUri(new String[] { "http://myuri" }); |
| 224 | + when(bootstrapContext.isRegistered(TextEncryptor.class)).thenReturn(true); |
| 225 | + when(bootstrapContext.get(TextEncryptor.class)).thenReturn(new TextEncryptorUtils.FailsafeTextEncryptor()); |
| 226 | + when(bootstrapContext.get(eq(ConfigClientProperties.class))).thenReturn(configClientProperties); |
| 227 | + when(context.getBootstrapContext()).thenReturn(bootstrapContext); |
| 228 | + this.resolver.resolve(context, ConfigDataLocation.of("configserver:http://urlNo1")); |
| 229 | + TextEncryptor textEncryptor = bootstrapContext.get(TextEncryptor.class); |
| 230 | + assertThat(textEncryptor).isInstanceOf(TextEncryptorUtils.FailsafeTextEncryptor.class); |
| 231 | + assertThat(((TextEncryptorUtils.FailsafeTextEncryptor) textEncryptor).getDelegate()).isNull(); |
| 232 | + } |
| 233 | + |
| 234 | + @Test |
| 235 | + void setFailsafeDelegateKeysConfigured() { |
| 236 | + ConfigurableBootstrapContext bootstrapContext = mock(ConfigurableBootstrapContext.class); |
| 237 | + when(bootstrapContext.isRegistered(eq(ConfigClientProperties.class))).thenReturn(true); |
| 238 | + environment.setProperty("encrypt.key", "mykey"); |
| 239 | + |
| 240 | + // The value is "password" encrypted with the key "mykey" |
| 241 | + environment.setProperty("spring.cloud.config.password", |
| 242 | + "{cipher}6defc102cd76752fcf4c78231ed82ead85133a09741d9a1442595b4800e2b3d1"); |
| 243 | + ConfigClientProperties configClientProperties = new ConfigClientProperties(); |
| 244 | + configClientProperties.setUri(new String[] { "http://myuri" }); |
| 245 | + when(bootstrapContext.isRegistered(TextEncryptor.class)).thenReturn(true); |
| 246 | + when(bootstrapContext.get(TextEncryptor.class)).thenReturn(new TextEncryptorUtils.FailsafeTextEncryptor()); |
| 247 | + when(bootstrapContext.get(eq(ConfigClientProperties.class))).thenReturn(configClientProperties); |
| 248 | + when(context.getBootstrapContext()).thenReturn(bootstrapContext); |
| 249 | + KeyProperties keyProperties = new KeyProperties(); |
| 250 | + keyProperties.setKey("mykey"); |
| 251 | + |
| 252 | + // Use this TextEncryptor in the BindHandler we return so it will decrypt the |
| 253 | + // password when we bind ConfigClientProperties |
| 254 | + TextEncryptor bindHandlerTextEncryptor = new EncryptorFactory(keyProperties.getSalt()) |
| 255 | + .create(keyProperties.getKey()); |
| 256 | + when(context.getBootstrapContext().getOrElse(eq(BindHandler.class), eq(null))) |
| 257 | + .thenReturn(new TextEncryptorBindHandler(bindHandlerTextEncryptor, keyProperties)); |
| 258 | + |
| 259 | + // Call resolve so we can test that the delegate is added to the |
| 260 | + // FailsafeTextEncryptor |
| 261 | + this.resolver.resolve(context, ConfigDataLocation.of("configserver:http://urlNo1")); |
| 262 | + TextEncryptor textEncryptor = bootstrapContext.get(TextEncryptor.class); |
| 263 | + |
| 264 | + // Capture the ConfigClientProperties we create and register in |
| 265 | + // ConfigServerConfigDataLocationResolver.resolveProfileSpecific |
| 266 | + // it should have the decrypted passord in it |
| 267 | + ArgumentCaptor<BootstrapRegistry.InstanceSupplier<ConfigClientProperties>> captor = ArgumentCaptor |
| 268 | + .forClass(BootstrapRegistry.InstanceSupplier.class); |
| 269 | + verify(bootstrapContext).register(eq(ConfigClientProperties.class), captor.capture()); |
| 270 | + assertThat(captor.getValue().get(bootstrapContext).getPassword()).isEqualTo("password"); |
| 271 | + assertThat(textEncryptor).isInstanceOf(TextEncryptorUtils.FailsafeTextEncryptor.class); |
| 272 | + assertThat(((TextEncryptorUtils.FailsafeTextEncryptor) textEncryptor).getDelegate()) |
| 273 | + .isInstanceOf(TextEncryptor.class); |
| 274 | + } |
| 275 | + |
208 | 276 | private ConfigServerConfigDataResource testUri(String propertyUri, String locationUri) {
|
209 | 277 | this.environment.setProperty(ConfigClientProperties.PREFIX + ".uri", propertyUri);
|
210 | 278 | when(context.getBootstrapContext()).thenReturn(mock(ConfigurableBootstrapContext.class));
|
|
0 commit comments