From d48eeadf535e18b8d74574fa0e97a64b00db20a0 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Fri, 8 Dec 2023 16:14:27 +0530 Subject: [PATCH 01/35] Implement graalvm based script engine --- .../pom.xml | 14 + .../graph/BaseSerializableJsFunction.java | 5 +- .../graph/JsBaseGraphBuilderFactory.java | 5 +- .../config/model/graph/JsGraphBuilder.java | 24 +- .../model/graph/JsGraphBuilderFactory.java | 2 +- .../model/graph/JsNashornGraphBuilder.java | 57 +- .../model/graph/JsNashornSerializer.java | 2 +- .../config/model/graph/JsSerializer.java | 10 +- .../model/graph/JsWrapperFactoryProvider.java | 9 +- .../model/graph/SerializableJsFunction.java | 5 +- .../graaljs/GraalSerializableJsFunction.java | 143 ++++ .../model/graph/graaljs/GraalSerializer.java | 160 +++++ .../graph/graaljs/JsGraalGraphBuilder.java | 637 ++++++++++++++++++ .../graaljs/JsGraalGraphBuilderFactory.java | 113 ++++ .../graph/graaljs/JsGraalWrapperFactory.java | 72 ++ .../js/AbstractJSContextMemberObject.java | 10 +- .../config/model/graph/js/JsClaims.java | 410 +++++++++++ .../config/model/graph/js/JsParameters.java | 4 +- .../js/graaljs/JsGraalAuthenticatedUser.java | 112 +++ .../graaljs/JsGraalAuthenticationContext.java | 110 +++ .../model/graph/js/graaljs/JsGraalClaims.java | 153 +++++ .../model/graph/js/graaljs/JsGraalCookie.java | 57 ++ .../graph/js/graaljs/JsGraalHeaders.java | 86 +++ .../graph/js/graaljs/JsGraalParameters.java | 63 ++ .../js/graaljs/JsGraalRuntimeClaims.java | 100 +++ .../js/graaljs/JsGraalServletRequest.java | 122 ++++ .../js/graaljs/JsGraalServletResponse.java | 87 +++ .../model/graph/js/graaljs/JsGraalStep.java | 135 ++++ .../model/graph/js/graaljs/JsGraalSteps.java | 81 +++ .../js/graaljs/JsGraalWritableParameters.java | 56 ++ .../nashorn/JsOpenJdkNashornGraphBuilder.java | 58 +- .../JsOpenJdkNashornGraphBuilderFactory.java | 4 +- .../nashorn/JsOpenJdkNashornSerializer.java | 2 +- .../OpenJdkNashornSerializableJsFunction.java | 2 +- .../framework/util/FrameworkConstants.java | 5 + pom.xml | 30 + 36 files changed, 2801 insertions(+), 144 deletions(-) create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml index 668392d8fca6..9af5b341e69c 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml @@ -130,6 +130,20 @@ com.google.code.gson gson + + + org.graalvm.sdk + graal-sdk + + + org.graalvm.js + js + + + org.graalvm.truffle + truffle-api + + org.testng testng diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/BaseSerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/BaseSerializableJsFunction.java index d4906388ea03..388c43f6db34 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/BaseSerializableJsFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/BaseSerializableJsFunction.java @@ -29,8 +29,9 @@ * The request may come to different node. * The current authentication context holds this function in serialized form. * + * @param Script Engine */ -public interface BaseSerializableJsFunction extends Serializable { +public interface BaseSerializableJsFunction extends Serializable { void setSource(String name); @@ -40,6 +41,6 @@ public interface BaseSerializableJsFunction extends Serializable { void setFunction(boolean function); - Object apply(ScriptEngine scriptEngine, Object... params); + Object apply(T scriptEngine, Object... params); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilderFactory.java index 36615abcfcaf..c7a5fd753ab6 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilderFactory.java @@ -28,9 +28,8 @@ /** * Interface for Factory to create a Javascript based sequence builder. * This factory is there to reuse of script engine and any related expensive objects. - * */ -public interface JsBaseGraphBuilderFactory { +public interface JsBaseGraphBuilderFactory { void init(); @@ -39,7 +38,7 @@ public interface JsBaseGraphBuilderFactory { JsBaseGraphBuilder createBuilder(AuthenticationContext authenticationContext, Map stepConfigMap, AuthGraphNode currentNode); - ScriptEngine createEngine(AuthenticationContext authenticationContext); + T createEngine(AuthenticationContext authenticationContext); JsSerializer getJsUtil(); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java index 3380dbd0b6b4..0636219912db 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java @@ -18,6 +18,9 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph; +import jdk.nashorn.api.scripting.ScriptObjectMirror; +import org.apache.abdera.model.Base; +import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -43,6 +46,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Function; import javax.script.ScriptEngine; import javax.script.ScriptException; @@ -54,14 +58,14 @@ public abstract class JsGraphBuilder implements JsBaseGraphBuilder { private static final Log log = LogFactory.getLog(JsGraphBuilder.class); - private Map stepNamedMap; - private AuthenticationGraph result = new AuthenticationGraph(); - private AuthGraphNode currentNode = null; - private AuthenticationContext authenticationContext; + protected Map stepNamedMap; + protected AuthenticationGraph result = new AuthenticationGraph(); + protected AuthGraphNode currentNode = null; + protected AuthenticationContext authenticationContext; private ScriptEngine engine; - private static ThreadLocal contextForJs = new ThreadLocal<>(); - private static ThreadLocal dynamicallyBuiltBaseNode = new ThreadLocal<>(); - private static ThreadLocal currentBuilder = new ThreadLocal<>(); + protected static ThreadLocal contextForJs = new ThreadLocal<>(); + protected static ThreadLocal dynamicallyBuiltBaseNode = new ThreadLocal<>(); + protected static ThreadLocal currentBuilder = new ThreadLocal<>(); private static final String REMOVE_FUNCTIONS = "var quit=function(){Log.error('quit function is restricted.')};" + "var exit=function(){Log.error('exit function is restricted.')};" + "var print=function(){Log.error('print function is restricted.')};" + @@ -519,7 +523,7 @@ public static void addLongWaitProcess(AsyncProcess asyncProcess, * @param destination Current node. * @param newNode New node to attach. */ - private static void infuse(AuthGraphNode destination, AuthGraphNode newNode) { + protected static void infuse(AuthGraphNode destination, AuthGraphNode newNode) { if (destination instanceof StepConfigGraphNode) { StepConfigGraphNode stepConfigGraphNode = ((StepConfigGraphNode) destination); @@ -545,7 +549,7 @@ private static void infuse(AuthGraphNode destination, AuthGraphNode newNode) { * @param baseNode Base node. * @param nodeToAttach Node to attach. */ - private static void attachToLeaf(AuthGraphNode baseNode, AuthGraphNode nodeToAttach) { + protected static void attachToLeaf(AuthGraphNode baseNode, AuthGraphNode nodeToAttach) { if (baseNode instanceof StepConfigGraphNode) { StepConfigGraphNode stepConfigGraphNode = ((StepConfigGraphNode) baseNode); @@ -594,7 +598,7 @@ private static void attachToLeaf(AuthGraphNode baseNode, AuthGraphNode nodeToAtt * @param stepConfig Step Config Object. * @return built and wrapped new StepConfigGraphNode. */ - private static StepConfigGraphNode wrap(StepConfig stepConfig) { + protected static StepConfigGraphNode wrap(StepConfig stepConfig) { return new StepConfigGraphNode(stepConfig); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilderFactory.java index 0d4d806a97bf..06ad45c789ec 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilderFactory.java @@ -45,7 +45,7 @@ * Factory to create a Javascript based sequence builder. * This factory is there to reuse of Nashorn engine and any related expnsive objects. */ -public class JsGraphBuilderFactory implements JsBaseGraphBuilderFactory { +public class JsGraphBuilderFactory implements JsBaseGraphBuilderFactory { private static final Log LOG = LogFactory.getLog(JsGraphBuilderFactory.class); private static final String JS_BINDING_CURRENT_CONTEXT = "JS_BINDING_CURRENT_CONTEXT"; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsNashornGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsNashornGraphBuilder.java index 019d30ea34e4..61c2da87b9c9 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsNashornGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsNashornGraphBuilder.java @@ -916,7 +916,7 @@ private static void addHandlers(ShowPromptNode showPromptNode, Map { private static final Log log = LogFactory.getLog(JsNashornSerializer.class); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsSerializer.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsSerializer.java index 4d35de2f0646..1ec65871f856 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsSerializer.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsSerializer.java @@ -20,15 +20,14 @@ import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; -import javax.script.ScriptEngine; - /** * Interface for serializer class supports Multiple JS Engines. */ -public interface JsSerializer { +public interface JsSerializer { /** * Serialize the object using selected serializable function. + * * @param value Object to evaluate. * @return Serialized Object. */ @@ -36,11 +35,12 @@ public interface JsSerializer { /** * De-Serialize the object using selected serializable function. - * @param value Serialized Object. + * + * @param value Serialized Object. * @param engine Js Engine. * @return De-Serialize object. * @throws FrameworkException FrameworkException. */ - Object fromJsSerializable(Object value, ScriptEngine engine) throws FrameworkException; + Object fromJsSerializable(Object value, T engine) throws FrameworkException; } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactoryProvider.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactoryProvider.java index 341f6f013c7d..f39e92b3d95c 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactoryProvider.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactoryProvider.java @@ -18,6 +18,8 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs.JsGraalGraphBuilderFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs.JsGraalWrapperFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.openjdk.nashorn.JsOpenJdkNashornGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.openjdk.nashorn.JsOpenJdkNashornWrapperFactory; import org.wso2.carbon.identity.application.authentication.framework.internal.FrameworkServiceDataHolder; @@ -33,9 +35,12 @@ public class JsWrapperFactoryProvider { private JsWrapperFactoryProvider() { - if (FrameworkServiceDataHolder.getInstance(). - getJsGraphBuilderFactory() instanceof JsOpenJdkNashornGraphBuilderFactory) { + if (FrameworkServiceDataHolder.getInstance() + .getJsGraphBuilderFactory() instanceof JsOpenJdkNashornGraphBuilderFactory) { jsWrapperBaseFactory = new JsOpenJdkNashornWrapperFactory(); + } else if (FrameworkServiceDataHolder.getInstance() + .getJsGraphBuilderFactory() instanceof JsGraalGraphBuilderFactory) { + jsWrapperBaseFactory = new JsGraalWrapperFactory(); } else { jsWrapperBaseFactory = new JsWrapperFactory(); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/SerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/SerializableJsFunction.java index 7b09bfcf9798..aa039c050ea8 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/SerializableJsFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/SerializableJsFunction.java @@ -31,10 +31,9 @@ import javax.script.ScriptException; /** - * Javascript function wrapper. This allows serialization of a javascript defined function. - * + * Javascript function wrapper. This allows serialization of a javascript defined function. */ -public class SerializableJsFunction implements BaseSerializableJsFunction { +public class SerializableJsFunction implements BaseSerializableJsFunction { private static final Log log = LogFactory.getLog(SerializableJsFunction.class); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java new file mode 100644 index 000000000000..c921f8c566d2 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.PolyglotException; +import org.graalvm.polyglot.Source; +import org.graalvm.polyglot.Value; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.BaseSerializableJsFunction; + +import java.io.IOException; +import java.util.function.Function; + +public class GraalSerializableJsFunction implements BaseSerializableJsFunction { + + private static final Log log = LogFactory.getLog(GraalSerializableJsFunction.class); + private static final long serialVersionUID = -7001351065432647040L; + private String source; + private boolean isPolyglotFunction = false; + private boolean isHostFunction = false; + private String name; + + public GraalSerializableJsFunction(String source, String functionType) { + + this.source = source; + if (functionType.equals("polyglotFunction")) { + this.isPolyglotFunction = true; + } else { + this.isHostFunction = true; + } + } + + public GraalSerializableJsFunction(String source, boolean isFunction) { + + this.source = source; + this.isPolyglotFunction = true; + } + + /** + * This will return the converted NashornSerializableJsFunction if the given ScriptObjectMirror is a function. + * + * @param functionObject Value type Function to Serialize + * @return null if the ScriptObjectMirror is not a function. + */ + public static GraalSerializableJsFunction toSerializableForm(Object functionObject) { + + if (functionObject == null) { + return null; + } + try { + Value functionAsValue; + if (functionObject instanceof Function) { + Context context = Context.getCurrent(); + functionAsValue = context.asValue(functionObject); + } else { + functionAsValue = (Value) functionObject; + } + if (functionAsValue.canExecute()) { + if (functionAsValue.isHostObject()) { + return serializePolyglot(null, "hostFunction"); + } + String source = (String) functionAsValue.getSourceLocation().getCharacters(); + return serializePolyglot(source, "polyglotFunction"); + } else { + return null; + } + } catch (PolyglotException e) { + log.error("Error when serializing JavaScript Function: ", e); + } + return null; + + } + + public Object apply(Context polyglotContext, Object... params) { + + if (isPolyglotFunction) { + try { + polyglotContext.eval(Source.newBuilder("js", " var curFunc = " + getSource(), "src.js").build()); + return polyglotContext.getBindings("js").getMember("curFunc").execute(params); + } catch (IOException e) { + log.error("Error when building the from function source", e); + } catch (PolyglotException e) { + log.error("Error when executing function", e); + } + } + + return null; + } + + public String getSource() { + + return source; + } + + @Override + public boolean isFunction() { + + return isHostFunction; + } + + @Override + public void setFunction(boolean function) { + + } + + public void setSource(String source) { + + this.source = source; + } + + public String getName() { + + return name; + } + + public void setName(String name) { + + this.name = name; + } + + private static GraalSerializableJsFunction serializePolyglot(String source, String functionType) { + + return new GraalSerializableJsFunction(source, functionType); + } +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java new file mode 100644 index 000000000000..0b20b4a3bf87 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2022, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs; + +import org.graalvm.polyglot.Value; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsSerializer; +import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; + +import org.apache.commons.logging.Log; +import org.graalvm.polyglot.Context; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class GraalSerializer implements JsSerializer { + + private static final Log log = LogFactory.getLog(GraalSerializer.class); + private static final GraalSerializer graalSerializer = new GraalSerializer(); + + public static GraalSerializer getInstance() { + + return graalSerializer; + } + + @Override + public Object toJsSerializable(Object value) { + + return toJsSerializableInternal(value); + } + + public static Object toJsSerializableInternal(Object value) { + + if (value instanceof Serializable) { + if (value instanceof HashMap) { + Map map = new HashMap<>(); + ((HashMap) value).forEach((k, v) -> map.put(k, toJsSerializableInternal(v))); + return map; + } else { + return value; + } + } else if (value instanceof Value) { + Value valueObj = (Value) value; + if (valueObj.canExecute()) { + return GraalSerializableJsFunction.toSerializableForm(valueObj); + } else if (valueObj.isProxyObject()) { + return valueObj.asProxyObject(); + } else if (valueObj.isNumber()) { + return valueObj.asInt(); + } else if (valueObj.isString()) { + return valueObj.toString(); + } else if (valueObj.isDate()) { + return valueObj.asDate(); + } else if (valueObj.isBoolean()) { + return valueObj.asBoolean(); + } else if (valueObj.hasArrayElements()) { + int arraySize = (int) valueObj.getArraySize(); + List arrayItems = new ArrayList<>(arraySize); + for (int key = 0; key < arraySize; key++) { + Object serializedObj = (valueObj.getArrayElement(key)); + if (serializedObj instanceof Serializable) { + arrayItems.add((Serializable) serializedObj); + if (log.isDebugEnabled()) { + log.debug("Serialized the value of array item as : " + serializedObj); + } + } else { + log.warn(String.format("Non serializable array item: %s. and will not be persisted.", + serializedObj)); + } + } + return arrayItems; + } else if (valueObj.hasMembers()) { + Map serializedMap = new HashMap<>(); + valueObj.getMemberKeys().forEach((key) -> { + Object serializedObj = toJsSerializableInternal(valueObj.getMember(key)); + if (serializedObj instanceof Serializable) { + serializedMap.put(key, (Serializable) serializedObj); + if (log.isDebugEnabled()) { + log.debug("Serialized the value for key : " + key); + } + } else { + log.warn( + String.format("Non serializable object for key : %s, and will not be persisted.", key)); + } + }); + return serializedMap; + } else if (valueObj.isDuration()) { + return valueObj.asDuration(); + } else if (valueObj.isTime()) { + return valueObj.asTime(); + } else if (valueObj.isTimeZone()) { + return valueObj.asTimeZone(); + } else if (valueObj.isNull()) { + return null; + } else { + return Collections.EMPTY_MAP; + } + } + return value; + + } + + @Override + public Object fromJsSerializable(Object value, Context engine) throws FrameworkException { + + return fromJsSerializableInternal(value, engine); + } + + public static Object fromJsSerializableInternal(Object value, Context context) throws FrameworkException { + + if (value instanceof GraalSerializableJsFunction) { + GraalSerializableJsFunction serializableJsFunction = (GraalSerializableJsFunction) value; + try { + context.eval(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, + "var tempFunc = " + serializableJsFunction.getSource()); + return context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE).getMember("tempFunc"); + } catch (Exception e) { + log.error("could not recreate JS Object", e); + } + } else if (value instanceof Map) { + Value deserializedValue = context.eval(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, "[]"); + for (Map.Entry entry : ((Map) value).entrySet()) { + Object deserializedObj = fromJsSerializableInternal(entry.getValue(), context); + deserializedValue.putMember(entry.getKey(), deserializedObj); + } + return deserializedValue; + } else if (value instanceof List) { + Value deserializedValue = context.eval(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, "[]"); + List valueList = (List) value; + int listSize = valueList.size(); + for (int index = 0; index < listSize; index++) { + Object deserializedObject = fromJsSerializableInternal(valueList.get(index), context); + deserializedValue.setArrayElement(index, deserializedObject); + } + return deserializedValue; + } + return value; + } +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java new file mode 100644 index 000000000000..df63d278ff52 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java @@ -0,0 +1,637 @@ +/* + * Copyright (c) 2022, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs; + +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang.StringUtils; +import org.wso2.carbon.identity.application.authentication.framework.AsyncProcess; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthGraphNode; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthenticationGraph; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.BaseSerializableJsFunction; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.DynamicDecisionNode; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.FailNode; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JSExecutionMonitorData; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JSExecutionSupervisor; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGraphBuilder; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.PolyglotException; +import org.graalvm.polyglot.Source; +import org.graalvm.polyglot.Value; +import org.wso2.carbon.identity.application.authentication.framework.AuthenticationDecisionEvaluator; +import org.wso2.carbon.identity.application.authentication.framework.JsFunctionRegistry; +import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.LongWaitNode; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.ShowPromptNode; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.StepConfigGraphNode; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalAuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.internal.FrameworkServiceDataHolder; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; + +import java.io.IOException; +import java.io.Serializable; +import java.util.Collections; +import java.util.Map; +import java.util.UUID; +import java.util.function.BiConsumer; +import java.util.stream.Collectors; + +public class JsGraalGraphBuilder extends JsGraphBuilder { + + private static final Log log = LogFactory.getLog(JsGraalGraphBuilder.class); + protected Context context; + + private static final String REMOVE_FUNCTIONS = "var quit=function(){Log.error('quit function is restricted.')};" + + "var exit=function(){Log.error('exit function is restricted.')};" + + "var print=function(){Log.error('print function is restricted.')};" + + "var echo=function(){Log.error('echo function is restricted.')};" + + "var readFully=function(){Log.error('readFully function is restricted.')};" + + "var readLine=function(){Log.error('readLine function is restricted.')};" + + "var load=function(){Log.error('load function is restricted.')};" + + "var loadWithNewGlobal=function(){Log.error('loadWithNewGlobal function is restricted.')};" + + "var $ARG=null;var $ENV=null;var $EXEC=null;" + + "var $OPTIONS=null;var $OUT=null;var $ERR=null;var $EXIT=null;" + + "Object.defineProperty(this, 'engine', {});"; + + /** + * Constructs the builder with the given authentication context. + * + * @param authenticationContext current authentication context. + * @param stepConfigMap The Step map from the service provider configuration. + * @param context Polyglot Context. + */ + public JsGraalGraphBuilder(AuthenticationContext authenticationContext, Map stepConfigMap, + Context context) { + + this.authenticationContext = authenticationContext; + this.context = context; + stepNamedMap = + stepConfigMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } + + /** + * Constructs the builder with the given authentication context. + * + * @param authenticationContext current authentication context. + * @param stepConfigMap The Step map from the service provider configuration. + * @param context polyglot context. + * @param currentNode Current authentication graph node. + */ + public JsGraalGraphBuilder(AuthenticationContext authenticationContext, Map stepConfigMap, + Context context, AuthGraphNode currentNode) { + + this.authenticationContext = authenticationContext; + this.context = context; + this.currentNode = currentNode; + stepNamedMap = + stepConfigMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } + + /** + * Creates the graph with the given Script and step map. + * + * @param script the Dynamic authentication script. + */ + @Override + public JsGraalGraphBuilder createWith(String script) { + + try { + currentBuilder.set(this); + Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + + bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_EXECUTE_STEP, (StepExecutor) this::executeStep); + bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_SEND_ERROR, + (BiConsumer) this::sendError); + bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_SHOW_PROMPT, + (PromptExecutor) this::addShowPrompt); + bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_LOAD_FUNC_LIB, + (LoadExecutor) this::loadLocalLibrary); + JsFunctionRegistry jsFunctionRegistrar = FrameworkServiceDataHolder.getInstance().getJsFunctionRegistry(); + if (jsFunctionRegistrar != null) { + Map functionMap = + jsFunctionRegistrar.getSubsystemFunctionsMap(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER); + functionMap.forEach(bindings::putMember); + } + currentBuilder.set(this); + context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, + FrameworkServiceDataHolder.getInstance().getCodeForRequireFunction(), + FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, script, + FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + + Value onLoginRequestFn = bindings.getMember(FrameworkConstants.JSAttributes.JS_FUNC_ON_LOGIN_REQUEST); + if (onLoginRequestFn == null) { + log.error("Could not find the entry function " + + FrameworkConstants.JSAttributes.JS_FUNC_ON_LOGIN_REQUEST + " \n" + script); + result.setBuildSuccessful(false); + result.setErrorReason("Error in executing the Javascript. " + + FrameworkConstants.JSAttributes.JS_FUNC_ON_LOGIN_REQUEST + " function is not defined."); + return this; + } + onLoginRequestFn.executeVoid(new JsGraalAuthenticationContext(authenticationContext)); + JsGraalGraphBuilderFactory.persistCurrentContext(authenticationContext, context); + } catch (PolyglotException e) { + result.setBuildSuccessful(false); + result.setErrorReason( + "Error in executing the Javascript. " + FrameworkConstants.JSAttributes.JS_FUNC_ON_LOGIN_REQUEST + + " reason, " + e.getMessage()); + if (log.isDebugEnabled()) { + log.debug("Error in executing the Javascript.", e); + } + } catch (IOException e) { + result.setBuildSuccessful(false); + result.setErrorReason("Error in building the Javascript source" + e.getMessage()); + if (log.isDebugEnabled()) { + log.debug("Error in building the Javascript source", e); + } + } finally { + clearCurrentBuilder(context); + } + return this; + } + + private static void attachEventListeners(Map eventsMap, AuthGraphNode currentNode) { + + if (eventsMap == null) { + return; + } + DynamicDecisionNode decisionNode = new DynamicDecisionNode(); + addEventListeners(decisionNode, eventsMap); + if (!decisionNode.getFunctionMap().isEmpty()) { + attachToLeaf(currentNode, decisionNode); + } + } + + private void attachEventListeners(Map eventsMap) { + + if (eventsMap == null) { + return; + } + DynamicDecisionNode decisionNode = new DynamicDecisionNode(); + addEventListeners(decisionNode, eventsMap); + if (!decisionNode.getFunctionMap().isEmpty()) { + attachToLeaf(currentNode, decisionNode); + currentNode = decisionNode; + } + } + + /** + * Adds all the event listeners to the decision node. + * + * @param eventsMap Map of events and event handler functions, which is handled by this execution. + * @return created Dynamic Decision node. + */ + private static void addEventListeners(DynamicDecisionNode decisionNode, Map eventsMap) { + + if (eventsMap == null) { + return; + } + eventsMap.forEach((key, value) -> { + if ((!(value instanceof GraalSerializableJsFunction))) { + GraalSerializableJsFunction jsFunction = GraalSerializableJsFunction.toSerializableForm(value); + if (jsFunction != null) { + decisionNode.addFunction(key, jsFunction); + } else { + log.error("Event handler : " + key + " is not a function : " + value); + } + } else { + decisionNode.addFunction(key, (GraalSerializableJsFunction) value); + } + }); + } + + private static void addHandlers(ShowPromptNode showPromptNode, Map handlersMap) { + + if (handlersMap == null) { + return; + } + handlersMap.forEach((key, value) -> { + if (!(value instanceof GraalSerializableJsFunction)) { + GraalSerializableJsFunction jsFunction = GraalSerializableJsFunction.toSerializableForm(value); + if (jsFunction != null) { + showPromptNode.addHandler(key, jsFunction); + } else { + log.error("Event handler : " + key + " is not a function : " + value); + } + } else { + showPromptNode.addHandler(key, (GraalSerializableJsFunction) value); + } + }); + } + + /** + * Adds the step given by step ID tp the authentication graph. + * + * @param params params + */ + @SuppressWarnings("unchecked") + public void executeStepInAsyncEvent(int stepId, Object... params) { + + AuthenticationContext context = contextForJs.get(); + AuthGraphNode currentNode = dynamicallyBuiltBaseNode.get(); + + if (log.isDebugEnabled()) { + log.debug("Execute Step on async event. Step ID : " + stepId); + } + AuthenticationGraph graph = context.getSequenceConfig().getAuthenticationGraph(); + if (graph == null) { + log.error("The graph happens to be null on the sequence config. Can not execute step : " + stepId); + return; + } + + StepConfig stepConfig = graph.getStepMap().get(stepId); + if (stepConfig == null) { + if (log.isDebugEnabled()) { + log.debug("The stepConfig of the step ID : " + stepId + " is null"); + } + return; + } + // Inorder to keep original stepConfig as a backup in AuthenticationGraph. + StepConfig clonedStepConfig = new StepConfig(stepConfig); + StepConfig stepConfigFromContext = null; + if (MapUtils.isNotEmpty(context.getSequenceConfig().getStepMap())) { + stepConfigFromContext = context.getSequenceConfig().getStepMap().values().stream() + .filter(contextStepConfig -> (stepConfig.getOrder() == contextStepConfig.getOrder())).findFirst() + .orElse(null); + } + clonedStepConfig.applyStateChangesToNewObjectFromContextStepMap(stepConfigFromContext); + if (log.isDebugEnabled()) { + log.debug("Found step for the Step ID : " + stepId + ", Step Config " + clonedStepConfig); + } + StepConfigGraphNode newNode = wrap(clonedStepConfig); + if (currentNode == null) { + if (log.isDebugEnabled()) { + log.debug("Setting a new node at the first time. Node : " + newNode.getName()); + } + dynamicallyBuiltBaseNode.set(newNode); + } else { + attachToLeaf(currentNode, newNode); + } + + if (params.length > 0) { + // if there is only one param, it is assumed to be the event listeners + if (params[params.length - 1] instanceof Map) { + attachEventListeners((Map) params[params.length - 1], newNode); + } else { + log.error("Invalid argument and hence ignored. Last argument should be a Map of event listeners."); + } + } + + if (params.length == 2) { + // There is an argument with options present + if (params[0] instanceof Map) { + Map options = (Map) params[0]; + handleOptionsAsyncEvent(options, clonedStepConfig, context.getSequenceConfig().getStepMap()); + } + } + } + + @Override + public void addLongWaitProcessInternal(AsyncProcess asyncProcess, Map parameterMap) { + + LongWaitNode newNode = new LongWaitNode(asyncProcess); + + if (parameterMap != null) { + addEventListeners(newNode, parameterMap); + } + if (this.currentNode == null) { + this.result.setStartNode(newNode); + } else { + attachToLeaf(this.currentNode, newNode); + } + + this.currentNode = newNode; + } + + /** + * @param templateId Identifier of the template. + * @param parameters Parameters. + * @param handlers Handlers to run before and after the prompt. + * @param callbacks Callbacks to run after the prompt. + */ + @SuppressWarnings("unchecked") + @Override + public void addPromptInternal(String templateId, Map parameters, Map handlers, + Map callbacks) { + + ShowPromptNode newNode = new ShowPromptNode(); + newNode.setTemplateId(templateId); + newNode.setParameters(parameters); + + JsGraalGraphBuilder currentBuilder = getCurrentBuilder(); + if (currentBuilder.currentNode == null) { + currentBuilder.result.setStartNode(newNode); + } else { + attachToLeaf(currentBuilder.currentNode, newNode); + } + + currentBuilder.currentNode = newNode; + addEventListeners(newNode, callbacks); + addHandlers(newNode, handlers); + } + + public AuthenticationDecisionEvaluator getScriptEvaluator(BaseSerializableJsFunction fn) { + + return new JsBasedEvaluator((GraalSerializableJsFunction) fn); + } + + public static void clearCurrentBuilder(Context context) { + + context.close(); + clearCurrentBuilder(); + } + + /** + * Adds the step given by step ID tp the authentication graph. + * + * @param stepId Step Id + * @param params params + */ + @SuppressWarnings("unchecked") + public void executeStep(int stepId, Object... params) { + + StepConfig stepConfig; + stepConfig = stepNamedMap.get(stepId); + + if (stepConfig == null) { + log.error("Given Authentication Step :" + stepId + " is not in Environment"); + return; + } + StepConfigGraphNode newNode = wrap(stepConfig); + if (currentNode == null) { + result.setStartNode(newNode); + } else { + attachToLeaf(currentNode, newNode); + } + currentNode = newNode; + if (params.length > 0) { + // if there are any params provided, last one is assumed to be the event listeners + if (params[params.length - 1] instanceof Map) { + attachEventListeners((Map) params[params.length - 1]); + } else { + log.error("Invalid argument and hence ignored. Last argument should be a Map of event listeners."); + } + } + if (params.length == 2) { + // There is an argument with options present + if (params[0] instanceof Map) { + Map options = (Map) params[0]; + handleOptions(options, stepConfig); + } + } + } + + public static void sendErrorAsync(String url, Map parameterMap) { + + FailNode newNode = createFailNode(url, parameterMap, true); + + AuthGraphNode currentNode = dynamicallyBuiltBaseNode.get(); + if (currentNode == null) { + dynamicallyBuiltBaseNode.set(newNode); + } else { + attachToLeaf(currentNode, newNode); + } + } + + private static FailNode createFailNode(String url, Map parameterMap, boolean isShowErrorPage) { + + FailNode failNode = new FailNode(); + if (isShowErrorPage && StringUtils.isNotBlank(url)) { + failNode.setErrorPageUri(url); + } + // setShowErrorPage is set to true as sendError function redirects to a specific error page. + failNode.setShowErrorPage(isShowErrorPage); + + parameterMap.forEach((key, value) -> failNode.getFailureData().put(key, String.valueOf(value))); + return failNode; + } + + /** + * Javascript based Decision Evaluator implementation. + * This is used to create the Authentication Graph structure dynamically on the fly while the authentication flow + * is happening. + * The graph is re-organized based on last execution of the decision. + */ + public class JsBasedEvaluator implements AuthenticationDecisionEvaluator { + + private static final long serialVersionUID = 6853505881096840344L; + private final GraalSerializableJsFunction jsFunction; + + public JsBasedEvaluator(GraalSerializableJsFunction jsFunction) { + + this.jsFunction = jsFunction; + } + + @Override + public Object evaluate(AuthenticationContext authenticationContext, Object... params) { + + JsGraalGraphBuilder graphBuilder = JsGraalGraphBuilder.this; + Object result = null; + if (jsFunction == null) { + return null; + } + if (!jsFunction.isFunction()) { + return jsFunction.getSource(); + } + try { + currentBuilder.set(graphBuilder); + JsGraalGraphBuilderFactory.restoreCurrentContext(authenticationContext, context); + Context context = getContext(); + Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + + bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_EXECUTE_STEP, + (StepExecutor) graphBuilder::executeStepInAsyncEvent); + bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_SEND_ERROR, + (BiConsumer) JsGraalGraphBuilder::sendErrorAsync); + bindings.putMember(FrameworkConstants.JSAttributes.JS_AUTH_FAILURE, + (FailAuthenticationFunction) JsGraalGraphBuilder::failAsync); + bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_SHOW_PROMPT, + (PromptExecutor) graphBuilder::addShowPrompt); + bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_LOAD_FUNC_LIB, + (LoadExecutor) graphBuilder::loadLocalLibrary); + JsFunctionRegistry jsFunctionRegistrar = + FrameworkServiceDataHolder.getInstance().getJsFunctionRegistry(); + if (jsFunctionRegistrar != null) { + Map functionMap = + jsFunctionRegistrar.getSubsystemFunctionsMap(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER); + functionMap.forEach(bindings::putMember); + } + removeDefaultFunctions(context); + JsGraalGraphBuilder.contextForJs.set(authenticationContext); + + String identifier = UUID.randomUUID().toString(); + JSExecutionMonitorData scriptExecutionData = + retrieveAuthScriptExecutionMonitorData(authenticationContext); + try { + result = jsFunction.apply(context, params); + } finally { + scriptExecutionData = endScriptExecutionMonitor(identifier); + } + if (scriptExecutionData != null) { + storeAuthScriptExecutionMonitorData(authenticationContext, scriptExecutionData); + } + + JsGraalGraphBuilderFactory.persistCurrentContext(authenticationContext, context); + + AuthGraphNode executingNode = (AuthGraphNode) authenticationContext.getProperty( + FrameworkConstants.JSAttributes.PROP_CURRENT_NODE); + if (canInfuse(executingNode)) { + infuse(executingNode, dynamicallyBuiltBaseNode.get()); + } + + } catch (Throwable e) { + //We need to catch all the javascript errors here, then log and handle. + log.error("Error in executing the javascript for service provider : " + + authenticationContext.getServiceProviderName() + ", Javascript Fragment : \n" + + jsFunction.getSource(), e); + AuthGraphNode executingNode = (AuthGraphNode) authenticationContext.getProperty( + FrameworkConstants.JSAttributes.PROP_CURRENT_NODE); + FailNode failNode = new FailNode(); + attachToLeaf(executingNode, failNode); + } finally { + contextForJs.remove(); + dynamicallyBuiltBaseNode.remove(); + clearCurrentBuilder(context); + } + return result; + } + } + + private Context getContext() { + + return this.context; + } + + /** + * Adds a function to show a prompt in Javascript code. + * + * @param templateId Identifier of the template + * @param parameters parameters + */ + @SuppressWarnings("unchecked") + public void addShowPrompt(String templateId, Object... parameters) { + + ShowPromptNode newNode = new ShowPromptNode(); + newNode.setTemplateId(templateId); + + if (parameters.length == 2) { + newNode.setData((Map) GraalSerializer.getInstance().toJsSerializable(parameters[0])); + } + if (currentNode == null) { + result.setStartNode(newNode); + } else { + attachToLeaf(currentNode, newNode); + } + + currentNode = newNode; + if (parameters.length > 0) { + if (parameters[parameters.length - 1] instanceof Map) { + addEventListeners(newNode, (Map) parameters[parameters.length - 1]); + } else { + log.error("Invalid argument and hence ignored. Last argument should be a Map of event listeners."); + } + + } + } + + private boolean canInfuse(AuthGraphNode executingNode) { + + return executingNode instanceof DynamicDecisionNode && dynamicallyBuiltBaseNode.get() != null; + } + + public static void failAsync(Object... parameters) { + + Map parameterMap; + + if (parameters.length == 1) { + parameterMap = (Map) parameters[0]; + } else { + parameterMap = Collections.EMPTY_MAP; + } + + FailNode newNode = createFailNode(StringUtils.EMPTY, parameterMap, false); + + AuthGraphNode currentNode = dynamicallyBuiltBaseNode.get(); + if (currentNode == null) { + dynamicallyBuiltBaseNode.set(newNode); + } else { + attachToLeaf(currentNode, newNode); + } + } + + private void removeDefaultFunctions(Context context) throws IOException { + + context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, REMOVE_FUNCTIONS, + FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + } + + private JSExecutionSupervisor getJSExecutionSupervisor() { + + return FrameworkServiceDataHolder.getInstance().getJsExecutionSupervisor(); + } + + private void storeAuthScriptExecutionMonitorData(AuthenticationContext context, + JSExecutionMonitorData jsExecutionMonitorData) { + + context.setProperty(FrameworkConstants.AdaptiveAuthentication.PROP_EXECUTION_SUPERVISOR_RESULT, + jsExecutionMonitorData); + } + + private JSExecutionMonitorData retrieveAuthScriptExecutionMonitorData(AuthenticationContext context) { + + JSExecutionMonitorData jsExecutionMonitorData; + Object storedResult = + context.getProperty(FrameworkConstants.AdaptiveAuthentication.PROP_EXECUTION_SUPERVISOR_RESULT); + if (storedResult != null) { + jsExecutionMonitorData = (JSExecutionMonitorData) storedResult; + } else { + jsExecutionMonitorData = new JSExecutionMonitorData(0L, 0L); + } + return jsExecutionMonitorData; + } + + private void startScriptExecutionMonitor(String identifier, AuthenticationContext context, + JSExecutionMonitorData previousExecutionResult) { + + JSExecutionSupervisor jsExecutionSupervisor = getJSExecutionSupervisor(); + if (jsExecutionSupervisor == null) { + return; + } + getJSExecutionSupervisor().monitor(identifier, context.getServiceProviderName(), context.getTenantDomain(), + previousExecutionResult.getElapsedTime(), previousExecutionResult.getConsumedMemory()); + } + + private void startScriptExecutionMonitor(String identifier, AuthenticationContext context) { + + startScriptExecutionMonitor(identifier, context, new JSExecutionMonitorData(0L, 0L)); + } + + private JSExecutionMonitorData endScriptExecutionMonitor(String identifier) { + + JSExecutionSupervisor executionSupervisor = getJSExecutionSupervisor(); + if (executionSupervisor == null) { + return null; + } + return getJSExecutionSupervisor().completed(identifier); + } + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java new file mode 100644 index 000000000000..2a501a67b193 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2022, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs; + +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthGraphNode; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilder; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilderFactory; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.HostAccess; +import org.graalvm.polyglot.Value; +import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsSerializer; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsLogger; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; + +import java.util.HashMap; +import java.util.Map; + +public class JsGraalGraphBuilderFactory implements JsBaseGraphBuilderFactory { + + private static final Log LOG = LogFactory.getLog(JsGraalGraphBuilderFactory.class); + private static final String JS_BINDING_CURRENT_CONTEXT = "JS_BINDING_CURRENT_CONTEXT"; + + public void init() { + + } + + @SuppressWarnings("unchecked") + public static void restoreCurrentContext(AuthenticationContext authContext, Context context) + throws FrameworkException { + + Map map = (Map) authContext.getProperty(JS_BINDING_CURRENT_CONTEXT); + Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + if (map != null) { + for (Map.Entry entry : map.entrySet()) { + Object deserializedValue = GraalSerializer.getInstance().fromJsSerializable(entry.getValue(), context); + bindings.putMember(entry.getKey(), deserializedValue); + } + } + } + + public static void persistCurrentContext(AuthenticationContext authContext, Context context) { + + Value engineBindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + Map persistableMap = new HashMap<>(); + engineBindings.getMemberKeys().forEach((key) -> { + Value binding = engineBindings.getMember(key); + if (!binding.isHostObject()) { + persistableMap.put(key, GraalSerializer.getInstance().toJsSerializable(binding)); + } + }); + authContext.setProperty(JS_BINDING_CURRENT_CONTEXT, persistableMap); + } + + public Context createEngine(AuthenticationContext authenticationContext) { + + Context context = + Context.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE).allowHostAccess(HostAccess.ALL) + .build(); + + Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + JsLogger jsLogger = new JsLogger(); + bindings.putMember(FrameworkConstants.JSAttributes.JS_LOG, jsLogger); + return context; + } + + @Override + public JsSerializer getJsUtil() { + + return GraalSerializer.getInstance(); + } + + @Override + public JsBaseGraphBuilder getCurrentBuilder() { + + return JsGraalGraphBuilder.getCurrentBuilder(); + } + + public JsGraalGraphBuilder createBuilder(AuthenticationContext authenticationContext, + Map stepConfigMap) { + + return new JsGraalGraphBuilder(authenticationContext, stepConfigMap, createEngine(authenticationContext)); + } + + public JsGraalGraphBuilder createBuilder(AuthenticationContext authenticationContext, + Map stepConfigMap, AuthGraphNode currentNode) { + + return new JsGraalGraphBuilder(authenticationContext, stepConfigMap, createEngine(authenticationContext), + currentNode); + } + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java new file mode 100644 index 000000000000..feebdea35714 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java @@ -0,0 +1,72 @@ +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs; + +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperBaseFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalAuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalAuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalCookie; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalServletRequest; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalServletResponse; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalWritableParameters; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; + +import java.util.Map; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class JsGraalWrapperFactory implements JsWrapperBaseFactory { + + @Override + public JsGraalAuthenticatedUser createJsAuthenticatedUser(AuthenticatedUser authenticatedUser) { + + return new JsGraalAuthenticatedUser(authenticatedUser); + } + + @Override + public JsGraalAuthenticatedUser createJsAuthenticatedUser(AuthenticationContext authenticationContext, + AuthenticatedUser authenticatedUser) { + + return new JsGraalAuthenticatedUser(authenticationContext, authenticatedUser); + } + + @Override + public JsGraalAuthenticationContext createJsAuthenticationContext + (AuthenticationContext authenticationContext) { + + return new JsGraalAuthenticationContext(authenticationContext); + } + + @Override + public JsGraalCookie createJsCookie(Cookie cookie) { + + return new JsGraalCookie(cookie); + } + + @Override + public JsGraalWritableParameters createJsParameters(Map parameters) { + + return new JsGraalWritableParameters(parameters); + } + + @Override + public JsGraalWritableParameters createJsWritableParameters(Map data) { + + return new JsGraalWritableParameters(data); + } + + @Override + public JsGraalServletRequest createJsServletRequest(TransientObjectWrapper wrapped) { + + return new JsGraalServletRequest(wrapped); + } + + @Override + public JsGraalServletResponse createJsServletResponse(TransientObjectWrapper wrapped) { + + return new JsGraalServletResponse(wrapped); + } + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/AbstractJSContextMemberObject.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/AbstractJSContextMemberObject.java index 0f918d307e8d..ceb2bbad24ff 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/AbstractJSContextMemberObject.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/AbstractJSContextMemberObject.java @@ -1,7 +1,7 @@ /* - * Copyright (c) 2018, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2018-2023, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. * - * WSO2 Inc. licenses this file to you under the Apache License, + * WSO2 LLC. 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 @@ -21,6 +21,7 @@ import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import java.io.Serializable; +import java.util.Objects; /** * Represents the abstract class for all context objects @@ -48,4 +49,9 @@ public AuthenticationContext getContext() { return context; } + + public boolean hasMember (String name) { + Objects.requireNonNull(name); + return false; + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java new file mode 100644 index 000000000000..eada1b8ce363 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.identity.application.authentication.framework.ApplicationAuthenticator; +import org.wso2.carbon.identity.application.authentication.framework.config.ConfigurationFacade; +import org.wso2.carbon.identity.application.authentication.framework.config.model.ExternalIdPConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.internal.FrameworkServiceDataHolder; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils; +import org.wso2.carbon.identity.application.common.model.ClaimMapping; +import org.wso2.carbon.identity.application.mgt.ApplicationConstants; +import org.wso2.carbon.identity.base.IdentityException; +import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataHandler; +import org.wso2.carbon.identity.claim.metadata.mgt.exception.ClaimMetadataException; +import org.wso2.carbon.identity.core.IdentityClaimManager; +import org.wso2.carbon.identity.core.util.IdentityTenantUtil; +import org.wso2.carbon.idp.mgt.IdentityProviderManagementException; +import org.wso2.carbon.idp.mgt.IdentityProviderManager; +import org.wso2.carbon.user.api.UserRealm; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.core.claim.Claim; +import org.wso2.carbon.user.core.service.RealmService; +import org.wso2.carbon.user.core.util.UserCoreUtil; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class JsClaims extends AbstractJSContextMemberObject { + + protected static final Log LOG = LogFactory.getLog(JsClaims.class); + private String idp; + protected boolean isRemoteClaimRequest; + private int step; + protected transient AuthenticatedUser authenticatedUser; + + /** + * Constructor to get the user authenticated in step 'n'. + * + * @param step The authentication step + * @param idp The authenticated IdP + * @param isRemoteClaimRequest Whether the request is for remote claim (false for local claim request) + */ + public JsClaims(AuthenticationContext context, int step, String idp, boolean isRemoteClaimRequest) { + + this(step, idp, isRemoteClaimRequest); + initializeContext(context); + } + + public JsClaims(int step, String idp, boolean isRemoteClaimRequest) { + + this.isRemoteClaimRequest = isRemoteClaimRequest; + this.idp = idp; + this.step = step; + } + + @Override + public void initializeContext(AuthenticationContext context) { + + super.initializeContext(context); + if (StringUtils.isNotBlank(idp) && getContext().getCurrentAuthenticatedIdPs().containsKey(idp)) { + this.authenticatedUser = getContext().getCurrentAuthenticatedIdPs().get(idp).getUser(); + } else { + this.authenticatedUser = getAuthenticatedUserFromSubjectIdentifierStep(); + } + } + + /** + * Get authenticated user from step config of current subject identifier. + * + * @return AuthenticatedUser. + */ + private AuthenticatedUser getAuthenticatedUserFromSubjectIdentifierStep() { + + AuthenticatedUser authenticatedUser = null; + StepConfig stepConfig = getCurrentSubjectIdentifierStep(); + if (stepConfig != null) { + authenticatedUser = getCurrentSubjectIdentifierStep().getAuthenticatedUser(); + } + return authenticatedUser; + } + + /** + * Retrieve step config of current subject identifier. + * + * @return StepConfig. + */ + private StepConfig getCurrentSubjectIdentifierStep() { + + if (getContext().getSequenceConfig() == null) { + // Sequence config is not yet initialized. + return null; + } + Map stepConfigs = getContext().getSequenceConfig().getStepMap(); + Optional subjectIdentifierStep = stepConfigs.values().stream() + .filter(stepConfig -> (stepConfig.isCompleted() && stepConfig.isSubjectIdentifierStep())).findFirst(); + if (subjectIdentifierStep.isPresent()) { + return subjectIdentifierStep.get(); + } else if (getContext().getCurrentStep() > 0) { + return stepConfigs.get(getContext().getCurrentStep()); + } else { + return null; + } + } + + /** + * Constructor to get user who is not directly from a authentication step. Eg. Associated user of authenticated + * federated user in a authentication step. + * + * @param authenticatedUser Authenticated user + * @param isRemoteClaimRequest Whether the request is for remote claim (false for local claim request) + */ + public JsClaims(AuthenticatedUser authenticatedUser, boolean isRemoteClaimRequest) { + + this.isRemoteClaimRequest = isRemoteClaimRequest; + this.authenticatedUser = authenticatedUser; + } + + public JsClaims(AuthenticationContext context, AuthenticatedUser authenticatedUser, boolean isRemoteClaimRequest) { + + this(authenticatedUser, isRemoteClaimRequest); + initializeContext(context); + } + + public Object getMember(String claimUri) { + + if (authenticatedUser != null) { + if (isRemoteClaimRequest) { + return getFederatedClaim(claimUri); + } else { + return getLocalClaim(claimUri); + } + } + return null; + } + + public boolean hasMember(String claimUri) { + + if (authenticatedUser != null) { + if (isRemoteClaimRequest) { + return hasFederatedClaim(claimUri); + } else { + return hasLocalClaim(claimUri); + } + } + return false; + } + + /** + * Get the claim by local claim URI. + * + * @param claimUri Local claim URI + * @param claimValue Claim Value + */ + protected void setLocalClaim(String claimUri, String claimValue) { + + if (isFederatedIdP()) { + setLocalMappedClaim(claimUri, claimValue); + } else { + // This covers step with a local authenticator, and the scenarios where step/idp is not set + // if the step/idp is not set, user is assumed to be a local user + setLocalUserClaim(claimUri, claimValue); + } + } + + /** + * Sets the remote claim value that is mapped to the give local claim. + * + * @param localClaimURI Local claim URI + * @param claimValue Value to be set + */ + private void setLocalMappedClaim(String localClaimURI, String claimValue) { + + Map idpAttributesMap = authenticatedUser.getUserAttributes(); + Map remoteMapping = FrameworkUtils.getClaimMappings(idpAttributesMap, false); + String mappedRemoteClaim = getRemoteClaimMappedToLocalClaim(localClaimURI, remoteMapping); + if (mappedRemoteClaim != null) { + setFederatedClaim(mappedRemoteClaim, claimValue); + } + } + + /** + * Sets a local claim directly at the userstore for the given user by given claim uri. + * + * @param claimUri Local claim URI + * @param claimValue Claim value + */ + protected void setLocalUserClaim(String claimUri, Object claimValue) { + + int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); + RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); + String usernameWithDomain = + UserCoreUtil.addDomainToName(authenticatedUser.getUserName(), authenticatedUser.getUserStoreDomain()); + try { + UserRealm userRealm = realmService.getTenantUserRealm(usersTenantId); + Map claimUriMap = new HashMap<>(); + claimUriMap.put(claimUri, String.valueOf(claimValue)); + userRealm.getUserStoreManager().setUserClaimValues(usernameWithDomain, claimUriMap, null); + } catch (UserStoreException e) { + LOG.error( + String.format("Error when setting claim : %s of user: %s to value: %s", claimUri, authenticatedUser, + claimValue), e); + } + } + + /** + * Gets the remote claim that is mapped to the given local claim. + * + * @param localClaim local claim URI + * @param remoteClaimsMap Remote claim URI - value map + * @return Mapped remote claim URI if present. null otherwise + */ + private String getRemoteClaimMappedToLocalClaim(String localClaim, Map remoteClaimsMap) { + + String authenticatorDialect = null; + Map localToIdpClaimMapping; + String tenantDomain = getContext().getTenantDomain(); + try { + // Check if the IDP use an standard dialect (like oidc), If it does, dialect claim mapping are + // prioritized over IdP claim mapping + ApplicationAuthenticator authenticator = + getContext().getSequenceConfig().getStepMap().get(step).getAuthenticatedAutenticator() + .getApplicationAuthenticator(); + authenticatorDialect = authenticator.getClaimDialectURI(); + ExternalIdPConfig idPConfig = ConfigurationFacade.getInstance().getIdPConfigByName(idp, tenantDomain); + boolean useDefaultIdpDialect = idPConfig.useDefaultLocalIdpDialect(); + + if (authenticatorDialect != null || useDefaultIdpDialect) { + if (authenticatorDialect == null) { + authenticatorDialect = ApplicationConstants.LOCAL_IDP_DEFAULT_CLAIM_DIALECT; + } + localToIdpClaimMapping = ClaimMetadataHandler.getInstance() + .getMappingsMapFromOtherDialectToCarbon(authenticatorDialect, remoteClaimsMap.keySet(), + tenantDomain, true); + } else { + localToIdpClaimMapping = IdentityProviderManager.getInstance() + .getMappedIdPClaimsMap(idp, tenantDomain, Collections.singletonList(localClaim)); + } + if (localToIdpClaimMapping != null) { + return localToIdpClaimMapping.get(localClaim); + } + } catch (IdentityProviderManagementException e) { + LOG.error(String.format("Error when getting claim : %s of user: %s", localClaim, authenticatedUser), e); + } catch (ClaimMetadataException e) { + LOG.error("Error when getting claim mappings from " + authenticatorDialect + " for tenant domain: " + + tenantDomain); + } + return null; + } + + protected boolean hasLocalClaim(String claimUri) { + + int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); + RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); + try { + UserRealm userRealm = realmService.getTenantUserRealm(usersTenantId); + Claim[] supportedClaims = IdentityClaimManager.getInstance() + .getAllSupportedClaims((org.wso2.carbon.user.core.UserRealm) userRealm); + for (Claim claim : supportedClaims) { + if (claim.getClaimUri().equals(claimUri)) { + return true; + } + } + } catch (UserStoreException e) { + LOG.error("Error when retrieving user realm for tenant : " + usersTenantId, e); + } catch (IdentityException e) { + LOG.error("Error when initializing identity claim manager.", e); + } + return false; + } + + /** + * Check if the user has a federated claim with given name. + * + * @param claimUri Federated claim URI + * @return true if the IdP is federated and it has a claim for user with given URI. + * false otherwise + */ + protected boolean hasFederatedClaim(String claimUri) { + + if (isFederatedIdP()) { + Map attributesMap = authenticatedUser.getUserAttributes(); + Map remoteMapping = FrameworkUtils.getClaimMappings(attributesMap, false); + return remoteMapping.containsKey(claimUri); + } + // Can be a case where step is not set (e.g. associated local user) + return false; + } + + /** + * Get the claim by federated claim URI. + * + * @param claimUri Federated claim URI + * @return Claim value if the Idp is a federated Idp, and has a claim by given url for the user. + * null otherwise. + */ + protected String getFederatedClaim(String claimUri) { + + // If the idp is local, return null + if (isFederatedIdP()) { + Map attributesMap = authenticatedUser.getUserAttributes(); + Map remoteMapping = FrameworkUtils.getClaimMappings(attributesMap, false); + return remoteMapping.get(claimUri); + } + // Can be a case where step is not set (e.g. associated local user) + return null; + } + + /** + * Get the claim by local claim URI. + * + * @param claimUri Local claim URI + * @return Local user's claim value if the Idp is local, Mapped remote claim if the Idp is federated. + */ + protected String getLocalClaim(String claimUri) { + + if (isFederatedIdP()) { + return getLocalMappedClaim(claimUri); + } else { + // This covers step with a local authenticator, and the scenarios where step/idp is not set + // if the step/idp is not set, user is assumed to be a local user + return getLocalUserClaim(claimUri); + } + } + + /** + * Check if step's IdP is a federated IDP. + * + * @return true if the idp is federated + */ + protected boolean isFederatedIdP() { + + return StringUtils.isNotBlank(idp) && !FrameworkConstants.LOCAL.equals(idp); + } + + /** + * Sets a custom remote claim to the user. + * + * @param claimUri Remote claim uri + * @param claimValue Claim value + */ + protected void setFederatedClaim(String claimUri, String claimValue) { + + if (claimValue == null) { + claimValue = StringUtils.EMPTY; + } + ClaimMapping newClaimMapping = ClaimMapping.build(claimUri, claimUri, null, false); + authenticatedUser.getUserAttributes().put(newClaimMapping, claimValue); + } + + /** + * Gets the mapped remote claim value for the given local claim URI. + * + * @param claimUri Local claim URI + * @return Mapped remote claim value from IdP + */ + private String getLocalMappedClaim(String claimUri) { + + Map idpAttributesMap = authenticatedUser.getUserAttributes(); + Map remoteMapping = FrameworkUtils.getClaimMappings(idpAttributesMap, false); + + String remoteMappedClaim = getRemoteClaimMappedToLocalClaim(claimUri, remoteMapping); + if (remoteMappedClaim != null) { + return remoteMapping.get(remoteMappedClaim); + } + return null; + } + + protected String getLocalUserClaim(String claimUri) { + + int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); + String usernameWithDomain = + UserCoreUtil.addDomainToName(authenticatedUser.getUserName(), authenticatedUser.getUserStoreDomain()); + RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); + try { + UserRealm userRealm = realmService.getTenantUserRealm(usersTenantId); + Map claimValues = userRealm.getUserStoreManager() + .getUserClaimValues(usernameWithDomain, new String[]{claimUri}, null); + return claimValues.get(claimUri); + } catch (UserStoreException e) { + LOG.error(String.format("Error when getting claim : %s of user: %s", claimUri, authenticatedUser), e); + } + return null; + } + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java index 872e71ebf9d2..20dc3f3b9d31 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2022-2023, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -32,7 +32,7 @@ */ public abstract class JsParameters extends AbstractJSObjectWrapper implements JsBaseParameters { - private static final Log LOG = LogFactory.getLog(JsParameters.class); + protected static final Log LOG = LogFactory.getLog(JsParameters.class); public JsParameters(Map wrapped) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java new file mode 100644 index 000000000000..f98de44b3f45 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; + +import org.apache.commons.lang.StringUtils; +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyArray; +import org.graalvm.polyglot.proxy.ProxyObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; + +public class JsGraalAuthenticatedUser extends JsAuthenticatedUser implements ProxyObject { + + public JsGraalAuthenticatedUser(AuthenticationContext context, AuthenticatedUser wrappedUser, int step, + String idp) { + + super(context, wrappedUser, step, idp); + } + + public JsGraalAuthenticatedUser(AuthenticatedUser wrappedUser) { + + super(wrappedUser); + } + + public JsGraalAuthenticatedUser(AuthenticationContext context, AuthenticatedUser wrappedUser) { + + super(context, wrappedUser); + } + + @Override + public Object getMember(String name) { + + switch (name) { + case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT_IDENTIFIER: + return getWrapped().getAuthenticatedSubjectIdentifier(); + case FrameworkConstants.JSAttributes.JS_USERNAME: + return getWrapped().getUserName(); + case FrameworkConstants.JSAttributes.JS_USER_STORE_DOMAIN: + return getWrapped().getUserStoreDomain(); + case FrameworkConstants.JSAttributes.JS_TENANT_DOMAIN: + return getWrapped().getTenantDomain(); + case FrameworkConstants.JSAttributes.JS_LOCAL_CLAIMS: + if (StringUtils.isNotBlank(idp)) { + return new JsGraalClaims(getContext(), step, idp, false); + } else { + // Represent step independent user + return new JsGraalClaims(getContext(), getWrapped(), false); + } + case FrameworkConstants.JSAttributes.JS_REMOTE_CLAIMS: + if (StringUtils.isNotBlank(idp)) { + return new JsGraalClaims(getContext(), step, idp, true); + } else { + // Represent step independent user + return new JsGraalClaims(getContext(), getWrapped(), true); + } + case FrameworkConstants.JSAttributes.JS_LOCAL_ROLES: + return getLocalRoles(); + case FrameworkConstants.JSAttributes.JS_CLAIMS: + if (StringUtils.isNotBlank(idp)) { + return new JsGraalRuntimeClaims(getContext(), step, idp); + } else { + // Represent step independent user + return new JsGraalRuntimeClaims(getContext(), getWrapped()); + } + default: + return super.getMember(name); + } + } + + @Override + public Object getMemberKeys() { + + return ProxyArray.fromArray(FrameworkConstants.JSAttributes.JS_USERNAME); + } + + public void putMember(String name, Value value) { + + setMember(name, value.asString()); + } + + @Override + public boolean hasMember(String name) { + + switch (name) { + case FrameworkConstants.JSAttributes.JS_LOCAL_CLAIMS: + case FrameworkConstants.JSAttributes.JS_REMOTE_CLAIMS: + case FrameworkConstants.JSAttributes.JS_CLAIMS: + return true; + default: + return super.hasMember(name); + } + } + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java new file mode 100644 index 000000000000..dde56aafd08c --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; + +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyArray; +import org.graalvm.polyglot.proxy.ProxyObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; + +public class JsGraalAuthenticationContext extends JsAuthenticationContext implements ProxyObject { + + public JsGraalAuthenticationContext(AuthenticationContext wrapped) { + + super(wrapped); + } + + @Override + public Object getMember(String name) { + + switch (name) { + case FrameworkConstants.JSAttributes.JS_REQUESTED_ACR: + return getWrapped().getRequestedAcr(); + case FrameworkConstants.JSAttributes.JS_TENANT_DOMAIN: + return getWrapped().getTenantDomain(); + case FrameworkConstants.JSAttributes.JS_SERVICE_PROVIDER_NAME: + return getWrapped().getServiceProviderName(); + case FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER: + return getLastLoginFailedUserFromWrappedContext(); + case FrameworkConstants.JSAttributes.JS_REQUEST: + return new JsGraalServletRequest((TransientObjectWrapper) getWrapped().getParameter( + FrameworkConstants.RequestAttribute.HTTP_REQUEST)); + case FrameworkConstants.JSAttributes.JS_RESPONSE: + return new JsGraalServletResponse((TransientObjectWrapper) getWrapped().getParameter( + FrameworkConstants.RequestAttribute.HTTP_RESPONSE)); + case FrameworkConstants.JSAttributes.JS_STEPS: + return new JsGraalSteps(getWrapped()); + case FrameworkConstants.JSAttributes.JS_CURRENT_STEP: + return new JsGraalStep(getContext(), getContext().getCurrentStep(), getAuthenticatedIdPOfCurrentStep()); + case FrameworkConstants.JSAttributes.JS_CURRENT_KNOWN_SUBJECT: + StepConfig stepConfig = getCurrentSubjectIdentifierStep(); + if (stepConfig != null) { + return new JsGraalAuthenticatedUser(this.getContext(), stepConfig.getAuthenticatedUser(), + stepConfig.getOrder(), stepConfig.getAuthenticatedIdP()); + } else { + return null; + } + case FrameworkConstants.JSAttributes.JS_RETRY_STEP: + return getWrapped().isRetrying(); + } + return super.getMember(name); + } + + @Override + public Object getMemberKeys() { + + return ProxyArray.fromArray(FrameworkConstants.JSAttributes.JS_STEPS, + FrameworkConstants.JSAttributes.JS_CURRENT_KNOWN_SUBJECT); + } + + @Override + public void putMember(String key, Value value) { + + if (FrameworkConstants.JSAttributes.JS_SELECTED_ACR.equals(key)) { + getWrapped().setSelectedAcr(String.valueOf(value)); + } + } + + @Override + public boolean removeMember(String name) { + + if (FrameworkConstants.JSAttributes.JS_SELECTED_ACR.equals(name)) { + getWrapped().setSelectedAcr(null); + return true; + } + return false; + } + + private JsGraalAuthenticatedUser getLastLoginFailedUserFromWrappedContext() { + + Object lastLoginFailedUser = + getWrapped().getProperty(FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER); + if (lastLoginFailedUser instanceof AuthenticatedUser) { + return new JsGraalAuthenticatedUser(getWrapped(), (AuthenticatedUser) lastLoginFailedUser); + } else { + return null; + } + } + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java new file mode 100644 index 000000000000..6dc86b0bdcae --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyArray; +import org.graalvm.polyglot.proxy.ProxyObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsClaims; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornClaims; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.internal.FrameworkServiceDataHolder; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.core.util.IdentityTenantUtil; +import org.wso2.carbon.user.api.UserRealm; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.core.service.RealmService; +import org.wso2.carbon.user.core.util.UserCoreUtil; + +import java.util.HashMap; +import java.util.Map; + +/** + * Represent the user's claim for GraalJs Execution. Can be either remote or local. + */ +public class JsGraalClaims extends JsClaims implements ProxyObject { + + private final transient Map localClaimUriToValueReadCache = new HashMap<>(); + private static final Log LOG = LogFactory.getLog(JsNashornClaims.class); + private String idp; + private boolean isRemoteClaimRequest; + private int step; + protected transient AuthenticatedUser authenticatedUser; + + public JsGraalClaims(AuthenticationContext context, int step, String idp, boolean isRemoteClaimRequest) { + + super(context, step, idp, isRemoteClaimRequest); + } + + public JsGraalClaims(AuthenticationContext context, AuthenticatedUser authenticatedUser, + boolean isRemoteClaimRequest) { + + super(context, authenticatedUser, isRemoteClaimRequest); + } + + @Override + public Object getMemberKeys() { + + return ProxyArray.fromArray(); + } + + @Override + public void putMember(String claimUri, Value claimValue) { + + if (authenticatedUser != null) { + if (isRemoteClaimRequest) { + setFederatedClaim(claimUri, String.valueOf(claimValue)); + } else { + setLocalClaim(claimUri, String.valueOf(claimValue)); + } + } + } + + /** + * Sets a local claim directly at the userstore for the given user by given claim uri. + * + * @param claimUri Local claim URI + * @param claimValue Claim value + */ + protected void setLocalUserClaim(String claimUri, Object claimValue) { + + localClaimUriToValueReadCache.clear(); + + int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); + RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); + String usernameWithDomain = + UserCoreUtil.addDomainToName(authenticatedUser.getUserName(), authenticatedUser.getUserStoreDomain()); + try { + UserRealm userRealm = realmService.getTenantUserRealm(usersTenantId); + Map claimUriMap = new HashMap<>(); + claimUriMap.put(claimUri, String.valueOf(claimValue)); + userRealm.getUserStoreManager().setUserClaimValues(usernameWithDomain, claimUriMap, null); + } catch (UserStoreException e) { + LOG.error( + String.format("Error when setting claim : %s of user: %s to value: %s", claimUri, authenticatedUser, + claimValue), e); + } + } + + /** + * Check if there is a local claim by given name. + * + * @param claimUri The local claim URI + * @return Claim value of the user authenticated by the indicated IdP + */ + protected boolean hasLocalClaim(String claimUri) { + + String value = localClaimUriToValueReadCache.get(claimUri); + if (value != null) { + return true; + } + value = getLocalClaim(claimUri); + if (value != null) { + localClaimUriToValueReadCache.put(claimUri, value); + return true; + } + return false; + } + + /** + * Get the local user claim value specified by the Claim URI. + * + * @param claimUri Local claim URI + * @return Claim value of the given claim URI for the local user if available. Null Otherwise. + */ + protected String getLocalUserClaim(String claimUri) { + + String value = localClaimUriToValueReadCache.get(claimUri); + if (value != null) { + return value; + } + int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); + String usernameWithDomain = + UserCoreUtil.addDomainToName(authenticatedUser.getUserName(), authenticatedUser.getUserStoreDomain()); + RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); + try { + UserRealm userRealm = realmService.getTenantUserRealm(usersTenantId); + Map claimValues = userRealm.getUserStoreManager() + .getUserClaimValues(usernameWithDomain, new String[]{claimUri}, null); + return claimValues.get(claimUri); + } catch (UserStoreException e) { + LOG.error(String.format("Error when getting claim : %s of user: %s", claimUri, authenticatedUser), e); + } + return null; + } +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java new file mode 100644 index 000000000000..c110ec45e69f --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyArray; +import org.graalvm.polyglot.proxy.ProxyObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsCookie; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; + +import java.util.Arrays; + +import javax.servlet.http.Cookie; + +public class JsGraalCookie extends JsCookie implements ProxyObject { + + protected static final Log LOG = LogFactory.getLog(JsGraalCookie.class); + + public JsGraalCookie(Cookie cookie) { + + super(cookie); + } + + @Override + public Object getMemberKeys() { + + String[] cookieProperties = new String[]{FrameworkConstants.JSAttributes.JS_COOKIE_NAME, + FrameworkConstants.JSAttributes.JS_COOKIE_VALUE, FrameworkConstants.JSAttributes.JS_COOKIE_COMMENT, + FrameworkConstants.JSAttributes.JS_COOKIE_DOMAIN, FrameworkConstants.JSAttributes.JS_COOKIE_MAX_AGE, + FrameworkConstants.JSAttributes.JS_COOKIE_PATH, FrameworkConstants.JSAttributes.JS_COOKIE_SECURE, + FrameworkConstants.JSAttributes.JS_COOKIE_VERSION, FrameworkConstants.JSAttributes.JS_COOKIE_HTTP_ONLY}; + return ProxyArray.fromArray(Arrays.stream(cookieProperties).filter(this::hasMember).toArray()); + } + + public void putMember(String key, Value value) { + + LOG.warn("Unsupported operation. Cookie is read only. Can't remove parameter " + key); + } +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java new file mode 100644 index 000000000000..33fcc07bfc5b --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; + +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyArray; +import org.graalvm.polyglot.proxy.ProxyObject; + +import java.util.Map; + +import javax.servlet.http.HttpServletResponse; + +public class JsGraalHeaders implements ProxyObject { + + private final Map wrapped; + private final HttpServletResponse response; + + public JsGraalHeaders(Map wrapped, HttpServletResponse response) { + + this.wrapped = wrapped; + this.response = response; + } + + @Override + public Object getMember(String name) { + + if (wrapped == null) { + return null; + } else { + return wrapped.get(name); + } + } + + @Override + public Object getMemberKeys() { + + return ProxyArray.fromArray(wrapped.keySet().toArray()); + } + + @Override + public boolean hasMember(String name) { + + if (wrapped == null) { + return false; + } else { + return wrapped.get(name) != null; + } + } + + @Override + public boolean removeMember(String name) { + + if (wrapped == null) { + return false; + } else { + wrapped.remove(name); + } + return false; + } + + @Override + public void putMember(String name, Value value) { + + if (wrapped != null) { + wrapped.put(name, value); + //adds a new header to the response. + response.addHeader(name, String.valueOf(value)); + } + } +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java new file mode 100644 index 000000000000..d908deece9db --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; + +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyArray; +import org.graalvm.polyglot.proxy.ProxyObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsParameters; + +import java.util.Map; + +public class JsGraalParameters extends JsParameters implements ProxyObject { + + public JsGraalParameters(Map wrapped) { + + super(wrapped); + } + + @Override + public Object getMember(String name) { + + Object member = getWrapped().get(name); + if (member instanceof Map) { + return new JsGraalParameters((Map) member); + } + return member; + } + + @Override + public Object getMemberKeys() { + + return ProxyArray.fromArray(getWrapped().keySet().toArray()); + } + + public void putMember(String key, Value value) { + + LOG.warn("Unsupported operation. Parameters are read only. Can't set parameter " + key + " to value: " + value); + } + + @Override + public boolean removeMember(String name) { + + LOG.warn("Unsupported operation. Parameters are read only. Can't remove parameter " + name); + return false; + } + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java new file mode 100644 index 000000000000..9a3c887dd64d --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; + +import org.apache.commons.lang.StringUtils; +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyObject; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; + +/** + * Represent the user's runtime claims for GraalJs Execution. + */ +public class JsGraalRuntimeClaims extends JsGraalClaims implements ProxyObject { + + public JsGraalRuntimeClaims(AuthenticationContext context, int step, String idp) { + + super(context, step, idp, false); + } + + public JsGraalRuntimeClaims(AuthenticationContext context, AuthenticatedUser user) { + + super(context, user, false); + } + + @Override + public Object getMember(String claimUri) { + + if (authenticatedUser != null) { + return getRuntimeClaim(claimUri); + } + return null; + } + + @Override + public boolean hasMember(String claimUri) { + + if (authenticatedUser != null) { + return hasRuntimeClaim(claimUri); + } + return false; + } + + @Override + public void putMember(String claimUri, Value claimValue) { + + if (authenticatedUser != null) { + setRuntimeClaim(claimUri, String.valueOf(claimValue)); + } + } + + private Object getRuntimeClaim(String claimUri) { + + String runtimeClaimValue = getContext().getRuntimeClaim(claimUri); + if (runtimeClaimValue != null) { + return runtimeClaimValue; + } + if (isFederatedIdP()) { + return getFederatedClaim(claimUri); + } + return getLocalClaim(claimUri); + } + + private boolean hasRuntimeClaim(String claimUri) { + + String claim = getContext().getRuntimeClaim(claimUri); + if (claim != null) { + return true; + } + if (isFederatedIdP()) { + return hasFederatedClaim(claimUri); + } + return hasLocalClaim(claimUri); + } + + private void setRuntimeClaim(String claimUri, String claimValue) { + + String claimValueAsString = String.valueOf(claimValue); + if (claimValueAsString == null) { + claimValueAsString = StringUtils.EMPTY; + } + getContext().addRuntimeClaim(claimUri, claimValueAsString); + } +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java new file mode 100644 index 000000000000..520137886a7b --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyArray; +import org.graalvm.polyglot.proxy.ProxyObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsServletRequest; +import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; +import org.wso2.carbon.identity.core.util.IdentityUtil; + +import java.util.Arrays; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; + +public class JsGraalServletRequest extends JsServletRequest implements ProxyObject { + + protected static final Log LOG = LogFactory.getLog(JsGraalServletRequest.class); + + public JsGraalServletRequest(TransientObjectWrapper wrapped) { + + super(wrapped); + } + + @Override + public Object getMember(String name) { + + switch (name) { + case FrameworkConstants.JSAttributes.JS_HEADERS: + Map headers = new HashMap(); + Enumeration headerNames = getRequest().getHeaderNames(); + if (headerNames != null) { + while (headerNames.hasMoreElements()) { + String headerName = headerNames.nextElement(); + headers.put(headerName, getRequest().getHeader(headerName)); + } + } + return new JsGraalWritableParameters(headers); + case FrameworkConstants.JSAttributes.JS_PARAMS: + return new JsGraalParameters(getRequest().getParameterMap()); + case FrameworkConstants.JSAttributes.JS_COOKIES: + Map cookies = new HashMap(); + Cookie[] cookieArr = getRequest().getCookies(); + if (cookieArr != null) { + for (Cookie cookie : cookieArr) { + cookies.put(cookie.getName(), new JsGraalCookie(cookie)); + } + } + return new JsGraalWritableParameters(cookies); + case FrameworkConstants.JSAttributes.JS_REQUEST_IP: + return IdentityUtil.getClientIpAddress(getRequest()); + default: + return super.getMember(name); + } + } + + @Override + public Object getMemberKeys() { + + String[] servletRequestProperties = + new String[]{FrameworkConstants.JSAttributes.JS_HEADERS, FrameworkConstants.JSAttributes.JS_COOKIES, + FrameworkConstants.JSAttributes.JS_REQUEST_IP, FrameworkConstants.JSAttributes.JS_PARAMS}; + + return ProxyArray.fromArray(Arrays.stream(servletRequestProperties).filter(this::hasMember).toArray()); + } + + @Override + public boolean hasMember(String name) { + + if (getRequest() == null) { + //Transient Object is null, hence no member access is possible. + return false; + } + + switch (name) { + case FrameworkConstants.JSAttributes.JS_HEADERS: + case FrameworkConstants.JSAttributes.JS_COOKIES: + case FrameworkConstants.JSAttributes.JS_REQUEST_IP: + return true; + case FrameworkConstants.JSAttributes.JS_PARAMS: + return getRequest().getParameterMap() != null; + default: + return super.hasMember(name); + } + } + + @Override + public void putMember(String key, Value value) { + + LOG.warn("Unsupported operation. Servlet Request is read only. Can't remove parameter " + key); + } + + @Override + public boolean removeMember(String key) { + + return false; + } + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java new file mode 100644 index 000000000000..d5885805dd83 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyArray; +import org.graalvm.polyglot.proxy.ProxyObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsServletResponse; +import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletResponse; + +public class JsGraalServletResponse extends JsServletResponse implements ProxyObject { + + Log LOG = LogFactory.getLog(JsGraalServletResponse.class); + + public JsGraalServletResponse(TransientObjectWrapper wrapped) { + + super(wrapped); + } + + @Override + public Object getMember(String name) { + + if (FrameworkConstants.JSAttributes.JS_HEADERS.equals(name)) { + Map headers = new HashMap<>(); + Collection headerNames = getResponse().getHeaderNames(); + if (headerNames != null) { + for (String element : headerNames) { + headers.put(element, getResponse().getHeader(element)); + } + } + return new JsGraalHeaders(headers, getResponse()); + } + return super.getMember(name); + } + + @Override + public Object getMemberKeys() { + + return ProxyArray.fromArray(FrameworkConstants.JSAttributes.JS_HEADERS); + } + + @Override + public boolean hasMember(String name) { + + if (getResponse() == null) { + //Transient Object is null, hence no member access is possible. + return false; + } + if (FrameworkConstants.JSAttributes.JS_HEADERS.equals(name)) { + return true; + } + return super.hasMember(name); + } + + @Override + public void putMember(String key, Value value) { + + LOG.warn("Unsupported operation. Servlet Response is read only. Can't set parameter " + key + " to value: " + + value); + } + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java new file mode 100644 index 000000000000..a78b6952df3f --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyArray; +import org.graalvm.polyglot.proxy.ProxyObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.AbstractJSContextMemberObject; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedIdPData; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public class JsGraalStep extends AbstractJSContextMemberObject implements ProxyObject { + + protected static final Log LOG = LogFactory.getLog(JsGraalStep.class); + + protected int step; + protected String authenticatedIdp; + + public JsGraalStep(int step, String authenticatedIdp) { + + this.step = step; + this.authenticatedIdp = authenticatedIdp; + } + + public JsGraalStep(AuthenticationContext context, int step, String authenticatedIdp) { + + this(step, authenticatedIdp); + initializeContext(context); + } + + @Override + public Object getMember(String name) { + + switch (name) { + case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT: + return new JsGraalAuthenticatedUser(getContext(), getSubject(), step, authenticatedIdp); + case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP: + return authenticatedIdp; + case FrameworkConstants.JSAttributes.JS_AUTHENTICATION_OPTIONS: + return getOptions(); + default: + return null; + } + } + + @Override + public Object getMemberKeys() { + + return ProxyArray.fromArray(FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT, + FrameworkConstants.JSAttributes.JS_AUTHENTICATION_OPTIONS, + FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP); + } + + @Override + public void putMember(String key, Value value) { + + LOG.warn("Step is readonly, hence the put member is ignored."); + } + + @Override + public boolean removeMember(String name) { + + LOG.warn("Step is readonly, hence the can't remove the member."); + return false; + } + + public boolean hasMember(String name) { + + switch (name) { + case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT: + case FrameworkConstants.JSAttributes.JS_AUTHENTICATION_OPTIONS: + case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP: + return true; + default: + return super.hasMember(name); + } + } + + protected AuthenticatedUser getSubject() { + + if (authenticatedIdp != null) { + AuthenticatedIdPData idPData = getContext().getCurrentAuthenticatedIdPs().get(authenticatedIdp); + if (idPData == null) { + idPData = getContext().getPreviousAuthenticatedIdPs().get(authenticatedIdp); + } + if (idPData != null) { + return idPData.getUser(); + } + } + return null; + } + + protected List> getOptions() { + + List> optionsList = new ArrayList<>(); + Optional optionalStepConfig = getContext().getSequenceConfig().getStepMap().values().stream() + .filter(stepConfig -> stepConfig.getOrder() == step).findFirst(); + optionalStepConfig.ifPresent(stepConfig -> stepConfig.getAuthenticatorList() + .forEach(authConfig -> authConfig.getIdpNames().forEach(name -> { + Map option = new HashMap<>(); + option.put(FrameworkConstants.JSAttributes.IDP, name); + option.put(FrameworkConstants.JSAttributes.AUTHENTICATOR, + authConfig.getApplicationAuthenticator().getName()); + optionsList.add(option); + }))); + return optionsList; + } +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java new file mode 100644 index 000000000000..bc5eceb3d2d0 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyArray; +import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.AbstractJSContextMemberObject; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; + +import java.util.Optional; + +public class JsGraalSteps extends AbstractJSContextMemberObject implements ProxyArray { + + private static final Log LOG = LogFactory.getLog(JsGraalSteps.class); + + public JsGraalSteps() { + + } + + public JsGraalSteps(AuthenticationContext context) { + + initializeContext(context); + } + + private String getAuthenticatedIdPOfStep(int step) { + + if (getContext().getSequenceConfig() == null) { + //Sequence config is not yet initialized + return null; + } + + Optional optionalStepConfig = getContext().getSequenceConfig().getStepMap().values().stream() + .filter(stepConfig -> stepConfig.getOrder() == step).findFirst(); + return optionalStepConfig.map(StepConfig::getAuthenticatedIdP).orElse(null); + } + + @Override + public Object get(long index) { + + if (getContext() == null) { + return null; + } else { + return new JsGraalStep(getContext(), (int) index, getAuthenticatedIdPOfStep((int) index)); + } + } + + @Override + public void set(long index, Value value) { + //Steps can n ot be set withs script + } + + @Override + public long getSize() { + + if (getContext() == null) { + return 0; + } else { + return getContext().getSequenceConfig().getStepMap().size(); + } + } + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java new file mode 100644 index 000000000000..4b00f9b9db5a --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; + +import org.graalvm.polyglot.Value; + +import java.util.List; +import java.util.Map; + +public class JsGraalWritableParameters extends JsGraalParameters { + + public JsGraalWritableParameters(Map wrapped) { + + super(wrapped); + } + + @Override + public Object getMember(String name) { + + Object member = getWrapped().get(name); + if (member instanceof Map) { + return new JsGraalWritableParameters((Map) member); + } + return member; + } + + @Override + public boolean removeMember(String name) { + + getWrapped().remove(name); + return false; + } + + @Override + public void putMember(String key, Value value) { + + getWrapped().put(key, value.as(List.class)); + } + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornGraphBuilder.java index 4ce548a5b932..833547f16a15 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornGraphBuilder.java @@ -88,7 +88,6 @@ public class JsOpenJdkNashornGraphBuilder extends JsGraphBuilder { private Map stepNamedMap; private AuthenticationGraph result = new AuthenticationGraph(); private AuthGraphNode currentNode = null; - private AuthenticationContext authenticationContext; private ScriptEngine engine; private static ThreadLocal contextForJs = new ThreadLocal<>(); private static ThreadLocal dynamicallyBuiltBaseNode = new ThreadLocal<>(); @@ -942,7 +941,7 @@ private static void addHandlers(ShowPromptNode showPromptNode, Map * Since Nashorn is deprecated in JDK 11 and onwards. We are introducing OpenJDK Nashorn engine. */ -public class JsOpenJdkNashornGraphBuilderFactory implements JsBaseGraphBuilderFactory { +public class JsOpenJdkNashornGraphBuilderFactory implements JsBaseGraphBuilderFactory { private static final Log LOG = LogFactory.getLog(JsOpenJdkNashornGraphBuilderFactory.class); private static final String JS_BINDING_CURRENT_CONTEXT = "JS_BINDING_CURRENT_CONTEXT"; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornSerializer.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornSerializer.java index f4b0e25923f0..ae7aa3f556c9 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornSerializer.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornSerializer.java @@ -37,7 +37,7 @@ /** * Serializer class supports Open JDK Nashorn Engine. */ -public class JsOpenJdkNashornSerializer implements JsSerializer { +public class JsOpenJdkNashornSerializer implements JsSerializer { private static final Log log = LogFactory.getLog(JsOpenJdkNashornSerializer.class); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/OpenJdkNashornSerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/OpenJdkNashornSerializableJsFunction.java index 99c3ece9b66d..40c2b19a2ae7 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/OpenJdkNashornSerializableJsFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/OpenJdkNashornSerializableJsFunction.java @@ -35,7 +35,7 @@ * Javascript function wrapper. This allows serialization of a javascript defined function. * Since Nashorn is deprecated in JDK 11 and onwards. We replaced it with OpenJDK Nashorn classes. */ -public class OpenJdkNashornSerializableJsFunction implements BaseSerializableJsFunction { +public class OpenJdkNashornSerializableJsFunction implements BaseSerializableJsFunction { private static final Log log = LogFactory.getLog(OpenJdkNashornSerializableJsFunction.class); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java index 44c9795fb67f..f41d8b013d33 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java @@ -608,6 +608,11 @@ public static class JSAttributes { public static final String SUBJECT_IDENTIFIER_PARAM = "markAsSubjectIdentifierStep"; public static final String SUBJECT_ATTRIBUTE_PARAM = "markAsSubjectAttributeStep"; public static final String SKIP_PROMPT = "skipPrompt"; + + public static final String POLYGLOT_SOURCE = "src.js"; + public static final String POLYGLOT_LANGUAGE = "js"; + public static final String GRAALJS = "graaljs"; + public static final String NASHORN = "nashorn"; } /** diff --git a/pom.xml b/pom.xml index b50267d77dd4..6c37c8f15695 100644 --- a/pom.xml +++ b/pom.xml @@ -1782,6 +1782,32 @@ jackson-dataformat-cbor ${com.fasterxml.jackson.cbor.version} + + + org.graalvm.sdk + graal-sdk + ${graalvm.version} + + + org.graalvm.js + js + ${graalvm.version} + + + org.graalvm.truffle + truffle-api + ${graalvm.version} + + + + + + + + + + + @@ -2086,6 +2112,10 @@ 2.2.224 + 20.2.0 + + 68.1 + 3.1.0 4.8.4.0 From 72dfb8f9d32fa222e1c3bfd4b81c3a66dcb13038 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Tue, 2 Jan 2024 17:30:03 +0530 Subject: [PATCH 02/35] Reduce code duplication --- .../graph/BaseSerializableJsFunction.java | 2 - .../graaljs/GraalSerializableJsFunction.java | 74 ++--- .../config/model/graph/js/JsClaims.java | 54 ++-- .../model/graph/js/graaljs/JsGraalClaims.java | 4 - .../graph/js/nashorn/JsNashornClaims.java | 290 +---------------- .../nashorn/JsOpenJdkNashornClaims.java | 292 +----------------- .../framework/util/FrameworkConstants.java | 1 + .../framework/util/FrameworkUtils.java | 3 + 8 files changed, 85 insertions(+), 635 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/BaseSerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/BaseSerializableJsFunction.java index 388c43f6db34..e07210f5f001 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/BaseSerializableJsFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/BaseSerializableJsFunction.java @@ -20,8 +20,6 @@ import java.io.Serializable; -import javax.script.ScriptEngine; - /** * Serializable javascript function. * This is required since the next javascript execution may happen on a different node than current node, when user diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java index c921f8c566d2..c99a129cabef 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java @@ -54,6 +54,43 @@ public GraalSerializableJsFunction(String source, boolean isFunction) { this.isPolyglotFunction = true; } + public String getSource() { + + return source; + } + + public void setSource(String source) { + + this.source = source; + } + + @Override + public boolean isFunction() { + + return isHostFunction; + } + + @Override + public void setFunction(boolean function) { + + } + + public Object apply(Context polyglotContext, Object... params) { + + if (isPolyglotFunction) { + try { + polyglotContext.eval(Source.newBuilder("js", " var curFunc = " + getSource(), "src.js").build()); + return polyglotContext.getBindings("js").getMember("curFunc").execute(params); + } catch (IOException e) { + log.error("Error when building the from function source", e); + } catch (PolyglotException e) { + log.error("Error when executing function", e); + } + } + + return null; + } + /** * This will return the converted NashornSerializableJsFunction if the given ScriptObjectMirror is a function. * @@ -89,43 +126,6 @@ public static GraalSerializableJsFunction toSerializableForm(Object functionObje } - public Object apply(Context polyglotContext, Object... params) { - - if (isPolyglotFunction) { - try { - polyglotContext.eval(Source.newBuilder("js", " var curFunc = " + getSource(), "src.js").build()); - return polyglotContext.getBindings("js").getMember("curFunc").execute(params); - } catch (IOException e) { - log.error("Error when building the from function source", e); - } catch (PolyglotException e) { - log.error("Error when executing function", e); - } - } - - return null; - } - - public String getSource() { - - return source; - } - - @Override - public boolean isFunction() { - - return isHostFunction; - } - - @Override - public void setFunction(boolean function) { - - } - - public void setSource(String source) { - - this.source = source; - } - public String getName() { return name; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java index eada1b8ce363..e396e266dd09 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java @@ -26,6 +26,7 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.ExternalIdPConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException; import org.wso2.carbon.identity.application.authentication.framework.internal.FrameworkServiceDataHolder; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; @@ -41,9 +42,10 @@ import org.wso2.carbon.idp.mgt.IdentityProviderManager; import org.wso2.carbon.user.api.UserRealm; import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.core.UserStoreClientException; import org.wso2.carbon.user.core.claim.Claim; +import org.wso2.carbon.user.core.common.AbstractUserStoreManager; import org.wso2.carbon.user.core.service.RealmService; -import org.wso2.carbon.user.core.util.UserCoreUtil; import java.util.Collections; import java.util.HashMap; @@ -53,9 +55,9 @@ public class JsClaims extends AbstractJSContextMemberObject { protected static final Log LOG = LogFactory.getLog(JsClaims.class); - private String idp; + protected String idp; protected boolean isRemoteClaimRequest; - private int step; + protected int step; protected transient AuthenticatedUser authenticatedUser; /** @@ -78,6 +80,10 @@ public JsClaims(int step, String idp, boolean isRemoteClaimRequest) { this.step = step; } + public JsClaims() { + + } + @Override public void initializeContext(AuthenticationContext context) { @@ -128,8 +134,8 @@ private StepConfig getCurrentSubjectIdentifierStep() { } /** - * Constructor to get user who is not directly from a authentication step. Eg. Associated user of authenticated - * federated user in a authentication step. + * Constructor to get user who is not directly from an authentication step. E.g. Associated user of authenticated + * federated user in an authentication step. * * @param authenticatedUser Authenticated user * @param isRemoteClaimRequest Whether the request is for remote claim (false for local claim request) @@ -193,7 +199,7 @@ protected void setLocalClaim(String claimUri, String claimValue) { * @param localClaimURI Local claim URI * @param claimValue Value to be set */ - private void setLocalMappedClaim(String localClaimURI, String claimValue) { + protected void setLocalMappedClaim(String localClaimURI, String claimValue) { Map idpAttributesMap = authenticatedUser.getUserAttributes(); Map remoteMapping = FrameworkUtils.getClaimMappings(idpAttributesMap, false); @@ -213,17 +219,22 @@ protected void setLocalUserClaim(String claimUri, Object claimValue) { int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); - String usernameWithDomain = - UserCoreUtil.addDomainToName(authenticatedUser.getUserName(), authenticatedUser.getUserStoreDomain()); try { UserRealm userRealm = realmService.getTenantUserRealm(usersTenantId); Map claimUriMap = new HashMap<>(); claimUriMap.put(claimUri, String.valueOf(claimValue)); - userRealm.getUserStoreManager().setUserClaimValues(usernameWithDomain, claimUriMap, null); + ((AbstractUserStoreManager) userRealm.getUserStoreManager()) + .setUserClaimValuesWithID(authenticatedUser.getUserId(), claimUriMap, null); + } catch (UserStoreClientException e) { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Error when setting claim : %s of user: %s to value: %s. Error Message: %s", + claimUri, authenticatedUser, claimValue, e.getMessage())); + } } catch (UserStoreException e) { - LOG.error( - String.format("Error when setting claim : %s of user: %s to value: %s", claimUri, authenticatedUser, - claimValue), e); + LOG.error(String.format("Error when setting claim : %s of user: %s to value: %s", claimUri, + authenticatedUser, claimValue), e); + } catch (UserIdNotFoundException e) { + LOG.error("User id is not available for the user: " + authenticatedUser.getLoggableMaskedUserId(), e); } } @@ -240,7 +251,7 @@ private String getRemoteClaimMappedToLocalClaim(String localClaim, Map localToIdpClaimMapping; String tenantDomain = getContext().getTenantDomain(); try { - // Check if the IDP use an standard dialect (like oidc), If it does, dialect claim mapping are + // Check if the IDP use a standard dialect (like oidc), If it does, dialect claim mapping are // prioritized over IdP claim mapping ApplicationAuthenticator authenticator = getContext().getSequenceConfig().getStepMap().get(step).getAuthenticatedAutenticator() @@ -297,7 +308,7 @@ protected boolean hasLocalClaim(String claimUri) { * Check if the user has a federated claim with given name. * * @param claimUri Federated claim URI - * @return true if the IdP is federated and it has a claim for user with given URI. + * @return true if the IdP is federated, and it has a claim for user with given URI. * false otherwise */ protected boolean hasFederatedClaim(String claimUri) { @@ -390,19 +401,26 @@ private String getLocalMappedClaim(String claimUri) { return null; } + /** + * Get the local user claim value specified by the Claim URI. + * + * @param claimUri Local claim URI + * @return Claim value of the given claim URI for the local user if available. Null Otherwise. + */ protected String getLocalUserClaim(String claimUri) { int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); - String usernameWithDomain = - UserCoreUtil.addDomainToName(authenticatedUser.getUserName(), authenticatedUser.getUserStoreDomain()); RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); try { UserRealm userRealm = realmService.getTenantUserRealm(usersTenantId); - Map claimValues = userRealm.getUserStoreManager() - .getUserClaimValues(usernameWithDomain, new String[]{claimUri}, null); + Map claimValues = + ((AbstractUserStoreManager) userRealm.getUserStoreManager()) + .getUserClaimValuesWithID(authenticatedUser.getUserId(), new String[] {claimUri}, null); return claimValues.get(claimUri); } catch (UserStoreException e) { LOG.error(String.format("Error when getting claim : %s of user: %s", claimUri, authenticatedUser), e); + } catch (UserIdNotFoundException e) { + LOG.error("User id is not available for the user: " + authenticatedUser.getLoggableMaskedUserId(), e); } return null; } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java index 6dc86b0bdcae..71c1ee468bf0 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java @@ -44,10 +44,6 @@ public class JsGraalClaims extends JsClaims implements ProxyObject { private final transient Map localClaimUriToValueReadCache = new HashMap<>(); private static final Log LOG = LogFactory.getLog(JsNashornClaims.class); - private String idp; - private boolean isRemoteClaimRequest; - private int step; - protected transient AuthenticatedUser authenticatedUser; public JsGraalClaims(AuthenticationContext context, int step, String idp, boolean isRemoteClaimRequest) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornClaims.java index 28b973dbb7dd..f8f25940ca4f 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornClaims.java @@ -21,35 +21,11 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.identity.application.authentication.framework.ApplicationAuthenticator; -import org.wso2.carbon.identity.application.authentication.framework.config.ConfigurationFacade; -import org.wso2.carbon.identity.application.authentication.framework.config.model.ExternalIdPConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.AbstractJSContextMemberObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsClaims; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException; -import org.wso2.carbon.identity.application.authentication.framework.internal.FrameworkServiceDataHolder; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils; -import org.wso2.carbon.identity.application.common.model.ClaimMapping; -import org.wso2.carbon.identity.application.mgt.ApplicationConstants; -import org.wso2.carbon.identity.base.IdentityException; -import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataHandler; -import org.wso2.carbon.identity.claim.metadata.mgt.exception.ClaimMetadataException; -import org.wso2.carbon.identity.core.IdentityClaimManager; -import org.wso2.carbon.identity.core.util.IdentityTenantUtil; -import org.wso2.carbon.idp.mgt.IdentityProviderManagementException; -import org.wso2.carbon.idp.mgt.IdentityProviderManager; -import org.wso2.carbon.user.api.UserRealm; -import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.user.core.UserStoreClientException; -import org.wso2.carbon.user.core.claim.Claim; -import org.wso2.carbon.user.core.common.AbstractUserStoreManager; -import org.wso2.carbon.user.core.service.RealmService; -import java.util.Collections; -import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -57,13 +33,9 @@ * Represent the user's claim. Can be either remote or local. * This wrapper uses jdk.nashorn engine. */ -public class JsNashornClaims extends AbstractJSContextMemberObject implements AbstractJsObject { +public class JsNashornClaims extends JsClaims implements AbstractJsObject { private static final Log LOG = LogFactory.getLog(JsNashornClaims.class); - private String idp; - private boolean isRemoteClaimRequest; - private int step; - protected transient AuthenticatedUser authenticatedUser; /** * Constructor to get the user authenticated in step 'n' @@ -187,268 +159,14 @@ public void setMember(String claimUri, Object claimValue) { if (authenticatedUser != null) { if (isRemoteClaimRequest) { - setFederatedClaim(claimUri, claimValue); + setFederatedClaim(claimUri, String.valueOf(claimValue)); return; } else { - setLocalClaim(claimUri, claimValue); + setLocalClaim(claimUri, String.valueOf(claimValue)); return; } } AbstractJsObject.super.setMember(claimUri, claimValue); } - /** - * Get the claim by local claim URI. - * - * @param claimUri Local claim URI - * @param claimValue Claim Value - */ - private void setLocalClaim(String claimUri, Object claimValue) { - - if (isFederatedIdP()) { - setLocalMappedClaim(claimUri, claimValue); - } else { - // This covers step with a local authenticator, and the scenarios where step/idp is not set - // if the step/idp is not set, user is assumed to be a local user - setLocalUserClaim(claimUri, claimValue); - } - } - - /** - * Sets the remote claim value that is mapped to the give local claim - * - * @param localClaimURI Local claim URI - * @param claimValue Value to be set - */ - private void setLocalMappedClaim(String localClaimURI, Object claimValue) { - - Map idpAttributesMap = authenticatedUser.getUserAttributes(); - Map remoteMapping = FrameworkUtils.getClaimMappings(idpAttributesMap, false); - String mappedRemoteClaim = getRemoteClaimMappedToLocalClaim(localClaimURI, remoteMapping); - if (mappedRemoteClaim != null) { - setFederatedClaim(mappedRemoteClaim, String.valueOf(claimValue)); - } - } - - /** - * Sets a local claim directly at the userstore for the given user by given claim uri - * - * @param claimUri Local claim URI - * @param claimValue Claim value - */ - private void setLocalUserClaim(String claimUri, Object claimValue) { - - int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); - RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); - try { - UserRealm userRealm = realmService.getTenantUserRealm(usersTenantId); - Map claimUriMap = new HashMap<>(); - claimUriMap.put(claimUri, String.valueOf(claimValue)); - ((AbstractUserStoreManager) userRealm.getUserStoreManager()) - .setUserClaimValuesWithID(authenticatedUser.getUserId(), claimUriMap, null); - } catch (UserStoreClientException e) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Error when setting claim : %s of user: %s to value: %s. Error Message: %s", - claimUri, authenticatedUser, String.valueOf(claimValue), e.getMessage())); - } - } catch (UserStoreException e) { - LOG.error(String.format("Error when setting claim : %s of user: %s to value: %s", claimUri, - authenticatedUser, String.valueOf(claimValue)), e); - } catch (UserIdNotFoundException e) { - LOG.error("User id is not available for the user: " + authenticatedUser.getLoggableUserId(), e); - } - } - - /** - * Gets the remote claim that is mapped to the given local claim - * - * @param localClaim local claim URI - * @param remoteClaimsMap Remote claim URI - value map - * @return Mapped remote claim URI if present. null otherwise - */ - private String getRemoteClaimMappedToLocalClaim(String localClaim, Map remoteClaimsMap) { - - String authenticatorDialect = null; - Map localToIdpClaimMapping = null; - String tenantDomain = getContext().getTenantDomain(); - try { - // Check if the IDP use an standard dialect (like oidc), If it does, dialect claim mapping are - // prioritized over IdP claim mapping - ApplicationAuthenticator authenticator = getContext().getSequenceConfig().getStepMap().get(step) - .getAuthenticatedAutenticator().getApplicationAuthenticator(); - authenticatorDialect = authenticator.getClaimDialectURI(); - ExternalIdPConfig idPConfig = ConfigurationFacade.getInstance().getIdPConfigByName(idp, tenantDomain); - boolean useDefaultIdpDialect = idPConfig.useDefaultLocalIdpDialect(); - - if (authenticatorDialect != null || useDefaultIdpDialect) { - if (authenticatorDialect == null) { - authenticatorDialect = ApplicationConstants.LOCAL_IDP_DEFAULT_CLAIM_DIALECT; - } - localToIdpClaimMapping = ClaimMetadataHandler.getInstance().getMappingsMapFromOtherDialectToCarbon - (authenticatorDialect, remoteClaimsMap.keySet(), tenantDomain, true); - } else { - localToIdpClaimMapping = IdentityProviderManager.getInstance().getMappedIdPClaimsMap - (idp, tenantDomain, Collections - .singletonList(localClaim)); - - } - if (localToIdpClaimMapping != null) { - return localToIdpClaimMapping.get(localClaim); - } - } catch (IdentityProviderManagementException e) { - LOG.error(String.format("Error when getting claim : %s of user: %s", localClaim, authenticatedUser), e); - } catch (ClaimMetadataException e) { - LOG.error("Error when getting claim mappings from " + authenticatorDialect + " for tenant domain: " + - tenantDomain); - } - return null; - } - - /** - * Check if the user has a federated claim with given name. - * - * @param claimUri Federated claim URI - * @return true if the IdP is federated and it has a claim for user with given URI. - * false otherwise - */ - protected boolean hasFederatedClaim(String claimUri) { - - if (isFederatedIdP()) { - Map attributesMap = authenticatedUser.getUserAttributes(); - Map remoteMapping = FrameworkUtils.getClaimMappings(attributesMap, false); - return remoteMapping.containsKey(claimUri); - } - // Can be a case where step is not set (e.g. associated local user) - return false; - } - - /** - * Check if there is a local claim by given name. - * - * @param claimUri The local claim URI - * @return Claim value of the user authenticated by the indicated IdP - */ - protected boolean hasLocalClaim(String claimUri) { - - int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); - RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); - try { - UserRealm userRealm = realmService.getTenantUserRealm(usersTenantId); - Claim[] supportedClaims = IdentityClaimManager.getInstance().getAllSupportedClaims((org.wso2.carbon.user - .core.UserRealm) userRealm); - for (Claim claim : supportedClaims) { - if (claim.getClaimUri().equals(claimUri)) { - return true; - } - } - } catch (UserStoreException e) { - LOG.error("Error when retrieving user realm for tenant : " + usersTenantId, e); - } catch (IdentityException e) { - LOG.error("Error when initializing identity claim manager.", e); - } - return false; - } - - /** - * Get the claim by federated claim URI. - * - * @param claimUri Federated claim URI - * @return Claim value if the Idp is a federated Idp, and has a claim by given url for the user. - * null otherwise. - */ - protected String getFederatedClaim(String claimUri) { - - // If the idp is local, return null - if (isFederatedIdP()) { - Map attributesMap = authenticatedUser.getUserAttributes(); - Map remoteMapping = FrameworkUtils.getClaimMappings(attributesMap, false); - return remoteMapping.get(claimUri); - } - // Can be a case where step is not set (e.g. associated local user) - return null; - } - - /** - * Get the claim by local claim URI. - * - * @param claimUri Local claim URI - * @return Local user's claim value if the Idp is local, Mapped remote claim if the Idp is federated. - */ - protected String getLocalClaim(String claimUri) { - - if (isFederatedIdP()) { - return getLocalMappedClaim(claimUri); - } else { - // This covers step with a local authenticator, and the scenarios where step/idp is not set - // if the step/idp is not set, user is assumed to be a local user - return getLocalUserClaim(claimUri); - } - } - - /** - * Check if step's IdP is a federated IDP - * - * @return true if the idp is federated - */ - protected boolean isFederatedIdP() { - - return StringUtils.isNotBlank(idp) && !FrameworkConstants.LOCAL.equals(idp); - } - - /** - * Sets a custom remote claim to the user. - * - * @param claimUri Remote claim uri - * @param claimValue Claim value - */ - private void setFederatedClaim(String claimUri, Object claimValue) { - - if (claimValue == null) { - claimValue = StringUtils.EMPTY; - } - ClaimMapping newClaimMapping = ClaimMapping.build(claimUri, claimUri, null, false); - authenticatedUser.getUserAttributes().put(newClaimMapping, String.valueOf(claimValue)); - } - - /** - * Gets the mapped remote claim value for the given local claim URI - * - * @param claimUri Local claim URI - * @return Mapped remote claim value from IdP - */ - private String getLocalMappedClaim(String claimUri) { - - Map idpAttributesMap = authenticatedUser.getUserAttributes(); - Map remoteMapping = FrameworkUtils.getClaimMappings(idpAttributesMap, false); - - String remoteMappedClaim = getRemoteClaimMappedToLocalClaim(claimUri, remoteMapping); - if (remoteMappedClaim != null) { - return remoteMapping.get(remoteMappedClaim); - } - return null; - } - - /** - * Get the local user claim value specified by the Claim URI. - * - * @param claimUri Local claim URI - * @return Claim value of the given claim URI for the local user if available. Null Otherwise. - */ - private String getLocalUserClaim(String claimUri) { - - int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); - RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); - try { - UserRealm userRealm = realmService.getTenantUserRealm(usersTenantId); - Map claimValues = - ((AbstractUserStoreManager) userRealm.getUserStoreManager()) - .getUserClaimValuesWithID(authenticatedUser.getUserId(), new String[] {claimUri}, null); - return claimValues.get(claimUri); - } catch (UserStoreException e) { - LOG.error(String.format("Error when getting claim : %s of user: %s", claimUri, authenticatedUser), e); - } catch (UserIdNotFoundException e) { - LOG.error("User id is not available for the user: " + authenticatedUser.getLoggableUserId(), e); - } - return null; - } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornClaims.java index 96f0830e3865..2bd5727a2295 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornClaims.java @@ -21,35 +21,10 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.identity.application.authentication.framework.ApplicationAuthenticator; -import org.wso2.carbon.identity.application.authentication.framework.config.ConfigurationFacade; -import org.wso2.carbon.identity.application.authentication.framework.config.model.ExternalIdPConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.AbstractJSContextMemberObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsClaims; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException; -import org.wso2.carbon.identity.application.authentication.framework.internal.FrameworkServiceDataHolder; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils; -import org.wso2.carbon.identity.application.common.model.ClaimMapping; -import org.wso2.carbon.identity.application.mgt.ApplicationConstants; -import org.wso2.carbon.identity.base.IdentityException; -import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataHandler; -import org.wso2.carbon.identity.claim.metadata.mgt.exception.ClaimMetadataException; -import org.wso2.carbon.identity.core.IdentityClaimManager; -import org.wso2.carbon.identity.core.util.IdentityTenantUtil; -import org.wso2.carbon.idp.mgt.IdentityProviderManagementException; -import org.wso2.carbon.idp.mgt.IdentityProviderManager; -import org.wso2.carbon.user.api.UserRealm; -import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.user.core.UserStoreClientException; -import org.wso2.carbon.user.core.claim.Claim; -import org.wso2.carbon.user.core.common.AbstractUserStoreManager; -import org.wso2.carbon.user.core.service.RealmService; - -import java.util.Collections; -import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -58,13 +33,9 @@ * Since Nashorn is deprecated in JDK 11 and onwards. We are introducing OpenJDK Nashorn engine. * */ -public class JsOpenJdkNashornClaims extends AbstractJSContextMemberObject implements AbstractOpenJdkNashornJsObject { +public class JsOpenJdkNashornClaims extends JsClaims implements AbstractOpenJdkNashornJsObject { private static final Log LOG = LogFactory.getLog(JsOpenJdkNashornClaims.class); - private String idp; - private boolean isRemoteClaimRequest; - private int step; - protected transient AuthenticatedUser authenticatedUser; /** * Constructor to get the user authenticated in step 'n' @@ -188,268 +159,13 @@ public void setMember(String claimUri, Object claimValue) { if (authenticatedUser != null) { if (isRemoteClaimRequest) { - setFederatedClaim(claimUri, claimValue); + setFederatedClaim(claimUri, String.valueOf(claimValue)); return; } else { - setLocalClaim(claimUri, claimValue); + setLocalClaim(claimUri, String.valueOf(claimValue)); return; } } AbstractOpenJdkNashornJsObject.super.setMember(claimUri, claimValue); } - - /** - * Get the claim by local claim URI. - * - * @param claimUri Local claim URI - * @param claimValue Claim Value - */ - private void setLocalClaim(String claimUri, Object claimValue) { - - if (isFederatedIdP()) { - setLocalMappedClaim(claimUri, claimValue); - } else { - // This covers step with a local authenticator, and the scenarios where step/idp is not set - // if the step/idp is not set, user is assumed to be a local user - setLocalUserClaim(claimUri, claimValue); - } - } - - /** - * Sets the remote claim value that is mapped to the give local claim - * - * @param localClaimURI Local claim URI - * @param claimValue Value to be set - */ - private void setLocalMappedClaim(String localClaimURI, Object claimValue) { - - Map idpAttributesMap = authenticatedUser.getUserAttributes(); - Map remoteMapping = FrameworkUtils.getClaimMappings(idpAttributesMap, false); - String mappedRemoteClaim = getRemoteClaimMappedToLocalClaim(localClaimURI, remoteMapping); - if (mappedRemoteClaim != null) { - setFederatedClaim(mappedRemoteClaim, String.valueOf(claimValue)); - } - } - - /** - * Sets a local claim directly at the userstore for the given user by given claim uri - * - * @param claimUri Local claim URI - * @param claimValue Claim value - */ - private void setLocalUserClaim(String claimUri, Object claimValue) { - - int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); - RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); - try { - UserRealm userRealm = realmService.getTenantUserRealm(usersTenantId); - Map claimUriMap = new HashMap<>(); - claimUriMap.put(claimUri, String.valueOf(claimValue)); - ((AbstractUserStoreManager) userRealm.getUserStoreManager()) - .setUserClaimValuesWithID(authenticatedUser.getUserId(), claimUriMap, null); - } catch (UserStoreClientException e) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Error when setting claim : %s of user: %s to value: %s. Error Message: %s", - claimUri, authenticatedUser, String.valueOf(claimValue), e.getMessage())); - } - } catch (UserStoreException e) { - LOG.error(String.format("Error when setting claim : %s of user: %s to value: %s", claimUri, - authenticatedUser, String.valueOf(claimValue)), e); - } catch (UserIdNotFoundException e) { - LOG.error("User id is not available for the user: " + authenticatedUser.getLoggableUserId(), e); - } - } - - /** - * Gets the remote claim that is mapped to the given local claim - * - * @param localClaim local claim URI - * @param remoteClaimsMap Remote claim URI - value map - * @return Mapped remote claim URI if present. null otherwise - */ - private String getRemoteClaimMappedToLocalClaim(String localClaim, Map remoteClaimsMap) { - - String authenticatorDialect = null; - Map localToIdpClaimMapping = null; - String tenantDomain = getContext().getTenantDomain(); - try { - // Check if the IDP use an standard dialect (like oidc), If it does, dialect claim mapping are - // prioritized over IdP claim mapping - ApplicationAuthenticator authenticator = getContext().getSequenceConfig().getStepMap().get(step) - .getAuthenticatedAutenticator().getApplicationAuthenticator(); - authenticatorDialect = authenticator.getClaimDialectURI(); - ExternalIdPConfig idPConfig = ConfigurationFacade.getInstance().getIdPConfigByName(idp, tenantDomain); - boolean useDefaultIdpDialect = idPConfig.useDefaultLocalIdpDialect(); - - if (authenticatorDialect != null || useDefaultIdpDialect) { - if (authenticatorDialect == null) { - authenticatorDialect = ApplicationConstants.LOCAL_IDP_DEFAULT_CLAIM_DIALECT; - } - localToIdpClaimMapping = ClaimMetadataHandler.getInstance().getMappingsMapFromOtherDialectToCarbon - (authenticatorDialect, remoteClaimsMap.keySet(), tenantDomain, true); - } else { - localToIdpClaimMapping = IdentityProviderManager.getInstance().getMappedIdPClaimsMap - (idp, tenantDomain, Collections - .singletonList(localClaim)); - - } - if (localToIdpClaimMapping != null) { - return localToIdpClaimMapping.get(localClaim); - } - } catch (IdentityProviderManagementException e) { - LOG.error(String.format("Error when getting claim : %s of user: %s", localClaim, authenticatedUser), e); - } catch (ClaimMetadataException e) { - LOG.error("Error when getting claim mappings from " + authenticatorDialect + " for tenant domain: " + - tenantDomain); - } - return null; - } - - /** - * Check if the user has a federated claim with given name. - * - * @param claimUri Federated claim URI - * @return true if the IdP is federated and it has a claim for user with given URI. - * false otherwise - */ - protected boolean hasFederatedClaim(String claimUri) { - - if (isFederatedIdP()) { - Map attributesMap = authenticatedUser.getUserAttributes(); - Map remoteMapping = FrameworkUtils.getClaimMappings(attributesMap, false); - return remoteMapping.containsKey(claimUri); - } - // Can be a case where step is not set (e.g. associated local user) - return false; - } - - /** - * Check if there is a local claim by given name. - * - * @param claimUri The local claim URI - * @return Claim value of the user authenticated by the indicated IdP - */ - protected boolean hasLocalClaim(String claimUri) { - - int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); - RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); - try { - UserRealm userRealm = realmService.getTenantUserRealm(usersTenantId); - Claim[] supportedClaims = IdentityClaimManager.getInstance().getAllSupportedClaims((org.wso2.carbon.user - .core.UserRealm) userRealm); - for (Claim claim : supportedClaims) { - if (claim.getClaimUri().equals(claimUri)) { - return true; - } - } - } catch (UserStoreException e) { - LOG.error("Error when retrieving user realm for tenant : " + usersTenantId, e); - } catch (IdentityException e) { - LOG.error("Error when initializing identity claim manager.", e); - } - return false; - } - - /** - * Get the claim by federated claim URI. - * - * @param claimUri Federated claim URI - * @return Claim value if the Idp is a federated Idp, and has a claim by given url for the user. - * null otherwise. - */ - protected String getFederatedClaim(String claimUri) { - - // If the idp is local, return null - if (isFederatedIdP()) { - Map attributesMap = authenticatedUser.getUserAttributes(); - Map remoteMapping = FrameworkUtils.getClaimMappings(attributesMap, false); - return remoteMapping.get(claimUri); - } - // Can be a case where step is not set (e.g. associated local user) - return null; - } - - /** - * Get the claim by local claim URI. - * - * @param claimUri Local claim URI - * @return Local user's claim value if the Idp is local, Mapped remote claim if the Idp is federated. - */ - protected String getLocalClaim(String claimUri) { - - if (isFederatedIdP()) { - return getLocalMappedClaim(claimUri); - } else { - // This covers step with a local authenticator, and the scenarios where step/idp is not set - // if the step/idp is not set, user is assumed to be a local user - return getLocalUserClaim(claimUri); - } - } - - /** - * Check if step's IdP is a federated IDP - * - * @return true if the idp is federated - */ - protected boolean isFederatedIdP() { - - return StringUtils.isNotBlank(idp) && !FrameworkConstants.LOCAL.equals(idp); - } - - /** - * Sets a custom remote claim to the user. - * - * @param claimUri Remote claim uri - * @param claimValue Claim value - */ - private void setFederatedClaim(String claimUri, Object claimValue) { - - if (claimValue == null) { - claimValue = StringUtils.EMPTY; - } - ClaimMapping newClaimMapping = ClaimMapping.build(claimUri, claimUri, null, false); - authenticatedUser.getUserAttributes().put(newClaimMapping, String.valueOf(claimValue)); - } - - /** - * Gets the mapped remote claim value for the given local claim URI - * - * @param claimUri Local claim URI - * @return Mapped remote claim value from IdP - */ - private String getLocalMappedClaim(String claimUri) { - - Map idpAttributesMap = authenticatedUser.getUserAttributes(); - Map remoteMapping = FrameworkUtils.getClaimMappings(idpAttributesMap, false); - - String remoteMappedClaim = getRemoteClaimMappedToLocalClaim(claimUri, remoteMapping); - if (remoteMappedClaim != null) { - return remoteMapping.get(remoteMappedClaim); - } - return null; - } - - /** - * Get the local user claim value specified by the Claim URI. - * - * @param claimUri Local claim URI - * @return Claim value of the given claim URI for the local user if available. Null Otherwise. - */ - private String getLocalUserClaim(String claimUri) { - - int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); - RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); - try { - UserRealm userRealm = realmService.getTenantUserRealm(usersTenantId); - Map claimValues = - ((AbstractUserStoreManager) userRealm.getUserStoreManager()) - .getUserClaimValuesWithID(authenticatedUser.getUserId(), new String[] {claimUri}, null); - return claimValues.get(claimUri); - } catch (UserStoreException e) { - LOG.error(String.format("Error when getting claim : %s of user: %s", claimUri, authenticatedUser), e); - } catch (UserIdNotFoundException e) { - LOG.error("User id is not available for the user: " + authenticatedUser.getLoggableUserId(), e); - } - return null; - } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java index f41d8b013d33..3617d2c8ead0 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java @@ -228,6 +228,7 @@ public abstract class FrameworkConstants { public static final String THREAD_LOCAL_SCRIPT_ENGINE_CONFIG = "AdaptiveAuth.LimitScriptEngineCreation"; public static final String OPENJDK_NASHORN = "openjdkNashorn"; public static final String NASHORN = "nashorn"; + public static final String GRAAL_JS = "graaljs"; // Attribute sync related constants. public static final String ATTRIBUTE_SYNC_METHOD = "attributeSyncMethod"; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java index 98ca00514508..0e2473a20177 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java @@ -67,6 +67,7 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGraphBuilderFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs.JsGraalGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.openjdk.nashorn.JsOpenJdkNashornGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.context.SessionContext; @@ -4005,6 +4006,8 @@ public static JsBaseGraphBuilderFactory createJsGraphBuilderFactoryFromConfig() if (scriptEngineName != null) { if (StringUtils.equalsIgnoreCase(FrameworkConstants.OPENJDK_NASHORN, scriptEngineName)) { return new JsOpenJdkNashornGraphBuilderFactory(); + } else if (StringUtils.equalsIgnoreCase(FrameworkConstants.GRAAL_JS, scriptEngineName)) { + return new JsGraalGraphBuilderFactory(); } } // Config is not set. Hence going with class for name approach. From 0b00caeb4eb5cf43d3f3e6bd0d59503f0faabccd Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Fri, 5 Jan 2024 17:02:29 +0530 Subject: [PATCH 03/35] Fix following bugs: * Fix serializing not working for array objects * Fix callback function not working * Fix interpreter warning being displayed --- .../graaljs/GraalSerializableJsFunction.java | 2 +- .../model/graph/graaljs/GraalSerializer.java | 30 +++++++------------ .../graaljs/JsGraalGraphBuilderFactory.java | 1 + 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java index c99a129cabef..08712285834a 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java @@ -67,7 +67,7 @@ public void setSource(String source) { @Override public boolean isFunction() { - return isHostFunction; + return isPolyglotFunction; } @Override diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java index 0b20b4a3bf87..119ed7cfe2b1 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java @@ -74,20 +74,21 @@ public static Object toJsSerializableInternal(Object value) { return valueObj.asDate(); } else if (valueObj.isBoolean()) { return valueObj.asBoolean(); + } else if (valueObj.isDuration()) { + return valueObj.asDuration(); + } else if (valueObj.isTime()) { + return valueObj.asTime(); + } else if (valueObj.isTimeZone()) { + return valueObj.asTimeZone(); + } else if (valueObj.isNull()) { + return null; } else if (valueObj.hasArrayElements()) { int arraySize = (int) valueObj.getArraySize(); List arrayItems = new ArrayList<>(arraySize); for (int key = 0; key < arraySize; key++) { - Object serializedObj = (valueObj.getArrayElement(key)); - if (serializedObj instanceof Serializable) { - arrayItems.add((Serializable) serializedObj); - if (log.isDebugEnabled()) { - log.debug("Serialized the value of array item as : " + serializedObj); - } - } else { - log.warn(String.format("Non serializable array item: %s. and will not be persisted.", - serializedObj)); - } + Object arrayObj = valueObj.getArrayElement(key); + Object serializedObj = toJsSerializableInternal(arrayObj); + arrayItems.add((Serializable) serializedObj); } return arrayItems; } else if (valueObj.hasMembers()) { @@ -105,20 +106,11 @@ public static Object toJsSerializableInternal(Object value) { } }); return serializedMap; - } else if (valueObj.isDuration()) { - return valueObj.asDuration(); - } else if (valueObj.isTime()) { - return valueObj.asTime(); - } else if (valueObj.isTimeZone()) { - return valueObj.asTimeZone(); - } else if (valueObj.isNull()) { - return null; } else { return Collections.EMPTY_MAP; } } return value; - } @Override diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java index 2a501a67b193..23445941e4e3 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java @@ -77,6 +77,7 @@ public Context createEngine(AuthenticationContext authenticationContext) { Context context = Context.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE).allowHostAccess(HostAccess.ALL) + .option("engine.WarnInterpreterOnly", "false") .build(); Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); From 90265cd83645fb16d1b528e626821054699616d7 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Tue, 9 Jan 2024 11:25:55 +0530 Subject: [PATCH 04/35] Fix checkstyle issues. --- .../graph/JsBaseGraphBuilderFactory.java | 4 +-- .../config/model/graph/JsGraphBuilder.java | 5 +--- .../config/model/graph/JsSerializer.java | 2 ++ .../graaljs/GraalSerializableJsFunction.java | 4 +++ .../model/graph/graaljs/GraalSerializer.java | 10 +++++--- .../graph/graaljs/JsGraalGraphBuilder.java | 25 +++++++++++-------- .../graaljs/JsGraalGraphBuilderFactory.java | 16 +++++++----- .../graph/graaljs/JsGraalWrapperFactory.java | 4 +++ .../config/model/graph/js/JsClaims.java | 3 +++ .../js/graaljs/JsGraalAuthenticatedUser.java | 15 +++++++++++ .../graaljs/JsGraalAuthenticationContext.java | 15 +++++++++++ .../model/graph/js/graaljs/JsGraalCookie.java | 8 ++++++ .../graph/js/graaljs/JsGraalHeaders.java | 5 ++++ .../graph/js/graaljs/JsGraalParameters.java | 7 ++++++ .../js/graaljs/JsGraalServletRequest.java | 13 ++++++++++ .../js/graaljs/JsGraalServletResponse.java | 17 +++++++++++-- .../model/graph/js/graaljs/JsGraalStep.java | 4 +++ .../model/graph/js/graaljs/JsGraalSteps.java | 4 +++ .../js/graaljs/JsGraalWritableParameters.java | 4 +++ .../nashorn/JsOpenJdkNashornClaims.java | 1 + 20 files changed, 138 insertions(+), 28 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilderFactory.java index c7a5fd753ab6..d0e3214c4cae 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilderFactory.java @@ -23,11 +23,11 @@ import java.util.Map; -import javax.script.ScriptEngine; - /** * Interface for Factory to create a Javascript based sequence builder. * This factory is there to reuse of script engine and any related expensive objects. + * + * @param Type of the Javascript Engine */ public interface JsBaseGraphBuilderFactory { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java index 0636219912db..b05e3c269458 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java @@ -18,9 +18,6 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph; -import jdk.nashorn.api.scripting.ScriptObjectMirror; -import org.apache.abdera.model.Base; -import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -46,7 +43,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Function; import javax.script.ScriptEngine; import javax.script.ScriptException; @@ -77,6 +73,7 @@ public abstract class JsGraphBuilder implements JsBaseGraphBuilder { "var $ARG=null;var $ENV=null;var $EXEC=null;" + "var $OPTIONS=null;var $OUT=null;var $ERR=null;var $EXIT=null;" + "Object.defineProperty(this, 'engine', {});"; + /** * Returns the built graph. * diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsSerializer.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsSerializer.java index 1ec65871f856..591249b5ae8a 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsSerializer.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsSerializer.java @@ -22,6 +22,8 @@ /** * Interface for serializer class supports Multiple JS Engines. + * + * @param Js Engine. */ public interface JsSerializer { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java index 08712285834a..3fd6887b287a 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java @@ -29,6 +29,10 @@ import java.io.IOException; import java.util.function.Function; +/** + * Javascript function wrapper. This allows serialization of a javascript defined function. + * Since Nashorn is deprecated in JDK 11 and onwards. We replaced it with GraalJS classes. + */ public class GraalSerializableJsFunction implements BaseSerializableJsFunction { private static final Log log = LogFactory.getLog(GraalSerializableJsFunction.class); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java index 119ed7cfe2b1..2a93ed0089b9 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java @@ -18,13 +18,12 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Value; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsSerializer; import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; - -import org.apache.commons.logging.Log; -import org.graalvm.polyglot.Context; -import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import java.io.Serializable; @@ -34,6 +33,9 @@ import java.util.List; import java.util.Map; +/** + * Serializer class supports GraalJS Engine. + */ public class GraalSerializer implements JsSerializer { private static final Log log = LogFactory.getLog(GraalSerializer.class); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java index df63d278ff52..56846633db9a 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java @@ -20,25 +20,24 @@ import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.StringUtils; -import org.wso2.carbon.identity.application.authentication.framework.AsyncProcess; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthGraphNode; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthenticationGraph; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.BaseSerializableJsFunction; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.DynamicDecisionNode; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.FailNode; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JSExecutionMonitorData; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JSExecutionSupervisor; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGraphBuilder; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.PolyglotException; import org.graalvm.polyglot.Source; import org.graalvm.polyglot.Value; +import org.wso2.carbon.identity.application.authentication.framework.AsyncProcess; import org.wso2.carbon.identity.application.authentication.framework.AuthenticationDecisionEvaluator; import org.wso2.carbon.identity.application.authentication.framework.JsFunctionRegistry; import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthGraphNode; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthenticationGraph; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.BaseSerializableJsFunction; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.DynamicDecisionNode; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.FailNode; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JSExecutionMonitorData; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JSExecutionSupervisor; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGraphBuilder; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.LongWaitNode; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.ShowPromptNode; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.StepConfigGraphNode; @@ -55,6 +54,12 @@ import java.util.function.BiConsumer; import java.util.stream.Collectors; +/** + * Translate the authentication graph config to runtime model. + * This is not thread safe. Should be discarded after each build. + * + * Since Nashorn is deprecated in JDK 11 and onwards. We are introducing GraalJS engine. + */ public class JsGraalGraphBuilder extends JsGraphBuilder { private static final Log log = LogFactory.getLog(JsGraalGraphBuilder.class); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java index 23445941e4e3..74461bc1f881 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java @@ -18,16 +18,15 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthGraphNode; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilder; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilderFactory; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.HostAccess; import org.graalvm.polyglot.Value; import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthGraphNode; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilder; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsSerializer; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsLogger; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; @@ -37,6 +36,12 @@ import java.util.HashMap; import java.util.Map; +/** + * Factory to create a Javascript based sequence builder. + * This factory is there to reuse of GraalJS Polyglot Context and any related expensive objects. + *

+ * Since Nashorn is deprecated in JDK 11 and onwards. We are introducing GraalJS engine. + */ public class JsGraalGraphBuilderFactory implements JsBaseGraphBuilderFactory { private static final Log LOG = LogFactory.getLog(JsGraalGraphBuilderFactory.class); @@ -77,8 +82,7 @@ public Context createEngine(AuthenticationContext authenticationContext) { Context context = Context.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE).allowHostAccess(HostAccess.ALL) - .option("engine.WarnInterpreterOnly", "false") - .build(); + .option("engine.WarnInterpreterOnly", "false").build(); Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); JsLogger jsLogger = new JsLogger(); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java index feebdea35714..e0842215c1fe 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java @@ -17,6 +17,10 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +/** + * Factory to create a Javascript Object Wrappers for GraalJS execution. + * Since Nashorn is deprecated in JDK 11 and onwards. We are introducing GraalJS engine. + */ public class JsGraalWrapperFactory implements JsWrapperBaseFactory { @Override diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java index e396e266dd09..2d51bbe12546 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java @@ -52,6 +52,9 @@ import java.util.Map; import java.util.Optional; +/** + * Represent the user's claim for Javascript Execution. This contains the common methods all script engines. + */ public class JsClaims extends AbstractJSContextMemberObject { protected static final Log LOG = LogFactory.getLog(JsClaims.class); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java index f98de44b3f45..6ad9d0acbac1 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java @@ -27,6 +27,21 @@ import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; +/** + * Javascript wrapper for Java level AuthenticatedUser. + * This wrapper uses GraalJS polyglot context. + * This provides controlled access to AuthenticatedUser object via provided javascript native syntax. + * e.g + * var userName = context.lastAuthenticatedUser.username + *

+ * instead of + * var userName = context.getLastAuthenticatedUser().getUserName() + *

+ * Also it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime + * AuthenticatedUser. + * + * @see AuthenticatedUser + */ public class JsGraalAuthenticatedUser extends JsAuthenticatedUser implements ProxyObject { public JsGraalAuthenticatedUser(AuthenticationContext context, AuthenticatedUser wrappedUser, int step, diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java index dde56aafd08c..d48307fa1d5b 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java @@ -28,6 +28,21 @@ import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; +/** + * Javascript wrapper for Java level AuthenticationContext. + * This wrapper uses GraalJS polyglot context. + * This provides controlled access to AuthenticationContext object via provided javascript native syntax. + * e.g + * var requestedAcr = context.requestedAcr + *

+ * instead of + * var requestedAcr = context.getRequestedAcr() + *

+ * Also it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime + * AuthenticationContext. + * + * @see AuthenticationContext + */ public class JsGraalAuthenticationContext extends JsAuthenticationContext implements ProxyObject { public JsGraalAuthenticationContext(AuthenticationContext wrapped) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java index c110ec45e69f..5b0fc4be4127 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java @@ -30,6 +30,14 @@ import javax.servlet.http.Cookie; +/** + * Javascript wrapper for Java level Cookie. + * This wrapper uses GraalJS polyglot context. + * This provides controlled access to Cookie object via provided javascript native syntax. + * e.g + * var commonAuthIdDomain = context.request.cookies.commonAuthId.domain + * Also it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime Cookie. + */ public class JsGraalCookie extends JsCookie implements ProxyObject { protected static final Log LOG = LogFactory.getLog(JsGraalCookie.class); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java index 33fcc07bfc5b..e3b63cf41c17 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java @@ -26,6 +26,11 @@ import javax.servlet.http.HttpServletResponse; +/** + * Javascript wrapper for Java level HashMap of HTTP headers. + * This provides controlled access to HTTPServletResponse object's headers via provided javascript native syntax. + * Also, it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime. + */ public class JsGraalHeaders implements ProxyObject { private final Map wrapped; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java index d908deece9db..7bb990726598 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java @@ -25,6 +25,13 @@ import java.util.Map; +/** + * Javascript wrapper for Java level HashMap of HTTP headers/cookies. + * This wrapper uses GraalJS polyglot context. + * This provides controlled access to HTTPServletRequest object's headers and cookies via provided javascript native + * syntax. + * Also it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime. + */ public class JsGraalParameters extends JsParameters implements ProxyObject { public JsGraalParameters(Map wrapped) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java index 520137886a7b..c1f6cd7912e6 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java @@ -36,6 +36,19 @@ import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; +/** + * Javascript wrapper for Java level HTTPServletRequest. + * This wrapper uses GraalJS polyglot context. + * This provides controlled access to HTTPServletRequest object via provided javascript native syntax. + * e.g + * var redirect_uri = context.request.params.redirect_uri + *

+ * instead of + * var userName = context.getRequest().getParameter("redirect_uri) + *

+ * Also it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime + * HTTPServletRequest. + */ public class JsGraalServletRequest extends JsServletRequest implements ProxyObject { protected static final Log LOG = LogFactory.getLog(JsGraalServletRequest.class); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java index d5885805dd83..9c3502017020 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java @@ -33,9 +33,22 @@ import javax.servlet.http.HttpServletResponse; +/** + * Javascript wrapper for Java level HttpServletResponse. + * This wrapper uses GraalJS polyglot context. + * This provides controlled access to HttpServletResponse object via provided javascript native syntax. + * e.g + * response.headers.["Set-Cookie"] = ['crsftoken=xxxxxssometokenxxxxx'] + *

+ * instead of + * context.getResponse().addCookie(cookie); + *

+ * Also, it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime + * HttpServletResponse. + */ public class JsGraalServletResponse extends JsServletResponse implements ProxyObject { - Log LOG = LogFactory.getLog(JsGraalServletResponse.class); + Log log = LogFactory.getLog(JsGraalServletResponse.class); public JsGraalServletResponse(TransientObjectWrapper wrapped) { @@ -80,7 +93,7 @@ public boolean hasMember(String name) { @Override public void putMember(String key, Value value) { - LOG.warn("Unsupported operation. Servlet Response is read only. Can't set parameter " + key + " to value: " + + log.warn("Unsupported operation. Servlet Response is read only. Can't set parameter " + key + " to value: " + value); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java index a78b6952df3f..f88f900cd21d 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java @@ -36,6 +36,10 @@ import java.util.Map; import java.util.Optional; +/** + * Represents a authentication step. + * This wrapper uses GraalJS polyglot context. + */ public class JsGraalStep extends AbstractJSContextMemberObject implements ProxyObject { protected static final Log LOG = LogFactory.getLog(JsGraalStep.class); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java index bc5eceb3d2d0..3324732d83ba 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java @@ -28,6 +28,10 @@ import java.util.Optional; +/** + * Returns when context.steps[ Date: Wed, 10 Jan 2024 12:38:16 +0530 Subject: [PATCH 05/35] Implement hasMember method to relevant ProxyObject implementations --- .../model/graph/js/JsAuthenticationContext.java | 2 +- .../js/graaljs/JsGraalAuthenticationContext.java | 15 +++++++++++++++ .../model/graph/js/graaljs/JsGraalCookie.java | 11 +++++++++++ .../graph/js/graaljs/JsGraalServletRequest.java | 12 +++--------- .../graph/js/graaljs/JsGraalServletResponse.java | 13 ------------- .../model/graph/js/graaljs/JsGraalSteps.java | 2 +- .../js/graaljs/JsGraalWritableParameters.java | 6 ++++++ .../nashorn/JsNashornAuthenticationContext.java | 2 +- .../JsOpenJdkNashornAuthenticationContext.java | 2 +- 9 files changed, 39 insertions(+), 26 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticationContext.java index ca88bee0e9cc..1fc02fc5543e 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticationContext.java @@ -87,7 +87,7 @@ public void setMember(String name, Object value) { } } - private boolean hasTransientValueInParameters(String key) { + protected boolean hasTransientValueInParameters(String key) { TransientObjectWrapper transientObjectWrapper = (TransientObjectWrapper) getWrapped().getParameter(key); return transientObjectWrapper != null && transientObjectWrapper.getWrapped() != null; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java index d48307fa1d5b..7f0da8b1b43b 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java @@ -93,6 +93,21 @@ public Object getMemberKeys() { FrameworkConstants.JSAttributes.JS_CURRENT_KNOWN_SUBJECT); } + @Override + public boolean hasMember(String name) { + + switch (name) { + case FrameworkConstants.JSAttributes.JS_CURRENT_STEP: + case FrameworkConstants.JSAttributes.JS_RETRY_STEP: + return true; + case FrameworkConstants.JSAttributes.JS_CURRENT_KNOWN_SUBJECT: + return getCurrentSubjectIdentifierStep() != null; + default: + return super.hasMember(name); + + } + } + @Override public void putMember(String key, Value value) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java index 5b0fc4be4127..aa20dd152590 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java @@ -58,6 +58,17 @@ public Object getMemberKeys() { return ProxyArray.fromArray(Arrays.stream(cookieProperties).filter(this::hasMember).toArray()); } + @Override + public boolean hasMember(String name) { + + switch (name) { + case FrameworkConstants.JSAttributes.JS_COOKIE_SECURE: + case FrameworkConstants.JSAttributes.JS_COOKIE_HTTP_ONLY: + return true; + } + return super.hasMember(name); + } + public void putMember(String key, Value value) { LOG.warn("Unsupported operation. Cookie is read only. Can't remove parameter " + key); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java index c1f6cd7912e6..8e069b322ced 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java @@ -108,16 +108,10 @@ public boolean hasMember(String name) { return false; } - switch (name) { - case FrameworkConstants.JSAttributes.JS_HEADERS: - case FrameworkConstants.JSAttributes.JS_COOKIES: - case FrameworkConstants.JSAttributes.JS_REQUEST_IP: - return true; - case FrameworkConstants.JSAttributes.JS_PARAMS: - return getRequest().getParameterMap() != null; - default: - return super.hasMember(name); + if (name.equals(FrameworkConstants.JSAttributes.JS_REQUEST_IP)) { + return true; } + return super.hasMember(name); } @Override diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java index 9c3502017020..e34406b7a1fb 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java @@ -77,19 +77,6 @@ public Object getMemberKeys() { return ProxyArray.fromArray(FrameworkConstants.JSAttributes.JS_HEADERS); } - @Override - public boolean hasMember(String name) { - - if (getResponse() == null) { - //Transient Object is null, hence no member access is possible. - return false; - } - if (FrameworkConstants.JSAttributes.JS_HEADERS.equals(name)) { - return true; - } - return super.hasMember(name); - } - @Override public void putMember(String key, Value value) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java index 3324732d83ba..fa7fc7d67511 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java @@ -69,7 +69,7 @@ public Object get(long index) { @Override public void set(long index, Value value) { - //Steps can n ot be set withs script + //Steps can not be set with script. } @Override diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java index cf7063d62ddd..69e962c3d7ab 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java @@ -57,4 +57,10 @@ public void putMember(String key, Value value) { getWrapped().put(key, value.as(List.class)); } + @Override + public boolean hasMember(String name) { + + return getWrapped().containsKey(name); + } + } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticationContext.java index 86571be07ebb..55fd66fc9685 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticationContext.java @@ -140,7 +140,7 @@ public void setMember(String name, Object value) { } } - private boolean hasTransientValueInParameters(String key) { + protected boolean hasTransientValueInParameters(String key) { TransientObjectWrapper transientObjectWrapper = (TransientObjectWrapper) getWrapped().getParameter(key); return transientObjectWrapper != null && transientObjectWrapper.getWrapped() != null; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticationContext.java index 028050490d6d..0cbe54eae9c5 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticationContext.java @@ -141,7 +141,7 @@ public void setMember(String name, Object value) { } } - private boolean hasTransientValueInParameters(String key) { + protected boolean hasTransientValueInParameters(String key) { TransientObjectWrapper transientObjectWrapper = (TransientObjectWrapper) getWrapped().getParameter(key); return transientObjectWrapper != null && transientObjectWrapper.getWrapped() != null; From 0a7cf6db9c7b0a8c435968f752ec51c3b68296ef Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Thu, 11 Jan 2024 10:20:24 +0530 Subject: [PATCH 06/35] Add getContext method to JsBaseAuthenticatedUser interface. --- .../config/model/graph/js/base/JsBaseAuthenticatedUser.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseAuthenticatedUser.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseAuthenticatedUser.java index 56560100ae56..f08ca5c56f51 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseAuthenticatedUser.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseAuthenticatedUser.java @@ -18,6 +18,7 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; /** @@ -29,4 +30,5 @@ public interface JsBaseAuthenticatedUser { * @return Wrapped Authenticated User */ AuthenticatedUser getWrapped(); + AuthenticationContext getContext(); } From 54ada51cbb00beb5c0f2cd5d7dc7235cd72665a4 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Wed, 31 Jan 2024 18:19:24 +0530 Subject: [PATCH 07/35] Add JsGraalAuthenticationContextTest and JsGraalGraphBuilderTest --- .../model/graph/JsGraalGraphBuilderTest.java | 375 ++++++++++++++++++ ...st.java => JsNashornGraphBuilderTest.java} | 2 +- .../js/JsGraalAuthenticationContextTest.java | 238 +++++++++++ ...> JsNashornAuthenticationContextTest.java} | 2 +- 4 files changed, 615 insertions(+), 2 deletions(-) create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraalGraphBuilderTest.java rename components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/{JsGraphBuilderTest.java => JsNashornGraphBuilderTest.java} (99%) create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java rename components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/{JsAuthenticationContextTest.java => JsNashornAuthenticationContextTest.java} (99%) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraalGraphBuilderTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraalGraphBuilderTest.java new file mode 100644 index 000000000000..04fa591d362f --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraalGraphBuilderTest.java @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph; + +import org.mockito.Mock; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.wso2.carbon.identity.application.authentication.framework.AbstractFrameworkTest; +import org.wso2.carbon.identity.application.authentication.framework.FederatedApplicationAuthenticator; +import org.wso2.carbon.identity.application.authentication.framework.LocalApplicationAuthenticator; +import org.wso2.carbon.identity.application.authentication.framework.config.model.AuthenticatorConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs.JsGraalGraphBuilder; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs.JsGraalGraphBuilderFactory; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.internal.FrameworkServiceDataHolder; +import org.wso2.carbon.identity.application.common.ApplicationAuthenticatorService; +import org.wso2.carbon.identity.application.common.model.FederatedAuthenticatorConfig; +import org.wso2.carbon.identity.application.common.model.IdentityProvider; +import org.wso2.carbon.identity.application.common.model.LocalAuthenticatorConfig; +import org.wso2.carbon.identity.application.common.model.ServiceProvider; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.when; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; + +@Test +public class JsGraalGraphBuilderTest extends AbstractFrameworkTest { + + private JsGraalGraphBuilderFactory jsGraphBuilderFactory; + @Mock + private LocalApplicationAuthenticator localApplicationAuthenticator; + + @Mock + private LocalApplicationAuthenticator totpApplicationAuthenticator; + + @Mock + private FederatedApplicationAuthenticator federatedApplicationAuthenticator; + + @BeforeTest + public void setUp() { + + initMocks(this); + jsGraphBuilderFactory = new JsGraalGraphBuilderFactory(); + JSExecutionSupervisor jsExecutionSupervisor = new JSExecutionSupervisor(1, 5000L); + FrameworkServiceDataHolder.getInstance().setJsExecutionSupervisor(jsExecutionSupervisor); + } + + @AfterTest + public void teardown() { + + FrameworkServiceDataHolder.getInstance().getJsExecutionSupervisor().shutdown(); + } + + @Test + public void testCreateDirectJavaInvalidStepId() throws Exception { + + ServiceProvider sp1 = getTestServiceProvider("js-sp-1.xml"); + AuthenticationContext context = getAuthenticationContext(sp1); + Map stepConfigMap = new HashMap<>(); + stepConfigMap.put(1, new StepConfig()); + JsGraalGraphBuilder jsGraphBuilder = jsGraphBuilderFactory.createBuilder(context, stepConfigMap); + jsGraphBuilder.executeStep(2); + + AuthenticationGraph graph = jsGraphBuilder.build(); + assertNull(graph.getStartNode()); + } + + @Test + public void testCreateDirectJava() throws Exception { + + ServiceProvider sp1 = getTestServiceProvider("js-sp-1.xml"); + AuthenticationContext context = getAuthenticationContext(sp1); + Map stepConfigMap = new HashMap<>(); + stepConfigMap.put(1, new StepConfig()); + stepConfigMap.put(2, new StepConfig()); + JsGraalGraphBuilder jsGraphBuilder = jsGraphBuilderFactory.createBuilder(context, stepConfigMap); + jsGraphBuilder.executeStep(1); + jsGraphBuilder.executeStep(2); + + AuthenticationGraph graph = jsGraphBuilder.build(); + assertNotNull(graph.getStartNode()); + assertTrue(graph.getStartNode() instanceof StepConfigGraphNode); + + StepConfigGraphNode firstStep = (StepConfigGraphNode) graph.getStartNode(); + assertNotNull(firstStep.getNext()); + assertTrue(firstStep.getNext() instanceof StepConfigGraphNode); + } + + @Test + public void testCreateJavascript() throws Exception { + + String script = "var onLoginRequest = function(context) { executeStep(1, { onSuccess : function(context) {" + + "executeStep(2);}})};"; + + ServiceProvider sp1 = getTestServiceProvider("js-sp-1.xml"); + AuthenticationContext context = getAuthenticationContext(sp1); + + Map stepConfigMap = new HashMap<>(); + stepConfigMap.put(1, new StepConfig()); + stepConfigMap.put(2, new StepConfig()); + + JsGraalGraphBuilder jsGraphBuilder = jsGraphBuilderFactory.createBuilder(context, stepConfigMap); + jsGraphBuilder.createWith(script); + + AuthenticationGraph graph = jsGraphBuilder.build(); + assertNotNull(graph.getStartNode()); + assertTrue(graph.getStartNode() instanceof StepConfigGraphNode); + + StepConfigGraphNode firstStep = (StepConfigGraphNode) graph.getStartNode(); + assertNotNull(firstStep.getNext()); + assertTrue(firstStep.getNext() instanceof DynamicDecisionNode); + } + + @Test(dataProvider = "filterOptionsDataProvider") + public void testFilterOptions(Map> options, StepConfig stepConfig, + int expectedStepsAfterFilter) throws Exception { + + ServiceProvider sp1 = getTestServiceProvider("js-sp-1.xml"); + AuthenticationContext context = getAuthenticationContext(sp1); + + Map stepConfigMap = new HashMap<>(); + stepConfigMap.put(1, stepConfig); + + JsGraalGraphBuilder jsGraphBuilder = jsGraphBuilderFactory.createBuilder(context, stepConfigMap); + jsGraphBuilder.filterOptions(options, stepConfig); + assertEquals(stepConfig.getAuthenticatorList().size(), expectedStepsAfterFilter, + "Authentication options after filtering mismatches expected. " + options); + } + + @DataProvider + public Object[][] filterOptionsDataProvider() { + + ApplicationAuthenticatorService.getInstance().getLocalAuthenticators().clear(); + LocalAuthenticatorConfig basic = new LocalAuthenticatorConfig(); + basic.setName("BasicAuthenticator"); + basic.setDisplayName("basic"); + LocalAuthenticatorConfig totp = new LocalAuthenticatorConfig(); + totp.setName("TOTPAuthenticator"); + totp.setDisplayName("totp"); + ApplicationAuthenticatorService.getInstance().getLocalAuthenticators().add(basic); + ApplicationAuthenticatorService.getInstance().getLocalAuthenticators().add(totp); + + IdentityProvider localIdp = new IdentityProvider(); + localIdp.setId("LOCAL"); + localIdp.setFederatedAuthenticatorConfigs(new FederatedAuthenticatorConfig[0]); + + FederatedAuthenticatorConfig samlFederated = new FederatedAuthenticatorConfig(); + samlFederated.setDisplayName("samlsso"); + samlFederated.setName("SAMLAuthenticator"); + + FederatedAuthenticatorConfig oidcFederated = new FederatedAuthenticatorConfig(); + oidcFederated.setDisplayName("oidc"); + oidcFederated.setName("OIDCAuthenticator"); + + FederatedAuthenticatorConfig twitterFederated = new FederatedAuthenticatorConfig(); + twitterFederated.setDisplayName("twitter"); + twitterFederated.setName("TwitterAuthenticator"); + + IdentityProvider customIdp1 = new IdentityProvider(); + customIdp1.setId("customIdp1"); + customIdp1.setFederatedAuthenticatorConfigs(new FederatedAuthenticatorConfig[]{samlFederated, oidcFederated}); + customIdp1.setDefaultAuthenticatorConfig(samlFederated); + + IdentityProvider customIdp2 = new IdentityProvider(); + customIdp2.setId("customIdp2"); + customIdp2.setFederatedAuthenticatorConfigs(new FederatedAuthenticatorConfig[]{twitterFederated}); + customIdp2.setDefaultAuthenticatorConfig(twitterFederated); + + AuthenticatorConfig basicAuthConfig = new AuthenticatorConfig(); + basicAuthConfig.setName("BasicAuthenticator"); + basicAuthConfig.setEnabled(true); + basicAuthConfig.getIdps().put("LOCAL", localIdp); + + AuthenticatorConfig totpAuthConfig = new AuthenticatorConfig(); + totpAuthConfig.setName("TOTPAuthenticator"); + totpAuthConfig.setEnabled(true); + totpAuthConfig.getIdps().put("LOCAL", localIdp); + + AuthenticatorConfig samlAuthConfig = new AuthenticatorConfig(); + samlAuthConfig.setName("SAMLAuthenticator"); + samlAuthConfig.setEnabled(true); + samlAuthConfig.getIdps().put("customIdp1", customIdp1); + + AuthenticatorConfig oidcAuthConfig = new AuthenticatorConfig(); + oidcAuthConfig.setName("OIDCAuthenticator"); + oidcAuthConfig.setEnabled(true); + oidcAuthConfig.getIdps().put("customIdp1", customIdp1); + + AuthenticatorConfig twitterAuthConfig = new AuthenticatorConfig(); + twitterAuthConfig.setName("TwitterAuthenticator"); + twitterAuthConfig.setEnabled(true); + twitterAuthConfig.getIdps().put("customIdp2", customIdp2); + + StepConfig stepWithSingleOption = new StepConfig(); + stepWithSingleOption.setAuthenticatorList(Collections.singletonList(basicAuthConfig)); + Map> singleOptionConfig = new HashMap<>(); + singleOptionConfig.put("0", Collections.singletonMap("authenticator", "basic")); + + StepConfig stepWithMultipleOptions = new StepConfig(); + stepWithMultipleOptions.setAuthenticatorList( + new ArrayList<>(Arrays.asList(basicAuthConfig, totpAuthConfig, oidcAuthConfig, twitterAuthConfig))); + + Map oidcOption = new HashMap<>(); + oidcOption.put("idp", "customIdp1"); + oidcOption.put("authenticator", "oidc"); + + Map twitterOption = new HashMap<>(); + twitterOption.put("idp", "customIdp2"); + twitterOption.put("authenticator", "twitter"); + + Map invalidOption = new HashMap<>(); + invalidOption.put("idp", "customIdp1"); + invalidOption.put("authenticator", "twitter"); + + Map> multipleOptionConfig = new HashMap<>(); + multipleOptionConfig.put("0", Collections.singletonMap("authenticator", "basic")); + multipleOptionConfig.put("1", oidcOption); + multipleOptionConfig.put("2", twitterOption); + + Map> multipleAndInvalidOptionConfig = new HashMap<>(); + multipleAndInvalidOptionConfig.put("0", Collections.singletonMap("authenticator", "basic")); + multipleAndInvalidOptionConfig.put("1", oidcOption); + multipleAndInvalidOptionConfig.put("2", invalidOption); + + Map> idpOnlyOptionConfig = new HashMap<>(); + idpOnlyOptionConfig.put("0", Collections.singletonMap("authenticator", "basic")); + idpOnlyOptionConfig.put("1", Collections.singletonMap("idp", "customIdp1")); + + Map> singleInvalidOptionConfig = new HashMap<>(); + singleInvalidOptionConfig.put("0", invalidOption); + + return new Object[][]{{singleOptionConfig, duplicateStepConfig(stepWithSingleOption), 1}, + {singleOptionConfig, duplicateStepConfig(stepWithMultipleOptions), 1}, + {multipleOptionConfig, duplicateStepConfig(stepWithMultipleOptions), 3}, + {multipleAndInvalidOptionConfig, duplicateStepConfig(stepWithMultipleOptions), 2}, + {singleInvalidOptionConfig, duplicateStepConfig(stepWithMultipleOptions), 4}, + {idpOnlyOptionConfig, duplicateStepConfig(stepWithMultipleOptions), 2},}; + } + + private StepConfig duplicateStepConfig(StepConfig stepConfig) { + + StepConfig newStepConfig = new StepConfig(); + newStepConfig.setAuthenticatorList(new ArrayList<>(stepConfig.getAuthenticatorList())); + return newStepConfig; + } + + @Test(dataProvider = "filterParamsDataProvider", alwaysRun = true) + public void testParamsOptions(Map options, StepConfig stepConfig, String authenticatorName, + String key, String value) throws Exception { + + ServiceProvider sp1 = getTestServiceProvider("js-sp-1.xml"); + AuthenticationContext context = getAuthenticationContext(sp1); + + Map stepConfigMap = new HashMap<>(); + stepConfigMap.put(1, stepConfig); + + JsGraalGraphBuilder jsGraphBuilder = jsGraphBuilderFactory.createBuilder(context, stepConfigMap); + jsGraphBuilder.authenticatorParamsOptions(options, stepConfig); + assertEquals(context.getAuthenticatorParams(authenticatorName).get(key), value, "Params are not set expected"); + } + + @DataProvider + public Object[][] filterParamsDataProvider() { + + ApplicationAuthenticatorService.getInstance().getLocalAuthenticators().clear(); + LocalAuthenticatorConfig basic = new LocalAuthenticatorConfig(); + basic.setName("BasicAuthenticator"); + basic.setDisplayName("basic"); + + LocalAuthenticatorConfig totp = new LocalAuthenticatorConfig(); + totp.setName("TOTPAuthenticator"); + totp.setDisplayName("totp"); + + ApplicationAuthenticatorService.getInstance().getLocalAuthenticators().add(basic); + ApplicationAuthenticatorService.getInstance().getLocalAuthenticators().add(totp); + + FederatedAuthenticatorConfig twitterFederated = new FederatedAuthenticatorConfig(); + twitterFederated.setDisplayName("twitter"); + twitterFederated.setName("TwitterAuthenticator"); + + IdentityProvider localIdp = new IdentityProvider(); + localIdp.setId("local"); + localIdp.setFederatedAuthenticatorConfigs(new FederatedAuthenticatorConfig[0]); + + IdentityProvider customIdp2 = new IdentityProvider(); + customIdp2.setId("customIdp2"); + customIdp2.setFederatedAuthenticatorConfigs(new FederatedAuthenticatorConfig[]{twitterFederated}); + customIdp2.setDefaultAuthenticatorConfig(twitterFederated); + + AuthenticatorConfig basicAuthConfig = new AuthenticatorConfig(); + basicAuthConfig.setName("BasicAuthenticator"); + basicAuthConfig.setEnabled(true); + when(localApplicationAuthenticator.getName()).thenReturn("BasicAuthenticator"); + when(localApplicationAuthenticator.getFriendlyName()).thenReturn("basic"); + basicAuthConfig.setApplicationAuthenticator(localApplicationAuthenticator); + basicAuthConfig.getIdps().put("local", localIdp); + + AuthenticatorConfig totpAuthConfig = new AuthenticatorConfig(); + totpAuthConfig.setName("TOTPAuthenticator"); + totpAuthConfig.setEnabled(true); + when(totpApplicationAuthenticator.getName()).thenReturn("TOTPAuthenticator"); + when(totpApplicationAuthenticator.getFriendlyName()).thenReturn("totp"); + totpAuthConfig.setApplicationAuthenticator(totpApplicationAuthenticator); + totpAuthConfig.getIdps().put("local", localIdp); + + AuthenticatorConfig twitterAuthConfig = new AuthenticatorConfig(); + twitterAuthConfig.setName("TwitterAuthenticator"); + twitterAuthConfig.setEnabled(true); + when(federatedApplicationAuthenticator.getName()).thenReturn("TwitterAuthenticator"); + when(federatedApplicationAuthenticator.getFriendlyName()).thenReturn("twitter"); + twitterAuthConfig.setApplicationAuthenticator(federatedApplicationAuthenticator); + twitterAuthConfig.getIdps().put("customIdp2", customIdp2); + + StepConfig stepWithSingleOption = new StepConfig(); + stepWithSingleOption.setAuthenticatorList(Collections.singletonList(basicAuthConfig)); + + Map singleParamConfig = new HashMap<>(); + Map params = new HashMap<>(); + params.put("BasicAuthenticator", Collections.singletonMap("foo", "xyz")); + singleParamConfig.put("local", params); + + StepConfig stepWithMultipleOptions = new StepConfig(); + stepWithMultipleOptions.setAuthenticatorList( + new ArrayList<>(Arrays.asList(basicAuthConfig, totpAuthConfig, twitterAuthConfig))); + + Map localParams = new HashMap<>(); + localParams.put("BasicAuthenticator", Collections.singletonMap("foo", "xyz")); + localParams.put("TOTPAuthenticator", Collections.singletonMap("domain", "localhost")); + + Map federatedParams = new HashMap<>(); + federatedParams.put("customIdp2", Collections.singletonMap("foo", "user")); + + Map multiParamConfig = new HashMap<>(); + multiParamConfig.put("local", localParams); + multiParamConfig.put("federated", federatedParams); + + return new Object[][]{ + {singleParamConfig, duplicateStepConfig(stepWithSingleOption), "BasicAuthenticator", "foo", "xyz"}, + {singleParamConfig, duplicateStepConfig(stepWithSingleOption), "BasicAuthenticator", "foos", null}, + {singleParamConfig, duplicateStepConfig(stepWithMultipleOptions), "BasicAuthenticator", "foo", "xyz"}, + {multiParamConfig, duplicateStepConfig(stepWithMultipleOptions), "BasicAuthenticator", "domain", null}, + {multiParamConfig, duplicateStepConfig(stepWithMultipleOptions), "TwitterAuthenticator", "foo", "user"}, + {multiParamConfig, duplicateStepConfig(stepWithMultipleOptions), "TOTPAuthenticator", "domain", + "localhost"}}; + } + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilderTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsNashornGraphBuilderTest.java similarity index 99% rename from components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilderTest.java rename to components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsNashornGraphBuilderTest.java index 61ab1ec27aab..42bc89340e8e 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilderTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsNashornGraphBuilderTest.java @@ -53,7 +53,7 @@ * Tests for graph builder with Javascript. */ @Test -public class JsGraphBuilderTest extends AbstractFrameworkTest { +public class JsNashornGraphBuilderTest extends AbstractFrameworkTest { private JsGraphBuilderFactory jsGraphBuilderFactory; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java new file mode 100644 index 000000000000..202c067825ac --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js; + +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.Source; +import org.graalvm.polyglot.Value; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import org.wso2.carbon.identity.application.authentication.framework.config.model.AuthenticatorConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.SequenceConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthenticationGraph; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalAuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedIdPData; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; +import org.wso2.carbon.identity.application.common.model.ClaimMapping; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +public class JsGraalAuthenticationContextTest { + + public static final String TEST_IDP = "testIdP"; + private static final String LAST_ATTEMPTED_USER_USERNAME = "lastAttemptedUsername"; + private static final String LAST_ATTEMPTED_USER_TENANT_DOMAIN = "lastAttemptedTenantDomain"; + private static final String LAST_ATTEMPTED_USER_USERSTORE_DOMAIN = "lastAttemptedUserstoreDomain"; + private static final String SERVICE_PROVIDER_NAME = "service_provider_js_test"; + private static final String BASIC_AUTHENTICATOR = "BasicAuthenticator"; + + private Context context; + + @BeforeClass + public void setUp() { + + context = Context.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE).allowAllAccess(true).build(); + } + + @Test + public void testClaimAssignment() throws IOException { + + ClaimMapping claimMapping1 = ClaimMapping.build("", "", "", false); + + ClaimMapping claimMapping2 = + ClaimMapping.build("Test.Remote.Claim.Url.2", "Test.Remote.Claim.Url.2", "", false); + + AuthenticatedUser authenticatedUser = new AuthenticatedUser(); + authenticatedUser.getUserAttributes().put(claimMapping1, "TestClaimVal1"); + authenticatedUser.getUserAttributes().put(claimMapping2, "TestClaimVal2"); + AuthenticationContext authenticationContext = new AuthenticationContext(); + setupAuthContextWithStepData(authenticationContext, authenticatedUser); + + JsGraalAuthenticationContext jsAuthenticationContext = new JsGraalAuthenticationContext(authenticationContext); + Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + bindings.putMember("context", jsAuthenticationContext); + + Value result = context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, + "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.1']", + FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + assertTrue(result.isNull()); + + result = context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, + "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.2']", + FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + assertEquals(result.asString(), "TestClaimVal2"); + + context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, + "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.2'] = 'Modified2'", + FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + result = context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, + "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.2']", + FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + assertEquals(result.asString(), "Modified2"); + + } + + private void setupAuthContextWithStepData(AuthenticationContext context, AuthenticatedUser authenticatedUser) { + + AuthenticatorConfig basicAuthenticatorConfig = new AuthenticatorConfig(); + basicAuthenticatorConfig.setName(BASIC_AUTHENTICATOR); + basicAuthenticatorConfig.setEnabled(true); + SequenceConfig sequenceConfig = new SequenceConfig(); + Map stepConfigMap = new HashMap<>(); + StepConfig stepConfig = new StepConfig(); + stepConfig.setOrder(1); + stepConfig.setAuthenticatedIdP(TEST_IDP); + stepConfig.setAuthenticatedAutenticator(basicAuthenticatorConfig); + stepConfigMap.put(1, stepConfig); + sequenceConfig.setStepMap(stepConfigMap); + AuthenticationGraph authenticationGraph = new AuthenticationGraph(); + authenticationGraph.setStepMap(stepConfigMap); + sequenceConfig.setAuthenticationGraph(authenticationGraph); + context.setSequenceConfig(sequenceConfig); + Map idPDataMap = new HashMap<>(); + AuthenticatedIdPData idPData = new AuthenticatedIdPData(); + idPData.setUser(authenticatedUser); + idPData.setIdpName(TEST_IDP); + idPDataMap.put(TEST_IDP, idPData); + context.setCurrentAuthenticatedIdPs(idPDataMap); + } + + @Test + public void testRemoteAddition() throws IOException { + + AuthenticatedUser authenticatedUser = new AuthenticatedUser(); + AuthenticationContext authenticationContext = new AuthenticationContext(); + setupAuthContextWithStepData(authenticationContext, authenticatedUser); + + JsGraalAuthenticationContext jsAuthenticationContext = new JsGraalAuthenticationContext(authenticationContext); + Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + bindings.putMember("context", jsAuthenticationContext); + + context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, + "context.steps[1].subject.remoteClaims['testClaim']='testValue'", + FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + + ClaimMapping claimMapping = ClaimMapping.build("testClaim", "testClaim", "", false); + String claimCreatedByJs = authenticatedUser.getUserAttributes().get(claimMapping); + assertEquals(claimCreatedByJs, "testValue"); + } + + @Test + public void testGetServiceProviderFromWrappedContext() throws Exception { + + AuthenticationContext authenticationContext = new AuthenticationContext(); + authenticationContext.setServiceProviderName(SERVICE_PROVIDER_NAME); + + JsGraalAuthenticationContext jsAuthenticationContext = new JsGraalAuthenticationContext(authenticationContext); + Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + bindings.putMember("context", jsAuthenticationContext); + + Value result = context.eval( + Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, "context.serviceProviderName", + FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + assertFalse(result.isNull()); + assertEquals(result.asString(), SERVICE_PROVIDER_NAME, + "Service Provider name set in AuthenticationContext is not " + + "accessible from JSAuthenticationContext"); + } + + @Test + public void testGetLastLoginFailedUserFromWrappedContext() throws Exception { + + AuthenticatedUser lastAttemptedUser = new AuthenticatedUser(); + lastAttemptedUser.setUserName(LAST_ATTEMPTED_USER_USERNAME); + lastAttemptedUser.setTenantDomain(LAST_ATTEMPTED_USER_TENANT_DOMAIN); + lastAttemptedUser.setUserStoreDomain(LAST_ATTEMPTED_USER_USERSTORE_DOMAIN); + + AuthenticationContext authenticationContext = new AuthenticationContext(); + authenticationContext.setProperty(FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER, lastAttemptedUser); + + JsGraalAuthenticationContext jsAuthenticationContext = new JsGraalAuthenticationContext(authenticationContext); + Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + bindings.putMember("context", jsAuthenticationContext); + + Value result = context.eval( + Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, "context.lastLoginFailedUser", + FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + assertFalse(result.isNull()); + assertTrue(result.asProxyObject() instanceof JsAuthenticatedUser); + + Value username = context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, + "context.lastLoginFailedUser.username", FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + assertEquals(username.asString(), LAST_ATTEMPTED_USER_USERNAME); + + Value tenantDomain = context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, + "context.lastLoginFailedUser.tenantDomain", FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + assertEquals(tenantDomain.asString(), LAST_ATTEMPTED_USER_TENANT_DOMAIN); + + Value userStoreDomain = context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, + "context.lastLoginFailedUser.userStoreDomain", FrameworkConstants.JSAttributes.POLYGLOT_SOURCE) + .build()); + assertEquals(userStoreDomain.asString(), LAST_ATTEMPTED_USER_USERSTORE_DOMAIN.toUpperCase()); + } + + @Test + public void testGetLastLoginFailedUserNullFromWrappedContext() throws Exception { + + AuthenticationContext authenticationContext = new AuthenticationContext(); + authenticationContext.setProperty(FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER, null); + + JsGraalAuthenticationContext jsAuthenticationContext = new JsGraalAuthenticationContext(authenticationContext); + Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + bindings.putMember("context", jsAuthenticationContext); + + Value result = context.eval( + Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, "context.lastLoginFailedUser", + FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + assertTrue(result.isNull()); + } + + @Test + public void testGetLastLoginAuthenticatorFromStep() throws Exception { + + AuthenticationContext authenticationContext = new AuthenticationContext(); + AuthenticatedUser authenticatedUser = new AuthenticatedUser(); + + setupAuthContextWithStepData(authenticationContext, authenticatedUser); + + JsGraalAuthenticationContext jsAuthenticationContext = new JsGraalAuthenticationContext(authenticationContext); + Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + bindings.putMember("context", jsAuthenticationContext); + + Value result = context.eval( + Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, "context.steps[1].authenticator", + FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + + assertFalse(result.isNull()); + assertEquals(result.asString(), BASIC_AUTHENTICATOR, + "Authenticator of the step in AuthenticationContext is not " + + "accessible from JSAuthenticationContext"); + + } + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticationContextTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsNashornAuthenticationContextTest.java similarity index 99% rename from components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticationContextTest.java rename to components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsNashornAuthenticationContextTest.java index 341159f10c98..4efbc8a8d065 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticationContextTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsNashornAuthenticationContextTest.java @@ -47,7 +47,7 @@ import static org.testng.Assert.assertTrue; @Test -public class JsAuthenticationContextTest { +public class JsNashornAuthenticationContextTest { public static final String TEST_IDP = "testIdP"; private static final String LAST_ATTEMPTED_USER_USERNAME = "lastAttemptedUsername"; From 4caf5dd629d53a440b13f4377a3c9d2954bf2148 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Wed, 31 Jan 2024 18:21:20 +0530 Subject: [PATCH 08/35] Add authenticatedAuthenticator to JsGraalStep --- .../graaljs/JsGraalAuthenticationContext.java | 19 ++++++++++++++++++- .../model/graph/js/graaljs/JsGraalStep.java | 19 +++++++++++++------ .../model/graph/js/graaljs/JsGraalSteps.java | 18 +++++++++++++++++- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java index 7f0da8b1b43b..de1dae6166d7 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java @@ -71,7 +71,8 @@ public Object getMember(String name) { case FrameworkConstants.JSAttributes.JS_STEPS: return new JsGraalSteps(getWrapped()); case FrameworkConstants.JSAttributes.JS_CURRENT_STEP: - return new JsGraalStep(getContext(), getContext().getCurrentStep(), getAuthenticatedIdPOfCurrentStep()); + return new JsGraalStep(getContext(), getContext().getCurrentStep(), getAuthenticatedIdPOfCurrentStep(), + getAuthenticatedAuthenticatorOfCurrentStep()); case FrameworkConstants.JSAttributes.JS_CURRENT_KNOWN_SUBJECT: StepConfig stepConfig = getCurrentSubjectIdentifierStep(); if (stepConfig != null) { @@ -137,4 +138,20 @@ private JsGraalAuthenticatedUser getLastLoginFailedUserFromWrappedContext() { } } + protected String getAuthenticatedAuthenticatorOfCurrentStep() { + + if (getContext().getSequenceConfig() == null) { + //Sequence config is not yet initialized + return null; + } + + StepConfig stepConfig = getContext().getSequenceConfig().getStepMap() + .get(getContext().getCurrentStep()); + if (stepConfig != null) { + return stepConfig.getAuthenticatedAutenticator().getName(); + } + return null; + + } + } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java index f88f900cd21d..d6a3f21b89b6 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java @@ -42,20 +42,23 @@ */ public class JsGraalStep extends AbstractJSContextMemberObject implements ProxyObject { - protected static final Log LOG = LogFactory.getLog(JsGraalStep.class); + private static final Log LOG = LogFactory.getLog(JsGraalStep.class); - protected int step; - protected String authenticatedIdp; + private final int step; + private final String authenticatedIdp; + private final String authenticatedAuthenticator; - public JsGraalStep(int step, String authenticatedIdp) { + public JsGraalStep(int step, String authenticatedIdp, String authenticatedAuthenticator) { this.step = step; this.authenticatedIdp = authenticatedIdp; + this.authenticatedAuthenticator = authenticatedAuthenticator; } - public JsGraalStep(AuthenticationContext context, int step, String authenticatedIdp) { + public JsGraalStep(AuthenticationContext context, int step, String authenticatedIdp, + String authenticatedAuthenticator) { - this(step, authenticatedIdp); + this(step, authenticatedIdp, authenticatedAuthenticator); initializeContext(context); } @@ -67,6 +70,8 @@ public Object getMember(String name) { return new JsGraalAuthenticatedUser(getContext(), getSubject(), step, authenticatedIdp); case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP: return authenticatedIdp; + case FrameworkConstants.JSAttributes.JS_AUTHENTICATOR: + return authenticatedAuthenticator; case FrameworkConstants.JSAttributes.JS_AUTHENTICATION_OPTIONS: return getOptions(); default: @@ -79,6 +84,7 @@ public Object getMemberKeys() { return ProxyArray.fromArray(FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT, FrameworkConstants.JSAttributes.JS_AUTHENTICATION_OPTIONS, + FrameworkConstants.JSAttributes.JS_AUTHENTICATOR, FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP); } @@ -100,6 +106,7 @@ public boolean hasMember(String name) { switch (name) { case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT: case FrameworkConstants.JSAttributes.JS_AUTHENTICATION_OPTIONS: + case FrameworkConstants.JSAttributes.JS_AUTHENTICATOR: case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP: return true; default: diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java index fa7fc7d67511..5cd3366542ca 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java @@ -22,6 +22,7 @@ import org.apache.commons.logging.LogFactory; import org.graalvm.polyglot.Value; import org.graalvm.polyglot.proxy.ProxyArray; +import org.wso2.carbon.identity.application.authentication.framework.config.model.AuthenticatorConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.AbstractJSContextMemberObject; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; @@ -63,7 +64,8 @@ public Object get(long index) { if (getContext() == null) { return null; } else { - return new JsGraalStep(getContext(), (int) index, getAuthenticatedIdPOfStep((int) index)); + return new JsGraalStep(getContext(), (int) index, getAuthenticatedIdPOfStep((int) index), + getAuthenticatedAuthenticatorOfStep((int) index)); } } @@ -82,4 +84,18 @@ public long getSize() { } } + private String getAuthenticatedAuthenticatorOfStep(int step) { + + if (getContext().getSequenceConfig() == null) { + //Sequence config is not yet initialized. + return null; + } + + Optional optionalStepConfig = getContext().getSequenceConfig().getStepMap().values().stream() + .filter(stepConfig -> stepConfig.getOrder() == step).findFirst(); + AuthenticatorConfig authenticatorConfig = + optionalStepConfig.map(StepConfig::getAuthenticatedAutenticator).orElse(null); + return authenticatorConfig != null ? authenticatorConfig.getName() : null; + } + } From b142b9164f415590b7787fb18e009708ddf7ad6c Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Wed, 31 Jan 2024 18:24:05 +0530 Subject: [PATCH 09/35] Support SelectAcrFrom Function for GraalJs --- .../graaljs/JsGraalGraphBuilderFactory.java | 3 + .../impl/GraalSelectAcrFromFunction.java | 94 +++++++++++++++++++ .../impl/OpenJdkSelectAcrFromFunction.java | 6 +- .../sequence/impl/SelectAcrFromFunction.java | 6 +- .../sequence/impl/SelectOneFunction.java | 4 +- 5 files changed, 105 insertions(+), 8 deletions(-) create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java index 74461bc1f881..aba2dc278ee0 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java @@ -31,6 +31,7 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsLogger; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; +import org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.GraalSelectAcrFromFunction; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import java.util.HashMap; @@ -85,6 +86,8 @@ public Context createEngine(AuthenticationContext authenticationContext) { .option("engine.WarnInterpreterOnly", "false").build(); Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + GraalSelectAcrFromFunction selectAcrFromFunction = new GraalSelectAcrFromFunction(); + bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_SELECT_ACR_FROM, selectAcrFromFunction); JsLogger jsLogger = new JsLogger(); bindings.putMember(FrameworkConstants.JSAttributes.JS_LOG, jsLogger); return context; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java new file mode 100644 index 000000000000..bd8194ab6d45 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * Select the preferred acr value from the available list. + */ +public class GraalSelectAcrFromFunction implements SelectOneFunction { + + private static final Log log = LogFactory.getLog(SelectAcrFromFunction.class); + + public String evaluate(JsBaseAuthenticationContext context, Object possibleOutcomesObj) { + + String[] possibleOutcomes = extractPossibleOutcomes(context, possibleOutcomesObj); + List acrListRequested = context.getWrapped().getRequestedAcr(); + if (acrListRequested == null || acrListRequested.isEmpty()) { + if (log.isDebugEnabled()) { + log.debug("ACR values from context is empty. Selecting the default outcome as null."); + } + return null; + } + if (possibleOutcomes.length > 0) { + return selectBestOutcome(acrListRequested, possibleOutcomes); + } + return null; + } + + private String[] extractPossibleOutcomes(JsBaseAuthenticationContext context, Object possibleOutcomesObj) { + + String[] possibleOutcomes; + if (possibleOutcomesObj instanceof List) { + possibleOutcomes = ((List) possibleOutcomesObj).toArray(new String[0]); + } else { + log.error("Invalid argument provided for possible outcomes for " + + FrameworkConstants.JSAttributes.JS_FUNC_SELECT_ACR_FROM + " function in service provider: " + + context.getWrapped().getServiceProviderName() + ". Expected array of strings."); + possibleOutcomes = new String[0]; + } + return possibleOutcomes; + } + + private String selectBestOutcome(List acrListRequested, String[] possibleOutcomes) { + + Map acrRequestedWithPriority = + new TreeMap<>(Collections.reverseOrder((o1, o2) -> o2.compareTo(o1))); + String acrSelected = null; + + for (String acrChecked : acrListRequested) { + for (int x = 0; x < possibleOutcomes.length; x++) { + String outcomeToTest = possibleOutcomes[x]; + if (outcomeToTest.equals(acrChecked)) { + if (log.isDebugEnabled()) { + log.debug( + "Reassigning Best Match for the outcome : " + outcomeToTest + " with priority : " + x + + 1); + } + acrRequestedWithPriority.put(x + 1, acrChecked); + break; + } + } + } + if (!acrRequestedWithPriority.entrySet().isEmpty()) { + acrSelected = acrRequestedWithPriority.entrySet().iterator().next().getValue(); + } + return acrSelected; + } +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/OpenJdkSelectAcrFromFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/OpenJdkSelectAcrFromFunction.java index 61f2b2c049fc..a2c7ac8e8c63 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/OpenJdkSelectAcrFromFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/OpenJdkSelectAcrFromFunction.java @@ -21,7 +21,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openjdk.nashorn.api.scripting.ScriptObjectMirror; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import java.util.Collections; @@ -37,7 +37,7 @@ public class OpenJdkSelectAcrFromFunction implements SelectOneFunction { private static final Log log = LogFactory.getLog(OpenJdkSelectAcrFromFunction.class); - public String evaluate(JsAuthenticationContext context, Object possibleOutcomesObj) { + public String evaluate(JsBaseAuthenticationContext context, Object possibleOutcomesObj) { String[] possibleOutcomes = extractPossibleOutcomes(context, possibleOutcomesObj); List acrListRequested = context.getWrapped().getRequestedAcr(); @@ -53,7 +53,7 @@ public String evaluate(JsAuthenticationContext context, Object possibleOutcomesO return null; } - private String[] extractPossibleOutcomes(JsAuthenticationContext context, Object possibleOutcomesObj) { + private String[] extractPossibleOutcomes(JsBaseAuthenticationContext context, Object possibleOutcomesObj) { String[] possibleOutcomes; if (possibleOutcomesObj instanceof String[]) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectAcrFromFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectAcrFromFunction.java index 8d21b194bb7a..2df70d21a17d 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectAcrFromFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectAcrFromFunction.java @@ -21,7 +21,7 @@ import jdk.nashorn.api.scripting.ScriptObjectMirror; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import java.util.Collections; @@ -37,7 +37,7 @@ public class SelectAcrFromFunction implements SelectOneFunction { private static final Log log = LogFactory.getLog(SelectAcrFromFunction.class); - public String evaluate(JsAuthenticationContext context, Object possibleOutcomesObj) { + public String evaluate(JsBaseAuthenticationContext context, Object possibleOutcomesObj) { String[] possibleOutcomes = extractPossibleOutcomes(context, possibleOutcomesObj); List acrListRequested = context.getWrapped().getRequestedAcr(); @@ -53,7 +53,7 @@ public String evaluate(JsAuthenticationContext context, Object possibleOutcomesO return null; } - private String[] extractPossibleOutcomes(JsAuthenticationContext context, Object possibleOutcomesObj) { + private String[] extractPossibleOutcomes(JsBaseAuthenticationContext context, Object possibleOutcomesObj) { String[] possibleOutcomes; if (possibleOutcomesObj instanceof String[]) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectOneFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectOneFunction.java index 849b8372cabc..bcde7e9bba45 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectOneFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectOneFunction.java @@ -18,12 +18,12 @@ package org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticationContext; /** * Functional interface to select one outcome from possible outcomes. */ @FunctionalInterface public interface SelectOneFunction { - String evaluate(JsAuthenticationContext context, Object possibleOutcomesObj); + String evaluate(JsBaseAuthenticationContext context, Object possibleOutcomesObj); } From 4a275b9d5f3a3af6ecdcfa2d35a35ec5064eb106 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Wed, 31 Jan 2024 18:24:45 +0530 Subject: [PATCH 10/35] Bump GraalJs related versions to fix inherent bugs. --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6c37c8f15695..dc4f072de754 100644 --- a/pom.xml +++ b/pom.xml @@ -2112,9 +2112,9 @@ 2.2.224 - 20.2.0 + 22.3.4 - 68.1 + 71.1 3.1.0 4.8.4.0 From 0e8178670bb3038770543bb5cd28529b1200fb6c Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Wed, 31 Jan 2024 22:32:57 +0530 Subject: [PATCH 11/35] Fix the following for GraalJs based script engine implementation. * Fix handle options in JsGraalGraphBuilder * Reduce code redundancy in JsGraalClaims * Fix serialization and deserialization of maps in GraalSerializer --- .../config/model/graph/JsGraphBuilder.java | 2 +- .../model/graph/JsNashornGraphBuilder.java | 2 +- .../model/graph/graaljs/GraalSerializer.java | 16 +++- .../graph/graaljs/JsGraalGraphBuilder.java | 87 ++++++++++++++++--- .../model/graph/js/graaljs/JsGraalClaims.java | 87 ------------------- .../nashorn/JsOpenJdkNashornGraphBuilder.java | 2 +- 6 files changed, 92 insertions(+), 104 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java index b05e3c269458..80838fe130f4 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java @@ -248,7 +248,7 @@ protected void handleOptionsAsyncEvent(Map options, StepConfig s * @param stepOptions Options provided from the script for the step. * @param stepConfigMap StepConfigs of each step as a map. */ - private void handleStepOptions(StepConfig stepConfig, Map stepOptions, + protected void handleStepOptions(StepConfig stepConfig, Map stepOptions, Map stepConfigMap) { stepConfig.setForced(Boolean.parseBoolean(stepOptions.get(FrameworkConstants.JSAttributes.FORCE_AUTH_PARAM))); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsNashornGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsNashornGraphBuilder.java index 61c2da87b9c9..9455106702ef 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsNashornGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsNashornGraphBuilder.java @@ -401,7 +401,7 @@ protected void handleOptionsAsyncEvent(Map options, StepConfig s * @param stepOptions Options provided from the script for the step. * @param stepConfigMap StepConfigs of each step as a map. */ - private void handleStepOptions(StepConfig stepConfig, Map stepOptions, + protected void handleStepOptions(StepConfig stepConfig, Map stepOptions, Map stepConfigMap) { stepConfig.setForced(Boolean.parseBoolean(stepOptions.get(FrameworkConstants.JSAttributes.FORCE_AUTH_PARAM))); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java index 2a93ed0089b9..0d335ca06a64 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java @@ -62,6 +62,16 @@ public static Object toJsSerializableInternal(Object value) { } else { return value; } + } else if (value instanceof Map) { + // Polyglot Map is not serializable. Hence, converting to HashMap. + Map map = new HashMap<>(); + ((Map) value).forEach((k, v) -> map.put(k, toJsSerializableInternal(v))); + return map; + } else if (value instanceof List) { + // Polyglot List is not serializable. Hence, converting to ArrayList. + List list = new ArrayList<>(); + ((List) value).forEach(v -> list.add(toJsSerializableInternal(v))); + return list; } else if (value instanceof Value) { Value valueObj = (Value) value; if (valueObj.canExecute()) { @@ -133,12 +143,12 @@ public static Object fromJsSerializableInternal(Object value, Context context) t log.error("could not recreate JS Object", e); } } else if (value instanceof Map) { - Value deserializedValue = context.eval(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, "[]"); + Map deserializedMap = new HashMap<>(); for (Map.Entry entry : ((Map) value).entrySet()) { Object deserializedObj = fromJsSerializableInternal(entry.getValue(), context); - deserializedValue.putMember(entry.getKey(), deserializedObj); + deserializedMap.put(entry.getKey(), deserializedObj); } - return deserializedValue; + return deserializedMap; } else if (value instanceof List) { Value deserializedValue = context.eval(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, "[]"); List valueList = (List) value; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java index 56846633db9a..ebf337e670bf 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java @@ -49,10 +49,12 @@ import java.io.IOException; import java.io.Serializable; import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.UUID; import java.util.function.BiConsumer; import java.util.stream.Collectors; +import java.util.stream.IntStream; /** * Translate the authentication graph config to runtime model. @@ -140,19 +142,31 @@ public JsGraalGraphBuilder createWith(String script) { context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, FrameworkServiceDataHolder.getInstance().getCodeForRequireFunction(), FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); - context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, script, - FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); - Value onLoginRequestFn = bindings.getMember(FrameworkConstants.JSAttributes.JS_FUNC_ON_LOGIN_REQUEST); - if (onLoginRequestFn == null) { - log.error("Could not find the entry function " + - FrameworkConstants.JSAttributes.JS_FUNC_ON_LOGIN_REQUEST + " \n" + script); - result.setBuildSuccessful(false); - result.setErrorReason("Error in executing the Javascript. " + - FrameworkConstants.JSAttributes.JS_FUNC_ON_LOGIN_REQUEST + " function is not defined."); - return this; + String identifier = UUID.randomUUID().toString(); + JSExecutionMonitorData scriptExecutionData; + + try { + startScriptExecutionMonitor(identifier, authenticationContext); + context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, script, + FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + + Value onLoginRequestFn = bindings.getMember(FrameworkConstants.JSAttributes.JS_FUNC_ON_LOGIN_REQUEST); + if (onLoginRequestFn == null) { + log.error("Could not find the entry function " + + FrameworkConstants.JSAttributes.JS_FUNC_ON_LOGIN_REQUEST + " \n" + script); + result.setBuildSuccessful(false); + result.setErrorReason("Error in executing the Javascript. " + + FrameworkConstants.JSAttributes.JS_FUNC_ON_LOGIN_REQUEST + " function is not defined."); + return this; + } + onLoginRequestFn.executeVoid(new JsGraalAuthenticationContext(authenticationContext)); + } finally { + scriptExecutionData = endScriptExecutionMonitor(identifier); + } + if (scriptExecutionData != null) { + storeAuthScriptExecutionMonitorData(authenticationContext, scriptExecutionData); } - onLoginRequestFn.executeVoid(new JsGraalAuthenticationContext(authenticationContext)); JsGraalGraphBuilderFactory.persistCurrentContext(authenticationContext, context); } catch (PolyglotException e) { result.setBuildSuccessful(false); @@ -405,6 +419,56 @@ public void executeStep(int stepId, Object... params) { } } + /** + * Handle options within executeStepInAsyncEvent function. This method will update step configs through context. + * + * @param options Map of authenticator options. + * @param stepConfig Current stepConfig. + * @param stepConfigMap Map of stepConfigs get from the context object. + */ + @Override + @SuppressWarnings("unchecked") + protected void handleOptionsAsyncEvent(Map options, StepConfig stepConfig, + Map stepConfigMap) { + + Object authenticationOptionsObj = options.get(FrameworkConstants.JSAttributes.AUTHENTICATION_OPTIONS); + if (authenticationOptionsObj instanceof List) { + List> authenticationOptionsList = (List>) authenticationOptionsObj; + authenticationOptionsObj = IntStream.range(0, authenticationOptionsList.size()) + .boxed() + .collect(Collectors.toMap( + String::valueOf, + authenticationOptionsList::get + )); + } + + if (authenticationOptionsObj instanceof Map) { + filterOptions((Map>) authenticationOptionsObj, stepConfig); + } else { + if (log.isDebugEnabled()) { + log.debug("Authenticator options not provided or invalid, hence proceeding without filtering"); + } + } + + Object authenticatorParams = options.get(FrameworkConstants.JSAttributes.AUTHENTICATOR_PARAMS); + if (authenticatorParams instanceof Map) { + authenticatorParamsOptions((Map) authenticatorParams, stepConfig); + } else { + if (log.isDebugEnabled()) { + log.debug("Authenticator params not provided or invalid, hence proceeding without setting params"); + } + } + + Object stepOptions = options.get(FrameworkConstants.JSAttributes.STEP_OPTIONS); + if (stepOptions instanceof Map) { + handleStepOptions(stepConfig, (Map) stepOptions, stepConfigMap); + } else { + if (log.isDebugEnabled()) { + log.debug("Step options not provided or invalid, hence proceeding without handling"); + } + } + } + public static void sendErrorAsync(String url, Map parameterMap) { FailNode newNode = createFailNode(url, parameterMap, true); @@ -487,6 +551,7 @@ public Object evaluate(AuthenticationContext authenticationContext, Object... pa JSExecutionMonitorData scriptExecutionData = retrieveAuthScriptExecutionMonitorData(authenticationContext); try { + startScriptExecutionMonitor(identifier, authenticationContext, scriptExecutionData); result = jsFunction.apply(context, params); } finally { scriptExecutionData = endScriptExecutionMonitor(identifier); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java index 71c1ee468bf0..e1a36a7d1282 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java @@ -18,33 +18,18 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.graalvm.polyglot.Value; import org.graalvm.polyglot.proxy.ProxyArray; import org.graalvm.polyglot.proxy.ProxyObject; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsClaims; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornClaims; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.internal.FrameworkServiceDataHolder; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import org.wso2.carbon.identity.core.util.IdentityTenantUtil; -import org.wso2.carbon.user.api.UserRealm; -import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.user.core.service.RealmService; -import org.wso2.carbon.user.core.util.UserCoreUtil; - -import java.util.HashMap; -import java.util.Map; /** * Represent the user's claim for GraalJs Execution. Can be either remote or local. */ public class JsGraalClaims extends JsClaims implements ProxyObject { - private final transient Map localClaimUriToValueReadCache = new HashMap<>(); - private static final Log LOG = LogFactory.getLog(JsNashornClaims.class); - public JsGraalClaims(AuthenticationContext context, int step, String idp, boolean isRemoteClaimRequest) { super(context, step, idp, isRemoteClaimRequest); @@ -74,76 +59,4 @@ public void putMember(String claimUri, Value claimValue) { } } - /** - * Sets a local claim directly at the userstore for the given user by given claim uri. - * - * @param claimUri Local claim URI - * @param claimValue Claim value - */ - protected void setLocalUserClaim(String claimUri, Object claimValue) { - - localClaimUriToValueReadCache.clear(); - - int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); - RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); - String usernameWithDomain = - UserCoreUtil.addDomainToName(authenticatedUser.getUserName(), authenticatedUser.getUserStoreDomain()); - try { - UserRealm userRealm = realmService.getTenantUserRealm(usersTenantId); - Map claimUriMap = new HashMap<>(); - claimUriMap.put(claimUri, String.valueOf(claimValue)); - userRealm.getUserStoreManager().setUserClaimValues(usernameWithDomain, claimUriMap, null); - } catch (UserStoreException e) { - LOG.error( - String.format("Error when setting claim : %s of user: %s to value: %s", claimUri, authenticatedUser, - claimValue), e); - } - } - - /** - * Check if there is a local claim by given name. - * - * @param claimUri The local claim URI - * @return Claim value of the user authenticated by the indicated IdP - */ - protected boolean hasLocalClaim(String claimUri) { - - String value = localClaimUriToValueReadCache.get(claimUri); - if (value != null) { - return true; - } - value = getLocalClaim(claimUri); - if (value != null) { - localClaimUriToValueReadCache.put(claimUri, value); - return true; - } - return false; - } - - /** - * Get the local user claim value specified by the Claim URI. - * - * @param claimUri Local claim URI - * @return Claim value of the given claim URI for the local user if available. Null Otherwise. - */ - protected String getLocalUserClaim(String claimUri) { - - String value = localClaimUriToValueReadCache.get(claimUri); - if (value != null) { - return value; - } - int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); - String usernameWithDomain = - UserCoreUtil.addDomainToName(authenticatedUser.getUserName(), authenticatedUser.getUserStoreDomain()); - RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); - try { - UserRealm userRealm = realmService.getTenantUserRealm(usersTenantId); - Map claimValues = userRealm.getUserStoreManager() - .getUserClaimValues(usernameWithDomain, new String[]{claimUri}, null); - return claimValues.get(claimUri); - } catch (UserStoreException e) { - LOG.error(String.format("Error when getting claim : %s of user: %s", claimUri, authenticatedUser), e); - } - return null; - } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornGraphBuilder.java index 833547f16a15..e84b733e61e2 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornGraphBuilder.java @@ -424,7 +424,7 @@ protected void handleOptionsAsyncEvent(Map options, StepConfig s * @param stepOptions Options provided from the script for the step. * @param stepConfigMap StepConfigs of each step as a map. */ - private void handleStepOptions(StepConfig stepConfig, Map stepOptions, + protected void handleStepOptions(StepConfig stepConfig, Map stepOptions, Map stepConfigMap) { stepConfig.setForced(Boolean.parseBoolean(stepOptions.get(FrameworkConstants.JSAttributes.FORCE_AUTH_PARAM))); From 6ed0db02f73f2772bd1f80430e1f249bfd13e219 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Thu, 1 Feb 2024 14:42:48 +0530 Subject: [PATCH 12/35] Modify unit tests to support GraalJs execution * Add config to switch between script engines in unit tests * Set Wrapper Factory based on the current script engine * Add new testng test suite got graal js based script execution related tests * Temporarily comment out GraphBasedSequenceHandlerClaimMappingsTest until fixed --- .../impl/GraalSelectAcrFromFunction.java | 1 - .../model/graph/JsGraalGraphBuilderTest.java | 4 +- ...GraphBasedSequenceHandlerAbstractTest.java | 47 ++++++++++++++-- ...sedSequenceHandlerCustomFunctionsTest.java | 54 +++++++++++-------- ...GraphBasedSequenceHandlerLongWaitTest.java | 4 +- .../src/test/resources/testng.xml | 47 ++++++++++++---- 6 files changed, 117 insertions(+), 40 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java index bd8194ab6d45..7b6dfa349823 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java @@ -24,7 +24,6 @@ import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import java.util.Collections; -import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.TreeMap; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraalGraphBuilderTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraalGraphBuilderTest.java index 04fa591d362f..1b4d47588364 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraalGraphBuilderTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraalGraphBuilderTest.java @@ -44,8 +44,8 @@ import java.util.HashMap; import java.util.Map; +import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; -import static org.powermock.api.mockito.PowerMockito.when; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; @@ -262,7 +262,7 @@ public Object[][] filterOptionsDataProvider() { {multipleOptionConfig, duplicateStepConfig(stepWithMultipleOptions), 3}, {multipleAndInvalidOptionConfig, duplicateStepConfig(stepWithMultipleOptions), 2}, {singleInvalidOptionConfig, duplicateStepConfig(stepWithMultipleOptions), 4}, - {idpOnlyOptionConfig, duplicateStepConfig(stepWithMultipleOptions), 2},}; + {idpOnlyOptionConfig, duplicateStepConfig(stepWithMultipleOptions), 2}, }; } private StepConfig duplicateStepConfig(StepConfig stepConfig) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerAbstractTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerAbstractTest.java index affc44a3532a..78879df96233 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerAbstractTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerAbstractTest.java @@ -20,19 +20,30 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Parameters; +import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.identity.application.authentication.framework.AbstractFrameworkTest; import org.wso2.carbon.identity.application.authentication.framework.MockAuthenticator; import org.wso2.carbon.identity.application.authentication.framework.config.builder.FileBasedConfigurationBuilder; import org.wso2.carbon.identity.application.authentication.framework.config.loader.UIBasedConfigurationLoader; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JSExecutionSupervisor; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsFunctionRegistryImpl; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGraphBuilderFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactoryProvider; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs.JsGraalGraphBuilderFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs.JsGraalWrapperFactory; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.handler.SubjectCallback; import org.wso2.carbon.identity.application.authentication.framework.internal.FrameworkServiceDataHolder; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import org.wso2.carbon.identity.application.common.model.ClaimMapping; import org.wso2.carbon.idp.mgt.IdentityProviderManager; import org.wso2.carbon.idp.mgt.dao.CacheBackedIdPMgtDAO; @@ -56,6 +67,7 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; +import static org.mockito.MockitoAnnotations.initMocks; public class GraphBasedSequenceHandlerAbstractTest extends AbstractFrameworkTest { @@ -68,13 +80,42 @@ public class GraphBasedSequenceHandlerAbstractTest extends AbstractFrameworkTest protected static final String TEST_USER_1_ID = "4b4414e1-916b-4475-aaee-6b0751c29ff6"; protected GraphBasedSequenceHandler graphBasedSequenceHandler = new GraphBasedSequenceHandler(); protected UIBasedConfigurationLoader configurationLoader; - protected JsGraphBuilderFactory graphBuilderFactory; + protected JsBaseGraphBuilderFactory graphBuilderFactory; + + @BeforeTest + public void setUpExecutionSupervisor() { + + initMocks(this); + JSExecutionSupervisor jsExecutionSupervisor = new JSExecutionSupervisor(1, 500000L); + FrameworkServiceDataHolder.getInstance().setJsExecutionSupervisor(jsExecutionSupervisor); + } + + @AfterTest + public void tearDownExecutionSupervisor() { + + FrameworkServiceDataHolder.getInstance().getJsExecutionSupervisor().shutdown(); + } @BeforeClass - protected void setupSuite() { + @Parameters({"scriptEngine"}) + protected void setupSuite(String scriptEngine) throws NoSuchFieldException, IllegalAccessException { configurationLoader = new UIBasedConfigurationLoader(); - graphBuilderFactory = new JsGraphBuilderFactory(); + CarbonConstants.ENABLE_LEGACY_AUTHZ_RUNTIME = false; + + if (scriptEngine.contentEquals(FrameworkConstants.JSAttributes.NASHORN)) { + graphBuilderFactory = new JsGraphBuilderFactory(); + } else if (scriptEngine.contentEquals(FrameworkConstants.JSAttributes.GRAALJS)) { + graphBuilderFactory = new JsGraalGraphBuilderFactory(); + } + + Field wrapperFactory = JsWrapperFactoryProvider.class.getDeclaredField("jsWrapperBaseFactory"); + wrapperFactory.setAccessible(true); + if (graphBuilderFactory instanceof JsGraphBuilderFactory) { + wrapperFactory.set(JsWrapperFactoryProvider.getInstance(), new JsWrapperFactory()); + } else if (graphBuilderFactory instanceof JsGraalGraphBuilderFactory) { + wrapperFactory.set(JsWrapperFactoryProvider.getInstance(), new JsGraalWrapperFactory()); + } JsFunctionRegistryImpl jsFunctionRegistry = new JsFunctionRegistryImpl(); FrameworkServiceDataHolder.getInstance().setJsFunctionRegistry(jsFunctionRegistry); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerCustomFunctionsTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerCustomFunctionsTest.java index e90bdcfbd236..b719d7067a71 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerCustomFunctionsTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerCustomFunctionsTest.java @@ -32,7 +32,7 @@ import org.wso2.carbon.identity.application.authentication.framework.MockAuthenticator; import org.wso2.carbon.identity.application.authentication.framework.config.model.SequenceConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsFunctionRegistryImpl; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornAuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.context.AuthHistory; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.exception.AuthenticationFailedException; @@ -91,17 +91,17 @@ public void tearDown() { CentralLogMgtServiceComponentHolder.getInstance().setIdentityEventService(null); } - public static String customFunction1(JsNashornAuthenticationContext context) { + public static String customFunction1(JsBaseAuthenticationContext context) { return "testResult1"; } - public static Boolean customBoolean(JsNashornAuthenticationContext context) { + public static Boolean customBoolean(JsBaseAuthenticationContext context) { return true; } - public static Boolean customBoolean2(JsNashornAuthenticationContext context, String value) { + public static Boolean customBoolean2(JsBaseAuthenticationContext context, String value) { return true; } @@ -113,7 +113,7 @@ public void testHandleDynamicJavascript1() throws Exception { JsFunctionRegistryImpl jsFunctionRegistrar = new JsFunctionRegistryImpl(); FrameworkServiceDataHolder.getInstance().setJsFunctionRegistry(jsFunctionRegistrar); jsFunctionRegistrar.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "fn1", - (Function) GraphBasedSequenceHandlerCustomFunctionsTest + (Function) GraphBasedSequenceHandlerCustomFunctionsTest ::customFunction1); jsFunctionRegistrar.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "fn2", new CustomFunctionImpl2()); @@ -136,16 +136,13 @@ public void testHandleDynamicBoolean() throws Exception { JsFunctionRegistry jsFunctionRegistrar = new JsFunctionRegistryImpl(); FrameworkServiceDataHolder.getInstance().setJsFunctionRegistry(jsFunctionRegistrar); jsFunctionRegistrar.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "fn1", - (Function) GraphBasedSequenceHandlerCustomFunctionsTest + (Function) GraphBasedSequenceHandlerCustomFunctionsTest ::customFunction1); jsFunctionRegistrar.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "getTrueFunction", - (Function) GraphBasedSequenceHandlerCustomFunctionsTest + (Function) GraphBasedSequenceHandlerCustomFunctionsTest ::customBoolean); - - jsFunctionRegistrar.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "getTrueFunction2", - (BiFunction) - GraphBasedSequenceHandlerCustomFunctionsTest - ::customBoolean2); + CustomBoolean2Impl customBoolean2 = new CustomBoolean2Impl(); + jsFunctionRegistrar.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "getTrueFunction2", customBoolean2); ServiceProvider sp1 = getTestServiceProvider("js-sp-dynamic-1.xml"); @@ -188,14 +185,14 @@ public void testHandleDynamicOnFail() throws Exception { JsFunctionRegistryImpl jsFunctionRegistrar = new JsFunctionRegistryImpl(); FrameworkServiceDataHolder.getInstance().setJsFunctionRegistry(jsFunctionRegistrar); jsFunctionRegistrar.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "fn1", - (Function) GraphBasedSequenceHandlerCustomFunctionsTest + (Function) GraphBasedSequenceHandlerCustomFunctionsTest ::customFunction1); jsFunctionRegistrar.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "getTrueFunction", - (Function) GraphBasedSequenceHandlerCustomFunctionsTest + (Function) GraphBasedSequenceHandlerCustomFunctionsTest ::customBoolean); jsFunctionRegistrar.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "getTrueFunction2", - (BiFunction) + (BiFunction) GraphBasedSequenceHandlerCustomFunctionsTest ::customBoolean2); @@ -222,14 +219,14 @@ public void testHandleDynamicOnFallback() throws Exception { JsFunctionRegistryImpl jsFunctionRegistrar = new JsFunctionRegistryImpl(); FrameworkServiceDataHolder.getInstance().setJsFunctionRegistry(jsFunctionRegistrar); jsFunctionRegistrar.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "fn1", - (Function) GraphBasedSequenceHandlerCustomFunctionsTest + (Function) GraphBasedSequenceHandlerCustomFunctionsTest ::customFunction1); jsFunctionRegistrar.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "getTrueFunction", - (Function) GraphBasedSequenceHandlerCustomFunctionsTest + (Function) GraphBasedSequenceHandlerCustomFunctionsTest ::customBoolean); jsFunctionRegistrar.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "getTrueFunction2", - (BiFunction) + (BiFunction) GraphBasedSequenceHandlerCustomFunctionsTest ::customBoolean2); @@ -254,7 +251,7 @@ public void testHandleDynamicJavascriptSerialization() throws Exception { JsFunctionRegistry jsFunctionRegistrar = new JsFunctionRegistryImpl(); FrameworkServiceDataHolder.getInstance().setJsFunctionRegistry(jsFunctionRegistrar); jsFunctionRegistrar.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, "fn1", - (Function) GraphBasedSequenceHandlerCustomFunctionsTest + (Function) GraphBasedSequenceHandlerCustomFunctionsTest ::customFunction1); ServiceProvider sp1 = getTestServiceProvider("js-sp-dynamic-1.xml"); @@ -297,6 +294,7 @@ private AuthenticationContext processSequenceWithAcr(String[] acrArray) return processAndGetAuthenticationContext(acrArray, sp1); } + // private AuthenticationContext processAndGetAuthenticationContext(String[] acrArray, ServiceProvider sp1) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, FrameworkException { @@ -349,10 +347,16 @@ public Object answer(InvocationOnMock invocation) throws Throwable { }).when(request).getAttribute(Mockito.anyString()); } + @FunctionalInterface + public interface CustomBoolean2Interface extends Serializable { + + boolean getTrueFunction2(JsBaseAuthenticationContext context, String param1); + } + @FunctionalInterface public interface CustomFunctionInterface2 extends Serializable { - String customFunction2(JsNashornAuthenticationContext context, String param1, String param2); + String customFunction2(JsBaseAuthenticationContext context, String param1, String param2); } public static class MockFailingAuthenticator extends MockAuthenticator { @@ -389,9 +393,17 @@ public AuthenticatorFlowStatus process(HttpServletRequest request, HttpServletRe public class CustomFunctionImpl2 implements CustomFunctionInterface2 { - public String customFunction2(JsNashornAuthenticationContext context, String param1, String param2) { + public String customFunction2(JsBaseAuthenticationContext context, String param1, String param2) { return "testResult2"; } } + + public class CustomBoolean2Impl implements CustomBoolean2Interface { + + public boolean getTrueFunction2(JsBaseAuthenticationContext context, String param1) { + + return true; + } + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerLongWaitTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerLongWaitTest.java index 3d2b135c0a28..01ef15ebb16a 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerLongWaitTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerLongWaitTest.java @@ -27,7 +27,7 @@ import org.wso2.carbon.identity.application.authentication.framework.JsFunctionRegistry; import org.wso2.carbon.identity.application.authentication.framework.config.model.SequenceConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsFunctionRegistryImpl; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsNashornGraphBuilder; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGraphBuilder; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.dao.impl.CacheBackedLongWaitStatusDAO; import org.wso2.carbon.identity.application.authentication.framework.dao.impl.LongWaitStatusDAOImpl; @@ -123,7 +123,7 @@ public void publishEvent(String siddhiAppName, String inStreamName, String outSt AsyncProcess asyncProcess = new AsyncProcess((ctx, r) -> { r.accept(ctx, Collections.emptyMap(), "onSuccess"); }); - JsNashornGraphBuilder.addLongWaitProcess(asyncProcess, eventHandlers); + JsGraphBuilder.addLongWaitProcess(asyncProcess, eventHandlers); } } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/resources/testng.xml b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/resources/testng.xml index 581212c1f10b..16f2f973dafd 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/resources/testng.xml +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/resources/testng.xml @@ -33,15 +33,6 @@ - - - - - - - - - @@ -56,8 +47,11 @@ - - + + + + + @@ -69,6 +63,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 17fe397b6d9fc5aae63dd75da1e05842378b24f8 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Thu, 8 Feb 2024 09:53:58 +0530 Subject: [PATCH 13/35] * Fix host objects not getting persisted * Add GraaVM Regex and ICU4J dependencies --- .../pom.xml | 10 ++++++++ .../graaljs/JsGraalGraphBuilderFactory.java | 2 +- pom.xml | 23 +++++++++++-------- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml index 9af5b341e69c..311a3b1dd41a 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml @@ -143,6 +143,14 @@ org.graalvm.truffle truffle-api + + org.graalvm.regex + regex + + + com.ibm.icu + icu4j + org.testng @@ -266,6 +274,8 @@ org.osgi.service.http; version="${osgi.service.http.imp.pkg.version.range}", org.osgi.util.tracker; version="${osgi.util.tracker.imp.pkg.version.range}", + org.graalvm.polyglot.*; version="${graalvm.version.range}", + org.wso2.carbon.user.api; version="${carbon.user.api.imp.pkg.version.range}", org.wso2.carbon.registry.core.*; version="${carbon.kernel.registry.imp.pkg.version}", diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java index aba2dc278ee0..a10d822ebcfd 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java @@ -72,7 +72,7 @@ public static void persistCurrentContext(AuthenticationContext authContext, Cont Map persistableMap = new HashMap<>(); engineBindings.getMemberKeys().forEach((key) -> { Value binding = engineBindings.getMember(key); - if (!binding.isHostObject()) { + if (!(binding.isHostObject() && (binding.canExecute() || !binding.hasArrayElements()))) { persistableMap.put(key, GraalSerializer.getInstance().toJsSerializable(binding)); } }); diff --git a/pom.xml b/pom.xml index dc4f072de754..4ab47df5a841 100644 --- a/pom.xml +++ b/pom.xml @@ -1798,16 +1798,16 @@ truffle-api ${graalvm.version} - - - - - - - - - - + + org.graalvm.regex + regex + ${graalvm.version} + + + com.ibm.icu + icu4j + ${icu.version} + @@ -1990,6 +1990,8 @@ [4.1.0,5.0.0) [1.2.0,2.0.0) + + 2.0.4.wso2v5 [2.0.4.wso2v4,3.0.0) 0.16.0.wso2v1 @@ -2113,6 +2115,7 @@ 2.2.224 22.3.4 + [22.3.0,23.0.0) 71.1 From df81848ce62cb19503ebf0130bbe44a6b82f7902 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Thu, 8 Feb 2024 18:43:08 +0530 Subject: [PATCH 14/35] Pack GraalVM dependencies --- .../pom.xml | 2 - .../pom.xml | 61 +++++++++++++++++++ .../resources/p2.inf | 3 +- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml index 311a3b1dd41a..92ca384a7887 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml @@ -274,8 +274,6 @@ org.osgi.service.http; version="${osgi.service.http.imp.pkg.version.range}", org.osgi.util.tracker; version="${osgi.util.tracker.imp.pkg.version.range}", - org.graalvm.polyglot.*; version="${graalvm.version.range}", - org.wso2.carbon.user.api; version="${carbon.user.api.imp.pkg.version.range}", org.wso2.carbon.registry.core.*; version="${carbon.kernel.registry.imp.pkg.version}", diff --git a/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/pom.xml b/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/pom.xml index 90ae2fcdd83d..9898b333ae09 100644 --- a/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/pom.xml +++ b/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/pom.xml @@ -42,6 +42,27 @@ org.wso2.carbon.identity.framework org.wso2.carbon.identity.application.authentication.endpoint.util + + + org.graalvm.sdk + graal-sdk + + + org.graalvm.js + js + + + org.graalvm.truffle + truffle-api + + + com.ibm.icu + icu4j + + + org.graalvm.regex + regex + @@ -67,6 +88,46 @@ true ${basedir}/src/main/resources/runtimes/cxf3 + + org.graalvm.sdk + graal-sdk + ${graalvm.version} + jar + true + ${basedir}/src/main/resources/graal + + + org.graalvm.js + js + ${graalvm.version} + jar + true + ${basedir}/src/main/resources/graal + + + org.graalvm.truffle + truffle-api + ${graalvm.version} + jar + true + ${basedir}/src/main/resources/graal + + + com.ibm.icu + icu4j + ${icu.version} + jar + true + ${basedir}/src/main/resources/graal + + + org.graalvm.regex + regex + ${graalvm.version} + jar + true + ${basedir}/src/main/resources/graal + diff --git a/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/resources/p2.inf b/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/resources/p2.inf index 8635ecc75825..ebcc0cc337f8 100644 --- a/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/resources/p2.inf +++ b/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/resources/p2.inf @@ -21,4 +21,5 @@ org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../featur org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../lib/); \ org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../lib/runtimes/); \ org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../lib/runtimes/cxf3/); \ -org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.identity.application.authentication.framework.server_${feature.version}/runtimes/cxf3/,target:${installFolder}/../../../lib/runtimes/cxf3/,overwrite:true);\ \ No newline at end of file +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.identity.application.authentication.framework.server_${feature.version}/runtimes/cxf3/,target:${installFolder}/../../../lib/runtimes/cxf3/,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.identity.application.authentication.framework.server_${feature.version}/graal/,target:${installFolder}/../../../lib/,overwrite:true);\ \ No newline at end of file From 8190db06a42fb44035ddbcc0fa827213bd377b6e Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Mon, 12 Feb 2024 13:39:19 +0530 Subject: [PATCH 15/35] Fix license headers --- .../graaljs/GraalSerializableJsFunction.java | 2 +- .../model/graph/graaljs/GraalSerializer.java | 2 +- .../graph/graaljs/JsGraalGraphBuilder.java | 2 +- .../graaljs/JsGraalGraphBuilderFactory.java | 2 +- .../graph/graaljs/JsGraalWrapperFactory.java | 18 ++++++++++++++++++ .../graph/js/graaljs/JsGraalRuntimeClaims.java | 4 ++-- .../impl/GraalSelectAcrFromFunction.java | 2 +- .../model/graph/JsGraalGraphBuilderTest.java | 2 +- .../js/JsGraalAuthenticationContextTest.java | 2 +- pom.xml | 2 -- 10 files changed, 27 insertions(+), 11 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java index 3fd6887b287a..fbc7736c49e7 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java @@ -96,7 +96,7 @@ public Object apply(Context polyglotContext, Object... params) { } /** - * This will return the converted NashornSerializableJsFunction if the given ScriptObjectMirror is a function. + * This will return the converted GraalSerializableJsFunction if the given value is a function. * * @param functionObject Value type Function to Serialize * @return null if the ScriptObjectMirror is not a function. diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java index 0d335ca06a64..8b83b64d034b 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java index ebf337e670bf..29c1a6298172 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java index a10d822ebcfd..90b68ee934ee 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java index e0842215c1fe..ba102bb00cd8 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperBaseFactory; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java index 9a3c887dd64d..a3bdc2aeeb8f 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java @@ -1,7 +1,7 @@ /* - * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. * - * WSO2 Inc. licenses this file to you under the Apache License, + * WSO2 LLC. 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 diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java index 7b6dfa349823..49f86555f0c2 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraalGraphBuilderTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraalGraphBuilderTest.java index 1b4d47588364..930f15f9b90d 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraalGraphBuilderTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraalGraphBuilderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java index 202c067825ac..b11f219d3834 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/pom.xml b/pom.xml index 4ab47df5a841..dd94ed5c5867 100644 --- a/pom.xml +++ b/pom.xml @@ -1990,8 +1990,6 @@ [4.1.0,5.0.0) [1.2.0,2.0.0) - - 2.0.4.wso2v5 [2.0.4.wso2v4,3.0.0) 0.16.0.wso2v1 From 1ce00bda964a7e26c295c374f55f325731d3734d Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Mon, 19 Feb 2024 12:08:54 +0530 Subject: [PATCH 16/35] Address review comments --- .../graaljs/GraalSerializableJsFunction.java | 19 +-- .../model/graph/graaljs/GraalSerializer.java | 13 +- .../graph/graaljs/JsGraalGraphBuilder.java | 161 +++++++++--------- .../graaljs/JsGraalGraphBuilderFactory.java | 31 ++-- .../graph/graaljs/JsGraalWrapperFactory.java | 2 +- .../config/model/graph/js/JsClaims.java | 2 +- .../js/graaljs/JsGraalAuthenticatedUser.java | 12 +- .../graaljs/JsGraalAuthenticationContext.java | 15 +- .../model/graph/js/graaljs/JsGraalClaims.java | 2 +- .../model/graph/js/graaljs/JsGraalCookie.java | 2 +- .../graph/js/graaljs/JsGraalHeaders.java | 2 +- .../graph/js/graaljs/JsGraalParameters.java | 2 +- .../js/graaljs/JsGraalRuntimeClaims.java | 2 +- .../js/graaljs/JsGraalServletRequest.java | 2 +- .../js/graaljs/JsGraalServletResponse.java | 2 +- .../model/graph/js/graaljs/JsGraalStep.java | 2 +- .../model/graph/js/graaljs/JsGraalSteps.java | 2 +- .../js/graaljs/JsGraalWritableParameters.java | 2 +- .../js/JsGraalAuthenticationContextTest.java | 75 ++++---- ...GraphBasedSequenceHandlerAbstractTest.java | 2 +- .../src/test/resources/testng.xml | 1 + .../resources/p2.inf | 2 +- 22 files changed, 187 insertions(+), 168 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java index fbc7736c49e7..5c6cd896abd7 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -39,17 +39,12 @@ public class GraalSerializableJsFunction implements BaseSerializableJsFunction deserializedMap = new HashMap<>(); @@ -150,7 +151,7 @@ public static Object fromJsSerializableInternal(Object value, Context context) t } return deserializedMap; } else if (value instanceof List) { - Value deserializedValue = context.eval(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, "[]"); + Value deserializedValue = context.eval(POLYGLOT_LANGUAGE, "[]"); List valueList = (List) value; int listSize = valueList.size(); for (int index = 0; index < listSize; index++) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java index 29c1a6298172..00d1800d0378 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -44,22 +44,36 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.internal.FrameworkServiceDataHolder; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import java.io.IOException; import java.io.Serializable; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.UUID; import java.util.function.BiConsumer; import java.util.stream.Collectors; import java.util.stream.IntStream; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.AdaptiveAuthentication.PROP_EXECUTION_SUPERVISOR_RESULT; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.AUTHENTICATION_OPTIONS; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.AUTHENTICATOR_PARAMS; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.JS_AUTH_FAILURE; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.JS_FUNC_EXECUTE_STEP; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.JS_FUNC_LOAD_FUNC_LIB; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.JS_FUNC_ON_LOGIN_REQUEST; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.JS_FUNC_SEND_ERROR; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.JS_FUNC_SHOW_PROMPT; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.POLYGLOT_SOURCE; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.PROP_CURRENT_NODE; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.STEP_OPTIONS; + /** * Translate the authentication graph config to runtime model. * This is not thread safe. Should be discarded after each build. - * + *

* Since Nashorn is deprecated in JDK 11 and onwards. We are introducing GraalJS engine. */ public class JsGraalGraphBuilder extends JsGraphBuilder { @@ -91,8 +105,9 @@ public JsGraalGraphBuilder(AuthenticationContext authenticationContext, Map) this::sendError); - bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_SHOW_PROMPT, - (PromptExecutor) this::addShowPrompt); - bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_LOAD_FUNC_LIB, - (LoadExecutor) this::loadLocalLibrary); + Value bindings = context.getBindings(POLYGLOT_LANGUAGE); + + bindings.putMember(JS_FUNC_EXECUTE_STEP, (StepExecutor) this::executeStep); + bindings.putMember(JS_FUNC_SEND_ERROR, (BiConsumer) this::sendError); + bindings.putMember(JS_FUNC_SHOW_PROMPT, (PromptExecutor) this::addShowPrompt); + bindings.putMember(JS_FUNC_LOAD_FUNC_LIB, (LoadExecutor) this::loadLocalLibrary); JsFunctionRegistry jsFunctionRegistrar = FrameworkServiceDataHolder.getInstance().getJsFunctionRegistry(); if (jsFunctionRegistrar != null) { Map functionMap = @@ -139,40 +152,39 @@ public JsGraalGraphBuilder createWith(String script) { functionMap.forEach(bindings::putMember); } currentBuilder.set(this); - context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, - FrameworkServiceDataHolder.getInstance().getCodeForRequireFunction(), - FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + context.eval(Source + .newBuilder(POLYGLOT_LANGUAGE, + FrameworkServiceDataHolder.getInstance().getCodeForRequireFunction(), + POLYGLOT_SOURCE) + .build()); String identifier = UUID.randomUUID().toString(); - JSExecutionMonitorData scriptExecutionData; + Optional optionalScriptExecutionData; try { startScriptExecutionMonitor(identifier, authenticationContext); - context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, script, - FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + context.eval(Source.newBuilder(POLYGLOT_LANGUAGE, script, POLYGLOT_SOURCE).build()); - Value onLoginRequestFn = bindings.getMember(FrameworkConstants.JSAttributes.JS_FUNC_ON_LOGIN_REQUEST); + Value onLoginRequestFn = bindings.getMember(JS_FUNC_ON_LOGIN_REQUEST); if (onLoginRequestFn == null) { - log.error("Could not find the entry function " + - FrameworkConstants.JSAttributes.JS_FUNC_ON_LOGIN_REQUEST + " \n" + script); + log.error("Could not find the entry function " + JS_FUNC_ON_LOGIN_REQUEST + " \n" + script); result.setBuildSuccessful(false); - result.setErrorReason("Error in executing the Javascript. " + - FrameworkConstants.JSAttributes.JS_FUNC_ON_LOGIN_REQUEST + " function is not defined."); + result.setErrorReason("Error in executing the Javascript. " + JS_FUNC_ON_LOGIN_REQUEST + + " function is not defined."); return this; } onLoginRequestFn.executeVoid(new JsGraalAuthenticationContext(authenticationContext)); } finally { - scriptExecutionData = endScriptExecutionMonitor(identifier); - } - if (scriptExecutionData != null) { - storeAuthScriptExecutionMonitorData(authenticationContext, scriptExecutionData); + optionalScriptExecutionData = Optional.ofNullable(endScriptExecutionMonitor(identifier)); } + optionalScriptExecutionData.ifPresent( + scriptExecutionData -> storeAuthScriptExecutionMonitorData(authenticationContext, + scriptExecutionData)); JsGraalGraphBuilderFactory.persistCurrentContext(authenticationContext, context); } catch (PolyglotException e) { result.setBuildSuccessful(false); result.setErrorReason( - "Error in executing the Javascript. " + FrameworkConstants.JSAttributes.JS_FUNC_ON_LOGIN_REQUEST + - " reason, " + e.getMessage()); + "Error in executing the Javascript. " + JS_FUNC_ON_LOGIN_REQUEST + " reason, " + e.getMessage()); if (log.isDebugEnabled()) { log.debug("Error in executing the Javascript.", e); } @@ -280,7 +292,7 @@ public void executeStepInAsyncEvent(int stepId, Object... params) { StepConfig stepConfig = graph.getStepMap().get(stepId); if (stepConfig == null) { if (log.isDebugEnabled()) { - log.debug("The stepConfig of the step ID : " + stepId + " is null"); + log.error("The stepConfig of the step ID : " + stepId + " is null"); } return; } @@ -288,8 +300,10 @@ public void executeStepInAsyncEvent(int stepId, Object... params) { StepConfig clonedStepConfig = new StepConfig(stepConfig); StepConfig stepConfigFromContext = null; if (MapUtils.isNotEmpty(context.getSequenceConfig().getStepMap())) { - stepConfigFromContext = context.getSequenceConfig().getStepMap().values().stream() - .filter(contextStepConfig -> (stepConfig.getOrder() == contextStepConfig.getOrder())).findFirst() + stepConfigFromContext = context.getSequenceConfig().getStepMap().values() + .stream() + .filter(contextStepConfig -> (stepConfig.getOrder() == contextStepConfig.getOrder())) + .findFirst() .orElse(null); } clonedStepConfig.applyStateChangesToNewObjectFromContextStepMap(stepConfigFromContext); @@ -431,41 +445,33 @@ public void executeStep(int stepId, Object... params) { protected void handleOptionsAsyncEvent(Map options, StepConfig stepConfig, Map stepConfigMap) { - Object authenticationOptionsObj = options.get(FrameworkConstants.JSAttributes.AUTHENTICATION_OPTIONS); + Object authenticationOptionsObj = options.get(AUTHENTICATION_OPTIONS); if (authenticationOptionsObj instanceof List) { List> authenticationOptionsList = (List>) authenticationOptionsObj; - authenticationOptionsObj = IntStream.range(0, authenticationOptionsList.size()) + authenticationOptionsObj = IntStream + .range(0, authenticationOptionsList.size()) .boxed() - .collect(Collectors.toMap( - String::valueOf, - authenticationOptionsList::get - )); + .collect(Collectors.toMap(String::valueOf, authenticationOptionsList::get)); } if (authenticationOptionsObj instanceof Map) { filterOptions((Map>) authenticationOptionsObj, stepConfig); } else { - if (log.isDebugEnabled()) { - log.debug("Authenticator options not provided or invalid, hence proceeding without filtering"); - } + log.debug("Authenticator options not provided or invalid, hence proceeding without filtering"); } - Object authenticatorParams = options.get(FrameworkConstants.JSAttributes.AUTHENTICATOR_PARAMS); + Object authenticatorParams = options.get(AUTHENTICATOR_PARAMS); if (authenticatorParams instanceof Map) { authenticatorParamsOptions((Map) authenticatorParams, stepConfig); } else { - if (log.isDebugEnabled()) { - log.debug("Authenticator params not provided or invalid, hence proceeding without setting params"); - } + log.debug("Authenticator params not provided or invalid, hence proceeding without setting params"); } - Object stepOptions = options.get(FrameworkConstants.JSAttributes.STEP_OPTIONS); + Object stepOptions = options.get(STEP_OPTIONS); if (stepOptions instanceof Map) { handleStepOptions(stepConfig, (Map) stepOptions, stepConfigMap); } else { - if (log.isDebugEnabled()) { - log.debug("Step options not provided or invalid, hence proceeding without handling"); - } + log.debug("Step options not provided or invalid, hence proceeding without handling"); } } @@ -525,18 +531,13 @@ public Object evaluate(AuthenticationContext authenticationContext, Object... pa currentBuilder.set(graphBuilder); JsGraalGraphBuilderFactory.restoreCurrentContext(authenticationContext, context); Context context = getContext(); - Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); - - bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_EXECUTE_STEP, - (StepExecutor) graphBuilder::executeStepInAsyncEvent); - bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_SEND_ERROR, - (BiConsumer) JsGraalGraphBuilder::sendErrorAsync); - bindings.putMember(FrameworkConstants.JSAttributes.JS_AUTH_FAILURE, - (FailAuthenticationFunction) JsGraalGraphBuilder::failAsync); - bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_SHOW_PROMPT, - (PromptExecutor) graphBuilder::addShowPrompt); - bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_LOAD_FUNC_LIB, - (LoadExecutor) graphBuilder::loadLocalLibrary); + Value bindings = context.getBindings(POLYGLOT_LANGUAGE); + + bindings.putMember(JS_FUNC_EXECUTE_STEP, (StepExecutor) graphBuilder::executeStepInAsyncEvent); + bindings.putMember(JS_FUNC_SEND_ERROR, (BiConsumer) JsGraalGraphBuilder::sendErrorAsync); + bindings.putMember(JS_AUTH_FAILURE, (FailAuthenticationFunction) JsGraalGraphBuilder::failAsync); + bindings.putMember(JS_FUNC_SHOW_PROMPT, (PromptExecutor) graphBuilder::addShowPrompt); + bindings.putMember(JS_FUNC_LOAD_FUNC_LIB, (LoadExecutor) graphBuilder::loadLocalLibrary); JsFunctionRegistry jsFunctionRegistrar = FrameworkServiceDataHolder.getInstance().getJsFunctionRegistry(); if (jsFunctionRegistrar != null) { @@ -548,22 +549,22 @@ public Object evaluate(AuthenticationContext authenticationContext, Object... pa JsGraalGraphBuilder.contextForJs.set(authenticationContext); String identifier = UUID.randomUUID().toString(); - JSExecutionMonitorData scriptExecutionData = - retrieveAuthScriptExecutionMonitorData(authenticationContext); + Optional optionalScriptExecutionData = + Optional.ofNullable(retrieveAuthScriptExecutionMonitorData(authenticationContext)); try { - startScriptExecutionMonitor(identifier, authenticationContext, scriptExecutionData); + startScriptExecutionMonitor(identifier, authenticationContext, + optionalScriptExecutionData.orElse(null)); result = jsFunction.apply(context, params); } finally { - scriptExecutionData = endScriptExecutionMonitor(identifier); - } - if (scriptExecutionData != null) { - storeAuthScriptExecutionMonitorData(authenticationContext, scriptExecutionData); + optionalScriptExecutionData = Optional.ofNullable(endScriptExecutionMonitor(identifier)); } + optionalScriptExecutionData.ifPresent( + scriptExecutionData -> storeAuthScriptExecutionMonitorData(authenticationContext, + scriptExecutionData)); JsGraalGraphBuilderFactory.persistCurrentContext(authenticationContext, context); - AuthGraphNode executingNode = (AuthGraphNode) authenticationContext.getProperty( - FrameworkConstants.JSAttributes.PROP_CURRENT_NODE); + AuthGraphNode executingNode = (AuthGraphNode) authenticationContext.getProperty(PROP_CURRENT_NODE); if (canInfuse(executingNode)) { infuse(executingNode, dynamicallyBuiltBaseNode.get()); } @@ -573,8 +574,7 @@ public Object evaluate(AuthenticationContext authenticationContext, Object... pa log.error("Error in executing the javascript for service provider : " + authenticationContext.getServiceProviderName() + ", Javascript Fragment : \n" + jsFunction.getSource(), e); - AuthGraphNode executingNode = (AuthGraphNode) authenticationContext.getProperty( - FrameworkConstants.JSAttributes.PROP_CURRENT_NODE); + AuthGraphNode executingNode = (AuthGraphNode) authenticationContext.getProperty(PROP_CURRENT_NODE); FailNode failNode = new FailNode(); attachToLeaf(executingNode, failNode); } finally { @@ -650,8 +650,7 @@ public static void failAsync(Object... parameters) { private void removeDefaultFunctions(Context context) throws IOException { - context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, REMOVE_FUNCTIONS, - FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + context.eval(Source.newBuilder(POLYGLOT_LANGUAGE, REMOVE_FUNCTIONS, POLYGLOT_SOURCE).build()); } private JSExecutionSupervisor getJSExecutionSupervisor() { @@ -662,15 +661,13 @@ private JSExecutionSupervisor getJSExecutionSupervisor() { private void storeAuthScriptExecutionMonitorData(AuthenticationContext context, JSExecutionMonitorData jsExecutionMonitorData) { - context.setProperty(FrameworkConstants.AdaptiveAuthentication.PROP_EXECUTION_SUPERVISOR_RESULT, - jsExecutionMonitorData); + context.setProperty(PROP_EXECUTION_SUPERVISOR_RESULT, jsExecutionMonitorData); } private JSExecutionMonitorData retrieveAuthScriptExecutionMonitorData(AuthenticationContext context) { JSExecutionMonitorData jsExecutionMonitorData; - Object storedResult = - context.getProperty(FrameworkConstants.AdaptiveAuthentication.PROP_EXECUTION_SUPERVISOR_RESULT); + Object storedResult = context.getProperty(PROP_EXECUTION_SUPERVISOR_RESULT); if (storedResult != null) { jsExecutionMonitorData = (JSExecutionMonitorData) storedResult; } else { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java index 90b68ee934ee..0d414ce4d5e3 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -32,11 +32,14 @@ import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; import org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.GraalSelectAcrFromFunction; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import java.util.HashMap; import java.util.Map; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.JS_FUNC_SELECT_ACR_FROM; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.JS_LOG; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE; + /** * Factory to create a Javascript based sequence builder. * This factory is there to reuse of GraalJS Polyglot Context and any related expensive objects. @@ -57,7 +60,7 @@ public static void restoreCurrentContext(AuthenticationContext authContext, Cont throws FrameworkException { Map map = (Map) authContext.getProperty(JS_BINDING_CURRENT_CONTEXT); - Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + Value bindings = context.getBindings(POLYGLOT_LANGUAGE); if (map != null) { for (Map.Entry entry : map.entrySet()) { Object deserializedValue = GraalSerializer.getInstance().fromJsSerializable(entry.getValue(), context); @@ -68,10 +71,17 @@ public static void restoreCurrentContext(AuthenticationContext authContext, Cont public static void persistCurrentContext(AuthenticationContext authContext, Context context) { - Value engineBindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + Value engineBindings = context.getBindings(POLYGLOT_LANGUAGE); Map persistableMap = new HashMap<>(); engineBindings.getMemberKeys().forEach((key) -> { Value binding = engineBindings.getMember(key); + /* + * Since, we don't have a difference between global and engine scopes, we need to identify what are the + * custom functions and the logger object we added bindings to, and not persist them since we will anyways + * bind them again. + * The functions will be host objects and can be executed. The logger object will be host object and will + * not have any array elements. + */ if (!(binding.isHostObject() && (binding.canExecute() || !binding.hasArrayElements()))) { persistableMap.put(key, GraalSerializer.getInstance().toJsSerializable(binding)); } @@ -81,15 +91,12 @@ public static void persistCurrentContext(AuthenticationContext authContext, Cont public Context createEngine(AuthenticationContext authenticationContext) { - Context context = - Context.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE).allowHostAccess(HostAccess.ALL) - .option("engine.WarnInterpreterOnly", "false").build(); + Context context = Context.newBuilder(POLYGLOT_LANGUAGE).allowHostAccess(HostAccess.ALL) + .option("engine.WarnInterpreterOnly", "false").build(); - Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); - GraalSelectAcrFromFunction selectAcrFromFunction = new GraalSelectAcrFromFunction(); - bindings.putMember(FrameworkConstants.JSAttributes.JS_FUNC_SELECT_ACR_FROM, selectAcrFromFunction); - JsLogger jsLogger = new JsLogger(); - bindings.putMember(FrameworkConstants.JSAttributes.JS_LOG, jsLogger); + Value bindings = context.getBindings(POLYGLOT_LANGUAGE); + bindings.putMember(JS_FUNC_SELECT_ACR_FROM, new GraalSelectAcrFromFunction()); + bindings.putMember(JS_LOG, new JsLogger()); return context; } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java index ba102bb00cd8..6461bfaf9c76 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java index 2d51bbe12546..376cac472e39 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java index 6ad9d0acbac1..aaf50a351ec5 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -103,7 +103,15 @@ public Object getMember(String name) { @Override public Object getMemberKeys() { - return ProxyArray.fromArray(FrameworkConstants.JSAttributes.JS_USERNAME); + return ProxyArray.fromArray( + FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT_IDENTIFIER, + FrameworkConstants.JSAttributes.JS_USERNAME, + FrameworkConstants.JSAttributes.JS_USER_STORE_DOMAIN, + FrameworkConstants.JSAttributes.JS_TENANT_DOMAIN, + FrameworkConstants.JSAttributes.JS_LOCAL_CLAIMS, + FrameworkConstants.JSAttributes.JS_REMOTE_CLAIMS, + FrameworkConstants.JSAttributes.JS_LOCAL_ROLES, + FrameworkConstants.JSAttributes.JS_CLAIMS); } public void putMember(String name, Value value) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java index de1dae6166d7..58bee07632bc 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -90,8 +90,17 @@ public Object getMember(String name) { @Override public Object getMemberKeys() { - return ProxyArray.fromArray(FrameworkConstants.JSAttributes.JS_STEPS, - FrameworkConstants.JSAttributes.JS_CURRENT_KNOWN_SUBJECT); + return ProxyArray.fromArray( + FrameworkConstants.JSAttributes.JS_REQUESTED_ACR, + FrameworkConstants.JSAttributes.JS_TENANT_DOMAIN, + FrameworkConstants.JSAttributes.JS_SERVICE_PROVIDER_NAME, + FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER, + FrameworkConstants.JSAttributes.JS_REQUEST, + FrameworkConstants.JSAttributes.JS_RESPONSE, + FrameworkConstants.JSAttributes.JS_STEPS, + FrameworkConstants.JSAttributes.JS_CURRENT_STEP, + FrameworkConstants.JSAttributes.JS_CURRENT_KNOWN_SUBJECT, + FrameworkConstants.JSAttributes.JS_RETRY_STEP); } @Override diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java index e1a36a7d1282..c847276002b2 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java index aa20dd152590..3fe279b0953a 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java index e3b63cf41c17..69bcdccc4320 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java index 7bb990726598..680faae7377b 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java index a3bdc2aeeb8f..0a6f3e2a8595 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java index 8e069b322ced..db39a6938484 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java index e34406b7a1fb..a4c27277596d 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java index d6a3f21b89b6..b64d1f1d4fae 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java index 5cd3366542ca..e0084e280d51 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java index 69e962c3d7ab..05d241a0f541 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java index b11f219d3834..87c8326b42d7 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java @@ -41,6 +41,8 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.POLYGLOT_SOURCE; public class JsGraalAuthenticationContextTest { @@ -56,7 +58,7 @@ public class JsGraalAuthenticationContextTest { @BeforeClass public void setUp() { - context = Context.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE).allowAllAccess(true).build(); + context = Context.newBuilder(POLYGLOT_LANGUAGE).allowAllAccess(true).build(); } @Test @@ -74,25 +76,27 @@ public void testClaimAssignment() throws IOException { setupAuthContextWithStepData(authenticationContext, authenticatedUser); JsGraalAuthenticationContext jsAuthenticationContext = new JsGraalAuthenticationContext(authenticationContext); - Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + Value bindings = context.getBindings(POLYGLOT_LANGUAGE); bindings.putMember("context", jsAuthenticationContext); - Value result = context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, - "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.1']", - FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + Value result = context.eval( + Source.newBuilder(POLYGLOT_LANGUAGE, "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.1']", + POLYGLOT_SOURCE).build()); assertTrue(result.isNull()); - result = context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, - "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.2']", - FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + result = context.eval( + Source.newBuilder(POLYGLOT_LANGUAGE, + "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.2']", + POLYGLOT_SOURCE).build()); assertEquals(result.asString(), "TestClaimVal2"); - context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, - "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.2'] = 'Modified2'", - FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); - result = context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, - "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.2']", - FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + context.eval(Source.newBuilder(POLYGLOT_LANGUAGE, + "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.2'] = 'Modified2'", + POLYGLOT_SOURCE).build()); + result = context.eval( + Source.newBuilder(POLYGLOT_LANGUAGE, + "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.2']", + POLYGLOT_SOURCE).build()); assertEquals(result.asString(), "Modified2"); } @@ -130,12 +134,12 @@ public void testRemoteAddition() throws IOException { setupAuthContextWithStepData(authenticationContext, authenticatedUser); JsGraalAuthenticationContext jsAuthenticationContext = new JsGraalAuthenticationContext(authenticationContext); - Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + Value bindings = context.getBindings(POLYGLOT_LANGUAGE); bindings.putMember("context", jsAuthenticationContext); - context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, - "context.steps[1].subject.remoteClaims['testClaim']='testValue'", - FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + context.eval( + Source.newBuilder(POLYGLOT_LANGUAGE, "context.steps[1].subject.remoteClaims['testClaim']='testValue'", + POLYGLOT_SOURCE).build()); ClaimMapping claimMapping = ClaimMapping.build("testClaim", "testClaim", "", false); String claimCreatedByJs = authenticatedUser.getUserAttributes().get(claimMapping); @@ -149,12 +153,11 @@ public void testGetServiceProviderFromWrappedContext() throws Exception { authenticationContext.setServiceProviderName(SERVICE_PROVIDER_NAME); JsGraalAuthenticationContext jsAuthenticationContext = new JsGraalAuthenticationContext(authenticationContext); - Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + Value bindings = context.getBindings(POLYGLOT_LANGUAGE); bindings.putMember("context", jsAuthenticationContext); Value result = context.eval( - Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, "context.serviceProviderName", - FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + Source.newBuilder(POLYGLOT_LANGUAGE, "context.serviceProviderName", POLYGLOT_SOURCE).build()); assertFalse(result.isNull()); assertEquals(result.asString(), SERVICE_PROVIDER_NAME, "Service Provider name set in AuthenticationContext is not " + @@ -173,26 +176,26 @@ public void testGetLastLoginFailedUserFromWrappedContext() throws Exception { authenticationContext.setProperty(FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER, lastAttemptedUser); JsGraalAuthenticationContext jsAuthenticationContext = new JsGraalAuthenticationContext(authenticationContext); - Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + Value bindings = context.getBindings(POLYGLOT_LANGUAGE); bindings.putMember("context", jsAuthenticationContext); Value result = context.eval( - Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, "context.lastLoginFailedUser", - FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + Source.newBuilder(POLYGLOT_LANGUAGE, "context.lastLoginFailedUser", POLYGLOT_SOURCE).build()); assertFalse(result.isNull()); assertTrue(result.asProxyObject() instanceof JsAuthenticatedUser); - Value username = context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, - "context.lastLoginFailedUser.username", FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + Value username = context.eval( + Source.newBuilder(POLYGLOT_LANGUAGE, "context.lastLoginFailedUser.username", POLYGLOT_SOURCE).build()); assertEquals(username.asString(), LAST_ATTEMPTED_USER_USERNAME); - Value tenantDomain = context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, - "context.lastLoginFailedUser.tenantDomain", FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + Value tenantDomain = context.eval( + Source.newBuilder(POLYGLOT_LANGUAGE, "context.lastLoginFailedUser.tenantDomain", POLYGLOT_SOURCE) + .build()); assertEquals(tenantDomain.asString(), LAST_ATTEMPTED_USER_TENANT_DOMAIN); - Value userStoreDomain = context.eval(Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, - "context.lastLoginFailedUser.userStoreDomain", FrameworkConstants.JSAttributes.POLYGLOT_SOURCE) - .build()); + Value userStoreDomain = context.eval( + Source.newBuilder(POLYGLOT_LANGUAGE, "context.lastLoginFailedUser.userStoreDomain", POLYGLOT_SOURCE) + .build()); assertEquals(userStoreDomain.asString(), LAST_ATTEMPTED_USER_USERSTORE_DOMAIN.toUpperCase()); } @@ -203,12 +206,11 @@ public void testGetLastLoginFailedUserNullFromWrappedContext() throws Exception authenticationContext.setProperty(FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER, null); JsGraalAuthenticationContext jsAuthenticationContext = new JsGraalAuthenticationContext(authenticationContext); - Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + Value bindings = context.getBindings(POLYGLOT_LANGUAGE); bindings.putMember("context", jsAuthenticationContext); Value result = context.eval( - Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, "context.lastLoginFailedUser", - FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + Source.newBuilder(POLYGLOT_LANGUAGE, "context.lastLoginFailedUser", POLYGLOT_SOURCE).build()); assertTrue(result.isNull()); } @@ -221,12 +223,11 @@ public void testGetLastLoginAuthenticatorFromStep() throws Exception { setupAuthContextWithStepData(authenticationContext, authenticatedUser); JsGraalAuthenticationContext jsAuthenticationContext = new JsGraalAuthenticationContext(authenticationContext); - Value bindings = context.getBindings(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE); + Value bindings = context.getBindings(POLYGLOT_LANGUAGE); bindings.putMember("context", jsAuthenticationContext); Value result = context.eval( - Source.newBuilder(FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE, "context.steps[1].authenticator", - FrameworkConstants.JSAttributes.POLYGLOT_SOURCE).build()); + Source.newBuilder(POLYGLOT_LANGUAGE, "context.steps[1].authenticator", POLYGLOT_SOURCE).build()); assertFalse(result.isNull()); assertEquals(result.asString(), BASIC_AUTHENTICATOR, diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerAbstractTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerAbstractTest.java index 78879df96233..036ffa6bbc5b 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerAbstractTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerAbstractTest.java @@ -86,7 +86,7 @@ public class GraphBasedSequenceHandlerAbstractTest extends AbstractFrameworkTest public void setUpExecutionSupervisor() { initMocks(this); - JSExecutionSupervisor jsExecutionSupervisor = new JSExecutionSupervisor(1, 500000L); + JSExecutionSupervisor jsExecutionSupervisor = new JSExecutionSupervisor(1, 5000L); FrameworkServiceDataHolder.getInstance().setJsExecutionSupervisor(jsExecutionSupervisor); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/resources/testng.xml b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/resources/testng.xml index 16f2f973dafd..f28f7a8c8a9d 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/resources/testng.xml +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/resources/testng.xml @@ -85,6 +85,7 @@ + diff --git a/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/resources/p2.inf b/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/resources/p2.inf index ebcc0cc337f8..f24ac13d5940 100644 --- a/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/resources/p2.inf +++ b/features/authentication-framework/org.wso2.carbon.identity.application.authentication.framework.server.feature/resources/p2.inf @@ -22,4 +22,4 @@ org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../l org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../lib/runtimes/); \ org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../lib/runtimes/cxf3/); \ org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.identity.application.authentication.framework.server_${feature.version}/runtimes/cxf3/,target:${installFolder}/../../../lib/runtimes/cxf3/,overwrite:true);\ -org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.identity.application.authentication.framework.server_${feature.version}/graal/,target:${installFolder}/../../../lib/,overwrite:true);\ \ No newline at end of file +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.identity.application.authentication.framework.server_${feature.version}/graal/,target:${installFolder}/../../../lib/,overwrite:true);\ From e0b197d69c1283326911f694b2f40dbfd35ffe15 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Tue, 20 Feb 2024 10:40:52 +0530 Subject: [PATCH 17/35] Set HostAccess to EXPLICIT to restrict access to JAVA classes. --- .../AuthenticationDecisionEvaluator.java | 2 + .../config/model/graph/JsGraphBuilder.java | 16 +++++ .../graaljs/GraalSerializableJsFunction.java | 10 +-- .../model/graph/graaljs/GraalSerializer.java | 4 +- .../graph/graaljs/JsGraalGraphBuilder.java | 70 +++++++++++++++++-- .../graaljs/JsGraalGraphBuilderFactory.java | 6 +- .../config/model/graph/js/JsLogger.java | 6 ++ .../js/base/JsBaseAuthenticationContext.java | 2 + .../graaljs/JsGraalAuthenticationContext.java | 1 - .../model/graph/js/graaljs/JsGraalClaims.java | 4 +- .../js/graaljs/JsGraalRuntimeClaims.java | 9 ++- .../js/graaljs/JsGraalWritableParameters.java | 1 - .../impl/GraalSelectAcrFromFunction.java | 2 + .../js/JsGraalAuthenticationContextTest.java | 14 ++-- ...sedSequenceHandlerCustomFunctionsTest.java | 2 + ...GraphBasedSequenceHandlerLongWaitTest.java | 2 + 16 files changed, 118 insertions(+), 33 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/AuthenticationDecisionEvaluator.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/AuthenticationDecisionEvaluator.java index 44bce0fd0e7d..1b59a3837961 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/AuthenticationDecisionEvaluator.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/AuthenticationDecisionEvaluator.java @@ -18,6 +18,7 @@ package org.wso2.carbon.identity.application.authentication.framework; +import org.graalvm.polyglot.HostAccess; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import java.io.Serializable; @@ -39,5 +40,6 @@ public interface AuthenticationDecisionEvaluator extends Serializable { * @param context * @return */ + @HostAccess.Export Object evaluate(AuthenticationContext context, Object... params); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java index 80838fe130f4..b6b929b4fe2b 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java @@ -21,6 +21,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.graalvm.polyglot.HostAccess; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.identity.application.authentication.framework.AsyncProcess; import org.wso2.carbon.identity.application.authentication.framework.config.model.AuthenticatorConfig; @@ -482,6 +483,7 @@ public static void addPrompt(String templateId, Map parameters, * @return functionLibraryScript * @throws FunctionLibraryManagementException */ + @HostAccess.Export public String loadLocalLibrary(String functionLibraryName) throws FunctionLibraryManagementException { FunctionLibraryManagementService functionLibMgtService = FrameworkServiceComponent. @@ -500,6 +502,18 @@ public String loadLocalLibrary(String functionLibraryName) throws FunctionLibrar return libraryScript; } + /** + * Load Executor implementation to load local libraries. + */ + public class LoadExecutorImpl implements LoadExecutor { + + @HostAccess.Export + public String loadLocalLibrary(String libraryName) throws FunctionLibraryManagementException { + + return JsGraphBuilder.this.loadLocalLibrary(libraryName); + } + } + /** * Adds a function to show a prompt in Javascript code. * @@ -615,6 +629,7 @@ public interface FailAuthenticationFunction { @FunctionalInterface public interface StepExecutor { + @HostAccess.Export void executeStep(Integer stepId, Object... parameterMap); } @@ -624,6 +639,7 @@ public interface StepExecutor { @FunctionalInterface public interface PromptExecutor { + @HostAccess.Export void prompt(String template, Object... parameterMap); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java index 5c6cd896abd7..d8a31d827ed6 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java @@ -22,11 +22,9 @@ import org.apache.commons.logging.LogFactory; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.PolyglotException; -import org.graalvm.polyglot.Source; import org.graalvm.polyglot.Value; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.BaseSerializableJsFunction; -import java.io.IOException; import java.util.function.Function; /** @@ -78,10 +76,8 @@ public Object apply(Context polyglotContext, Object... params) { if (isPolyglotFunction) { try { - polyglotContext.eval(Source.newBuilder("js", " var curFunc = " + getSource(), "src.js").build()); - return polyglotContext.getBindings("js").getMember("curFunc").execute(params); - } catch (IOException e) { - log.error("Error when building the from function source", e); + Value jsFunction = polyglotContext.eval("js", "(" + getSource() + ")"); + return jsFunction.execute(params); } catch (PolyglotException e) { log.error("Error when executing function", e); } @@ -115,8 +111,6 @@ public static GraalSerializableJsFunction toSerializableForm(Object functionObje } String source = (String) functionAsValue.getSourceLocation().getCharacters(); return serializePolyglot(source); - } else { - return null; } } catch (PolyglotException e) { log.error("Error when serializing JavaScript Function: ", e); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java index b09d694aae8a..bada6360f198 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java @@ -137,9 +137,7 @@ public static Object fromJsSerializableInternal(Object value, Context context) t if (value instanceof GraalSerializableJsFunction) { GraalSerializableJsFunction serializableJsFunction = (GraalSerializableJsFunction) value; try { - context.eval(POLYGLOT_LANGUAGE, - "var tempFunc = " + serializableJsFunction.getSource()); - return context.getBindings(POLYGLOT_LANGUAGE).getMember("tempFunc"); + return context.eval("js", "(" + serializableJsFunction.getSource() + ")"); } catch (Exception e) { log.error("Error when recreating JS Object", e); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java index 00d1800d0378..4d033d4f23f8 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java @@ -23,6 +23,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.HostAccess; import org.graalvm.polyglot.PolyglotException; import org.graalvm.polyglot.Source; import org.graalvm.polyglot.Value; @@ -141,10 +142,10 @@ public JsGraalGraphBuilder createWith(String script) { currentBuilder.set(this); Value bindings = context.getBindings(POLYGLOT_LANGUAGE); - bindings.putMember(JS_FUNC_EXECUTE_STEP, (StepExecutor) this::executeStep); + bindings.putMember(JS_FUNC_EXECUTE_STEP, new JsGraalStepExecuter()); bindings.putMember(JS_FUNC_SEND_ERROR, (BiConsumer) this::sendError); - bindings.putMember(JS_FUNC_SHOW_PROMPT, (PromptExecutor) this::addShowPrompt); - bindings.putMember(JS_FUNC_LOAD_FUNC_LIB, (LoadExecutor) this::loadLocalLibrary); + bindings.putMember(JS_FUNC_SHOW_PROMPT, new PromptExecutorImpl()); + bindings.putMember(JS_FUNC_LOAD_FUNC_LIB, new LoadExecutorImpl()); JsFunctionRegistry jsFunctionRegistrar = FrameworkServiceDataHolder.getInstance().getJsFunctionRegistry(); if (jsFunctionRegistrar != null) { Map functionMap = @@ -275,6 +276,7 @@ private static void addHandlers(ShowPromptNode showPromptNode, Map parameterMap) { @@ -400,6 +415,7 @@ public static void clearCurrentBuilder(Context context) { * @param params params */ @SuppressWarnings("unchecked") + @HostAccess.Export public void executeStep(int stepId, Object... params) { StepConfig stepConfig; @@ -433,6 +449,18 @@ public void executeStep(int stepId, Object... params) { } } + /** + * Executes the given script. + */ + public class JsGraalStepExecuter implements StepExecutor { + + @HostAccess.Export + public void executeStep(Integer stepId, Object... parameterMap) { + + JsGraalGraphBuilder.this.executeStep(stepId, parameterMap); + } + } + /** * Handle options within executeStepInAsyncEvent function. This method will update step configs through context. * @@ -475,6 +503,7 @@ protected void handleOptionsAsyncEvent(Map options, StepConfig s } } + @HostAccess.Export public static void sendErrorAsync(String url, Map parameterMap) { FailNode newNode = createFailNode(url, parameterMap, true); @@ -517,6 +546,7 @@ public JsBasedEvaluator(GraalSerializableJsFunction jsFunction) { } @Override + @HostAccess.Export public Object evaluate(AuthenticationContext authenticationContext, Object... params) { JsGraalGraphBuilder graphBuilder = JsGraalGraphBuilder.this; @@ -533,11 +563,11 @@ public Object evaluate(AuthenticationContext authenticationContext, Object... pa Context context = getContext(); Value bindings = context.getBindings(POLYGLOT_LANGUAGE); - bindings.putMember(JS_FUNC_EXECUTE_STEP, (StepExecutor) graphBuilder::executeStepInAsyncEvent); + bindings.putMember(JS_FUNC_EXECUTE_STEP, new JsGraalStepExecuterInAsyncEvent()); bindings.putMember(JS_FUNC_SEND_ERROR, (BiConsumer) JsGraalGraphBuilder::sendErrorAsync); - bindings.putMember(JS_AUTH_FAILURE, (FailAuthenticationFunction) JsGraalGraphBuilder::failAsync); - bindings.putMember(JS_FUNC_SHOW_PROMPT, (PromptExecutor) graphBuilder::addShowPrompt); - bindings.putMember(JS_FUNC_LOAD_FUNC_LIB, (LoadExecutor) graphBuilder::loadLocalLibrary); + bindings.putMember(JS_AUTH_FAILURE, new FailAuthenticationFunctionImpl()); + bindings.putMember(JS_FUNC_SHOW_PROMPT, new PromptExecutorImpl()); + bindings.putMember(JS_FUNC_LOAD_FUNC_LIB, new LoadExecutorImpl()); JsFunctionRegistry jsFunctionRegistrar = FrameworkServiceDataHolder.getInstance().getJsFunctionRegistry(); if (jsFunctionRegistrar != null) { @@ -598,6 +628,7 @@ private Context getContext() { * @param parameters parameters */ @SuppressWarnings("unchecked") + @HostAccess.Export public void addShowPrompt(String templateId, Object... parameters) { ShowPromptNode newNode = new ShowPromptNode(); @@ -623,11 +654,24 @@ public void addShowPrompt(String templateId, Object... parameters) { } } + /** + * GraalJS specific prompt implementation + */ + public class PromptExecutorImpl implements PromptExecutor { + + @HostAccess.Export + public void prompt(String templateId, Object... parameters) { + + JsGraalGraphBuilder.this.addShowPrompt(templateId, parameters); + } + } + private boolean canInfuse(AuthGraphNode executingNode) { return executingNode instanceof DynamicDecisionNode && dynamicallyBuiltBaseNode.get() != null; } + @HostAccess.Export public static void failAsync(Object... parameters) { Map parameterMap; @@ -648,6 +692,18 @@ public static void failAsync(Object... parameters) { } } + /** + * Fail function implementation for GraalJS. + */ + public class FailAuthenticationFunctionImpl implements FailAuthenticationFunction { + + @HostAccess.Export + public void fail(Object... parameters) { + + failAsync(parameters); + } + } + private void removeDefaultFunctions(Context context) throws IOException { context.eval(Source.newBuilder(POLYGLOT_LANGUAGE, REMOVE_FUNCTIONS, POLYGLOT_SOURCE).build()); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java index 0d414ce4d5e3..ef8526a00cec 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java @@ -91,8 +91,10 @@ public static void persistCurrentContext(AuthenticationContext authContext, Cont public Context createEngine(AuthenticationContext authenticationContext) { - Context context = Context.newBuilder(POLYGLOT_LANGUAGE).allowHostAccess(HostAccess.ALL) - .option("engine.WarnInterpreterOnly", "false").build(); + Context context = Context.newBuilder(POLYGLOT_LANGUAGE) + .allowHostAccess(HostAccess.EXPLICIT) + .option("engine.WarnInterpreterOnly", "false") + .build(); Value bindings = context.getBindings(POLYGLOT_LANGUAGE); bindings.putMember(JS_FUNC_SELECT_ACR_FROM, new GraalSelectAcrFromFunction()); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsLogger.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsLogger.java index 5b121e9848fc..609cb0f96b38 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsLogger.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsLogger.java @@ -20,6 +20,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.graalvm.polyglot.HostAccess; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import org.wso2.carbon.identity.central.log.mgt.utils.LoggerUtils; import org.wso2.carbon.utils.DiagnosticLog; @@ -49,6 +50,7 @@ public static JsLogger getInstance() { * * @param values */ + @HostAccess.Export public void log(Object... values) { if (values != null) { @@ -78,6 +80,7 @@ public void log(Object... values) { } } + @HostAccess.Export public void debug(String value) { logger.debug(value); @@ -91,6 +94,7 @@ public void debug(String value) { } } + @HostAccess.Export public void info(String value) { logger.info(value); @@ -104,6 +108,7 @@ public void info(String value) { } } + @HostAccess.Export public void error(String value) { logger.error(value); @@ -117,6 +122,7 @@ public void error(String value) { } } + @HostAccess.Export public void log(String message, Object... values) { } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseAuthenticationContext.java index 4cf97f12587c..7a2f7bf6c789 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseAuthenticationContext.java @@ -18,11 +18,13 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base; +import org.graalvm.polyglot.HostAccess; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; /** * Interface for JavaScript Authentication Context Wrapper. */ +@HostAccess.Implementable public interface JsBaseAuthenticationContext { AuthenticationContext getWrapped(); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java index 58bee07632bc..63e0f22f695a 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java @@ -114,7 +114,6 @@ public boolean hasMember(String name) { return getCurrentSubjectIdentifierStep() != null; default: return super.hasMember(name); - } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java index c847276002b2..1332a9277f89 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java @@ -52,9 +52,9 @@ public void putMember(String claimUri, Value claimValue) { if (authenticatedUser != null) { if (isRemoteClaimRequest) { - setFederatedClaim(claimUri, String.valueOf(claimValue)); + setFederatedClaim(claimUri, claimValue.asString()); } else { - setLocalClaim(claimUri, String.valueOf(claimValue)); + setLocalClaim(claimUri, claimValue.asString()); } } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java index 0a6f3e2a8595..a8c4fd622180 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java @@ -61,7 +61,7 @@ public boolean hasMember(String claimUri) { public void putMember(String claimUri, Value claimValue) { if (authenticatedUser != null) { - setRuntimeClaim(claimUri, String.valueOf(claimValue)); + setRuntimeClaim(claimUri, claimValue.asString()); } } @@ -91,10 +91,9 @@ private boolean hasRuntimeClaim(String claimUri) { private void setRuntimeClaim(String claimUri, String claimValue) { - String claimValueAsString = String.valueOf(claimValue); - if (claimValueAsString == null) { - claimValueAsString = StringUtils.EMPTY; + if (claimValue == null) { + claimValue = StringUtils.EMPTY; } - getContext().addRuntimeClaim(claimUri, claimValueAsString); + getContext().addRuntimeClaim(claimUri, claimValue); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java index 05d241a0f541..b41e15cea832 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java @@ -62,5 +62,4 @@ public boolean hasMember(String name) { return getWrapped().containsKey(name); } - } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java index 49f86555f0c2..67ea4d808306 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraalSelectAcrFromFunction.java @@ -20,6 +20,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.graalvm.polyglot.HostAccess; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; @@ -35,6 +36,7 @@ public class GraalSelectAcrFromFunction implements SelectOneFunction { private static final Log log = LogFactory.getLog(SelectAcrFromFunction.class); + @HostAccess.Export public String evaluate(JsBaseAuthenticationContext context, Object possibleOutcomesObj) { String[] possibleOutcomes = extractPossibleOutcomes(context, possibleOutcomesObj); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java index 87c8326b42d7..dceba157cf46 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java @@ -19,6 +19,7 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js; import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.HostAccess; import org.graalvm.polyglot.Source; import org.graalvm.polyglot.Value; import org.testng.annotations.BeforeClass; @@ -58,7 +59,10 @@ public class JsGraalAuthenticationContextTest { @BeforeClass public void setUp() { - context = Context.newBuilder(POLYGLOT_LANGUAGE).allowAllAccess(true).build(); + context = Context.newBuilder(POLYGLOT_LANGUAGE) + .allowHostAccess(HostAccess.EXPLICIT) + .option("engine.WarnInterpreterOnly", "false") + .build(); } @Test @@ -80,7 +84,8 @@ public void testClaimAssignment() throws IOException { bindings.putMember("context", jsAuthenticationContext); Value result = context.eval( - Source.newBuilder(POLYGLOT_LANGUAGE, "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.1']", + Source.newBuilder(POLYGLOT_LANGUAGE, + "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.1']", POLYGLOT_SOURCE).build()); assertTrue(result.isNull()); @@ -90,9 +95,10 @@ public void testClaimAssignment() throws IOException { POLYGLOT_SOURCE).build()); assertEquals(result.asString(), "TestClaimVal2"); - context.eval(Source.newBuilder(POLYGLOT_LANGUAGE, + context.eval( + Source.newBuilder(POLYGLOT_LANGUAGE, "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.2'] = 'Modified2'", - POLYGLOT_SOURCE).build()); + POLYGLOT_SOURCE).build()); result = context.eval( Source.newBuilder(POLYGLOT_LANGUAGE, "context.steps[1].subject.remoteClaims['Test.Remote.Claim.Url.2']", diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerCustomFunctionsTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerCustomFunctionsTest.java index b719d7067a71..e0a172e8eef5 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerCustomFunctionsTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerCustomFunctionsTest.java @@ -19,6 +19,7 @@ package org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl; import org.apache.commons.lang3.SerializationUtils; +import org.graalvm.polyglot.HostAccess; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; @@ -401,6 +402,7 @@ public String customFunction2(JsBaseAuthenticationContext context, String param1 public class CustomBoolean2Impl implements CustomBoolean2Interface { + @HostAccess.Export public boolean getTrueFunction2(JsBaseAuthenticationContext context, String param1) { return true; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerLongWaitTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerLongWaitTest.java index 01ef15ebb16a..5653aa44b25f 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerLongWaitTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerLongWaitTest.java @@ -18,6 +18,7 @@ package org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl; +import org.graalvm.polyglot.HostAccess; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -117,6 +118,7 @@ void publishEvent(String siddhiAppName, String inStreamName, String outStreamNam public static class AsyncAnalyticsCbFunctionImpl implements Fn1 { + @HostAccess.Export public void publishEvent(String siddhiAppName, String inStreamName, String outStreamName, Map payloadData, Map eventHandlers) { From 013cbe65802928751cf09319cd882325786afc9c Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Tue, 20 Feb 2024 16:09:12 +0530 Subject: [PATCH 18/35] Access JsBaseObject classes from GraalJS --- .../config/model/graph/js/base/JsBaseAuthenticatedUser.java | 2 ++ .../framework/config/model/graph/js/base/JsBaseCookie.java | 3 +++ .../framework/config/model/graph/js/base/JsBaseParameters.java | 3 +++ .../config/model/graph/js/base/JsBaseServletRequest.java | 2 ++ .../config/model/graph/js/base/JsBaseServletResponse.java | 2 ++ 5 files changed, 12 insertions(+) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseAuthenticatedUser.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseAuthenticatedUser.java index f08ca5c56f51..2c56c85960f9 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseAuthenticatedUser.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseAuthenticatedUser.java @@ -18,12 +18,14 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base; +import org.graalvm.polyglot.HostAccess; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; /** * Interface for JavaScript Authenticated User Wrapper. */ +@HostAccess.Implementable public interface JsBaseAuthenticatedUser { /** diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseCookie.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseCookie.java index 64d23123bff7..28e0773eb76d 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseCookie.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseCookie.java @@ -18,6 +18,8 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base; +import org.graalvm.polyglot.HostAccess; + import javax.servlet.http.Cookie; /** @@ -27,6 +29,7 @@ * var commonAuthIdDomain = context.request.cookies.commonAuthId.domain * Also it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime Cookie. */ +@HostAccess.Implementable public interface JsBaseCookie { Cookie getWrapped(); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseParameters.java index 6fb03974a1e0..2d13adcf6197 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseParameters.java @@ -18,6 +18,8 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base; +import org.graalvm.polyglot.HostAccess; + import java.util.Map; /** @@ -26,6 +28,7 @@ * syntax. * Also it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime. */ +@HostAccess.Implementable public interface JsBaseParameters { /** diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseServletRequest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseServletRequest.java index 22216f906bad..b1a5b9690c52 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseServletRequest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseServletRequest.java @@ -18,6 +18,7 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base; +import org.graalvm.polyglot.HostAccess; import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; import javax.servlet.http.HttpServletRequest; @@ -25,6 +26,7 @@ /** * Interface for JavaScript Servlet Request Wrapper. */ +@HostAccess.Implementable public interface JsBaseServletRequest { /** diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseServletResponse.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseServletResponse.java index d4e3c6ceb9a8..dafdb6678524 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseServletResponse.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseServletResponse.java @@ -18,6 +18,7 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base; +import org.graalvm.polyglot.HostAccess; import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; import javax.servlet.http.Cookie; @@ -26,6 +27,7 @@ /** * Interface for JavaScript Servlet Response Wrapper. */ +@HostAccess.Implementable public interface JsBaseServletResponse { /** From 33b06304478c6b12b64d475cf8720b106d64ddc5 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Wed, 21 Feb 2024 09:59:06 +0530 Subject: [PATCH 19/35] Handle guest to host language string conversion in graalJs based script execution --- .../model/graph/js/graaljs/JsGraalAuthenticationContext.java | 3 ++- .../config/model/graph/js/graaljs/JsGraalHeaders.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java index 63e0f22f695a..5fada6808842 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java @@ -121,7 +121,8 @@ public boolean hasMember(String name) { public void putMember(String key, Value value) { if (FrameworkConstants.JSAttributes.JS_SELECTED_ACR.equals(key)) { - getWrapped().setSelectedAcr(String.valueOf(value)); + String valueAsString = value.isString() ? value.asString() : String.valueOf(value); + getWrapped().setSelectedAcr(valueAsString); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java index 69bcdccc4320..cc721934874b 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java @@ -85,7 +85,8 @@ public void putMember(String name, Value value) { if (wrapped != null) { wrapped.put(name, value); //adds a new header to the response. - response.addHeader(name, String.valueOf(value)); + String valueAsString = value.isString() ? value.asString() : String.valueOf(value); + response.addHeader(name, valueAsString); } } } From 1a49d0498ff7b2ef9519803bff6a12be4a667db9 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Wed, 21 Feb 2024 12:09:12 +0530 Subject: [PATCH 20/35] Handle initializing authentication context when graaljs proxy objects are deserialized --- .../model/graph/graaljs/JsGraalGraphBuilderFactory.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java index ef8526a00cec..7f31adcf8a1a 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java @@ -28,6 +28,7 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilder; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsSerializer; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.AbstractJSObjectWrapper; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsLogger; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; @@ -64,6 +65,9 @@ public static void restoreCurrentContext(AuthenticationContext authContext, Cont if (map != null) { for (Map.Entry entry : map.entrySet()) { Object deserializedValue = GraalSerializer.getInstance().fromJsSerializable(entry.getValue(), context); + if (deserializedValue instanceof AbstractJSObjectWrapper) { + ((AbstractJSObjectWrapper) deserializedValue).initializeContext(authContext); + } bindings.putMember(entry.getKey(), deserializedValue); } } From 9be25d509c9238acdd2b97402f9d067ae20520e2 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Wed, 28 Feb 2024 18:08:30 +0530 Subject: [PATCH 21/35] Extract the Javascript Wrapper logic to the parent class only --- .../model/graph/JsWrapperBaseFactory.java | 85 ++++++++++ .../config/model/graph/JsWrapperFactory.java | 64 ++++++++ .../graph/graaljs/JsGraalWrapperFactory.java | 63 +++++++ .../model/graph/js/JsAuthenticatedUser.java | 76 ++++++++- .../graph/js/JsAuthenticationContext.java | 129 ++++++++++++--- .../config/model/graph/js/JsClaims.java | 36 ++-- .../config/model/graph/js/JsCookie.java | 25 +++ .../graph/js/{nashorn => }/JsHeaders.java | 47 +++--- .../config/model/graph/js/JsParameters.java | 13 +- .../model/graph/js/JsRuntimeClaims.java | 95 +++++++++++ .../model/graph/js/JsServletRequest.java | 65 +++++++- .../model/graph/js/JsServletResponse.java | 41 ++++- .../config/model/graph/js/JsStep.java | 155 ++++++++++++++++++ .../config/model/graph/js/JsSteps.java | 103 ++++++++++++ .../model/graph/js/JsWritableParameters.java | 43 +++++ .../model/graph/js/base/JsBaseClaims.java | 34 ++++ .../model/graph/js/base/JsBaseHeaders.java | 26 +++ .../graph/js/base/JsBaseRuntimeClaims.java | 33 ++++ .../model/graph/js/base/JsBaseStep.java | 33 ++++ .../model/graph/js/base/JsBaseSteps.java | 33 ++++ .../js/graaljs/JsGraalAuthenticatedUser.java | 68 +------- .../graaljs/JsGraalAuthenticationContext.java | 107 +----------- .../model/graph/js/graaljs/JsGraalClaims.java | 14 +- .../model/graph/js/graaljs/JsGraalCookie.java | 28 +--- .../graph/js/graaljs/JsGraalHeaders.java | 46 +----- .../graph/js/graaljs/JsGraalParameters.java | 15 +- .../js/graaljs/JsGraalRuntimeClaims.java | 66 ++------ .../js/graaljs/JsGraalServletRequest.java | 64 +------- .../js/graaljs/JsGraalServletResponse.java | 28 +--- .../model/graph/js/graaljs/JsGraalStep.java | 100 +---------- .../model/graph/js/graaljs/JsGraalSteps.java | 63 +------ .../js/graaljs/JsGraalWritableParameters.java | 28 +--- .../nashorn/JsNashornAuthenticatedUser.java | 56 ------- .../JsNashornAuthenticationContext.java | 149 +---------------- .../graph/js/nashorn/JsNashornClaims.java | 111 +------------ .../graph/js/nashorn/JsNashornHeaders.java | 63 +++++++ .../graph/js/nashorn/JsNashornParameters.java | 5 - .../js/nashorn/JsNashornRuntimeClaims.java | 66 +------- .../js/nashorn/JsNashornServletRequest.java | 39 ----- .../js/nashorn/JsNashornServletResponse.java | 22 --- .../model/graph/js/nashorn/JsNashornStep.java | 99 ++--------- .../graph/js/nashorn/JsNashornSteps.java | 60 +------ .../nashorn/JsNashornWritableParameters.java | 14 +- .../JsOpenJdkNashornAuthenticatedUser.java | 56 ------- ...JsOpenJdkNashornAuthenticationContext.java | 148 +---------------- .../nashorn/JsOpenJdkNashornClaims.java | 111 +------------ .../nashorn/JsOpenJdkNashornHeaders.java | 45 ++--- .../nashorn/JsOpenJdkNashornParameters.java | 4 - .../JsOpenJdkNashornRuntimeClaims.java | 67 +------- .../JsOpenJdkNashornServletRequest.java | 39 ----- .../JsOpenJdkNashornServletResponse.java | 23 --- .../openjdk/nashorn/JsOpenJdkNashornStep.java | 99 ++--------- .../nashorn/JsOpenJdkNashornSteps.java | 55 +------ .../JsOpenJdkNashornWritableParameters.java | 15 +- .../JsOpenJdkNashornWrapperFactory.java | 63 +++++++ .../js/JsGraalAuthenticationContextTest.java | 10 +- .../JsNashornAuthenticationContextTest.java | 8 +- 57 files changed, 1424 insertions(+), 1829 deletions(-) rename components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/{nashorn => }/JsHeaders.java (63%) create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsRuntimeClaims.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsStep.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsSteps.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsWritableParameters.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseClaims.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseHeaders.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseRuntimeClaims.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseStep.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseSteps.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornHeaders.java diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperBaseFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperBaseFactory.java index 0a1ff5a0ecb0..6a2c047825f2 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperBaseFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperBaseFactory.java @@ -20,10 +20,15 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseClaims; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseCookie; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseHeaders; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseParameters; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseRuntimeClaims; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseServletRequest; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseServletResponse; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseStep; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseSteps; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; @@ -55,6 +60,17 @@ public interface JsWrapperBaseFactory { JsBaseAuthenticatedUser createJsAuthenticatedUser(AuthenticationContext authenticationContext, AuthenticatedUser authenticatedUser); + /** + * Creates a JavaScript Proxy for authenticated User. + * + * @param context - Represent Authentication Request data from servlet + * @param wrappedUser - Wrapped Authenticated User + * @param step - Represent Authentication Step + * @param idp - Represent Identity Provider + * @return Proxy for authenticated User + */ + JsBaseAuthenticatedUser createJsAuthenticatedUser(AuthenticationContext context, AuthenticatedUser wrappedUser, + int step, String idp); /** * Creates a JavaScript Proxy for authentication Context. @@ -97,4 +113,73 @@ JsBaseAuthenticatedUser createJsAuthenticatedUser(AuthenticationContext authenti * @return Proxy for wrapped Servlet Response */ JsBaseServletResponse createJsServletResponse(TransientObjectWrapper wrapped); + + /** + * Creates a JavaScript Proxy for Claims. + * + * @param context - Represent Authentication Request data from servlet + * @param step - Represent Authentication Step + * @param idp - Represent Identity Provider + * @param isRemoteClaimRequest - Represent Remote Claim Request + * @return Proxy for Claims + */ + JsBaseClaims createJsClaims(AuthenticationContext context, int step, String idp, boolean isRemoteClaimRequest); + + /** + * Creates a JavaScript Proxy for Claims. + * + * @param context - Represent Authentication Request data from servlet + * @param user - Represent Authenticated Subject + * @param isRemoteClaimRequest - Represent Remote Claim Request + * @return Proxy for Claims + */ + JsBaseClaims createJsClaims(AuthenticationContext context, AuthenticatedUser user, boolean isRemoteClaimRequest); + + /** + * Creates a JavaScript Proxy for Runtime Claims. + * + * @param context - Represent Authentication Request data from servlet + * @param step - Represent Authentication Step + * @param idp - Represent Identity Provider + * @return Proxy for Runtime Claims + */ + JsBaseRuntimeClaims createJsRuntimeClaims(AuthenticationContext context, int step, String idp); + + /** + * Creates a JavaScript Proxy for Runtime Claims. + * + * @param context - Represent Authentication Request data from servlet + * @param user - Represent Authenticated Subject + * @return Proxy for Runtime Claims + */ + JsBaseRuntimeClaims createJsRuntimeClaims(AuthenticationContext context, AuthenticatedUser user); + + /** + * Creates a JavaScript Proxy for Step. + * + * @param context - Represent Authentication Request data from servlet + * @param step - Represent Authentication Step + * @param authenticatedIdp - Represent Identity Provider + * @param authenticatedAuthenticator - Represent Authenticator + * @return Proxy for Step + */ + JsBaseStep createJsStep(AuthenticationContext context, int step, String authenticatedIdp, + String authenticatedAuthenticator); + + /** + * Creates a JavaScript Proxy for HTTP Headers. + * + * @param wrapped - HTTP Headers in Servlet Request + * @param response - Wrapped Servlet Response + * @return Proxy for HTTP headers/Cookies in Servlet Request + */ + JsBaseHeaders createJsHeaders(Map wrapped, HttpServletResponse response); + + /** + * Creates a JavaScript Proxy for Steps. + * + * @param context - Represent Authentication Request data from servlet + * @return Proxy for Steps + */ + JsBaseSteps createJsSteps(AuthenticationContext context); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactory.java index 2f8cfb8ab866..972dd71f024a 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactory.java @@ -18,12 +18,23 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseClaims; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseHeaders; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseRuntimeClaims; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseStep; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseSteps; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornAuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornAuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornClaims; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornCookie; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornHeaders; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornParameters; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornRuntimeClaims; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornServletRequest; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornServletResponse; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornStep; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornSteps; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornWritableParameters; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; @@ -52,6 +63,14 @@ public JsNashornAuthenticatedUser createJsAuthenticatedUser(AuthenticationContex return new JsNashornAuthenticatedUser(authenticationContext, authenticatedUser); } + + @Override + public JsBaseAuthenticatedUser createJsAuthenticatedUser(AuthenticationContext context, + AuthenticatedUser wrappedUser, int step, String idp) { + + return new JsNashornAuthenticatedUser(context, wrappedUser, step, idp); + } + @Override public JsNashornAuthenticationContext createJsAuthenticationContext(AuthenticationContext authenticationContext) { @@ -87,4 +106,49 @@ public JsNashornServletResponse createJsServletResponse(TransientObjectWrapper idpAttributesMap = authenticatedUser.getUserAttributes(); Map remoteMapping = FrameworkUtils.getClaimMappings(idpAttributesMap, false); @@ -218,7 +232,7 @@ protected void setLocalMappedClaim(String localClaimURI, String claimValue) { * @param claimUri Local claim URI * @param claimValue Claim value */ - protected void setLocalUserClaim(String claimUri, Object claimValue) { + private void setLocalUserClaim(String claimUri, Object claimValue) { int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); @@ -377,7 +391,7 @@ protected boolean isFederatedIdP() { * @param claimUri Remote claim uri * @param claimValue Claim value */ - protected void setFederatedClaim(String claimUri, String claimValue) { + private void setFederatedClaim(String claimUri, String claimValue) { if (claimValue == null) { claimValue = StringUtils.EMPTY; @@ -410,7 +424,7 @@ private String getLocalMappedClaim(String claimUri) { * @param claimUri Local claim URI * @return Claim value of the given claim URI for the local user if available. Null Otherwise. */ - protected String getLocalUserClaim(String claimUri) { + private String getLocalUserClaim(String claimUri) { int usersTenantId = IdentityTenantUtil.getTenantId(authenticatedUser.getTenantDomain()); RealmService realmService = FrameworkServiceDataHolder.getInstance().getRealmService(); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsCookie.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsCookie.java index 487ce4404b5d..0f145a960e5f 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsCookie.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsCookie.java @@ -18,9 +18,13 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseCookie; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; +import java.util.Arrays; + import javax.servlet.http.Cookie; /** @@ -32,6 +36,8 @@ */ public abstract class JsCookie extends AbstractJSObjectWrapper implements JsBaseCookie { + protected static final Log LOG = LogFactory.getLog(JsCookie.class); + public JsCookie(Cookie cookie) { super(cookie); } @@ -63,6 +69,17 @@ public Object getMember(String name) { } } + public Object getMemberKeys() { + + String[] cookieProperties = new String[]{ + FrameworkConstants.JSAttributes.JS_COOKIE_NAME, FrameworkConstants.JSAttributes.JS_COOKIE_VALUE, + FrameworkConstants.JSAttributes.JS_COOKIE_COMMENT, FrameworkConstants.JSAttributes.JS_COOKIE_DOMAIN, + FrameworkConstants.JSAttributes.JS_COOKIE_MAX_AGE, FrameworkConstants.JSAttributes.JS_COOKIE_PATH, + FrameworkConstants.JSAttributes.JS_COOKIE_SECURE, FrameworkConstants.JSAttributes.JS_COOKIE_VERSION, + FrameworkConstants.JSAttributes.JS_COOKIE_HTTP_ONLY}; + return Arrays.stream(cookieProperties).filter(this::hasMember).toArray(); + } + @Override public boolean hasMember(String name) { @@ -81,8 +98,16 @@ public boolean hasMember(String name) { return getWrapped().getPath() != null; case FrameworkConstants.JSAttributes.JS_COOKIE_VERSION: return getWrapped().getVersion() != 0; + case FrameworkConstants.JSAttributes.JS_COOKIE_SECURE: + case FrameworkConstants.JSAttributes.JS_COOKIE_HTTP_ONLY: + return true; default: return super.hasMember(name); } } + + public void setMember(String name, Object value) { + + LOG.warn("Unsupported operation. Cookie is read only. Can't remove parameter " + name); + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsHeaders.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsHeaders.java similarity index 63% rename from components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsHeaders.java rename to components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsHeaders.java index 2a1803d9fb67..31ff3cbc4397 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsHeaders.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsHeaders.java @@ -1,7 +1,7 @@ /* - * Copyright (c) 2018, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * - * WSO2 Inc. licenses this file to you under the Apache License, + * WSO2 LLC. 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 @@ -16,23 +16,23 @@ * under the License. */ -package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn; +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js; -import jdk.nashorn.api.scripting.AbstractJSObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseHeaders; import java.util.Map; import javax.servlet.http.HttpServletResponse; /** - * Javascript wrapper for Java level HashMap of HTTP headers. + * Abstract Javascript wrapper for Java level HashMap of HTTP headers. * This provides controlled access to HTTPServletResponse object's headers via provided javascript native syntax. * Also it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime. */ -public class JsHeaders extends AbstractJSObject { +public abstract class JsHeaders implements JsBaseHeaders { - private Map wrapped; - private HttpServletResponse response; + private final Map wrapped; + private final HttpServletResponse response; public JsHeaders(Map wrapped, HttpServletResponse response) { @@ -40,17 +40,20 @@ public JsHeaders(Map wrapped, HttpServletResponse response) { this.response = response; } - @Override public Object getMember(String name) { if (wrapped == null) { - return super.getMember(name); + return null; } else { return wrapped.get(name); } } - @Override + public Object getMemberKeys() { + + return wrapped.keySet().toArray(); + } + public boolean hasMember(String name) { if (wrapped == null) { @@ -60,27 +63,23 @@ public boolean hasMember(String name) { } } - @Override - public void removeMember(String name) { + public boolean removeMemberObject(String name) { - if (wrapped == null) { - super.removeMember(name); - } else { - if (wrapped.containsKey(name)) { - wrapped.remove(name); - } + if (wrapped != null) { + wrapped.remove(name); + return true; } + return false; } - @Override - public void setMember(String name, Object value) { + public boolean setMemberObject(String name, Object value) { - if (wrapped == null) { - super.setMember(name, value); - } else { + if (wrapped != null) { wrapped.put(name, value); //adds a new header to the response. response.addHeader(name, String.valueOf(value)); + return true; } + return false; } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java index 20dc3f3b9d31..19d8af198ba0 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java @@ -20,6 +20,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactoryProvider; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseParameters; import java.util.Map; @@ -42,7 +43,17 @@ public JsParameters(Map wrapped) { @Override public Object getMember(String name) { - return getWrapped().get(name); + Object member = getWrapped().get(name); + if (member instanceof Map) { + return JsWrapperFactoryProvider.getInstance().getWrapperFactory() + .createJsWritableParameters((Map) member); + } + return member; + } + + public Object getMemberKeys() { + + return getWrapped().keySet().toArray(); } @Override diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsRuntimeClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsRuntimeClaims.java new file mode 100644 index 000000000000..04fe7640a49e --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsRuntimeClaims.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js; + +import org.apache.commons.lang.StringUtils; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseRuntimeClaims; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; + +/** + * Represent the user's runtime claims. + */ +public abstract class JsRuntimeClaims extends JsClaims implements JsBaseRuntimeClaims { + + public JsRuntimeClaims(AuthenticationContext context, int step, String idp) { + + super(context, step, idp, false); + } + + public JsRuntimeClaims(AuthenticationContext context, AuthenticatedUser user) { + + super(context, user, false); + } + + public Object getMember(String claimUri) { + + if (authenticatedUser != null) { + return getRuntimeClaim(claimUri); + } + return null; + } + + public boolean hasMember(String claimUri) { + + if (authenticatedUser != null) { + return hasRuntimeClaim(claimUri); + } + return false; + } + + public void setMember(String claimUri, Object claimValue) { + + if (authenticatedUser != null) { + setRuntimeClaim(claimUri, claimValue); + } + } + + private Object getRuntimeClaim(String claimUri) { + + String runtimeClaimValue = getContext().getRuntimeClaim(claimUri); + if (runtimeClaimValue != null) { + return runtimeClaimValue; + } + if (isFederatedIdP()) { + return getFederatedClaim(claimUri); + } + return getLocalClaim(claimUri); + } + + private boolean hasRuntimeClaim(String claimUri) { + + String claim = getContext().getRuntimeClaim(claimUri); + if (claim != null) { + return true; + } + if (isFederatedIdP()) { + return hasFederatedClaim(claimUri); + } + return hasLocalClaim(claimUri); + } + + private void setRuntimeClaim(String claimUri, Object claimValue) { + + if (claimValue == null) { + claimValue = StringUtils.EMPTY; + } + getContext().addRuntimeClaim(claimUri, String.valueOf(claimValue)); + } +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletRequest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletRequest.java index 09db927fb3a0..ca85eead3f46 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletRequest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletRequest.java @@ -18,10 +18,20 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactoryProvider; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseServletRequest; import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; +import org.wso2.carbon.identity.core.util.IdentityUtil; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; /** @@ -40,6 +50,9 @@ public abstract class JsServletRequest extends AbstractJSObjectWrapper> implements JsBaseServletRequest { + private static final Log LOG = LogFactory.getLog(JsServletRequest.class); + + public JsServletRequest(TransientObjectWrapper wrapped) { super(wrapped); @@ -54,6 +67,8 @@ public boolean hasMember(String name) { } switch (name) { + case FrameworkConstants.JSAttributes.JS_REQUEST_IP: + return true; case FrameworkConstants.JSAttributes.JS_HEADERS: return getRequest().getHeaderNames() != null; case FrameworkConstants.JSAttributes.JS_PARAMS: @@ -65,7 +80,55 @@ public boolean hasMember(String name) { } } - protected HttpServletRequest getRequest() { + public Object getMemberKeys() { + + String[] servletRequestProperties = + new String[]{FrameworkConstants.JSAttributes.JS_HEADERS, FrameworkConstants.JSAttributes.JS_COOKIES, + FrameworkConstants.JSAttributes.JS_REQUEST_IP, FrameworkConstants.JSAttributes.JS_PARAMS}; + + return Arrays.stream(servletRequestProperties).filter(this::hasMember).toArray(); + } + + public Object getMember(String name) { + + switch (name) { + case FrameworkConstants.JSAttributes.JS_HEADERS: + Map headers = new HashMap(); + Enumeration headerNames = getRequest().getHeaderNames(); + if (headerNames != null) { + while (headerNames.hasMoreElements()) { + String headerName = headerNames.nextElement(); + headers.put(headerName, getRequest().getHeader(headerName)); + } + } + return JsWrapperFactoryProvider.getInstance().getWrapperFactory().createJsWritableParameters(headers); + case FrameworkConstants.JSAttributes.JS_PARAMS: + return JsWrapperFactoryProvider.getInstance().getWrapperFactory() + .createJsParameters(getRequest().getParameterMap()); + case FrameworkConstants.JSAttributes.JS_COOKIES: + Map cookies = new HashMap(); + Cookie[] cookieArr = getRequest().getCookies(); + if (cookieArr != null) { + for (Cookie cookie : cookieArr) { + cookies.put(cookie.getName(), + JsWrapperFactoryProvider.getInstance().getWrapperFactory().createJsCookie(cookie)); + } + } + return JsWrapperFactoryProvider.getInstance().getWrapperFactory().createJsWritableParameters(cookies); + case FrameworkConstants.JSAttributes.JS_REQUEST_IP: + return IdentityUtil.getClientIpAddress(getRequest()); + default: + return super.getMember(name); + } + } + + public void setMember(String name, Object value) { + + LOG.warn("Unsupported operation. Servlet Request is read only. Can't add parameter " + value); + + } + + private HttpServletRequest getRequest() { TransientObjectWrapper transientObjectWrapper = getWrapped(); return transientObjectWrapper.getWrapped(); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletResponse.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletResponse.java index 17b9fda2a82b..0e8cac200252 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletResponse.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletResponse.java @@ -18,10 +18,17 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactoryProvider; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseServletResponse; import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; @@ -41,11 +48,19 @@ public abstract class JsServletResponse extends AbstractJSObjectWrapper> implements JsBaseServletResponse { + private static final Log LOG = LogFactory.getLog(JsServletResponse.class); + + public JsServletResponse(TransientObjectWrapper wrapped) { super(wrapped); } + public Object getMemberKeys() { + + return new String[]{FrameworkConstants.JSAttributes.JS_HEADERS}; + } + @Override public boolean hasMember(String name) { @@ -62,7 +77,31 @@ public boolean hasMember(String name) { } } - protected HttpServletResponse getResponse() { + public Object getMember(String name) { + + switch (name) { + case FrameworkConstants.JSAttributes.JS_HEADERS: + Map headers = new HashMap(); + Collection headerNames = getResponse().getHeaderNames(); + if (headerNames != null) { + for (String element : headerNames) { + headers.put(element, getResponse().getHeader(element)); + } + } + return JsWrapperFactoryProvider.getInstance().getWrapperFactory() + .createJsHeaders(headers, getResponse()); + default: + return super.getMember(name); + } + } + + public void setMember(String name, Object value) { + + LOG.warn("Unsupported operation. Servlet Response is read only. Can't set parameter " + name + " to value: " + + value); + } + + private HttpServletResponse getResponse() { TransientObjectWrapper transientObjectWrapper = getWrapped(); return transientObjectWrapper.getWrapped(); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsStep.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsStep.java new file mode 100644 index 000000000000..b54b8a74c1f0 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsStep.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactoryProvider; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseStep; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalStep; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedIdPData; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/** + * Represents a authentication step. + * This is the abstract wrapper used for all script engine implementations. + */ +public abstract class JsStep extends AbstractJSContextMemberObject implements JsBaseStep { + + private static final Log LOG = LogFactory.getLog(JsGraalStep.class); + + private final int step; + private final String authenticatedIdp; + private String authenticatedAuthenticator; + + @Deprecated + public JsStep(int step, String authenticatedIdp) { + + this.step = step; + this.authenticatedIdp = authenticatedIdp; + } + + public JsStep(int step, String authenticatedIdp, String authenticatedAuthenticator) { + + this.step = step; + this.authenticatedIdp = authenticatedIdp; + this.authenticatedAuthenticator = authenticatedAuthenticator; + } + + @Deprecated + public JsStep(AuthenticationContext context, int step, String authenticatedIdp) { + + this(step, authenticatedIdp, null); + initializeContext(context); + } + + public JsStep(AuthenticationContext context, int step, String authenticatedIdp, + String authenticatedAuthenticator) { + + this(step, authenticatedIdp, authenticatedAuthenticator); + initializeContext(context); + } + + public Object getMember(String name) { + + switch (name) { + case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT: + return JsWrapperFactoryProvider.getInstance().getWrapperFactory() + .createJsAuthenticatedUser(getContext(), getSubject(), step, authenticatedIdp); + case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP: + return authenticatedIdp; + case FrameworkConstants.JSAttributes.JS_AUTHENTICATOR: + return authenticatedAuthenticator; + case FrameworkConstants.JSAttributes.JS_AUTHENTICATION_OPTIONS: + return getOptions(); + default: + return null; + } + } + + public Object getMemberKeys() { + + return new String[]{FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT, + FrameworkConstants.JSAttributes.JS_AUTHENTICATION_OPTIONS, + FrameworkConstants.JSAttributes.JS_AUTHENTICATOR, + FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP}; + } + + public boolean hasMember(String name) { + + switch (name) { + case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT: + case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP: + case FrameworkConstants.JSAttributes.JS_AUTHENTICATOR: + case FrameworkConstants.JSAttributes.JS_AUTHENTICATION_OPTIONS: + return true; + default: + return false; + } + } + + public void removeMemberObject(String name) { + + LOG.warn("Step is readonly, hence the can't remove the member."); + } + + public void setMember(String name, Object value) { + + LOG.warn("Step is readonly, hence the setter is ignored."); + } + + private AuthenticatedUser getSubject() { + + if (authenticatedIdp != null) { + AuthenticatedIdPData idPData = getContext().getCurrentAuthenticatedIdPs().get(authenticatedIdp); + if (idPData == null) { + idPData = getContext().getPreviousAuthenticatedIdPs().get(authenticatedIdp); + } + if (idPData != null) { + return idPData.getUser(); + } + } + return null; + } + + private List> getOptions() { + + List> optionsList = new ArrayList<>(); + Optional optionalStepConfig = getContext().getSequenceConfig().getStepMap().values().stream() + .filter(stepConfig -> stepConfig.getOrder() == step).findFirst(); + optionalStepConfig.ifPresent(stepConfig -> stepConfig.getAuthenticatorList().forEach( + authConfig -> authConfig.getIdpNames().forEach(name -> { + Map option = new HashMap<>(); + option.put(FrameworkConstants.JSAttributes.IDP, name); + option.put(FrameworkConstants.JSAttributes.AUTHENTICATOR, authConfig.getApplicationAuthenticator() + .getName()); + optionsList.add(option); + }))); + return optionsList; + } +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsSteps.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsSteps.java new file mode 100644 index 000000000000..64a741a40c3f --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsSteps.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js; + +import org.wso2.carbon.identity.application.authentication.framework.config.model.AuthenticatorConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactoryProvider; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseSteps; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; + +import java.util.Optional; + +/** + * Returns when context.steps[ optionalStepConfig = getContext().getSequenceConfig().getStepMap().values().stream() + .filter(stepConfig -> stepConfig.getOrder() == step).findFirst(); + return optionalStepConfig.map(StepConfig::getAuthenticatedIdP).orElse(null); + } + + private String getAuthenticatedAuthenticatorOfStep(int step) { + + if (getContext().getSequenceConfig() == null) { + // Sequence config is not yet initialized. + return null; + } + + Optional optionalStepConfig = getContext().getSequenceConfig().getStepMap().values().stream() + .filter(stepConfig -> stepConfig.getOrder() == step).findFirst(); + AuthenticatorConfig authenticatorConfig = optionalStepConfig.map(StepConfig::getAuthenticatedAutenticator) + .orElse(null); + return authenticatorConfig != null ? authenticatorConfig.getName() : null; + } +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsWritableParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsWritableParameters.java new file mode 100644 index 000000000000..883cd578ac61 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsWritableParameters.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js; + +import java.util.Map; + +/** + * Parameters that can be modified from the authentication script. + * This is the abstract wrapper used for all script engine implementations. + */ +public abstract class JsWritableParameters extends JsParameters { + + public JsWritableParameters(Map wrapped) { + + super(wrapped); + } + + public void removeMemberObject(String name) { + + getWrapped().remove(name); + } + + public void setMember(String name, Object value) { + + getWrapped().put(name, value); + } +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseClaims.java new file mode 100644 index 000000000000..2568ce9a6e85 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseClaims.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base; + +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; + +/** + * Interface for Javascript wrapper for Java level Claims. + * This provides controlled access to Claims List via provided javascript native syntax. + */ +public interface JsBaseClaims { + + /** + * Get the Authentication Context. + * @return Authentication Context. + */ + AuthenticationContext getContext(); +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseHeaders.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseHeaders.java new file mode 100644 index 000000000000..ae6f890805b3 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseHeaders.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base; + +/** + * Interface for Javascript wrapper for Java level HashMap of HTTP headers. + */ +public interface JsBaseHeaders { + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseRuntimeClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseRuntimeClaims.java new file mode 100644 index 000000000000..50373754850a --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseRuntimeClaims.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base; + +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; + +/** + * Interface to represent the user's runtime claims in javascript. + */ +public interface JsBaseRuntimeClaims { + + /** + * Get the Authentication Context. + * @return Authentication Context. + */ + AuthenticationContext getContext(); +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseStep.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseStep.java new file mode 100644 index 000000000000..93879f8d926c --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseStep.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base; + +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; + +/** + * Interface for Javascript wrapper for Java level step. + */ +public interface JsBaseStep { + + /** + * Get the Authentication Context. + * @return Authentication Context. + */ + AuthenticationContext getContext(); +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseSteps.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseSteps.java new file mode 100644 index 000000000000..3e401776b410 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseSteps.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base; + +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; + +/** + * Interface for Javascript wrapper for Java level step. + */ +public interface JsBaseSteps { + + /** + * Get the Authentication Context. + * @return Authentication Context. + */ + AuthenticationContext getContext(); +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java index aaf50a351ec5..055bf0330f88 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java @@ -18,14 +18,12 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; -import org.apache.commons.lang.StringUtils; import org.graalvm.polyglot.Value; import org.graalvm.polyglot.proxy.ProxyArray; import org.graalvm.polyglot.proxy.ProxyObject; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; /** * Javascript wrapper for Java level AuthenticatedUser. @@ -60,76 +58,16 @@ public JsGraalAuthenticatedUser(AuthenticationContext context, AuthenticatedUser super(context, wrappedUser); } - @Override - public Object getMember(String name) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT_IDENTIFIER: - return getWrapped().getAuthenticatedSubjectIdentifier(); - case FrameworkConstants.JSAttributes.JS_USERNAME: - return getWrapped().getUserName(); - case FrameworkConstants.JSAttributes.JS_USER_STORE_DOMAIN: - return getWrapped().getUserStoreDomain(); - case FrameworkConstants.JSAttributes.JS_TENANT_DOMAIN: - return getWrapped().getTenantDomain(); - case FrameworkConstants.JSAttributes.JS_LOCAL_CLAIMS: - if (StringUtils.isNotBlank(idp)) { - return new JsGraalClaims(getContext(), step, idp, false); - } else { - // Represent step independent user - return new JsGraalClaims(getContext(), getWrapped(), false); - } - case FrameworkConstants.JSAttributes.JS_REMOTE_CLAIMS: - if (StringUtils.isNotBlank(idp)) { - return new JsGraalClaims(getContext(), step, idp, true); - } else { - // Represent step independent user - return new JsGraalClaims(getContext(), getWrapped(), true); - } - case FrameworkConstants.JSAttributes.JS_LOCAL_ROLES: - return getLocalRoles(); - case FrameworkConstants.JSAttributes.JS_CLAIMS: - if (StringUtils.isNotBlank(idp)) { - return new JsGraalRuntimeClaims(getContext(), step, idp); - } else { - // Represent step independent user - return new JsGraalRuntimeClaims(getContext(), getWrapped()); - } - default: - return super.getMember(name); - } - } - @Override public Object getMemberKeys() { - return ProxyArray.fromArray( - FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT_IDENTIFIER, - FrameworkConstants.JSAttributes.JS_USERNAME, - FrameworkConstants.JSAttributes.JS_USER_STORE_DOMAIN, - FrameworkConstants.JSAttributes.JS_TENANT_DOMAIN, - FrameworkConstants.JSAttributes.JS_LOCAL_CLAIMS, - FrameworkConstants.JSAttributes.JS_REMOTE_CLAIMS, - FrameworkConstants.JSAttributes.JS_LOCAL_ROLES, - FrameworkConstants.JSAttributes.JS_CLAIMS); + return ProxyArray.fromArray(super.getMemberKeys()); } public void putMember(String name, Value value) { - setMember(name, value.asString()); - } - - @Override - public boolean hasMember(String name) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_LOCAL_CLAIMS: - case FrameworkConstants.JSAttributes.JS_REMOTE_CLAIMS: - case FrameworkConstants.JSAttributes.JS_CLAIMS: - return true; - default: - return super.hasMember(name); - } + String valueAsString = value.isString() ? value.asString() : String.valueOf(value); + setMember(name, valueAsString); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java index 5fada6808842..0556fec04b4d 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java @@ -21,12 +21,8 @@ import org.graalvm.polyglot.Value; import org.graalvm.polyglot.proxy.ProxyArray; import org.graalvm.polyglot.proxy.ProxyObject; -import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; -import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; /** * Javascript wrapper for Java level AuthenticationContext. @@ -50,117 +46,22 @@ public JsGraalAuthenticationContext(AuthenticationContext wrapped) { super(wrapped); } - @Override - public Object getMember(String name) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_REQUESTED_ACR: - return getWrapped().getRequestedAcr(); - case FrameworkConstants.JSAttributes.JS_TENANT_DOMAIN: - return getWrapped().getTenantDomain(); - case FrameworkConstants.JSAttributes.JS_SERVICE_PROVIDER_NAME: - return getWrapped().getServiceProviderName(); - case FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER: - return getLastLoginFailedUserFromWrappedContext(); - case FrameworkConstants.JSAttributes.JS_REQUEST: - return new JsGraalServletRequest((TransientObjectWrapper) getWrapped().getParameter( - FrameworkConstants.RequestAttribute.HTTP_REQUEST)); - case FrameworkConstants.JSAttributes.JS_RESPONSE: - return new JsGraalServletResponse((TransientObjectWrapper) getWrapped().getParameter( - FrameworkConstants.RequestAttribute.HTTP_RESPONSE)); - case FrameworkConstants.JSAttributes.JS_STEPS: - return new JsGraalSteps(getWrapped()); - case FrameworkConstants.JSAttributes.JS_CURRENT_STEP: - return new JsGraalStep(getContext(), getContext().getCurrentStep(), getAuthenticatedIdPOfCurrentStep(), - getAuthenticatedAuthenticatorOfCurrentStep()); - case FrameworkConstants.JSAttributes.JS_CURRENT_KNOWN_SUBJECT: - StepConfig stepConfig = getCurrentSubjectIdentifierStep(); - if (stepConfig != null) { - return new JsGraalAuthenticatedUser(this.getContext(), stepConfig.getAuthenticatedUser(), - stepConfig.getOrder(), stepConfig.getAuthenticatedIdP()); - } else { - return null; - } - case FrameworkConstants.JSAttributes.JS_RETRY_STEP: - return getWrapped().isRetrying(); - } - return super.getMember(name); - } - @Override public Object getMemberKeys() { - return ProxyArray.fromArray( - FrameworkConstants.JSAttributes.JS_REQUESTED_ACR, - FrameworkConstants.JSAttributes.JS_TENANT_DOMAIN, - FrameworkConstants.JSAttributes.JS_SERVICE_PROVIDER_NAME, - FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER, - FrameworkConstants.JSAttributes.JS_REQUEST, - FrameworkConstants.JSAttributes.JS_RESPONSE, - FrameworkConstants.JSAttributes.JS_STEPS, - FrameworkConstants.JSAttributes.JS_CURRENT_STEP, - FrameworkConstants.JSAttributes.JS_CURRENT_KNOWN_SUBJECT, - FrameworkConstants.JSAttributes.JS_RETRY_STEP); - } - - @Override - public boolean hasMember(String name) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_CURRENT_STEP: - case FrameworkConstants.JSAttributes.JS_RETRY_STEP: - return true; - case FrameworkConstants.JSAttributes.JS_CURRENT_KNOWN_SUBJECT: - return getCurrentSubjectIdentifierStep() != null; - default: - return super.hasMember(name); - } + return ProxyArray.fromArray(super.getMemberKeys()); } @Override public void putMember(String key, Value value) { - if (FrameworkConstants.JSAttributes.JS_SELECTED_ACR.equals(key)) { - String valueAsString = value.isString() ? value.asString() : String.valueOf(value); - getWrapped().setSelectedAcr(valueAsString); - } + String valueAsString = value.isString() ? value.asString() : String.valueOf(value); + super.setMemberObject(key, valueAsString); } @Override public boolean removeMember(String name) { - if (FrameworkConstants.JSAttributes.JS_SELECTED_ACR.equals(name)) { - getWrapped().setSelectedAcr(null); - return true; - } - return false; + return super.removeMemberObject(name); } - - private JsGraalAuthenticatedUser getLastLoginFailedUserFromWrappedContext() { - - Object lastLoginFailedUser = - getWrapped().getProperty(FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER); - if (lastLoginFailedUser instanceof AuthenticatedUser) { - return new JsGraalAuthenticatedUser(getWrapped(), (AuthenticatedUser) lastLoginFailedUser); - } else { - return null; - } - } - - protected String getAuthenticatedAuthenticatorOfCurrentStep() { - - if (getContext().getSequenceConfig() == null) { - //Sequence config is not yet initialized - return null; - } - - StepConfig stepConfig = getContext().getSequenceConfig().getStepMap() - .get(getContext().getCurrentStep()); - if (stepConfig != null) { - return stepConfig.getAuthenticatedAutenticator().getName(); - } - return null; - - } - } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java index 1332a9277f89..7919f375c136 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java @@ -48,15 +48,9 @@ public Object getMemberKeys() { } @Override - public void putMember(String claimUri, Value claimValue) { - - if (authenticatedUser != null) { - if (isRemoteClaimRequest) { - setFederatedClaim(claimUri, claimValue.asString()); - } else { - setLocalClaim(claimUri, claimValue.asString()); - } - } - } + public void putMember(String claimUri, Value value) { + String valueAsString = value.isString() ? value.asString() : String.valueOf(value); + setMemberObject(claimUri, valueAsString); + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java index 3fe279b0953a..a0cbecbfce5e 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java @@ -18,15 +18,10 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.graalvm.polyglot.Value; import org.graalvm.polyglot.proxy.ProxyArray; import org.graalvm.polyglot.proxy.ProxyObject; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsCookie; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; - -import java.util.Arrays; import javax.servlet.http.Cookie; @@ -40,8 +35,6 @@ */ public class JsGraalCookie extends JsCookie implements ProxyObject { - protected static final Log LOG = LogFactory.getLog(JsGraalCookie.class); - public JsGraalCookie(Cookie cookie) { super(cookie); @@ -50,27 +43,12 @@ public JsGraalCookie(Cookie cookie) { @Override public Object getMemberKeys() { - String[] cookieProperties = new String[]{FrameworkConstants.JSAttributes.JS_COOKIE_NAME, - FrameworkConstants.JSAttributes.JS_COOKIE_VALUE, FrameworkConstants.JSAttributes.JS_COOKIE_COMMENT, - FrameworkConstants.JSAttributes.JS_COOKIE_DOMAIN, FrameworkConstants.JSAttributes.JS_COOKIE_MAX_AGE, - FrameworkConstants.JSAttributes.JS_COOKIE_PATH, FrameworkConstants.JSAttributes.JS_COOKIE_SECURE, - FrameworkConstants.JSAttributes.JS_COOKIE_VERSION, FrameworkConstants.JSAttributes.JS_COOKIE_HTTP_ONLY}; - return ProxyArray.fromArray(Arrays.stream(cookieProperties).filter(this::hasMember).toArray()); - } - - @Override - public boolean hasMember(String name) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_COOKIE_SECURE: - case FrameworkConstants.JSAttributes.JS_COOKIE_HTTP_ONLY: - return true; - } - return super.hasMember(name); + return ProxyArray.fromArray(super.getMemberKeys()); } public void putMember(String key, Value value) { - LOG.warn("Unsupported operation. Cookie is read only. Can't remove parameter " + key); + String valueAsString = value.isString() ? value.asString() : String.valueOf(value); + super.setMember(key, valueAsString); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java index cc721934874b..fdbf6c1ac2cb 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java @@ -21,6 +21,7 @@ import org.graalvm.polyglot.Value; import org.graalvm.polyglot.proxy.ProxyArray; import org.graalvm.polyglot.proxy.ProxyObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsHeaders; import java.util.Map; @@ -31,62 +32,29 @@ * This provides controlled access to HTTPServletResponse object's headers via provided javascript native syntax. * Also, it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime. */ -public class JsGraalHeaders implements ProxyObject { - - private final Map wrapped; - private final HttpServletResponse response; +public class JsGraalHeaders extends JsHeaders implements ProxyObject { public JsGraalHeaders(Map wrapped, HttpServletResponse response) { - this.wrapped = wrapped; - this.response = response; - } - - @Override - public Object getMember(String name) { - - if (wrapped == null) { - return null; - } else { - return wrapped.get(name); - } + super(wrapped, response); } @Override public Object getMemberKeys() { - return ProxyArray.fromArray(wrapped.keySet().toArray()); - } - - @Override - public boolean hasMember(String name) { - - if (wrapped == null) { - return false; - } else { - return wrapped.get(name) != null; - } + return ProxyArray.fromArray(super.getMemberKeys()); } @Override public boolean removeMember(String name) { - if (wrapped == null) { - return false; - } else { - wrapped.remove(name); - } - return false; + return super.removeMemberObject(name); } @Override public void putMember(String name, Value value) { - if (wrapped != null) { - wrapped.put(name, value); - //adds a new header to the response. - String valueAsString = value.isString() ? value.asString() : String.valueOf(value); - response.addHeader(name, valueAsString); - } + String valueAsString = value.isString() ? value.asString() : String.valueOf(value); + super.setMemberObject(name, valueAsString); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java index 680faae7377b..9811ced1aba3 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java @@ -39,25 +39,16 @@ public JsGraalParameters(Map wrapped) { super(wrapped); } - @Override - public Object getMember(String name) { - - Object member = getWrapped().get(name); - if (member instanceof Map) { - return new JsGraalParameters((Map) member); - } - return member; - } - @Override public Object getMemberKeys() { - return ProxyArray.fromArray(getWrapped().keySet().toArray()); + return ProxyArray.fromArray(super.getMemberKeys()); } public void putMember(String key, Value value) { - LOG.warn("Unsupported operation. Parameters are read only. Can't set parameter " + key + " to value: " + value); + String valueAsString = value.isString() ? value.asString() : String.valueOf(value); + super.setMember(key, valueAsString); } @Override diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java index a8c4fd622180..9c63de89f9f6 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -18,82 +18,38 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; -import org.apache.commons.lang.StringUtils; import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyArray; import org.graalvm.polyglot.proxy.ProxyObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsRuntimeClaims; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; /** * Represent the user's runtime claims for GraalJs Execution. */ -public class JsGraalRuntimeClaims extends JsGraalClaims implements ProxyObject { +public class JsGraalRuntimeClaims extends JsRuntimeClaims implements ProxyObject { public JsGraalRuntimeClaims(AuthenticationContext context, int step, String idp) { - super(context, step, idp, false); + super(context, step, idp); } public JsGraalRuntimeClaims(AuthenticationContext context, AuthenticatedUser user) { - super(context, user, false); + super(context, user); } @Override - public Object getMember(String claimUri) { + public Object getMemberKeys() { - if (authenticatedUser != null) { - return getRuntimeClaim(claimUri); - } - return null; + return ProxyArray.fromArray(); } @Override - public boolean hasMember(String claimUri) { + public void putMember(String claimUri, Value value) { - if (authenticatedUser != null) { - return hasRuntimeClaim(claimUri); - } - return false; - } - - @Override - public void putMember(String claimUri, Value claimValue) { - - if (authenticatedUser != null) { - setRuntimeClaim(claimUri, claimValue.asString()); - } - } - - private Object getRuntimeClaim(String claimUri) { - - String runtimeClaimValue = getContext().getRuntimeClaim(claimUri); - if (runtimeClaimValue != null) { - return runtimeClaimValue; - } - if (isFederatedIdP()) { - return getFederatedClaim(claimUri); - } - return getLocalClaim(claimUri); - } - - private boolean hasRuntimeClaim(String claimUri) { - - String claim = getContext().getRuntimeClaim(claimUri); - if (claim != null) { - return true; - } - if (isFederatedIdP()) { - return hasFederatedClaim(claimUri); - } - return hasLocalClaim(claimUri); - } - - private void setRuntimeClaim(String claimUri, String claimValue) { - - if (claimValue == null) { - claimValue = StringUtils.EMPTY; - } - getContext().addRuntimeClaim(claimUri, claimValue); + String valueAsString = value.isString() ? value.asString() : String.valueOf(value); + setMember(claimUri, valueAsString); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java index db39a6938484..fa0bc8e7accb 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java @@ -25,15 +25,7 @@ import org.graalvm.polyglot.proxy.ProxyObject; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsServletRequest; import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; -import org.wso2.carbon.identity.core.util.IdentityUtil; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; /** @@ -58,66 +50,17 @@ public JsGraalServletRequest(TransientObjectWrapper wrapped) super(wrapped); } - @Override - public Object getMember(String name) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_HEADERS: - Map headers = new HashMap(); - Enumeration headerNames = getRequest().getHeaderNames(); - if (headerNames != null) { - while (headerNames.hasMoreElements()) { - String headerName = headerNames.nextElement(); - headers.put(headerName, getRequest().getHeader(headerName)); - } - } - return new JsGraalWritableParameters(headers); - case FrameworkConstants.JSAttributes.JS_PARAMS: - return new JsGraalParameters(getRequest().getParameterMap()); - case FrameworkConstants.JSAttributes.JS_COOKIES: - Map cookies = new HashMap(); - Cookie[] cookieArr = getRequest().getCookies(); - if (cookieArr != null) { - for (Cookie cookie : cookieArr) { - cookies.put(cookie.getName(), new JsGraalCookie(cookie)); - } - } - return new JsGraalWritableParameters(cookies); - case FrameworkConstants.JSAttributes.JS_REQUEST_IP: - return IdentityUtil.getClientIpAddress(getRequest()); - default: - return super.getMember(name); - } - } - @Override public Object getMemberKeys() { - String[] servletRequestProperties = - new String[]{FrameworkConstants.JSAttributes.JS_HEADERS, FrameworkConstants.JSAttributes.JS_COOKIES, - FrameworkConstants.JSAttributes.JS_REQUEST_IP, FrameworkConstants.JSAttributes.JS_PARAMS}; - - return ProxyArray.fromArray(Arrays.stream(servletRequestProperties).filter(this::hasMember).toArray()); - } - - @Override - public boolean hasMember(String name) { - - if (getRequest() == null) { - //Transient Object is null, hence no member access is possible. - return false; - } - - if (name.equals(FrameworkConstants.JSAttributes.JS_REQUEST_IP)) { - return true; - } - return super.hasMember(name); + return ProxyArray.fromArray(super.getMemberKeys()); } @Override public void putMember(String key, Value value) { - LOG.warn("Unsupported operation. Servlet Request is read only. Can't remove parameter " + key); + String valueAsString = value.isString() ? value.asString() : String.valueOf(value); + super.setMember(key, valueAsString); } @Override @@ -125,5 +68,4 @@ public boolean removeMember(String key) { return false; } - } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java index a4c27277596d..deec431268bb 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java @@ -25,11 +25,6 @@ import org.graalvm.polyglot.proxy.ProxyObject; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsServletResponse; import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; import javax.servlet.http.HttpServletResponse; @@ -55,33 +50,16 @@ public JsGraalServletResponse(TransientObjectWrapper wrappe super(wrapped); } - @Override - public Object getMember(String name) { - - if (FrameworkConstants.JSAttributes.JS_HEADERS.equals(name)) { - Map headers = new HashMap<>(); - Collection headerNames = getResponse().getHeaderNames(); - if (headerNames != null) { - for (String element : headerNames) { - headers.put(element, getResponse().getHeader(element)); - } - } - return new JsGraalHeaders(headers, getResponse()); - } - return super.getMember(name); - } - @Override public Object getMemberKeys() { - return ProxyArray.fromArray(FrameworkConstants.JSAttributes.JS_HEADERS); + return ProxyArray.fromArray(super.getMemberKeys()); } @Override public void putMember(String key, Value value) { - log.warn("Unsupported operation. Servlet Response is read only. Can't set parameter " + key + " to value: " + - value); + String valueAsString = value.isString() ? value.asString() : String.valueOf(value); + super.setMember(key, valueAsString); } - } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java index b64d1f1d4fae..b0b02362e685 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java @@ -18,129 +18,45 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.graalvm.polyglot.Value; import org.graalvm.polyglot.proxy.ProxyArray; import org.graalvm.polyglot.proxy.ProxyObject; -import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.AbstractJSContextMemberObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsStep; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedIdPData; -import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; /** * Represents a authentication step. * This wrapper uses GraalJS polyglot context. */ -public class JsGraalStep extends AbstractJSContextMemberObject implements ProxyObject { - - private static final Log LOG = LogFactory.getLog(JsGraalStep.class); - - private final int step; - private final String authenticatedIdp; - private final String authenticatedAuthenticator; +public class JsGraalStep extends JsStep implements ProxyObject { public JsGraalStep(int step, String authenticatedIdp, String authenticatedAuthenticator) { - this.step = step; - this.authenticatedIdp = authenticatedIdp; - this.authenticatedAuthenticator = authenticatedAuthenticator; + super(step, authenticatedIdp, authenticatedAuthenticator); } public JsGraalStep(AuthenticationContext context, int step, String authenticatedIdp, String authenticatedAuthenticator) { - this(step, authenticatedIdp, authenticatedAuthenticator); - initializeContext(context); - } - - @Override - public Object getMember(String name) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT: - return new JsGraalAuthenticatedUser(getContext(), getSubject(), step, authenticatedIdp); - case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP: - return authenticatedIdp; - case FrameworkConstants.JSAttributes.JS_AUTHENTICATOR: - return authenticatedAuthenticator; - case FrameworkConstants.JSAttributes.JS_AUTHENTICATION_OPTIONS: - return getOptions(); - default: - return null; - } + super(context, step, authenticatedIdp, authenticatedAuthenticator); } @Override public Object getMemberKeys() { - return ProxyArray.fromArray(FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT, - FrameworkConstants.JSAttributes.JS_AUTHENTICATION_OPTIONS, - FrameworkConstants.JSAttributes.JS_AUTHENTICATOR, - FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP); + return ProxyArray.fromArray(super.getMemberKeys()); } @Override public void putMember(String key, Value value) { - LOG.warn("Step is readonly, hence the put member is ignored."); + super.setMember(key, value); } @Override public boolean removeMember(String name) { - LOG.warn("Step is readonly, hence the can't remove the member."); - return false; - } - - public boolean hasMember(String name) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT: - case FrameworkConstants.JSAttributes.JS_AUTHENTICATION_OPTIONS: - case FrameworkConstants.JSAttributes.JS_AUTHENTICATOR: - case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP: - return true; - default: - return super.hasMember(name); - } - } - - protected AuthenticatedUser getSubject() { - - if (authenticatedIdp != null) { - AuthenticatedIdPData idPData = getContext().getCurrentAuthenticatedIdPs().get(authenticatedIdp); - if (idPData == null) { - idPData = getContext().getPreviousAuthenticatedIdPs().get(authenticatedIdp); - } - if (idPData != null) { - return idPData.getUser(); - } - } - return null; - } - - protected List> getOptions() { - - List> optionsList = new ArrayList<>(); - Optional optionalStepConfig = getContext().getSequenceConfig().getStepMap().values().stream() - .filter(stepConfig -> stepConfig.getOrder() == step).findFirst(); - optionalStepConfig.ifPresent(stepConfig -> stepConfig.getAuthenticatorList() - .forEach(authConfig -> authConfig.getIdpNames().forEach(name -> { - Map option = new HashMap<>(); - option.put(FrameworkConstants.JSAttributes.IDP, name); - option.put(FrameworkConstants.JSAttributes.AUTHENTICATOR, - authConfig.getApplicationAuthenticator().getName()); - optionsList.add(option); - }))); - return optionsList; + super.removeMemberObject(name); + return true; } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java index e0084e280d51..5ccbfd411d88 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java @@ -18,84 +18,29 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.graalvm.polyglot.Value; import org.graalvm.polyglot.proxy.ProxyArray; -import org.wso2.carbon.identity.application.authentication.framework.config.model.AuthenticatorConfig; -import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.AbstractJSContextMemberObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsSteps; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import java.util.Optional; - /** * Returns when context.steps[ optionalStepConfig = getContext().getSequenceConfig().getStepMap().values().stream() - .filter(stepConfig -> stepConfig.getOrder() == step).findFirst(); - return optionalStepConfig.map(StepConfig::getAuthenticatedIdP).orElse(null); - } - - @Override - public Object get(long index) { - - if (getContext() == null) { - return null; - } else { - return new JsGraalStep(getContext(), (int) index, getAuthenticatedIdPOfStep((int) index), - getAuthenticatedAuthenticatorOfStep((int) index)); - } + super(context); } @Override public void set(long index, Value value) { //Steps can not be set with script. } - - @Override - public long getSize() { - - if (getContext() == null) { - return 0; - } else { - return getContext().getSequenceConfig().getStepMap().size(); - } - } - - private String getAuthenticatedAuthenticatorOfStep(int step) { - - if (getContext().getSequenceConfig() == null) { - //Sequence config is not yet initialized. - return null; - } - - Optional optionalStepConfig = getContext().getSequenceConfig().getStepMap().values().stream() - .filter(stepConfig -> stepConfig.getOrder() == step).findFirst(); - AuthenticatorConfig authenticatorConfig = - optionalStepConfig.map(StepConfig::getAuthenticatedAutenticator).orElse(null); - return authenticatorConfig != null ? authenticatorConfig.getName() : null; - } - } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java index b41e15cea832..32709f29598e 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java @@ -19,6 +19,8 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs; import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsWritableParameters; import java.util.List; import java.util.Map; @@ -27,39 +29,21 @@ * Parameters that can be modified from the authentication script. * This wrapper uses GraalJS polyglot context. */ -public class JsGraalWritableParameters extends JsGraalParameters { +public class JsGraalWritableParameters extends JsWritableParameters implements ProxyObject { public JsGraalWritableParameters(Map wrapped) { super(wrapped); } - @Override - public Object getMember(String name) { - - Object member = getWrapped().get(name); - if (member instanceof Map) { - return new JsGraalWritableParameters((Map) member); - } - return member; - } - - @Override public boolean removeMember(String name) { - getWrapped().remove(name); - return false; + super.removeMemberObject(name); + return true; } - @Override public void putMember(String key, Value value) { - getWrapped().put(key, value.as(List.class)); - } - - @Override - public boolean hasMember(String name) { - - return getWrapped().containsKey(name); + super.setMember(key, value.as(List.class)); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticatedUser.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticatedUser.java index 1f6a405114db..cd2f3f4ded2a 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticatedUser.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticatedUser.java @@ -18,15 +18,9 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; /** * Javascript wrapper for Java level AuthenticatedUser. @@ -45,8 +39,6 @@ */ public class JsNashornAuthenticatedUser extends JsAuthenticatedUser implements AbstractJsObject { - private static final Log LOG = LogFactory.getLog(JsNashornAuthenticatedUser.class); - /** * Constructor to be used when required to access step specific user details. * @@ -87,52 +79,4 @@ public JsNashornAuthenticatedUser(AuthenticationContext context, AuthenticatedUs super(context, wrappedUser); } - - @Override - public Object getMember(String name) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT_IDENTIFIER: - return getWrapped().getAuthenticatedSubjectIdentifier(); - case FrameworkConstants.JSAttributes.JS_USERNAME: - return getWrapped().getUserName(); - case FrameworkConstants.JSAttributes.JS_UNIQUE_ID: - Object userId = null; - try { - userId = getWrapped().getUserId(); - } catch (UserIdNotFoundException e) { - LOG.error("Error while retrieving user Id of user : " + getWrapped().getLoggableUserId(), e); - } - return userId; - case FrameworkConstants.JSAttributes.JS_USER_STORE_DOMAIN: - return getWrapped().getUserStoreDomain(); - case FrameworkConstants.JSAttributes.JS_TENANT_DOMAIN: - return getWrapped().getTenantDomain(); - case FrameworkConstants.JSAttributes.JS_LOCAL_CLAIMS: - if (StringUtils.isNotBlank(idp)) { - return new JsNashornClaims(getContext(), step, idp, false); - } else { - // Represent step independent user - return new JsNashornClaims(getContext(), getWrapped(), false); - } - case FrameworkConstants.JSAttributes.JS_REMOTE_CLAIMS: - if (StringUtils.isNotBlank(idp)) { - return new JsNashornClaims(getContext(), step, idp, true); - } else { - // Represent step independent user - return new JsNashornClaims(getContext(), getWrapped(), true); - } - case FrameworkConstants.JSAttributes.JS_LOCAL_ROLES: - return getLocalRoles(); - case FrameworkConstants.JSAttributes.JS_CLAIMS: - if (StringUtils.isNotBlank(idp)) { - return new JsNashornRuntimeClaims(getContext(), step, idp); - } else { - // Represent step independent user - return new JsNashornRuntimeClaims(getContext(), getWrapped()); - } - default: - return super.getMember(name); - } - } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticationContext.java index 55fd66fc9685..174486a3894d 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticationContext.java @@ -18,16 +18,10 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn; -import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; -import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; -import java.util.Map; -import java.util.Optional; - /** * Javascript wrapper for Java level AuthenticationContext. * This wrapper uses jdk.nashorn engine. @@ -51,68 +45,11 @@ public JsNashornAuthenticationContext(AuthenticationContext wrapped) { initializeContext(wrapped); } - @Override - public Object getMember(String name) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_REQUESTED_ACR: - return getWrapped().getRequestedAcr(); - case FrameworkConstants.JSAttributes.JS_TENANT_DOMAIN: - return getWrapped().getTenantDomain(); - case FrameworkConstants.JSAttributes.JS_SERVICE_PROVIDER_NAME: - return getWrapped().getServiceProviderName(); - case FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER: - return getLastLoginFailedUserFromWrappedContext(); - case FrameworkConstants.JSAttributes.JS_REQUEST: - return new JsNashornServletRequest((TransientObjectWrapper) getWrapped() - .getParameter(FrameworkConstants.RequestAttribute.HTTP_REQUEST)); - case FrameworkConstants.JSAttributes.JS_RESPONSE: - return new JsNashornServletResponse((TransientObjectWrapper) getWrapped() - .getParameter(FrameworkConstants.RequestAttribute.HTTP_RESPONSE)); - case FrameworkConstants.JSAttributes.JS_STEPS: - return new JsNashornSteps(getWrapped()); - case FrameworkConstants.JSAttributes.JS_CURRENT_STEP: - return new JsNashornStep(getContext(), getContext().getCurrentStep(), - getAuthenticatedIdPOfCurrentStep(), getAuthenticatedAuthenticatorOfCurrentStep()); - case FrameworkConstants.JSAttributes.JS_CURRENT_KNOWN_SUBJECT: - StepConfig stepConfig = getCurrentSubjectIdentifierStep(); - if (stepConfig != null) { - return new JsNashornAuthenticatedUser(this.getContext(), stepConfig.getAuthenticatedUser(), - stepConfig.getOrder(), stepConfig.getAuthenticatedIdP()); - } else { - return null; - } - case FrameworkConstants.JSAttributes.JS_RETRY_STEP: - return getWrapped().isRetrying(); - case FrameworkConstants.JSAttributes.JS_ENDPOINT_PARAMS: - return new JsNashornWritableParameters(getContext().getEndpointParams()); - default: - return super.getMember(name); - } - } - - @Override - public boolean hasMember(String name) { + public void setMember(String name, Object value) { - switch (name) { - case FrameworkConstants.JSAttributes.JS_REQUESTED_ACR: - return getWrapped().getRequestedAcr() != null; - case FrameworkConstants.JSAttributes.JS_TENANT_DOMAIN: - return getWrapped().getTenantDomain() != null; - case FrameworkConstants.JSAttributes.JS_SERVICE_PROVIDER_NAME: - return getWrapped().getServiceProviderName() != null; - case FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER: - return getWrapped().getProperty(FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER) != null; - case FrameworkConstants.JSAttributes.JS_REQUEST: - return hasTransientValueInParameters(FrameworkConstants.RequestAttribute.HTTP_REQUEST); - case FrameworkConstants.JSAttributes.JS_RESPONSE: - return hasTransientValueInParameters(FrameworkConstants.RequestAttribute.HTTP_RESPONSE); - case FrameworkConstants.JSAttributes.JS_STEPS: - return !getWrapped().getSequenceConfig().getStepMap().isEmpty(); - case FrameworkConstants.JSAttributes.JS_ENDPOINT_PARAMS: - return getWrapped().getEndpointParams() != null; - default: - return super.hasMember(name); + boolean isSet = super.setMemberObject(name, value); + if (!isSet) { + AbstractJsObject.super.setMember(name, value); } } @@ -127,82 +64,4 @@ public void removeMember(String name) { AbstractJsObject.super.removeMember(name); } } - - @Override - public void setMember(String name, Object value) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_SELECTED_ACR: - getWrapped().setSelectedAcr(String.valueOf(value)); - break; - default: - super.setMember(name, value); - } - } - - protected boolean hasTransientValueInParameters(String key) { - - TransientObjectWrapper transientObjectWrapper = (TransientObjectWrapper) getWrapped().getParameter(key); - return transientObjectWrapper != null && transientObjectWrapper.getWrapped() != null; - } - - protected JsNashornAuthenticatedUser getLastLoginFailedUserFromWrappedContext() { - - Object lastLoginFailedUser - = getWrapped().getProperty(FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER); - if (lastLoginFailedUser instanceof AuthenticatedUser) { - return new JsNashornAuthenticatedUser(getWrapped(), (AuthenticatedUser) lastLoginFailedUser); - } else { - return null; - } - } - - protected String getAuthenticatedIdPOfCurrentStep() { - - if (getContext().getSequenceConfig() == null) { - //Sequence config is not yet initialized - return null; - } - - StepConfig stepConfig = getContext().getSequenceConfig().getStepMap() - .get(getContext().getCurrentStep()); - if (stepConfig != null) { - return stepConfig.getAuthenticatedIdP(); - } - return null; - - } - - protected String getAuthenticatedAuthenticatorOfCurrentStep() { - - if (getContext().getSequenceConfig() == null) { - // Sequence config is not yet initialized. - return null; - } - - StepConfig stepConfig = getContext().getSequenceConfig().getStepMap() - .get(getContext().getCurrentStep()); - - return stepConfig != null ? stepConfig.getAuthenticatedAutenticator().getName() : null; - } - - protected StepConfig getCurrentSubjectIdentifierStep() { - - if (getContext().getSequenceConfig() == null) { - //Sequence config is not yet initialized - return null; - } - - Map stepConfigs = getContext().getSequenceConfig().getStepMap(); - Optional subjectIdentifierStep = stepConfigs.values().stream() - .filter(stepConfig -> (stepConfig.isCompleted() && stepConfig.isSubjectIdentifierStep())).findFirst(); - - if (subjectIdentifierStep.isPresent()) { - return subjectIdentifierStep.get(); - } else if (getContext().getCurrentStep() > 0) { - return stepConfigs.get(getContext().getCurrentStep()); - } else { - return null; - } - } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornClaims.java index f8f25940ca4f..49a4c37d5b93 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornClaims.java @@ -18,25 +18,16 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsClaims; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import java.util.Map; -import java.util.Optional; - /** * Represent the user's claim. Can be either remote or local. * This wrapper uses jdk.nashorn engine. */ public class JsNashornClaims extends JsClaims implements AbstractJsObject { - private static final Log LOG = LogFactory.getLog(JsNashornClaims.class); - /** * Constructor to get the user authenticated in step 'n' * @@ -46,66 +37,12 @@ public class JsNashornClaims extends JsClaims implements AbstractJsObject { */ public JsNashornClaims(AuthenticationContext context, int step, String idp, boolean isRemoteClaimRequest) { - this(step, idp, isRemoteClaimRequest); - initializeContext(context); + super(context, step, idp, isRemoteClaimRequest); } public JsNashornClaims(int step, String idp, boolean isRemoteClaimRequest) { - this.isRemoteClaimRequest = isRemoteClaimRequest; - this.idp = idp; - this.step = step; - } - - @Override - public void initializeContext(AuthenticationContext context) { - - super.initializeContext(context); - if (this.authenticatedUser == null) { - if (StringUtils.isNotBlank(idp) && getContext().getCurrentAuthenticatedIdPs().containsKey(idp)) { - this.authenticatedUser = getContext().getCurrentAuthenticatedIdPs().get(idp).getUser(); - } else { - this.authenticatedUser = getAuthenticatedUserFromSubjectIdentifierStep(); - } - } - } - - /** - * Get authenticated user from step config of current subject identifier. - * - * @return AuthenticatedUser. - */ - private AuthenticatedUser getAuthenticatedUserFromSubjectIdentifierStep() { - - AuthenticatedUser authenticatedUser = null; - StepConfig stepConfig = getCurrentSubjectIdentifierStep(); - if (stepConfig != null) { - authenticatedUser = getCurrentSubjectIdentifierStep().getAuthenticatedUser(); - } - return authenticatedUser; - } - - /** - * Retrieve step config of current subject identifier. - * - * @return StepConfig. - */ - private StepConfig getCurrentSubjectIdentifierStep() { - - if (getContext().getSequenceConfig() == null) { - // Sequence config is not yet initialized. - return null; - } - Map stepConfigs = getContext().getSequenceConfig().getStepMap(); - Optional subjectIdentifierStep = stepConfigs.values().stream() - .filter(stepConfig -> (stepConfig.isCompleted() && stepConfig.isSubjectIdentifierStep())).findFirst(); - if (subjectIdentifierStep.isPresent()) { - return subjectIdentifierStep.get(); - } else if (getContext().getCurrentStep() > 0) { - return stepConfigs.get(getContext().getCurrentStep()); - } else { - return null; - } + super(step, idp, isRemoteClaimRequest); } /** @@ -117,56 +54,22 @@ private StepConfig getCurrentSubjectIdentifierStep() { */ public JsNashornClaims(AuthenticatedUser authenticatedUser, boolean isRemoteClaimRequest) { - this.isRemoteClaimRequest = isRemoteClaimRequest; - this.authenticatedUser = authenticatedUser; + super(authenticatedUser, isRemoteClaimRequest); } public JsNashornClaims(AuthenticationContext context, AuthenticatedUser authenticatedUser, boolean isRemoteClaimRequest) { - this(authenticatedUser, isRemoteClaimRequest); - initializeContext(context); - } - - @Override - public Object getMember(String claimUri) { - - if (authenticatedUser != null) { - if (isRemoteClaimRequest) { - return getFederatedClaim(claimUri); - } else { - return getLocalClaim(claimUri); - } - } - return null; - } - - @Override - public boolean hasMember(String claimUri) { - - if (authenticatedUser != null) { - if (isRemoteClaimRequest) { - return hasFederatedClaim(claimUri); - } else { - return hasLocalClaim(claimUri); - } - } - return false; + super(context, authenticatedUser, isRemoteClaimRequest); } @Override public void setMember(String claimUri, Object claimValue) { - if (authenticatedUser != null) { - if (isRemoteClaimRequest) { - setFederatedClaim(claimUri, String.valueOf(claimValue)); - return; - } else { - setLocalClaim(claimUri, String.valueOf(claimValue)); - return; - } + boolean isClaimSet = setMemberObject(claimUri, claimValue); + if (isClaimSet) { + return; } AbstractJsObject.super.setMember(claimUri, claimValue); } - } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornHeaders.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornHeaders.java new file mode 100644 index 000000000000..fdeef926e615 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornHeaders.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn; + +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsHeaders; + +import java.util.Map; + +import javax.servlet.http.HttpServletResponse; + +/** + * Javascript wrapper for Java level HashMap of HTTP headers. + * This provides controlled access to HTTPServletResponse object's headers via provided javascript native syntax. + * Also it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime. + */ +public class JsNashornHeaders extends JsHeaders implements AbstractJsObject { + + public JsNashornHeaders(Map wrapped, HttpServletResponse response) { + + super(wrapped, response); + } + + @Override + public Object getMember(String name) { + + Object member = super.getMember(name); + return member != null ? member : AbstractJsObject.super.getMember(name); + } + + @Override + public void removeMember(String name) { + + boolean isRemoved = super.removeMemberObject(name); + if (!isRemoved) { + AbstractJsObject.super.removeMember(name); + } + } + + @Override + public void setMember(String name, Object value) { + + boolean isSet = super.setMemberObject(name, value); + if (!isSet) { + AbstractJsObject.super.setMember(name, value); + } + } +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornParameters.java index c1d9b38a40f7..8b91a8afe48c 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornParameters.java @@ -18,8 +18,6 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsParameters; import java.util.Map; @@ -33,11 +31,8 @@ */ public class JsNashornParameters extends JsParameters implements AbstractJsObject { - private static final Log LOG = LogFactory.getLog(JsNashornParameters.class); - public JsNashornParameters(Map wrapped) { super(wrapped); } - } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornRuntimeClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornRuntimeClaims.java index d6a1ba6f3b65..9b60f7d458b9 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornRuntimeClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornRuntimeClaims.java @@ -18,7 +18,7 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn; -import org.apache.commons.lang.StringUtils; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsRuntimeClaims; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; @@ -26,73 +26,15 @@ * Represent the user's runtime claims. * This wrapper uses jdk.nashorn engine. */ -public class JsNashornRuntimeClaims extends JsNashornClaims { +public class JsNashornRuntimeClaims extends JsRuntimeClaims implements AbstractJsObject { public JsNashornRuntimeClaims(AuthenticationContext context, int step, String idp) { - super(context, step, idp, false); + super(context, step, idp); } public JsNashornRuntimeClaims(AuthenticationContext context, AuthenticatedUser user) { - super(context, user, false); - } - - @Override - public Object getMember(String claimUri) { - - if (authenticatedUser != null) { - return getRuntimeClaim(claimUri); - } - return null; - } - - @Override - public boolean hasMember(String claimUri) { - - if (authenticatedUser != null) { - return hasRuntimeClaim(claimUri); - } - return false; - } - - @Override - public void setMember(String claimUri, Object claimValue) { - - if (authenticatedUser != null) { - setRuntimeClaim(claimUri, claimValue); - } - } - - private Object getRuntimeClaim(String claimUri) { - - String runtimeClaimValue = getContext().getRuntimeClaim(claimUri); - if (runtimeClaimValue != null) { - return runtimeClaimValue; - } - if (isFederatedIdP()) { - return getFederatedClaim(claimUri); - } - return getLocalClaim(claimUri); - } - - private boolean hasRuntimeClaim(String claimUri) { - - String claim = getContext().getRuntimeClaim(claimUri); - if (claim != null) { - return true; - } - if (isFederatedIdP()) { - return hasFederatedClaim(claimUri); - } - return hasLocalClaim(claimUri); - } - - private void setRuntimeClaim(String claimUri, Object claimValue) { - - if (claimValue == null) { - claimValue = StringUtils.EMPTY; - } - getContext().addRuntimeClaim(claimUri, String.valueOf(claimValue)); + super(context, user); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornServletRequest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornServletRequest.java index b3dc3b87cb37..3a16e605be05 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornServletRequest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornServletRequest.java @@ -20,14 +20,7 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsServletRequest; import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; -import org.wso2.carbon.identity.core.util.IdentityUtil; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; /** @@ -49,37 +42,5 @@ public JsNashornServletRequest(TransientObjectWrapper wrappe super(wrapped); } - - @Override - public Object getMember(String name) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_HEADERS: - Map headers = new HashMap(); - Enumeration headerNames = getRequest().getHeaderNames(); - if (headerNames != null) { - while (headerNames.hasMoreElements()) { - String headerName = headerNames.nextElement(); - headers.put(headerName, getRequest().getHeader(headerName)); - } - } - return new JsNashornWritableParameters(headers); - case FrameworkConstants.JSAttributes.JS_PARAMS: - return new JsNashornParameters(getRequest().getParameterMap()); - case FrameworkConstants.JSAttributes.JS_COOKIES: - Map cookies = new HashMap(); - Cookie[] cookieArr = getRequest().getCookies(); - if (cookieArr != null) { - for (Cookie cookie : cookieArr) { - cookies.put(cookie.getName(), new JsNashornCookie(cookie)); - } - } - return new JsNashornWritableParameters(cookies); - case FrameworkConstants.JSAttributes.JS_REQUEST_IP: - return IdentityUtil.getClientIpAddress(getRequest()); - default: - return super.getMember(name); - } - } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornServletResponse.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornServletResponse.java index 1a26b2b64dca..d25f8516e4b7 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornServletResponse.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornServletResponse.java @@ -20,11 +20,6 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsServletResponse; import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; import javax.servlet.http.HttpServletResponse; @@ -48,21 +43,4 @@ public JsNashornServletResponse(TransientObjectWrapper wrap super(wrapped); } - @Override - public Object getMember(String name) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_HEADERS: - Map headers = new HashMap(); - Collection headerNames = getResponse().getHeaderNames(); - if (headerNames != null) { - for (String element : headerNames) { - headers.put(element, getResponse().getHeader(element)); - } - } - return new JsHeaders(headers, getResponse()); - default: - return super.getMember(name); - } - } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornStep.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornStep.java index 3e6f5dc3092b..6da745a6cdcd 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornStep.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornStep.java @@ -18,132 +18,53 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.AbstractJSContextMemberObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsStep; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedIdPData; -import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; /** * Represents a authentication step. * This wrapper uses jdk.nashorn engine. */ -public class JsNashornStep extends AbstractJSContextMemberObject implements AbstractJsObject { - - private static final Log LOG = LogFactory.getLog(JsNashornSteps.class); - - private int step; - private String authenticatedIdp; - private String authenticatedAuthenticator; +public class JsNashornStep extends JsStep implements AbstractJsObject { @Deprecated public JsNashornStep(int step, String authenticatedIdp) { - this.step = step; - this.authenticatedIdp = authenticatedIdp; + super(step, authenticatedIdp); } public JsNashornStep(int step, String authenticatedIdp, String authenticatedAuthenticator) { - this.step = step; - this.authenticatedIdp = authenticatedIdp; - this.authenticatedAuthenticator = authenticatedAuthenticator; + super(step, authenticatedIdp, authenticatedAuthenticator); } @Deprecated public JsNashornStep(AuthenticationContext context, int step, String authenticatedIdp) { - this(step, authenticatedIdp, null); - initializeContext(context); + super(context, step, authenticatedIdp); } public JsNashornStep(AuthenticationContext context, int step, String authenticatedIdp, String authenticatedAuthenticator) { - this(step, authenticatedIdp, authenticatedAuthenticator); - initializeContext(context); + super(context, step, authenticatedIdp, authenticatedAuthenticator); } @Override public Object getMember(String name) { - switch (name) { - case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT: - return new JsNashornAuthenticatedUser(getContext(), getSubject(), step, authenticatedIdp); - case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP: - return authenticatedIdp; - case FrameworkConstants.JSAttributes.JS_AUTHENTICATOR: - return authenticatedAuthenticator; - case FrameworkConstants.JSAttributes.JS_AUTHENTICATION_OPTIONS: - return getOptions(); - default: - return AbstractJsObject.super.getMember(name); - } + Object member = super.getMember(name); + return member != null ? member : AbstractJsObject.super.getMember(name); } @Override public boolean hasMember(String name) { - switch (name) { - case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT: - return true; - case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP: - return true; - case FrameworkConstants.JSAttributes.JS_AUTHENTICATOR: - return true; - default: - return AbstractJsObject.super.hasMember(name); - } + return super.hasMember(name) || AbstractJsObject.super.hasMember(name); } - @Override public void removeMember(String name) { - LOG.warn("Step is readonly, hence the can't remove the member."); - } - - @Override - public void setMember(String name, Object value) { - - LOG.warn("Step is readonly, hence the setter is ignored."); - } - - private AuthenticatedUser getSubject() { - - if (authenticatedIdp != null) { - AuthenticatedIdPData idPData = getContext().getCurrentAuthenticatedIdPs().get(authenticatedIdp); - if (idPData == null) { - idPData = getContext().getPreviousAuthenticatedIdPs().get(authenticatedIdp); - } - if (idPData != null) { - return idPData.getUser(); - } - } - return null; - } - - private List> getOptions() { - - List> optionsList = new ArrayList<>(); - Optional optionalStepConfig = getContext().getSequenceConfig().getStepMap().values().stream() - .filter(stepConfig -> stepConfig.getOrder() == step).findFirst(); - optionalStepConfig.ifPresent(stepConfig -> stepConfig.getAuthenticatorList().forEach( - authConfig -> authConfig.getIdpNames().forEach(name -> { - Map option = new HashMap<>(); - option.put(FrameworkConstants.JSAttributes.IDP, name); - option.put(FrameworkConstants.JSAttributes.AUTHENTICATOR, authConfig.getApplicationAuthenticator() - .getName()); - optionsList.add(option); - }))); - return optionsList; + super.removeMemberObject(name); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornSteps.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornSteps.java index f4c5e602c032..cadde96a4c9f 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornSteps.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornSteps.java @@ -18,76 +18,32 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.identity.application.authentication.framework.config.model.AuthenticatorConfig; -import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.AbstractJSContextMemberObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsSteps; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import java.util.Optional; +import java.util.Objects; /** * Returns when context.steps[ optionalStepConfig = getContext().getSequenceConfig().getStepMap().values().stream() - .filter(stepConfig -> stepConfig.getOrder() == step).findFirst(); - return optionalStepConfig.map(StepConfig::getAuthenticatedIdP).orElse(null); - } - - private String getAuthenticatedAuthenticatorOfStep(int step) { - - if (getContext().getSequenceConfig() == null) { - // Sequence config is not yet initialized. - return null; - } - - Optional optionalStepConfig = getContext().getSequenceConfig().getStepMap().values().stream() - .filter(stepConfig -> stepConfig.getOrder() == step).findFirst(); - AuthenticatorConfig authenticatorConfig = optionalStepConfig.map(StepConfig::getAuthenticatedAutenticator) - .orElse(null); - return authenticatorConfig != null ? authenticatorConfig.getName() : null; + Object jsStep = super.getSlot(step); + return Objects.nonNull(jsStep) ? jsStep : AbstractJsObject.super.getSlot(step); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornWritableParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornWritableParameters.java index 17b88ff83427..28c8d0220900 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornWritableParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornWritableParameters.java @@ -18,6 +18,7 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsWritableParameters; import java.util.Map; @@ -25,24 +26,15 @@ * Parameters that can be modified from the authentication script. * This wrapper uses jdk.nashorn engine. */ -public class JsNashornWritableParameters extends JsNashornParameters { +public class JsNashornWritableParameters extends JsWritableParameters implements AbstractJsObject { public JsNashornWritableParameters(Map wrapped) { super(wrapped); } - - @Override public void removeMember(String name) { - if (getWrapped().containsKey(name)) { - getWrapped().remove(name); - } + super.removeMemberObject(name); } - @Override - public void setMember(String name, Object value) { - - getWrapped().put(name, value); - } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticatedUser.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticatedUser.java index ff420b7167d9..a3e03b704f24 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticatedUser.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticatedUser.java @@ -18,15 +18,9 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; /** * Javascript wrapper for Java level AuthenticatedUser. @@ -46,8 +40,6 @@ public class JsOpenJdkNashornAuthenticatedUser extends JsAuthenticatedUser implements AbstractOpenJdkNashornJsObject { - private static final Log LOG = LogFactory.getLog(JsOpenJdkNashornAuthenticatedUser.class); - /** * Constructor to be used when required to access step specific user details. * @@ -88,52 +80,4 @@ public JsOpenJdkNashornAuthenticatedUser(AuthenticationContext context, Authenti super(context, wrappedUser); } - - @Override - public Object getMember(String name) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT_IDENTIFIER: - return getWrapped().getAuthenticatedSubjectIdentifier(); - case FrameworkConstants.JSAttributes.JS_USERNAME: - return getWrapped().getUserName(); - case FrameworkConstants.JSAttributes.JS_UNIQUE_ID: - Object userId = null; - try { - userId = getWrapped().getUserId(); - } catch (UserIdNotFoundException e) { - LOG.error("Error while retrieving user Id of user : " + getWrapped().getLoggableUserId(), e); - } - return userId; - case FrameworkConstants.JSAttributes.JS_USER_STORE_DOMAIN: - return getWrapped().getUserStoreDomain(); - case FrameworkConstants.JSAttributes.JS_TENANT_DOMAIN: - return getWrapped().getTenantDomain(); - case FrameworkConstants.JSAttributes.JS_LOCAL_CLAIMS: - if (StringUtils.isNotBlank(idp)) { - return new JsOpenJdkNashornClaims(getContext(), step, idp, false); - } else { - // Represent step independent user - return new JsOpenJdkNashornClaims(getContext(), getWrapped(), false); - } - case FrameworkConstants.JSAttributes.JS_REMOTE_CLAIMS: - if (StringUtils.isNotBlank(idp)) { - return new JsOpenJdkNashornClaims(getContext(), step, idp, true); - } else { - // Represent step independent user - return new JsOpenJdkNashornClaims(getContext(), getWrapped(), true); - } - case FrameworkConstants.JSAttributes.JS_LOCAL_ROLES: - return getLocalRoles(); - case FrameworkConstants.JSAttributes.JS_CLAIMS: - if (StringUtils.isNotBlank(idp)) { - return new JsOpenJdkNashornRuntimeClaims(getContext(), step, idp); - } else { - // Represent step independent user - return new JsOpenJdkNashornRuntimeClaims(getContext(), getWrapped()); - } - default: - return super.getMember(name); - } - } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticationContext.java index 0cbe54eae9c5..42e2edb15380 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticationContext.java @@ -18,16 +18,10 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn; -import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; -import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; -import java.util.Map; -import java.util.Optional; - /** * Javascript wrapper for Java level AuthenticationContext. * This provides controlled access to AuthenticationContext object via provided javascript native syntax. @@ -52,68 +46,11 @@ public JsOpenJdkNashornAuthenticationContext(AuthenticationContext wrapped) { initializeContext(wrapped); } - @Override - public Object getMember(String name) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_REQUESTED_ACR: - return getWrapped().getRequestedAcr(); - case FrameworkConstants.JSAttributes.JS_TENANT_DOMAIN: - return getWrapped().getTenantDomain(); - case FrameworkConstants.JSAttributes.JS_SERVICE_PROVIDER_NAME: - return getWrapped().getServiceProviderName(); - case FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER: - return getLastLoginFailedUserFromWrappedContext(); - case FrameworkConstants.JSAttributes.JS_REQUEST: - return new JsOpenJdkNashornServletRequest((TransientObjectWrapper) getWrapped() - .getParameter(FrameworkConstants.RequestAttribute.HTTP_REQUEST)); - case FrameworkConstants.JSAttributes.JS_RESPONSE: - return new JsOpenJdkNashornServletResponse((TransientObjectWrapper) getWrapped() - .getParameter(FrameworkConstants.RequestAttribute.HTTP_RESPONSE)); - case FrameworkConstants.JSAttributes.JS_STEPS: - return new JsOpenJdkNashornSteps(getWrapped()); - case FrameworkConstants.JSAttributes.JS_CURRENT_STEP: - return new JsOpenJdkNashornStep(getContext(), getContext().getCurrentStep(), - getAuthenticatedIdPOfCurrentStep(), getAuthenticatedAuthenticatorOfCurrentStep()); - case FrameworkConstants.JSAttributes.JS_CURRENT_KNOWN_SUBJECT: - StepConfig stepConfig = getCurrentSubjectIdentifierStep(); - if (stepConfig != null) { - return new JsOpenJdkNashornAuthenticatedUser(this.getContext(), stepConfig.getAuthenticatedUser(), - stepConfig.getOrder(), stepConfig.getAuthenticatedIdP()); - } else { - return null; - } - case FrameworkConstants.JSAttributes.JS_RETRY_STEP: - return getWrapped().isRetrying(); - case FrameworkConstants.JSAttributes.JS_ENDPOINT_PARAMS: - return new JsOpenJdkNashornWritableParameters(getContext().getEndpointParams()); - default: - return super.getMember(name); - } - } - - @Override - public boolean hasMember(String name) { + public void setMember(String name, Object value) { - switch (name) { - case FrameworkConstants.JSAttributes.JS_REQUESTED_ACR: - return getWrapped().getRequestedAcr() != null; - case FrameworkConstants.JSAttributes.JS_TENANT_DOMAIN: - return getWrapped().getTenantDomain() != null; - case FrameworkConstants.JSAttributes.JS_SERVICE_PROVIDER_NAME: - return getWrapped().getServiceProviderName() != null; - case FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER: - return getWrapped().getProperty(FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER) != null; - case FrameworkConstants.JSAttributes.JS_REQUEST: - return hasTransientValueInParameters(FrameworkConstants.RequestAttribute.HTTP_REQUEST); - case FrameworkConstants.JSAttributes.JS_RESPONSE: - return hasTransientValueInParameters(FrameworkConstants.RequestAttribute.HTTP_RESPONSE); - case FrameworkConstants.JSAttributes.JS_STEPS: - return !getWrapped().getSequenceConfig().getStepMap().isEmpty(); - case FrameworkConstants.JSAttributes.JS_ENDPOINT_PARAMS: - return getWrapped().getEndpointParams() != null; - default: - return super.hasMember(name); + boolean isSet = super.setMemberObject(name, value); + if (!isSet) { + AbstractOpenJdkNashornJsObject.super.setMember(name, value); } } @@ -128,81 +65,4 @@ public void removeMember(String name) { AbstractOpenJdkNashornJsObject.super.removeMember(name); } } - - @Override - public void setMember(String name, Object value) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_SELECTED_ACR: - getWrapped().setSelectedAcr(String.valueOf(value)); - break; - default: - super.setMember(name, value); - } - } - - protected boolean hasTransientValueInParameters(String key) { - - TransientObjectWrapper transientObjectWrapper = (TransientObjectWrapper) getWrapped().getParameter(key); - return transientObjectWrapper != null && transientObjectWrapper.getWrapped() != null; - } - - protected JsOpenJdkNashornAuthenticatedUser getLastLoginFailedUserFromWrappedContext() { - - Object lastLoginFailedUser - = getWrapped().getProperty(FrameworkConstants.JSAttributes.JS_LAST_LOGIN_FAILED_USER); - if (lastLoginFailedUser instanceof AuthenticatedUser) { - return new JsOpenJdkNashornAuthenticatedUser(getWrapped(), (AuthenticatedUser) lastLoginFailedUser); - } else { - return null; - } - } - - protected String getAuthenticatedIdPOfCurrentStep() { - - if (getContext().getSequenceConfig() == null) { - //Sequence config is not yet initialized - return null; - } - - StepConfig stepConfig = getContext().getSequenceConfig().getStepMap() - .get(getContext().getCurrentStep()); - if (stepConfig != null) { - return stepConfig.getAuthenticatedIdP(); - } - return null; - - } - - protected String getAuthenticatedAuthenticatorOfCurrentStep() { - - if (getContext().getSequenceConfig() == null) { - // Sequence config is not yet initialized. - return null; - } - - StepConfig stepConfig = getContext().getSequenceConfig().getStepMap() - .get(getContext().getCurrentStep()); - return stepConfig != null ? stepConfig.getAuthenticatedAutenticator().getName() : null; - } - - protected StepConfig getCurrentSubjectIdentifierStep() { - - if (getContext().getSequenceConfig() == null) { - //Sequence config is not yet initialized - return null; - } - - Map stepConfigs = getContext().getSequenceConfig().getStepMap(); - Optional subjectIdentifierStep = stepConfigs.values().stream() - .filter(stepConfig -> (stepConfig.isCompleted() && stepConfig.isSubjectIdentifierStep())).findFirst(); - - if (subjectIdentifierStep.isPresent()) { - return subjectIdentifierStep.get(); - } else if (getContext().getCurrentStep() > 0) { - return stepConfigs.get(getContext().getCurrentStep()); - } else { - return null; - } - } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornClaims.java index 1fe6a8699fa0..65c691b7f33f 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornClaims.java @@ -18,17 +18,10 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsClaims; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import java.util.Map; -import java.util.Optional; - /** * Represent the user's claim. Can be either remote or local. * Since Nashorn is deprecated in JDK 11 and onwards. We are introducing OpenJDK Nashorn engine. @@ -36,8 +29,6 @@ */ public class JsOpenJdkNashornClaims extends JsClaims implements AbstractOpenJdkNashornJsObject { - private static final Log LOG = LogFactory.getLog(JsOpenJdkNashornClaims.class); - /** * Constructor to get the user authenticated in step 'n' * @@ -47,66 +38,12 @@ public class JsOpenJdkNashornClaims extends JsClaims implements AbstractOpenJdkN */ public JsOpenJdkNashornClaims(AuthenticationContext context, int step, String idp, boolean isRemoteClaimRequest) { - this(step, idp, isRemoteClaimRequest); - initializeContext(context); + super(context, step, idp, isRemoteClaimRequest); } public JsOpenJdkNashornClaims(int step, String idp, boolean isRemoteClaimRequest) { - this.isRemoteClaimRequest = isRemoteClaimRequest; - this.idp = idp; - this.step = step; - } - - @Override - public void initializeContext(AuthenticationContext context) { - - super.initializeContext(context); - if (this.authenticatedUser == null) { - if (StringUtils.isNotBlank(idp) && getContext().getCurrentAuthenticatedIdPs().containsKey(idp)) { - this.authenticatedUser = getContext().getCurrentAuthenticatedIdPs().get(idp).getUser(); - } else { - this.authenticatedUser = getAuthenticatedUserFromSubjectIdentifierStep(); - } - } - } - - /** - * Get authenticated user from step config of current subject identifier. - * - * @return AuthenticatedUser. - */ - private AuthenticatedUser getAuthenticatedUserFromSubjectIdentifierStep() { - - AuthenticatedUser authenticatedUser = null; - StepConfig stepConfig = getCurrentSubjectIdentifierStep(); - if (stepConfig != null) { - authenticatedUser = getCurrentSubjectIdentifierStep().getAuthenticatedUser(); - } - return authenticatedUser; - } - - /** - * Retrieve step config of current subject identifier. - * - * @return StepConfig. - */ - private StepConfig getCurrentSubjectIdentifierStep() { - - if (getContext().getSequenceConfig() == null) { - // Sequence config is not yet initialized. - return null; - } - Map stepConfigs = getContext().getSequenceConfig().getStepMap(); - Optional subjectIdentifierStep = stepConfigs.values().stream() - .filter(stepConfig -> (stepConfig.isCompleted() && stepConfig.isSubjectIdentifierStep())).findFirst(); - if (subjectIdentifierStep.isPresent()) { - return subjectIdentifierStep.get(); - } else if (getContext().getCurrentStep() > 0) { - return stepConfigs.get(getContext().getCurrentStep()); - } else { - return null; - } + super(step, idp, isRemoteClaimRequest); } /** @@ -118,55 +55,21 @@ private StepConfig getCurrentSubjectIdentifierStep() { */ public JsOpenJdkNashornClaims(AuthenticatedUser authenticatedUser, boolean isRemoteClaimRequest) { - this.isRemoteClaimRequest = isRemoteClaimRequest; - this.authenticatedUser = authenticatedUser; + super(authenticatedUser, isRemoteClaimRequest); } public JsOpenJdkNashornClaims(AuthenticationContext context, AuthenticatedUser authenticatedUser, boolean isRemoteClaimRequest) { - this(authenticatedUser, isRemoteClaimRequest); - initializeContext(context); - } - - @Override - public Object getMember(String claimUri) { - - if (authenticatedUser != null) { - if (isRemoteClaimRequest) { - return getFederatedClaim(claimUri); - } else { - return getLocalClaim(claimUri); - } - } - return null; - } - - @Override - public boolean hasMember(String claimUri) { - - if (authenticatedUser != null) { - if (isRemoteClaimRequest) { - return hasFederatedClaim(claimUri); - } else { - return hasLocalClaim(claimUri); - } - } - return false; + super(context, authenticatedUser, isRemoteClaimRequest); } @Override public void setMember(String claimUri, Object claimValue) { - if (authenticatedUser != null) { - if (isRemoteClaimRequest) { - setFederatedClaim(claimUri, String.valueOf(claimValue)); - return; - } else { - setLocalClaim(claimUri, String.valueOf(claimValue)); - return; - } + boolean isClaimSet = setMemberObject(claimUri, claimValue); + if (!isClaimSet) { + AbstractOpenJdkNashornJsObject.super.setMember(claimUri, claimValue); } - AbstractOpenJdkNashornJsObject.super.setMember(claimUri, claimValue); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornHeaders.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornHeaders.java index 3a1ab717c192..a003917a0339 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornHeaders.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornHeaders.java @@ -18,7 +18,7 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn; -import org.openjdk.nashorn.api.scripting.AbstractJSObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsHeaders; import java.util.Map; @@ -31,58 +31,39 @@ * Also it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime. * Since Nashorn is deprecated in JDK 11 and onwards. We are introducing OpenJDK Nashorn engine. */ -public class JsOpenJdkNashornHeaders extends AbstractJSObject { - - private Map wrapped; - private HttpServletResponse response; +public class JsOpenJdkNashornHeaders extends JsHeaders implements AbstractOpenJdkNashornJsObject { public JsOpenJdkNashornHeaders(Map wrapped, HttpServletResponse response) { - this.wrapped = wrapped; - this.response = response; + super(wrapped, response); } @Override public Object getMember(String name) { - if (wrapped == null) { - return super.getMember(name); + Object member = super.getMember(name); + if (member != null) { + return member; } else { - return wrapped.get(name); - } - } - - @Override - public boolean hasMember(String name) { - - if (wrapped == null) { - return false; - } else { - return wrapped.get(name) != null; + return AbstractOpenJdkNashornJsObject.super.getMember(name); } } @Override public void removeMember(String name) { - if (wrapped == null) { - super.removeMember(name); - } else { - if (wrapped.containsKey(name)) { - wrapped.remove(name); - } + boolean isRemoved = super.removeMemberObject(name); + if (!isRemoved) { + AbstractOpenJdkNashornJsObject.super.removeMember(name); } } @Override public void setMember(String name, Object value) { - if (wrapped == null) { - super.setMember(name, value); - } else { - wrapped.put(name, value); - //adds a new header to the response. - response.addHeader(name, String.valueOf(value)); + boolean isSet = super.setMemberObject(name, value); + if (!isSet) { + AbstractOpenJdkNashornJsObject.super.setMember(name, value); } } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornParameters.java index 3d782ef1b996..e414064209ea 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornParameters.java @@ -18,8 +18,6 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsParameters; import java.util.Map; @@ -33,8 +31,6 @@ */ public class JsOpenJdkNashornParameters extends JsParameters implements AbstractOpenJdkNashornJsObject { - private static final Log LOG = LogFactory.getLog(JsOpenJdkNashornParameters.class); - public JsOpenJdkNashornParameters(Map wrapped) { super(wrapped); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornRuntimeClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornRuntimeClaims.java index d7655836df61..be503c2ad9e5 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornRuntimeClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornRuntimeClaims.java @@ -18,7 +18,8 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn; -import org.apache.commons.lang.StringUtils; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsRuntimeClaims; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.AbstractJsObject; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; @@ -26,73 +27,15 @@ * Represent the user's runtime claims. * Since Nashorn is deprecated in JDK 11 and onwards. We are introducing OpenJDK Nashorn engine. */ -public class JsOpenJdkNashornRuntimeClaims extends JsOpenJdkNashornClaims { +public class JsOpenJdkNashornRuntimeClaims extends JsRuntimeClaims implements AbstractJsObject { public JsOpenJdkNashornRuntimeClaims(AuthenticationContext context, int step, String idp) { - super(context, step, idp, false); + super(context, step, idp); } public JsOpenJdkNashornRuntimeClaims(AuthenticationContext context, AuthenticatedUser user) { - super(context, user, false); - } - - @Override - public Object getMember(String claimUri) { - - if (authenticatedUser != null) { - return getRuntimeClaim(claimUri); - } - return null; - } - - @Override - public boolean hasMember(String claimUri) { - - if (authenticatedUser != null) { - return hasRuntimeClaim(claimUri); - } - return false; - } - - @Override - public void setMember(String claimUri, Object claimValue) { - - if (authenticatedUser != null) { - setRuntimeClaim(claimUri, claimValue); - } - } - - private Object getRuntimeClaim(String claimUri) { - - String runtimeClaimValue = getContext().getRuntimeClaim(claimUri); - if (runtimeClaimValue != null) { - return runtimeClaimValue; - } - if (isFederatedIdP()) { - return getFederatedClaim(claimUri); - } - return getLocalClaim(claimUri); - } - - private boolean hasRuntimeClaim(String claimUri) { - - String claim = getContext().getRuntimeClaim(claimUri); - if (claim != null) { - return true; - } - if (isFederatedIdP()) { - return hasFederatedClaim(claimUri); - } - return hasLocalClaim(claimUri); - } - - private void setRuntimeClaim(String claimUri, Object claimValue) { - - if (claimValue == null) { - claimValue = StringUtils.EMPTY; - } - getContext().addRuntimeClaim(claimUri, String.valueOf(claimValue)); + super(context, user); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornServletRequest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornServletRequest.java index 743576ca58ae..ed7a903547aa 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornServletRequest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornServletRequest.java @@ -20,14 +20,7 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsServletRequest; import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; -import org.wso2.carbon.identity.core.util.IdentityUtil; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; /** @@ -49,37 +42,5 @@ public JsOpenJdkNashornServletRequest(TransientObjectWrapper super(wrapped); } - - @Override - public Object getMember(String name) { - - switch (name) { - case FrameworkConstants.JSAttributes.JS_HEADERS: - Map headers = new HashMap(); - Enumeration headerNames = getRequest().getHeaderNames(); - if (headerNames != null) { - while (headerNames.hasMoreElements()) { - String headerName = headerNames.nextElement(); - headers.put(headerName, getRequest().getHeader(headerName)); - } - } - return new JsOpenJdkNashornWritableParameters(headers); - case FrameworkConstants.JSAttributes.JS_PARAMS: - return new JsOpenJdkNashornParameters(getRequest().getParameterMap()); - case FrameworkConstants.JSAttributes.JS_COOKIES: - Map cookies = new HashMap(); - Cookie[] cookieArr = getRequest().getCookies(); - if (cookieArr != null) { - for (Cookie cookie : cookieArr) { - cookies.put(cookie.getName(), new JsOpenJdkNashornCookie(cookie)); - } - } - return new JsOpenJdkNashornWritableParameters(cookies); - case FrameworkConstants.JSAttributes.JS_REQUEST_IP: - return IdentityUtil.getClientIpAddress(getRequest()); - default: - return super.getMember(name); - } - } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornServletResponse.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornServletResponse.java index a0b19d515ca1..5d03a944fc6a 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornServletResponse.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornServletResponse.java @@ -20,11 +20,6 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsServletResponse; import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; import javax.servlet.http.HttpServletResponse; @@ -48,22 +43,4 @@ public JsOpenJdkNashornServletResponse(TransientObjectWrapper headerNames = getResponse().getHeaderNames(); - if (headerNames != null) { - for (String element : headerNames) { - headers.put(element, getResponse().getHeader(element)); - } - } - return new JsOpenJdkNashornHeaders(headers, getResponse()); - default: - return super.getMember(name); - } - } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornStep.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornStep.java index 5b3ff2b93050..590440f1de59 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornStep.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornStep.java @@ -18,132 +18,53 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.AbstractJSContextMemberObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsStep; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedIdPData; -import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; /** * Represents a authentication step. * Since Nashorn is deprecated in JDK 11 and onwards. We are introducing OpenJDK Nashorn engine. */ -public class JsOpenJdkNashornStep extends AbstractJSContextMemberObject implements AbstractOpenJdkNashornJsObject { - - private static final Log LOG = LogFactory.getLog(JsOpenJdkNashornStep.class); - - private int step; - private String authenticatedIdp; - private String authenticatedAuthenticator; +public class JsOpenJdkNashornStep extends JsStep implements AbstractOpenJdkNashornJsObject { @Deprecated public JsOpenJdkNashornStep(int step, String authenticatedIdp) { - this.step = step; - this.authenticatedIdp = authenticatedIdp; + super(step, authenticatedIdp); } public JsOpenJdkNashornStep(int step, String authenticatedIdp, String authenticatedAuthenticator) { - this.step = step; - this.authenticatedIdp = authenticatedIdp; - this.authenticatedAuthenticator = authenticatedAuthenticator; + super(step, authenticatedIdp, authenticatedAuthenticator); } @Deprecated public JsOpenJdkNashornStep(AuthenticationContext context, int step, String authenticatedIdp) { - this(step, authenticatedIdp, null); - initializeContext(context); + super(context, step, authenticatedIdp); } public JsOpenJdkNashornStep(AuthenticationContext context, int step, String authenticatedIdp, String authenticatedAuthenticator) { - this(step, authenticatedIdp, authenticatedAuthenticator); - initializeContext(context); + super(context, step, authenticatedIdp, authenticatedAuthenticator); } @Override public Object getMember(String name) { - switch (name) { - case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT: - return new JsOpenJdkNashornAuthenticatedUser(getContext(), getSubject(), step, authenticatedIdp); - case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP: - return authenticatedIdp; - case FrameworkConstants.JSAttributes.JS_AUTHENTICATOR: - return authenticatedAuthenticator; - case FrameworkConstants.JSAttributes.JS_AUTHENTICATION_OPTIONS: - return getOptions(); - default: - return AbstractOpenJdkNashornJsObject.super.getMember(name); - } + Object member = super.getMember(name); + return member != null ? member : AbstractOpenJdkNashornJsObject.super.getMember(name); } @Override public boolean hasMember(String name) { - switch (name) { - case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_SUBJECT: - return true; - case FrameworkConstants.JSAttributes.JS_AUTHENTICATED_IDP: - return true; - case FrameworkConstants.JSAttributes.JS_AUTHENTICATOR: - return true; - default: - return AbstractOpenJdkNashornJsObject.super.hasMember(name); - } + return super.hasMember(name) || AbstractOpenJdkNashornJsObject.super.hasMember(name); } - @Override public void removeMember(String name) { - LOG.warn("Step is readonly, hence the can't remove the member."); - } - - @Override - public void setMember(String name, Object value) { - - LOG.warn("Step is readonly, hence the setter is ignored."); - } - - private AuthenticatedUser getSubject() { - - if (authenticatedIdp != null) { - AuthenticatedIdPData idPData = getContext().getCurrentAuthenticatedIdPs().get(authenticatedIdp); - if (idPData == null) { - idPData = getContext().getPreviousAuthenticatedIdPs().get(authenticatedIdp); - } - if (idPData != null) { - return idPData.getUser(); - } - } - return null; - } - - private List> getOptions() { - - List> optionsList = new ArrayList<>(); - Optional optionalStepConfig = getContext().getSequenceConfig().getStepMap().values().stream() - .filter(stepConfig -> stepConfig.getOrder() == step).findFirst(); - optionalStepConfig.ifPresent(stepConfig -> stepConfig.getAuthenticatorList().forEach( - authConfig -> authConfig.getIdpNames().forEach(name -> { - Map option = new HashMap<>(); - option.put(FrameworkConstants.JSAttributes.IDP, name); - option.put(FrameworkConstants.JSAttributes.AUTHENTICATOR, authConfig.getApplicationAuthenticator() - .getName()); - optionsList.add(option); - }))); - return optionsList; + super.removeMemberObject(name); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornSteps.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornSteps.java index f54bb82bcef5..c70e88e09165 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornSteps.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornSteps.java @@ -20,74 +20,33 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.identity.application.authentication.framework.config.model.AuthenticatorConfig; -import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.AbstractJSContextMemberObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsSteps; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import java.util.Optional; +import java.util.Objects; /** * Returns when context.steps[ optionalStepConfig = getContext().getSequenceConfig().getStepMap().values().stream() - .filter(stepConfig -> stepConfig.getOrder() == step).findFirst(); - return optionalStepConfig.map(StepConfig::getAuthenticatedIdP).orElse(null); - } - - private String getAuthenticatedAuthenticatorOfStep(int step) { - - if (getContext().getSequenceConfig() == null) { - // Sequence config is not yet initialized. - return null; - } - - Optional optionalStepConfig = getContext().getSequenceConfig().getStepMap().values().stream() - .filter(stepConfig -> stepConfig.getOrder() == step).findFirst(); - AuthenticatorConfig authenticatorConfig = optionalStepConfig.map(StepConfig::getAuthenticatedAutenticator) - .orElse(null); - return authenticatorConfig != null ? authenticatorConfig.getName() : null; + Object jsStep = super.getSlot(step); + return Objects.nonNull(jsStep) ? jsStep : AbstractOpenJdkNashornJsObject.super.getSlot(step); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornWritableParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornWritableParameters.java index 628dad6f8c14..b22bca9d7f9e 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornWritableParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornWritableParameters.java @@ -18,30 +18,23 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsWritableParameters; + import java.util.Map; /** * Parameters that can be modified from the authentication script. * Since Nashorn is deprecated in JDK 11 and onwards. We are introducing OpenJDK Nashorn engine. */ -public class JsOpenJdkNashornWritableParameters extends JsOpenJdkNashornParameters { +public class JsOpenJdkNashornWritableParameters extends JsWritableParameters implements AbstractOpenJdkNashornJsObject { public JsOpenJdkNashornWritableParameters(Map wrapped) { super(wrapped); } - @Override public void removeMember(String name) { - if (getWrapped().containsKey(name)) { - getWrapped().remove(name); - } - } - - @Override - public void setMember(String name, Object value) { - - getWrapped().put(name, value); + super.removeMemberObject(name); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornWrapperFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornWrapperFactory.java index 4f7fdb088b8d..d22b80d19b5f 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornWrapperFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornWrapperFactory.java @@ -19,12 +19,23 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.openjdk.nashorn; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperBaseFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseClaims; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseHeaders; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseRuntimeClaims; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseStep; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseSteps; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn.JsOpenJdkNashornAuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn.JsOpenJdkNashornAuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn.JsOpenJdkNashornClaims; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn.JsOpenJdkNashornCookie; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn.JsOpenJdkNashornHeaders; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn.JsOpenJdkNashornParameters; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn.JsOpenJdkNashornRuntimeClaims; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn.JsOpenJdkNashornServletRequest; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn.JsOpenJdkNashornServletResponse; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn.JsOpenJdkNashornStep; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn.JsOpenJdkNashornSteps; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn.JsOpenJdkNashornWritableParameters; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.context.TransientObjectWrapper; @@ -55,6 +66,13 @@ public JsOpenJdkNashornAuthenticatedUser createJsAuthenticatedUser(Authenticatio return new JsOpenJdkNashornAuthenticatedUser(authenticationContext, authenticatedUser); } + @Override + public JsBaseAuthenticatedUser createJsAuthenticatedUser(AuthenticationContext context, + AuthenticatedUser wrappedUser, int step, String idp) { + + return new JsOpenJdkNashornAuthenticatedUser(context, wrappedUser, step, idp); + } + @Override public JsOpenJdkNashornAuthenticationContext createJsAuthenticationContext (AuthenticationContext authenticationContext) { @@ -92,4 +110,49 @@ public JsOpenJdkNashornServletRequest createJsServletRequest(TransientObjectWrap return new JsOpenJdkNashornServletResponse(wrapped); } + + @Override + public JsBaseClaims createJsClaims(AuthenticationContext context, int step, String idp, + boolean isRemoteClaimRequest) { + + return new JsOpenJdkNashornClaims(context, step, idp, isRemoteClaimRequest); + } + + @Override + public JsBaseClaims createJsClaims(AuthenticationContext context, AuthenticatedUser user, + boolean isRemoteClaimRequest) { + + return new JsOpenJdkNashornClaims(context, user, isRemoteClaimRequest); + } + + @Override + public JsBaseRuntimeClaims createJsRuntimeClaims(AuthenticationContext context, int step, String idp) { + + return new JsOpenJdkNashornRuntimeClaims(context, step, idp); + } + + @Override + public JsBaseRuntimeClaims createJsRuntimeClaims(AuthenticationContext context, AuthenticatedUser user) { + + return new JsOpenJdkNashornRuntimeClaims(context, user); + } + + @Override + public JsBaseStep createJsStep(AuthenticationContext context, int step, String authenticatedIdp, + String authenticatedAuthenticator) { + + return new JsOpenJdkNashornStep(context, step, authenticatedIdp, authenticatedAuthenticator); + } + + @Override + public JsBaseHeaders createJsHeaders(Map wrapped, HttpServletResponse response) { + + return new JsOpenJdkNashornHeaders(wrapped, response); + } + + @Override + public JsBaseSteps createJsSteps(AuthenticationContext context) { + + return new JsOpenJdkNashornSteps(context); + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java index dceba157cf46..a6be14710c53 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java @@ -28,6 +28,8 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.SequenceConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthenticationGraph; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactoryProvider; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs.JsGraalWrapperFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedIdPData; @@ -36,6 +38,7 @@ import org.wso2.carbon.identity.application.common.model.ClaimMapping; import java.io.IOException; +import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; @@ -57,12 +60,17 @@ public class JsGraalAuthenticationContextTest { private Context context; @BeforeClass - public void setUp() { + public void setUp() throws NoSuchFieldException, IllegalAccessException { context = Context.newBuilder(POLYGLOT_LANGUAGE) .allowHostAccess(HostAccess.EXPLICIT) .option("engine.WarnInterpreterOnly", "false") .build(); + + Field wrapperFactory = JsWrapperFactoryProvider.class.getDeclaredField("jsWrapperBaseFactory"); + wrapperFactory.setAccessible(true); + wrapperFactory.set(JsWrapperFactoryProvider.getInstance(), new JsGraalWrapperFactory()); + } @Test diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsNashornAuthenticationContextTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsNashornAuthenticationContextTest.java index 4efbc8a8d065..0788d9051b7d 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsNashornAuthenticationContextTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsNashornAuthenticationContextTest.java @@ -24,6 +24,8 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.SequenceConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthenticationGraph; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactoryProvider; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornAuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; @@ -32,6 +34,7 @@ import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import org.wso2.carbon.identity.application.common.model.ClaimMapping; +import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; @@ -59,9 +62,12 @@ public class JsNashornAuthenticationContextTest { private ScriptEngine scriptEngine; @BeforeClass - public void setUp() { + public void setUp() throws NoSuchFieldException, IllegalAccessException { scriptEngine = new ScriptEngineManager().getEngineByName("nashorn"); + Field wrapperFactory = JsWrapperFactoryProvider.class.getDeclaredField("jsWrapperBaseFactory"); + wrapperFactory.setAccessible(true); + wrapperFactory.set(JsWrapperFactoryProvider.getInstance(), new JsWrapperFactory()); } @Test From d12602f49772083260e3a07e21151ce12591bce8 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Fri, 1 Mar 2024 15:18:49 +0530 Subject: [PATCH 22/35] Expost GraalJS Proxy Objects as their abstract parent classes in GraalJS script execution --- .../config/model/graph/JsGraphBuilder.java | 11 +++++- .../graph/graaljs/JsGraalGraphBuilder.java | 38 ++++++++++++++----- .../graaljs/JsGraalGraphBuilderFactory.java | 24 +++++++++++- 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java index b6b929b4fe2b..dad3ee475155 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java @@ -505,7 +505,7 @@ public String loadLocalLibrary(String functionLibraryName) throws FunctionLibrar /** * Load Executor implementation to load local libraries. */ - public class LoadExecutorImpl implements LoadExecutor { + public class JsGraalLoadExecutorImpl implements LoadExecutor { @HostAccess.Export public String loadLocalLibrary(String libraryName) throws FunctionLibraryManagementException { @@ -662,6 +662,15 @@ public interface LoadExecutor { String loadLocalLibrary(String libraryName) throws FunctionLibraryManagementException; } + /** + * Functional interface for sending error in the authentication script. + */ + @FunctionalInterface + public interface SendErrorFunction { + + void sendError(String url, Map parameterMap); + } + @Deprecated public void exitFunction(Object... arg) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java index 4d033d4f23f8..1dcce98e3e8c 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java @@ -53,7 +53,6 @@ import java.util.Map; import java.util.Optional; import java.util.UUID; -import java.util.function.BiConsumer; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -143,9 +142,9 @@ public JsGraalGraphBuilder createWith(String script) { Value bindings = context.getBindings(POLYGLOT_LANGUAGE); bindings.putMember(JS_FUNC_EXECUTE_STEP, new JsGraalStepExecuter()); - bindings.putMember(JS_FUNC_SEND_ERROR, (BiConsumer) this::sendError); - bindings.putMember(JS_FUNC_SHOW_PROMPT, new PromptExecutorImpl()); - bindings.putMember(JS_FUNC_LOAD_FUNC_LIB, new LoadExecutorImpl()); + bindings.putMember(JS_FUNC_SEND_ERROR, new SendErrorAsyncFunctionImpl()); + bindings.putMember(JS_FUNC_SHOW_PROMPT, new JsGraalPromptExecutorImpl()); + bindings.putMember(JS_FUNC_LOAD_FUNC_LIB, new JsGraalLoadExecutorImpl()); JsFunctionRegistry jsFunctionRegistrar = FrameworkServiceDataHolder.getInstance().getJsFunctionRegistry(); if (jsFunctionRegistrar != null) { Map functionMap = @@ -516,6 +515,27 @@ public static void sendErrorAsync(String url, Map parameterMap) } } + /** + * Implementation of the SendErrorFunction interface as an adaptor for sendErrorAsync function. + */ + public static class SendErrorAsyncFunctionImpl implements SendErrorFunction { + + @HostAccess.Export + public void sendError(String url, Map parameterMap) { + sendErrorAsync(url, parameterMap); + } + } + + /** + * Implementation of the SendErrorFunction interface as an adaptor for sendError function. + */ + public class SendErrorFunctionImpl implements SendErrorFunction { + + @HostAccess.Export + public void sendError(String url, Map parameterMap) { + JsGraalGraphBuilder.this.sendError(url, parameterMap); + } + } private static FailNode createFailNode(String url, Map parameterMap, boolean isShowErrorPage) { FailNode failNode = new FailNode(); @@ -564,10 +584,10 @@ public Object evaluate(AuthenticationContext authenticationContext, Object... pa Value bindings = context.getBindings(POLYGLOT_LANGUAGE); bindings.putMember(JS_FUNC_EXECUTE_STEP, new JsGraalStepExecuterInAsyncEvent()); - bindings.putMember(JS_FUNC_SEND_ERROR, (BiConsumer) JsGraalGraphBuilder::sendErrorAsync); + bindings.putMember(JS_FUNC_SEND_ERROR, new SendErrorFunctionImpl()); bindings.putMember(JS_AUTH_FAILURE, new FailAuthenticationFunctionImpl()); - bindings.putMember(JS_FUNC_SHOW_PROMPT, new PromptExecutorImpl()); - bindings.putMember(JS_FUNC_LOAD_FUNC_LIB, new LoadExecutorImpl()); + bindings.putMember(JS_FUNC_SHOW_PROMPT, new JsGraalPromptExecutorImpl()); + bindings.putMember(JS_FUNC_LOAD_FUNC_LIB, new JsGraalLoadExecutorImpl()); JsFunctionRegistry jsFunctionRegistrar = FrameworkServiceDataHolder.getInstance().getJsFunctionRegistry(); if (jsFunctionRegistrar != null) { @@ -657,7 +677,7 @@ public void addShowPrompt(String templateId, Object... parameters) { /** * GraalJS specific prompt implementation */ - public class PromptExecutorImpl implements PromptExecutor { + public class JsGraalPromptExecutorImpl implements PromptExecutor { @HostAccess.Export public void prompt(String templateId, Object... parameters) { @@ -695,7 +715,7 @@ public static void failAsync(Object... parameters) { /** * Fail function implementation for GraalJS. */ - public class FailAuthenticationFunctionImpl implements FailAuthenticationFunction { + public static class FailAuthenticationFunctionImpl implements FailAuthenticationFunction { @HostAccess.Export public void fail(Object... parameters) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java index 7f31adcf8a1a..7b581da8f2d2 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java @@ -29,7 +29,12 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsSerializer; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.AbstractJSObjectWrapper; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsLogger; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsServletRequest; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsServletResponse; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalAuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; import org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.GraalSelectAcrFromFunction; @@ -95,8 +100,25 @@ public static void persistCurrentContext(AuthenticationContext authContext, Cont public Context createEngine(AuthenticationContext authenticationContext) { + HostAccess.Builder hostAccess = HostAccess.newBuilder(HostAccess.EXPLICIT); + /* + * We need to map the graaljs proxy objects be exposed as their abstract classes to be able to use the current + * functional interfaces we have for existing conditional authentication functions. + */ + hostAccess.targetTypeMapping(Value.class, JsAuthenticationContext.class, + (v) -> v.asProxyObject() instanceof JsAuthenticationContext, + (v) -> (JsAuthenticationContext) v.asProxyObject()); + hostAccess.targetTypeMapping(Value.class, JsAuthenticatedUser.class, + (v) -> v.asProxyObject() instanceof JsGraalAuthenticatedUser, + (v) -> (JsAuthenticatedUser) v.asProxyObject()); + hostAccess.targetTypeMapping(Value.class, JsServletRequest.class, + (v) -> v.asProxyObject() instanceof JsServletRequest, + (v) -> (JsServletRequest) v.asProxyObject()); + hostAccess.targetTypeMapping(Value.class, JsServletResponse.class, + (v) -> v.asProxyObject() instanceof JsServletResponse, + (v) -> (JsServletResponse) v.asProxyObject()); Context context = Context.newBuilder(POLYGLOT_LANGUAGE) - .allowHostAccess(HostAccess.EXPLICIT) + .allowHostAccess(hostAccess.build()) .option("engine.WarnInterpreterOnly", "false") .build(); From 53e7a9c8210d7392f0c27f4131aa434cd0ea022d Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Mon, 4 Mar 2024 09:52:41 +0530 Subject: [PATCH 23/35] Fix errors due to refactoring of proxy objects --- .../config/model/graph/JsGraphBuilder.java | 2 -- .../model/graph/graaljs/JsGraalWrapperFactory.java | 5 +++-- .../js/nashorn/JsNashornAuthenticationContext.java | 14 +++----------- .../JsOpenJdkNashornAuthenticationContext.java | 14 +++----------- 4 files changed, 9 insertions(+), 26 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java index dad3ee475155..c03f8bcc2828 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java @@ -483,7 +483,6 @@ public static void addPrompt(String templateId, Map parameters, * @return functionLibraryScript * @throws FunctionLibraryManagementException */ - @HostAccess.Export public String loadLocalLibrary(String functionLibraryName) throws FunctionLibraryManagementException { FunctionLibraryManagementService functionLibMgtService = FrameworkServiceComponent. @@ -629,7 +628,6 @@ public interface FailAuthenticationFunction { @FunctionalInterface public interface StepExecutor { - @HostAccess.Export void executeStep(Integer stepId, Object... parameterMap); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java index bd0f64a7c5a3..e9130bec5152 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalWrapperFactory.java @@ -30,6 +30,7 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalClaims; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalCookie; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalHeaders; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalParameters; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalRuntimeClaims; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalServletRequest; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.graaljs.JsGraalServletResponse; @@ -86,9 +87,9 @@ public JsGraalCookie createJsCookie(Cookie cookie) { } @Override - public JsGraalWritableParameters createJsParameters(Map parameters) { + public JsGraalParameters createJsParameters(Map parameters) { - return new JsGraalWritableParameters(parameters); + return new JsGraalParameters(parameters); } @Override diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticationContext.java index 174486a3894d..08018349c77f 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornAuthenticationContext.java @@ -20,7 +20,6 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; /** * Javascript wrapper for Java level AuthenticationContext. @@ -47,21 +46,14 @@ public JsNashornAuthenticationContext(AuthenticationContext wrapped) { public void setMember(String name, Object value) { - boolean isSet = super.setMemberObject(name, value); - if (!isSet) { - AbstractJsObject.super.setMember(name, value); - } + super.setMemberObject(name, value); } @Override public void removeMember(String name) { - switch (name) { - case FrameworkConstants.JSAttributes.JS_SELECTED_ACR: - getWrapped().setSelectedAcr(null); - break; - default: - AbstractJsObject.super.removeMember(name); + if (!super.removeMemberObject(name)) { + AbstractJsObject.super.removeMember(name); } } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticationContext.java index 42e2edb15380..71ac923a256e 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornAuthenticationContext.java @@ -20,7 +20,6 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; /** * Javascript wrapper for Java level AuthenticationContext. @@ -48,21 +47,14 @@ public JsOpenJdkNashornAuthenticationContext(AuthenticationContext wrapped) { public void setMember(String name, Object value) { - boolean isSet = super.setMemberObject(name, value); - if (!isSet) { - AbstractOpenJdkNashornJsObject.super.setMember(name, value); - } + super.setMemberObject(name, value); } @Override public void removeMember(String name) { - switch (name) { - case FrameworkConstants.JSAttributes.JS_SELECTED_ACR: - getWrapped().setSelectedAcr(null); - break; - default: - AbstractOpenJdkNashornJsObject.super.removeMember(name); + if (!super.removeMemberObject(name)) { + AbstractOpenJdkNashornJsObject.super.removeMember(name); } } } From 34fbef76efbfd4d5186d0808d2f9d0bf9013bd82 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Wed, 6 Mar 2024 15:07:03 +0530 Subject: [PATCH 24/35] Following changes are made with this commit * Add statement limit config for javascript execution * Fix hasMember logic for JsAuthenticatedUser --- .../graaljs/JsGraalGraphBuilderFactory.java | 69 ++++++++++++++----- .../model/graph/js/JsAuthenticatedUser.java | 3 +- .../framework/util/FrameworkConstants.java | 1 + .../resources/identity.xml.j2 | 1 + 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java index 7b581da8f2d2..22adcd2dcbc5 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java @@ -22,6 +22,7 @@ import org.apache.commons.logging.LogFactory; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.HostAccess; +import org.graalvm.polyglot.ResourceLimits; import org.graalvm.polyglot.Value; import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthGraphNode; @@ -38,6 +39,7 @@ import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; import org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.GraalSelectAcrFromFunction; +import org.wso2.carbon.identity.core.util.IdentityUtil; import java.util.HashMap; import java.util.Map; @@ -45,6 +47,7 @@ import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.JS_FUNC_SELECT_ACR_FROM; import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.JS_LOG; import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.SCRIPT_STATEMENTS_LIMIT; /** * Factory to create a Javascript based sequence builder. @@ -56,9 +59,11 @@ public class JsGraalGraphBuilderFactory implements JsBaseGraphBuilderFactory v.asProxyObject() instanceof JsAuthenticationContext, - (v) -> (JsAuthenticationContext) v.asProxyObject()); - hostAccess.targetTypeMapping(Value.class, JsAuthenticatedUser.class, - (v) -> v.asProxyObject() instanceof JsGraalAuthenticatedUser, - (v) -> (JsAuthenticatedUser) v.asProxyObject()); - hostAccess.targetTypeMapping(Value.class, JsServletRequest.class, - (v) -> v.asProxyObject() instanceof JsServletRequest, - (v) -> (JsServletRequest) v.asProxyObject()); - hostAccess.targetTypeMapping(Value.class, JsServletResponse.class, - (v) -> v.asProxyObject() instanceof JsServletResponse, - (v) -> (JsServletResponse) v.asProxyObject()); Context context = Context.newBuilder(POLYGLOT_LANGUAGE) - .allowHostAccess(hostAccess.build()) + .allowHostAccess(getHostAccess()) + .resourceLimits(getResourceLimits()) .option("engine.WarnInterpreterOnly", "false") .build(); @@ -128,6 +117,35 @@ public Context createEngine(AuthenticationContext authenticationContext) { return context; } + public ResourceLimits getResourceLimits() { + + ResourceLimits.Builder resourceLimitsBuilder = ResourceLimits.newBuilder(); + resourceLimitsBuilder.statementLimit(javascriptResourceLimit, null); + return resourceLimitsBuilder.build(); + } + + public HostAccess getHostAccess() { + + /* + * We need to map the graaljs proxy objects be exposed as their abstract classes to be able to use the current + * functional interfaces we have for existing conditional authentication functions. + */ + return HostAccess.newBuilder(HostAccess.EXPLICIT) + .targetTypeMapping(Value.class, JsAuthenticationContext.class, + (v) -> v.asProxyObject() instanceof JsAuthenticationContext, + (v) -> (JsAuthenticationContext) v.asProxyObject()) + .targetTypeMapping(Value.class, JsAuthenticatedUser.class, + (v) -> v.asProxyObject() instanceof JsGraalAuthenticatedUser, + (v) -> (JsAuthenticatedUser) v.asProxyObject()) + .targetTypeMapping(Value.class, JsServletRequest.class, + (v) -> v.asProxyObject() instanceof JsServletRequest, + (v) -> (JsServletRequest) v.asProxyObject()) + .targetTypeMapping(Value.class, JsServletResponse.class, + (v) -> v.asProxyObject() instanceof JsServletResponse, + (v) -> (JsServletResponse) v.asProxyObject()) + .build(); + } + @Override public JsSerializer getJsUtil() { @@ -153,4 +171,19 @@ public JsGraalGraphBuilder createBuilder(AuthenticationContext authenticationCon currentNode); } + private void setJavascriptResourceLimit() { + + String statementLimit = IdentityUtil.getProperty(SCRIPT_STATEMENTS_LIMIT); + int defaultLimit = 500; + if (statementLimit != null) { + try { + javascriptResourceLimit = Integer.parseInt(statementLimit); + } catch (NumberFormatException e) { + LOG.warn("Error while parsing the script statement limit. Defaulting to " + defaultLimit, e); + javascriptResourceLimit = defaultLimit; + } + } else { + javascriptResourceLimit = defaultLimit; + } + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticatedUser.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticatedUser.java index 5554e15ac92a..23876b3aa439 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticatedUser.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticatedUser.java @@ -197,9 +197,8 @@ public boolean hasMember(String name) { return getWrapped().getTenantDomain() != null; case FrameworkConstants.JSAttributes.JS_CLAIMS: case FrameworkConstants.JSAttributes.JS_LOCAL_CLAIMS: - return idp != null; case FrameworkConstants.JSAttributes.JS_REMOTE_CLAIMS: - return idp != null && !FrameworkConstants.LOCAL.equals(idp); + return true; default: return super.hasMember(name); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java index 3617d2c8ead0..dac14e502404 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java @@ -226,6 +226,7 @@ public abstract class FrameworkConstants { public static final String SCRIPT_ENGINE_CONFIG = "AdaptiveAuth.ScriptEngine"; public static final String THREAD_LOCAL_SCRIPT_ENGINE_CONFIG = "AdaptiveAuth.LimitScriptEngineCreation"; + public static final String SCRIPT_STATEMENTS_LIMIT = "AdaptiveAuth.StatementsLimit"; public static final String OPENJDK_NASHORN = "openjdkNashorn"; public static final String NASHORN = "nashorn"; public static final String GRAAL_JS = "graaljs"; diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 index 79d8ba00aaf0..5034bdaf35f6 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 @@ -1206,6 +1206,7 @@ {{AdaptiveAuth.ScriptEngine}} {{AdaptiveAuth.LimitScriptEngineCreation}} + {{AdaptiveAuth.StatementsLimit}} From 26158043c074a2003ba471bf77e003e7b2651861 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Wed, 6 Mar 2024 20:31:35 +0530 Subject: [PATCH 25/35] Add following new generic parent interfaces for graph builder related interfaces * GenericSerializableJsFunction * JsGenericGraphBuilderFactory * JsGenericSerializer --- .../pom.xml | 1 - .../loader/UIBasedConfigurationLoader.java | 6 +-- .../graph/BaseSerializableJsFunction.java | 7 ++- .../model/graph/DynamicDecisionNode.java | 24 +++++++++- .../graph/GenericSerializableJsFunction.java | 44 +++++++++++++++++ .../model/graph/JsBaseGraphBuilder.java | 5 ++ .../graph/JsBaseGraphBuilderFactory.java | 7 +-- .../graph/JsGenericGraphBuilderFactory.java | 46 ++++++++++++++++++ .../model/graph/JsGenericSerializer.java | 48 +++++++++++++++++++ .../config/model/graph/JsGraphBuilder.java | 4 +- .../model/graph/JsGraphBuilderFactory.java | 2 +- .../model/graph/JsNashornGraphBuilder.java | 17 ++++--- .../model/graph/JsNashornSerializer.java | 2 +- .../config/model/graph/JsSerializer.java | 7 +-- .../model/graph/JsWrapperFactoryProvider.java | 4 +- .../model/graph/SerializableJsFunction.java | 2 +- .../config/model/graph/ShowPromptNode.java | 30 +++++++++++- .../graaljs/GraalSerializableJsFunction.java | 4 +- .../model/graph/graaljs/GraalSerializer.java | 4 +- .../graph/graaljs/JsGraalGraphBuilder.java | 21 +++++--- .../graaljs/JsGraalGraphBuilderFactory.java | 8 ++-- .../nashorn/JsOpenJdkNashornGraphBuilder.java | 16 +++++-- .../JsOpenJdkNashornGraphBuilderFactory.java | 2 +- .../nashorn/JsOpenJdkNashornSerializer.java | 2 +- .../OpenJdkNashornSerializableJsFunction.java | 2 +- .../impl/GraphBasedSequenceHandler.java | 20 ++++---- .../internal/FrameworkServiceComponent.java | 6 +-- .../internal/FrameworkServiceDataHolder.java | 16 ++++++- .../framework/util/FrameworkUtils.java | 13 ++++- ...GraphBasedSequenceHandlerAbstractTest.java | 6 +-- 30 files changed, 306 insertions(+), 70 deletions(-) create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/GenericSerializableJsFunction.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGenericGraphBuilderFactory.java create mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGenericSerializer.java diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml index 92ca384a7887..073207a47c38 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/pom.xml @@ -151,7 +151,6 @@ com.ibm.icu icu4j - org.testng testng diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/loader/UIBasedConfigurationLoader.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/loader/UIBasedConfigurationLoader.java index b2bb62b3a851..dfa705ab168d 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/loader/UIBasedConfigurationLoader.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/loader/UIBasedConfigurationLoader.java @@ -27,7 +27,7 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthenticationGraph; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilder; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilderFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGenericGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; import org.wso2.carbon.identity.application.authentication.framework.internal.FrameworkServiceComponent; @@ -88,8 +88,8 @@ public SequenceConfig getSequenceConfig(AuthenticationContext context, Map stepConfigMapCopy = new HashMap<>(); originalStepConfigMap.forEach((k, v) -> stepConfigMapCopy.put(k, new StepConfig(v))); sequenceConfig.getStepMap().clear(); - JsBaseGraphBuilderFactory jsGraphBuilderFactory = FrameworkServiceDataHolder.getInstance() - .getJsGraphBuilderFactory(); + JsGenericGraphBuilderFactory jsGraphBuilderFactory = FrameworkServiceDataHolder.getInstance() + .getJsGenericGraphBuilderFactory(); JsBaseGraphBuilder jsGraphBuilder = jsGraphBuilderFactory.createBuilder(context, stepConfigMapCopy); context.setServiceProviderName(serviceProvider.getApplicationName()); context.setServiceProviderResourceId(serviceProvider.getApplicationResourceId()); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/BaseSerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/BaseSerializableJsFunction.java index e07210f5f001..281745c1373a 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/BaseSerializableJsFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/BaseSerializableJsFunction.java @@ -18,7 +18,7 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph; -import java.io.Serializable; +import javax.script.ScriptEngine; /** * Serializable javascript function. @@ -27,9 +27,8 @@ * The request may come to different node. * The current authentication context holds this function in serialized form. * - * @param Script Engine */ -public interface BaseSerializableJsFunction extends Serializable { +public interface BaseSerializableJsFunction extends GenericSerializableJsFunction { void setSource(String name); @@ -39,6 +38,6 @@ public interface BaseSerializableJsFunction extends Serializable { void setFunction(boolean function); - Object apply(T scriptEngine, Object... params); + Object apply(ScriptEngine scriptEngine, Object... params); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/DynamicDecisionNode.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/DynamicDecisionNode.java index e69285307110..73c1d773aced 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/DynamicDecisionNode.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/DynamicDecisionNode.java @@ -29,7 +29,7 @@ public class DynamicDecisionNode extends AbstractAuthGraphNode implements AuthGraphNode { private static final long serialVersionUID = -2151385170280964420L; - private Map functionMap = new HashMap<>(); + private Map functionMap = new HashMap<>(); private AuthGraphNode defaultEdge; @Override @@ -39,6 +39,15 @@ public String getName() { } public Map getFunctionMap() { + + if (isFunctionMapInstanceOfBaseSerializableJsFunction()) { + return Collections.unmodifiableMap((Map) (Map) functionMap); + } + return null; + } + + public Map getGenericFunctionMap() { + return Collections.unmodifiableMap(functionMap); } @@ -46,6 +55,10 @@ public void addFunction(String outcome, BaseSerializableJsFunction function) { functionMap.put(outcome, function); } + public void addGenericFunction(String outcome, GenericSerializableJsFunction function) { + functionMap.put(outcome, function); + } + public AuthGraphNode getDefaultEdge() { return defaultEdge; } @@ -53,4 +66,13 @@ public AuthGraphNode getDefaultEdge() { public void setDefaultEdge(AuthGraphNode defaultEdge) { this.defaultEdge = defaultEdge; } + + private boolean isFunctionMapInstanceOfBaseSerializableJsFunction() { + + if (functionMap == null || functionMap.isEmpty()) { + return true; + } + // Get the first element of the map and check if that is an instance of BaseSerializableJsFunction + return functionMap.entrySet().iterator().next().getValue() instanceof BaseSerializableJsFunction; + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/GenericSerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/GenericSerializableJsFunction.java new file mode 100644 index 000000000000..bd2b242bcd42 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/GenericSerializableJsFunction.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph; + +import java.io.Serializable; + +/** + * Serializable javascript function. + * This is required since the next javascript execution may happen on a different node than current node, when user + * submits a form in the browser. + * The request may come to different node. + * The current authentication context holds this function in serialized form. + * + * @param Script Engine + */ +public interface GenericSerializableJsFunction extends Serializable { + + void setSource(String name); + + String getSource(); + + boolean isFunction(); + + void setFunction(boolean function); + + Object apply(T scriptEngine, Object... params); + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilder.java index ec4711192704..c79220d6f4c0 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilder.java @@ -41,6 +41,11 @@ public interface JsBaseGraphBuilder { AuthenticationDecisionEvaluator getScriptEvaluator(BaseSerializableJsFunction fn); + default AuthenticationDecisionEvaluator getScriptEvaluator(GenericSerializableJsFunction fn) { + + return null; + } + void addLongWaitProcessInternal(AsyncProcess asyncProcess, Map parameterMap); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilderFactory.java index d0e3214c4cae..cdda2986b485 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsBaseGraphBuilderFactory.java @@ -23,13 +23,14 @@ import java.util.Map; +import javax.script.ScriptEngine; + /** * Interface for Factory to create a Javascript based sequence builder. * This factory is there to reuse of script engine and any related expensive objects. * - * @param Type of the Javascript Engine */ -public interface JsBaseGraphBuilderFactory { +public interface JsBaseGraphBuilderFactory extends JsGenericGraphBuilderFactory { void init(); @@ -38,7 +39,7 @@ public interface JsBaseGraphBuilderFactory { JsBaseGraphBuilder createBuilder(AuthenticationContext authenticationContext, Map stepConfigMap, AuthGraphNode currentNode); - T createEngine(AuthenticationContext authenticationContext); + ScriptEngine createEngine(AuthenticationContext authenticationContext); JsSerializer getJsUtil(); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGenericGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGenericGraphBuilderFactory.java new file mode 100644 index 000000000000..dd6f93b369d3 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGenericGraphBuilderFactory.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph; + +import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; +import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; + +import java.util.Map; + +/** + * Interface for Factory to create a Javascript based sequence builder. + * This factory is there to reuse of script engine and any related expensive objects. + * + * @param Type of the Javascript Engine + */ +public interface JsGenericGraphBuilderFactory { + + void init(); + + JsBaseGraphBuilder createBuilder(AuthenticationContext context, Map stepConfigMapCopy); + + JsBaseGraphBuilder createBuilder(AuthenticationContext authenticationContext, + Map stepConfigMap, AuthGraphNode currentNode); + + T createEngine(AuthenticationContext authenticationContext); + + JsGenericSerializer getJsUtil(); + + JsBaseGraphBuilder getCurrentBuilder(); +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGenericSerializer.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGenericSerializer.java new file mode 100644 index 000000000000..5cbbafd79866 --- /dev/null +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGenericSerializer.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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. + */ + +package org.wso2.carbon.identity.application.authentication.framework.config.model.graph; + +import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; + +/** + * Interface for serializer class supports Multiple JS Engines. + * + * @param Js Engine. + */ +public interface JsGenericSerializer { + + /** + * Serialize the object using selected serializable function. + * + * @param value Object to evaluate. + * @return Serialized Object. + */ + Object toJsSerializable(Object value); + + /** + * De-Serialize the object using selected serializable function. + * + * @param value Serialized Object. + * @param engine Js Engine. + * @return De-Serialize object. + * @throws FrameworkException FrameworkException. + */ + Object fromJsSerializable(Object value, T engine) throws FrameworkException; + +} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java index c03f8bcc2828..8694677d50eb 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilder.java @@ -472,7 +472,7 @@ protected void authenticatorParamsOptions(Map options, StepConfi public static void addPrompt(String templateId, Map parameters, Map handlers, Map callbacks) { - FrameworkServiceDataHolder.getInstance().getJsGraphBuilderFactory().getCurrentBuilder() + FrameworkServiceDataHolder.getInstance().getJsGenericGraphBuilderFactory().getCurrentBuilder() .addPromptInternal(templateId, parameters, handlers, callbacks); } @@ -521,7 +521,7 @@ public String loadLocalLibrary(String libraryName) throws FunctionLibraryManagem public static void addLongWaitProcess(AsyncProcess asyncProcess, Map parameterMap) { - FrameworkServiceDataHolder.getInstance().getJsGraphBuilderFactory().getCurrentBuilder() + FrameworkServiceDataHolder.getInstance().getJsGenericGraphBuilderFactory().getCurrentBuilder() .addLongWaitProcessInternal(asyncProcess, parameterMap); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilderFactory.java index 06ad45c789ec..0d4d806a97bf 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsGraphBuilderFactory.java @@ -45,7 +45,7 @@ * Factory to create a Javascript based sequence builder. * This factory is there to reuse of Nashorn engine and any related expnsive objects. */ -public class JsGraphBuilderFactory implements JsBaseGraphBuilderFactory { +public class JsGraphBuilderFactory implements JsBaseGraphBuilderFactory { private static final Log LOG = LogFactory.getLog(JsGraphBuilderFactory.class); private static final String JS_BINDING_CURRENT_CONTEXT = "JS_BINDING_CURRENT_CONTEXT"; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsNashornGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsNashornGraphBuilder.java index 9455106702ef..52f18ae6f8d9 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsNashornGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsNashornGraphBuilder.java @@ -143,6 +143,12 @@ public AuthenticationGraph build() { return result; } + @Override + public AuthenticationDecisionEvaluator getScriptEvaluator(GenericSerializableJsFunction fn) { + + return new JsBasedEvaluator((SerializableJsFunction) fn); + } + /** * Creates the graph with the given Script and step map. * @@ -843,7 +849,7 @@ private static void attachEventListeners(Map eventsMap, AuthGrap } DynamicDecisionNode decisionNode = new DynamicDecisionNode(); addEventListeners(decisionNode, eventsMap); - if (!decisionNode.getFunctionMap().isEmpty()) { + if (!decisionNode.getGenericFunctionMap().isEmpty()) { attachToLeaf(currentNode, decisionNode); } } @@ -855,7 +861,7 @@ private void attachEventListeners(Map eventsMap) { } DynamicDecisionNode decisionNode = new DynamicDecisionNode(); addEventListeners(decisionNode, eventsMap); - if (!decisionNode.getFunctionMap().isEmpty()) { + if (!decisionNode.getGenericFunctionMap().isEmpty()) { attachToLeaf(currentNode, decisionNode); currentNode = decisionNode; } @@ -898,12 +904,12 @@ private static void addHandlers(ShowPromptNode showPromptNode, Map { +public class JsNashornSerializer implements JsSerializer { private static final Log log = LogFactory.getLog(JsNashornSerializer.class); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsSerializer.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsSerializer.java index 591249b5ae8a..180172a86477 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsSerializer.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsSerializer.java @@ -20,12 +20,13 @@ import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; +import javax.script.ScriptEngine; + /** * Interface for serializer class supports Multiple JS Engines. * - * @param Js Engine. */ -public interface JsSerializer { +public interface JsSerializer extends JsGenericSerializer { /** * Serialize the object using selected serializable function. @@ -43,6 +44,6 @@ public interface JsSerializer { * @return De-Serialize object. * @throws FrameworkException FrameworkException. */ - Object fromJsSerializable(Object value, T engine) throws FrameworkException; + Object fromJsSerializable(Object value, ScriptEngine engine) throws FrameworkException; } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactoryProvider.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactoryProvider.java index f39e92b3d95c..087e220f3db2 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactoryProvider.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactoryProvider.java @@ -36,10 +36,10 @@ public class JsWrapperFactoryProvider { private JsWrapperFactoryProvider() { if (FrameworkServiceDataHolder.getInstance() - .getJsGraphBuilderFactory() instanceof JsOpenJdkNashornGraphBuilderFactory) { + .getJsGenericGraphBuilderFactory() instanceof JsOpenJdkNashornGraphBuilderFactory) { jsWrapperBaseFactory = new JsOpenJdkNashornWrapperFactory(); } else if (FrameworkServiceDataHolder.getInstance() - .getJsGraphBuilderFactory() instanceof JsGraalGraphBuilderFactory) { + .getJsGenericGraphBuilderFactory() instanceof JsGraalGraphBuilderFactory) { jsWrapperBaseFactory = new JsGraalWrapperFactory(); } else { jsWrapperBaseFactory = new JsWrapperFactory(); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/SerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/SerializableJsFunction.java index aa039c050ea8..03547862d903 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/SerializableJsFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/SerializableJsFunction.java @@ -33,7 +33,7 @@ /** * Javascript function wrapper. This allows serialization of a javascript defined function. */ -public class SerializableJsFunction implements BaseSerializableJsFunction { +public class SerializableJsFunction implements BaseSerializableJsFunction { private static final Log log = LogFactory.getLog(SerializableJsFunction.class); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/ShowPromptNode.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/ShowPromptNode.java index 3c8217f3ab3a..6c2164d57d8e 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/ShowPromptNode.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/ShowPromptNode.java @@ -35,7 +35,7 @@ public class ShowPromptNode extends DynamicDecisionNode implements AuthGraphNode private String templateId; private Map data; private Map parameters; - private Map handlerMap = new HashMap<>(); + private Map handlerMap = new HashMap<>(); public String getTemplateId() { @@ -69,11 +69,26 @@ public void setParameters(Map parameters) { public Map getHandlerMap() { + if (isHandlerMapInstanceOfBaseSerializableJsFunction()) { + return Collections.unmodifiableMap((Map) (Map) handlerMap); + } + return null; + } + + public Map getGenericHandlerMap() { + return Collections.unmodifiableMap(handlerMap); } public void setHandlerMap(Map handlerMap) { + if (isHandlerMapInstanceOfBaseSerializableJsFunction()) { + this.handlerMap = (Map) (Map) handlerMap; + } + } + + public void setGenericHandlerMap(Map handlerMap) { + this.handlerMap = handlerMap; } @@ -81,9 +96,22 @@ public void addHandler(String outcome, BaseSerializableJsFunction function) { handlerMap.put(outcome, function); } + public void addGenericHandler(String outcome, GenericSerializableJsFunction function) { + handlerMap.put(outcome, function); + } + @Override public String getName() { return "ShowPromptNode"; } + + private boolean isHandlerMapInstanceOfBaseSerializableJsFunction() { + + if (handlerMap == null || handlerMap.isEmpty()) { + return true; + } + // Get the first element of the map and check if that is an instance of BaseSerializableJsFunction + return handlerMap.entrySet().iterator().next().getValue() instanceof BaseSerializableJsFunction; + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java index d8a31d827ed6..82967d74e1f2 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializableJsFunction.java @@ -23,7 +23,7 @@ import org.graalvm.polyglot.Context; import org.graalvm.polyglot.PolyglotException; import org.graalvm.polyglot.Value; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.BaseSerializableJsFunction; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.GenericSerializableJsFunction; import java.util.function.Function; @@ -31,7 +31,7 @@ * Javascript function wrapper. This allows serialization of a javascript defined function. * Since Nashorn is deprecated in JDK 11 and onwards. We replaced it with GraalJS classes. */ -public class GraalSerializableJsFunction implements BaseSerializableJsFunction { +public class GraalSerializableJsFunction implements GenericSerializableJsFunction { private static final Log log = LogFactory.getLog(GraalSerializableJsFunction.class); private static final long serialVersionUID = -7001351065432647040L; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java index bada6360f198..c15bd311f2ca 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java @@ -22,7 +22,7 @@ import org.apache.commons.logging.LogFactory; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Value; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsSerializer; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGenericSerializer; import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; import java.io.Serializable; @@ -37,7 +37,7 @@ /** * Serializer class supports GraalJS Engine. */ -public class GraalSerializer implements JsSerializer { +public class GraalSerializer implements JsGenericSerializer { private static final Log log = LogFactory.getLog(GraalSerializer.class); private static final GraalSerializer graalSerializer = new GraalSerializer(); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java index 1dcce98e3e8c..3791f4529236 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilder.java @@ -36,6 +36,7 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.BaseSerializableJsFunction; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.DynamicDecisionNode; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.FailNode; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.GenericSerializableJsFunction; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JSExecutionMonitorData; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JSExecutionSupervisor; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGraphBuilder; @@ -200,6 +201,12 @@ public JsGraalGraphBuilder createWith(String script) { return this; } + @Override + public AuthenticationDecisionEvaluator getScriptEvaluator(BaseSerializableJsFunction fn) { + + return null; + } + private static void attachEventListeners(Map eventsMap, AuthGraphNode currentNode) { if (eventsMap == null) { @@ -207,7 +214,7 @@ private static void attachEventListeners(Map eventsMap, AuthGrap } DynamicDecisionNode decisionNode = new DynamicDecisionNode(); addEventListeners(decisionNode, eventsMap); - if (!decisionNode.getFunctionMap().isEmpty()) { + if (!decisionNode.getGenericFunctionMap().isEmpty()) { attachToLeaf(currentNode, decisionNode); } } @@ -219,7 +226,7 @@ private void attachEventListeners(Map eventsMap) { } DynamicDecisionNode decisionNode = new DynamicDecisionNode(); addEventListeners(decisionNode, eventsMap); - if (!decisionNode.getFunctionMap().isEmpty()) { + if (!decisionNode.getGenericFunctionMap().isEmpty()) { attachToLeaf(currentNode, decisionNode); currentNode = decisionNode; } @@ -240,12 +247,12 @@ private static void addEventListeners(DynamicDecisionNode decisionNode, Map parameters, addHandlers(newNode, handlers); } - public AuthenticationDecisionEvaluator getScriptEvaluator(BaseSerializableJsFunction fn) { + public AuthenticationDecisionEvaluator getScriptEvaluator(GenericSerializableJsFunction fn) { return new JsBasedEvaluator((GraalSerializableJsFunction) fn); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java index 22adcd2dcbc5..dde9aca75d8d 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java @@ -27,8 +27,8 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthGraphNode; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilder; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilderFactory; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsSerializer; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGenericGraphBuilderFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGenericSerializer; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.AbstractJSObjectWrapper; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext; @@ -55,7 +55,7 @@ *

* Since Nashorn is deprecated in JDK 11 and onwards. We are introducing GraalJS engine. */ -public class JsGraalGraphBuilderFactory implements JsBaseGraphBuilderFactory { +public class JsGraalGraphBuilderFactory implements JsGenericGraphBuilderFactory { private static final Log LOG = LogFactory.getLog(JsGraalGraphBuilderFactory.class); private static final String JS_BINDING_CURRENT_CONTEXT = "JS_BINDING_CURRENT_CONTEXT"; @@ -147,7 +147,7 @@ public HostAccess getHostAccess() { } @Override - public JsSerializer getJsUtil() { + public JsGenericSerializer getJsUtil() { return GraalSerializer.getInstance(); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornGraphBuilder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornGraphBuilder.java index e84b733e61e2..105162ae4807 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornGraphBuilder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornGraphBuilder.java @@ -35,6 +35,7 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.DynamicDecisionNode; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.EndStep; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.FailNode; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.GenericSerializableJsFunction; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JSExecutionMonitorData; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JSExecutionSupervisor; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGraphBuilder; @@ -161,6 +162,11 @@ public AuthenticationGraph build() { } @Override + public AuthenticationDecisionEvaluator getScriptEvaluator(GenericSerializableJsFunction fn) { + + return new JsBasedEvaluator((OpenJdkNashornSerializableJsFunction) fn); + } + public AuthenticationDecisionEvaluator getScriptEvaluator(BaseSerializableJsFunction fn) { return new JsBasedEvaluator((OpenJdkNashornSerializableJsFunction) fn); @@ -868,7 +874,7 @@ private static void attachEventListeners(Map eventsMap, AuthGrap } DynamicDecisionNode decisionNode = new DynamicDecisionNode(); addEventListeners(decisionNode, eventsMap); - if (!decisionNode.getFunctionMap().isEmpty()) { + if (!decisionNode.getGenericFunctionMap().isEmpty()) { attachToLeaf(currentNode, decisionNode); } } @@ -880,7 +886,7 @@ private void attachEventListeners(Map eventsMap) { } DynamicDecisionNode decisionNode = new DynamicDecisionNode(); addEventListeners(decisionNode, eventsMap); - if (!decisionNode.getFunctionMap().isEmpty()) { + if (!decisionNode.getGenericFunctionMap().isEmpty()) { attachToLeaf(currentNode, decisionNode); currentNode = decisionNode; } @@ -923,12 +929,12 @@ private static void addHandlers(ShowPromptNode showPromptNode, Map * Since Nashorn is deprecated in JDK 11 and onwards. We are introducing OpenJDK Nashorn engine. */ -public class JsOpenJdkNashornGraphBuilderFactory implements JsBaseGraphBuilderFactory { +public class JsOpenJdkNashornGraphBuilderFactory implements JsBaseGraphBuilderFactory { private static final Log LOG = LogFactory.getLog(JsOpenJdkNashornGraphBuilderFactory.class); private static final String JS_BINDING_CURRENT_CONTEXT = "JS_BINDING_CURRENT_CONTEXT"; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornSerializer.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornSerializer.java index ae7aa3f556c9..f4b0e25923f0 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornSerializer.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/JsOpenJdkNashornSerializer.java @@ -37,7 +37,7 @@ /** * Serializer class supports Open JDK Nashorn Engine. */ -public class JsOpenJdkNashornSerializer implements JsSerializer { +public class JsOpenJdkNashornSerializer implements JsSerializer { private static final Log log = LogFactory.getLog(JsOpenJdkNashornSerializer.class); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/OpenJdkNashornSerializableJsFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/OpenJdkNashornSerializableJsFunction.java index 40c2b19a2ae7..99c3ece9b66d 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/OpenJdkNashornSerializableJsFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/openjdk/nashorn/OpenJdkNashornSerializableJsFunction.java @@ -35,7 +35,7 @@ * Javascript function wrapper. This allows serialization of a javascript defined function. * Since Nashorn is deprecated in JDK 11 and onwards. We replaced it with OpenJDK Nashorn classes. */ -public class OpenJdkNashornSerializableJsFunction implements BaseSerializableJsFunction { +public class OpenJdkNashornSerializableJsFunction implements BaseSerializableJsFunction { private static final Log log = LogFactory.getLog(OpenJdkNashornSerializableJsFunction.class); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandler.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandler.java index 40854afb9ab7..f73f74884126 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandler.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandler.java @@ -31,12 +31,12 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthGraphNode; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.AuthenticationGraph; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.BaseSerializableJsFunction; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.DynamicDecisionNode; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.EndStep; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.FailNode; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.GenericSerializableJsFunction; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilder; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilderFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGenericGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactoryProvider; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.LongWaitNode; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.ShowPromptNode; @@ -266,7 +266,7 @@ private boolean handlePrompt(HttpServletRequest request, HttpServletResponse res context.setProperty(FrameworkConstants.JSAttributes.PROP_CURRENT_NODE, nextNode); context.setReturning(false); } else { - if (promptNode.getHandlerMap().get(ShowPromptNode.PRE_HANDLER) != null) { + if (promptNode.getGenericHandlerMap().get(ShowPromptNode.PRE_HANDLER) != null) { Object result = evaluateHandler(ShowPromptNode.PRE_HANDLER, promptNode, context, promptNode .getParameters().get(STEP_IDENTIFIER_PARAM)); if (Boolean.TRUE.equals(result)) { @@ -749,7 +749,7 @@ private void handleDecisionPoint(HttpServletRequest request, HttpServletResponse executeFunction("onSuccess", dynamicDecisionNode, context); break; case FAIL_COMPLETED: - if (dynamicDecisionNode.getFunctionMap().get("onFail") != null) { + if (dynamicDecisionNode.getGenericFunctionMap().get("onFail") != null) { executeFunction("onFail", dynamicDecisionNode, context); } else { if (context.isRetrying()) { @@ -778,9 +778,9 @@ private void handleDecisionPoint(HttpServletRequest request, HttpServletResponse private void executeFunction(String outcomeName, DynamicDecisionNode dynamicDecisionNode, AuthenticationContext context) { - BaseSerializableJsFunction fn = dynamicDecisionNode.getFunctionMap().get(outcomeName); + GenericSerializableJsFunction fn = dynamicDecisionNode.getGenericFunctionMap().get(outcomeName); FrameworkServiceDataHolder dataHolder = FrameworkServiceDataHolder.getInstance(); - JsBaseGraphBuilderFactory jsGraphBuilderFactory = dataHolder.getJsGraphBuilderFactory(); + JsGenericGraphBuilderFactory jsGraphBuilderFactory = dataHolder.getJsGenericGraphBuilderFactory(); JsBaseGraphBuilder graphBuilder = jsGraphBuilderFactory.createBuilder(context, context .getSequenceConfig().getAuthenticationGraph().getStepMap(), dynamicDecisionNode); graphBuilder.getScriptEvaluator(fn).evaluate(context, JsWrapperFactoryProvider.getInstance() @@ -794,9 +794,9 @@ private void executeFunction(String outcomeName, DynamicDecisionNode dynamicDeci private void executeFunction(String outcomeName, DynamicDecisionNode dynamicDecisionNode, AuthenticationContext context, Map data) { - BaseSerializableJsFunction fn = dynamicDecisionNode.getFunctionMap().get(outcomeName); + GenericSerializableJsFunction fn = dynamicDecisionNode.getGenericFunctionMap().get(outcomeName); FrameworkServiceDataHolder dataHolder = FrameworkServiceDataHolder.getInstance(); - JsBaseGraphBuilderFactory jsGraphBuilderFactory = dataHolder.getJsGraphBuilderFactory(); + JsGenericGraphBuilderFactory jsGraphBuilderFactory = dataHolder.getJsGenericGraphBuilderFactory(); JsBaseGraphBuilder jsGraphBuilder = jsGraphBuilderFactory.createBuilder(context, context .getSequenceConfig().getAuthenticationGraph().getStepMap(), dynamicDecisionNode); jsGraphBuilder.getScriptEvaluator(fn).evaluate(context, JsWrapperFactoryProvider.getInstance() @@ -811,9 +811,9 @@ private void executeFunction(String outcomeName, DynamicDecisionNode dynamicDeci private Object evaluateHandler(String outcomeName, ShowPromptNode dynamicDecisionNode, AuthenticationContext context, Object stepId) { - BaseSerializableJsFunction fn = dynamicDecisionNode.getHandlerMap().get(outcomeName); + GenericSerializableJsFunction fn = dynamicDecisionNode.getGenericHandlerMap().get(outcomeName); FrameworkServiceDataHolder dataHolder = FrameworkServiceDataHolder.getInstance(); - JsBaseGraphBuilderFactory jsGraphBuilderFactory = dataHolder.getJsGraphBuilderFactory(); + JsGenericGraphBuilderFactory jsGraphBuilderFactory = dataHolder.getJsGenericGraphBuilderFactory(); JsBaseGraphBuilder graphBuilder = jsGraphBuilderFactory.createBuilder(context, context .getSequenceConfig().getAuthenticationGraph().getStepMap(), dynamicDecisionNode); return graphBuilder.getScriptEvaluator(fn).evaluate(context, JsWrapperFactoryProvider.getInstance() diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/internal/FrameworkServiceComponent.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/internal/FrameworkServiceComponent.java index 89465a790021..776ccc2d6e10 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/internal/FrameworkServiceComponent.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/internal/FrameworkServiceComponent.java @@ -49,8 +49,8 @@ import org.wso2.carbon.identity.application.authentication.framework.config.loader.UIBasedConfigurationLoader; import org.wso2.carbon.identity.application.authentication.framework.config.model.AuthenticatorConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JSExecutionSupervisor; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsFunctionRegistryImpl; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGenericGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.dao.impl.CacheBackedLongWaitStatusDAO; import org.wso2.carbon.identity.application.authentication.framework.dao.impl.LongWaitStatusDAOImpl; import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; @@ -276,12 +276,12 @@ protected void activate(ComponentContext ctxt) { UIBasedConfigurationLoader uiBasedConfigurationLoader = new UIBasedConfigurationLoader(); dataHolder.setSequenceLoader(uiBasedConfigurationLoader); - JsBaseGraphBuilderFactory jsGraphBuilderFactory = FrameworkUtils.createJsGraphBuilderFactoryFromConfig(); + JsGenericGraphBuilderFactory jsGraphBuilderFactory = FrameworkUtils.createJsGraphBuilderFactoryFromConfig(); if (jsGraphBuilderFactory != null) { bundleContext.registerService(JsFunctionRegistry.class, dataHolder.getJsFunctionRegistry(), null); dataHolder.setAdaptiveAuthenticationAvailable(true); jsGraphBuilderFactory.init(); - dataHolder.setJsGraphBuilderFactory(jsGraphBuilderFactory); + dataHolder.setJsGenericGraphBuilderFactory(jsGraphBuilderFactory); } else { dataHolder.setAdaptiveAuthenticationAvailable(false); log.warn("Adaptive authentication is disabled."); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/internal/FrameworkServiceDataHolder.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/internal/FrameworkServiceDataHolder.java index 1d7373284b35..1455092ab4b0 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/internal/FrameworkServiceDataHolder.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/internal/FrameworkServiceDataHolder.java @@ -30,6 +30,7 @@ import org.wso2.carbon.identity.application.authentication.framework.config.loader.SequenceLoader; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JSExecutionSupervisor; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilderFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGenericGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; import org.wso2.carbon.identity.application.authentication.framework.handler.approles.ApplicationRolesResolver; import org.wso2.carbon.identity.application.authentication.framework.handler.claims.ClaimFilter; @@ -83,7 +84,7 @@ public class FrameworkServiceDataHolder { private List httpIdentityResponseFactories = new ArrayList<>(); private AuthenticationDataPublisher authnDataPublisherProxy = null; private SequenceLoader sequenceLoader = null; - private JsBaseGraphBuilderFactory jsGraphBuilderFactory; + private JsGenericGraphBuilderFactory jsGraphBuilderFactory; private AuthenticationMethodNameTranslator authenticationMethodNameTranslator; private List postAuthenticationHandlers = new ArrayList<>(); private PostAuthenticationMgtService postAuthenticationMgtService = null; @@ -284,6 +285,14 @@ public void setAuthenticationMethodNameTranslator( public JsBaseGraphBuilderFactory getJsGraphBuilderFactory() { + if (jsGraphBuilderFactory instanceof JsBaseGraphBuilderFactory) { + return (JsBaseGraphBuilderFactory) jsGraphBuilderFactory; + } + return null; + } + + public JsGenericGraphBuilderFactory getJsGenericGraphBuilderFactory() { + return jsGraphBuilderFactory; } @@ -292,6 +301,11 @@ public void setJsGraphBuilderFactory(JsBaseGraphBuilderFactory jsGraphBuilderFac this.jsGraphBuilderFactory = jsGraphBuilderFactory; } + public void setJsGenericGraphBuilderFactory(JsGenericGraphBuilderFactory jsGraphBuilderFactory) { + + this.jsGraphBuilderFactory = jsGraphBuilderFactory; + } + public MultiAttributeLoginService getMultiAttributeLoginService() { return multiAttributeLoginService; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java index 0e2473a20177..956a9f05f1b9 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java @@ -66,6 +66,7 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.SequenceConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilderFactory; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGenericGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.graaljs.JsGraalGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.openjdk.nashorn.JsOpenJdkNashornGraphBuilderFactory; @@ -3014,7 +3015,8 @@ public static String getStandardDialect(String clientType, ApplicationConfig app */ public static Object toJsSerializable(Object value) { - return FrameworkServiceDataHolder.getInstance().getJsGraphBuilderFactory().getJsUtil().toJsSerializable(value); + return FrameworkServiceDataHolder.getInstance().getJsGenericGraphBuilderFactory() + .getJsUtil().toJsSerializable(value); } /** @@ -4002,6 +4004,15 @@ public static boolean isPreviousIdPAuthenticationFlowHandler(AuthenticationConte public static JsBaseGraphBuilderFactory createJsGraphBuilderFactoryFromConfig() { + JsGenericGraphBuilderFactory jsGenericGraphBuilderFactory = createJsGenericGraphBuilderFactoryFromConfig(); + if (jsGenericGraphBuilderFactory instanceof JsBaseGraphBuilderFactory) { + return (JsBaseGraphBuilderFactory) jsGenericGraphBuilderFactory; + } + return null; + } + + public static JsGenericGraphBuilderFactory createJsGenericGraphBuilderFactoryFromConfig() { + String scriptEngineName = IdentityUtil.getProperty(FrameworkConstants.SCRIPT_ENGINE_CONFIG); if (scriptEngineName != null) { if (StringUtils.equalsIgnoreCase(FrameworkConstants.OPENJDK_NASHORN, scriptEngineName)) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerAbstractTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerAbstractTest.java index 036ffa6bbc5b..5bd267a411f4 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerAbstractTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/GraphBasedSequenceHandlerAbstractTest.java @@ -32,8 +32,8 @@ import org.wso2.carbon.identity.application.authentication.framework.config.builder.FileBasedConfigurationBuilder; import org.wso2.carbon.identity.application.authentication.framework.config.loader.UIBasedConfigurationLoader; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JSExecutionSupervisor; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsBaseGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsFunctionRegistryImpl; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGenericGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsGraphBuilderFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactory; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactoryProvider; @@ -80,7 +80,7 @@ public class GraphBasedSequenceHandlerAbstractTest extends AbstractFrameworkTest protected static final String TEST_USER_1_ID = "4b4414e1-916b-4475-aaee-6b0751c29ff6"; protected GraphBasedSequenceHandler graphBasedSequenceHandler = new GraphBasedSequenceHandler(); protected UIBasedConfigurationLoader configurationLoader; - protected JsBaseGraphBuilderFactory graphBuilderFactory; + protected JsGenericGraphBuilderFactory graphBuilderFactory; @BeforeTest public void setUpExecutionSupervisor() { @@ -121,7 +121,7 @@ protected void setupSuite(String scriptEngine) throws NoSuchFieldException, Ille FrameworkServiceDataHolder.getInstance().setJsFunctionRegistry(jsFunctionRegistry); graphBuilderFactory.init(); - FrameworkServiceDataHolder.getInstance().setJsGraphBuilderFactory(graphBuilderFactory); + FrameworkServiceDataHolder.getInstance().setJsGenericGraphBuilderFactory(graphBuilderFactory); AsyncSequenceExecutor asyncSequenceExecutor = new AsyncSequenceExecutor(); asyncSequenceExecutor.init(); From ec903125ceb73feb054e80ddf4c5cdddc6c13408 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Thu, 7 Mar 2024 12:43:17 +0530 Subject: [PATCH 26/35] Fix backward incompatibility * Change back the original protected methods * Change back the runtimeclaims' and runtimeparameters' parent classes * Change the JsHeaders class to original name --- .../config/model/graph/JsWrapperFactory.java | 4 +- .../js/AbstractJSContextMemberObject.java | 3 +- .../{JsHeaders.java => CommonJsHeaders.java} | 6 +- .../model/graph/js/JsAuthenticatedUser.java | 6 +- .../graph/js/JsAuthenticationContext.java | 8 +- .../config/model/graph/js/JsClaims.java | 31 ++++++ .../config/model/graph/js/JsParameters.java | 9 +- .../model/graph/js/JsRuntimeClaims.java | 95 ------------------- .../model/graph/js/JsServletRequest.java | 2 +- .../model/graph/js/JsWritableParameters.java | 43 --------- .../js/graaljs/JsGraalAuthenticatedUser.java | 4 + .../graaljs/JsGraalAuthenticationContext.java | 5 + .../model/graph/js/graaljs/JsGraalClaims.java | 5 + .../model/graph/js/graaljs/JsGraalCookie.java | 5 + .../graph/js/graaljs/JsGraalHeaders.java | 9 +- .../graph/js/graaljs/JsGraalParameters.java | 4 + .../js/graaljs/JsGraalRuntimeClaims.java | 28 +++++- .../js/graaljs/JsGraalServletRequest.java | 5 + .../js/graaljs/JsGraalServletResponse.java | 5 + .../model/graph/js/graaljs/JsGraalStep.java | 5 + .../model/graph/js/graaljs/JsGraalSteps.java | 5 + .../js/graaljs/JsGraalWritableParameters.java | 15 ++- .../{JsNashornHeaders.java => JsHeaders.java} | 6 +- .../js/nashorn/JsNashornRuntimeClaims.java | 31 +++++- .../nashorn/JsNashornWritableParameters.java | 8 +- .../nashorn/JsOpenJdkNashornHeaders.java | 4 +- .../JsOpenJdkNashornRuntimeClaims.java | 33 ++++++- .../JsOpenJdkNashornWritableParameters.java | 10 +- .../src/test/resources/testng.xml | 3 +- 29 files changed, 212 insertions(+), 185 deletions(-) rename components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/{JsHeaders.java => CommonJsHeaders.java} (91%) delete mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsRuntimeClaims.java delete mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsWritableParameters.java rename components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/{JsNashornHeaders.java => JsHeaders.java} (90%) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactory.java index 972dd71f024a..273fa1eff214 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactory.java @@ -24,11 +24,11 @@ import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseRuntimeClaims; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseStep; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseSteps; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsHeaders; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornAuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornClaims; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornCookie; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornHeaders; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornParameters; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornRuntimeClaims; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornServletRequest; @@ -143,7 +143,7 @@ public JsBaseStep createJsStep(AuthenticationContext context, int step, String a @Override public JsBaseHeaders createJsHeaders(Map wrapped, HttpServletResponse response) { - return new JsNashornHeaders(wrapped, response); + return new JsHeaders(wrapped, response); } @Override diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/AbstractJSContextMemberObject.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/AbstractJSContextMemberObject.java index ceb2bbad24ff..7247bf0dacdc 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/AbstractJSContextMemberObject.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/AbstractJSContextMemberObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2023, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2018-2024, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -51,6 +51,7 @@ public AuthenticationContext getContext() { } public boolean hasMember (String name) { + Objects.requireNonNull(name); return false; } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsHeaders.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/CommonJsHeaders.java similarity index 91% rename from components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsHeaders.java rename to components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/CommonJsHeaders.java index 31ff3cbc4397..b9020f9fdea3 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsHeaders.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/CommonJsHeaders.java @@ -25,16 +25,16 @@ import javax.servlet.http.HttpServletResponse; /** - * Abstract Javascript wrapper for Java level HashMap of HTTP headers. + * Javascript wrapper for Java level HashMap of HTTP headers. * This provides controlled access to HTTPServletResponse object's headers via provided javascript native syntax. * Also it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime. */ -public abstract class JsHeaders implements JsBaseHeaders { +public class CommonJsHeaders implements JsBaseHeaders { private final Map wrapped; private final HttpServletResponse response; - public JsHeaders(Map wrapped, HttpServletResponse response) { + public CommonJsHeaders(Map wrapped, HttpServletResponse response) { this.wrapped = wrapped; this.response = response; diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticatedUser.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticatedUser.java index 23876b3aa439..fa98cddcb529 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticatedUser.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticatedUser.java @@ -55,8 +55,8 @@ public abstract class JsAuthenticatedUser extends AbstractJSObjectWrapper implements JsBaseParameters { +public class JsParameters extends AbstractJSObjectWrapper implements JsBaseParameters { protected static final Log LOG = LogFactory.getLog(JsParameters.class); @@ -68,4 +68,9 @@ public void setMember(String name, Object value) { LOG.warn("Unsupported operation. Parameters are read only. Can't set parameter " + name + " to value: " + value); } + + public void removeMemberObject(String name) { + + getWrapped().remove(name); + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsRuntimeClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsRuntimeClaims.java deleted file mode 100644 index 04fe7640a49e..000000000000 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsRuntimeClaims.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). - * - * WSO2 LLC. 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. - */ - -package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js; - -import org.apache.commons.lang.StringUtils; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseRuntimeClaims; -import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; -import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; - -/** - * Represent the user's runtime claims. - */ -public abstract class JsRuntimeClaims extends JsClaims implements JsBaseRuntimeClaims { - - public JsRuntimeClaims(AuthenticationContext context, int step, String idp) { - - super(context, step, idp, false); - } - - public JsRuntimeClaims(AuthenticationContext context, AuthenticatedUser user) { - - super(context, user, false); - } - - public Object getMember(String claimUri) { - - if (authenticatedUser != null) { - return getRuntimeClaim(claimUri); - } - return null; - } - - public boolean hasMember(String claimUri) { - - if (authenticatedUser != null) { - return hasRuntimeClaim(claimUri); - } - return false; - } - - public void setMember(String claimUri, Object claimValue) { - - if (authenticatedUser != null) { - setRuntimeClaim(claimUri, claimValue); - } - } - - private Object getRuntimeClaim(String claimUri) { - - String runtimeClaimValue = getContext().getRuntimeClaim(claimUri); - if (runtimeClaimValue != null) { - return runtimeClaimValue; - } - if (isFederatedIdP()) { - return getFederatedClaim(claimUri); - } - return getLocalClaim(claimUri); - } - - private boolean hasRuntimeClaim(String claimUri) { - - String claim = getContext().getRuntimeClaim(claimUri); - if (claim != null) { - return true; - } - if (isFederatedIdP()) { - return hasFederatedClaim(claimUri); - } - return hasLocalClaim(claimUri); - } - - private void setRuntimeClaim(String claimUri, Object claimValue) { - - if (claimValue == null) { - claimValue = StringUtils.EMPTY; - } - getContext().addRuntimeClaim(claimUri, String.valueOf(claimValue)); - } -} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletRequest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletRequest.java index ca85eead3f46..161ab1e97527 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletRequest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletRequest.java @@ -128,7 +128,7 @@ public void setMember(String name, Object value) { } - private HttpServletRequest getRequest() { + protected HttpServletRequest getRequest() { TransientObjectWrapper transientObjectWrapper = getWrapped(); return transientObjectWrapper.getWrapped(); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsWritableParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsWritableParameters.java deleted file mode 100644 index 883cd578ac61..000000000000 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsWritableParameters.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). - * - * WSO2 LLC. 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. - */ - -package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js; - -import java.util.Map; - -/** - * Parameters that can be modified from the authentication script. - * This is the abstract wrapper used for all script engine implementations. - */ -public abstract class JsWritableParameters extends JsParameters { - - public JsWritableParameters(Map wrapped) { - - super(wrapped); - } - - public void removeMemberObject(String name) { - - getWrapped().remove(name); - } - - public void setMember(String name, Object value) { - - getWrapped().put(name, value); - } -} diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java index 055bf0330f88..8c808145b21e 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticatedUser.java @@ -70,4 +70,8 @@ public void putMember(String name, Value value) { setMember(name, valueAsString); } + public boolean hasMember(String name) { + + return true; + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java index 0556fec04b4d..59b9f77c6ee3 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalAuthenticationContext.java @@ -64,4 +64,9 @@ public boolean removeMember(String name) { return super.removeMemberObject(name); } + + public boolean hasMember(String name) { + + return true; + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java index 7919f375c136..12e98ca75469 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalClaims.java @@ -53,4 +53,9 @@ public void putMember(String claimUri, Value value) { String valueAsString = value.isString() ? value.asString() : String.valueOf(value); setMemberObject(claimUri, valueAsString); } + + public boolean hasMember(String name) { + + return true; + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java index a0cbecbfce5e..f0a390ec859e 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalCookie.java @@ -51,4 +51,9 @@ public void putMember(String key, Value value) { String valueAsString = value.isString() ? value.asString() : String.valueOf(value); super.setMember(key, valueAsString); } + + public boolean hasMember(String name) { + + return true; + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java index fdbf6c1ac2cb..6dfa32a533c9 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalHeaders.java @@ -21,7 +21,7 @@ import org.graalvm.polyglot.Value; import org.graalvm.polyglot.proxy.ProxyArray; import org.graalvm.polyglot.proxy.ProxyObject; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsHeaders; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.CommonJsHeaders; import java.util.Map; @@ -32,7 +32,7 @@ * This provides controlled access to HTTPServletResponse object's headers via provided javascript native syntax. * Also, it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime. */ -public class JsGraalHeaders extends JsHeaders implements ProxyObject { +public class JsGraalHeaders extends CommonJsHeaders implements ProxyObject { public JsGraalHeaders(Map wrapped, HttpServletResponse response) { @@ -57,4 +57,9 @@ public void putMember(String name, Value value) { String valueAsString = value.isString() ? value.asString() : String.valueOf(value); super.setMemberObject(name, valueAsString); } + + public boolean hasMember(String name) { + + return true; + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java index 9811ced1aba3..2baa0bee88c3 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java @@ -58,4 +58,8 @@ public boolean removeMember(String name) { return false; } + public boolean hasMember(String name) { + + return true; + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java index 9c63de89f9f6..7376e9cb621e 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalRuntimeClaims.java @@ -21,23 +21,23 @@ import org.graalvm.polyglot.Value; import org.graalvm.polyglot.proxy.ProxyArray; import org.graalvm.polyglot.proxy.ProxyObject; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsRuntimeClaims; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseRuntimeClaims; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; /** * Represent the user's runtime claims for GraalJs Execution. */ -public class JsGraalRuntimeClaims extends JsRuntimeClaims implements ProxyObject { +public class JsGraalRuntimeClaims extends JsGraalClaims implements JsBaseRuntimeClaims, ProxyObject { public JsGraalRuntimeClaims(AuthenticationContext context, int step, String idp) { - super(context, step, idp); + super(context, step, idp, false); } public JsGraalRuntimeClaims(AuthenticationContext context, AuthenticatedUser user) { - super(context, user); + super(context, user, false); } @Override @@ -52,4 +52,24 @@ public void putMember(String claimUri, Value value) { String valueAsString = value.isString() ? value.asString() : String.valueOf(value); setMember(claimUri, valueAsString); } + + public Object getMember(String claimUri) { + + if (authenticatedUser != null) { + return getRuntimeClaim(claimUri); + } + return null; + } + + public boolean hasMember(String name) { + + return true; + } + + public void setMember(String claimUri, Object claimValue) { + + if (authenticatedUser != null) { + setRuntimeClaim(claimUri, claimValue); + } + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java index fa0bc8e7accb..f21aff64663e 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletRequest.java @@ -68,4 +68,9 @@ public boolean removeMember(String key) { return false; } + + public boolean hasMember(String name) { + + return true; + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java index deec431268bb..6732881be102 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalServletResponse.java @@ -62,4 +62,9 @@ public void putMember(String key, Value value) { String valueAsString = value.isString() ? value.asString() : String.valueOf(value); super.setMember(key, valueAsString); } + + public boolean hasMember(String name) { + + return true; + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java index b0b02362e685..a392b6f1b84f 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalStep.java @@ -59,4 +59,9 @@ public boolean removeMember(String name) { super.removeMemberObject(name); return true; } + + public boolean hasMember(String name) { + + return true; + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java index 5ccbfd411d88..a91ccaacf904 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalSteps.java @@ -43,4 +43,9 @@ public JsGraalSteps(AuthenticationContext context) { public void set(long index, Value value) { //Steps can not be set with script. } + + public boolean hasMember(String name) { + + return true; + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java index 32709f29598e..80de0fd99a2b 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java @@ -20,7 +20,6 @@ import org.graalvm.polyglot.Value; import org.graalvm.polyglot.proxy.ProxyObject; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsWritableParameters; import java.util.List; import java.util.Map; @@ -29,7 +28,7 @@ * Parameters that can be modified from the authentication script. * This wrapper uses GraalJS polyglot context. */ -public class JsGraalWritableParameters extends JsWritableParameters implements ProxyObject { +public class JsGraalWritableParameters extends JsGraalParameters implements ProxyObject { public JsGraalWritableParameters(Map wrapped) { @@ -44,6 +43,16 @@ public boolean removeMember(String name) { public void putMember(String key, Value value) { - super.setMember(key, value.as(List.class)); + setMember(key, value.as(List.class)); + } + + public boolean hasMember(String name) { + + return true; + } + + public void setMember(String name, Object value) { + + getWrapped().put(name, value); } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornHeaders.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsHeaders.java similarity index 90% rename from components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornHeaders.java rename to components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsHeaders.java index fdeef926e615..ef13be939aef 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornHeaders.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsHeaders.java @@ -18,7 +18,7 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsHeaders; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.CommonJsHeaders; import java.util.Map; @@ -29,9 +29,9 @@ * This provides controlled access to HTTPServletResponse object's headers via provided javascript native syntax. * Also it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime. */ -public class JsNashornHeaders extends JsHeaders implements AbstractJsObject { +public class JsHeaders extends CommonJsHeaders implements AbstractJsObject { - public JsNashornHeaders(Map wrapped, HttpServletResponse response) { + public JsHeaders(Map wrapped, HttpServletResponse response) { super(wrapped, response); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornRuntimeClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornRuntimeClaims.java index 9b60f7d458b9..eface7c11e51 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornRuntimeClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornRuntimeClaims.java @@ -18,7 +18,7 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsRuntimeClaims; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseRuntimeClaims; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; @@ -26,15 +26,38 @@ * Represent the user's runtime claims. * This wrapper uses jdk.nashorn engine. */ -public class JsNashornRuntimeClaims extends JsRuntimeClaims implements AbstractJsObject { +public class JsNashornRuntimeClaims extends JsNashornClaims implements JsBaseRuntimeClaims, AbstractJsObject { public JsNashornRuntimeClaims(AuthenticationContext context, int step, String idp) { - super(context, step, idp); + super(context, step, idp, false); } public JsNashornRuntimeClaims(AuthenticationContext context, AuthenticatedUser user) { - super(context, user); + super(context, user, false); + } + + public Object getMember(String claimUri) { + + if (authenticatedUser != null) { + return getRuntimeClaim(claimUri); + } + return null; + } + + public boolean hasMember(String claimUri) { + + if (authenticatedUser != null) { + return hasRuntimeClaim(claimUri); + } + return false; + } + + public void setMember(String claimUri, Object claimValue) { + + if (authenticatedUser != null) { + setRuntimeClaim(claimUri, claimValue); + } } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornWritableParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornWritableParameters.java index 28c8d0220900..bba2387563a1 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornWritableParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornWritableParameters.java @@ -18,15 +18,13 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsWritableParameters; - import java.util.Map; /** * Parameters that can be modified from the authentication script. * This wrapper uses jdk.nashorn engine. */ -public class JsNashornWritableParameters extends JsWritableParameters implements AbstractJsObject { +public class JsNashornWritableParameters extends JsNashornParameters implements AbstractJsObject { public JsNashornWritableParameters(Map wrapped) { @@ -37,4 +35,8 @@ public void removeMember(String name) { super.removeMemberObject(name); } + public void setMember(String name, Object value) { + + getWrapped().put(name, value); + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornHeaders.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornHeaders.java index a003917a0339..6ca72912b209 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornHeaders.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornHeaders.java @@ -18,7 +18,7 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsHeaders; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.CommonJsHeaders; import java.util.Map; @@ -31,7 +31,7 @@ * Also it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime. * Since Nashorn is deprecated in JDK 11 and onwards. We are introducing OpenJDK Nashorn engine. */ -public class JsOpenJdkNashornHeaders extends JsHeaders implements AbstractOpenJdkNashornJsObject { +public class JsOpenJdkNashornHeaders extends CommonJsHeaders implements AbstractOpenJdkNashornJsObject { public JsOpenJdkNashornHeaders(Map wrapped, HttpServletResponse response) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornRuntimeClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornRuntimeClaims.java index be503c2ad9e5..089d108729a3 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornRuntimeClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornRuntimeClaims.java @@ -18,8 +18,7 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsRuntimeClaims; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.AbstractJsObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseRuntimeClaims; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; @@ -27,15 +26,39 @@ * Represent the user's runtime claims. * Since Nashorn is deprecated in JDK 11 and onwards. We are introducing OpenJDK Nashorn engine. */ -public class JsOpenJdkNashornRuntimeClaims extends JsRuntimeClaims implements AbstractJsObject { +public class JsOpenJdkNashornRuntimeClaims extends JsOpenJdkNashornClaims + implements JsBaseRuntimeClaims, AbstractOpenJdkNashornJsObject { public JsOpenJdkNashornRuntimeClaims(AuthenticationContext context, int step, String idp) { - super(context, step, idp); + super(context, step, idp, false); } public JsOpenJdkNashornRuntimeClaims(AuthenticationContext context, AuthenticatedUser user) { - super(context, user); + super(context, user, false); + } + + public Object getMember(String claimUri) { + + if (authenticatedUser != null) { + return getRuntimeClaim(claimUri); + } + return null; + } + + public boolean hasMember(String claimUri) { + + if (authenticatedUser != null) { + return hasRuntimeClaim(claimUri); + } + return false; + } + + public void setMember(String claimUri, Object claimValue) { + + if (authenticatedUser != null) { + setRuntimeClaim(claimUri, claimValue); + } } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornWritableParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornWritableParameters.java index b22bca9d7f9e..b5598c397ac5 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornWritableParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornWritableParameters.java @@ -18,15 +18,14 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsWritableParameters; - import java.util.Map; /** * Parameters that can be modified from the authentication script. * Since Nashorn is deprecated in JDK 11 and onwards. We are introducing OpenJDK Nashorn engine. */ -public class JsOpenJdkNashornWritableParameters extends JsWritableParameters implements AbstractOpenJdkNashornJsObject { +public class JsOpenJdkNashornWritableParameters extends JsOpenJdkNashornParameters + implements AbstractOpenJdkNashornJsObject { public JsOpenJdkNashornWritableParameters(Map wrapped) { @@ -37,4 +36,9 @@ public void removeMember(String name) { super.removeMemberObject(name); } + + public void setMember(String name, Object value) { + + getWrapped().put(name, value); + } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/resources/testng.xml b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/resources/testng.xml index f28f7a8c8a9d..6a92baeb22da 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/resources/testng.xml +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/resources/testng.xml @@ -85,8 +85,7 @@ - - + From 4434538783fd85dd373eca31716b68297f9ec836 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Thu, 7 Mar 2024 12:52:12 +0530 Subject: [PATCH 27/35] Address review comments --- .../framework/config/model/graph/js/JsParameters.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java index 609d09024f2e..97c17ed25e38 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2022-2024, WSO2 LLC. (http://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -26,12 +26,12 @@ import java.util.Map; /** - * Javascript wrapper for Java level HashMap of HTTP headers/cookies. + * Abstract Javascript abstract wrapper for Java level HashMap of HTTP headers/cookies. * This provides controlled access to HTTPServletRequest object's headers and cookies via provided javascript native * syntax. * Also it prevents writing an arbitrary values to the respective fields, keeping consistency on runtime. */ -public class JsParameters extends AbstractJSObjectWrapper implements JsBaseParameters { +public abstract class JsParameters extends AbstractJSObjectWrapper implements JsBaseParameters { protected static final Log LOG = LogFactory.getLog(JsParameters.class); From d88f98df7e692131a1bab2bd6da80635d86e55fb Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Thu, 7 Mar 2024 16:49:54 +0530 Subject: [PATCH 28/35] Fix error when setting GraalJS as script engine --- .../framework/internal/FrameworkServiceComponent.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/internal/FrameworkServiceComponent.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/internal/FrameworkServiceComponent.java index 776ccc2d6e10..2c8f48bc7584 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/internal/FrameworkServiceComponent.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/internal/FrameworkServiceComponent.java @@ -276,7 +276,8 @@ protected void activate(ComponentContext ctxt) { UIBasedConfigurationLoader uiBasedConfigurationLoader = new UIBasedConfigurationLoader(); dataHolder.setSequenceLoader(uiBasedConfigurationLoader); - JsGenericGraphBuilderFactory jsGraphBuilderFactory = FrameworkUtils.createJsGraphBuilderFactoryFromConfig(); + JsGenericGraphBuilderFactory jsGraphBuilderFactory = + FrameworkUtils.createJsGenericGraphBuilderFactoryFromConfig(); if (jsGraphBuilderFactory != null) { bundleContext.registerService(JsFunctionRegistry.class, dataHolder.getJsFunctionRegistry(), null); dataHolder.setAdaptiveAuthenticationAvailable(true); From 7bea192e9d29b36a78a0d8ad800131db17b315d1 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Fri, 8 Mar 2024 08:25:50 +0530 Subject: [PATCH 29/35] Address review comments --- .../model/graph/js/CommonJsHeaders.java | 6 ++--- .../model/graph/js/JsAuthenticatedUser.java | 22 +++++++++---------- .../graph/js/JsAuthenticationContext.java | 9 +++----- .../config/model/graph/js/JsClaims.java | 18 +++++++-------- .../model/graph/js/JsServletRequest.java | 2 -- .../model/graph/js/JsServletResponse.java | 1 - .../config/model/graph/js/JsSteps.java | 5 ++--- .../model/graph/js/graaljs/JsGraalSteps.java | 2 +- .../graph/js/nashorn/JsNashornSteps.java | 2 +- .../nashorn/JsOpenJdkNashornSteps.java | 2 +- .../impl/GraalSelectAcrFromFunction.java | 6 ++--- .../impl/OpenJdkSelectAcrFromFunction.java | 6 ++--- .../sequence/impl/SelectAcrFromFunction.java | 6 ++--- .../sequence/impl/SelectOneFunction.java | 4 ++-- .../js/JsGraalAuthenticationContextTest.java | 11 +++------- 15 files changed, 42 insertions(+), 60 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/CommonJsHeaders.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/CommonJsHeaders.java index b9020f9fdea3..257aef3419a5 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/CommonJsHeaders.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/CommonJsHeaders.java @@ -44,9 +44,8 @@ public Object getMember(String name) { if (wrapped == null) { return null; - } else { - return wrapped.get(name); } + return wrapped.get(name); } public Object getMemberKeys() { @@ -58,9 +57,8 @@ public boolean hasMember(String name) { if (wrapped == null) { return false; - } else { - return wrapped.get(name) != null; } + return wrapped.get(name) != null; } public boolean removeMemberObject(String name) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticatedUser.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticatedUser.java index fa98cddcb529..c543da0d4bfd 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticatedUser.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticatedUser.java @@ -126,31 +126,29 @@ public Object getMember(String name) { if (StringUtils.isNotBlank(idp)) { return JsWrapperFactoryProvider.getInstance().getWrapperFactory() .createJsClaims(getContext(), step, idp, false); - } else { - // Represent step independent user - return JsWrapperFactoryProvider.getInstance().getWrapperFactory() - .createJsClaims(getContext(), getWrapped(), false); } + // Represent step independent user + return JsWrapperFactoryProvider.getInstance().getWrapperFactory() + .createJsClaims(getContext(), getWrapped(), false); case FrameworkConstants.JSAttributes.JS_REMOTE_CLAIMS: if (StringUtils.isNotBlank(idp)) { return JsWrapperFactoryProvider.getInstance().getWrapperFactory() .createJsClaims(getContext(), step, idp, true); - } else { - // Represent step independent user - return JsWrapperFactoryProvider.getInstance().getWrapperFactory() - .createJsClaims(getContext(), getWrapped(), true); } + // Represent step independent user + return JsWrapperFactoryProvider.getInstance().getWrapperFactory() + .createJsClaims(getContext(), getWrapped(), true); + case FrameworkConstants.JSAttributes.JS_LOCAL_ROLES: return getLocalRoles(); case FrameworkConstants.JSAttributes.JS_CLAIMS: if (StringUtils.isNotBlank(idp)) { return JsWrapperFactoryProvider.getInstance().getWrapperFactory() .createJsRuntimeClaims(getContext(), step, idp); - } else { - // Represent step independent user - return JsWrapperFactoryProvider.getInstance().getWrapperFactory() - .createJsRuntimeClaims(getContext(), getWrapped()); } + // Represent step independent user + return JsWrapperFactoryProvider.getInstance().getWrapperFactory() + .createJsRuntimeClaims(getContext(), getWrapped()); default: return super.getMember(name); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticationContext.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticationContext.java index 1ce9cedd11f6..e988d7508798 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticationContext.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsAuthenticationContext.java @@ -114,9 +114,8 @@ public Object getMember(String name) { return JsWrapperFactoryProvider.getInstance().getWrapperFactory() .createJsAuthenticatedUser(this.getContext(), stepConfig.getAuthenticatedUser(), stepConfig.getOrder(), stepConfig.getAuthenticatedIdP()); - } else { - return null; } + return null; case FrameworkConstants.JSAttributes.JS_RETRY_STEP: return getWrapped().isRetrying(); case FrameworkConstants.JSAttributes.JS_ENDPOINT_PARAMS: @@ -211,9 +210,8 @@ protected StepConfig getCurrentSubjectIdentifierStep() { return subjectIdentifierStep.get(); } else if (getContext().getCurrentStep() > 0) { return stepConfigs.get(getContext().getCurrentStep()); - } else { - return null; } + return null; } protected JsBaseAuthenticatedUser getLastLoginFailedUserFromWrappedContext() { @@ -223,8 +221,7 @@ protected JsBaseAuthenticatedUser getLastLoginFailedUserFromWrappedContext() { if (lastLoginFailedUser instanceof AuthenticatedUser) { return JsWrapperFactoryProvider.getInstance().getWrapperFactory() .createJsAuthenticatedUser(getWrapped(), (AuthenticatedUser) lastLoginFailedUser); - } else { - return null; } + return null; } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java index 48ed6d37dcf3..99b82ba49fa0 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsClaims.java @@ -132,9 +132,8 @@ private StepConfig getCurrentSubjectIdentifierStep() { return subjectIdentifierStep.get(); } else if (getContext().getCurrentStep() > 0) { return stepConfigs.get(getContext().getCurrentStep()); - } else { - return null; } + return null; } /** @@ -204,8 +203,8 @@ private void setLocalClaim(String claimUri, String claimValue) { if (isFederatedIdP()) { setLocalMappedClaim(claimUri, claimValue); } else { - // This covers step with a local authenticator, and the scenarios where step/idp is not set - // if the step/idp is not set, user is assumed to be a local user + /* This covers step with a local authenticator, and the scenarios where step/idp is not set + if the step/idp is not set, user is assumed to be a local user. */ setLocalUserClaim(claimUri, claimValue); } } @@ -268,8 +267,8 @@ private String getRemoteClaimMappedToLocalClaim(String localClaim, Map localToIdpClaimMapping; String tenantDomain = getContext().getTenantDomain(); try { - // Check if the IDP use a standard dialect (like oidc), If it does, dialect claim mapping are - // prioritized over IdP claim mapping + /* Check if the IDP use a standard dialect (like oidc), If it does, dialect claim mapping are + prioritized over IdP claim mapping. */ ApplicationAuthenticator authenticator = getContext().getSequenceConfig().getStepMap().get(step).getAuthenticatedAutenticator() .getApplicationAuthenticator(); @@ -368,11 +367,10 @@ protected String getLocalClaim(String claimUri) { if (isFederatedIdP()) { return getLocalMappedClaim(claimUri); - } else { - // This covers step with a local authenticator, and the scenarios where step/idp is not set - // if the step/idp is not set, user is assumed to be a local user - return getLocalUserClaim(claimUri); } + /* This covers step with a local authenticator, and the scenarios where step/idp is not set + if the step/idp is not set, user is assumed to be a local user. */ + return getLocalUserClaim(claimUri); } /** diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletRequest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletRequest.java index 161ab1e97527..085d5a25268f 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletRequest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletRequest.java @@ -52,7 +52,6 @@ public abstract class JsServletRequest private static final Log LOG = LogFactory.getLog(JsServletRequest.class); - public JsServletRequest(TransientObjectWrapper wrapped) { super(wrapped); @@ -125,7 +124,6 @@ public Object getMember(String name) { public void setMember(String name, Object value) { LOG.warn("Unsupported operation. Servlet Request is read only. Can't add parameter " + value); - } protected HttpServletRequest getRequest() { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletResponse.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletResponse.java index 0e8cac200252..88d72e08dfba 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletResponse.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsServletResponse.java @@ -50,7 +50,6 @@ public abstract class JsServletResponse private static final Log LOG = LogFactory.getLog(JsServletResponse.class); - public JsServletResponse(TransientObjectWrapper wrapped) { super(wrapped); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsSteps.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsSteps.java index 64a741a40c3f..89d603f513b5 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsSteps.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsSteps.java @@ -27,7 +27,7 @@ import java.util.Optional; /** - * Returns when context.steps[ acrListRequested = context.getWrapped().getRequestedAcr(); @@ -53,7 +53,7 @@ public String evaluate(JsBaseAuthenticationContext context, Object possibleOutco return null; } - private String[] extractPossibleOutcomes(JsBaseAuthenticationContext context, Object possibleOutcomesObj) { + private String[] extractPossibleOutcomes(JsAuthenticationContext context, Object possibleOutcomesObj) { String[] possibleOutcomes; if (possibleOutcomesObj instanceof List) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/OpenJdkSelectAcrFromFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/OpenJdkSelectAcrFromFunction.java index a2c7ac8e8c63..61f2b2c049fc 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/OpenJdkSelectAcrFromFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/OpenJdkSelectAcrFromFunction.java @@ -21,7 +21,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openjdk.nashorn.api.scripting.ScriptObjectMirror; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import java.util.Collections; @@ -37,7 +37,7 @@ public class OpenJdkSelectAcrFromFunction implements SelectOneFunction { private static final Log log = LogFactory.getLog(OpenJdkSelectAcrFromFunction.class); - public String evaluate(JsBaseAuthenticationContext context, Object possibleOutcomesObj) { + public String evaluate(JsAuthenticationContext context, Object possibleOutcomesObj) { String[] possibleOutcomes = extractPossibleOutcomes(context, possibleOutcomesObj); List acrListRequested = context.getWrapped().getRequestedAcr(); @@ -53,7 +53,7 @@ public String evaluate(JsBaseAuthenticationContext context, Object possibleOutco return null; } - private String[] extractPossibleOutcomes(JsBaseAuthenticationContext context, Object possibleOutcomesObj) { + private String[] extractPossibleOutcomes(JsAuthenticationContext context, Object possibleOutcomesObj) { String[] possibleOutcomes; if (possibleOutcomesObj instanceof String[]) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectAcrFromFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectAcrFromFunction.java index 2df70d21a17d..8d21b194bb7a 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectAcrFromFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectAcrFromFunction.java @@ -21,7 +21,7 @@ import jdk.nashorn.api.scripting.ScriptObjectMirror; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import java.util.Collections; @@ -37,7 +37,7 @@ public class SelectAcrFromFunction implements SelectOneFunction { private static final Log log = LogFactory.getLog(SelectAcrFromFunction.class); - public String evaluate(JsBaseAuthenticationContext context, Object possibleOutcomesObj) { + public String evaluate(JsAuthenticationContext context, Object possibleOutcomesObj) { String[] possibleOutcomes = extractPossibleOutcomes(context, possibleOutcomesObj); List acrListRequested = context.getWrapped().getRequestedAcr(); @@ -53,7 +53,7 @@ public String evaluate(JsBaseAuthenticationContext context, Object possibleOutco return null; } - private String[] extractPossibleOutcomes(JsBaseAuthenticationContext context, Object possibleOutcomesObj) { + private String[] extractPossibleOutcomes(JsAuthenticationContext context, Object possibleOutcomesObj) { String[] possibleOutcomes; if (possibleOutcomesObj instanceof String[]) { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectOneFunction.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectOneFunction.java index bcde7e9bba45..849b8372cabc 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectOneFunction.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/sequence/impl/SelectOneFunction.java @@ -18,12 +18,12 @@ package org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticationContext; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext; /** * Functional interface to select one outcome from possible outcomes. */ @FunctionalInterface public interface SelectOneFunction { - String evaluate(JsBaseAuthenticationContext context, Object possibleOutcomesObj); + String evaluate(JsAuthenticationContext context, Object possibleOutcomesObj); } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java index a6be14710c53..938dc7f4ca7c 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsGraalAuthenticationContextTest.java @@ -70,7 +70,6 @@ public void setUp() throws NoSuchFieldException, IllegalAccessException { Field wrapperFactory = JsWrapperFactoryProvider.class.getDeclaredField("jsWrapperBaseFactory"); wrapperFactory.setAccessible(true); wrapperFactory.set(JsWrapperFactoryProvider.getInstance(), new JsGraalWrapperFactory()); - } @Test @@ -173,9 +172,8 @@ public void testGetServiceProviderFromWrappedContext() throws Exception { Value result = context.eval( Source.newBuilder(POLYGLOT_LANGUAGE, "context.serviceProviderName", POLYGLOT_SOURCE).build()); assertFalse(result.isNull()); - assertEquals(result.asString(), SERVICE_PROVIDER_NAME, - "Service Provider name set in AuthenticationContext is not " + - "accessible from JSAuthenticationContext"); + assertEquals(result.asString(), SERVICE_PROVIDER_NAME, "Service Provider name set in " + + "AuthenticationContext is not accessible from JSAuthenticationContext"); } @Test @@ -245,9 +243,6 @@ public void testGetLastLoginAuthenticatorFromStep() throws Exception { assertFalse(result.isNull()); assertEquals(result.asString(), BASIC_AUTHENTICATOR, - "Authenticator of the step in AuthenticationContext is not " + - "accessible from JSAuthenticationContext"); - + "Authenticator of the step in AuthenticationContext is not accessible from JSAuthenticationContext"); } - } From 9f18878cd0f6b7b6af17da9caccd6e751d63b061 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Fri, 8 Mar 2024 08:46:08 +0530 Subject: [PATCH 30/35] Address review comments --- .../model/graph/JsWrapperBaseFactory.java | 4 +-- .../config/model/graph/JsWrapperFactory.java | 22 ++++++---------- .../graph/graaljs/JsGraalWrapperFactory.java | 22 ++++++---------- .../model/graph/js/CommonJsHeaders.java | 6 ++--- .../config/model/graph/js/JsSteps.java | 10 +++---- .../model/graph/js/base/JsBaseHeaders.java | 26 ------------------- .../JsOpenJdkNashornWrapperFactory.java | 22 ++++++---------- .../js/JsGraalAuthenticationContextTest.java | 1 - 8 files changed, 32 insertions(+), 81 deletions(-) delete mode 100644 components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/base/JsBaseHeaders.java diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperBaseFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperBaseFactory.java index 6a2c047825f2..96c705894374 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperBaseFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperBaseFactory.java @@ -18,11 +18,11 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.CommonJsHeaders; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseClaims; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseCookie; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseHeaders; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseParameters; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseRuntimeClaims; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseServletRequest; @@ -173,7 +173,7 @@ JsBaseStep createJsStep(AuthenticationContext context, int step, String authenti * @param response - Wrapped Servlet Response * @return Proxy for HTTP headers/Cookies in Servlet Request */ - JsBaseHeaders createJsHeaders(Map wrapped, HttpServletResponse response); + CommonJsHeaders createJsHeaders(Map wrapped, HttpServletResponse response); /** * Creates a JavaScript Proxy for Steps. diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactory.java index 273fa1eff214..e6a672b3a192 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/JsWrapperFactory.java @@ -18,12 +18,6 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticatedUser; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseClaims; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseHeaders; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseRuntimeClaims; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseStep; -import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseSteps; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsHeaders; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornAuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn.JsNashornAuthenticationContext; @@ -65,7 +59,7 @@ public JsNashornAuthenticatedUser createJsAuthenticatedUser(AuthenticationContex } @Override - public JsBaseAuthenticatedUser createJsAuthenticatedUser(AuthenticationContext context, + public JsNashornAuthenticatedUser createJsAuthenticatedUser(AuthenticationContext context, AuthenticatedUser wrappedUser, int step, String idp) { return new JsNashornAuthenticatedUser(context, wrappedUser, step, idp); @@ -108,46 +102,46 @@ public JsNashornServletResponse createJsServletResponse(TransientObjectWrapper Date: Fri, 8 Mar 2024 14:34:06 +0530 Subject: [PATCH 31/35] Change ScriptStatementsLimit config name and set the default as 0 --- .../graaljs/JsGraalGraphBuilderFactory.java | 18 +++++++++++------- .../framework/util/FrameworkConstants.java | 4 +++- .../resources/identity.xml.j2 | 6 +++++- ...n.identity.core.server.feature.default.json | 1 + 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java index dde9aca75d8d..f30701ab0e48 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java @@ -44,10 +44,11 @@ import java.util.HashMap; import java.util.Map; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.AdaptiveAuthentication.DEFAULT_GRAALJS_SCRIPT_STATEMENTS_LIMIT; +import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.AdaptiveAuthentication.GRAALJS_SCRIPT_STATEMENTS_LIMIT; import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.JS_FUNC_SELECT_ACR_FROM; import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.JS_LOG; import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.JSAttributes.POLYGLOT_LANGUAGE; -import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.SCRIPT_STATEMENTS_LIMIT; /** * Factory to create a Javascript based sequence builder. @@ -59,7 +60,7 @@ public class JsGraalGraphBuilderFactory implements JsGenericGraphBuilderFactory< private static final Log LOG = LogFactory.getLog(JsGraalGraphBuilderFactory.class); private static final String JS_BINDING_CURRENT_CONTEXT = "JS_BINDING_CURRENT_CONTEXT"; - private int javascriptResourceLimit = 500; + private int javascriptResourceLimit = 0; public void init() { @@ -173,17 +174,20 @@ public JsGraalGraphBuilder createBuilder(AuthenticationContext authenticationCon private void setJavascriptResourceLimit() { - String statementLimit = IdentityUtil.getProperty(SCRIPT_STATEMENTS_LIMIT); - int defaultLimit = 500; + /* + * This sets the number of javascript statements that can be executed in a single execution. + * The default value is set to 0 which is equivalent to unlimited number of statement. + */ + String statementLimit = IdentityUtil.getProperty(GRAALJS_SCRIPT_STATEMENTS_LIMIT); if (statementLimit != null) { try { javascriptResourceLimit = Integer.parseInt(statementLimit); } catch (NumberFormatException e) { - LOG.warn("Error while parsing the script statement limit. Defaulting to " + defaultLimit, e); - javascriptResourceLimit = defaultLimit; + LOG.warn("Error while parsing the script statement limit. Defaulting to " + DEFAULT_GRAALJS_SCRIPT_STATEMENTS_LIMIT, e); + javascriptResourceLimit = DEFAULT_GRAALJS_SCRIPT_STATEMENTS_LIMIT; } } else { - javascriptResourceLimit = defaultLimit; + javascriptResourceLimit = DEFAULT_GRAALJS_SCRIPT_STATEMENTS_LIMIT; } } } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java index dac14e502404..1b62b1078bb2 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkConstants.java @@ -226,7 +226,6 @@ public abstract class FrameworkConstants { public static final String SCRIPT_ENGINE_CONFIG = "AdaptiveAuth.ScriptEngine"; public static final String THREAD_LOCAL_SCRIPT_ENGINE_CONFIG = "AdaptiveAuth.LimitScriptEngineCreation"; - public static final String SCRIPT_STATEMENTS_LIMIT = "AdaptiveAuth.StatementsLimit"; public static final String OPENJDK_NASHORN = "openjdkNashorn"; public static final String NASHORN = "nashorn"; public static final String GRAAL_JS = "graaljs"; @@ -674,6 +673,9 @@ public static class AdaptiveAuthentication { = "AdaptiveAuthExecutionSupervisorResult"; public static final String AUTHENTICATOR_NAME_IN_AUTH_CONFIG = "AdaptiveAuth.AuthenticatorNameInAuthConfig.Enable"; + public static final String GRAALJS_SCRIPT_STATEMENTS_LIMIT + = "AdaptiveAuth.GraalJS.ScriptStatementsLimit"; + public static final int DEFAULT_GRAALJS_SCRIPT_STATEMENTS_LIMIT = 0; } /** diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 index 5034bdaf35f6..2a07dfdd38f1 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 @@ -1206,7 +1206,6 @@ {{AdaptiveAuth.ScriptEngine}} {{AdaptiveAuth.LimitScriptEngineCreation}} - {{AdaptiveAuth.StatementsLimit}} @@ -3622,6 +3621,11 @@ {{authentication.adaptive.authenticator_name_in_auth_config.enable}} + + + + {{authentication.adaptive.graaljs.script_statements_limit}} + diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/org.wso2.carbon.identity.core.server.feature.default.json b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/org.wso2.carbon.identity.core.server.feature.default.json index dc7c9f7ec688..30c6a1c1e480 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/org.wso2.carbon.identity.core.server.feature.default.json +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/org.wso2.carbon.identity.core.server.feature.default.json @@ -769,6 +769,7 @@ "authentication.adaptive.execution_supervisor.thread_count": "1", "authentication.adaptive.execution_supervisor.timeout": "500ms", "authentication.adaptive.authenticator_name_in_auth_config.enable": true, + "authentication.adaptive.graaljs.script_statements_limit": "0", "federated.idp.role_claim_value_attribute_separator": ",", "configuration.store.query_length.max": "4194304", From 6d2f88f512c7c6e73ef5b5042e07464a18931b75 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Fri, 17 May 2024 09:07:17 +0530 Subject: [PATCH 32/35] Set GraalJS as default script executor --- .../framework/util/FrameworkUtils.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java index 956a9f05f1b9..1d17a6628027 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java @@ -254,6 +254,7 @@ public class FrameworkUtils { private static Boolean authenticatorNameInAuthConfigPreference; private static final String OPENJDK_SCRIPTER_CLASS_NAME = "org.openjdk.nashorn.api.scripting.ScriptObjectMirror"; private static final String JDK_SCRIPTER_CLASS_NAME = "jdk.nashorn.api.scripting.ScriptObjectMirror"; + private static final String GRAALJS_SCRIPTER_CLASS_NAME = "org.graalvm.polyglot.Context"; private FrameworkUtils() { } @@ -4015,22 +4016,27 @@ public static JsGenericGraphBuilderFactory createJsGenericGraphBuilderFactoryFro String scriptEngineName = IdentityUtil.getProperty(FrameworkConstants.SCRIPT_ENGINE_CONFIG); if (scriptEngineName != null) { - if (StringUtils.equalsIgnoreCase(FrameworkConstants.OPENJDK_NASHORN, scriptEngineName)) { - return new JsOpenJdkNashornGraphBuilderFactory(); - } else if (StringUtils.equalsIgnoreCase(FrameworkConstants.GRAAL_JS, scriptEngineName)) { + if (StringUtils.equalsIgnoreCase(FrameworkConstants.GRAAL_JS, scriptEngineName)) { return new JsGraalGraphBuilderFactory(); + } else if (StringUtils.equalsIgnoreCase(FrameworkConstants.OPENJDK_NASHORN, scriptEngineName)) { + return new JsOpenJdkNashornGraphBuilderFactory(); } } // Config is not set. Hence going with class for name approach. try { - Class.forName(OPENJDK_SCRIPTER_CLASS_NAME); - return new JsOpenJdkNashornGraphBuilderFactory(); + Class.forName(GRAALJS_SCRIPTER_CLASS_NAME); + return new JsGraalGraphBuilderFactory(); } catch (ClassNotFoundException e) { try { - Class.forName(JDK_SCRIPTER_CLASS_NAME); - return new JsGraphBuilderFactory(); + Class.forName(OPENJDK_SCRIPTER_CLASS_NAME); + return new JsOpenJdkNashornGraphBuilderFactory(); } catch (ClassNotFoundException classNotFoundException) { - return null; + try { + Class.forName(JDK_SCRIPTER_CLASS_NAME); + return new JsGraphBuilderFactory(); + } catch (ClassNotFoundException ex) { + return null; + } } } } From 478306c7d28926fd54e214dd441d4d48f980a7b4 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Fri, 17 May 2024 13:00:45 +0530 Subject: [PATCH 33/35] Fix checkstyle issue --- .../config/model/graph/graaljs/JsGraalGraphBuilderFactory.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java index f30701ab0e48..6f52580394af 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java @@ -183,7 +183,8 @@ private void setJavascriptResourceLimit() { try { javascriptResourceLimit = Integer.parseInt(statementLimit); } catch (NumberFormatException e) { - LOG.warn("Error while parsing the script statement limit. Defaulting to " + DEFAULT_GRAALJS_SCRIPT_STATEMENTS_LIMIT, e); + LOG.warn("Error while parsing the script statement limit. Defaulting to " + + DEFAULT_GRAALJS_SCRIPT_STATEMENTS_LIMIT, e); javascriptResourceLimit = DEFAULT_GRAALJS_SCRIPT_STATEMENTS_LIMIT; } } else { From d893a16338c4d196595c5e7581486c353b9c5b03 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Mon, 20 May 2024 08:00:06 +0530 Subject: [PATCH 34/35] Handle serialization of JAVA arrays in GraalJS execution --- .../model/graph/graaljs/GraalSerializer.java | 18 +++++++++++++++--- .../graaljs/JsGraalGraphBuilderFactory.java | 5 ++--- .../config/model/graph/js/JsParameters.java | 2 +- .../graph/js/graaljs/JsGraalParameters.java | 16 ++++++++++++++++ .../js/graaljs/JsGraalWritableParameters.java | 11 +++++++++++ .../nashorn/JsNashornWritableParameters.java | 13 +++++++++++++ .../JsOpenJdkNashornWritableParameters.java | 12 ++++++++++++ .../framework/util/FrameworkUtils.java | 2 ++ 8 files changed, 72 insertions(+), 7 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java index c15bd311f2ca..2b8c53ab5c6c 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java @@ -75,7 +75,9 @@ public static Object toJsSerializableInternal(Object value) { return list; } else if (value instanceof Value) { Value valueObj = (Value) value; - if (valueObj.canExecute()) { + if (valueObj.isHostObject() && valueObj.asHostObject().getClass().isArray()) { + return valueObj.asHostObject(); + } else if (valueObj.canExecute()) { return GraalSerializableJsFunction.toSerializableForm(valueObj); } else if (valueObj.isProxyObject()) { return valueObj.asProxyObject(); @@ -133,8 +135,9 @@ public Object fromJsSerializable(Object value, Context engine) throws FrameworkE } public static Object fromJsSerializableInternal(Object value, Context context) throws FrameworkException { - - if (value instanceof GraalSerializableJsFunction) { + if (value == null) { + return null; + } else if (value instanceof GraalSerializableJsFunction) { GraalSerializableJsFunction serializableJsFunction = (GraalSerializableJsFunction) value; try { return context.eval("js", "(" + serializableJsFunction.getSource() + ")"); @@ -157,6 +160,15 @@ public static Object fromJsSerializableInternal(Object value, Context context) t deserializedValue.setArrayElement(index, deserializedObject); } return deserializedValue; + } else if (value.getClass().isArray()) { + Value deserializedValue = context.eval(POLYGLOT_LANGUAGE, "[]"); + int arraySize = java.lang.reflect.Array.getLength(value); + for (int index = 0; index < arraySize; index++) { + Object deserializedObject = + fromJsSerializableInternal(java.lang.reflect.Array.get(value, index), context); + deserializedValue.setArrayElement(index, deserializedObject); + } + return deserializedValue; } return value; } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java index 6f52580394af..922657b1dea1 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/JsGraalGraphBuilderFactory.java @@ -94,10 +94,9 @@ public static void persistCurrentContext(AuthenticationContext authContext, Cont * Since, we don't have a difference between global and engine scopes, we need to identify what are the * custom functions and the logger object we added bindings to, and not persist them since we will anyways * bind them again. - * The functions will be host objects and can be executed. The logger object will be host object and will - * not have any array elements. + * The functions will be host objects and can be executed. The Logger object needs to be identified by name. */ - if (!(binding.isHostObject() && (binding.canExecute() || !binding.hasArrayElements()))) { + if (!((binding.isHostObject() && binding.canExecute()) || key.equals("Log"))) { persistableMap.put(key, GraalSerializer.getInstance().toJsSerializable(binding)); } }); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java index 97c17ed25e38..0a6fdc9fcab1 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/JsParameters.java @@ -46,7 +46,7 @@ public Object getMember(String name) { Object member = getWrapped().get(name); if (member instanceof Map) { return JsWrapperFactoryProvider.getInstance().getWrapperFactory() - .createJsWritableParameters((Map) member); + .createJsParameters((Map) member); } return member; } diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java index 2baa0bee88c3..d2fb1710dffa 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalParameters.java @@ -21,6 +21,7 @@ import org.graalvm.polyglot.Value; import org.graalvm.polyglot.proxy.ProxyArray; import org.graalvm.polyglot.proxy.ProxyObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactoryProvider; import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsParameters; import java.util.Map; @@ -39,6 +40,21 @@ public JsGraalParameters(Map wrapped) { super(wrapped); } + @Override + public Object getMember(String name) { + + Object member = getWrapped().get(name); + if (member instanceof Map) { + return JsWrapperFactoryProvider.getInstance().getWrapperFactory() + .createJsParameters((Map) member); + } + if (member != null && member.getClass().isArray()) { + return ProxyArray.fromArray((Object[]) member); + } else { + return member; + } + } + @Override public Object getMemberKeys() { diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java index 80de0fd99a2b..dc5802d57101 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/graaljs/JsGraalWritableParameters.java @@ -20,6 +20,7 @@ import org.graalvm.polyglot.Value; import org.graalvm.polyglot.proxy.ProxyObject; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactoryProvider; import java.util.List; import java.util.Map; @@ -35,6 +36,16 @@ public JsGraalWritableParameters(Map wrapped) { super(wrapped); } + public Object getMember(String name) { + + Object member = getWrapped().get(name); + if (member instanceof Map) { + return JsWrapperFactoryProvider.getInstance().getWrapperFactory() + .createJsWritableParameters((Map) member); + } + return member; + } + public boolean removeMember(String name) { super.removeMemberObject(name); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornWritableParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornWritableParameters.java index bba2387563a1..70b6ccb596dc 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornWritableParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/nashorn/JsNashornWritableParameters.java @@ -18,6 +18,8 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.nashorn; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactoryProvider; + import java.util.Map; /** @@ -30,6 +32,17 @@ public JsNashornWritableParameters(Map wrapped) { super(wrapped); } + + public Object getMember(String name) { + + Object member = getWrapped().get(name); + if (member instanceof Map) { + return JsWrapperFactoryProvider.getInstance().getWrapperFactory() + .createJsWritableParameters((Map) member); + } + return member; + } + public void removeMember(String name) { super.removeMemberObject(name); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornWritableParameters.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornWritableParameters.java index b5598c397ac5..52a77b6b4cef 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornWritableParameters.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/js/openjdk/nashorn/JsOpenJdkNashornWritableParameters.java @@ -18,6 +18,8 @@ package org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.openjdk.nashorn; +import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.JsWrapperFactoryProvider; + import java.util.Map; /** @@ -32,6 +34,16 @@ public JsOpenJdkNashornWritableParameters(Map wrapped) { super(wrapped); } + public Object getMember(String name) { + + Object member = getWrapped().get(name); + if (member instanceof Map) { + return JsWrapperFactoryProvider.getInstance().getWrapperFactory() + .createJsWritableParameters((Map) member); + } + return member; + } + public void removeMember(String name) { super.removeMemberObject(name); diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java index 1d17a6628027..ad5da87a1d1c 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java @@ -4020,6 +4020,8 @@ public static JsGenericGraphBuilderFactory createJsGenericGraphBuilderFactoryFro return new JsGraalGraphBuilderFactory(); } else if (StringUtils.equalsIgnoreCase(FrameworkConstants.OPENJDK_NASHORN, scriptEngineName)) { return new JsOpenJdkNashornGraphBuilderFactory(); + } else if (StringUtils.equalsIgnoreCase(FrameworkConstants.NASHORN, scriptEngineName)) { + return new JsGraphBuilderFactory(); } } // Config is not set. Hence going with class for name approach. From 32e860e538fa5f592852db8b79f8763ed44384b8 Mon Sep 17 00:00:00 2001 From: shanggeeth Date: Mon, 20 May 2024 16:17:04 +0530 Subject: [PATCH 35/35] Fix serialization of Array elements --- .../model/graph/graaljs/GraalSerializer.java | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java index 2b8c53ab5c6c..1ad2800f687c 100644 --- a/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java +++ b/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/config/model/graph/graaljs/GraalSerializer.java @@ -75,12 +75,8 @@ public static Object toJsSerializableInternal(Object value) { return list; } else if (value instanceof Value) { Value valueObj = (Value) value; - if (valueObj.isHostObject() && valueObj.asHostObject().getClass().isArray()) { - return valueObj.asHostObject(); - } else if (valueObj.canExecute()) { + if (valueObj.canExecute()) { return GraalSerializableJsFunction.toSerializableForm(valueObj); - } else if (valueObj.isProxyObject()) { - return valueObj.asProxyObject(); } else if (valueObj.isNumber()) { return valueObj.asInt(); } else if (valueObj.isString()) { @@ -106,6 +102,8 @@ public static Object toJsSerializableInternal(Object value) { arrayItems.add((Serializable) serializedObj); } return arrayItems; + } else if (valueObj.isProxyObject()) { + return toJsSerializableInternal(valueObj.asProxyObject()); } else if (valueObj.hasMembers()) { Map serializedMap = new HashMap<>(); valueObj.getMemberKeys().forEach((key) -> { @@ -145,12 +143,15 @@ public static Object fromJsSerializableInternal(Object value, Context context) t log.error("Error when recreating JS Object", e); } } else if (value instanceof Map) { - Map deserializedMap = new HashMap<>(); + context.eval(POLYGLOT_LANGUAGE, "_tempMap = {}"); + Value tempMap = context.getBindings(POLYGLOT_LANGUAGE).getMember("_tempMap"); for (Map.Entry entry : ((Map) value).entrySet()) { Object deserializedObj = fromJsSerializableInternal(entry.getValue(), context); - deserializedMap.put(entry.getKey(), deserializedObj); + tempMap.putMember(entry.getKey(), deserializedObj); } - return deserializedMap; + //remove from bindings + context.getBindings(POLYGLOT_LANGUAGE).removeMember("_tempMap"); + return tempMap; } else if (value instanceof List) { Value deserializedValue = context.eval(POLYGLOT_LANGUAGE, "[]"); List valueList = (List) value; @@ -160,15 +161,6 @@ public static Object fromJsSerializableInternal(Object value, Context context) t deserializedValue.setArrayElement(index, deserializedObject); } return deserializedValue; - } else if (value.getClass().isArray()) { - Value deserializedValue = context.eval(POLYGLOT_LANGUAGE, "[]"); - int arraySize = java.lang.reflect.Array.getLength(value); - for (int index = 0; index < arraySize; index++) { - Object deserializedObject = - fromJsSerializableInternal(java.lang.reflect.Array.get(value, index), context); - deserializedValue.setArrayElement(index, deserializedObject); - } - return deserializedValue; } return value; }