]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-22823 Improve Consent modal for GitHub and GitLab
authorguillaume-peoch-sonarsource <guillaume.peoch@sonarsource.com>
Wed, 25 Sep 2024 15:53:03 +0000 (17:53 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 26 Sep 2024 20:03:14 +0000 (20:03 +0000)
server/sonar-web/src/main/js/apps/settings/components/authentication/AutoProvisionningConsent.tsx
server/sonar-web/src/main/js/apps/settings/components/authentication/__tests__/Authentication-Github-it.tsx
server/sonar-web/src/main/js/apps/settings/components/authentication/__tests__/Authentication-Gitlab-it.tsx
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index 85281797e08e11acf1fe6e3b5e6b4ec383b331b7..e20089279b1fce2010a5888e4d144545b01238d3 100644 (file)
@@ -18,8 +18,8 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-import { Button } from '@sonarsource/echoes-react';
-import { Modal } from 'design-system';
+import { Button, ButtonVariety, RadioButtonGroup } from '@sonarsource/echoes-react';
+import { FormField, Modal } from 'design-system';
 import { noop } from 'lodash';
 import * as React from 'react';
 import { FormattedMessage, useIntl } from 'react-intl';
@@ -32,7 +32,6 @@ import { GitHubConfigurationResponse } from '../../../../types/dop-translation';
 import { GitlabConfiguration, ProvisioningType } from '../../../../types/provisioning';
 
 const CONSENT_SETTING_KEY = 'sonar.auth.gitlab.userConsentForPermissionProvisioningRequired';
-
 interface Props {
   githubConfiguration?: GitHubConfigurationResponse;
   gitlabConfiguration?: GitlabConfiguration;
@@ -42,6 +41,10 @@ export default function AutoProvisioningConsent(props: Readonly<Props>) {
   const { formatMessage } = useIntl();
   const { githubConfiguration, gitlabConfiguration } = props;
 
+  const [provisioningMethod, setProvisioningMethod] = React.useState<ProvisioningType>(
+    ProvisioningType.auto,
+  );
+
   const { mutate: updateGithubConfig } = useUpdateGitHubConfigurationMutation();
   const { mutate: updateGitlabConfig } = useUpdateGitLabConfigurationMutation();
   const { data: userConsent } = useGetValueQuery({ key: CONSENT_SETTING_KEY });
@@ -55,11 +58,17 @@ export default function AutoProvisioningConsent(props: Readonly<Props>) {
     return null;
   }
 
-  const header = formatMessage({
-    id: 'settings.authentication.confirm_auto_provisioning.header',
-  });
+  const onSubmit = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
+    event.preventDefault();
+    if (provisioningMethod === ProvisioningType.auto) {
+      confirmAutoProvisioning();
+    }
+    if (provisioningMethod === ProvisioningType.jit) {
+      confirmJitProvisioning();
+    }
+  };
 
-  const onClickAutoProvisioning = async () => {
+  const confirmAutoProvisioning = async () => {
     if (githubConfiguration) {
       updateGithubConfig({
         id: githubConfiguration.id,
@@ -79,7 +88,7 @@ export default function AutoProvisioningConsent(props: Readonly<Props>) {
     }
   };
 
-  const onClickJitProvisioning = () => {
+  const confirmJitProvisioning = () => {
     if (githubConfiguration) {
       updateGithubConfig({
         id: githubConfiguration.id,
@@ -101,45 +110,77 @@ export default function AutoProvisioningConsent(props: Readonly<Props>) {
   };
 
   return (
-    <Modal onClose={noop} closeOnOverlayClick={false} isLarge>
-      <Modal.Header title={header} />
+    <Modal onClose={noop} closeOnOverlayClick={false}>
+      <Modal.Header
+        title={formatMessage({
+          id: 'settings.authentication.confirm_auto_provisioning.header',
+        })}
+      />
       <Modal.Body>
         <FormattedMessage
           tagName="p"
           id="settings.authentication.confirm_auto_provisioning.description1"
         />
-        <FormattedMessage
-          id="settings.authentication.confirm_auto_provisioning.description2"
-          tagName="p"
-          values={{
-            alm: githubConfiguration
-              ? formatMessage({ id: 'alm.github' })
-              : formatMessage({ id: 'alm.gitlab' }),
-            documentation: (
-              <DocumentationLink
-                to={githubConfiguration ? DocLink.AlmGitHubAuth : DocLink.AlmGitLabAuth}
-              >
-                <FormattedMessage id="documentation" />
-              </DocumentationLink>
-            ),
-          }}
-        />
-        <FormattedMessage
-          tagName="p"
-          id="settings.authentication.confirm_auto_provisioning.question"
-        />
+        <div className="sw-mt-3">
+          <FormattedMessage
+            id="settings.authentication.confirm_auto_provisioning.description2"
+            tagName="p"
+            values={{
+              documentation: (
+                <DocumentationLink
+                  to={githubConfiguration ? DocLink.AlmGitHubAuth : DocLink.AlmGitLabAuth}
+                >
+                  <FormattedMessage id="documentation" />
+                </DocumentationLink>
+              ),
+            }}
+          />
+        </div>
+
+        <div className="sw-mt-12">
+          <FormField
+            label={formatMessage({
+              id: 'settings.authentication.confirm_auto_provisioning.question',
+            })}
+            htmlFor="consent-provisioning-method"
+            required
+          >
+            <RadioButtonGroup
+              id="consent-provisioning-method"
+              isRequired
+              options={[
+                {
+                  helpText: formatMessage({
+                    id: 'settings.authentication.confirm_auto_provisioning.auto.help',
+                  }),
+                  label: formatMessage({
+                    id: 'settings.authentication.confirm_auto_provisioning.auto.label',
+                  }),
+                  value: ProvisioningType.auto,
+                },
+                {
+                  helpText: formatMessage({
+                    id: 'settings.authentication.confirm_auto_provisioning.jit.help',
+                  }),
+                  label: formatMessage({
+                    id: 'settings.authentication.confirm_auto_provisioning.jit.label',
+                  }),
+                  value: ProvisioningType.jit,
+                },
+              ]}
+              value={provisioningMethod}
+              onChange={(method: ProvisioningType) => setProvisioningMethod(method)}
+            />
+          </FormField>
+        </div>
       </Modal.Body>
       <Modal.Footer
         primaryButton={
-          <Button onClick={onClickAutoProvisioning}>
-            <FormattedMessage id="settings.authentication.confirm_auto_provisioning.continue" />
-          </Button>
-        }
-        secondaryButton={
-          <Button onClick={onClickJitProvisioning}>
-            <FormattedMessage id="settings.authentication.confirm_auto_provisioning.switch_jit" />
+          <Button onClick={onSubmit} variety={ButtonVariety.Primary}>
+            <FormattedMessage id="settings.authentication.confirm_auto_provisioning.confirm_choice" />
           </Button>
         }
+        secondaryButton={null}
       />
     </Modal>
   );
index 13a0f954738fdc36fb070b8c38e8650a0f693a77..2fcd562ce05163d945845defdb397c51898d3ce0 100644 (file)
@@ -199,11 +199,14 @@ const ui = {
   configDetailsDialog: byRole('dialog', {
     name: 'settings.authentication.github.configuration.validation.details.title',
   }),
-  continueAutoButton: byRole('button', {
-    name: 'settings.authentication.confirm_auto_provisioning.continue',
+  autoRadioButton: byRole('radio', {
+    name: 'settings.authentication.confirm_auto_provisioning.auto.label',
   }),
-  switchJitButton: byRole('button', {
-    name: 'settings.authentication.confirm_auto_provisioning.switch_jit',
+  jitRadioButton: byRole('radio', {
+    name: 'settings.authentication.confirm_auto_provisioning.jit.label',
+  }),
+  confirmChoiceButton: byRole('button', {
+    name: 'settings.authentication.confirm_auto_provisioning.confirm_choice',
   }),
   consentDialog: byRole('dialog', {
     name: 'settings.authentication.confirm_auto_provisioning.header',
@@ -744,7 +747,8 @@ describe('Github tab', () => {
       await user.click(await ui.tab.find());
 
       expect(await ui.consentDialog.find()).toBeInTheDocument();
-      await user.click(ui.continueAutoButton.get());
+      await user.click(ui.autoRadioButton.get());
+      await user.click(ui.confirmChoiceButton.get());
 
       expect(await ui.githubProvisioningButton.find()).toBeChecked();
       expect(ui.consentDialog.query()).not.toBeInTheDocument();
@@ -761,7 +765,8 @@ describe('Github tab', () => {
       await user.click(await ui.tab.find());
 
       expect(await ui.consentDialog.find()).toBeInTheDocument();
-      await user.click(ui.switchJitButton.get());
+      await user.click(ui.jitRadioButton.get());
+      await user.click(ui.confirmChoiceButton.get());
 
       expect(await ui.jitProvisioningButton.find()).toBeChecked();
       expect(ui.consentDialog.query()).not.toBeInTheDocument();
index cab2d22afa38d518673c896bd10e1fe40a62afe7..4a68f12ff1666bc80b87465279606574d0690265 100644 (file)
@@ -150,11 +150,14 @@ const ui = {
   testConfiguration: glContainer.byRole('button', {
     name: 'settings.authentication.configuration.test',
   }),
-  continueAutoButton: byRole('button', {
-    name: 'settings.authentication.confirm_auto_provisioning.continue',
+  autoRadioButton: byRole('radio', {
+    name: 'settings.authentication.confirm_auto_provisioning.auto.label',
   }),
-  switchJitButton: byRole('button', {
-    name: 'settings.authentication.confirm_auto_provisioning.switch_jit',
+  jitRadioButton: byRole('radio', {
+    name: 'settings.authentication.confirm_auto_provisioning.jit.label',
+  }),
+  confirmChoiceButton: byRole('button', {
+    name: 'settings.authentication.confirm_auto_provisioning.confirm_choice',
   }),
   consentDialog: byRole('dialog', {
     name: 'settings.authentication.confirm_auto_provisioning.header',
@@ -639,7 +642,8 @@ describe('Gitlab Provisioning', () => {
     renderAuthentication([Feature.GitlabProvisioning]);
 
     expect(await ui.consentDialog.find()).toBeInTheDocument();
-    await user.click(ui.continueAutoButton.get());
+    await user.click(ui.autoRadioButton.get());
+    await user.click(ui.confirmChoiceButton.get());
 
     expect(await ui.autoProvisioningRadioButton.find()).toBeChecked();
     expect(ui.consentDialog.query()).not.toBeInTheDocument();
@@ -661,7 +665,8 @@ describe('Gitlab Provisioning', () => {
     renderAuthentication([Feature.GitlabProvisioning]);
 
     expect(await ui.consentDialog.find()).toBeInTheDocument();
-    await user.click(ui.switchJitButton.get());
+    await user.click(ui.jitRadioButton.get());
+    await user.click(ui.confirmChoiceButton.get());
 
     expect(await ui.jitProvisioningRadioButton.find()).toBeChecked();
     expect(ui.consentDialog.query()).not.toBeInTheDocument();
index 22a83bac09c904aca004869919f2ad004f2a57f5..20e9b40febf00f6efdb01e8d96ce12b298bb5b64 100644 (file)
@@ -1607,12 +1607,15 @@ settings.authentication.form.provisioning=Provisioning
 settings.authentication.form.provisioning_at_login=Just-in-Time user and group provisioning (default)
 settings.authentication.form.other_provisioning_enabled=Already enabled for another provider.  Only one identity provider can have automatic users and groups provisioning enabled.
 settings.authentication.form.settings.save_success=Settings saved successfully.
-settings.authentication.confirm_auto_provisioning.header=Confirm the provisioning method
-settings.authentication.confirm_auto_provisioning.description1=Automatic user and group provisioning is currently suspended.
-settings.authentication.confirm_auto_provisioning.description2=This provisioning method has been enhanced. It now includes the synchronization of user permissions and project visibility from {alm}. For more details, please refer to the {documentation}.
-settings.authentication.confirm_auto_provisioning.question=Which provisioning method would you like to use?
-settings.authentication.confirm_auto_provisioning.continue=Automatic user, group, and permission provisioning
-settings.authentication.confirm_auto_provisioning.switch_jit=Just-in-Time user and group provisioning
+settings.authentication.confirm_auto_provisioning.header=Automatic provisioning has been enhanced
+settings.authentication.confirm_auto_provisioning.description1=Your current version of automatic provisioning has been suspended and you must confirm a provisioning method.
+settings.authentication.confirm_auto_provisioning.description2=Automatic provisioning has now been enhanced with the 10.7 release. For more details, read our {documentation}.
+settings.authentication.confirm_auto_provisioning.question=Select your provisioning method
+settings.authentication.confirm_auto_provisioning.confirm_choice=Confirm choice
+settings.authentication.confirm_auto_provisioning.auto.label=Enhanced automatic provisioning (recommended)
+settings.authentication.confirm_auto_provisioning.auto.help=Now synchronizes users, groups, permissions and project visibility
+settings.authentication.confirm_auto_provisioning.jit.label=Just-in-Time provisioning
+settings.authentication.confirm_auto_provisioning.jit.help=Synchronises users and groups only
 
 # GITHUB
 settings.authentication.github.form.create=New GitHub Configuration