From 839e433d8b896f55ce9a8f8ad1a27de1e1f995d1 Mon Sep 17 00:00:00 2001 From: Lorenzo Natali Date: Mon, 14 May 2018 15:21:58 +0200 Subject: [PATCH] Fix #2892. Remove authkey from dashboard layers (#2894) --- web/client/libs/__tests__/ajax-test.js | 3 ++- web/client/libs/ajax.js | 2 ++ web/client/observables/wms.js | 4 +++- web/client/utils/SecurityUtils.js | 24 ++++++++++--------- .../utils/__tests__/SecurityUtils-test.js | 7 ++++++ 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/web/client/libs/__tests__/ajax-test.js b/web/client/libs/__tests__/ajax-test.js index 6d61245249..c24a8ac95c 100644 --- a/web/client/libs/__tests__/ajax-test.js +++ b/web/client/libs/__tests__/ajax-test.js @@ -208,12 +208,13 @@ describe('Tests ajax library', () => { expect.spyOn(SecurityUtils, 'getAuthenticationRules').andReturn(authenticationRules); // authkey authentication with user expect.spyOn(SecurityUtils, 'getSecurityInfo').andReturn(securityInfoB); - axios.get('http://www.some-site.com/geoserver?parameter1=value1¶meter2=value2').then(() => { + axios.get('http://www.some-site.com/geoserver?parameter1=value1¶meter2=value2&authkey=TEST_AUTHKEY').then(() => { done(); }).catch((exception) => { expect(exception.config).toExist(); expect(exception.config.url).toExist(); expect(exception.config.url.indexOf('authkey')).toBeGreaterThan(-1); + expect(exception.config.url.indexOf("TEST_AUTHKEY")).toBeLessThan(0); done(); }); }); diff --git a/web/client/libs/ajax.js b/web/client/libs/ajax.js index c4e1bbaebe..16aa413b85 100644 --- a/web/client/libs/ajax.js +++ b/web/client/libs/ajax.js @@ -20,6 +20,8 @@ const urlUtil = require('url'); function addParameterToAxiosConfig(axiosConfig, parameterName, parameterValue) { // FIXME: the parameters can also be a URLSearchParams axiosConfig.params = assign({}, axiosConfig.params, {[parameterName]: parameterValue}); + // remove from URL auth parameters if any, to avoid possible duplication + axiosConfig.url = axiosConfig.url ? ConfigUtils.getUrlWithoutParameters(axiosConfig.url, [parameterName]) : axiosConfig.url; } /** diff --git a/web/client/observables/wms.js b/web/client/observables/wms.js index 2d5e78d08b..3b3c0c52ad 100644 --- a/web/client/observables/wms.js +++ b/web/client/observables/wms.js @@ -9,6 +9,7 @@ const {Observable} = require('rxjs'); const axios = require('../libs/ajax'); const WMS = require('../api/WMS'); const LayersUtils = require('../utils/LayersUtils'); +const SecurityUtils = require('../utils/SecurityUtils'); const urlUtil = require('url'); const {interceptOGCError} = require('../utils/ObservableUtils'); const toDescribeLayerURL = ({name, search = {}, url} = {}) => { @@ -39,9 +40,10 @@ module.exports = { .map( ({data = {}}) => data && data.layerDescriptions[0]) .map(({owsURL} = {}) => ({ ...l, + params: {}, // TODO: if needed, clean them up search: owsURL ? { type: "wfs", - url: owsURL // TODO maybe we should we clean URL from authkey params + url: SecurityUtils.cleanAuthParamsFromURL(owsURL) } : undefined })) }; diff --git a/web/client/utils/SecurityUtils.js b/web/client/utils/SecurityUtils.js index e15a772bfc..00d64f01b8 100644 --- a/web/client/utils/SecurityUtils.js +++ b/web/client/utils/SecurityUtils.js @@ -17,7 +17,7 @@ const {head, isNil} = require('lodash'); const SecurityUtils = { /** - * Stores the logged user secuirty information. + * Stores the logged user security information. */ setStore: function(store) { this.store = store; @@ -65,7 +65,7 @@ const SecurityUtils = { /** * Return the user attributes as an array. If the user is undefined or - * doens't have any attributes an empty array is returned. + * doesn't have any attributes an empty array is returned. */ getUserAttributes: function(providedUser) { const user = providedUser ? providedUser : this.getUser(); @@ -79,7 +79,7 @@ const SecurityUtils = { }, /** - * Search in the user attributes an attribute that matchs the provided + * Search in the user attributes an attribute that matches the provided * attribute name. The search will not be case sensitive. Undefined is * returned if the attribute could not be found. */ @@ -95,7 +95,7 @@ const SecurityUtils = { }, /** - * Search in the user attributes an attribute that matchs the provided + * Search in the user attributes an attribute that matches the provided * attribute name. The search will not be case sensitive. Undefined is * returned if the attribute could not be found otherwise the attribute * value is returned. @@ -122,8 +122,8 @@ const SecurityUtils = { /** * Returns the authentication method that should be used for the provided URL. - * We go through the authentication rules and find the first one that matchs - * the provided URL, if no rule matchs the provided URL undefined is returned. + * We go through the authentication rules and find the first one that matches + * the provided URL, if no rule matches the provided URL undefined is returned. */ getAuthenticationMethod: function(url) { const foundRule = head(this.getAuthenticationRules().filter( @@ -133,8 +133,8 @@ const SecurityUtils = { /** * Returns the authentication rule that should be used for the provided URL. - * We go through the authentication rules and find the first one that matchs - * the provided URL, if no rule matchs the provided URL undefined is returned. + * We go through the authentication rules and find the first one that matches + * the provided URL, if no rule matches the provided URL undefined is returned. */ getAuthenticationRule: function(url) { return head(this.getAuthenticationRules().filter( @@ -157,7 +157,7 @@ const SecurityUtils = { /** * This method will add query parameter based authentications to an object - * containing query paramaters. + * containing query parameters. */ addAuthenticationParameter: function(url, parameters, securityToken) { if (!url || !this.isAuthenticationActivated()) { @@ -172,7 +172,7 @@ const SecurityUtils = { const authParam = this.getAuthKeyParameter(url); return assign(parameters || {}, {[authParam]: token}); default: - // we cannot handle the required authentication method + // we cannot handle the required authentication method return parameters; } }, @@ -180,7 +180,9 @@ const SecurityUtils = { const foundRule = head(this.getAuthenticationRules().filter( rule => rule && rule.urlPattern && url.match(new RegExp(rule.urlPattern, "i")))); return foundRule && foundRule.authkeyParamName ? foundRule.authkeyParamName : 'authkey'; - } + }, + cleanAuthParamsFromURL: (url) => ConfigUtils.filterUrlParams(url, [SecurityUtils.getAuthKeyParameter(url)].filter(p => p)) + }; module.exports = SecurityUtils; diff --git a/web/client/utils/__tests__/SecurityUtils-test.js b/web/client/utils/__tests__/SecurityUtils-test.js index 2f3ba87955..949e7ecf2d 100644 --- a/web/client/utils/__tests__/SecurityUtils-test.js +++ b/web/client/utils/__tests__/SecurityUtils-test.js @@ -200,4 +200,11 @@ describe('Test security utils methods', () => { expect.spyOn(SecurityUtils, 'isAuthenticationActivated').andReturn(true); expect(SecurityUtils.addAuthenticationParameter("a test url", null)).toEqual({'authkey': 'goodtoken'}); }); + it('cleanAuthParamsFromURL', () => { + // mocking the authentication rules + expect.spyOn(SecurityUtils, 'isAuthenticationActivated').andReturn(true); + expect.spyOn(SecurityUtils, 'getAuthenticationRules').andReturn(authenticationRules); + expect.spyOn(SecurityUtils, 'getSecurityInfo').andReturn(securityInfoC); + expect(SecurityUtils.cleanAuthParamsFromURL('http://www.some-site.com/geoserver?parameter1=value1¶meter2=value2&authkey=SOME_AUTH_KEY').indexOf('authkey')).toBe(-1); + }); });