From 83774f0672fe554b374128808b46c1a0abaca286 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 24 Mar 2021 16:22:53 +0100 Subject: [PATCH] SONAR-14606 Plugins require risk acknowledgment --- .../indexation/IndexationNotification.tsx | 4 +- .../src/main/js/apps/marketplace/App.tsx | 60 ++++++++- .../main/js/apps/marketplace/AppContainer.tsx | 16 +-- .../apps/marketplace/__tests__/App-test.tsx | 28 +++++ .../__tests__/AppContainer-test.tsx | 59 +++++++++ .../__tests__/__snapshots__/App-test.tsx.snap | 116 ------------------ .../components/PluginRiskConsentBox.tsx | 55 +++++++++ .../__tests__/PluginRiskConsentBox-test.tsx | 39 ++++++ .../PluginRiskConsentBox-test.tsx.snap | 100 +++++++++++++++ .../components/ApplicationCreation.tsx | 3 +- .../projects/components/EmptyInstance.tsx | 3 +- .../components/ProjectCreationMenu.tsx | 7 +- .../__tests__/EmptyInstance-test.tsx | 8 +- .../__snapshots__/EmptyInstance-test.tsx.snap | 49 +++++--- .../main/js/apps/projectsManagement/App.tsx | 3 +- .../src/main/js/types/permissions.ts | 25 ++++ server/sonar-web/src/main/js/types/plugins.ts | 6 + .../sonar-web/src/main/js/types/settings.ts | 3 +- .../resources/org/sonar/l10n/core.properties | 17 ++- 19 files changed, 443 insertions(+), 158 deletions(-) create mode 100644 server/sonar-web/src/main/js/apps/marketplace/__tests__/AppContainer-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/marketplace/__tests__/__snapshots__/App-test.tsx.snap create mode 100644 server/sonar-web/src/main/js/apps/marketplace/components/PluginRiskConsentBox.tsx create mode 100644 server/sonar-web/src/main/js/apps/marketplace/components/__tests__/PluginRiskConsentBox-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/PluginRiskConsentBox-test.tsx.snap create mode 100644 server/sonar-web/src/main/js/types/permissions.ts diff --git a/server/sonar-web/src/main/js/app/components/indexation/IndexationNotification.tsx b/server/sonar-web/src/main/js/app/components/indexation/IndexationNotification.tsx index 39a5b9b2d82..6111cb3bd0d 100644 --- a/server/sonar-web/src/main/js/app/components/indexation/IndexationNotification.tsx +++ b/server/sonar-web/src/main/js/app/components/indexation/IndexationNotification.tsx @@ -24,6 +24,7 @@ import withIndexationContext, { } from '../../../components/hoc/withIndexationContext'; import { hasGlobalPermission, isLoggedIn } from '../../../helpers/users'; import { IndexationNotificationType } from '../../../types/indexation'; +import { Permissions } from '../../../types/permissions'; import './IndexationNotification.css'; import IndexationNotificationHelper from './IndexationNotificationHelper'; import IndexationNotificationRenderer from './IndexationNotificationRenderer'; @@ -44,7 +45,8 @@ export class IndexationNotification extends React.PureComponent { super(props); this.isSystemAdmin = - isLoggedIn(this.props.currentUser) && hasGlobalPermission(this.props.currentUser, 'admin'); + isLoggedIn(this.props.currentUser) && + hasGlobalPermission(this.props.currentUser, Permissions.Admin); } componentDidMount() { diff --git a/server/sonar-web/src/main/js/apps/marketplace/App.tsx b/server/sonar-web/src/main/js/apps/marketplace/App.tsx index 9c0f15d14cc..6c837133eb2 100644 --- a/server/sonar-web/src/main/js/apps/marketplace/App.tsx +++ b/server/sonar-web/src/main/js/apps/marketplace/App.tsx @@ -20,6 +20,8 @@ import { sortBy, uniqBy } from 'lodash'; import * as React from 'react'; import { Helmet } from 'react-helmet-async'; +import { FormattedMessage } from 'react-intl'; +import { Link } from 'react-router'; import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner'; import { translate } from 'sonar-ui-common/helpers/l10n'; import { @@ -28,10 +30,13 @@ import { getInstalledPluginsWithUpdates, getPluginUpdates } from '../../api/plugins'; +import { getValues, setSimpleSettingValue } from '../../api/settings'; import Suggestions from '../../app/components/embed-docs-modal/Suggestions'; import { Location, Router, withRouter } from '../../components/hoc/withRouter'; import { EditionKey } from '../../types/editions'; -import { PendingPluginResult, Plugin } from '../../types/plugins'; +import { PendingPluginResult, Plugin, RiskConsent } from '../../types/plugins'; +import { SettingsKey } from '../../types/settings'; +import PluginRiskConsentBox from './components/PluginRiskConsentBox'; import EditionBoxes from './EditionBoxes'; import Footer from './Footer'; import Header from './Header'; @@ -53,6 +58,7 @@ interface Props { interface State { loadingPlugins: boolean; plugins: Plugin[]; + riskConsent?: RiskConsent; } export class App extends React.PureComponent { @@ -62,6 +68,7 @@ export class App extends React.PureComponent { componentDidMount() { this.mounted = true; this.fetchQueryPlugins(); + this.fetchRiskConsent(); } componentDidUpdate(prevProps: Props) { @@ -102,6 +109,27 @@ export class App extends React.PureComponent { ); }; + fetchRiskConsent = async () => { + const result = await getValues({ keys: SettingsKey.PluginRiskConsent }); + + if (!result || result.length < 1) { + return; + } + + const [consent] = result; + + this.setState({ riskConsent: consent.value as RiskConsent | undefined }); + }; + + acknowledgeRisk = async () => { + await setSimpleSettingValue({ + key: SettingsKey.PluginRiskConsent, + value: RiskConsent.Accepted + }); + + await this.fetchRiskConsent(); + }; + updateQuery = (newQuery: Partial) => { const query = serializeQuery({ ...parseQuery(this.props.location.query), ...newQuery }); this.props.router.push({ pathname: this.props.location.pathname, query }); @@ -115,7 +143,7 @@ export class App extends React.PureComponent { render() { const { currentEdition, standaloneMode, pendingPlugins } = this.props; - const { loadingPlugins, plugins } = this.state; + const { loadingPlugins, plugins, riskConsent } = this.state; const query = parseQuery(this.props.location.query); const filteredPlugins = filterPlugins(plugins, query.search); @@ -128,9 +156,33 @@ export class App extends React.PureComponent {

{translate('marketplace.page.plugins')}

- {translate('marketplace.page.plugins.description')} +

{translate('marketplace.page.plugins.description')}

+ {currentEdition !== EditionKey.community && ( +

+ + {translate('marketplace.page.plugins.description2.link')} + + ) + }} + /> +

+ )}
+ + + {