Skip to content

Commit

Permalink
Use @HostAccess.Export to export conditional authentication functions…
Browse files Browse the repository at this point in the history
… implementations.
  • Loading branch information
shanggeeth committed Feb 20, 2024
1 parent 1e6b113 commit 4e6e9e2
Show file tree
Hide file tree
Showing 35 changed files with 303 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.util.EntityUtils;
import org.graalvm.polyglot.HostAccess;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
Expand Down Expand Up @@ -61,6 +62,7 @@ public class CallAnalyticsFunctionImpl extends AbstractAnalyticsFunction impleme
private static final String PARAM_INPUT_STREAM = "InputStream";

@Override
@HostAccess.Export
public void callAnalytics(Map<String, String> metadata,
Map<String, Object> payloadData, Map<String, Object> eventHandlers) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.graalvm.polyglot.HostAccess;
import org.json.simple.JSONObject;
import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseAuthenticationContext;
import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException;
Expand All @@ -49,6 +50,7 @@ public class PublishToAnalyticsFunctionImpl extends AbstractAnalyticsFunction im
private static final String PARAM_INPUT_STREAM = "InputStream";

@Override
@HostAccess.Export
public void publishToAnalytics(Map<String, String> metadata, Map<String, Object> payloadData,
JsBaseAuthenticationContext context) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.graalvm.polyglot.HostAccess;
import org.json.simple.JSONObject;
import org.wso2.carbon.identity.application.authentication.framework.AsyncProcess;
import org.wso2.carbon.identity.application.authentication.framework.AsyncReturn;
Expand Down Expand Up @@ -123,6 +124,7 @@ public CallChoreoFunctionImpl() {
}

@Override
@HostAccess.Export
public void callChoreo(Map<String, String> connectionMetaData, Map<String, Object> payloadData,
Map<String, Object> eventHandlers) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.util.EntityUtils;
import org.graalvm.polyglot.HostAccess;
import org.json.JSONException;
import org.json.JSONObject;
import org.wso2.carbon.identity.application.authentication.framework.AsyncProcess;
Expand Down Expand Up @@ -66,6 +67,7 @@ public CallElasticFunctionImpl() {
}

