Skip to content

Commit 8f4510a

Browse files
committed
Use string-based config. Make the allowlists easier to work with
1 parent 3638e7b commit 8f4510a

8 files changed

Lines changed: 278 additions & 147 deletions

File tree

src/main/java/com/hubspot/jinjava/JinjavaConfig.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
import org.immutables.value.Value;
5454

5555
@Value.Immutable(singleton = true)
56-
@JinjavaImmutableStyle
56+
@JinjavaImmutableStyle.WithStyle
5757
public interface JinjavaConfig {
5858
@Value.Default
5959
default Charset getCharset() {
@@ -164,7 +164,9 @@ default TokenScannerSymbols getTokenScannerSymbols() {
164164

165165
@Value.Default
166166
default MethodValidator getMethodValidator() {
167-
return MethodValidator.create(MethodValidatorConfig.of());
167+
return MethodValidator.create(
168+
MethodValidatorConfig.builder().addDefaultAllowlistGroups().build()
169+
);
168170
}
169171

170172
@Value.Default

src/main/java/com/hubspot/jinjava/JinjavaImmutableStyle.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,20 @@
66
import org.immutables.value.Value;
77

88
@Value.Style(
9-
init = "with*",
9+
init = "set*",
1010
get = { "is*", "get*" } // Detect 'get' and 'is' prefixes in accessor methods
1111
)
1212
@ImmutableSetEncodingEnabled
1313
@ImmutableListEncodingEnabled
1414
@ImmutableMapEncodingEnabled
1515
public @interface JinjavaImmutableStyle {
16+
@Value.Style(
17+
init = "with*",
18+
get = { "is*", "get*" } // Detect 'get' and 'is' prefixes in accessor methods
19+
)
20+
@ImmutableSetEncodingEnabled
21+
@ImmutableListEncodingEnabled
22+
@ImmutableMapEncodingEnabled
23+
@interface WithStyle {
24+
}
1625
}

src/main/java/com/hubspot/jinjava/el/ext/JinjavaBeanELResolver.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ public JinjavaBeanELResolver() {
4545
this(true, MethodValidator.create(MethodValidatorConfig.builder().build()));
4646
}
4747

48+
public JinjavaBeanELResolver(MethodValidator methodValidator) {
49+
this(true, methodValidator);
50+
}
51+
4852
/**
4953
* Creates a new read/write {@link JinjavaBeanELResolver}.
5054
*/

src/main/java/com/hubspot/jinjava/el/ext/MethodAllowlists.java

Lines changed: 0 additions & 53 deletions
This file was deleted.

src/main/java/com/hubspot/jinjava/el/ext/MethodValidator.java

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,45 +6,65 @@
66
public final class MethodValidator {
77

88
private final ImmutableSet<Method> allowedMethods;
9-
private final ImmutableSet<Class<?>> allowedDeclaredMethodsFromClasses;
10-
private final ImmutableSet<String> allowedDeclaredMethodsFromPackages;
11-
private final ImmutableSet<Class<?>> allowedResultClasses;
12-
private final ImmutableSet<String> allowedResultPackages;
9+
private final ImmutableSet<String> allowedDeclaredMethodsFromCanonicalClassPrefixes;
10+
private final ImmutableSet<String> allowedDeclaredMethodsFromCanonicalClassNames;
11+
private final ImmutableSet<String> allowedResultCanonicalClassPrefixes;
12+
private final ImmutableSet<String> allowedResultCanonicalClassNames;
1313

1414
public static MethodValidator create(MethodValidatorConfig methodValidatorConfig) {
1515
return new MethodValidator(methodValidatorConfig);
1616
}
1717

1818
private MethodValidator(MethodValidatorConfig methodValidatorConfig) {
1919
this.allowedMethods = methodValidatorConfig.allowedMethods();
20-
this.allowedDeclaredMethodsFromClasses =
21-
methodValidatorConfig.allowedDeclaredMethodsFromClasses();
22-
this.allowedDeclaredMethodsFromPackages =
23-
methodValidatorConfig.allowedDeclaredMethodsFromPackages();
24-
this.allowedResultClasses = methodValidatorConfig.allowedResultClasses();
25-
this.allowedResultPackages = methodValidatorConfig.allowedResultPackages();
20+
this.allowedDeclaredMethodsFromCanonicalClassPrefixes =
21+
methodValidatorConfig.allowedDeclaredMethodsFromCanonicalClassPrefixes();
22+
this.allowedDeclaredMethodsFromCanonicalClassNames =
23+
methodValidatorConfig.allowedDeclaredMethodsFromCanonicalClassNames();
24+
this.allowedResultCanonicalClassPrefixes =
25+
ImmutableSet
26+
.<String>builder()
27+
.addAll(methodValidatorConfig.allowedResultCanonicalClassPrefixes())
28+
.addAll(methodValidatorConfig.allowedDeclaredMethodsFromCanonicalClassPrefixes())
29+
.build();
30+
this.allowedResultCanonicalClassNames =
31+
ImmutableSet
32+
.<String>builder()
33+
.addAll(methodValidatorConfig.allowedResultCanonicalClassNames())
34+
.addAll(methodValidatorConfig.allowedDeclaredMethodsFromCanonicalClassNames())
35+
.build();
2636
}
2737

2838
public Method validateMethod(Method m) {
39+
if (m == null) {
40+
return null;
41+
}
42+
String canonicalDeclaringClassName = m.getDeclaringClass().getCanonicalName();
2943
return (
30-
m == null ||
3144
allowedMethods.contains(m) ||
32-
allowedDeclaredMethodsFromClasses.contains(m.getDeclaringClass()) ||
33-
allowedDeclaredMethodsFromPackages
45+
allowedDeclaredMethodsFromCanonicalClassNames.contains(
46+
canonicalDeclaringClassName
47+
) ||
48+
allowedDeclaredMethodsFromCanonicalClassPrefixes
3449
.stream()
35-
.anyMatch(p -> m.getDeclaringClass().getPackageName().startsWith(p))
50+
.anyMatch(canonicalDeclaringClassName::startsWith)
3651
)
3752
? m
3853
: null;
3954
}
4055

4156
public Object validateResult(Object o) {
57+
if (o == null) {
58+
return null;
59+
}
60+
String canonicalClassName = o.getClass().getCanonicalName();
4261
return (
43-
o == null ||
44-
allowedResultClasses.contains(o.getClass()) ||
45-
allowedResultPackages
46-
.stream()
47-
.anyMatch(p -> o.getClass().getPackageName().startsWith(p))
48-
);
62+
allowedResultCanonicalClassNames.contains(canonicalClassName) ||
63+
allowedResultCanonicalClassPrefixes
64+
.stream()
65+
.anyMatch(canonicalClassName::startsWith)
66+
)
67+
? o
68+
: null;
4969
}
5070
}

0 commit comments

Comments
 (0)