diff --git a/aws-common/src/main/java/io/druid/common/aws/AWSCredentialsConfig.java b/aws-common/src/main/java/io/druid/common/aws/AWSCredentialsConfig.java index fbf3bc72ac0..ae213fe0dee 100644 --- a/aws-common/src/main/java/io/druid/common/aws/AWSCredentialsConfig.java +++ b/aws-common/src/main/java/io/druid/common/aws/AWSCredentialsConfig.java @@ -20,26 +20,28 @@ package io.druid.common.aws; import com.fasterxml.jackson.annotation.JsonProperty; +import io.druid.metadata.DefaultPasswordProvider; +import io.druid.metadata.PasswordProvider; /** */ public class AWSCredentialsConfig { @JsonProperty - private String accessKey = ""; + private PasswordProvider accessKey = new DefaultPasswordProvider(""); @JsonProperty - private String secretKey = ""; + private PasswordProvider secretKey = new DefaultPasswordProvider(""); @JsonProperty private String fileSessionCredentials = ""; - public String getAccessKey() + public PasswordProvider getAccessKey() { return accessKey; } - public String getSecretKey() + public PasswordProvider getSecretKey() { return secretKey; } diff --git a/aws-common/src/main/java/io/druid/common/aws/ConfigDrivenAwsCredentialsConfigProvider.java b/aws-common/src/main/java/io/druid/common/aws/ConfigDrivenAwsCredentialsConfigProvider.java index 33eca26a2c3..732c8c2a3bd 100644 --- a/aws-common/src/main/java/io/druid/common/aws/ConfigDrivenAwsCredentialsConfigProvider.java +++ b/aws-common/src/main/java/io/druid/common/aws/ConfigDrivenAwsCredentialsConfigProvider.java @@ -36,23 +36,25 @@ public class ConfigDrivenAwsCredentialsConfigProvider implements AWSCredentialsP @Override public AWSCredentials getCredentials() { - if (!Strings.isNullOrEmpty(config.getAccessKey()) && !Strings.isNullOrEmpty(config.getSecretKey())) { - return new AWSCredentials() + final String key = config.getAccessKey().getPassword(); + final String secret = config.getSecretKey().getPassword(); + if (!Strings.isNullOrEmpty(key) && !Strings.isNullOrEmpty(secret)) { + return new AWSCredentials() + { + @Override + public String getAWSAccessKeyId() { - @Override - public String getAWSAccessKeyId() - { - return config.getAccessKey(); - } + return key; + } - @Override - public String getAWSSecretKey() - { - return config.getSecretKey(); - } - }; - } - throw new AmazonClientException("Unable to load AWS credentials from druid AWSCredentialsConfig"); + @Override + public String getAWSSecretKey() + { + return secret; + } + }; + } + throw new AmazonClientException("Unable to load AWS credentials from druid AWSCredentialsConfig"); } @Override diff --git a/aws-common/src/test/java/io/druid/common/aws/AWSCredentialsConfigTest.java b/aws-common/src/test/java/io/druid/common/aws/AWSCredentialsConfigTest.java new file mode 100644 index 00000000000..daa66c557d0 --- /dev/null +++ b/aws-common/src/test/java/io/druid/common/aws/AWSCredentialsConfigTest.java @@ -0,0 +1,110 @@ +/* + * Licensed to Metamarkets Group Inc. (Metamarkets) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Metamarkets licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.druid.common.aws; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Scopes; +import com.google.inject.name.Names; +import io.druid.guice.JsonConfigProvider; +import io.druid.guice.JsonConfigurator; +import io.druid.guice.LazySingleton; +import io.druid.metadata.DefaultPasswordProvider; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import javax.validation.Validation; +import javax.validation.Validator; +import java.util.Properties; +import java.util.UUID; + +public class AWSCredentialsConfigTest +{ + private static final String PROPERTY_PREFIX = UUID.randomUUID().toString(); + private static final String SOME_SECRET = "someSecret"; + private final Properties properties = new Properties(); + + @Before + public void setUp() + { + cleanProperties(); + } + + @After + public void tearDown() + { + cleanProperties(); + } + + private void cleanProperties() + { + properties.clear(); + } + + @Test + public void testStringProperty() + { + properties.put(PROPERTY_PREFIX + ".accessKey", SOME_SECRET); + properties.put(PROPERTY_PREFIX + ".secretKey", SOME_SECRET); + + final Injector injector = Guice.createInjector( + binder -> { + binder.bindConstant().annotatedWith(Names.named("serviceName")).to("druid/test/redis"); + binder.bindConstant().annotatedWith(Names.named("servicePort")).to(0); + binder.bindConstant().annotatedWith(Names.named("tlsServicePort")).to(-1); + binder.bind(Validator.class).toInstance(Validation.buildDefaultValidatorFactory().getValidator()); + binder.bindScope(LazySingleton.class, Scopes.SINGLETON); + binder.bind(JsonConfigurator.class).in(LazySingleton.class); + binder.bind(Properties.class).toInstance(properties); + JsonConfigProvider.bind(binder, PROPERTY_PREFIX, AWSCredentialsConfig.class); + } + ); + final AWSCredentialsConfig credentialsConfig = injector.getInstance(AWSCredentialsConfig.class); + Assert.assertEquals(SOME_SECRET, credentialsConfig.getAccessKey().getPassword()); + Assert.assertEquals(SOME_SECRET, credentialsConfig.getSecretKey().getPassword()); + } + + @Test + public void testJsonProperty() throws Exception + { + final String someSecret = new ObjectMapper().writeValueAsString(new DefaultPasswordProvider(SOME_SECRET)); + properties.put(PROPERTY_PREFIX + ".accessKey", someSecret); + properties.put(PROPERTY_PREFIX + ".secretKey", someSecret); + + final Injector injector = Guice.createInjector( + binder -> { + binder.bindConstant().annotatedWith(Names.named("serviceName")).to("druid/test/redis"); + binder.bindConstant().annotatedWith(Names.named("servicePort")).to(0); + binder.bindConstant().annotatedWith(Names.named("tlsServicePort")).to(-1); + binder.bind(Validator.class).toInstance(Validation.buildDefaultValidatorFactory().getValidator()); + binder.bindScope(LazySingleton.class, Scopes.SINGLETON); + binder.bind(JsonConfigurator.class).in(LazySingleton.class); + binder.bind(Properties.class).toInstance(properties); + JsonConfigProvider.bind(binder, PROPERTY_PREFIX, AWSCredentialsConfig.class); + } + ); + final AWSCredentialsConfig credentialsConfig = injector.getInstance(AWSCredentialsConfig.class); + Assert.assertEquals(SOME_SECRET, credentialsConfig.getAccessKey().getPassword()); + Assert.assertEquals(SOME_SECRET, credentialsConfig.getSecretKey().getPassword()); + } +} diff --git a/extensions-core/s3-extensions/src/test/java/io/druid/storage/s3/TestAWSCredentialsProvider.java b/extensions-core/s3-extensions/src/test/java/io/druid/storage/s3/TestAWSCredentialsProvider.java index 17aa5f87ec7..a3bf27a40b4 100644 --- a/extensions-core/s3-extensions/src/test/java/io/druid/storage/s3/TestAWSCredentialsProvider.java +++ b/extensions-core/s3-extensions/src/test/java/io/druid/storage/s3/TestAWSCredentialsProvider.java @@ -25,6 +25,7 @@ import com.amazonaws.auth.AWSSessionCredentials; import com.google.common.io.Files; import io.druid.common.aws.AWSCredentialsConfig; import io.druid.guice.AWSModule; +import io.druid.metadata.DefaultPasswordProvider; import org.easymock.EasyMock; import org.junit.Rule; import org.junit.Test; @@ -47,8 +48,8 @@ public class TestAWSCredentialsProvider public void testWithFixedAWSKeys() { AWSCredentialsConfig config = EasyMock.createMock(AWSCredentialsConfig.class); - EasyMock.expect(config.getAccessKey()).andReturn("accessKeySample").atLeastOnce(); - EasyMock.expect(config.getSecretKey()).andReturn("secretKeySample").atLeastOnce(); + EasyMock.expect(config.getAccessKey()).andReturn(new DefaultPasswordProvider("accessKeySample")).atLeastOnce(); + EasyMock.expect(config.getSecretKey()).andReturn(new DefaultPasswordProvider("secretKeySample")).atLeastOnce(); EasyMock.replay(config); AWSCredentialsProvider provider = awsModule.getAWSCredentialsProvider(config); @@ -67,8 +68,8 @@ public class TestAWSCredentialsProvider public void testWithFileSessionCredentials() throws IOException { AWSCredentialsConfig config = EasyMock.createMock(AWSCredentialsConfig.class); - EasyMock.expect(config.getAccessKey()).andReturn(""); - EasyMock.expect(config.getSecretKey()).andReturn(""); + EasyMock.expect(config.getAccessKey()).andReturn(new DefaultPasswordProvider("")); + EasyMock.expect(config.getSecretKey()).andReturn(new DefaultPasswordProvider("")); File file = folder.newFile(); try (BufferedWriter out = Files.newWriter(file, StandardCharsets.UTF_8)) { out.write("sessionToken=sessionTokenSample\nsecretKey=secretKeySample\naccessKey=accessKeySample\n");