[v11.3.x] SSO: Fix client side validations for LDAP (#94596)

SSO: Fix client side validations for LDAP (#94561)

* fix client side validations for LDAP

* add translations for new messages

* simplify code in isInvalidField()

(cherry picked from commit 0bd3ad1d5a)

Co-authored-by: Mihai Doarna <mihai.doarna@grafana.com>
pull/94613/head
grafana-delivery-bot[bot] 1 year ago committed by GitHub
parent c938b751cf
commit f5d29152c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 29
      public/app/features/admin/ldap/LdapSettingsPage.tsx
  2. 9
      public/locales/en-US/grafana.json
  3. 9
      public/locales/pseudo-LOCALE/grafana.json

@ -108,7 +108,7 @@ export const LdapSettingsPage = () => {
const methods = useForm<LdapPayload>({ defaultValues: emptySettings }); const methods = useForm<LdapPayload>({ defaultValues: emptySettings });
const { const {
control, control,
formState: { isDirty }, formState: { isDirty, errors },
getValues, getValues,
setValue, setValue,
handleSubmit, handleSubmit,
@ -216,7 +216,7 @@ export const LdapSettingsPage = () => {
/** /**
* Button's Actions * Button's Actions
*/ */
const submitAndEnableLdapSettings = async (payload: LdapPayload) => { const submitFormAndToggleSettings = async (payload: LdapPayload) => {
payload.settings.enabled = !payload.settings.enabled; payload.settings.enabled = !payload.settings.enabled;
await putPayload(payload); await putPayload(payload);
reportInteraction('authentication_ldap_enabled'); reportInteraction('authentication_ldap_enabled');
@ -254,6 +254,11 @@ export const LdapSettingsPage = () => {
reportInteraction('authentication_ldap_abandoned'); reportInteraction('authentication_ldap_abandoned');
}; };
const isInvalidField = (field: string) => {
const err = errors?.settings?.config?.servers?.[0];
return typeof err === 'object' && field in err;
};
const subTitle = ( const subTitle = (
<Trans i18nKey="ldap-settings-page.subtitle"> <Trans i18nKey="ldap-settings-page.subtitle">
The LDAP integration in Grafana allows your Grafana users to log in with their LDAP credentials. Find out more in The LDAP integration in Grafana allows your Grafana users to log in with their LDAP credentials. Find out more in
@ -282,7 +287,7 @@ export const LdapSettingsPage = () => {
<Page.Contents> <Page.Contents>
{config.disableLoginForm && disabledFormAlert} {config.disableLoginForm && disabledFormAlert}
<FormProvider {...methods}> <FormProvider {...methods}>
<form onSubmit={handleSubmit(submitAndEnableLdapSettings, onErrors)}> <form onSubmit={handleSubmit(submitFormAndToggleSettings, onErrors)}>
<FormPrompt confirmRedirect={isDirty} onDiscard={onDiscard} /> <FormPrompt confirmRedirect={isDirty} onDiscard={onDiscard} />
{isLoading && <Loader />} {isLoading && <Loader />}
{!isLoading && ( {!isLoading && (
@ -291,7 +296,10 @@ export const LdapSettingsPage = () => {
<Trans i18nKey="ldap-settings-page.title">Basic Settings</Trans> <Trans i18nKey="ldap-settings-page.title">Basic Settings</Trans>
</h3> </h3>
<Field <Field
label={t('ldap-settings-page.host.label', 'Server host *')} label={t('ldap-settings-page.host.label', 'Server host')}
required={true}
error={t('ldap-settings-page.host.error', 'Server host is a required field')}
invalid={isInvalidField('host')}
description={t( description={t(
'ldap-settings-page.host.description', 'ldap-settings-page.host.description',
'Hostname or IP address of the LDAP server you wish to connect to.' 'Hostname or IP address of the LDAP server you wish to connect to.'
@ -331,7 +339,10 @@ export const LdapSettingsPage = () => {
/> />
</Field> </Field>
<Field <Field
label={t('ldap-settings-page.search_filter.label', 'Search filter *')} label={t('ldap-settings-page.search_filter.label', 'Search filter')}
required={true}
invalid={isInvalidField('search_filter')}
error={t('ldap-settings-page.search_filter.error', 'Search filter is a required field')}
description={t( description={t(
'ldap-settings-page.search_filter.description', 'ldap-settings-page.search_filter.description',
'LDAP search filter used to locate specific entries within the directory.' 'LDAP search filter used to locate specific entries within the directory.'
@ -345,13 +356,17 @@ export const LdapSettingsPage = () => {
/> />
</Field> </Field>
<Field <Field
label={t('ldap-settings-page.search-base-dns.label', 'Search base DNS *')} label={t('ldap-settings-page.search-base-dns.label', 'Search base DNS')}
required={true}
invalid={isInvalidField('search_base_dns')}
error={t('ldap-settings-page.search-base-dns.error', 'Search base DNS is a required field')}
description={t( description={t(
'ldap-settings-page.search-base-dns.description', 'ldap-settings-page.search-base-dns.description',
'An array of base dns to search through.' 'An array of base dns to search through.'
)} )}
> >
<Controller <Controller
rules={{ required: true, validate: (value) => !!value?.length }}
name={`${serverConfig}.search_base_dns`} name={`${serverConfig}.search_base_dns`}
control={control} control={control}
render={({ field: { onChange, ref, ...field } }) => ( render={({ field: { onChange, ref, ...field } }) => (
@ -397,7 +412,7 @@ export const LdapSettingsPage = () => {
<Trans i18nKey="ldap-settings-page.buttons-section.disable-button">Disable</Trans> <Trans i18nKey="ldap-settings-page.buttons-section.disable-button">Disable</Trans>
</Button> </Button>
)} )}
<Button variant="secondary" onClick={saveForm}> <Button variant="secondary" onClick={handleSubmit(saveForm)}>
<Trans i18nKey="ldap-settings-page.buttons-section.save-button">Save</Trans> <Trans i18nKey="ldap-settings-page.buttons-section.save-button">Save</Trans>
</Button> </Button>
<LinkButton href="/admin/authentication" variant="secondary"> <LinkButton href="/admin/authentication" variant="secondary">

@ -1225,7 +1225,8 @@
"documentation": "documentation", "documentation": "documentation",
"host": { "host": {
"description": "Hostname or IP address of the LDAP server you wish to connect to.", "description": "Hostname or IP address of the LDAP server you wish to connect to.",
"label": "Server host *", "error": "Server host is a required field",
"label": "Server host",
"placeholder": "example: 127.0.0.1" "placeholder": "example: 127.0.0.1"
}, },
"login-form-alert": { "login-form-alert": {
@ -1234,12 +1235,14 @@
}, },
"search_filter": { "search_filter": {
"description": "LDAP search filter used to locate specific entries within the directory.", "description": "LDAP search filter used to locate specific entries within the directory.",
"label": "Search filter *", "error": "Search filter is a required field",
"label": "Search filter",
"placeholder": "example: cn=%s" "placeholder": "example: cn=%s"
}, },
"search-base-dns": { "search-base-dns": {
"description": "An array of base dns to search through.", "description": "An array of base dns to search through.",
"label": "Search base DNS *", "error": "Search base DNS is a required field",
"label": "Search base DNS",
"placeholder": "example: dc=grafana,dc=org" "placeholder": "example: dc=grafana,dc=org"
}, },
"subtitle": "The LDAP integration in Grafana allows your Grafana users to log in with their LDAP credentials. Find out more in our <2><0>documentation</0></2>.", "subtitle": "The LDAP integration in Grafana allows your Grafana users to log in with their LDAP credentials. Find out more in our <2><0>documentation</0></2>.",

@ -1225,7 +1225,8 @@
"documentation": "đőčūmęʼnŧäŧįőʼn", "documentation": "đőčūmęʼnŧäŧįőʼn",
"host": { "host": {
"description": "Ħőşŧʼnämę őř ĨP äđđřęşş őƒ ŧĥę ĿĐÅP şęřvęř yőū ŵįşĥ ŧő čőʼnʼnęčŧ ŧő.", "description": "Ħőşŧʼnämę őř ĨP äđđřęşş őƒ ŧĥę ĿĐÅP şęřvęř yőū ŵįşĥ ŧő čőʼnʼnęčŧ ŧő.",
"label": "Ŝęřvęř ĥőşŧ *", "error": "Ŝęřvęř ĥőşŧ įş ä řęqūįřęđ ƒįęľđ",
"label": "Ŝęřvęř ĥőşŧ",
"placeholder": "ęχämpľę: 127.0.0.1" "placeholder": "ęχämpľę: 127.0.0.1"
}, },
"login-form-alert": { "login-form-alert": {
@ -1234,12 +1235,14 @@
}, },
"search_filter": { "search_filter": {
"description": "ĿĐÅP şęäřčĥ ƒįľŧęř ūşęđ ŧő ľőčäŧę şpęčįƒįč ęʼnŧřįęş ŵįŧĥįʼn ŧĥę đįřęčŧőřy.", "description": "ĿĐÅP şęäřčĥ ƒįľŧęř ūşęđ ŧő ľőčäŧę şpęčįƒįč ęʼnŧřįęş ŵįŧĥįʼn ŧĥę đįřęčŧőřy.",
"label": "Ŝęäřčĥ ƒįľŧęř *", "error": "Ŝęäřčĥ ƒįľŧęř įş ä řęqūįřęđ ƒįęľđ",
"label": "Ŝęäřčĥ ƒįľŧęř",
"placeholder": "ęχämpľę: čʼn=%ş" "placeholder": "ęχämpľę: čʼn=%ş"
}, },
"search-base-dns": { "search-base-dns": {
"description": "Åʼn äřřäy őƒ þäşę đʼnş ŧő şęäřčĥ ŧĥřőūģĥ.", "description": "Åʼn äřřäy őƒ þäşę đʼnş ŧő şęäřčĥ ŧĥřőūģĥ.",
"label": "Ŝęäřčĥ þäşę ĐŃŜ *", "error": "Ŝęäřčĥ þäşę ĐŃŜ įş ä řęqūįřęđ ƒįęľđ",
"label": "Ŝęäřčĥ þäşę ĐŃŜ",
"placeholder": "ęχämpľę: đč=ģřäƒäʼnä,đč=őřģ" "placeholder": "ęχämpľę: đč=ģřäƒäʼnä,đč=őřģ"
}, },
"subtitle": "Ŧĥę ĿĐÅP įʼnŧęģřäŧįőʼn įʼn Ğřäƒäʼnä äľľőŵş yőūř Ğřäƒäʼnä ūşęřş ŧő ľőģ įʼn ŵįŧĥ ŧĥęįř ĿĐÅP čřęđęʼnŧįäľş. Fįʼnđ őūŧ mőřę įʼn őūř <2><0>đőčūmęʼnŧäŧįőʼn</0></2>.", "subtitle": "Ŧĥę ĿĐÅP įʼnŧęģřäŧįőʼn įʼn Ğřäƒäʼnä äľľőŵş yőūř Ğřäƒäʼnä ūşęřş ŧő ľőģ įʼn ŵįŧĥ ŧĥęįř ĿĐÅP čřęđęʼnŧįäľş. Fįʼnđ őūŧ mőřę įʼn őūř <2><0>đőčūmęʼnŧäŧįőʼn</0></2>.",

Loading…
Cancel
Save