Skip to content

Commit 3c85272

Browse files
authored
Scripting: Augment String with sha1 and sha256 (elastic#59671)
Only available in the ingest context for use in ingest pipelines. Digests are computed on the UTF-8 encoding of the String and are returned as hex strings. sha1() return hex strings of length 40, sha256() returns length 64 Fixes: elastic#59647
1 parent 1dff3eb commit 3c85272

File tree

4 files changed

+92
-0
lines changed

4 files changed

+92
-0
lines changed

modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java

+6
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import org.elasticsearch.repositories.RepositoriesService;
4949
import org.elasticsearch.rest.RestController;
5050
import org.elasticsearch.rest.RestHandler;
51+
import org.elasticsearch.script.IngestScript;
5152
import org.elasticsearch.script.ScoreScript;
5253
import org.elasticsearch.script.ScriptContext;
5354
import org.elasticsearch.script.ScriptEngine;
@@ -90,6 +91,11 @@ public final class PainlessPlugin extends Plugin implements ScriptPlugin, Extens
9091
scoreFn.add(WhitelistLoader.loadFromResourceFiles(Whitelist.class, "org.elasticsearch.score.txt"));
9192
map.put(ScoreScript.CONTEXT, scoreFn);
9293

94+
// Functions available to ingest pipelines
95+
List<Whitelist> ingest = new ArrayList<>(Whitelist.BASE_WHITELISTS);
96+
ingest.add(WhitelistLoader.loadFromResourceFiles(Whitelist.class, "org.elasticsearch.ingest.txt"));
97+
map.put(IngestScript.CONTEXT, ingest);
98+
9399
whitelists = map;
94100
}
95101

modules/lang-painless/src/main/java/org/elasticsearch/painless/api/Augmentation.java

+14
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
package org.elasticsearch.painless.api;
2121

22+
import org.elasticsearch.common.hash.MessageDigests;
23+
2224
import java.nio.charset.StandardCharsets;
2325
import java.util.ArrayList;
2426
import java.util.Base64;
@@ -665,4 +667,16 @@ private static Object handleMissing(Object obj, String[] elements, int i, Suppli
665667
throw new IllegalArgumentException(
666668
String.format(Locale.ROOT, format, obj.getClass().getName(), elements[i], i, String.join(".", elements)));
667669
}
670+
671+
public static String sha1(String source) {
672+
return MessageDigests.toHexString(
673+
MessageDigests.sha1().digest(source.getBytes(StandardCharsets.UTF_8))
674+
);
675+
}
676+
677+
public static String sha256(String source) {
678+
return MessageDigests.toHexString(
679+
MessageDigests.sha256().digest(source.getBytes(StandardCharsets.UTF_8))
680+
);
681+
}
668682
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#
2+
# Licensed to Elasticsearch under one or more contributor
3+
# license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright
5+
# ownership. Elasticsearch licenses this file to you under
6+
# the Apache License, Version 2.0 (the "License"); you may
7+
# not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
#
19+
20+
# This file contains a whitelist for the ingest scripts
21+
22+
class java.lang.String {
23+
String org.elasticsearch.painless.api.Augmentation sha1()
24+
String org.elasticsearch.painless.api.Augmentation sha256()
25+
}

modules/lang-painless/src/test/java/org/elasticsearch/painless/AugmentationTests.java

+47
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,41 @@
1919

2020
package org.elasticsearch.painless;
2121

22+
import org.elasticsearch.painless.spi.Whitelist;
23+
import org.elasticsearch.painless.spi.WhitelistLoader;
24+
import org.elasticsearch.script.ScriptContext;
25+
26+
import java.util.ArrayList;
2227
import java.util.Arrays;
2328
import java.util.Collections;
2429
import java.util.HashMap;
30+
import java.util.List;
2531
import java.util.Map;
2632
import java.util.regex.Pattern;
2733

2834
public class AugmentationTests extends ScriptTestCase {
2935

36+
@Override
37+
protected Map<ScriptContext<?>, List<Whitelist>> scriptContexts() {
38+
Map<ScriptContext<?>, List<Whitelist>> contexts = super.scriptContexts();
39+
List<Whitelist> digestWhitelist = new ArrayList<>(Whitelist.BASE_WHITELISTS);
40+
digestWhitelist.add(WhitelistLoader.loadFromResourceFiles(Whitelist.class, "org.elasticsearch.ingest.txt"));
41+
contexts.put(DigestTestScript.CONTEXT, digestWhitelist);
42+
43+
return contexts;
44+
}
45+
46+
public abstract static class DigestTestScript {
47+
public static final String[] PARAMETERS = {};
48+
public abstract String execute();
49+
public interface Factory {
50+
DigestTestScript newInstance();
51+
}
52+
53+
public static final ScriptContext<DigestTestScript.Factory> CONTEXT =
54+
new ScriptContext<>("test", DigestTestScript.Factory.class);
55+
}
56+
3057
public void testStatic() {
3158
assertEquals(1, exec("ArrayList l = new ArrayList(); l.add(1); return l.getLength();"));
3259
assertEquals(1, exec("ArrayList l = new ArrayList(); l.add(1); return l.length;"));
@@ -238,4 +265,24 @@ public void testString_SplitOnToken() {
238265
);
239266
}
240267
}
268+
269+
public String execDigest(String script) {
270+
return scriptEngine.compile(
271+
"digest_test",
272+
script,
273+
DigestTestScript.CONTEXT, Collections.emptyMap()
274+
).newInstance().execute();
275+
}
276+
277+
public void testSha1() {
278+
assertEquals("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33", execDigest("'foo'.sha1()"));
279+
assertEquals("62cdb7020ff920e5aa642c3d4066950dd1f01f4d", execDigest("'bar'.sha1()"));
280+
assertEquals("5f5513f8822fdbe5145af33b64d8d970dcf95c6e", execDigest("'foobarbaz'.sha1()"));
281+
}
282+
283+
public void testSha256() {
284+
assertEquals("2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", execDigest("'foo'.sha256()"));
285+
assertEquals("fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9", execDigest("'bar'.sha256()"));
286+
assertEquals("97df3588b5a3f24babc3851b372f0ba71a9dcdded43b14b9d06961bfc1707d9d", execDigest("'foobarbaz'.sha256()"));
287+
}
241288
}

0 commit comments

Comments
 (0)