]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-19981 The GitHub config checker doesn't fail on suspended installation, for...
authorguillaume-peoch-sonarsource <guillaume.peoch@sonarsource.com>
Thu, 10 Aug 2023 13:39:13 +0000 (15:39 +0200)
committersonartech <sonartech@sonarsource.com>
Mon, 14 Aug 2023 20:02:57 +0000 (20:02 +0000)
server/sonar-web/src/main/js/api/mocks/AuthenticationServiceMock.ts
server/sonar-web/src/main/js/apps/settings/components/authentication/GitHubConfigurationValidity.tsx
server/sonar-web/src/main/js/apps/settings/components/authentication/__tests__/Authentication-it.tsx
server/sonar-web/src/main/js/types/provisioning.ts
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index 54510a6285ae4e0f6f0a4c54644daec2ca997886..a274646fa14c56e6b8c2a46b3df3d9e35baa4166 100644 (file)
@@ -48,6 +48,9 @@ const defaultConfigurationStatus: GitHubConfigurationStatus = {
       autoProvisioning: {
         status: GitHubProvisioningStatus.Success,
       },
+      jit: {
+        status: GitHubProvisioningStatus.Success,
+      },
     },
   ],
 };
index 06331668136a23da6773b8a54593a31f11d681be..0b9a01afb2817e90822be95719f6282637464333 100644 (file)
@@ -74,38 +74,43 @@ export default function GitHubConfigurationValidity({
     }
 
     const invalidOrgs =
-      isValidApp && isAutoProvisioning && data
+      isValidApp && data
         ? data.installations.filter(
-            (org) => org.autoProvisioning.status === GitHubProvisioningStatus.Failed
+            (org) => org[applicationField].status === GitHubProvisioningStatus.Failed
           )
         : [];
 
+    const invalidOrgsMessages = invalidOrgs.map((org) =>
+      translateWithParameters(
+        `${intlPrefix}.invalid_org`,
+        org.organization,
+        org[applicationField].errorMessage ?? ''
+      )
+    );
+
     if (isValidApp && invalidOrgs.length === 0) {
       setMessages([
         translateWithParameters(
           `${intlPrefix}.valid${data.installations.length === 1 ? '_one' : ''}`,
-          isAutoProvisioning
-            ? translate('settings.authentication.github.form.provisioning_with_github_short')
-            : translate('settings.authentication.form.provisioning_at_login_short'),
+          translate(
+            `settings.authentication.github.form.provisioning_with_github_short.${applicationField}`
+          ),
           data.installations.length === 1
             ? data.installations[0].organization
             : data.installations.length
         ),
       ]);
       setAlertVariant('success');
+    } else if (isValidApp && !isAutoProvisioning) {
+      setMessages([translate(`${intlPrefix}.valid.short`), ...invalidOrgsMessages]);
+      setAlertVariant('warning');
     } else {
       setMessages([
         translateWithParameters(
           `${intlPrefix}.invalid`,
           data?.application[applicationField].errorMessage ?? ''
         ),
-        ...invalidOrgs.map((org) =>
-          translateWithParameters(
-            `${intlPrefix}.invalid_org`,
-            org.organization,
-            org.autoProvisioning.errorMessage ?? ''
-          )
-        ),
+        ...invalidOrgsMessages,
       ]);
       setAlertVariant('error');
     }
@@ -152,16 +157,12 @@ export default function GitHubConfigurationValidity({
               {data?.installations.map((inst) => (
                 <li key={inst.organization}>
                   <ValidityIcon
-                    valid={
-                      !isAutoProvisioning ||
-                      inst.autoProvisioning.status === GitHubProvisioningStatus.Success
-                    }
+                    valid={inst[applicationField].status === GitHubProvisioningStatus.Success}
                   />
                   <span className="sw-ml-2">{inst.organization}</span>
-                  {isAutoProvisioning &&
-                    inst.autoProvisioning.status === GitHubProvisioningStatus.Failed && (
-                      <span> - {inst.autoProvisioning.errorMessage}</span>
-                    )}
+                  {inst[applicationField].status === GitHubProvisioningStatus.Failed && (
+                    <span> - {inst[applicationField].errorMessage}</span>
+                  )}
                 </li>
               ))}
               {failedOrgs.map((fo) => (
index 0b21b2eb99a8ff31b70e9d475c7d489c477da2b7..d5a119ebbc1064c62d6ed56b742f6fb2f76c867f 100644 (file)
@@ -172,6 +172,9 @@ const ui = {
     configurationValidityError: byRole('status', {
       name: /github.configuration.validation.invalid/,
     }),
+    configurationValidityWarning: byRole('status', {
+      name: /github.configuration.validation.valid.short/,
+    }),
     checkConfigButton: byRole('button', {
       name: 'settings.authentication.github.configuration.validation.test',
     }),
@@ -529,8 +532,16 @@ describe('Github tab', () => {
     it('should display that config is valid for both provisioning with multiple orgs', async () => {
       handler.setConfigurationValidity({
         installations: [
-          { organization: 'org1', autoProvisioning: { status: GitHubProvisioningStatus.Success } },
-          { organization: 'org2', autoProvisioning: { status: GitHubProvisioningStatus.Success } },
+          {
+            organization: 'org1',
+            autoProvisioning: { status: GitHubProvisioningStatus.Success },
+            jit: { status: GitHubProvisioningStatus.Success },
+          },
+          {
+            organization: 'org2',
+            autoProvisioning: { status: GitHubProvisioningStatus.Success },
+            jit: { status: GitHubProvisioningStatus.Success },
+          },
         ],
       });
       renderAuthentication([Feature.GithubProvisioning]);
@@ -551,10 +562,55 @@ describe('Github tab', () => {
       );
     });
 
-    it('should display that config is valid but some organizatios were not found', async () => {
+    it('should display that config is invalid for autoprovisioning if some apps are suspended but valid for jit', async () => {
+      const errorMessage = 'Installation suspended';
+      handler.setConfigurationValidity({
+        installations: [
+          {
+            organization: 'org1',
+            autoProvisioning: {
+              status: GitHubProvisioningStatus.Failed,
+              errorMessage,
+            },
+            jit: {
+              status: GitHubProvisioningStatus.Failed,
+              errorMessage,
+            },
+          },
+        ],
+      });
+
+      renderAuthentication([Feature.GithubProvisioning]);
+      await github.enableConfiguration(user);
+
+      await waitFor(() => expect(github.configurationValidityWarning.get()).toBeInTheDocument());
+      expect(github.configurationValidityWarning.get()).toHaveTextContent(errorMessage);
+
+      await act(() => user.click(github.viewConfigValidityDetailsButton.get()));
+      expect(github.getConfigDetailsTitle()).toHaveTextContent(
+        'settings.authentication.github.configuration.validation.details.valid_label'
+      );
+      expect(github.getOrgs()[0]).toHaveTextContent(
+        'settings.authentication.github.configuration.validation.details.invalid_labelorg1 - Installation suspended'
+      );
+
+      await act(() =>
+        user.click(within(github.configDetailsDialog.get()).getByRole('button', { name: 'close' }))
+      );
+
+      await user.click(github.githubProvisioningButton.get());
+      await waitFor(() => expect(github.configurationValidityError.get()).toBeInTheDocument());
+      expect(github.configurationValidityError.get()).toHaveTextContent(errorMessage);
+    });
+
+    it('should display that config is valid but some organizations were not found', async () => {
       handler.setConfigurationValidity({
         installations: [
-          { organization: 'org1', autoProvisioning: { status: GitHubProvisioningStatus.Success } },
+          {
+            organization: 'org1',
+            autoProvisioning: { status: GitHubProvisioningStatus.Success },
+            jit: { status: GitHubProvisioningStatus.Success },
+          },
         ],
       });
 
@@ -645,9 +701,14 @@ describe('Github tab', () => {
       const errorMessage = 'Test error';
       handler.setConfigurationValidity({
         installations: [
-          { organization: 'org1', autoProvisioning: { status: GitHubProvisioningStatus.Success } },
+          {
+            organization: 'org1',
+            autoProvisioning: { status: GitHubProvisioningStatus.Success },
+            jit: { status: GitHubProvisioningStatus.Success },
+          },
           {
             organization: 'org2',
+            jit: { status: GitHubProvisioningStatus.Failed, errorMessage },
             autoProvisioning: { status: GitHubProvisioningStatus.Failed, errorMessage },
           },
         ],
@@ -663,7 +724,7 @@ describe('Github tab', () => {
         'settings.authentication.github.configuration.validation.details.valid_labelorg1'
       );
       expect(github.getOrgs()[1]).toHaveTextContent(
-        'settings.authentication.github.configuration.validation.details.valid_labelorg2'
+        'settings.authentication.github.configuration.validation.details.invalid_labelorg2 - Test error'
       );
 
       await act(() =>
index a94b6f84a210a36a2bbb72aa0388f24201258306..521fdb8de442d07bc9955344b02204e8a2abf651 100644 (file)
@@ -70,6 +70,7 @@ export interface GitHubConfigurationStatus {
   };
   installations: {
     organization: string;
+    jit: GitHubProvisioning;
     autoProvisioning: GitHubProvisioning;
   }[];
 }
index 2fcfc18f68066892b8ce2208fe39134312c2dc67..a2cea2039c3deaafb59fc511fb1cdab255d1a877 100644 (file)
@@ -1399,7 +1399,6 @@ settings.authentication.form.enable=Enable configuration
 settings.authentication.form.disable=Disable configuration
 settings.authentication.form.provisioning=Provisioning
 settings.authentication.form.provisioning_at_login=Just-in-Time user and group provisioning (default)
-settings.authentication.form.provisioning_at_login_short=Just-in-Time provisioning
 settings.authentication.form.other_provisioning_enabled=Already enabled for another provider.  Only one identity provider can have automatic users and groups provisioning enabled.
 
 # GITHUB
@@ -1415,7 +1414,8 @@ settings.authentication.github.form.not_configured=GitHub App is not configured
 settings.authentication.github.form.legacy_configured=Compatibility with GitHub OAuth App is deprecated and will be removed in a future release. Your configuration will continue to work but with limited support. We recommend using GitHub Apps. Check out the {documentation} for more information.
 settings.authentication.github.enable_first=Enable your GitHub configuration for more provisioning options.
 settings.authentication.github.form.provisioning_with_github=Automatic user and group provisioning
-settings.authentication.github.form.provisioning_with_github_short=Automatic provisioning
+settings.authentication.github.form.provisioning_with_github_short.autoProvisioning=Automatic provisioning
+settings.authentication.github.form.provisioning_with_github_short.jit=Just-in-Time provisioning
 settings.authentication.github.form.provisioning_with_github.description=Users and groups are automatically provisioned from your GitHub organizations. Once activated, users and groups can only be created and modified from your GitHub organizations/teams. Existing local users will be kept and can only be deactivated.
 settings.authentication.github.form.provisioning_with_github.description.doc=For more details, see {documentation}.
 settings.authentication.github.form.provisioning.disabled=Your current edition does not support provisioning with GitHub. See the {documentation} for more information.
@@ -1430,6 +1430,7 @@ settings.authentication.github.synchronization_failed_link=More details
 settings.authentication.github.configuration.validation.details=View details
 settings.authentication.github.configuration.validation.test=Test configuration
 settings.authentication.github.configuration.validation.loading=Checking the configuration
+settings.authentication.github.configuration.validation.valid.short=Configuration is valid.
 settings.authentication.github.configuration.validation.valid=Configuration is valid for {0}. {1} organizations will be synced.
 settings.authentication.github.configuration.validation.valid_one=Configuration is valid for {0}. Organization '{1}' will be synced.
 settings.authentication.github.configuration.validation.invalid=Configuration is invalid. {0}