2024-08-20 10:31:13 -05:00
|
|
|
import { css } from '@emotion/css';
|
|
|
|
import { useEffect, useState } from 'react';
|
2024-09-17 10:52:53 -05:00
|
|
|
import { Controller, FormProvider, useForm } from 'react-hook-form';
|
2024-08-20 10:31:13 -05:00
|
|
|
import { connect } from 'react-redux';
|
|
|
|
|
|
|
|
import { AppEvents, GrafanaTheme2, NavModelItem } from '@grafana/data';
|
2024-10-02 04:42:23 -05:00
|
|
|
import { getBackendSrv, getAppEvents, locationService, reportInteraction } from '@grafana/runtime';
|
2024-09-10 10:06:40 -05:00
|
|
|
import {
|
|
|
|
useStyles2,
|
|
|
|
Alert,
|
|
|
|
Box,
|
|
|
|
Button,
|
|
|
|
Field,
|
|
|
|
IconButton,
|
|
|
|
Input,
|
|
|
|
LinkButton,
|
|
|
|
Menu,
|
|
|
|
Stack,
|
|
|
|
Text,
|
|
|
|
TextLink,
|
|
|
|
Dropdown,
|
2024-09-17 10:52:53 -05:00
|
|
|
MultiSelect,
|
2024-10-08 04:54:16 -05:00
|
|
|
SecretInput,
|
2024-09-10 10:06:40 -05:00
|
|
|
} from '@grafana/ui';
|
2024-09-25 08:59:57 -05:00
|
|
|
import { FormPrompt } from 'app/core/components/FormPrompt/FormPrompt';
|
2024-08-20 10:31:13 -05:00
|
|
|
import { Page } from 'app/core/components/Page/Page';
|
|
|
|
import config from 'app/core/config';
|
|
|
|
import { t, Trans } from 'app/core/internationalization';
|
|
|
|
import { Loader } from 'app/features/plugins/admin/components/Loader';
|
2024-09-04 05:19:45 -05:00
|
|
|
import { LdapPayload, MapKeyCertConfigured, StoreState } from 'app/types';
|
2024-08-20 10:31:13 -05:00
|
|
|
|
2024-08-22 10:16:18 -05:00
|
|
|
import { LdapDrawerComponent } from './LdapDrawer';
|
|
|
|
|
2024-08-20 10:31:13 -05:00
|
|
|
const appEvents = getAppEvents();
|
|
|
|
|
|
|
|
const mapStateToProps = (state: StoreState) => ({
|
|
|
|
ldapSsoSettings: state.ldap.ldapSsoSettings,
|
|
|
|
});
|
|
|
|
|
|
|
|
const mapDispatchToProps = {};
|
|
|
|
|
|
|
|
const connector = connect(mapStateToProps, mapDispatchToProps);
|
|
|
|
|
|
|
|
const pageNav: NavModelItem = {
|
|
|
|
text: 'LDAP',
|
|
|
|
icon: 'shield',
|
|
|
|
id: 'LDAP',
|
|
|
|
};
|
|
|
|
|
2024-09-17 10:52:53 -05:00
|
|
|
const serverConfig = 'settings.config.servers.0';
|
|
|
|
|
2024-10-02 04:42:23 -05:00
|
|
|
const isOptionDefined = (option: string | undefined) => option !== undefined && option !== '';
|
|
|
|
|
2024-08-20 10:31:13 -05:00
|
|
|
const emptySettings: LdapPayload = {
|
|
|
|
id: '',
|
|
|
|
provider: '',
|
|
|
|
source: '',
|
|
|
|
settings: {
|
|
|
|
activeSyncEnabled: false,
|
|
|
|
allowSignUp: false,
|
|
|
|
config: {
|
|
|
|
servers: [
|
|
|
|
{
|
|
|
|
attributes: {},
|
|
|
|
bind_dn: '',
|
|
|
|
bind_password: '',
|
|
|
|
client_cert: '',
|
2024-09-04 05:19:45 -05:00
|
|
|
client_cert_value: '',
|
2024-08-20 10:31:13 -05:00
|
|
|
client_key: '',
|
2024-09-04 05:19:45 -05:00
|
|
|
client_key_value: '',
|
2024-08-20 10:31:13 -05:00
|
|
|
group_mappings: [],
|
|
|
|
group_search_base_dns: [],
|
|
|
|
group_search_filter: '',
|
|
|
|
group_search_filter_user_attribute: '',
|
|
|
|
host: '',
|
|
|
|
min_tls_version: '',
|
|
|
|
port: 389,
|
|
|
|
root_ca_cert: '',
|
2024-09-04 05:19:45 -05:00
|
|
|
root_ca_cert_value: [],
|
2024-08-20 10:31:13 -05:00
|
|
|
search_base_dns: [],
|
|
|
|
search_filter: '',
|
|
|
|
skip_org_role_sync: false,
|
|
|
|
ssl_skip_verify: false,
|
|
|
|
start_tls: false,
|
|
|
|
timeout: 10,
|
|
|
|
tls_ciphers: [],
|
|
|
|
tls_skip_verify: false,
|
|
|
|
use_ssl: false,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
enabled: false,
|
|
|
|
skipOrgRoleSync: false,
|
|
|
|
syncCron: '',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
export const LdapSettingsPage = () => {
|
|
|
|
const [isLoading, setIsLoading] = useState(true);
|
2024-08-22 10:16:18 -05:00
|
|
|
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
|
2024-08-20 10:31:13 -05:00
|
|
|
|
2024-10-08 04:54:16 -05:00
|
|
|
const [isBindPasswordConfigured, setBindPasswordConfigured] = useState(false);
|
2024-09-04 05:19:45 -05:00
|
|
|
const [mapKeyCertConfigured, setMapKeyCertConfigured] = useState<MapKeyCertConfigured>({
|
|
|
|
clientKeyCertValue: false,
|
|
|
|
clientKeyCertPath: false,
|
|
|
|
});
|
|
|
|
|
2024-08-20 10:31:13 -05:00
|
|
|
const methods = useForm<LdapPayload>({ defaultValues: emptySettings });
|
2024-09-25 08:59:57 -05:00
|
|
|
const {
|
|
|
|
control,
|
|
|
|
formState: { isDirty },
|
|
|
|
getValues,
|
2024-10-08 04:54:16 -05:00
|
|
|
setValue,
|
2024-09-25 08:59:57 -05:00
|
|
|
handleSubmit,
|
|
|
|
register,
|
|
|
|
reset,
|
|
|
|
watch,
|
|
|
|
} = methods;
|
2024-08-20 10:31:13 -05:00
|
|
|
|
|
|
|
const styles = useStyles2(getStyles);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
async function init() {
|
2024-09-10 10:06:40 -05:00
|
|
|
const payload = await getSettings();
|
2024-09-25 08:59:57 -05:00
|
|
|
let serverConfig = emptySettings.settings.config.servers[0];
|
|
|
|
if (payload.settings.config.servers?.length > 0) {
|
|
|
|
serverConfig = payload.settings.config.servers[0];
|
|
|
|
}
|
2024-09-04 05:19:45 -05:00
|
|
|
setMapKeyCertConfigured({
|
2024-10-02 04:42:23 -05:00
|
|
|
clientKeyCertValue: isOptionDefined(serverConfig.client_key_value),
|
|
|
|
clientKeyCertPath: isOptionDefined(serverConfig.client_key),
|
2024-09-04 05:19:45 -05:00
|
|
|
});
|
2024-10-08 04:54:16 -05:00
|
|
|
setBindPasswordConfigured(isOptionDefined(serverConfig.bind_password));
|
2024-09-04 05:19:45 -05:00
|
|
|
|
2024-08-20 10:31:13 -05:00
|
|
|
reset(payload);
|
|
|
|
setIsLoading(false);
|
|
|
|
}
|
|
|
|
init();
|
|
|
|
}, [reset]);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Display warning if the feature flag is disabled
|
|
|
|
*/
|
|
|
|
if (!config.featureToggles.ssoSettingsLDAP) {
|
|
|
|
return (
|
|
|
|
<Alert title="invalid configuration">
|
|
|
|
<Trans i18nKey="ldap-settings-page.alert.feature-flag-disabled">
|
|
|
|
This page is only accessible by enabling the <strong>ssoSettingsLDAP</strong> feature flag.
|
|
|
|
</Trans>
|
|
|
|
</Alert>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-09-10 10:06:40 -05:00
|
|
|
/**
|
|
|
|
* Fetches the settings from the backend
|
|
|
|
* @returns Promise<LdapPayload>
|
|
|
|
*/
|
|
|
|
const getSettings = async () => {
|
|
|
|
try {
|
|
|
|
const payload = await getBackendSrv().get<LdapPayload>('/api/v1/sso-settings/ldap');
|
|
|
|
if (!payload || !payload.settings || !payload.settings.config) {
|
|
|
|
appEvents.publish({
|
|
|
|
type: AppEvents.alertError.name,
|
|
|
|
payload: [t('ldap-settings-page.alert.error-fetching', 'Error fetching LDAP settings')],
|
|
|
|
});
|
|
|
|
return emptySettings;
|
|
|
|
}
|
|
|
|
return payload;
|
|
|
|
} catch (error) {
|
|
|
|
appEvents.publish({
|
|
|
|
type: AppEvents.alertError.name,
|
|
|
|
payload: [t('ldap-settings-page.alert.error-fetching', 'Error fetching LDAP settings')],
|
|
|
|
});
|
|
|
|
return emptySettings;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-08-20 10:31:13 -05:00
|
|
|
/**
|
|
|
|
* Save payload to the backend
|
|
|
|
* @param payload LdapPayload
|
|
|
|
*/
|
|
|
|
const putPayload = async (payload: LdapPayload) => {
|
|
|
|
try {
|
|
|
|
const result = await getBackendSrv().put('/api/v1/sso-settings/ldap', payload);
|
|
|
|
if (result) {
|
|
|
|
appEvents.publish({
|
|
|
|
type: AppEvents.alertError.name,
|
|
|
|
payload: [t('ldap-settings-page.alert.error-saving', 'Error saving LDAP settings')],
|
|
|
|
});
|
|
|
|
}
|
|
|
|
appEvents.publish({
|
|
|
|
type: AppEvents.alertSuccess.name,
|
|
|
|
payload: [t('ldap-settings-page.alert.saved', 'LDAP settings saved')],
|
|
|
|
});
|
2024-09-10 10:06:40 -05:00
|
|
|
reset(await getSettings());
|
2024-10-02 04:42:23 -05:00
|
|
|
|
|
|
|
// Delay redirect so the form state can update
|
|
|
|
setTimeout(() => {
|
|
|
|
locationService.push(`/admin/authentication`);
|
|
|
|
}, 300);
|
2024-08-20 10:31:13 -05:00
|
|
|
} catch (error) {
|
|
|
|
appEvents.publish({
|
|
|
|
type: AppEvents.alertError.name,
|
|
|
|
payload: [t('ldap-settings-page.alert.error-saving', 'Error saving LDAP settings')],
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const onErrors = () => {
|
|
|
|
appEvents.publish({
|
|
|
|
type: AppEvents.alertError.name,
|
|
|
|
payload: [t('ldap-settings-page.alert.error-validate-form', 'Error validating LDAP settings')],
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Button's Actions
|
|
|
|
*/
|
2024-09-25 08:59:57 -05:00
|
|
|
const submitAndEnableLdapSettings = async (payload: LdapPayload) => {
|
2024-10-02 04:42:23 -05:00
|
|
|
payload.settings.enabled = !payload.settings.enabled;
|
2024-09-25 08:59:57 -05:00
|
|
|
await putPayload(payload);
|
|
|
|
reportInteraction('authentication_ldap_enabled');
|
2024-08-20 10:31:13 -05:00
|
|
|
};
|
2024-09-25 08:59:57 -05:00
|
|
|
const saveForm = async () => {
|
|
|
|
await putPayload(getValues());
|
|
|
|
reportInteraction('authentication_ldap_saved');
|
2024-08-20 10:31:13 -05:00
|
|
|
};
|
2024-09-17 10:52:53 -05:00
|
|
|
const deleteLDAPConfig = async () => {
|
2024-08-20 10:31:13 -05:00
|
|
|
try {
|
|
|
|
setIsLoading(true);
|
|
|
|
await getBackendSrv().delete('/api/v1/sso-settings/ldap');
|
2024-09-10 10:06:40 -05:00
|
|
|
const payload = await getSettings();
|
2024-08-22 10:16:18 -05:00
|
|
|
appEvents.publish({
|
|
|
|
type: AppEvents.alertSuccess.name,
|
|
|
|
payload: [t('ldap-settings-page.alert.discard-success', 'LDAP settings discarded')],
|
|
|
|
});
|
2024-08-20 10:31:13 -05:00
|
|
|
reset(payload);
|
2024-09-25 08:59:57 -05:00
|
|
|
reportInteraction('authentication_ldap_deleted');
|
2024-10-02 04:42:23 -05:00
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
locationService.push(`/admin/authentication`);
|
|
|
|
}, 300);
|
2024-08-20 10:31:13 -05:00
|
|
|
} catch (error) {
|
|
|
|
appEvents.publish({
|
|
|
|
type: AppEvents.alertError.name,
|
|
|
|
payload: [t('ldap-settings-page.alert.error-saving', 'Error saving LDAP settings')],
|
|
|
|
});
|
|
|
|
} finally {
|
|
|
|
setIsLoading(false);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-09-25 08:59:57 -05:00
|
|
|
const onDiscard = () => {
|
|
|
|
reportInteraction('authentication_ldap_abandoned');
|
|
|
|
};
|
|
|
|
|
2024-08-20 10:31:13 -05:00
|
|
|
const 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
|
2024-09-09 09:32:23 -05:00
|
|
|
our{' '}
|
|
|
|
<TextLink
|
|
|
|
href="https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/ldap/"
|
|
|
|
external
|
|
|
|
>
|
|
|
|
<Trans i18nKey="ldap-settings-page.documentation">documentation</Trans>
|
|
|
|
</TextLink>
|
|
|
|
.
|
2024-08-20 10:31:13 -05:00
|
|
|
</Trans>
|
|
|
|
);
|
|
|
|
|
2024-09-06 08:13:22 -05:00
|
|
|
const disabledFormAlert = (
|
|
|
|
<Alert title={t('ldap-settings-page.login-form-alert.title', 'Basic login disabled')}>
|
|
|
|
<Trans i18nKey="ldap-settings-page.login-form-alert.description">
|
|
|
|
Your LDAP configuration is not working because the basic login form is currently disabled. Please enable the
|
|
|
|
login form to use LDAP authentication. You can enable it on the Authentication page under “Auth settings”.
|
|
|
|
</Trans>
|
|
|
|
</Alert>
|
|
|
|
);
|
|
|
|
|
2024-08-20 10:31:13 -05:00
|
|
|
return (
|
|
|
|
<Page navId="authentication" pageNav={pageNav} subTitle={subTitle}>
|
|
|
|
<Page.Contents>
|
2024-09-06 08:13:22 -05:00
|
|
|
{config.disableLoginForm && disabledFormAlert}
|
2024-08-20 10:31:13 -05:00
|
|
|
<FormProvider {...methods}>
|
|
|
|
<form onSubmit={handleSubmit(submitAndEnableLdapSettings, onErrors)}>
|
2024-09-25 08:59:57 -05:00
|
|
|
<FormPrompt confirmRedirect={isDirty} onDiscard={onDiscard} />
|
2024-08-20 10:31:13 -05:00
|
|
|
{isLoading && <Loader />}
|
|
|
|
{!isLoading && (
|
|
|
|
<section className={styles.form}>
|
|
|
|
<h3>
|
|
|
|
<Trans i18nKey="ldap-settings-page.title">Basic Settings</Trans>
|
|
|
|
</h3>
|
|
|
|
<Field
|
2024-09-25 08:59:57 -05:00
|
|
|
label={t('ldap-settings-page.host.label', 'Server host *')}
|
2024-08-20 10:31:13 -05:00
|
|
|
description={t(
|
|
|
|
'ldap-settings-page.host.description',
|
|
|
|
'Hostname or IP address of the LDAP server you wish to connect to.'
|
|
|
|
)}
|
|
|
|
>
|
|
|
|
<Input
|
|
|
|
id="host"
|
|
|
|
placeholder={t('ldap-settings-page.host.placeholder', 'example: 127.0.0.1')}
|
|
|
|
type="text"
|
2024-09-17 10:52:53 -05:00
|
|
|
{...register(`${serverConfig}.host`, { required: true })}
|
2024-08-20 10:31:13 -05:00
|
|
|
/>
|
|
|
|
</Field>
|
|
|
|
<Field
|
|
|
|
label={t('ldap-settings-page.bind-dn.label', 'Bind DN')}
|
|
|
|
description={t(
|
|
|
|
'ldap-settings-page.bind-dn.description',
|
|
|
|
'Distinguished name of the account used to bind and authenticate to the LDAP server.'
|
|
|
|
)}
|
|
|
|
>
|
|
|
|
<Input
|
|
|
|
id="bind-dn"
|
|
|
|
placeholder={t('ldap-settings-page.bind-dn.placeholder', 'example: cn=admin,dc=grafana,dc=org')}
|
|
|
|
type="text"
|
2024-09-17 10:52:53 -05:00
|
|
|
{...register(`${serverConfig}.bind_dn`)}
|
2024-08-20 10:31:13 -05:00
|
|
|
/>
|
|
|
|
</Field>
|
|
|
|
<Field label={t('ldap-settings-page.bind-password.label', 'Bind password')}>
|
2024-10-08 04:54:16 -05:00
|
|
|
<SecretInput
|
2024-08-20 10:31:13 -05:00
|
|
|
id="bind-password"
|
2024-10-08 04:54:16 -05:00
|
|
|
isConfigured={isBindPasswordConfigured}
|
|
|
|
onReset={() => {
|
|
|
|
setValue(`${serverConfig}.bind_password`, '');
|
|
|
|
setBindPasswordConfigured(false);
|
|
|
|
}}
|
|
|
|
value={watch(`${serverConfig}.bind_password`)}
|
|
|
|
onChange={({ currentTarget: { value } }) => setValue(`${serverConfig}.bind_password`, value)}
|
2024-08-20 10:31:13 -05:00
|
|
|
/>
|
|
|
|
</Field>
|
|
|
|
<Field
|
2024-09-25 08:59:57 -05:00
|
|
|
label={t('ldap-settings-page.search_filter.label', 'Search filter *')}
|
2024-08-20 10:31:13 -05:00
|
|
|
description={t(
|
|
|
|
'ldap-settings-page.search_filter.description',
|
|
|
|
'LDAP search filter used to locate specific entries within the directory.'
|
|
|
|
)}
|
|
|
|
>
|
|
|
|
<Input
|
|
|
|
id="search_filter"
|
|
|
|
placeholder={t('ldap-settings-page.search_filter.placeholder', 'example: cn=%s')}
|
|
|
|
type="text"
|
2024-09-17 10:52:53 -05:00
|
|
|
{...register(`${serverConfig}.search_filter`, { required: true })}
|
2024-08-20 10:31:13 -05:00
|
|
|
/>
|
|
|
|
</Field>
|
|
|
|
<Field
|
|
|
|
label={t('ldap-settings-page.search-base-dns.label', 'Search base DNS *')}
|
|
|
|
description={t(
|
|
|
|
'ldap-settings-page.search-base-dns.description',
|
2024-09-17 10:52:53 -05:00
|
|
|
'An array of base dns to search through.'
|
2024-08-20 10:31:13 -05:00
|
|
|
)}
|
|
|
|
>
|
2024-09-17 10:52:53 -05:00
|
|
|
<Controller
|
|
|
|
name={`${serverConfig}.search_base_dns`}
|
|
|
|
control={control}
|
2024-09-25 08:59:57 -05:00
|
|
|
render={({ field: { onChange, ref, ...field } }) => (
|
2024-09-17 10:52:53 -05:00
|
|
|
<MultiSelect
|
|
|
|
{...field}
|
|
|
|
allowCustomValue
|
2024-09-25 08:59:57 -05:00
|
|
|
className={styles.multiSelect}
|
2024-10-02 04:42:23 -05:00
|
|
|
noOptionsMessage=""
|
|
|
|
placeholder={t('ldap-settings-page.search-base-dns.placeholder', 'example: dc=grafana,dc=org')}
|
2024-09-17 10:52:53 -05:00
|
|
|
onChange={(v) => onChange(v.map(({ value }) => String(value)))}
|
|
|
|
/>
|
|
|
|
)}
|
2024-10-02 04:42:23 -05:00
|
|
|
/>
|
2024-08-20 10:31:13 -05:00
|
|
|
</Field>
|
2024-08-22 10:16:18 -05:00
|
|
|
<Box borderColor="strong" borderStyle="solid" padding={2} width={68}>
|
|
|
|
<Stack alignItems={'center'} direction={'row'} gap={2} justifyContent={'space-between'}>
|
|
|
|
<Stack alignItems={'start'} direction={'column'}>
|
|
|
|
<Text element="h2">
|
|
|
|
<Trans i18nKey="ldap-settings-page.advanced-settings-section.title">Advanced Settings</Trans>
|
|
|
|
</Text>
|
|
|
|
<Text>
|
|
|
|
<Trans i18nKey="ldap-settings-page.advanced-settings-section.subtitle">
|
|
|
|
Mappings, extra security measures, and more.
|
|
|
|
</Trans>
|
|
|
|
</Text>
|
|
|
|
</Stack>
|
|
|
|
<Button variant="secondary" onClick={() => setIsDrawerOpen(true)}>
|
2024-09-25 08:59:57 -05:00
|
|
|
<Trans i18nKey="ldap-settings-page.advanced-settings-section.edit-button">Edit</Trans>
|
2024-08-22 10:16:18 -05:00
|
|
|
</Button>
|
|
|
|
</Stack>
|
|
|
|
</Box>
|
2024-09-10 10:06:40 -05:00
|
|
|
<Box display="flex" gap={2} marginTop={5}>
|
|
|
|
<Stack alignItems="center" gap={2}>
|
2024-10-02 04:42:23 -05:00
|
|
|
{!watch('settings.enabled') && (
|
|
|
|
<Button type="submit">
|
|
|
|
<Trans i18nKey="ldap-settings-page.buttons-section.save-and-enable-button">
|
|
|
|
Save and enable
|
|
|
|
</Trans>
|
|
|
|
</Button>
|
|
|
|
)}
|
|
|
|
{watch('settings.enabled') && (
|
|
|
|
<Button variant="secondary" type="submit">
|
|
|
|
<Trans i18nKey="ldap-settings-page.buttons-section.disable-button">Disable</Trans>
|
|
|
|
</Button>
|
|
|
|
)}
|
2024-08-20 10:31:13 -05:00
|
|
|
<Button variant="secondary" onClick={saveForm}>
|
2024-09-25 08:59:57 -05:00
|
|
|
<Trans i18nKey="ldap-settings-page.buttons-section.save-button">Save</Trans>
|
2024-08-20 10:31:13 -05:00
|
|
|
</Button>
|
2024-09-10 10:06:40 -05:00
|
|
|
<LinkButton href="/admin/authentication" variant="secondary">
|
2024-09-25 08:59:57 -05:00
|
|
|
<Trans i18nKey="ldap-settings-page.buttons-section.discard-button">Discard</Trans>
|
2024-09-10 10:06:40 -05:00
|
|
|
</LinkButton>
|
|
|
|
<Dropdown
|
|
|
|
overlay={
|
|
|
|
<Menu>
|
2024-09-17 10:52:53 -05:00
|
|
|
<Menu.Item label="Reset to default values" icon="history-alt" onClick={deleteLDAPConfig} />
|
2024-09-10 10:06:40 -05:00
|
|
|
</Menu>
|
|
|
|
}
|
|
|
|
placement="bottom-start"
|
|
|
|
>
|
|
|
|
<IconButton
|
|
|
|
tooltip="More actions"
|
|
|
|
title="More actions"
|
|
|
|
size="md"
|
|
|
|
variant="secondary"
|
|
|
|
name="ellipsis-v"
|
|
|
|
hidden={watch('source') === 'system'}
|
|
|
|
/>
|
|
|
|
</Dropdown>
|
2024-08-20 10:31:13 -05:00
|
|
|
</Stack>
|
|
|
|
</Box>
|
|
|
|
</section>
|
|
|
|
)}
|
2024-09-04 05:19:45 -05:00
|
|
|
{isDrawerOpen && (
|
|
|
|
<LdapDrawerComponent
|
|
|
|
onClose={() => setIsDrawerOpen(false)}
|
|
|
|
mapKeyCertConfigured={mapKeyCertConfigured}
|
|
|
|
setMapKeyCertConfigured={setMapKeyCertConfigured}
|
|
|
|
/>
|
|
|
|
)}
|
2024-08-20 10:31:13 -05:00
|
|
|
</form>
|
|
|
|
</FormProvider>
|
|
|
|
</Page.Contents>
|
|
|
|
</Page>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
function getStyles(theme: GrafanaTheme2) {
|
|
|
|
return {
|
|
|
|
form: css({
|
|
|
|
width: theme.spacing(68),
|
|
|
|
}),
|
2024-09-25 08:59:57 -05:00
|
|
|
multiSelect: css({
|
2024-10-02 04:42:23 -05:00
|
|
|
'div:last-of-type > svg': {
|
2024-09-25 08:59:57 -05:00
|
|
|
display: 'none',
|
|
|
|
},
|
|
|
|
}),
|
2024-08-20 10:31:13 -05:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export default connector(LdapSettingsPage);
|