@Override
@HostAccess.Export
public void callElastic(Map<String, String> params, Map<String, Object> eventHandlers) {

Map<String, String> paramsMap = new HashMap<>(params);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,14 @@
/**
* Implementation of the setCookie and getCookieValue functions.
*/
@Deprecated
public class CookieFunctionImpl implements SetCookieFunction, GetCookieFunction {

private static final Log log = LogFactory.getLog(CookieFunctionImpl.class);
private static final String ENABLE_ADAPTIVE_SCRIPT_COOKIE_LEGACY_MODE = "enableAdaptiveScriptCookieLegacyMode";

@Override
@Deprecated
public void setCookie(JsBaseServletResponse response, String name, Object... params) {

Map<String, Object> properties = null;
Expand Down Expand Up @@ -121,6 +123,7 @@ public void setCookie(JsBaseServletResponse response, String name, Object... par
}

@Override
@Deprecated
public String getCookieValue(JsBaseServletRequest request, Object... params) {

Map<String, Object> properties = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package org.wso2.carbon.identity.conditional.auth.functions.http;

import org.graalvm.polyglot.HostAccess;
import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseServletRequest;

import java.util.Map;
Expand All @@ -36,6 +37,7 @@ public interface GetCookieFunction {
* @param params value mandatory and properties optional
* @return cookieValue
*/
@HostAccess.Export
String getCookieValue(JsBaseServletRequest request, Object... params);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* 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.conditional.auth.functions.http;

import org.apache.axiom.om.util.Base64;
import org.apache.commons.io.Charsets;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.graalvm.polyglot.HostAccess;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.wso2.carbon.core.util.CryptoException;
import org.wso2.carbon.core.util.CryptoUtil;
import org.wso2.carbon.core.util.SignatureUtil;
import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseServletRequest;
import org.wso2.carbon.identity.conditional.auth.functions.http.util.HTTPConstants;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Optional;

import javax.servlet.http.Cookie;

public class GetCookieFunctionImpl implements GetCookieFunction {

private static final Log log = LogFactory.getLog(GetCookieFunctionImpl.class);
private static final String ENABLE_ADAPTIVE_SCRIPT_COOKIE_LEGACY_MODE = "enableAdaptiveScriptCookieLegacyMode";

@Override
@HostAccess.Export
public String getCookieValue(JsBaseServletRequest request, Object... params) {

Map<String, Object> properties = null;
if (params.length == 0 || params.length > 2) {
return null;
}
if (params.length == 2) {
if (params[1] instanceof Map) {
properties = (Map<String, Object>) params[1];
}
}
String name = (String) params[0];
Cookie[] cookies = request.getWrapped().getWrapped().getCookies();
if (cookies == null) {
return null;
}
for (Cookie cookie : cookies) {
if (name.equals(cookie.getName())) {
JSONObject cookieValueJSON;
try {
JSONParser jsonParser = new JSONParser();
cookieValueJSON = (JSONObject) jsonParser.parse(new String(Base64.decode(cookie.getValue()),
Charsets.UTF_8));
} catch (ParseException e) {
log.error("Error occurred when converting cookie value to JSON.", e);
return null;
}
String valueString = (String) cookieValueJSON.get(HTTPConstants.VALUE);

if (properties != null) {
boolean validateSignature = Optional.ofNullable((Boolean) properties.get(
HTTPConstants.VALIDATE_SIGN)).orElse(false);
boolean decrypt = Optional.ofNullable((Boolean) properties.get(HTTPConstants.DECRYPT))
.orElse(false);
if (decrypt) {
try {
if (Boolean.parseBoolean(System.getProperty(ENABLE_ADAPTIVE_SCRIPT_COOKIE_LEGACY_MODE))) {
valueString = Base64.encode(CryptoUtil.getDefaultCryptoUtil()
.base64DecodeAndDecrypt(valueString));
} else {
valueString = new String(CryptoUtil.getDefaultCryptoUtil()
.base64DecodeAndDecrypt(valueString), StandardCharsets.UTF_8);
}
} catch (CryptoException e) {
log.error("Error occurred when decrypting the cookie value.", e);
return null;
}
}
if (validateSignature) {
byte[] signature = Base64.decode((String) cookieValueJSON.get(HTTPConstants.SIGNATURE));
try {
boolean isValid = SignatureUtil.validateSignature(valueString, signature);
if (!isValid) {
log.error("Cookie signature didn't matched with the cookie value.");
return null;
}
} catch (Exception e) {
log.error("Error occurred when validating signature of the cookie value.", e);
return null;
}
}
}
return valueString;
}
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.client.methods.HttpGet;
import org.graalvm.polyglot.HostAccess;

import java.util.HashMap;
import java.util.Map;
Expand All @@ -41,6 +42,7 @@ public HTTPGetFunctionImpl() {
}

@Override
@HostAccess.Export
public void httpGet(String endpointURL, Object... params) {

Map<String, Object> eventHandlers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicNameValuePair;
import org.graalvm.polyglot.HostAccess;
import org.json.simple.JSONObject;

import java.nio.charset.StandardCharsets;
Expand All @@ -52,6 +53,7 @@ public HTTPPostFunctionImpl() {
}

@Override
@HostAccess.Export
public void httpPost(String endpointURL, Object... params) {

Map<String, Object> eventHandlers;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* 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.conditional.auth.functions.http;

import org.apache.axiom.om.util.Base64;
import org.apache.commons.io.Charsets;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.graalvm.polyglot.HostAccess;
import org.json.simple.JSONObject;
import org.wso2.carbon.core.SameSiteCookie;
import org.wso2.carbon.core.ServletCookie;
import org.wso2.carbon.core.util.CryptoException;
import org.wso2.carbon.core.util.CryptoUtil;
import org.wso2.carbon.core.util.SignatureUtil;
import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.base.JsBaseServletResponse;
import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants;
import org.wso2.carbon.identity.conditional.auth.functions.http.util.HTTPConstants;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Optional;

public class SetCookieFunctionImpl implements SetCookieFunction {

private static final Log log = LogFactory.getLog(SetCookieFunctionImpl.class);
private static final String ENABLE_ADAPTIVE_SCRIPT_COOKIE_LEGACY_MODE = "enableAdaptiveScriptCookieLegacyMode";

@Override
@HostAccess.Export
public void setCookie(JsBaseServletResponse response, String name, Object... params) {

Map<String, Object> properties = null;
if (params.length == 0 || params.length > 2) {
return;
}
if (params.length == 2) {
if (params[1] instanceof Map) {
properties = (Map<String, Object>) params[1];
}
}

String value = (String) params[0];
String signature = null;
if (properties != null) {
boolean sign = Optional.ofNullable((Boolean) properties.get(HTTPConstants.SIGN)).orElse(false);
boolean encrypt = Optional.ofNullable((Boolean) properties.get(HTTPConstants.ENCRYPT)).orElse(false);
if (sign) {
try {
signature = Base64.encode(SignatureUtil.doSignature(value));
} catch (Exception e) {
log.error("Error occurred when signing the cookie value.", e);
return;
}
}
if (encrypt) {
try {
if (Boolean.parseBoolean(System.getProperty(ENABLE_ADAPTIVE_SCRIPT_COOKIE_LEGACY_MODE))) {
value = CryptoUtil.getDefaultCryptoUtil().encryptAndBase64Encode(Base64.decode(value));
} else {
value = CryptoUtil.getDefaultCryptoUtil().encryptAndBase64Encode(
value.getBytes(StandardCharsets.UTF_8));
}
} catch (CryptoException e) {
log.error("Error occurred when encrypting the cookie value.", e);
return;
}
}
}
JSONObject cookieValueJson = new JSONObject();
cookieValueJson.put(HTTPConstants.VALUE, value);
cookieValueJson.put(HTTPConstants.SIGNATURE, signature);

String cookieValue = cookieValueJson.toString();

cookieValue = Base64.encode((cookieValue.getBytes(Charsets.UTF_8)));
ServletCookie cookie = new ServletCookie(name, cookieValue);
if (properties != null) {
Optional.ofNullable((String) properties.get(FrameworkConstants.JSAttributes.JS_COOKIE_DOMAIN))
.ifPresent(cookie::setDomain);
Optional.ofNullable((String) properties.get(FrameworkConstants.JSAttributes.JS_COOKIE_PATH))
.ifPresent(cookie::setPath);
Optional.ofNullable((String) properties.get(FrameworkConstants.JSAttributes.JS_COOKIE_COMMENT))
.ifPresent(cookie::setComment);
Optional.ofNullable((Integer) properties.get(FrameworkConstants.JSAttributes.JS_COOKIE_MAX_AGE))
.ifPresent(cookie::setMaxAge);
Optional.ofNullable((Integer) properties.get(FrameworkConstants.JSAttributes.JS_COOKIE_VERSION))
.ifPresent(cookie::setVersion);
Optional.ofNullable((Boolean) properties.get(FrameworkConstants.JSAttributes.JS_COOKIE_HTTP_ONLY))
.ifPresent(cookie::setHttpOnly);
Optional.ofNullable((Boolean) properties.get(FrameworkConstants.JSAttributes.JS_COOKIE_SECURE))
.ifPresent(cookie::setSecure);
String sameSite = (String) properties.get(FrameworkConstants.JSAttributes.JS_COOKIE_SAMESITE);
Optional.ofNullable((sameSite != null) ? SameSiteCookie.valueOf(sameSite) : null)
.ifPresent(cookie::setSameSite);
}
response.getWrapped().getWrapped().addCookie(cookie);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,12 @@
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.wso2.carbon.identity.application.authentication.framework.JsFunctionRegistry;
import org.wso2.carbon.identity.conditional.auth.functions.http.GetCookieFunctionImpl;
import org.wso2.carbon.identity.conditional.auth.functions.http.HTTPGetFunction;
import org.wso2.carbon.identity.conditional.auth.functions.http.HTTPGetFunctionImpl;
import org.wso2.carbon.identity.conditional.auth.functions.http.HTTPPostFunction;
import org.wso2.carbon.identity.conditional.auth.functions.http.HTTPPostFunctionImpl;
import org.wso2.carbon.identity.conditional.auth.functions.http.CookieFunctionImpl;
import org.wso2.carbon.identity.conditional.auth.functions.http.GetCookieFunction;
import org.wso2.carbon.identity.conditional.auth.functions.http.SetCookieFunction;
import org.wso2.carbon.identity.conditional.auth.functions.http.SetCookieFunctionImpl;
import org.wso2.carbon.identity.core.util.IdentityCoreInitializedEvent;

/**
Expand All @@ -58,12 +57,10 @@ public class HTTPFunctionsServiceComponent {
@Activate
protected void activate(ComponentContext ctxt) {

CookieFunctionImpl cookieFunction = new CookieFunctionImpl();
JsFunctionRegistry jsFunctionRegistry = HTTPFunctionsServiceHolder.getInstance().getJsFunctionRegistry();
jsFunctionRegistry.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, FUNC_SET_COOKIE,
(SetCookieFunction) cookieFunction::setCookie);
jsFunctionRegistry.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, FUNC_GET_COOKIE_VALUE,
(GetCookieFunction) cookieFunction::getCookieValue);
jsFunctionRegistry.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, FUNC_SET_COOKIE, new GetCookieFunctionImpl());
jsFunctionRegistry.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER,
FUNC_GET_COOKIE_VALUE, new SetCookieFunctionImpl());

HTTPPostFunction httpPost = new HTTPPostFunctionImpl();
jsFunctionRegistry.register(JsFunctionRegistry.Subsystem.SEQUENCE_HANDLER, FUNC_HTTP_POST, httpPost);
Expand Down
Loading

0 comments on commit 4e6e9e2

Please sign in to comment.