From 35fcc48832ce85263446e9a4d019b091cd0221c3 Mon Sep 17 00:00:00 2001 From: Mathieu Suen Date: Tue, 24 Aug 2021 11:19:41 +0200 Subject: [PATCH] SONAR-13149 Add validation for URL in settings --- .../settings/store/__tests__/actions-test.ts | 21 ++++++++++++++ .../main/js/apps/settings/store/actions.ts | 28 ++++++++++++++++++- .../resources/org/sonar/l10n/core.properties | 1 + 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/server/sonar-web/src/main/js/apps/settings/store/__tests__/actions-test.ts b/server/sonar-web/src/main/js/apps/settings/store/__tests__/actions-test.ts index 924aa9190a1..9944b748fc9 100644 --- a/server/sonar-web/src/main/js/apps/settings/store/__tests__/actions-test.ts +++ b/server/sonar-web/src/main/js/apps/settings/store/__tests__/actions-test.ts @@ -142,4 +142,25 @@ describe('checkValue', () => { key }); }); + + it('should correctly identify URL', () => { + (getSettingsAppDefinition as jest.Mock).mockReturnValue({ + key: 'sonar.core.serverBaseURL' + }); + + (getSettingsAppChangedValue as jest.Mock).mockReturnValue('http://test'); + const key = 'sonar.core.serverBaseURL'; + expect(checkValue(key)(dispatch, jest.fn())).toBe(true); + expect(dispatch).toBeCalledWith({ + type: 'settingsPage/PASS_VALIDATION', + key + }); + + (getSettingsAppChangedValue as jest.Mock).mockReturnValue('not valid'); + expect(checkValue(key)(dispatch, jest.fn())).toBe(false); + expect(dispatch).toBeCalledWith({ + type: 'settingsPage/PASS_VALIDATION', + key + }); + }); }); diff --git a/server/sonar-web/src/main/js/apps/settings/store/actions.ts b/server/sonar-web/src/main/js/apps/settings/store/actions.ts index 6bc80bb37e6..ae7dc188a00 100644 --- a/server/sonar-web/src/main/js/apps/settings/store/actions.ts +++ b/server/sonar-web/src/main/js/apps/settings/store/actions.ts @@ -24,7 +24,7 @@ import { resetSettingValue, setSettingValue } from '../../../api/settings'; -import { translate } from '../../../helpers/l10n'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; import { parseError } from '../../../helpers/request'; import { closeAllGlobalMessages } from '../../../store/globalMessages'; import { @@ -32,6 +32,7 @@ import { getSettingsAppDefinition, Store } from '../../../store/rootReducer'; +import { SettingDefinition } from '../../../types/settings'; import { isEmptyValue } from '../utils'; import { receiveDefinitions } from './definitions'; import { @@ -43,6 +44,18 @@ import { } from './settingsPage'; import { receiveValues } from './values'; +function isURLKind(definition: SettingDefinition) { + return [ + 'sonar.core.serverBaseURL', + 'sonar.auth.github.apiUrl', + 'sonar.auth.github.webUrl', + 'sonar.auth.gitlab.url', + 'sonar.lf.gravatarServerUrl', + 'sonar.lf.logoUrl', + 'sonar.auth.saml.loginUrl' + ].includes(definition.key); +} + export function fetchSettings(component?: string) { return (dispatch: Dispatch) => { return getDefinitions(component).then(definitions => { @@ -75,11 +88,24 @@ export function checkValue(key: string) { return false; } + if (isURLKind(definition)) { + try { + // eslint-disable-next-line no-new + new URL(value); + } catch (e) { + dispatch( + failValidation(key, translateWithParameters('settings.state.url_not_valid', value)) + ); + return false; + } + } + if (definition.type === 'JSON') { try { JSON.parse(value); } catch (e) { dispatch(failValidation(key, e.message)); + return false; } } diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 6fe548ce23c..ff56b8f48bb 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -1089,6 +1089,7 @@ settings.state.saved=Saved! settings.state.validation_failed=Validation failed. {0} settings.state.value_cant_be_empty=Provide a value or use "Reset" to set the value to the default one. settings.state.value_cant_be_empty_no_default=Provide a value. +settings.state.url_not_valid={0} is not a valid URL settings._default=(default) settings.boolean.true=True settings.boolean.false=False -- 2.39.5