From 8f2b519d647e03935aa32d39643bc14dab2630d5 Mon Sep 17 00:00:00 2001 From: Chanaka Jayasena Date: Fri, 18 Nov 2022 15:31:56 +0530 Subject: [PATCH 1/2] Fixing error after configuring proxy context path --- .../services/login/login_callback.jag | 201 ++++++++++++++++++ .../webapp/services/login/login_callback.jsp | 2 +- .../src/app/data/ServiceCatalogClient.js | 10 +- .../main/webapp/source/src/app/data/Utils.js | 20 +- 4 files changed, 226 insertions(+), 7 deletions(-) create mode 100644 portals/publisher/services/login/login_callback.jag diff --git a/portals/publisher/services/login/login_callback.jag b/portals/publisher/services/login/login_callback.jag new file mode 100644 index 00000000000..ef236e0ab70 --- /dev/null +++ b/portals/publisher/services/login/login_callback.jag @@ -0,0 +1,201 @@ +<% +/* + * Copyright (c) 2019, 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. + */ + +(function () { + include("/services/constants.jag"); + var appUtils = require("/services/utils.js"); + include("/services/constants.jag"); + var app = require("/site/public/conf/settings.js").AppConfig.app; + app.context = appUtils.getTenantBasePublisherContext(); + var utils = Packages.org.wso2.carbon.apimgt.impl.utils.APIUtil; + var log = new Log(); + log.debug("Login Callback Endpoint"); + + var appContext = appUtils.getAppContextForServerUrl(); + + var serverUrl = ''; + var forwarded_for = request.getHeader(app.customUrl.forwardedHeader); + if (app.customUrl.enabled && forwarded_for) { + serverUrl = "https://" + forwarded_for; + } else { + serverUrl = utils.getServerURL(); + } + var loginCallbackUrl = appUtils.getTenantBasedLoginCallBack(); + if (loginCallbackUrl == null) { + loginCallbackUrl = serverUrl + appContext + LOGIN_CALLBACK_URL_SUFFIX; + } + if(request.getParameter("error") == "login_required") { + response.sendRedirect(serverUrl + appContext + "/services/logout"); + } else if (request.getParameter("code") != null) { + var tokenRequestData = { + "grant_type": "authorization_code", + "code": request.getParameter("code", "UTF-8"), + "redirect_uri": loginCallbackUrl + }; + var tenantDomain = "carbon.super" ; + if (appUtils.isPerTenantServiceProviderEnabled()) { + tenantDomain = appUtils.getTenantDomain(); + } + var SystemApplicationDTO = Packages.org.wso2.carbon.apimgt.impl.dao.SystemApplicationDAO; + var systemApplicationDAO = new SystemApplicationDTO(); + // this is to support migration from admin_publisher to apim_publisher + var systemApplicationDTO = systemApplicationDAO.getClientCredentialsForApplication(PUBLISHER_CLIENT_APP_NAME, tenantDomain); + if (systemApplicationDTO === null) { + systemApplicationDTO = systemApplicationDAO.getClientCredentialsForApplication(PUBLISHER_CLIENT_APP_NAME_OLD, tenantDomain); + } + var clientId = systemApplicationDTO.getConsumerKey(); + var clientSecret = systemApplicationDTO.getConsumerSecret(); + var Base64 = org.apache.axiom.om.util.Base64; + var String = Packages.java.lang.String; + var Integer = Packages.java.lang.Integer; + var base64encoded = Base64.encode(new String(clientId + ":" + clientSecret).getBytes()); + var tokenEndpoint = appUtils.getLoopbackOrigin() + TOKEN_URL_SUFFIX; + var result = post(tokenEndpoint, tokenRequestData, {"Authorization": "Basic " + base64encoded}); + + var erroLogin = serverUrl + appContext +"/error-pages?code="; + var responseFailed = false; + if (JSON.parse(result.data).error != null) { + responseFailed = true; + } else { + response.contentType = "application/json"; + var tokenResponse = JSON.parse(result.data); + + var tokenLength = tokenResponse.access_token.length; + var accessToken = String(tokenResponse.access_token); + + var idTokenLength = tokenResponse.id_token.length; + var idToken = String(tokenResponse.id_token); + + var idTokenPart1 = idToken.substring(0, idTokenLength / 2); + var idTokenPart2 = idToken.substring(idTokenLength / 2, idTokenLength); + + var accessTokenPart1 = accessToken.substring(0, tokenLength / 2); + var accessTokenPart2 = accessToken.substring(tokenLength / 2, tokenLength); + + var refreshToken = String(tokenResponse.refresh_token); + tokenLength = tokenResponse.refresh_token.length; + var refreshTokenPart1 = refreshToken.substring(0, tokenLength / 2); + var refreshTokenPart2 = refreshToken.substring(tokenLength / 2, tokenLength); + + // Setting access token part 1 as secured HTTP only cookie, Can't restrict the path to /api/am/publisher + // because partial HTTP only cookie is required for get the user information from access token, + // hence setting the HTTP only access token path to App context + var cookie = { + 'name': 'AM_ACC_TOKEN_DEFAULT_P2', + 'value': accessTokenPart2, + 'path': app.context + "/", + "httpOnly": true, + "secure": true, + "maxAge": Integer(tokenResponse.expires_in) + }; + response.addCookie(cookie); + + cookie = { + 'name': 'AM_ACC_TOKEN_DEFAULT_P2', + 'value': accessTokenPart2, + 'path': app.proxy_context_path ? app.proxy_context_path + "/api/am/publisher/": "/api/am/publisher/", + "httpOnly": true, + "secure": true, + "maxAge": Integer(tokenResponse.expires_in) + }; + response.addCookie(cookie); + + cookie = { + 'name': 'AM_ACC_TOKEN_DEFAULT_P2', + 'value': accessTokenPart2, + 'path': app.proxy_context_path ? app.proxy_context_path + "/api/am/service-catalog/v1/": "/api/am/service-catalog/v1/", + "httpOnly": true, + "secure": true, + "maxAge": Integer(tokenResponse.expires_in) + }; + response.addCookie(cookie); + + + cookie = { + 'name': 'AM_REF_TOKEN_DEFAULT_P2', + 'value': refreshTokenPart2, + 'path': app.context + "/", + "httpOnly": true, + "secure": true, + "maxAge": 86400 // TODO: Default value a day, need to get this from idn configs ~tmkb + }; + response.addCookie(cookie); + + cookie = { + 'name': 'WSO2_AM_TOKEN_1_Default', + 'value': accessTokenPart1, + 'path': app.context + "/", + "secure": true, + "maxAge": Integer(tokenResponse.expires_in) + }; + response.addCookie(cookie); + + cookie = { + 'name': 'WSO2_AM_REFRESH_TOKEN_1_Default', + 'value': refreshTokenPart1, + 'path': app.context + "/", + "secure": true, + "maxAge": 86400 // TODO: Default value a day, need to get this from idn configs ~tmkb + }; + response.addCookie(cookie); + + cookie = { + 'name': 'AM_ID_TOKEN_DEFAULT_P2', + 'value': idTokenPart2, + 'path': app.context + "/services/logout", + "secure": true, + "maxAge": Integer(tokenResponse.expires_in) + }; + response.addCookie(cookie); + + cookie = { + 'name': 'AM_ID_TOKEN_DEFAULT_P1', + 'value': idTokenPart1, + 'path': app.context + "/services/logout", + "secure": true, + "maxAge": Integer(tokenResponse.expires_in) + }; + response.addCookie(cookie); + + cookie = { + 'name': 'publisher_session_state', + 'value': request.getParameter("session_state", "UTF-8"), + 'path': app.context + "/", + "secure": true, + "maxAge": Integer(-1) + }; + response.addCookie(cookie); + } + var state = request.getParameter("state"); + if (responseFailed === true) { + response.sendRedirect(erroLogin + "500"); + } else if (state !== null) { + state = decodeURIComponent(state); + if ( state !== '/') { + response.sendRedirect(app.context + state); + } else { + response.sendRedirect(app.context + '/'); + } + } else { + response.sendRedirect(app.context + '/'); + } + + } +}()); +%> diff --git a/portals/publisher/src/main/webapp/services/login/login_callback.jsp b/portals/publisher/src/main/webapp/services/login/login_callback.jsp index 9530db09b4e..17d076bd225 100644 --- a/portals/publisher/src/main/webapp/services/login/login_callback.jsp +++ b/portals/publisher/src/main/webapp/services/login/login_callback.jsp @@ -149,7 +149,7 @@ response.addCookie(cookie); cookie = new Cookie("AM_ACC_TOKEN_DEFAULT_P2", accessTokenPart2); - cookie.setPath("/api/am/service-catalog/v1/"); + cookie.setPath(proxyContext != null ? proxyContext + "/api/am/service-catalog/v1/" : "/api/am/service-catalog/v1/"); cookie.setHttpOnly(true); cookie.setSecure(true); cookie.setMaxAge((int) expiresIn); diff --git a/portals/publisher/src/main/webapp/source/src/app/data/ServiceCatalogClient.js b/portals/publisher/src/main/webapp/source/src/app/data/ServiceCatalogClient.js index 7d4fa2cb083..60ad7f41fe4 100644 --- a/portals/publisher/src/main/webapp/source/src/app/data/ServiceCatalogClient.js +++ b/portals/publisher/src/main/webapp/source/src/app/data/ServiceCatalogClient.js @@ -113,9 +113,17 @@ class ServiceCatalogClient { * @returns {JSON} : Fixed specification * @private */ + _fixSpec(spec) { const updatedSpec = spec; - updatedSpec.servers = [{ url: window.origin + '/api/am/service-catalog/v1' }]; + if (Configurations.app.proxy_context_path && Configurations.app.proxy_context_path !== '') { + updatedSpec.servers = [{ url: window.origin + Configurations.app.proxy_context_path + + '/api/am/service-catalog/v1' }]; + + } else { + updatedSpec.servers = [{ url: window.origin + '/api/am/service-catalog/v1' }]; + } + return updatedSpec; } diff --git a/portals/publisher/src/main/webapp/source/src/app/data/Utils.js b/portals/publisher/src/main/webapp/source/src/app/data/Utils.js index 6180d8cb0cc..5a88830eb8a 100644 --- a/portals/publisher/src/main/webapp/source/src/app/data/Utils.js +++ b/portals/publisher/src/main/webapp/source/src/app/data/Utils.js @@ -238,11 +238,21 @@ class Utils { * @memberof Utils */ static getServiceCatalogSwaggerURL() { - return ( - 'https://' + - Utils.getCurrentEnvironment().host + - Utils.CONST.SERVICE_CATALOG_SWAGGER_YAML - ); + if (Configurations.app.proxy_context_path) { + return ( + 'https://' + + Utils.getCurrentEnvironment().host + + Configurations.app.proxy_context_path + + Utils.CONST.SERVICE_CATALOG_SWAGGER_YAML + ); + } else { + return ( + 'https://' + + Utils.getCurrentEnvironment().host + + Utils.CONST.SERVICE_CATALOG_SWAGGER_YAML + ); + } + // return Utils.CONST.SERVICE_CATALOG_SWAGGER_YAML; } From a763f326d292e89c30601ffa2575f59740c50d00 Mon Sep 17 00:00:00 2001 From: Chanaka Jayasena Date: Wed, 30 Nov 2022 11:11:34 +0530 Subject: [PATCH 2/2] removing accidental addition of old jag file from the PR --- .../services/login/login_callback.jag | 201 ------------------ 1 file changed, 201 deletions(-) delete mode 100644 portals/publisher/services/login/login_callback.jag diff --git a/portals/publisher/services/login/login_callback.jag b/portals/publisher/services/login/login_callback.jag deleted file mode 100644 index ef236e0ab70..00000000000 --- a/portals/publisher/services/login/login_callback.jag +++ /dev/null @@ -1,201 +0,0 @@ -<% -/* - * Copyright (c) 2019, 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. - */ - -(function () { - include("/services/constants.jag"); - var appUtils = require("/services/utils.js"); - include("/services/constants.jag"); - var app = require("/site/public/conf/settings.js").AppConfig.app; - app.context = appUtils.getTenantBasePublisherContext(); - var utils = Packages.org.wso2.carbon.apimgt.impl.utils.APIUtil; - var log = new Log(); - log.debug("Login Callback Endpoint"); - - var appContext = appUtils.getAppContextForServerUrl(); - - var serverUrl = ''; - var forwarded_for = request.getHeader(app.customUrl.forwardedHeader); - if (app.customUrl.enabled && forwarded_for) { - serverUrl = "https://" + forwarded_for; - } else { - serverUrl = utils.getServerURL(); - } - var loginCallbackUrl = appUtils.getTenantBasedLoginCallBack(); - if (loginCallbackUrl == null) { - loginCallbackUrl = serverUrl + appContext + LOGIN_CALLBACK_URL_SUFFIX; - } - if(request.getParameter("error") == "login_required") { - response.sendRedirect(serverUrl + appContext + "/services/logout"); - } else if (request.getParameter("code") != null) { - var tokenRequestData = { - "grant_type": "authorization_code", - "code": request.getParameter("code", "UTF-8"), - "redirect_uri": loginCallbackUrl - }; - var tenantDomain = "carbon.super" ; - if (appUtils.isPerTenantServiceProviderEnabled()) { - tenantDomain = appUtils.getTenantDomain(); - } - var SystemApplicationDTO = Packages.org.wso2.carbon.apimgt.impl.dao.SystemApplicationDAO; - var systemApplicationDAO = new SystemApplicationDTO(); - // this is to support migration from admin_publisher to apim_publisher - var systemApplicationDTO = systemApplicationDAO.getClientCredentialsForApplication(PUBLISHER_CLIENT_APP_NAME, tenantDomain); - if (systemApplicationDTO === null) { - systemApplicationDTO = systemApplicationDAO.getClientCredentialsForApplication(PUBLISHER_CLIENT_APP_NAME_OLD, tenantDomain); - } - var clientId = systemApplicationDTO.getConsumerKey(); - var clientSecret = systemApplicationDTO.getConsumerSecret(); - var Base64 = org.apache.axiom.om.util.Base64; - var String = Packages.java.lang.String; - var Integer = Packages.java.lang.Integer; - var base64encoded = Base64.encode(new String(clientId + ":" + clientSecret).getBytes()); - var tokenEndpoint = appUtils.getLoopbackOrigin() + TOKEN_URL_SUFFIX; - var result = post(tokenEndpoint, tokenRequestData, {"Authorization": "Basic " + base64encoded}); - - var erroLogin = serverUrl + appContext +"/error-pages?code="; - var responseFailed = false; - if (JSON.parse(result.data).error != null) { - responseFailed = true; - } else { - response.contentType = "application/json"; - var tokenResponse = JSON.parse(result.data); - - var tokenLength = tokenResponse.access_token.length; - var accessToken = String(tokenResponse.access_token); - - var idTokenLength = tokenResponse.id_token.length; - var idToken = String(tokenResponse.id_token); - - var idTokenPart1 = idToken.substring(0, idTokenLength / 2); - var idTokenPart2 = idToken.substring(idTokenLength / 2, idTokenLength); - - var accessTokenPart1 = accessToken.substring(0, tokenLength / 2); - var accessTokenPart2 = accessToken.substring(tokenLength / 2, tokenLength); - - var refreshToken = String(tokenResponse.refresh_token); - tokenLength = tokenResponse.refresh_token.length; - var refreshTokenPart1 = refreshToken.substring(0, tokenLength / 2); - var refreshTokenPart2 = refreshToken.substring(tokenLength / 2, tokenLength); - - // Setting access token part 1 as secured HTTP only cookie, Can't restrict the path to /api/am/publisher - // because partial HTTP only cookie is required for get the user information from access token, - // hence setting the HTTP only access token path to App context - var cookie = { - 'name': 'AM_ACC_TOKEN_DEFAULT_P2', - 'value': accessTokenPart2, - 'path': app.context + "/", - "httpOnly": true, - "secure": true, - "maxAge": Integer(tokenResponse.expires_in) - }; - response.addCookie(cookie); - - cookie = { - 'name': 'AM_ACC_TOKEN_DEFAULT_P2', - 'value': accessTokenPart2, - 'path': app.proxy_context_path ? app.proxy_context_path + "/api/am/publisher/": "/api/am/publisher/", - "httpOnly": true, - "secure": true, - "maxAge": Integer(tokenResponse.expires_in) - }; - response.addCookie(cookie); - - cookie = { - 'name': 'AM_ACC_TOKEN_DEFAULT_P2', - 'value': accessTokenPart2, - 'path': app.proxy_context_path ? app.proxy_context_path + "/api/am/service-catalog/v1/": "/api/am/service-catalog/v1/", - "httpOnly": true, - "secure": true, - "maxAge": Integer(tokenResponse.expires_in) - }; - response.addCookie(cookie); - - - cookie = { - 'name': 'AM_REF_TOKEN_DEFAULT_P2', - 'value': refreshTokenPart2, - 'path': app.context + "/", - "httpOnly": true, - "secure": true, - "maxAge": 86400 // TODO: Default value a day, need to get this from idn configs ~tmkb - }; - response.addCookie(cookie); - - cookie = { - 'name': 'WSO2_AM_TOKEN_1_Default', - 'value': accessTokenPart1, - 'path': app.context + "/", - "secure": true, - "maxAge": Integer(tokenResponse.expires_in) - }; - response.addCookie(cookie); - - cookie = { - 'name': 'WSO2_AM_REFRESH_TOKEN_1_Default', - 'value': refreshTokenPart1, - 'path': app.context + "/", - "secure": true, - "maxAge": 86400 // TODO: Default value a day, need to get this from idn configs ~tmkb - }; - response.addCookie(cookie); - - cookie = { - 'name': 'AM_ID_TOKEN_DEFAULT_P2', - 'value': idTokenPart2, - 'path': app.context + "/services/logout", - "secure": true, - "maxAge": Integer(tokenResponse.expires_in) - }; - response.addCookie(cookie); - - cookie = { - 'name': 'AM_ID_TOKEN_DEFAULT_P1', - 'value': idTokenPart1, - 'path': app.context + "/services/logout", - "secure": true, - "maxAge": Integer(tokenResponse.expires_in) - }; - response.addCookie(cookie); - - cookie = { - 'name': 'publisher_session_state', - 'value': request.getParameter("session_state", "UTF-8"), - 'path': app.context + "/", - "secure": true, - "maxAge": Integer(-1) - }; - response.addCookie(cookie); - } - var state = request.getParameter("state"); - if (responseFailed === true) { - response.sendRedirect(erroLogin + "500"); - } else if (state !== null) { - state = decodeURIComponent(state); - if ( state !== '/') { - response.sendRedirect(app.context + state); - } else { - response.sendRedirect(app.context + '/'); - } - } else { - response.sendRedirect(app.context + '/'); - } - - } -}()); -%>