From 6ae4c2140b35dd4569a4a17a0c3f577f0895d56e Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 9 Apr 2021 11:27:07 +0200 Subject: [PATCH] SONAR-14662 New risk consent page --- .../js/app/components/PluginRiskConsent.css | 35 +++++++ .../js/app/components/PluginRiskConsent.tsx | 91 +++++++++++++++++++ .../main/js/app/components/ResetPassword.tsx | 8 +- .../__tests__/PluginRiskConsent-test.tsx | 66 ++++++++++++++ .../__tests__/ResetPassword-test.tsx | 6 +- .../PluginRiskConsent-test.tsx.snap | 57 ++++++++++++ .../src/main/js/app/utils/startReactApp.tsx | 6 ++ 7 files changed, 260 insertions(+), 9 deletions(-) create mode 100644 server/sonar-web/src/main/js/app/components/PluginRiskConsent.css create mode 100644 server/sonar-web/src/main/js/app/components/PluginRiskConsent.tsx create mode 100644 server/sonar-web/src/main/js/app/components/__tests__/PluginRiskConsent-test.tsx create mode 100644 server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/PluginRiskConsent-test.tsx.snap diff --git a/server/sonar-web/src/main/js/app/components/PluginRiskConsent.css b/server/sonar-web/src/main/js/app/components/PluginRiskConsent.css new file mode 100644 index 00000000000..7d44b2f5825 --- /dev/null +++ b/server/sonar-web/src/main/js/app/components/PluginRiskConsent.css @@ -0,0 +1,35 @@ +/* + * SonarQube + * Copyright (C) 2009-2021 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +.plugin-risk-consent-page { + padding-top: 10vh; +} + +.plugin-risk-consent-page h1 { + line-height: 1.5; + font-size: 24px; + font-weight: 300; + text-align: center; +} + +.plugin-risk-consent-content { + min-width: 500px; + width: 40%; + margin: 0 auto; +} diff --git a/server/sonar-web/src/main/js/app/components/PluginRiskConsent.tsx b/server/sonar-web/src/main/js/app/components/PluginRiskConsent.tsx new file mode 100644 index 00000000000..e251fba3900 --- /dev/null +++ b/server/sonar-web/src/main/js/app/components/PluginRiskConsent.tsx @@ -0,0 +1,91 @@ +/* + * SonarQube + * Copyright (C) 2009-2021 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import { FormattedMessage } from 'react-intl'; +import { Link } from 'react-router'; +import { Button } from 'sonar-ui-common/components/controls/buttons'; +import { translate } from 'sonar-ui-common/helpers/l10n'; +import { setSimpleSettingValue } from '../../api/settings'; +import { whenLoggedIn } from '../../components/hoc/whenLoggedIn'; +import { Router, withRouter } from '../../components/hoc/withRouter'; +import { hasGlobalPermission } from '../../helpers/users'; +import { Permissions } from '../../types/permissions'; +import { RiskConsent } from '../../types/plugins'; +import { SettingsKey } from '../../types/settings'; +import GlobalMessagesContainer from './GlobalMessagesContainer'; +import './PluginRiskConsent.css'; + +export interface PluginRiskConsentProps { + currentUser: T.LoggedInUser; + router: Router; +} + +export function PluginRiskConsent(props: PluginRiskConsentProps) { + const { router, currentUser } = props; + + if (!hasGlobalPermission(currentUser, Permissions.Admin)) { + router.replace('/'); + return null; + } + + const acknowledgeRisk = async () => { + try { + await setSimpleSettingValue({ + key: SettingsKey.PluginRiskConsent, + value: RiskConsent.Accepted + }); + + window.location.href = `/`; // force a refresh for the backend + } catch (_) { + /* Do nothing */ + } + }; + + return ( +
+ + +
+
+

{translate('plugin_risk_consent.title')}

+

{translate('plugin_risk_consent.description')}

+

{translate('plugin_risk_consent.description2')}

+

+ + {translate('plugin_risk_consent.description3.link')} + + ) + }} + /> +

