Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.x] Deprecate 'Whitelist' classes in package 'org.opensearch.painless.spi' and create alternative 'Allowlist' classes #4101

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.painless.spi;

import org.opensearch.painless.spi.annotation.WhitelistAnnotationParser;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* Allowlist contains data structures designed to be used to generate an allowlist of Java classes,
* constructors, methods, and fields that can be used within a Painless script at both compile-time
* and run-time.
*
* An Allowlist consists of several pieces with {@link AllowlistClass}s as the top level. Each
* {@link AllowlistClass} will contain zero-to-many {@link AllowlistConstructor}s, {@link AllowlistMethod}s, and
* {@link AllowlistField}s which are what will be available with a Painless script. See each individual
* allowlist object for more detail.
*/
public final class Allowlist extends Whitelist {

public static final List<Allowlist> BASE_ALLOWLISTS = Collections.singletonList(
AllowlistLoader.loadFromResourceFiles(Allowlist.class, WhitelistAnnotationParser.BASE_ANNOTATION_PARSERS, BASE_ALLOWLIST_FILES)
);

/** The {@link List} of all the allowlisted Painless classes. */
public final List<AllowlistClass> allowlistClasses;

/** The {@link List} of all the allowlisted static Painless methods. */
public final List<AllowlistMethod> allowlistImportedMethods;

/** The {@link List} of all the allowlisted Painless class bindings. */
public final List<AllowlistClassBinding> allowlistClassBindings;

/** The {@link List} of all the allowlisted Painless instance bindings. */
public final List<AllowlistInstanceBinding> allowlistInstanceBindings;

/** Standard constructor. All values must be not {@code null}. */
public Allowlist(
ClassLoader classLoader,
List<AllowlistClass> allowlistClasses,
List<AllowlistMethod> allowlistImportedMethods,
List<AllowlistClassBinding> allowlistClassBindings,
List<AllowlistInstanceBinding> allowlistInstanceBindings
) {
super(
classLoader,
allowlistClasses.stream().map(e -> (WhitelistClass) e).collect(Collectors.toList()),
allowlistImportedMethods.stream().map(e -> (WhitelistMethod) e).collect(Collectors.toList()),
allowlistClassBindings.stream().map(e -> (WhitelistClassBinding) e).collect(Collectors.toList()),
allowlistInstanceBindings.stream().map(e -> (WhitelistInstanceBinding) e).collect(Collectors.toList())
);

this.allowlistClasses = Collections.unmodifiableList(Objects.requireNonNull(allowlistClasses));
this.allowlistImportedMethods = Collections.unmodifiableList(Objects.requireNonNull(allowlistImportedMethods));
this.allowlistClassBindings = Collections.unmodifiableList(Objects.requireNonNull(allowlistClassBindings));
this.allowlistInstanceBindings = Collections.unmodifiableList(Objects.requireNonNull(allowlistInstanceBindings));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.painless.spi;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* Class represents the equivalent of a Java class in Painless complete with super classes,
* constructors, methods, and fields. There must be a one-to-one mapping of class names to Java
* classes. Though, since multiple allowlists may be combined into a single allowlist for a
* specific context, as long as multiple classes representing the same Java class have the same
* class name and have legal constructor/method overloading they can be merged together.
*
* Classes in Painless allow for arity overloading for constructors and methods. Arity overloading
* means that multiple constructors are allowed for a single class as long as they have a different
* number of parameters, and multiples methods with the same name are allowed for a single class
* as long as they have the same return type and a different number of parameters.
*
* Classes will automatically extend other allowlisted classes if the Java class they represent is a
* subclass of other classes including Java interfaces.
*/
public final class AllowlistClass extends WhitelistClass {

/** The {@link List} of allowlisted ({@link AllowlistConstructor}s) available to this class. */
public final List<AllowlistConstructor> allowlistConstructors;

/** The {@link List} of allowlisted ({@link AllowlistMethod}s) available to this class. */
public final List<AllowlistMethod> allowlistMethods;

/** The {@link List} of allowlisted ({@link AllowlistField}s) available to this class. */
public final List<AllowlistField> allowlistFields;

/** Standard constructor. All values must be not {@code null}. */
public AllowlistClass(
String origin,
String javaClassName,
List<AllowlistConstructor> allowlistConstructors,
List<AllowlistMethod> allowlistMethods,
List<AllowlistField> allowlistFields,
List<Object> painlessAnnotations
) {
super(
origin,
javaClassName,
allowlistConstructors.stream().map(e -> (WhitelistConstructor) e).collect(Collectors.toList()),
allowlistMethods.stream().map(e -> (WhitelistMethod) e).collect(Collectors.toList()),
allowlistFields.stream().map(e -> (WhitelistField) e).collect(Collectors.toList()),
painlessAnnotations
);

this.allowlistConstructors = Collections.unmodifiableList(Objects.requireNonNull(allowlistConstructors));
this.allowlistMethods = Collections.unmodifiableList(Objects.requireNonNull(allowlistMethods));
this.allowlistFields = Collections.unmodifiableList(Objects.requireNonNull(allowlistFields));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.painless.spi;

import java.util.List;

/**
* A class binding represents a method call that stores state. Each class binding's Java class must
* have exactly one public constructor and one public method excluding those inherited directly
* from {@link Object}. The canonical type name parameters provided must match those of the
* constructor and method combined. The constructor for a class binding's Java class will be called
* when the binding method is called for the first time at which point state may be stored for the
* arguments passed into the constructor. The method for a binding class will be called each time
* the binding method is called and may use the previously stored state.
*/
public class AllowlistClassBinding extends WhitelistClassBinding {
/**
* Standard constructor. All values must be not {@code null}.
*/
public AllowlistClassBinding(
String origin,
String targetJavaClassName,
String methodName,
String returnCanonicalTypeName,
List<String> canonicalTypeNameParameters,
List<Object> painlessAnnotations
) {
super(origin, targetJavaClassName, methodName, returnCanonicalTypeName, canonicalTypeNameParameters, painlessAnnotations);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.painless.spi;

import java.util.List;

/**
* Constructor represents the equivalent of a Java constructor available as a allowlisted class
* constructor within Painless. Constructors for Painless classes may be accessed exactly as
* constructors for Java classes are using the 'new' keyword. Painless classes may have multiple
* constructors as long as they comply with arity overloading described for {@link AllowlistClass}.
*/
public final class AllowlistConstructor extends WhitelistConstructor {
/**
* Standard constructor. All values must be not {@code null}.
*/
AllowlistConstructor(String origin, List<String> canonicalTypeNameParameters, List<Object> painlessAnnotations) {
super(origin, canonicalTypeNameParameters, painlessAnnotations);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.painless.spi;

import java.util.List;

/**
* Field represents the equivalent of a Java field available as an allowlisted class field
* within Painless. Fields for Painless classes may be accessed exactly as fields for Java classes
* are using the '.' operator on an existing class variable/field.
*/
public class AllowlistField extends WhitelistField {
/**
* Standard constructor. All values must be not {@code null}.
*/
public AllowlistField(String origin, String fieldName, String canonicalTypeNameParameter, List<Object> painlessAnnotations) {
super(origin, fieldName, canonicalTypeNameParameter, painlessAnnotations);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.painless.spi;

import java.util.List;

/**
* An instance binding represents a method call that stores state. Each instance binding must provide
* exactly one public method name. The canonical type name parameters provided must match those of the
* method. The method for an instance binding will target the specified Java instance.
*/
public class AllowlistInstanceBinding extends WhitelistInstanceBinding {
/**
* Standard constructor. All values must be not {@code null}.
*/
public AllowlistInstanceBinding(
String origin,
Object targetInstance,
String methodName,
String returnCanonicalTypeName,
List<String> canonicalTypeNameParameters,
List<Object> painlessAnnotations
) {
super(origin, targetInstance, methodName, returnCanonicalTypeName, canonicalTypeNameParameters, painlessAnnotations);
}
}
Loading