]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-21508 SONAR-21483 Fix SSF-530 and Fix SSF-548
authorguillaume-peoch-sonarsource <guillaume.peoch@sonarsource.com>
Fri, 2 Feb 2024 11:32:07 +0000 (12:32 +0100)
committersonartech <sonartech@sonarsource.com>
Mon, 5 Feb 2024 10:09:38 +0000 (10:09 +0000)
server/sonar-web/src/main/js/api/mocks/AuthenticationServiceMock.ts
server/sonar-web/src/main/js/apps/settings/components/CategoryDefinitionsList.tsx
server/sonar-web/src/main/js/apps/settings/components/authentication/__tests__/Authentication-it.tsx
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index 45f584f34eccc5a541bae0f8c715d243385c816d..7b5837dad9bb9b644cafd66a1b4017c8db9f687c 100644 (file)
@@ -31,6 +31,11 @@ export default class AuthenticationServiceMock {
     mockSettingValue({ key: 'sonar.auth.saml.certificate.secured' }),
     mockSettingValue({ key: 'sonar.auth.saml.enabled', value: 'false' }),
     mockSettingValue({ key: 'sonar.auth.github.enabled', value: 'true' }),
+    mockSettingValue({ key: 'sonar.auth.github.allowUsersToSignUp', value: 'true' }),
+    mockSettingValue({ key: 'sonar.auth.gitlab.enabled', value: 'true' }),
+    mockSettingValue({ key: 'sonar.auth.gitlab.allowUsersToSignUp', value: 'true' }),
+    mockSettingValue({ key: 'sonar.auth.bitbucket.enabled', value: 'true' }),
+    mockSettingValue({ key: 'sonar.auth.bitbucket.allowUsersToSignUp', value: 'true' }),
   ];
 
   constructor() {
index 23c644f6265acb49307612b5f785f3575b85bb06..974cb95f07bd7068059d2591ffabb9a4a6ee9165 100644 (file)
@@ -42,12 +42,12 @@ interface Props {
 
 interface State {
   settings: SettingDefinitionAndValue[];
-  displayGithubOrganizationWarning: boolean;
+  displaySecurityWarning: boolean;
 }
 
 export default class CategoryDefinitionsList extends React.PureComponent<Props, State> {
   mounted = false;
-  state: State = { settings: [], displayGithubOrganizationWarning: false };
+  state: State = { settings: [], displaySecurityWarning: false };
 
   componentDidMount() {
     this.mounted = true;
@@ -65,17 +65,37 @@ export default class CategoryDefinitionsList extends React.PureComponent<Props,
     this.mounted = false;
   }
 
-  shouldDisplayGithubWarning = (settings: SettingDefinitionAndValue[]) => {
+  shouldDisplaySecurityWarning = (settings: SettingDefinitionAndValue[]) => {
     const { category, subCategory } = this.props;
-    if (category !== 'authentication' || subCategory !== 'github') {
+    if (category !== 'authentication' || subCategory === 'saml') {
       return false;
     }
-    const isGithubEnabled = settings.find((s) => s.definition.key === 'sonar.auth.github.enabled');
-    const organizationsSetting = settings.find(
-      (s) => s.definition.key === 'sonar.auth.github.organizations'
+    const isEnabled = settings.find(
+      (s) => s.definition.key === `sonar.auth.${subCategory}.enabled`
     );
+    const isAllowUsersToSignUpEnabled = settings.find(
+      (s) => s.definition.key === `sonar.auth.${subCategory}.allowUsersToSignUp`
+    );
+    let organizationsSetting;
+    if (subCategory === 'github') {
+      organizationsSetting = settings.find(
+        (s) => s.definition.key === `sonar.auth.${subCategory}.organizations`
+      );
+    }
+    if (subCategory === 'bitbucket') {
+      organizationsSetting = settings.find(
+        (s) => s.definition.key === `sonar.auth.${subCategory}.workspaces`
+      );
+    }
+    if (subCategory === 'gitlab') {
+      organizationsSetting = settings.find(
+        (s) => s.definition.key === `sonar.auth.${subCategory}.allowedGroups`
+      );
+    }
+
     if (
-      isGithubEnabled?.settingValue?.value === 'true' &&
+      isEnabled?.settingValue?.value === 'true' &&
+      isAllowUsersToSignUpEnabled?.settingValue?.value === 'true' &&
       organizationsSetting?.settingValue === undefined
     ) {
       return true;
@@ -106,26 +126,32 @@ export default class CategoryDefinitionsList extends React.PureComponent<Props,
       };
     });
 
-    const displayGithubOrganizationWarning = this.shouldDisplayGithubWarning(settings);
+    const displaySecurityWarning = this.shouldDisplaySecurityWarning(settings);
 
-    this.setState({ settings, displayGithubOrganizationWarning });
+    this.setState({ settings, displaySecurityWarning });
   };
 
   render() {
     const { category, component, subCategory, displaySubCategoryTitle } = this.props;
-    const { settings, displayGithubOrganizationWarning } = this.state;
+    const { settings, displaySecurityWarning } = this.state;
 
     return (
       <>
-        {displayGithubOrganizationWarning && (
+        {displaySecurityWarning && (
           <Alert variant="error">
             <FormattedMessage
-              id="settings.authentication.github.organization.warning"
-              defaultMessage={translate('settings.authentication.github.organization.warning')}
+              id={`settings.authentication.${subCategory}.organization.warning`}
+              defaultMessage={translate(
+                `settings.authentication.${subCategory}.organization.warning`
+              )}
               values={{
                 learn_more: (
-                  <DocLink to="/instance-administration/authentication/github/#setting-your-authentication-settings-in-sonarqube">
-                    {translate('settings.authentication.github.organization.warning.learn_more')}
+                  <DocLink
+                    to={`/instance-administration/authentication/${
+                      subCategory === 'bitbucket' ? 'bitbucket-cloud' : subCategory
+                    }/#setting-your-authentication-settings-in-sonarqube`}
+                  >
+                    {translate('learn_more')}
                   </DocLink>
                 ),
               }}
index 1678dc3a726bca80f30fa400ea139f293b9f3a48..fbe92039271f4fa0cec2b0237db3ef0c30c89c0b 100644 (file)
@@ -80,7 +80,11 @@ const ui = {
   textbox1: byRole('textbox', { name: 'test1' }),
   textbox2: byRole('textbox', { name: 'test2' }),
   githubTab: byRole('tab', { name: 'github GitHub' }),
+  gitlabTab: byRole('tab', { name: 'gitlab GitLab' }),
+  bitbucketTab: byRole('tab', { name: 'bitbucket Bitbucket' }),
   githubOrganizationWarning: byText('settings.authentication.github.organization.warning'),
+  gitlabOrganizationWarning: byText('settings.authentication.gitlab.organization.warning'),
+  bitbucketOrganizationWarning: byText('settings.authentication.bitbucket.organization.warning'),
 };
 
 it('should render tabs and allow navigation', async () => {
@@ -220,11 +224,20 @@ describe('GitHub tab', () => {
         key: 'sonar.auth.github.enabled',
         category: 'authentication',
         subCategory: 'github',
-        name: '"Enabled"',
+        name: 'Enabled',
         description:
           'Enable GitHub users to login. Value is ignored if client ID and secret are not defined.',
         type: SettingType.BOOLEAN,
       }),
+      mockDefinition({
+        key: 'sonar.auth.github.allowUsersToSignUp',
+        category: 'authentication',
+        subCategory: 'github',
+        name: 'Allow users to sign-up',
+        description:
+          'Allow new users to authenticate. When set to false, only existing users will be able to authenticate to the server.',
+        type: SettingType.BOOLEAN,
+      }),
       mockDefinition({
         key: 'sonar.auth.github.organizations',
         category: 'authentication',
@@ -246,6 +259,94 @@ describe('GitHub tab', () => {
   });
 });
 
+describe('GitLab tab', () => {
+  it('should display a warning if gitlab authentication is enabled but no organizations are whitelisted', async () => {
+    const user = userEvent.setup();
+
+    const definitions = [
+      mockDefinition({
+        key: 'sonar.auth.gitlab.enabled',
+        category: 'authentication',
+        subCategory: 'gitlab',
+        name: '"Enabled"',
+        description:
+          'Enable gitlab users to login. Value is ignored if client ID and secret are not defined.',
+        type: SettingType.BOOLEAN,
+      }),
+      mockDefinition({
+        key: 'sonar.auth.gitlab.allowUsersToSignUp',
+        category: 'authentication',
+        subCategory: 'gitlab',
+        name: 'Allow users to sign-up',
+        description:
+          'Allow new users to authenticate. When set to false, only existing users will be able to authenticate to the server.',
+        type: SettingType.BOOLEAN,
+      }),
+      mockDefinition({
+        key: 'sonar.auth.gitlab.allowedGroups',
+        category: 'authentication',
+        subCategory: 'gitlab',
+        name: 'Allowed Groups',
+        description:
+          'Only members of these groups will be able to authenticate to the server. If a user is a member of any of the group listed they will be authenticated.',
+        type: SettingType.BOOLEAN,
+        fields: [],
+        multiValues: true,
+        options: [],
+      }),
+    ];
+
+    renderAuthentication(definitions);
+
+    await user.click(await ui.gitlabTab.find());
+    expect(ui.gitlabOrganizationWarning.get()).toBeInTheDocument();
+  });
+});
+
+describe('bitbucket tab', () => {
+  it('should display a warning if bitbucket authentication is enabled but no organizations are whitelisted', async () => {
+    const user = userEvent.setup();
+
+    const definitions = [
+      mockDefinition({
+        key: 'sonar.auth.bitbucket.enabled',
+        category: 'authentication',
+        subCategory: 'bitbucket',
+        name: '"Enabled"',
+        description:
+          'Enable bitbucket users to login. Value is ignored if client ID and secret are not defined.',
+        type: SettingType.BOOLEAN,
+      }),
+      mockDefinition({
+        key: 'sonar.auth.bitbucket.allowUsersToSignUp',
+        category: 'authentication',
+        subCategory: 'bitbucket',
+        name: 'Allow users to sign-up',
+        description:
+          'Allow new users to authenticate. When set to false, only existing users will be able to authenticate to the server.',
+        type: SettingType.BOOLEAN,
+      }),
+      mockDefinition({
+        key: 'sonar.auth.bitbucket.organizations',
+        category: 'authentication',
+        subCategory: 'bitbucket',
+        name: 'Organizations',
+        description:
+          'Only members of these organizations will be able to authenticate to the server. If a user is a member of any of the organizations listed they will be authenticated.',
+        type: SettingType.BOOLEAN,
+        fields: [],
+        multiValues: true,
+        options: [],
+      }),
+    ];
+
+    renderAuthentication(definitions);
+
+    await user.click(await ui.bitbucketTab.find());
+    expect(ui.bitbucketOrganizationWarning.get()).toBeInTheDocument();
+  });
+});
+
 function renderAuthentication(definitions: ExtendedSettingDefinition[], features: Feature[] = []) {
   renderComponent(
     <AvailableFeaturesContext.Provider value={features}>
index c43b1e3a9fb94ca4d49a4e925fa92eba782975bc..599e3127f23af7bcbf088b59857ab2d4a125b7db 100644 (file)
@@ -1284,7 +1284,9 @@ settings.authentication.saml.form.save_success=Saved successfully
 settings.authentication.saml.form.save_partial=Saved partially
 settings.authentication.saml.form.save_warn=Please check the error messages in the form above, saving failed for {0} field(s).
 settings.authentication.saml.tooltip.required_fields=Please provide a value for the following required field(s): {0}
-settings.authentication.github.organization.warning=GitHub authentication is activated but no allowed organization was provided. Please review your settings to make sure the integration is secure. {learn_more}.
+settings.authentication.github.organization.warning=GitHub Authentication allows users to sign up, but no list of allowed organizations was provided. This is potentially insecure. We recommend entering a list of allowed Organizations. {learn_more}.
+settings.authentication.gitlab.organization.warning=GitLab Authentication allows users to sign up, but no list of allowed groups was provided. This is potentially insecure. We recommend entering a list of allowed groups. {learn_more}.
+settings.authentication.bitbucket.organization.warning=BitBucket Authentication allows users to sign up, but no list of allowed workspaces was provided. This is potentially insecure. We recommend entering a list of allowed workspaces. {learn_more}.
 settings.authentication.github.organization.warning.learn_more=Learn more
 
 settings.pr_decoration.binding.category=DevOps Platform Integration