diff options
author | Sarath Nair <91882341+sarath-nair-sonarsource@users.noreply.github.com> | 2024-03-08 12:54:05 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2024-03-08 20:02:34 +0000 |
commit | 875ad375ffd8d8323141701b7355a4f10629bb7e (patch) | |
tree | 0075771c30f882ac0bed769bc6664ed097f0a20d /server/sonar-web/src/main/js/apps | |
parent | e64df27ae07319d522cb2c486c1031674ae91b23 (diff) | |
download | sonarqube-875ad375ffd8d8323141701b7355a4f10629bb7e.tar.gz sonarqube-875ad375ffd8d8323141701b7355a4f10629bb7e.zip |
SONAR-21413 Show insecure configuration warning for GitLab (#10742)
Diffstat (limited to 'server/sonar-web/src/main/js/apps')
6 files changed, 142 insertions, 87 deletions
diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/ConfigurationForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/ConfigurationForm.tsx index 2cab4f65783..e52fdc491d1 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/ConfigurationForm.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/ConfigurationForm.tsx @@ -28,12 +28,12 @@ import { translate } from '../../../../helpers/l10n'; import { useSaveValuesMutation } from '../../../../queries/settings'; import { AlmKeys } from '../../../../types/alm-settings'; import { ProvisioningType } from '../../../../types/provisioning'; -import { Dict } from '../../../../types/types'; +import { Dict, Provider } from '../../../../types/types'; import { AuthenticationTabs, DOCUMENTATION_LINK_SUFFIXES } from './Authentication'; import AuthenticationFormField from './AuthenticationFormField'; -import GitHubConfirmModal from './GitHubConfirmModal'; import { SettingValue } from './hook/useConfiguration'; import { isAllowToSignUpEnabled, isOrganizationListEmpty } from './hook/useGithubConfiguration'; +import ConfirmProvisioningModal from './ConfirmProvisioningModal'; interface Props { canBeSave: boolean; @@ -176,11 +176,13 @@ export default function ConfigurationForm(props: Readonly<Props>) { } /> {showConfirmModal && ( - <GitHubConfirmModal + <ConfirmProvisioningModal + allowUsersToSignUp={isAllowToSignUpEnabled(values)} + isAllowListEmpty={isOrganizationListEmpty(values)} onClose={() => setShowConfirmModal(false)} onConfirm={onSave} + provider={Provider.Github} provisioningStatus={provisioningStatus ?? ProvisioningType.jit} - values={values} /> )} </> diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/ConfirmProvisioningModal.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/ConfirmProvisioningModal.tsx new file mode 100644 index 00000000000..2968b425252 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/ConfirmProvisioningModal.tsx @@ -0,0 +1,74 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 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 { FlagMessage } from 'design-system'; +import React from 'react'; +import ConfirmModal from '../../../../components/controls/ConfirmModal'; +import { ProvisioningType } from '../../../../types/provisioning'; +import { Provider } from '../../../../types/types'; +import { useIntl } from 'react-intl'; + +interface Props { + allowUsersToSignUp?: boolean; + provider: Provider.Github | Provider.Gitlab; + isAllowListEmpty: boolean; + onClose: VoidFunction; + onConfirm: VoidFunction; + hasProvisioningTypeChange?: boolean; + provisioningStatus: ProvisioningType; +} + +export default function ConfirmProvisioningModal(props: Readonly<Props>) { + const { + allowUsersToSignUp, + hasProvisioningTypeChange, + isAllowListEmpty, + onConfirm, + onClose, + provider, + provisioningStatus, + } = props; + + const intl = useIntl(); + + return ( + <ConfirmModal + onConfirm={onConfirm} + header={intl.formatMessage({ + id: `settings.authentication.${provider}.confirm.${hasProvisioningTypeChange ? provisioningStatus : 'insecure'}`, + })} + onClose={onClose} + confirmButtonText={intl.formatMessage({ + id: `settings.authentication.${provider}.provisioning_change.confirm_changes`, + })} + > + {hasProvisioningTypeChange && + intl.formatMessage({ + id: `settings.authentication.${provider}.confirm.${provisioningStatus}.description`, + })} + {(provisioningStatus === ProvisioningType.auto || allowUsersToSignUp) && isAllowListEmpty && ( + <FlagMessage className="sw-mt-2" variant="warning"> + {intl.formatMessage({ + id: `settings.authentication.${provider}.provisioning_change.insecure_config`, + })} + </FlagMessage> + )} + </ConfirmModal> + ); +} diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/GitHubConfirmModal.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/GitHubConfirmModal.tsx deleted file mode 100644 index 41a55f68e40..00000000000 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/GitHubConfirmModal.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2024 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 { FlagMessage } from 'design-system'; -import React from 'react'; -import ConfirmModal from '../../../../components/controls/ConfirmModal'; -import { translate } from '../../../../helpers/l10n'; -import { ProvisioningType } from '../../../../types/provisioning'; -import { SettingValue } from './hook/useConfiguration'; -import { isAllowToSignUpEnabled, isOrganizationListEmpty } from './hook/useGithubConfiguration'; - -interface GithubAuthenticationProps { - onConfirm: () => void; - onClose: () => void; - values: Record<string, SettingValue>; - hasGithubProvisioningTypeChange?: boolean; - provisioningStatus: ProvisioningType; -} - -export default function GitHubConfirmModal(props: Readonly<GithubAuthenticationProps>) { - const { onConfirm, onClose, hasGithubProvisioningTypeChange, provisioningStatus, values } = props; - - const organizationListIsEmpty = isOrganizationListEmpty(values); - const allowToSignUpEnabled = isAllowToSignUpEnabled(values); - - return ( - <ConfirmModal - onConfirm={onConfirm} - header={translate( - 'settings.authentication.github.confirm', - hasGithubProvisioningTypeChange ? provisioningStatus : 'insecure', - )} - onClose={onClose} - confirmButtonText={translate( - 'settings.authentication.github.provisioning_change.confirm_changes', - )} - > - {hasGithubProvisioningTypeChange && - translate('settings.authentication.github.confirm', provisioningStatus, 'description')} - {(provisioningStatus === ProvisioningType.auto || allowToSignUpEnabled) && - organizationListIsEmpty && ( - <FlagMessage className="sw-mt-2" variant="warning"> - {translate('settings.authentication.github.provisioning_change.insecure_config')} - </FlagMessage> - )} - </ConfirmModal> - ); -} diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/GitLabAuthenticationTab.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/GitLabAuthenticationTab.tsx index e7e2b41e01e..189ec2d1ab8 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/GitLabAuthenticationTab.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/GitLabAuthenticationTab.tsx @@ -18,13 +18,12 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { Spinner } from 'design-system'; -import { omitBy } from 'lodash'; +import { isEmpty, omitBy } from 'lodash'; import React, { FormEvent, useContext } from 'react'; import { FormattedMessage } from 'react-intl'; import GitLabSynchronisationWarning from '../../../../app/components/GitLabSynchronisationWarning'; import { AvailableFeaturesContext } from '../../../../app/components/available-features/AvailableFeaturesContext'; import DocumentationLink from '../../../../components/common/DocumentationLink'; -import ConfirmModal from '../../../../components/controls/ConfirmModal'; import { translate, translateWithParameters } from '../../../../helpers/l10n'; import { useIdentityProviderQuery } from '../../../../queries/identity-provider/common'; import { @@ -45,6 +44,7 @@ import GitLabConfigurationForm from './GitLabConfigurationForm'; import GitLabConfigurationValidity from './GitLabConfigurationValidity'; import ProvisioningSection from './ProvisioningSection'; import TabHeader from './TabHeader'; +import ConfirmProvisioningModal from './ConfirmProvisioningModal'; interface ChangesForm { provisioningType?: GitLabConfigurationUpdateBody['provisioningType']; @@ -125,7 +125,10 @@ export default function GitLabAuthenticationTab() { const handleSubmit = (e: FormEvent) => { e.preventDefault(); - if (changes?.provisioningType !== undefined) { + if ( + changes?.provisioningType !== undefined || + (provisioningType === ProvisioningType.jit && allowUsersToSignUp && isEmpty(allowedGroups)) + ) { setShowConfirmProvisioningModal(true); } else { updateProvisioning(); @@ -381,16 +384,15 @@ export default function GitLabAuthenticationTab() { )} </div> {showConfirmProvisioningModal && provisioningType && ( - <ConfirmModal - onConfirm={updateProvisioning} - header={translate('settings.authentication.gitlab.confirm', provisioningType)} + <ConfirmProvisioningModal + allowUsersToSignUp={allowUsersToSignUp} + hasProvisioningTypeChange={Boolean(changes?.provisioningType)} + isAllowListEmpty={isEmpty(allowedGroups)} onClose={() => setShowConfirmProvisioningModal(false)} - confirmButtonText={translate( - 'settings.authentication.gitlab.provisioning_change.confirm_changes', - )} - > - {translate('settings.authentication.gitlab.confirm', provisioningType, 'description')} - </ConfirmModal> + onConfirm={updateProvisioning} + provider={Provider.Gitlab} + provisioningStatus={provisioningType} + /> )} {openForm && ( <GitLabConfigurationForm data={configuration ?? null} onClose={() => setOpenForm(false)} /> diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/GithubAuthenticationTab.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/GithubAuthenticationTab.tsx index d582ecd64a8..2f4937eefba 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/GithubAuthenticationTab.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/GithubAuthenticationTab.tsx @@ -38,7 +38,6 @@ import AutoProvisioningConsent from './AutoProvisionningConsent'; import ConfigurationDetails from './ConfigurationDetails'; import ConfigurationForm from './ConfigurationForm'; import GitHubConfigurationValidity from './GitHubConfigurationValidity'; -import GitHubConfirmModal from './GitHubConfirmModal'; import GitHubMappingModal from './GitHubMappingModal'; import ProvisioningSection from './ProvisioningSection'; import TabHeader from './TabHeader'; @@ -49,6 +48,7 @@ import useGithubConfiguration, { isAllowToSignUpEnabled, isOrganizationListEmpty, } from './hook/useGithubConfiguration'; +import ConfirmProvisioningModal from './ConfirmProvisioningModal'; interface GithubAuthenticationProps { definitions: ExtendedSettingDefinition[]; @@ -309,11 +309,13 @@ export default function GithubAuthenticationTab(props: GithubAuthenticationProps } /> {showConfirmProvisioningModal && ( - <GitHubConfirmModal - onConfirm={() => changeProvisioning()} + <ConfirmProvisioningModal + allowUsersToSignUp={isAllowToSignUpEnabled(values)} + hasProvisioningTypeChange={hasGithubProvisioningTypeChange} + isAllowListEmpty={isOrganizationListEmpty(values)} onClose={() => setShowConfirmProvisioningModal(false)} - values={values} - hasGithubProvisioningTypeChange={hasGithubProvisioningTypeChange} + onConfirm={changeProvisioning} + provider={Provider.Github} provisioningStatus={provisioningStatus} /> )} diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/__tests__/Authentication-Gitlab-it.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/__tests__/Authentication-Gitlab-it.tsx index 21cd232a262..0f7cbe05794 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/__tests__/Authentication-Gitlab-it.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/__tests__/Authentication-Gitlab-it.tsx @@ -117,6 +117,9 @@ const ui = { confirmJitProvisioningDialog: byRole('dialog', { name: 'settings.authentication.gitlab.confirm.JIT', }), + confirmInsecureProvisioningDialog: byRole('dialog', { + name: 'settings.authentication.gitlab.confirm.insecure', + }), confirmProvisioningChange: byRole('button', { name: 'settings.authentication.gitlab.provisioning_change.confirm_changes', }), @@ -329,10 +332,46 @@ it('should change from auto provisioning to JIT with proper validation', async ( expect(await ui.saveProvisioning.find()).toBeEnabled(); - expect(ui.jitAllowUsersToSignUpToggle.get()).toBeInTheDocument(); + await user.click(ui.jitAllowUsersToSignUpToggle.get()); + await user.click(ui.deleteGroupButton.get()); + + await user.click(ui.saveProvisioning.get()); + expect( + ui.confirmJitProvisioningDialog + .byText('settings.authentication.gitlab.provisioning_change.insecure_config') + .get(), + ).toBeInTheDocument(); + await user.click(ui.confirmProvisioningChange.get()); + expect(ui.confirmJitProvisioningDialog.query()).not.toBeInTheDocument(); + + expect(ui.jitProvisioningRadioButton.get()).toBeChecked(); + expect(await ui.saveProvisioning.find()).toBeDisabled(); +}); + +it('should show configuration warning with jit provisioning and no groups', async () => { + handler.setGitlabConfigurations([ + mockGitlabConfiguration({ + allowUsersToSignUp: false, + enabled: true, + provisioningType: ProvisioningType.jit, + allowedGroups: [], + isProvisioningTokenSet: true, + }), + ]); + const user = userEvent.setup(); + renderAuthentication([Feature.GitlabProvisioning]); + + expect(await ui.editConfigButton.find()).toBeInTheDocument(); + await user.click(ui.jitAllowUsersToSignUpToggle.get()); await user.click(ui.saveProvisioning.get()); - expect(ui.confirmJitProvisioningDialog.get()).toBeInTheDocument(); + + expect( + ui.confirmInsecureProvisioningDialog + .byText('settings.authentication.gitlab.provisioning_change.insecure_config') + .get(), + ).toBeInTheDocument(); + await user.click(ui.confirmProvisioningChange.get()); expect(ui.confirmJitProvisioningDialog.query()).not.toBeInTheDocument(); |