From b8f623e04ad5e19350c710bc9840d5ed5e19a460 Mon Sep 17 00:00:00 2001 From: Rasika Perera Date: Mon, 17 Oct 2016 10:51:39 +0530 Subject: [PATCH] Supporting custom contentTypes for service invoker --- .../jaggeryapps/devicemgt/api/invoker-api.jag | 23 +++++++-- .../oauth/token-protected-service-invokers.js | 51 +++++++++++++++---- 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/invoker-api.jag b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/invoker-api.jag index 3e410ee2c56..b701ad3f019 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/invoker-api.jag +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/invoker-api.jag @@ -27,6 +27,12 @@ var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"]; var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"]; if (uriMatcher.match("/{context}/api/invoker/execute/")) { + //NOTE: We are only interested in Content-Type headers. Appending all request headers to the back-end call + // will cause unforeseen security issues. + var contentType = request.getHeader(constants.CONTENT_TYPE_IDENTIFIER); + var requestHeaders = []; + requestHeaders.push({"name": constants.CONTENT_TYPE_IDENTIFIER, "value" : contentType}); + var restAPIRequestDetails = request.getContent(); var requestMethod = restAPIRequestDetails["requestMethod"]; @@ -57,7 +63,8 @@ if (uriMatcher.match("/{context}/api/invoker/execute/")) { if (restAPIResponse["responseText"]) { response["content"] = restAPIResponse["responseText"]; } - } + }, + requestHeaders ); break; case constants["HTTP_POST"]: @@ -69,7 +76,8 @@ if (uriMatcher.match("/{context}/api/invoker/execute/")) { if (restAPIResponse["responseText"]) { response["content"] = restAPIResponse["responseText"]; } - } + }, + requestHeaders ); break; case constants["HTTP_PUT"]: @@ -81,7 +89,8 @@ if (uriMatcher.match("/{context}/api/invoker/execute/")) { if (restAPIResponse["responseText"]) { response["content"] = restAPIResponse["responseText"]; } - } + }, + requestHeaders ); break; case constants["HTTP_DELETE"]: @@ -92,13 +101,17 @@ if (uriMatcher.match("/{context}/api/invoker/execute/")) { if (restAPIResponse["responseText"]) { response["content"] = restAPIResponse["responseText"]; } - } + }, + requestHeaders ); break; } } catch (e) { + //Since this is an API we'll log the error message. + log.error(e.message); // JavaScript error message + log.error(e.stack); // Executed JavaScript file stack throw new Error("Exception occurred while trying to access " + - "backend REST API services from Jaggery API invoker layer", e); + "backend REST API services from Jaggery API invoker layer", e); } } %> diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/oauth/token-protected-service-invokers.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/oauth/token-protected-service-invokers.js index b79e7c6a070..bb260ae5ea6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/oauth/token-protected-service-invokers.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/oauth/token-protected-service-invokers.js @@ -73,11 +73,26 @@ var invokers = function () { var xmlHttpRequest = new XMLHttpRequest(); xmlHttpRequest.open(httpMethod, endpoint); + + var contentTypeFound = false; + var acceptTypeFound = false; for (var i in headers) { xmlHttpRequest.setRequestHeader(headers[i].name, headers[i].value); + if(constants["CONTENT_TYPE_IDENTIFIER"] == headers[i].name){ + contentTypeFound = true; + } + if(constants["ACCEPT_IDENTIFIER"] == headers[i].name){ + acceptTypeFound = true; + } + } + + if (!contentTypeFound) { + xmlHttpRequest.setRequestHeader(constants["CONTENT_TYPE_IDENTIFIER"], constants["APPLICATION_JSON"]); + } + + if (!acceptTypeFound) { + xmlHttpRequest.setRequestHeader(constants["ACCEPT_IDENTIFIER"], constants["APPLICATION_JSON"]); } - xmlHttpRequest.setRequestHeader(constants["CONTENT_TYPE_IDENTIFIER"], constants["APPLICATION_JSON"]); - xmlHttpRequest.setRequestHeader(constants["ACCEPT_IDENTIFIER"], constants["APPLICATION_JSON"]); if (devicemgtProps["isOAuthEnabled"]) { var accessToken = privateMethods.getAccessToken(); @@ -284,23 +299,37 @@ var invokers = function () { //noinspection JSUnresolvedVariable var Header = Packages.org.apache.commons.httpclient.Header; + var contentTypeFound = false; + var acceptTypeFound = false; for (var i in headers) { var header = new Header(); header.setName(headers[i].name); header.setValue(headers[i].value); httpMethodObject.addRequestHeader(header); + + if(constants["CONTENT_TYPE_IDENTIFIER"] == headers[i].name){ + contentTypeFound = true; + } + if(constants["ACCEPT_IDENTIFIER"] == headers[i].name){ + acceptTypeFound = true; + } } var header = new Header(); - header.setName(constants["CONTENT_TYPE_IDENTIFIER"]); - header.setValue(constants["APPLICATION_JSON"]); - //noinspection JSUnresolvedFunction - httpMethodObject.addRequestHeader(header); - header = new Header(); - header.setName(constants["ACCEPT_IDENTIFIER"]); - header.setValue(constants["APPLICATION_JSON"]); - //noinspection JSUnresolvedFunction - httpMethodObject.addRequestHeader(header); + if(!contentTypeFound){ + header.setName(constants["CONTENT_TYPE_IDENTIFIER"]); + header.setValue(constants["APPLICATION_JSON"]); + //noinspection JSUnresolvedFunction + httpMethodObject.addRequestHeader(header); + } + + if(!acceptTypeFound) { + header = new Header(); + header.setName(constants["ACCEPT_IDENTIFIER"]); + header.setValue(constants["APPLICATION_JSON"]); + //noinspection JSUnresolvedFunction + httpMethodObject.addRequestHeader(header); + } if (devicemgtProps["isOAuthEnabled"]) { var accessToken = privateMethods.getAccessToken();