Settings: Fix secure settings by prefix (#25064)

This commit fixes a bug in retrieving a sub Settings object for a given
prefix with secure settings. Before this commit the returned Settings
would be filtered by the prefix, but the found setting names would not
have the prefix removed.
This commit is contained in:
Ryan Ernst 2017-06-06 00:11:33 -07:00 committed by GitHub
parent e51246023a
commit ac82824d80
2 changed files with 21 additions and 8 deletions

View File

@ -219,7 +219,7 @@ public final class Settings implements ToXContent {
*/
public Settings getByPrefix(String prefix) {
return new Settings(new FilteredMap(this.settings, (k) -> k.startsWith(prefix), prefix), secureSettings == null ? null :
new PrefixedSecureSettings(secureSettings, s -> prefix + s, s -> s.startsWith(prefix)));
new PrefixedSecureSettings(secureSettings, prefix, s -> s.startsWith(prefix)));
}
/**
@ -227,7 +227,7 @@ public final class Settings implements ToXContent {
*/
public Settings filter(Predicate<String> predicate) {
return new Settings(new FilteredMap(this.settings, predicate, null), secureSettings == null ? null :
new PrefixedSecureSettings(secureSettings, UnaryOperator.identity(), predicate));
new PrefixedSecureSettings(secureSettings, "", predicate));
}
/**
@ -1281,13 +1281,15 @@ public final class Settings implements ToXContent {
private static class PrefixedSecureSettings implements SecureSettings {
private final SecureSettings delegate;
private final UnaryOperator<String> keyTransform;
private final UnaryOperator<String> addPrefix;
private final UnaryOperator<String> removePrefix;
private final Predicate<String> keyPredicate;
private final SetOnce<Set<String>> settingNames = new SetOnce<>();
PrefixedSecureSettings(SecureSettings delegate, UnaryOperator<String> keyTransform, Predicate<String> keyPredicate) {
PrefixedSecureSettings(SecureSettings delegate, String prefix, Predicate<String> keyPredicate) {
this.delegate = delegate;
this.keyTransform = keyTransform;
this.addPrefix = s -> prefix + s;
this.removePrefix = s -> s.substring(prefix.length());
this.keyPredicate = keyPredicate;
}
@ -1300,7 +1302,8 @@ public final class Settings implements ToXContent {
public Set<String> getSettingNames() {
synchronized (settingNames) {
if (settingNames.get() == null) {
Set<String> names = delegate.getSettingNames().stream().filter(keyPredicate).collect(Collectors.toSet());
Set<String> names = delegate.getSettingNames().stream()
.filter(keyPredicate).map(removePrefix).collect(Collectors.toSet());
settingNames.set(Collections.unmodifiableSet(names));
}
}
@ -1309,12 +1312,12 @@ public final class Settings implements ToXContent {
@Override
public SecureString getString(String setting) throws GeneralSecurityException{
return delegate.getString(keyTransform.apply(setting));
return delegate.getString(addPrefix.apply(setting));
}
@Override
public InputStream getFile(String setting) throws GeneralSecurityException{
return delegate.getFile(keyTransform.apply(setting));
return delegate.getFile(addPrefix.apply(setting));
}
@Override

View File

@ -515,6 +515,16 @@ public class SettingsTests extends ESTestCase {
expectThrows(NoSuchElementException.class, () -> prefixIterator.next());
}
public void testSecureSettingsPrefix() {
MockSecureSettings secureSettings = new MockSecureSettings();
secureSettings.setString("test.prefix.foo", "somethingsecure");
Settings.Builder builder = Settings.builder();
builder.setSecureSettings(secureSettings);
Settings settings = builder.build();
Settings prefixSettings = settings.getByPrefix("test.prefix.");
assertTrue(prefixSettings.names().contains("foo"));
}
public void testEmptyFilterMap() {
Settings.Builder builder = Settings.builder();
builder.put("a", "a1");