diff --git a/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPPostFunctionImpl.java b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPPostFunctionImpl.java index 56728a96..fea5c0a4 100644 --- a/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPPostFunctionImpl.java +++ b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPPostFunctionImpl.java @@ -37,7 +37,7 @@ import java.util.Map; import static org.apache.http.HttpHeaders.CONTENT_TYPE; - +import static org.wso2.carbon.identity.conditional.auth.functions.common.utils.CommonUtils.getPayloadDataMap; /** * Implementation of the {@link HTTPPostFunction} @@ -111,20 +111,22 @@ public void httpPost(String endpointURL, Object... params) { setHeaders(request, headers); if (MapUtils.isNotEmpty(payloadData)) { + + Map payloadDataMap = getPayloadDataMap(payloadData); /* For the header "Content-Type : application/x-www-form-urlencoded" request body data is set to UrlEncodedFormEntity format. For the other cases request body data is set to StringEntity format. */ if (TYPE_APPLICATION_FORM_URLENCODED.equals(headers.get(CONTENT_TYPE))) { List entities = new ArrayList<>(); - for (Map.Entry dataElements : payloadData.entrySet()) { + for (Map.Entry dataElements : payloadDataMap.entrySet()) { String value = (dataElements.getValue() != null) ? dataElements.getValue().toString() : null; entities.add(new BasicNameValuePair(dataElements.getKey(), value)); } request.setEntity(new UrlEncodedFormEntity(entities, StandardCharsets.UTF_8)); } else { JSONObject jsonObject = new JSONObject(); - jsonObject.putAll(payloadData); + jsonObject.putAll(payloadDataMap); request.setEntity(new StringEntity(jsonObject.toJSONString(), StandardCharsets.UTF_8)); } } diff --git a/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/test/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPPostFunctionImplTest.java b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/test/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPPostFunctionImplTest.java index 712de177..ada195a0 100644 --- a/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/test/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPPostFunctionImplTest.java +++ b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/test/java/org/wso2/carbon/identity/conditional/auth/functions/http/HTTPPostFunctionImplTest.java @@ -18,6 +18,8 @@ package org.wso2.carbon.identity.conditional.auth.functions.http; +import com.google.gson.Gson; +import com.google.gson.JsonObject; import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.JOSEObjectType; import com.nimbusds.jose.JWSAlgorithm; @@ -94,6 +96,8 @@ public class HTTPPostFunctionImplTest extends JsSequenceHandlerAbstractTest { private static final String ALLOWED_DOMAIN = "abc"; private static final String AUTHORIZATION = "Authorization"; private static final String API_KEY_HEADER = "X-API-KEY"; + public static final String HTTP_POST_PAYLOAD = "http-post-payload.json"; + public static final String HTTP_POST_PAYLOAD_TEST_SP = "http-post-payload-test-sp.xml"; private HTTPPostFunctionImpl httpPostFunction; @InjectMicroservicePort @@ -229,6 +233,20 @@ public void testHttpPostMethodWithClientCredentialAuthConfig() throws JsTestExce result); } + /** + * Test httpPost method with payload. + * Check if the payload data is sent with the request. + * + * @throws JsTestException + */ + @Test + public void testHttpPostMethodWithPayload() throws JsTestException { + + String result = executeHttpPostFunction("dummy-post-with-payload", HTTP_POST_PAYLOAD_TEST_SP); + assertEquals(result, SUCCESS, "The http post request was not successful. Result from request: " + + result); + } + /** * Tests the behavior of the httpPost function when provided with null headers. * @@ -291,7 +309,7 @@ private String executeHttpPostFunction(String path, String adaptiveAuthScript) t return context.getSelectedAcr(); } - private void updateSPAuthScriptRequestUrl(ServiceProvider sp, String path) { + private void updateSPAuthScriptRequestUrl(ServiceProvider sp, String path) throws JsTestException { LocalAndOutboundAuthenticationConfig localAndOutboundAuthenticationConfig = sp.getLocalAndOutBoundAuthenticationConfig(); @@ -303,7 +321,7 @@ private void updateSPAuthScriptRequestUrl(ServiceProvider sp, String path) { sp.setLocalAndOutBoundAuthenticationConfig(localAndOutboundAuthenticationConfig); } - private String getFormattedScript(String script, String path) { + private String getFormattedScript(String script, String path) throws JsTestException { switch (path) { case "dummy-post": return String.format(script, getRequestUrl("dummy-post")); @@ -318,6 +336,9 @@ private String getFormattedScript(String script, String path) { case "dummy-post-with-clientcredential-auth-config": return String.format(script, getRequestUrl("dummy-post-with-clientcredential-auth-config"), getRequestUrl("dummy-token-endpoint")); + case "dummy-post-with-payload": + JsonObject Payload = sequenceHandlerRunner.loadJson(HTTP_POST_PAYLOAD, this); + return String.format(script, Payload.toString(), getRequestUrl("dummy-post-with-payload")); default: return null; } @@ -466,6 +487,28 @@ public Map dummyPostWithClientCredentialAuthConfig(@HeaderParam( return response; } + @POST + @Path("/dummy-post-with-payload") + @Consumes("application/json") + @Produces("application/json") + public Map dummyPostWithPayload(Map data) throws JsTestException { + + JsonObject expectedPayload = sequenceHandlerRunner.loadJson(HTTP_POST_PAYLOAD, this); + Gson gson = new Gson(); + String dataStr = gson.toJson(data); + JsonObject actualPayload = gson.fromJson(dataStr, JsonObject.class); + Map response = new HashMap<>(); + response.put(STATUS, SUCCESS); + response.put("data", dataStr); + + if (expectedPayload.equals(actualPayload)) { + return response; + } else { + throw new JsTestException("Payloads do not match. " + + String.format("Expected payload: %s, Actual payload: %s", expectedPayload, actualPayload)); + } + } + /** * Dummy token endpoint to test the http post function with clientcredential auth config. * diff --git a/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/test/resources/org/wso2/carbon/identity/conditional/auth/functions/http/http-post-payload-test-sp.xml b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/test/resources/org/wso2/carbon/identity/conditional/auth/functions/http/http-post-payload-test-sp.xml new file mode 100644 index 00000000..da35fef7 --- /dev/null +++ b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/test/resources/org/wso2/carbon/identity/conditional/auth/functions/http/http-post-payload-test-sp.xml @@ -0,0 +1,72 @@ + + + 1 + default + Default Service Provider + + + + default + + + + + + + + + 1 + + + BasicMockAuthenticator + basicauth + true + + + true + true + + + + flow + + + + + + true + + + diff --git a/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/test/resources/org/wso2/carbon/identity/conditional/auth/functions/http/http-post-payload.json b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/test/resources/org/wso2/carbon/identity/conditional/auth/functions/http/http-post-payload.json new file mode 100644 index 00000000..1692934b --- /dev/null +++ b/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/test/resources/org/wso2/carbon/identity/conditional/auth/functions/http/http-post-payload.json @@ -0,0 +1,39 @@ +{ + "stringKey": "stringValue", + "numberKey": 123, + "booleanKey": true, + "arrayKey": [ + "arrayString", + 456, + false, + { + "nestedObjectInArrayKey": "nestedObjectValue", + "nestedArrayInArrayKey": ["nestedArrayValue1", "nestedArrayValue2"] + } + ], + "objectKey": { + "objectStringKey": "objectStringValue", + "objectNumberKey": 789, + "objectBooleanKey": false, + "nestedObjectKey": { + "nestedObjectStringKey": "nestedObjectStringValue", + "nestedObjectArrayKey": [ + "nestedArrayValue1", + 101112, + true + ] + }, + "arrayOfObjectsKey": [ + { + "arrayOfObjectsStringKey": "arrayOfObjectsStringValue1", + "arrayOfObjectsNumberKey": 131415, + "arrayOfObjectsBooleanKey": true + }, + { + "arrayOfObjectsStringKey": "arrayOfObjectsStringValue2", + "arrayOfObjectsNumberKey": 161718, + "arrayOfObjectsBooleanKey": false + } + ] + } +} \ No newline at end of file