Browse Source

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.
Ryan Ernst 8 years ago
parent
commit
ac82824d80

+ 11 - 8
core/src/main/java/org/elasticsearch/common/settings/Settings.java

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

+ 10 - 0
core/src/test/java/org/elasticsearch/common/settings/SettingsTests.java

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