Skip to content

Commit bfea29d

Browse files
mashhursyaauie
andcommitted
Key pattern is moved to a central config expander class with its description.
Co-authored-by: Rye Biesemeyer <[email protected]>
1 parent 3f6f66d commit bfea29d

File tree

3 files changed

+43
-33
lines changed

3 files changed

+43
-33
lines changed

logstash-core/src/main/java/org/logstash/plugins/ConfigVariableExpander.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,14 @@
3535
* */
3636
public class ConfigVariableExpander implements AutoCloseable {
3737

38-
private static String SUBSTITUTION_PLACEHOLDER_REGEX = "\\$\\{(?<name>[a-zA-Z_.][a-zA-Z0-9_.]*)(:(?<default>[^}]*))?}";
39-
40-
private Pattern substitutionPattern = Pattern.compile(SUBSTITUTION_PLACEHOLDER_REGEX);
41-
private SecretStore secretStore;
42-
private EnvironmentVariableProvider envVarProvider;
38+
public static final Pattern KEY_PATTERN = Pattern.compile("[a-zA-Z_.][a-zA-Z0-9_.]*");
39+
public static final String KEY_PATTERN_DESCRIPTION = "Key names are limited to ASCII letters (`a`-`z`, `A`-`Z`), numbers (`0`-`9`), " +
40+
"underscores (`_`), and dots (`.`); they must be at least one character long and cannot begin with a number";
41+
private static final String SUBSTITUTION_PLACEHOLDER_REGEX = "\\$\\{(?<name>" + KEY_PATTERN + ")(:(?<default>[^}]*))?}";
42+
43+
private static final Pattern substitutionPattern = Pattern.compile(SUBSTITUTION_PLACEHOLDER_REGEX);
44+
private final SecretStore secretStore;
45+
private final EnvironmentVariableProvider envVarProvider;
4346

4447
/**
4548
* Creates a ConfigVariableExpander that doesn't lookup any secreted placeholder.

logstash-core/src/main/java/org/logstash/secret/SecretIdentifier.java

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.logging.log4j.Logger;
2424
import org.apache.logging.log4j.LogManager;
2525
import org.apache.logging.log4j.util.Strings;
26+
import org.logstash.plugins.ConfigVariableExpander;
2627

2728
import java.util.Locale;
2829
import java.util.regex.Pattern;
@@ -33,9 +34,6 @@
3334
*/
3435
public class SecretIdentifier {
3536

36-
// aligns with ConfigVariableExpander substitution pattern
37-
public final static Pattern KEY_PATTERN = Pattern.compile("[a-zA-Z_.][a-zA-Z0-9_.]*");
38-
3937
private final static Pattern colonPattern = Pattern.compile(":");
4038
private final static String VERSION = "v1";
4139
private final static Pattern urnPattern = Pattern.compile("urn:logstash:secret:"+ VERSION + ":.*$");
@@ -66,24 +64,6 @@ public static SecretIdentifier fromExternalForm(final String urn) {
6664
return new SecretIdentifier(validateWithTransform(parts[4], "key"));
6765
}
6866

69-
/**
70-
* Minor validation and downcases the parts
71-
*
72-
* @param key The key, a part of the URN to validate.
73-
* @param partName The name of the part used for logging.
74-
* @return The validated and transformed part.
75-
*/
76-
private static String validateWithTransform(final String key, final String partName) {
77-
if (key == null || key.isEmpty() || Strings.isBlank(key)) {
78-
throw new IllegalArgumentException(String.format("%s may not be null or empty", partName));
79-
}
80-
81-
if (!KEY_PATTERN.matcher(key).matches()) {
82-
logger.warn(String.format("Invalid `%s` key appeared in keystore. Please remove it as it cannot be used in the pipelines", key));
83-
}
84-
return key.toLowerCase(Locale.US);
85-
}
86-
8767
@Override
8868
public boolean equals(Object o) {
8969
if (this == o) return true;
@@ -131,4 +111,31 @@ public String toExternalForm() {
131111
public String toString() {
132112
return toExternalForm();
133113
}
114+
115+
/**
116+
* Validates the provided key against null, empty and {@link ConfigVariableExpander#KEY_PATTERN}
117+
* @param key a key to be validated
118+
* @param keyName a key name
119+
*/
120+
private static void validateKey(final String key, final String keyName) {
121+
if (key == null || key.isEmpty() || Strings.isBlank(key)) {
122+
throw new IllegalArgumentException(String.format("%s may not be null or empty", keyName));
123+
}
124+
125+
if (!ConfigVariableExpander.KEY_PATTERN.matcher(key).matches()) {
126+
logger.warn(String.format("Invalid secret key name `%s` provided.", key) + ConfigVariableExpander.KEY_PATTERN_DESCRIPTION);
127+
}
128+
}
129+
130+
/**
131+
* Minor validation and downcases the parts
132+
*
133+
* @param key The key, a part of the URN to validate.
134+
* @param partName The name of the part used for logging.
135+
* @return The validated and transformed part.
136+
*/
137+
private static String validateWithTransform(final String key, final String partName) {
138+
validateKey(key, partName);
139+
return key.toLowerCase(Locale.US);
140+
}
134141
}

logstash-core/src/main/java/org/logstash/secret/cli/SecretStoreCli.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,12 @@
2020

2121
package org.logstash.secret.cli;
2222

23+
import org.logstash.plugins.ConfigVariableExpander;
2324
import org.logstash.secret.SecretIdentifier;
24-
import org.logstash.secret.store.*;
25+
import org.logstash.secret.store.SecretStore;
26+
import org.logstash.secret.store.SecretStoreFactory;
27+
import org.logstash.secret.store.SecretStoreUtil;
28+
import org.logstash.secret.store.SecureConfig;
2529

2630
import java.nio.CharBuffer;
2731
import java.nio.charset.CharsetEncoder;
@@ -258,12 +262,8 @@ public void command(String primaryCommand, SecureConfig config, String... allArg
258262
if (secretStoreFactory.exists(config.clone())) {
259263
final SecretStore secretStore = secretStoreFactory.load(config);
260264
for (String argument : commandLine.getArguments()) {
261-
if (!SecretIdentifier.KEY_PATTERN.matcher(argument).matches()) {
262-
final String errorMessage = String.format(
263-
"Invalid secret key %s provided. " +
264-
"It can only accept digits, letters with optional `.` " +
265-
"and/or `_` symbols included between or after.", argument);
266-
throw new IllegalArgumentException(errorMessage);
265+
if (!ConfigVariableExpander.KEY_PATTERN.matcher(argument).matches()) {
266+
throw new IllegalArgumentException(String.format("Invalid secret key name `%s` provided.", argument) + ConfigVariableExpander.KEY_PATTERN_DESCRIPTION);
267267
}
268268
final SecretIdentifier id = new SecretIdentifier(argument);
269269
final byte[] existingValue = secretStore.retrieveSecret(id);

0 commit comments

Comments
 (0)