+ + +
+
+
+ ); +} + +export default whenLoggedIn(withRouter(PluginRiskConsent)); diff --git a/server/sonar-web/src/main/js/app/components/ResetPassword.tsx b/server/sonar-web/src/main/js/app/components/ResetPassword.tsx index 672c3f9fc18..9a55f23a4d2 100644 --- a/server/sonar-web/src/main/js/app/components/ResetPassword.tsx +++ b/server/sonar-web/src/main/js/app/components/ResetPassword.tsx @@ -21,19 +21,17 @@ import * as React from 'react'; import { translate } from 'sonar-ui-common/helpers/l10n'; import ResetPasswordForm from '../../components/common/ResetPassword'; import { whenLoggedIn } from '../../components/hoc/whenLoggedIn'; -import { Router, withRouter } from '../../components/hoc/withRouter'; import GlobalMessagesContainer from './GlobalMessagesContainer'; import './ResetPassword.css'; export interface ResetPasswordProps { currentUser: T.LoggedInUser; - router: Router; } export function ResetPassword(props: ResetPasswordProps) { - const { router, currentUser } = props; + const { currentUser } = props; const redirect = () => { - router.replace('/'); + window.location.href = `/`; // force a refresh for the backend to handle additional redirects }; return ( @@ -50,4 +48,4 @@ export function ResetPassword(props: ResetPasswordProps) { ); } -export default whenLoggedIn(withRouter(ResetPassword)); +export default whenLoggedIn(ResetPassword); diff --git a/server/sonar-web/src/main/js/app/components/__tests__/PluginRiskConsent-test.tsx b/server/sonar-web/src/main/js/app/components/__tests__/PluginRiskConsent-test.tsx new file mode 100644 index 00000000000..5aedf55b0ac --- /dev/null +++ b/server/sonar-web/src/main/js/app/components/__tests__/PluginRiskConsent-test.tsx @@ -0,0 +1,66 @@ +/* + * SonarQube + * Copyright (C) 2009-2021 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { shallow } from 'enzyme'; +import * as React from 'react'; +import { Button } from 'sonar-ui-common/components/controls/buttons'; +import { setSimpleSettingValue } from '../../../api/settings'; +import { mockLoggedInUser, mockRouter } from '../../../helpers/testMocks'; +import { PluginRiskConsent, PluginRiskConsentProps } from '../PluginRiskConsent'; + +jest.mock('../../../api/settings', () => ({ + setSimpleSettingValue: jest.fn().mockResolvedValue({}) +})); + +it('should render correctly', () => { + expect(shallowRender()).toMatchSnapshot('default'); +}); + +it('should redirect non-admin users', () => { + const replace = jest.fn(); + const wrapper = shallowRender({ + currentUser: mockLoggedInUser(), + router: mockRouter({ replace }) + }); + expect(wrapper.type()).toBeNull(); + expect(replace).toBeCalled(); +}); + +it('should handle acknowledgement and redirect', async () => { + const wrapper = shallowRender(); + + wrapper + .find(Button) + .first() + .simulate('click'); + + await new Promise(setImmediate); + + expect(setSimpleSettingValue).toBeCalled(); +}); + +function shallowRender(props: Partial = {}) { + return shallow( + + ); +} diff --git a/server/sonar-web/src/main/js/app/components/__tests__/ResetPassword-test.tsx b/server/sonar-web/src/main/js/app/components/__tests__/ResetPassword-test.tsx index ef2a7dd7983..0f3093f3f51 100644 --- a/server/sonar-web/src/main/js/app/components/__tests__/ResetPassword-test.tsx +++ b/server/sonar-web/src/main/js/app/components/__tests__/ResetPassword-test.tsx @@ -19,7 +19,7 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import { mockLoggedInUser, mockRouter } from '../../../helpers/testMocks'; +import { mockLoggedInUser } from '../../../helpers/testMocks'; import { ResetPassword, ResetPasswordProps } from '../ResetPassword'; it('should render correctly', () => { @@ -27,7 +27,5 @@ it('should render correctly', () => { }); function shallowRender(props: Partial = {}) { - return shallow( - - ); + return shallow(); } diff --git a/server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/PluginRiskConsent-test.tsx.snap b/server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/PluginRiskConsent-test.tsx.snap new file mode 100644 index 00000000000..aecc22a2247 --- /dev/null +++ b/server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/PluginRiskConsent-test.tsx.snap @@ -0,0 +1,57 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly: default 1`] = ` +
+ +
+
+

+ plugin_risk_consent.title +

+

+ plugin_risk_consent.description +

+

+ plugin_risk_consent.description2 +

+

+ + plugin_risk_consent.description3.link + , + } + } + /> +

+ +
+
+
+`; diff --git a/server/sonar-web/src/main/js/app/utils/startReactApp.tsx b/server/sonar-web/src/main/js/app/utils/startReactApp.tsx index 65afaf311a4..6bf4a7bacbc 100644 --- a/server/sonar-web/src/main/js/app/utils/startReactApp.tsx +++ b/server/sonar-web/src/main/js/app/utils/startReactApp.tsx @@ -332,6 +332,12 @@ export default function startReactApp( import('../../apps/change-admin-password/ChangeAdminPasswordApp') )} /> + import('../components/PluginRiskConsent'))} + /> import('../components/NotFound'))} -- 2.39.5