Skip to content

Commit

Permalink
Scripting: Augment String with sha1 and sha256 (#59671) (#59723)
Browse files Browse the repository at this point in the history
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
Backport: 3c85272
  • Loading branch information
stu-elastic authored Jul 16, 2020
1 parent c491212 commit 8fdaed0
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.elasticsearch.plugins.ScriptPlugin;
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;
Expand Down Expand Up @@ -81,6 +82,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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -665,4 +667,16 @@ private static Object handleMissing(Object obj, String[] elements, int i, Suppli
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))
);
}
}
Original file line number Diff line number Diff line change
@@ -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()
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;"));
Expand Down Expand Up @@ -238,4 +265,24 @@ public void testString_SplitOnToken() {
);
}
}

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()"));
}
}

0 comments on commit 8fdaed0

Please sign in to comment.