Make AWSCredentialsConfig use PasswordProvider for the string matter (#4613)

* Make AWSCredentialsConfig use PasswordProvider for the string matter
* Fixes https://github.com/druid-io/druid/issues/3911

* Add unit tests
This commit is contained in:
Charles Allen 2017-07-29 15:48:49 -07:00 committed by Gian Merlino
parent f4ba7a68ab
commit 8921538251
4 changed files with 138 additions and 23 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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());
}
}

View File

@ -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");