Skip to content

Commit 3c918d7

Browse files
sohaibiftikharmartijnvg
authored andcommitted
Deprecate accepting malformed requests in stored script API (#28939)
The stored scripts API today accepts malformed requests instead of throwing an exception. This PR deprecates accepting malformed put stored script requests (requests not using the official script format). Relates to #27612
1 parent eaee530 commit 3c918d7

File tree

5 files changed

+59
-25
lines changed

5 files changed

+59
-25
lines changed

modules/lang-mustache/src/test/java/org/elasticsearch/script/mustache/SearchTemplateIT.java

+4
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ public void testIndexedTemplateClient() throws Exception {
198198

199199
getResponse = client().admin().cluster().prepareGetStoredScript("testTemplate").get();
200200
assertNull(getResponse.getSource());
201+
assertWarnings("the template context is now deprecated. Specify templates in a \"script\" element.");
201202
}
202203

203204
public void testIndexedTemplate() throws Exception {
@@ -267,6 +268,7 @@ public void testIndexedTemplate() throws Exception {
267268
.setScript("2").setScriptType(ScriptType.STORED).setScriptParams(templateParams)
268269
.get();
269270
assertHitCount(searchResponse.getResponse(), 1);
271+
assertWarnings("the template context is now deprecated. Specify templates in a \"script\" element.");
270272
}
271273

272274
// Relates to #10397
@@ -311,6 +313,7 @@ public void testIndexedTemplateOverwrite() throws Exception {
311313
.get();
312314
assertHitCount(searchResponse.getResponse(), 1);
313315
}
316+
assertWarnings("the template context is now deprecated. Specify templates in a \"script\" element.");
314317
}
315318

316319
public void testIndexedTemplateWithArray() throws Exception {
@@ -339,6 +342,7 @@ public void testIndexedTemplateWithArray() throws Exception {
339342
.setScript("4").setScriptType(ScriptType.STORED).setScriptParams(arrayTemplateParams)
340343
.get();
341344
assertHitCount(searchResponse.getResponse(), 5);
345+
assertWarnings("the template context is now deprecated. Specify templates in a \"script\" element.");
342346
}
343347

344348
}

server/src/main/java/org/elasticsearch/script/StoredScriptSource.java

+38-23
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ public class StoredScriptSource extends AbstractDiffable<StoredScriptSource> imp
7474
*/
7575
public static final ParseField TEMPLATE_PARSE_FIELD = new ParseField("template");
7676

77+
/**
78+
* Standard {@link ParseField} for query on the inner field.
79+
*/
80+
public static final ParseField TEMPLATE_NO_WRAPPER_PARSE_FIELD = new ParseField("query");
81+
7782
/**
7883
* Standard {@link ParseField} for lang on the inner level.
7984
*/
@@ -189,6 +194,26 @@ private StoredScriptSource build(boolean ignoreEmpty) {
189194
PARSER.declareField(Builder::setOptions, XContentParser::mapStrings, OPTIONS_PARSE_FIELD, ValueType.OBJECT);
190195
}
191196

197+
private static StoredScriptSource parseRemaining(Token token, XContentParser parser) throws IOException {
198+
try (XContentBuilder builder = XContentFactory.jsonBuilder()) {
199+
if (token != Token.START_OBJECT) {
200+
builder.startObject();
201+
builder.copyCurrentStructure(parser);
202+
builder.endObject();
203+
} else {
204+
builder.copyCurrentStructure(parser);
205+
}
206+
207+
String source = Strings.toString(builder);
208+
209+
if (source == null || source.isEmpty()) {
210+
DEPRECATION_LOGGER.deprecated("empty templates should no longer be used");
211+
}
212+
213+
return new StoredScriptSource(Script.DEFAULT_TEMPLATE_LANG, source, Collections.emptyMap());
214+
}
215+
}
216+
192217
/**
193218
* This will parse XContent into a {@link StoredScriptSource}. The following formats can be parsed:
194219
*
@@ -304,38 +329,28 @@ public static StoredScriptSource parse(BytesReference content, XContentType xCon
304329
} else {
305330
throw new ParsingException(parser.getTokenLocation(), "unexpected token [" + token + "], expected [{, <source>]");
306331
}
307-
} else {
308-
if (TEMPLATE_PARSE_FIELD.getPreferredName().equals(name)) {
309-
token = parser.nextToken();
310-
311-
if (token == Token.VALUE_STRING) {
312-
String source = parser.text();
313-
314-
if (source == null || source.isEmpty()) {
315-
DEPRECATION_LOGGER.deprecated("empty templates should no longer be used");
316-
}
317-
318-
return new StoredScriptSource(Script.DEFAULT_TEMPLATE_LANG, source, Collections.emptyMap());
319-
}
320-
}
332+
} else if (TEMPLATE_PARSE_FIELD.getPreferredName().equals(name)) {
321333

322-
try (XContentBuilder builder = XContentFactory.jsonBuilder()) {
323-
if (token != Token.START_OBJECT) {
324-
builder.startObject();
325-
builder.copyCurrentStructure(parser);
326-
builder.endObject();
327-
} else {
328-
builder.copyCurrentStructure(parser);
329-
}
334+
DEPRECATION_LOGGER.deprecated("the template context is now deprecated. Specify templates in a \"script\" element.");
330335

331-
String source = Strings.toString(builder);
336+
token = parser.nextToken();
337+
if (token == Token.VALUE_STRING) {
338+
String source = parser.text();
332339

333340
if (source == null || source.isEmpty()) {
334341
DEPRECATION_LOGGER.deprecated("empty templates should no longer be used");
335342
}
336343

337344
return new StoredScriptSource(Script.DEFAULT_TEMPLATE_LANG, source, Collections.emptyMap());
345+
} else {
346+
return parseRemaining(token, parser);
338347
}
348+
} else if (TEMPLATE_NO_WRAPPER_PARSE_FIELD.getPreferredName().equals(name)) {
349+
DEPRECATION_LOGGER.deprecated("the template context is now deprecated. Specify templates in a \"script\" element.");
350+
return parseRemaining(token, parser);
351+
} else {
352+
DEPRECATION_LOGGER.deprecated("scripts should not be stored without a context. Specify them in a \"script\" element.");
353+
return parseRemaining(token, parser);
339354
}
340355
} catch (IOException ioe) {
341356
throw new UncheckedIOException(ioe);

server/src/test/java/org/elasticsearch/script/ScriptMetaDataTests.java

+7
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,12 @@ public void testGetScript() throws Exception {
8181
XContentBuilder sourceBuilder = XContentFactory.jsonBuilder();
8282
sourceBuilder.startObject().startObject("template").field("field", "value").endObject().endObject();
8383
builder.storeScript("template", StoredScriptSource.parse(BytesReference.bytes(sourceBuilder), sourceBuilder.contentType()));
84+
assertWarnings("the template context is now deprecated. Specify templates in a \"script\" element.");
8485

8586
sourceBuilder = XContentFactory.jsonBuilder();
8687
sourceBuilder.startObject().field("template", "value").endObject();
8788
builder.storeScript("template_field", StoredScriptSource.parse(BytesReference.bytes(sourceBuilder), sourceBuilder.contentType()));
89+
assertWarnings("the template context is now deprecated. Specify templates in a \"script\" element.");
8890

8991
sourceBuilder = XContentFactory.jsonBuilder();
9092
sourceBuilder.startObject().startObject("script").field("lang", "_lang").field("source", "_source").endObject().endObject();
@@ -99,14 +101,19 @@ public void testGetScript() throws Exception {
99101
public void testDiff() throws Exception {
100102
ScriptMetaData.Builder builder = new ScriptMetaData.Builder(null);
101103
builder.storeScript("1", StoredScriptSource.parse(new BytesArray("{\"foo\":\"abc\"}"), XContentType.JSON));
104+
assertWarnings("scripts should not be stored without a context. Specify them in a \"script\" element.");
102105
builder.storeScript("2", StoredScriptSource.parse(new BytesArray("{\"foo\":\"def\"}"), XContentType.JSON));
106+
assertWarnings("scripts should not be stored without a context. Specify them in a \"script\" element.");
103107
builder.storeScript("3", StoredScriptSource.parse(new BytesArray("{\"foo\":\"ghi\"}"), XContentType.JSON));
108+
assertWarnings("scripts should not be stored without a context. Specify them in a \"script\" element.");
104109
ScriptMetaData scriptMetaData1 = builder.build();
105110

106111
builder = new ScriptMetaData.Builder(scriptMetaData1);
107112
builder.storeScript("2", StoredScriptSource.parse(new BytesArray("{\"foo\":\"changed\"}"), XContentType.JSON));
113+
assertWarnings("scripts should not be stored without a context. Specify them in a \"script\" element.");
108114
builder.deleteScript("3");
109115
builder.storeScript("4", StoredScriptSource.parse(new BytesArray("{\"foo\":\"jkl\"}"), XContentType.JSON));
116+
assertWarnings("scripts should not be stored without a context. Specify them in a \"script\" element.");
110117
ScriptMetaData scriptMetaData2 = builder.build();
111118

112119
ScriptMetaData.ScriptMetadataDiff diff = (ScriptMetaData.ScriptMetadataDiff) scriptMetaData2.diff(scriptMetaData1);

server/src/test/java/org/elasticsearch/script/StoredScriptSourceTests.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ protected StoredScriptSource createTestInstance() {
5050
if (randomBoolean()) {
5151
options.put(Script.CONTENT_TYPE_OPTION, xContentType.mediaType());
5252
}
53-
return StoredScriptSource.parse(BytesReference.bytes(template), xContentType);
53+
StoredScriptSource source = StoredScriptSource.parse(BytesReference.bytes(template), xContentType);
54+
assertWarnings("the template context is now deprecated. Specify templates in a \"script\" element.");
55+
return source;
5456
} catch (IOException e) {
5557
throw new AssertionError("Failed to create test instance", e);
5658
}

server/src/test/java/org/elasticsearch/script/StoredScriptTests.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public void testSourceParsing() throws Exception {
7474
StoredScriptSource source = new StoredScriptSource("mustache", "code", Collections.emptyMap());
7575

7676
assertThat(parsed, equalTo(source));
77+
assertWarnings("the template context is now deprecated. Specify templates in a \"script\" element.");
7778
}
7879

7980
// complex template with wrapper template object
@@ -89,6 +90,7 @@ public void testSourceParsing() throws Exception {
8990
StoredScriptSource source = new StoredScriptSource("mustache", code, Collections.emptyMap());
9091

9192
assertThat(parsed, equalTo(source));
93+
assertWarnings("the template context is now deprecated. Specify templates in a \"script\" element.");
9294
}
9395

9496
// complex template with no wrapper object
@@ -104,6 +106,7 @@ public void testSourceParsing() throws Exception {
104106
StoredScriptSource source = new StoredScriptSource("mustache", code, Collections.emptyMap());
105107

106108
assertThat(parsed, equalTo(source));
109+
assertWarnings("the template context is now deprecated. Specify templates in a \"script\" element.");
107110
}
108111

109112
// complex template using script as the field name
@@ -223,7 +226,10 @@ public void testEmptyTemplateDeprecations() throws IOException {
223226
StoredScriptSource source = new StoredScriptSource(Script.DEFAULT_TEMPLATE_LANG, "", Collections.emptyMap());
224227

225228
assertThat(parsed, equalTo(source));
226-
assertWarnings("empty templates should no longer be used");
229+
assertWarnings(
230+
"the template context is now deprecated. Specify templates in a \"script\" element.",
231+
"empty templates should no longer be used"
232+
);
227233
}
228234

229235
try (XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON)) {

0 commit comments

Comments
 (0)