瀏覽代碼

Scripting: Augment String with sha1 and sha256 (#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: #59647
Stuart Tettemer 5 年之前
父節點
當前提交
3c85272561

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

@@ -48,6 +48,7 @@ import org.elasticsearch.plugins.ScriptPlugin;
 import org.elasticsearch.repositories.RepositoriesService;
 import org.elasticsearch.rest.RestController;
 import org.elasticsearch.rest.RestHandler;
+import org.elasticsearch.script.IngestScript;
 import org.elasticsearch.script.ScoreScript;
 import org.elasticsearch.script.ScriptContext;
 import org.elasticsearch.script.ScriptEngine;
@@ -90,6 +91,11 @@ public final class PainlessPlugin extends Plugin implements ScriptPlugin, Extens
         scoreFn.add(WhitelistLoader.loadFromResourceFiles(Whitelist.class, "org.elasticsearch.score.txt"));
         map.put(ScoreScript.CONTEXT, scoreFn);
 
+        // Functions available to ingest pipelines
+        List<Whitelist> ingest = new ArrayList<>(Whitelist.BASE_WHITELISTS);
+        ingest.add(WhitelistLoader.loadFromResourceFiles(Whitelist.class, "org.elasticsearch.ingest.txt"));
+        map.put(IngestScript.CONTEXT, ingest);
+
         whitelists = map;
     }
 

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

@@ -19,6 +19,8 @@
 
 package org.elasticsearch.painless.api;
 
+import org.elasticsearch.common.hash.MessageDigests;
+
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Base64;
@@ -665,4 +667,16 @@ public class Augmentation {
         throw new IllegalArgumentException(
             String.format(Locale.ROOT, format, obj.getClass().getName(), elements[i], i, String.join(".", elements)));
     }
+
+    public static String sha1(String source) {
+        return MessageDigests.toHexString(
+            MessageDigests.sha1().digest(source.getBytes(StandardCharsets.UTF_8))
+        );
+    }
+
+    public static String sha256(String source) {
+        return MessageDigests.toHexString(
+            MessageDigests.sha256().digest(source.getBytes(StandardCharsets.UTF_8))
+        );
+    }
 }

+ 25 - 0
modules/lang-painless/src/main/resources/org/elasticsearch/painless/spi/org.elasticsearch.ingest.txt

@@ -0,0 +1,25 @@
+#
+# Licensed to Elasticsearch under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Elasticsearch licenses this file to you under
+# the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# This file contains a whitelist for the ingest scripts
+
+class java.lang.String {
+  String org.elasticsearch.painless.api.Augmentation sha1()
+  String org.elasticsearch.painless.api.Augmentation sha256()
+}

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

@@ -19,14 +19,41 @@
 
 package org.elasticsearch.painless;
 
+import org.elasticsearch.painless.spi.Whitelist;
+import org.elasticsearch.painless.spi.WhitelistLoader;
+import org.elasticsearch.script.ScriptContext;
+
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.regex.Pattern;
 
 public class AugmentationTests extends ScriptTestCase {
 
+    @Override
+    protected Map<ScriptContext<?>, List<Whitelist>> scriptContexts() {
+        Map<ScriptContext<?>, List<Whitelist>> contexts = super.scriptContexts();
+        List<Whitelist> digestWhitelist = new ArrayList<>(Whitelist.BASE_WHITELISTS);
+        digestWhitelist.add(WhitelistLoader.loadFromResourceFiles(Whitelist.class, "org.elasticsearch.ingest.txt"));
+        contexts.put(DigestTestScript.CONTEXT, digestWhitelist);
+
+        return contexts;
+    }
+
+    public abstract static class DigestTestScript {
+        public static final String[] PARAMETERS = {};
+        public abstract String execute();
+        public interface Factory {
+            DigestTestScript newInstance();
+        }
+
+        public static final ScriptContext<DigestTestScript.Factory> CONTEXT =
+            new ScriptContext<>("test", DigestTestScript.Factory.class);
+    }
+
     public void testStatic() {
         assertEquals(1, exec("ArrayList l = new ArrayList(); l.add(1); return l.getLength();"));
         assertEquals(1, exec("ArrayList l = new ArrayList(); l.add(1); return l.length;"));
@@ -238,4 +265,24 @@ public class AugmentationTests extends ScriptTestCase {
             );
         }
     }
+
+    public String execDigest(String script) {
+        return scriptEngine.compile(
+            "digest_test",
+            script,
+            DigestTestScript.CONTEXT, Collections.emptyMap()
+        ).newInstance().execute();
+    }
+
+    public void testSha1() {
+        assertEquals("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33", execDigest("'foo'.sha1()"));
+        assertEquals("62cdb7020ff920e5aa642c3d4066950dd1f01f4d", execDigest("'bar'.sha1()"));
+        assertEquals("5f5513f8822fdbe5145af33b64d8d970dcf95c6e", execDigest("'foobarbaz'.sha1()"));
+    }
+
+    public void testSha256() {
+        assertEquals("2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", execDigest("'foo'.sha256()"));
+        assertEquals("fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9", execDigest("'bar'.sha256()"));
+        assertEquals("97df3588b5a3f24babc3851b372f0ba71a9dcdded43b14b9d06961bfc1707d9d", execDigest("'foobarbaz'.sha256()"));
+    }
 }