diff --git a/README.md b/README.md
index 1166491..c315198 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ For adding a library only:
com.instancify.scriptify
core
- 1.3.3-SNAPSHOT
+ 1.3.4-SNAPSHOT
```
@@ -26,12 +26,12 @@ For adding a library with JS for Rhino or GraalVM:
com.instancify.scriptify
script-js-rhino
- 1.3.3-SNAPSHOT
+ 1.3.4-SNAPSHOT
com.instancify.scriptify
script-js-graalvm
- 1.3.3-SNAPSHOT
+ 1.3.4-SNAPSHOT
```
## Gradle
@@ -45,11 +45,11 @@ maven {
For adding a library only:
```groovy
-implementation "com.instancify.scriptify:core:1.3.3-SNAPSHOT"
+implementation "com.instancify.scriptify:core:1.3.4-SNAPSHOT"
```
For adding a library with JS for Rhino or GraalVM:
```groovy
-implementation "com.instancify.scriptify:script-js-rhino:1.3.3-SNAPSHOT"
-implementation "com.instancify.scriptify:script-js-graalvm:1.3.3-SNAPSHOT"
+implementation "com.instancify.scriptify:script-js-rhino:1.3.4-SNAPSHOT"
+implementation "com.instancify.scriptify:script-js-graalvm:1.3.4-SNAPSHOT"
```
\ No newline at end of file
diff --git a/api/src/main/java/com/instancify/scriptify/api/script/security/SecurityClassAccessor.java b/api/src/main/java/com/instancify/scriptify/api/script/security/SecurityClassAccessor.java
index a8f4a26..ac06de5 100644
--- a/api/src/main/java/com/instancify/scriptify/api/script/security/SecurityClassAccessor.java
+++ b/api/src/main/java/com/instancify/scriptify/api/script/security/SecurityClassAccessor.java
@@ -1,5 +1,7 @@
package com.instancify.scriptify.api.script.security;
+import com.instancify.scriptify.api.script.security.exclude.SecurityExclude;
+
import java.util.Set;
/**
@@ -12,12 +14,5 @@ public interface SecurityClassAccessor {
*
* @return A set of strings representing the names of allowed classes
*/
- Set getAllowedClasses();
-
- /**
- * Adds a class to the list of allowed classes, which can then be used or accessed.
- *
- * @param allowedClass The name of the class to be added to the allowed list
- */
- void addAllowedClass(String allowedClass);
+ Set getExcludes();
}
\ No newline at end of file
diff --git a/api/src/main/java/com/instancify/scriptify/api/script/security/exclude/ClassSecurityExclude.java b/api/src/main/java/com/instancify/scriptify/api/script/security/exclude/ClassSecurityExclude.java
index 118c770..5718879 100644
--- a/api/src/main/java/com/instancify/scriptify/api/script/security/exclude/ClassSecurityExclude.java
+++ b/api/src/main/java/com/instancify/scriptify/api/script/security/exclude/ClassSecurityExclude.java
@@ -1,9 +1,17 @@
package com.instancify.scriptify.api.script.security.exclude;
+/**
+ * Excludes a specific class for security purposes.
+ */
public class ClassSecurityExclude implements SecurityExclude {
private final Class> value;
+ /**
+ * Creates a class exclusion rule.
+ *
+ * @param value Class to exclude
+ */
public ClassSecurityExclude(Class> value) {
this.value = value;
}
diff --git a/api/src/main/java/com/instancify/scriptify/api/script/security/exclude/PackageSecurityExclude.java b/api/src/main/java/com/instancify/scriptify/api/script/security/exclude/PackageSecurityExclude.java
new file mode 100644
index 0000000..b1d8c24
--- /dev/null
+++ b/api/src/main/java/com/instancify/scriptify/api/script/security/exclude/PackageSecurityExclude.java
@@ -0,0 +1,23 @@
+package com.instancify.scriptify.api.script.security.exclude;
+
+/**
+ * Excludes an entire package for security purposes.
+ */
+public class PackageSecurityExclude implements SecurityExclude {
+
+ private final String value;
+
+ /**
+ * Creates a package exclusion rule.
+ *
+ * @param value Package name to exclude
+ */
+ public PackageSecurityExclude(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/api/src/main/java/com/instancify/scriptify/api/script/security/exclude/PathSecurityExclude.java b/api/src/main/java/com/instancify/scriptify/api/script/security/exclude/PathSecurityExclude.java
index 0c5e516..949286f 100644
--- a/api/src/main/java/com/instancify/scriptify/api/script/security/exclude/PathSecurityExclude.java
+++ b/api/src/main/java/com/instancify/scriptify/api/script/security/exclude/PathSecurityExclude.java
@@ -1,9 +1,17 @@
package com.instancify.scriptify.api.script.security.exclude;
+/**
+ * Excludes a specific path for security purposes.
+ */
public class PathSecurityExclude implements SecurityExclude {
private final String value;
+ /**
+ * Creates a path exclusion rule.
+ *
+ * @param value Path to exclude
+ */
public PathSecurityExclude(String value) {
this.value = value;
}
diff --git a/api/src/main/java/com/instancify/scriptify/api/script/security/exclude/SecurityExclude.java b/api/src/main/java/com/instancify/scriptify/api/script/security/exclude/SecurityExclude.java
index 1b14e79..d767fad 100644
--- a/api/src/main/java/com/instancify/scriptify/api/script/security/exclude/SecurityExclude.java
+++ b/api/src/main/java/com/instancify/scriptify/api/script/security/exclude/SecurityExclude.java
@@ -1,5 +1,9 @@
package com.instancify.scriptify.api.script.security.exclude;
+/**
+ * Defines exclusions for security purposes, specifically for paths, packages, or classes.
+ * This interface acts as a base for creating exclusion rules in a security context.
+ */
public interface SecurityExclude {
/**
@@ -20,6 +24,16 @@ default boolean isExcluded(String value) {
return value.startsWith(this.getValue());
}
+ /**
+ * Creates a new exclusion instance for the package.
+ *
+ * @param value A package that will be excluded
+ * @return A new exclusion instance for the package
+ */
+ static PackageSecurityExclude ofPackage(String value) {
+ return new PackageSecurityExclude(value);
+ }
+
/**
* Creates a new exclusion instance for the class.
*
diff --git a/build.gradle.kts b/build.gradle.kts
index 5e222ec..05aa678 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -12,7 +12,7 @@ java {
allprojects {
group = "com.instancify.scriptify"
- version = "1.3.3-SNAPSHOT"
+ version = "1.3.4-SNAPSHOT"
}
subprojects {
diff --git a/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsScript.java b/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsScript.java
index 5c53326..6db4ca4 100644
--- a/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsScript.java
+++ b/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsScript.java
@@ -7,10 +7,10 @@
import com.instancify.scriptify.api.script.function.ScriptFunction;
import com.instancify.scriptify.api.script.function.ScriptFunctionManager;
import com.instancify.scriptify.api.script.security.ScriptSecurityManager;
-import com.instancify.scriptify.api.script.security.exclude.ClassSecurityExclude;
-import com.instancify.scriptify.api.script.security.exclude.SecurityExclude;
import com.instancify.scriptify.core.script.security.StandardSecurityManager;
-import org.graalvm.polyglot.*;
+import org.graalvm.polyglot.Context;
+import org.graalvm.polyglot.HostAccess;
+import org.graalvm.polyglot.Value;
public class JsScript implements Script {
@@ -51,13 +51,7 @@ public Value eval(String script) throws ScriptException {
// If security mode is enabled, search all exclusions
// and add the classes that were excluded to JsSecurityClassAccessor
if (securityManager.getSecurityMode()) {
- JsSecurityClassAccessor classAccessor = new JsSecurityClassAccessor();
- for (SecurityExclude exclude : securityManager.getExcludes()) {
- if (exclude instanceof ClassSecurityExclude classExclude) {
- classAccessor.addAllowedClass(classExclude.getValue());
- }
- }
- builder.allowHostClassLookup(classAccessor);
+ builder.allowHostClassLookup(new JsSecurityClassAccessor(securityManager.getExcludes()));
} else {
builder.allowHostClassLookup(className -> true);
}
diff --git a/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsSecurityClassAccessor.java b/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsSecurityClassAccessor.java
index 23b4427..3b37f57 100644
--- a/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsSecurityClassAccessor.java
+++ b/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsSecurityClassAccessor.java
@@ -1,6 +1,9 @@
package com.instancify.scriptify.script;
import com.instancify.scriptify.api.script.security.SecurityClassAccessor;
+import com.instancify.scriptify.api.script.security.exclude.ClassSecurityExclude;
+import com.instancify.scriptify.api.script.security.exclude.PackageSecurityExclude;
+import com.instancify.scriptify.api.script.security.exclude.SecurityExclude;
import org.graalvm.polyglot.PolyglotException;
import java.util.HashSet;
@@ -9,24 +12,41 @@
public class JsSecurityClassAccessor implements Predicate, SecurityClassAccessor {
- private final Set allowedClasses = new HashSet<>();
+ private final Set excludes;
+ private final Set allowedClasses;
+ private final Set allowedPackages;
- public JsSecurityClassAccessor() {
- this.allowedClasses.add(PolyglotException.class.getName());
- }
+ public JsSecurityClassAccessor(Set excludes) {
+ this.excludes = excludes;
+ this.allowedClasses = new HashSet<>();
+ this.allowedPackages = new HashSet<>();
- @Override
- public Set getAllowedClasses() {
- return allowedClasses;
+ for (SecurityExclude exclude : excludes) {
+ if (exclude instanceof ClassSecurityExclude classExclude) {
+ allowedClasses.add(classExclude.getValue());
+ } else if (exclude instanceof PackageSecurityExclude packageExclude) {
+ allowedPackages.add(packageExclude.getValue());
+ }
+ }
+
+ this.allowedClasses.add(PolyglotException.class.getName());
}
@Override
- public void addAllowedClass(String allowedClass) {
- this.allowedClasses.add(allowedClass);
+ public Set getExcludes() {
+ return excludes;
}
@Override
public boolean test(String className) {
- return this.allowedClasses.contains(className);
+ if (this.allowedClasses.contains(className)) {
+ return true;
+ }
+ for (String exclude : this.allowedPackages) {
+ if (className.startsWith(exclude)) {
+ return true;
+ }
+ }
+ return false;
}
}
diff --git a/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsScript.java b/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsScript.java
index c984146..3e618a6 100644
--- a/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsScript.java
+++ b/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsScript.java
@@ -52,13 +52,7 @@ public Object eval(String script) throws ScriptException {
// If security mode is enabled, search all exclusions
// and add the classes that were excluded to JsSecurityClassAccessor
if (securityManager.getSecurityMode()) {
- JsSecurityClassAccessor classAccessor = new JsSecurityClassAccessor();
- for (SecurityExclude exclude : securityManager.getExcludes()) {
- if (exclude instanceof ClassSecurityExclude classExclude) {
- classAccessor.addAllowedClass(classExclude.getValue());
- }
- }
- context.setClassShutter(classAccessor);
+ context.setClassShutter(new JsSecurityClassAccessor(securityManager.getExcludes()));
}
if (functionManager != null) {
diff --git a/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsSecurityClassAccessor.java b/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsSecurityClassAccessor.java
index f94ed7f..a6f1092 100644
--- a/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsSecurityClassAccessor.java
+++ b/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsSecurityClassAccessor.java
@@ -1,6 +1,9 @@
package com.instancify.scriptify.script;
import com.instancify.scriptify.api.script.security.SecurityClassAccessor;
+import com.instancify.scriptify.api.script.security.exclude.ClassSecurityExclude;
+import com.instancify.scriptify.api.script.security.exclude.PackageSecurityExclude;
+import com.instancify.scriptify.api.script.security.exclude.SecurityExclude;
import org.mozilla.javascript.ClassShutter;
import org.mozilla.javascript.EcmaError;
@@ -9,24 +12,41 @@
public class JsSecurityClassAccessor implements ClassShutter, SecurityClassAccessor {
- private final Set allowedClasses = new HashSet<>();
+ private final Set excludes;
+ private final Set allowedClasses;
+ private final Set allowedPackages;
- public JsSecurityClassAccessor() {
- this.allowedClasses.add(EcmaError.class.getName());
- }
+ public JsSecurityClassAccessor(Set excludes) {
+ this.excludes = excludes;
+ this.allowedClasses = new HashSet<>();
+ this.allowedPackages = new HashSet<>();
- @Override
- public Set getAllowedClasses() {
- return allowedClasses;
+ for (SecurityExclude exclude : excludes) {
+ if (exclude instanceof ClassSecurityExclude classExclude) {
+ allowedClasses.add(classExclude.getValue());
+ } else if (exclude instanceof PackageSecurityExclude packageExclude) {
+ allowedPackages.add(packageExclude.getValue());
+ }
+ }
+
+ this.allowedClasses.add(EcmaError.class.getName());
}
@Override
- public void addAllowedClass(String allowedClass) {
- this.allowedClasses.add(allowedClass);
+ public Set getExcludes() {
+ return excludes;
}
@Override
- public boolean visibleToScripts(String fullClassName) {
- return this.allowedClasses.contains(fullClassName);
+ public boolean visibleToScripts(String className) {
+ if (this.allowedClasses.contains(className)) {
+ return true;
+ }
+ for (String exclude : this.allowedPackages) {
+ if (className.startsWith(exclude)) {
+ return true;
+ }
+ }
+ return false;
}
}