From f87b5668f3639a6fd9a2b26b1369989a55c2a810 Mon Sep 17 00:00:00 2001 From: guillaume-peoch-sonarsource Date: Fri, 2 Feb 2024 12:32:07 +0100 Subject: SONAR-21508 SONAR-21483 Fix SSF-530 and Fix SSF-548 --- .../main/js/api/mocks/AuthenticationServiceMock.ts | 5 + .../components/CategoryDefinitionsList.tsx | 58 ++++++++---- .../authentication/__tests__/Authentication-it.tsx | 103 ++++++++++++++++++++- 3 files changed, 149 insertions(+), 17 deletions(-) (limited to 'server') diff --git a/server/sonar-web/src/main/js/api/mocks/AuthenticationServiceMock.ts b/server/sonar-web/src/main/js/api/mocks/AuthenticationServiceMock.ts index 45f584f34ec..7b5837dad9b 100644 --- a/server/sonar-web/src/main/js/api/mocks/AuthenticationServiceMock.ts +++ b/server/sonar-web/src/main/js/api/mocks/AuthenticationServiceMock.ts @@ -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() { diff --git a/server/sonar-web/src/main/js/apps/settings/components/CategoryDefinitionsList.tsx b/server/sonar-web/src/main/js/apps/settings/components/CategoryDefinitionsList.tsx index 23c644f6265..974cb95f07b 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/CategoryDefinitionsList.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/CategoryDefinitionsList.tsx @@ -42,12 +42,12 @@ interface Props { interface State { settings: SettingDefinitionAndValue[]; - displayGithubOrganizationWarning: boolean; + displaySecurityWarning: boolean; } export default class CategoryDefinitionsList extends React.PureComponent { 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 { + 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 - {displayGithubOrganizationWarning && ( + {displaySecurityWarning && ( - {translate('settings.authentication.github.organization.warning.learn_more')} + + {translate('learn_more')} ), }} diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/__tests__/Authentication-it.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/__tests__/Authentication-it.tsx index 1678dc3a726..fbe92039271 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/__tests__/Authentication-it.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/__tests__/Authentication-it.tsx @@ -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( -- cgit v1.2.3