keycloak-uncached
Changes
authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/js/JSPolicyProvider.java 44(+27 -17)
Details
diff --git a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/js/JSPolicyProvider.java b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/js/JSPolicyProvider.java
index f875731..74befcb 100644
--- a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/js/JSPolicyProvider.java
+++ b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/js/JSPolicyProvider.java
@@ -17,37 +17,27 @@
*/
package org.keycloak.authorization.policy.provider.js;
-import java.util.function.Supplier;
-
-import javax.script.ScriptEngine;
-import javax.script.ScriptException;
-
+import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.policy.evaluation.Evaluation;
import org.keycloak.authorization.policy.provider.PolicyProvider;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.ScriptModel;
+import org.keycloak.scripting.InvocableScriptAdapter;
+import org.keycloak.scripting.ScriptingProvider;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public class JSPolicyProvider implements PolicyProvider {
- private Supplier<ScriptEngine> engineProvider;
-
- public JSPolicyProvider(Supplier<ScriptEngine> engineProvider) {
- this.engineProvider = engineProvider;
- }
-
@Override
public void evaluate(Evaluation evaluation) {
- ScriptEngine engine = engineProvider.get();
-
- engine.put("$evaluation", evaluation);
-
Policy policy = evaluation.getPolicy();
try {
- engine.eval(policy.getConfig().get("code"));
- } catch (ScriptException e) {
+ getInvocableScriptAdapter(policy, evaluation).eval();
+ } catch (Exception e) {
throw new RuntimeException("Error evaluating JS Policy [" + policy.getName() + "].", e);
}
}
@@ -56,4 +46,24 @@ public class JSPolicyProvider implements PolicyProvider {
public void close() {
}
+
+ private InvocableScriptAdapter getInvocableScriptAdapter(Policy policy, Evaluation evaluation) {
+ String scriptName = policy.getName();
+ String scriptCode = policy.getConfig().get("code");
+ String scriptDescription = policy.getDescription();
+
+ AuthorizationProvider authorization = evaluation.getAuthorizationProvider();
+ RealmModel realm = authorization.getRealm();
+
+ ScriptingProvider scripting = authorization.getKeycloakSession().getProvider(ScriptingProvider.class);
+
+ //TODO lookup script by scriptId instead of creating it every time
+ ScriptModel script = scripting.createScript(realm.getId(), ScriptModel.TEXT_JAVASCRIPT, scriptName, scriptCode, scriptDescription);
+
+ //how to deal with long running scripts -> timeout?
+ return scripting.prepareInvocableScript(script, bindings -> {
+ bindings.put("script", script);
+ bindings.put("$evaluation", evaluation);
+ });
+ }
}
diff --git a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/js/JSPolicyProviderFactory.java b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/js/JSPolicyProviderFactory.java
index 3e68d7f..a261296 100644
--- a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/js/JSPolicyProviderFactory.java
+++ b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/js/JSPolicyProviderFactory.java
@@ -1,9 +1,5 @@
package org.keycloak.authorization.policy.provider.js;
-import java.util.Map;
-
-import javax.script.ScriptEngineManager;
-
import org.keycloak.Config;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.Policy;
@@ -19,9 +15,7 @@ import org.keycloak.representations.idm.authorization.PolicyRepresentation;
*/
public class JSPolicyProviderFactory implements PolicyProviderFactory<JSPolicyRepresentation> {
- private static final String ENGINE = "nashorn";
-
- private JSPolicyProvider provider = new JSPolicyProvider(() -> new ScriptEngineManager().getEngineByName(ENGINE));
+ private JSPolicyProvider provider = new JSPolicyProvider();
@Override
public String getName() {
diff --git a/server-spi-private/src/main/java/org/keycloak/scripting/InvocableScriptAdapter.java b/server-spi-private/src/main/java/org/keycloak/scripting/InvocableScriptAdapter.java
index c3859ab..30644f0 100644
--- a/server-spi-private/src/main/java/org/keycloak/scripting/InvocableScriptAdapter.java
+++ b/server-spi-private/src/main/java/org/keycloak/scripting/InvocableScriptAdapter.java
@@ -78,6 +78,14 @@ public class InvocableScriptAdapter implements Invocable {
}
}
+ public Object eval() throws ScriptExecutionException {
+ try {
+ return scriptEngine.eval(scriptModel.getCode());
+ } catch (ScriptException e) {
+ throw new ScriptExecutionException(scriptModel, e);
+ }
+ }
+
@Override
public <T> T getInterface(Class<T> clazz) {
return getInvocableEngine().getInterface(clazz);