From: Mathieu Suen Date: Mon, 11 Sep 2023 10:05:25 +0000 (+0200) Subject: SONAR-20402 Align authentication settings card verticaly X-Git-Tag: 10.3.0.82913~437 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=6d021927d626cbe78bb2ee17bb2cc40ac5e6ee02;p=sonarqube.git SONAR-20402 Align authentication settings card verticaly --- diff --git a/server/sonar-web/src/main/js/api/mocks/SettingsServiceMock.ts b/server/sonar-web/src/main/js/api/mocks/SettingsServiceMock.ts index 2505f1661a0..1352b8dcc97 100644 --- a/server/sonar-web/src/main/js/api/mocks/SettingsServiceMock.ts +++ b/server/sonar-web/src/main/js/api/mocks/SettingsServiceMock.ts @@ -20,6 +20,7 @@ import { cloneDeep, isArray, isObject, isString } from 'lodash'; import { HousekeepingPolicy } from '../../apps/audit-logs/utils'; import { mockDefinition, mockSettingFieldDefinition } from '../../helpers/mocks/settings'; +import { isDefined } from '../../helpers/types'; import { BranchParameters } from '../../types/branch-like'; import { ExtendedSettingDefinition, @@ -101,6 +102,15 @@ export const DEFAULT_DEFINITIONS_MOCK = [ mockSettingFieldDefinition({ key: 'value', name: 'Value' }), ], }), + mockDefinition({ + category: 'authentication', + defaultValue: 'true', + key: 'sonar.auth.github.allowUsersToSignUp', + subCategory: 'github', + name: 'Compilation Constants', + description: 'Lets do it', + type: SettingType.BOOLEAN, + }), ]; export default class SettingsServiceMock { @@ -140,7 +150,17 @@ export default class SettingsServiceMock { }; handleGetValues = (data: { keys: string[]; component?: string } & BranchParameters) => { - const settings = this.#settingValues.filter((s) => data.keys.includes(s.key)); + const settings = data.keys + .map((k) => { + const def = this.#definitions.find((d) => d.key === k); + const v = this.#settingValues.find((s) => s.key === k); + if (v === undefined && def?.type === SettingType.BOOLEAN) { + return { key: k, value: def.defaultValue, inherited: true }; + } + return v; + }) + .filter(isDefined); + return this.reply(settings); }; @@ -185,7 +205,7 @@ export default class SettingsServiceMock { setting.fieldValues = []; } else if (definition.multiValues === true) { setting.values = definition.defaultValue?.split(',') ?? []; - } else { + } else if (setting) { setting.value = definition.defaultValue ?? ''; } diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/AuthenticationFormField.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/AuthenticationFormField.tsx index f4197d89ebc..1467e7a8701 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/AuthenticationFormField.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/AuthenticationFormField.tsx @@ -23,7 +23,7 @@ import ValidationInput, { } from '../../../../components/controls/ValidationInput'; import MandatoryFieldMarker from '../../../../components/ui/MandatoryFieldMarker'; import { ExtendedSettingDefinition, SettingType } from '../../../../types/settings'; -import { isSecuredDefinition } from '../../utils'; +import { getPropertyDescription, getPropertyName, isSecuredDefinition } from '../../utils'; import AuthenticationMultiValueField from './AuthenticationMultiValuesField'; import AuthenticationSecuredField from './AuthenticationSecuredField'; import AuthenticationToggleField from './AuthenticationToggleField'; @@ -40,16 +40,17 @@ interface SamlToggleFieldProps { export default function AuthenticationFormField(props: SamlToggleFieldProps) { const { mandatory = false, definition, settingValue, isNotSet, error } = props; + const name = getPropertyName(definition); + const description = getPropertyDescription(definition); + return (
{mandatory && } - {definition.description && ( -
{definition.description}
- )} + {definition.description &&
{description}
}
{definition.multiValues && ( 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 9421083b828..19e7d43ceb6 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 @@ -48,11 +48,7 @@ interface GithubAuthenticationProps { currentTab: AuthenticationTabs; } -const GITHUB_EXCLUDED_FIELD = [ - 'sonar.auth.github.enabled', - 'sonar.auth.github.groupsSync', - 'sonar.auth.github.allowUsersToSignUp', -]; +const GITHUB_EXCLUDED_FIELD = ['sonar.auth.github.enabled', 'sonar.auth.github.allowUsersToSignUp']; export default function GithubAuthenticationTab(props: GithubAuthenticationProps) { const { definitions, currentTab } = props; @@ -187,8 +183,58 @@ export default function GithubAuthenticationTab(props: GithubAuthenticationProps {enabled ? ( -
+
setNewGithubProvisioningStatus(false)} + > +

+ +

+

+ + {translate('documentation')} + + ), + }} + /> +

+ + {!(newGithubProvisioningStatus ?? githubProvisioningStatus) && ( + <> +
+ {Object.values(values).map((val) => { + if (!GITHUB_JIT_FIELDS.includes(val.key)) { + return null; + } + return ( +
+ +
+ ); + })} + + )} +
+ {hasDifferentProvider && ( -

+

{translate('settings.authentication.form.other_provisioning_enabled')}

)} @@ -213,10 +259,7 @@ export default function GithubAuthenticationTab(props: GithubAuthenticationProps

+ {githubProvisioningStatus && } -
+ +
) : ( diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/SamlAuthenticationTab.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/SamlAuthenticationTab.tsx index 0deaa73e7aa..04263974303 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/SamlAuthenticationTab.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/SamlAuthenticationTab.tsx @@ -182,8 +182,19 @@ export default function SamlAuthenticationTab(props: SamlAuthenticationProps) { {translate('settings.authentication.form.provisioning')} {samlEnabled ? ( -
+
setNewScimStatus(false)} + > +

+ {translate('settings.authentication.saml.form.provisioning_at_login.sub')} +

+
+ @@ -213,12 +221,12 @@ export default function SamlAuthenticationTab(props: SamlAuthenticationProps) { {translate('settings.authentication.form.other_provisioning_enabled')}

)} -

+

{translate( 'settings.authentication.saml.form.provisioning_with_scim.sub' )}

-

+

{translate( 'settings.authentication.saml.form.provisioning_with_scim.description' )} @@ -241,16 +249,6 @@ export default function SamlAuthenticationTab(props: SamlAuthenticationProps) { )} - setNewScimStatus(false)} - > -

- {translate('settings.authentication.saml.form.provisioning_at_login.sub')} -

-
) : ( 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 b0e2cea255a..eb65fdf02dc 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 @@ -83,12 +83,14 @@ const ui = { saml: { noSamlConfiguration: byText('settings.authentication.saml.form.not_configured'), createConfigButton: byRole('button', { name: 'settings.authentication.form.create' }), - providerName: byRole('textbox', { name: 'Provider Name' }), - providerId: byRole('textbox', { name: 'Provider ID' }), - providerCertificate: byRole('textbox', { name: 'Identity provider certificate' }), - loginUrl: byRole('textbox', { name: 'SAML login url' }), - userLoginAttribute: byRole('textbox', { name: 'SAML user login attribute' }), - userNameAttribute: byRole('textbox', { name: 'SAML user name attribute' }), + providerName: byRole('textbox', { name: 'property.sonar.auth.saml.providerName.name' }), + providerId: byRole('textbox', { name: 'property.sonar.auth.saml.providerId.name' }), + providerCertificate: byRole('textbox', { + name: 'property.sonar.auth.saml.certificate.secured.name', + }), + loginUrl: byRole('textbox', { name: 'property.sonar.auth.saml.loginUrl.name' }), + userLoginAttribute: byRole('textbox', { name: 'property.sonar.auth.saml.user.login.name' }), + userNameAttribute: byRole('textbox', { name: 'property.sonar.auth.saml.user.name.name' }), saveConfigButton: byRole('button', { name: 'settings.almintegration.form.save' }), confirmProvisioningButton: byRole('button', { name: 'yes' }), saveScim: byRole('button', { name: 'save' }), @@ -129,17 +131,16 @@ const ui = { tab: byRole('tab', { name: 'github GitHub' }), noGithubConfiguration: byText('settings.authentication.github.form.not_configured'), createConfigButton: byRole('button', { name: 'settings.authentication.form.create' }), - clientId: byRole('textbox', { name: 'Client ID' }), - clientSecret: byRole('textbox', { name: 'Client Secret' }), - githubAppId: byRole('textbox', { name: 'GitHub App ID' }), // not working - privateKey: byRole('textarea', { name: 'Private Key' }), // not working - githubApiUrl: byRole('textbox', { name: 'The API url for a GitHub instance.' }), - githubWebUrl: byRole('textbox', { name: 'The WEB url for a GitHub instance.' }), + clientId: byRole('textbox', { name: 'property.sonar.auth.github.clientId.secured.name' }), + clientSecret: byRole('textbox', { + name: 'property.sonar.auth.github.clientSecret.secured.name', + }), + githubApiUrl: byRole('textbox', { name: 'property.sonar.auth.github.apiUrl.name' }), + githubWebUrl: byRole('textbox', { name: 'property.sonar.auth.github.webUrl.name' }), allowUserToSignUp: byRole('switch', { name: 'sonar.auth.github.allowUsersToSignUp', }), - syncGroupsAsTeams: byRole('switch', { name: 'sonar.auth.github.groupsSync' }), - organizations: byRole('textbox', { name: 'Organizations' }), + organizations: byRole('textbox', { name: 'property.sonar.auth.github.organizations.name' }), saveConfigButton: byRole('button', { name: 'settings.almintegration.form.save' }), confirmProvisioningButton: byRole('button', { name: 'yes' }), saveGithubProvisioning: byRole('button', { name: 'save' }), @@ -436,7 +437,6 @@ describe('Github tab', () => { expect(github.saveGithubProvisioning.get()).toBeDisabled(); await user.click(github.allowUserToSignUp.get()); - await user.click(github.syncGroupsAsTeams.get()); expect(github.saveGithubProvisioning.get()).toBeEnabled(); await user.click(github.saveGithubProvisioning.get()); diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/hook/useGithubConfiguration.ts b/server/sonar-web/src/main/js/apps/settings/components/authentication/hook/useGithubConfiguration.ts index e8ca3a7fb62..01c24408e4b 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/authentication/hook/useGithubConfiguration.ts +++ b/server/sonar-web/src/main/js/apps/settings/components/authentication/hook/useGithubConfiguration.ts @@ -33,14 +33,12 @@ export const GITHUB_ENABLED_FIELD = 'sonar.auth.github.enabled'; export const GITHUB_APP_ID_FIELD = 'sonar.auth.github.appId'; export const GITHUB_API_URL_FIELD = 'sonar.auth.github.apiUrl'; export const GITHUB_CLIENT_ID_FIELD = 'sonar.auth.github.clientId.secured'; -export const GITHUB_JIT_FIELDS = [ - 'sonar.auth.github.allowUsersToSignUp', - 'sonar.auth.github.groupsSync', -]; +export const GITHUB_JIT_FIELDS = ['sonar.auth.github.allowUsersToSignUp']; export const OPTIONAL_FIELDS = [ GITHUB_ENABLED_FIELD, ...GITHUB_JIT_FIELDS, 'sonar.auth.github.organizations', + 'sonar.auth.github.groupsSync', ]; export interface SamlSettingValue { diff --git a/server/sonar-web/src/main/js/apps/settings/styles.css b/server/sonar-web/src/main/js/apps/settings/styles.css index a886b08c3fe..11c7821a249 100644 --- a/server/sonar-web/src/main/js/apps/settings/styles.css +++ b/server/sonar-web/src/main/js/apps/settings/styles.css @@ -248,7 +248,8 @@ } .authentication-configuration .radio-card { - width: 50%; + width: 100%; + min-height: 250px; background-color: var(--neutral50); border: 1px solid var(--neutral200); } @@ -266,10 +267,6 @@ justify-content: space-between; } -.authentication-configuration .radio-card-header { - justify-content: space-around; -} - .authentication-configuration .radio-card-body { justify-content: flex-start; } @@ -279,7 +276,6 @@ } .authentication-configuration .settings-definition-right { - display: flex; - align-items: center; - width: 50%; + align-items: end; + width: 20%; } diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 65e020d43fb..b1fa53d3b82 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -1505,7 +1505,8 @@ settings.authentication.github.form.provisioning_with_github=Automatic user, gro 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, groups and permissions 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.description.doc=For more details, see {documentation}. +settings.authentication.github.form.provisioning_at_login.description=User and group will be synchronise only when user log into Sonarqube. settings.authentication.github.form.provisioning.disabled=Your current edition does not support provisioning with GitHub. See the {documentation} for more information. settings.authentication.github.synchronize_now=Synchronize now settings.authentication.github.synchronization_in_progress=Synchronization is in progress.