Add all LDAP (Default-5) setting forms

This commit is contained in:
Marliana Lara 2020-12-04 16:28:48 -05:00
parent b24a1746ae
commit ba8cf1aaf2
No known key found for this signature in database
GPG Key ID: 38C73B40DFA809EE
5 changed files with 587 additions and 28 deletions

View File

@ -6,12 +6,13 @@ import {
waitForElement,
} from '../../../../testUtils/enzymeHelpers';
import { SettingsAPI } from '../../../api';
import { SettingsProvider } from '../../../contexts/Settings';
import mockAllOptions from '../shared/data.allSettingOptions.json';
import mockLDAP from '../shared/data.ldapSettings.json';
import LDAP from './LDAP';
jest.mock('../../../api/models/Settings');
SettingsAPI.readCategory.mockResolvedValue({
data: {},
});
SettingsAPI.readCategory.mockResolvedValue({ data: mockLDAP });
describe('<LDAP />', () => {
let wrapper;
@ -39,9 +40,14 @@ describe('<LDAP />', () => {
initialEntries: ['/settings/ldap/default/edit'],
});
await act(async () => {
wrapper = mountWithContexts(<LDAP />, {
context: { router: { history } },
});
wrapper = mountWithContexts(
<SettingsProvider value={mockAllOptions.actions}>
<LDAP />
</SettingsProvider>,
{
context: { router: { history } },
}
);
});
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
expect(wrapper.find('LDAPEdit').length).toBe(1);

View File

@ -1,25 +1,218 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Button } from '@patternfly/react-core';
import { CardBody, CardActionsRow } from '../../../../components/Card';
import React, { useCallback, useEffect } from 'react';
import { useHistory, useRouteMatch } from 'react-router-dom';
import { Formik } from 'formik';
import { Form } from '@patternfly/react-core';
import { CardBody } from '../../../../components/Card';
import ContentError from '../../../../components/ContentError';
import ContentLoading from '../../../../components/ContentLoading';
import { FormSubmitError } from '../../../../components/FormField';
import { FormColumnLayout } from '../../../../components/FormLayout';
import { useSettings } from '../../../../contexts/Settings';
import { RevertAllAlert, RevertFormActionGroup } from '../../shared';
import {
BooleanField,
ChoiceField,
EncryptedField,
InputField,
ObjectField,
} from '../../shared/SharedFields';
import { formatJson } from '../../shared/settingUtils';
import useModal from '../../../../util/useModal';
import useRequest from '../../../../util/useRequest';
import { SettingsAPI } from '../../../../api';
function LDAPEdit() {
const history = useHistory();
const { isModalOpen, toggleModal, closeModal } = useModal();
const { PUT: options } = useSettings();
const {
params: { category },
} = useRouteMatch('/settings/ldap/:category/edit');
const ldapCategory =
category === 'default' ? 'AUTH_LDAP_' : `AUTH_LDAP_${category}_`;
const { isLoading, error, request: fetchLDAP, result: ldap } = useRequest(
useCallback(async () => {
const { data } = await SettingsAPI.readCategory('ldap');
const mergedData = {};
Object.keys(data).forEach(key => {
if (!options[key]) {
return;
}
mergedData[key] = options[key];
mergedData[key].value = data[key];
});
return mergedData;
}, [options]),
null
);
useEffect(() => {
fetchLDAP();
}, [fetchLDAP]);
const { error: submitError, request: submitForm } = useRequest(
useCallback(
async values => {
await SettingsAPI.updateAll(values);
history.push(`/settings/ldap/${category}/details`);
},
[history, category]
),
null
);
const handleSubmit = async form => {
await submitForm({
[`${ldapCategory}BIND_DN`]: form[`${ldapCategory}BIND_DN`],
[`${ldapCategory}BIND_PASSWORD`]: form[`${ldapCategory}BIND_PASSWORD`],
[`${ldapCategory}DENY_GROUP`]: form[`${ldapCategory}DENY_GROUP`],
[`${ldapCategory}GROUP_TYPE`]: form[`${ldapCategory}GROUP_TYPE`],
[`${ldapCategory}REQUIRE_GROUP`]: form[`${ldapCategory}REQUIRE_GROUP`],
[`${ldapCategory}SERVER_URI`]: form[`${ldapCategory}SERVER_URI`],
[`${ldapCategory}START_TLS`]: form[`${ldapCategory}START_TLS`],
[`${ldapCategory}USER_DN_TEMPLATE`]: form[
`${ldapCategory}USER_DN_TEMPLATE`
],
[`${ldapCategory}GROUP_SEARCH`]: formatJson(
form[`${ldapCategory}GROUP_SEARCH`]
),
[`${ldapCategory}GROUP_TYPE_PARAMS`]: formatJson(
form[`${ldapCategory}GROUP_TYPE_PARAMS`]
),
[`${ldapCategory}ORGANIZATION_MAP`]: formatJson(
form[`${ldapCategory}ORGANIZATION_MAP`]
),
[`${ldapCategory}TEAM_MAP`]: formatJson(form[`${ldapCategory}TEAM_MAP`]),
[`${ldapCategory}USER_ATTR_MAP`]: formatJson(
form[`${ldapCategory}USER_ATTR_MAP`]
),
[`${ldapCategory}USER_FLAGS_BY_GROUP`]: formatJson(
form[`${ldapCategory}USER_FLAGS_BY_GROUP`]
),
[`${ldapCategory}USER_SEARCH`]: formatJson(
form[`${ldapCategory}USER_SEARCH`]
),
});
};
const handleRevertAll = async () => {
const defaultValues = Object.assign(
...Object.entries(ldap).map(([key, value]) => ({
[key]: value.default,
}))
);
await submitForm(defaultValues);
closeModal();
};
const handleCancel = () => {
history.push(`/settings/ldap/${category}/details`);
};
const initialValues = fields =>
Object.keys(fields).reduce((acc, key) => {
if (fields[key].type === 'list' || fields[key].type === 'nested object') {
const emptyDefault = fields[key].type === 'list' ? '[]' : '{}';
acc[key] = fields[key].value
? JSON.stringify(fields[key].value, null, 2)
: emptyDefault;
} else {
acc[key] = fields[key].value ?? '';
}
return acc;
}, {});
function LDAPEdit({ i18n }) {
return (
<CardBody>
{i18n._(t`Edit form coming soon :)`)}
<CardActionsRow>
<Button
aria-label={i18n._(t`Cancel`)}
component={Link}
to="/settings/ldap/details"
>
{i18n._(t`Cancel`)}
</Button>
</CardActionsRow>
{isLoading && <ContentLoading />}
{!isLoading && error && <ContentError error={error} />}
{!isLoading && ldap && (
<Formik initialValues={initialValues(ldap)} onSubmit={handleSubmit}>
{formik => (
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
<FormColumnLayout>
<InputField
name={`${ldapCategory}SERVER_URI`}
config={ldap[`${ldapCategory}SERVER_URI`]}
/>
<InputField
name={`${ldapCategory}BIND_DN`}
config={ldap[`${ldapCategory}BIND_DN`]}
/>
<EncryptedField
name={`${ldapCategory}BIND_PASSWORD`}
config={ldap[`${ldapCategory}BIND_PASSWORD`]}
/>
<InputField
name={`${ldapCategory}USER_DN_TEMPLATE`}
config={ldap[`${ldapCategory}USER_DN_TEMPLATE`]}
/>
<InputField
name={`${ldapCategory}REQUIRE_GROUP`}
config={ldap[`${ldapCategory}REQUIRE_GROUP`]}
/>
<InputField
name={`${ldapCategory}DENY_GROUP`}
config={ldap[`${ldapCategory}DENY_GROUP`]}
/>
<ChoiceField
name={`${ldapCategory}GROUP_TYPE`}
config={ldap[`${ldapCategory}GROUP_TYPE`]}
/>
<BooleanField
name={`${ldapCategory}START_TLS`}
config={ldap[`${ldapCategory}START_TLS`]}
/>
<ObjectField
name={`${ldapCategory}USER_SEARCH`}
config={ldap[`${ldapCategory}USER_SEARCH`]}
/>
<ObjectField
name={`${ldapCategory}GROUP_SEARCH`}
config={ldap[`${ldapCategory}GROUP_SEARCH`]}
/>
<ObjectField
name={`${ldapCategory}USER_ATTR_MAP`}
config={ldap[`${ldapCategory}USER_ATTR_MAP`]}
/>
<ObjectField
name={`${ldapCategory}GROUP_TYPE_PARAMS`}
config={ldap[`${ldapCategory}GROUP_TYPE_PARAMS`]}
/>
<ObjectField
name={`${ldapCategory}USER_FLAGS_BY_GROUP`}
config={ldap[`${ldapCategory}USER_FLAGS_BY_GROUP`]}
/>
<ObjectField
name={`${ldapCategory}ORGANIZATION_MAP`}
config={ldap[`${ldapCategory}ORGANIZATION_MAP`]}
/>
<ObjectField
name={`${ldapCategory}TEAM_MAP`}
config={ldap[`${ldapCategory}TEAM_MAP`]}
/>
{submitError && <FormSubmitError error={submitError} />}
</FormColumnLayout>
<RevertFormActionGroup
onCancel={handleCancel}
onSubmit={formik.handleSubmit}
onRevert={toggleModal}
/>
{isModalOpen && (
<RevertAllAlert
onClose={closeModal}
onRevertAll={handleRevertAll}
/>
)}
</Form>
)}
</Formik>
)}
</CardBody>
);
}
export default withI18n()(LDAPEdit);
export default LDAPEdit;

View File

@ -1,16 +1,242 @@
import React from 'react';
import { mountWithContexts } from '../../../../../testUtils/enzymeHelpers';
import { act } from 'react-dom/test-utils';
import { createMemoryHistory } from 'history';
import { useRouteMatch } from 'react-router-dom';
import {
mountWithContexts,
waitForElement,
} from '../../../../../testUtils/enzymeHelpers';
import mockAllOptions from '../../shared/data.allSettingOptions.json';
import mockLDAP from '../../shared/data.ldapSettings.json';
import mockLDAPDefault from '../../shared/data.ldapDefaultSettings.json';
import { SettingsProvider } from '../../../../contexts/Settings';
import { SettingsAPI } from '../../../../api';
import LDAPEdit from './LDAPEdit';
jest.mock('../../../../api/models/Settings');
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useRouteMatch: jest.fn(),
}));
SettingsAPI.readCategory.mockResolvedValue({ data: mockLDAP });
describe('<LDAPEdit />', () => {
let wrapper;
beforeEach(() => {
wrapper = mountWithContexts(<LDAPEdit />);
let history;
beforeEach(async () => {
history = createMemoryHistory({
initialEntries: ['/settings/ldap/default/edit'],
});
useRouteMatch.mockImplementation(() => ({
url: '/settings/ldap/default/edit',
path: '/settings/ldap/:category/edit',
params: { category: 'default' },
}));
await act(async () => {
wrapper = mountWithContexts(
<SettingsProvider value={mockAllOptions.actions}>
<LDAPEdit />
</SettingsProvider>,
{
context: { router: { history } },
}
);
});
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
});
afterEach(() => {
wrapper.unmount();
jest.clearAllMocks();
});
test('initially renders without crashing', () => {
expect(wrapper.find('LDAPEdit').length).toBe(1);
});
test('should display expected form fields', async () => {
expect(wrapper.find('FormGroup[label="LDAP Server URI"]').length).toBe(1);
expect(wrapper.find('FormGroup[label="LDAP Bind DN"]').length).toBe(1);
expect(wrapper.find('FormGroup[label="LDAP Bind Password"]').length).toBe(
1
);
expect(wrapper.find('FormGroup[label="LDAP User Search"]').length).toBe(1);
expect(
wrapper.find('FormGroup[label="LDAP User DN Template"]').length
).toBe(1);
expect(
wrapper.find('FormGroup[label="LDAP User Attribute Map"]').length
).toBe(1);
expect(wrapper.find('FormGroup[label="LDAP Group Search"]').length).toBe(1);
expect(wrapper.find('FormGroup[label="LDAP Group Type"]').length).toBe(1);
expect(
wrapper.find('FormGroup[label="LDAP Group Type Parameters"]').length
).toBe(1);
expect(wrapper.find('FormGroup[label="LDAP Require Group"]').length).toBe(
1
);
expect(wrapper.find('FormGroup[label="LDAP Deny Group"]').length).toBe(1);
expect(wrapper.find('FormGroup[label="LDAP Start TLS"]').length).toBe(1);
expect(
wrapper.find('FormGroup[label="LDAP User Flags By Group"]').length
).toBe(1);
expect(
wrapper.find('FormGroup[label="LDAP Organization Map"]').length
).toBe(1);
expect(wrapper.find('FormGroup[label="LDAP Team Map"]').length).toBe(1);
expect(
wrapper.find('FormGroup[fieldId="AUTH_LDAP_SERVER_URI"]').length
).toBe(1);
expect(
wrapper.find('FormGroup[fieldId="AUTH_LDAP_5_SERVER_URI"]').length
).toBe(0);
});
test('should successfully send default values to api on form revert all', async () => {
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
await act(async () => {
wrapper
.find('button[aria-label="Revert all to default"]')
.invoke('onClick')();
});
wrapper.update();
expect(wrapper.find('RevertAllAlert')).toHaveLength(1);
await act(async () => {
wrapper
.find('RevertAllAlert button[aria-label="Confirm revert all"]')
.invoke('onClick')();
});
wrapper.update();
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
expect(SettingsAPI.updateAll).toHaveBeenCalledWith(mockLDAPDefault);
});
test('should successfully send request to api on form submission', async () => {
act(() => {
wrapper
.find(
'FormGroup[fieldId="AUTH_LDAP_BIND_PASSWORD"] button[aria-label="Revert"]'
)
.invoke('onClick')();
wrapper
.find(
'FormGroup[fieldId="AUTH_LDAP_BIND_DN"] button[aria-label="Revert"]'
)
.invoke('onClick')();
wrapper.find('input#AUTH_LDAP_SERVER_URI').simulate('change', {
target: {
value: 'ldap://mock.example.com',
name: 'AUTH_LDAP_SERVER_URI',
},
});
wrapper.find('CodeMirrorInput#AUTH_LDAP_TEAM_MAP').invoke('onChange')(
'{\n"LDAP Sales":{\n"organization":\n"mock org"\n}\n}'
);
});
wrapper.update();
await act(async () => {
wrapper.find('Form').invoke('onSubmit')();
});
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
AUTH_LDAP_BIND_DN: '',
AUTH_LDAP_BIND_PASSWORD: '',
AUTH_LDAP_DENY_GROUP: '',
AUTH_LDAP_GROUP_SEARCH: [],
AUTH_LDAP_GROUP_TYPE: 'MemberDNGroupType',
AUTH_LDAP_GROUP_TYPE_PARAMS: { name_attr: 'cn', member_attr: 'member' },
AUTH_LDAP_ORGANIZATION_MAP: {},
AUTH_LDAP_REQUIRE_GROUP: 'CN=Tower Users,OU=Users,DC=example,DC=com',
AUTH_LDAP_SERVER_URI: 'ldap://mock.example.com',
AUTH_LDAP_START_TLS: false,
AUTH_LDAP_USER_ATTR_MAP: {},
AUTH_LDAP_USER_DN_TEMPLATE: 'uid=%(user)s,OU=Users,DC=example,DC=com',
AUTH_LDAP_USER_FLAGS_BY_GROUP: {},
AUTH_LDAP_USER_SEARCH: [],
AUTH_LDAP_TEAM_MAP: {
'LDAP Sales': {
organization: 'mock org',
},
},
});
});
test('should navigate to ldap default detail on successful submission', async () => {
await act(async () => {
wrapper.find('Form').invoke('onSubmit')();
});
expect(history.location.pathname).toEqual('/settings/ldap/default/details');
});
test('should navigate to ldap default detail when cancel is clicked', async () => {
await act(async () => {
wrapper.find('button[aria-label="Cancel"]').invoke('onClick')();
});
expect(history.location.pathname).toEqual('/settings/ldap/default/details');
});
test('should display error message on unsuccessful submission', async () => {
const error = {
response: {
data: { detail: 'An error occurred' },
},
};
SettingsAPI.updateAll.mockImplementation(() => Promise.reject(error));
expect(wrapper.find('FormSubmitError').length).toBe(0);
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
await act(async () => {
wrapper.find('Form').invoke('onSubmit')();
});
wrapper.update();
expect(wrapper.find('FormSubmitError').length).toBe(1);
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
});
test('should display ContentError on throw', async () => {
SettingsAPI.readCategory.mockImplementationOnce(() =>
Promise.reject(new Error())
);
await act(async () => {
wrapper = mountWithContexts(
<SettingsProvider value={mockAllOptions.actions}>
<LDAPEdit />
</SettingsProvider>
);
});
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
expect(wrapper.find('ContentError').length).toBe(1);
});
test('should display ldap category 5 edit form', async () => {
history = createMemoryHistory({
initialEntries: ['/settings/ldap/5/edit'],
});
useRouteMatch.mockImplementation(() => ({
url: '/settings/ldap/5/edit',
path: '/settings/ldap/:category/edit',
params: { category: '5' },
}));
await act(async () => {
wrapper = mountWithContexts(
<SettingsProvider value={mockAllOptions.actions}>
<LDAPEdit />
</SettingsProvider>,
{
context: { router: { history } },
}
);
});
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
expect(
wrapper.find('FormGroup[fieldId="AUTH_LDAP_SERVER_URI"]').length
).toBe(0);
expect(
wrapper.find('FormGroup[fieldId="AUTH_LDAP_5_SERVER_URI"]').length
).toBe(1);
expect(
wrapper.find('FormGroup[fieldId="AUTH_LDAP_5_SERVER_URI"] input').props()
.value
).toEqual('ldap://ldap5.example.com');
});
});

View File

@ -0,0 +1,134 @@
{
"AUTH_LDAP_1_BIND_DN": "",
"AUTH_LDAP_1_BIND_PASSWORD": "",
"AUTH_LDAP_1_CONNECTION_OPTIONS": {
"OPT_NETWORK_TIMEOUT": 30,
"OPT_REFERRALS": 0
},
"AUTH_LDAP_1_DENY_GROUP": null,
"AUTH_LDAP_1_GROUP_SEARCH": [],
"AUTH_LDAP_1_GROUP_TYPE": "MemberDNGroupType",
"AUTH_LDAP_1_GROUP_TYPE_PARAMS": {
"member_attr": "member",
"name_attr": "cn"
},
"AUTH_LDAP_1_ORGANIZATION_MAP": {},
"AUTH_LDAP_1_REQUIRE_GROUP": null,
"AUTH_LDAP_1_SERVER_URI": "",
"AUTH_LDAP_1_START_TLS": false,
"AUTH_LDAP_1_TEAM_MAP": {},
"AUTH_LDAP_1_USER_ATTR_MAP": {},
"AUTH_LDAP_1_USER_DN_TEMPLATE": null,
"AUTH_LDAP_1_USER_FLAGS_BY_GROUP": {},
"AUTH_LDAP_1_USER_SEARCH": [],
"AUTH_LDAP_2_BIND_DN": "",
"AUTH_LDAP_2_BIND_PASSWORD": "",
"AUTH_LDAP_2_CONNECTION_OPTIONS": {
"OPT_NETWORK_TIMEOUT": 30,
"OPT_REFERRALS": 0
},
"AUTH_LDAP_2_DENY_GROUP": null,
"AUTH_LDAP_2_GROUP_SEARCH": [],
"AUTH_LDAP_2_GROUP_TYPE": "MemberDNGroupType",
"AUTH_LDAP_2_GROUP_TYPE_PARAMS": {
"member_attr": "member",
"name_attr": "cn"
},
"AUTH_LDAP_2_ORGANIZATION_MAP": {},
"AUTH_LDAP_2_REQUIRE_GROUP": null,
"AUTH_LDAP_2_SERVER_URI": "",
"AUTH_LDAP_2_START_TLS": false,
"AUTH_LDAP_2_TEAM_MAP": {},
"AUTH_LDAP_2_USER_ATTR_MAP": {},
"AUTH_LDAP_2_USER_DN_TEMPLATE": null,
"AUTH_LDAP_2_USER_FLAGS_BY_GROUP": {},
"AUTH_LDAP_2_USER_SEARCH": [],
"AUTH_LDAP_3_BIND_DN": "",
"AUTH_LDAP_3_BIND_PASSWORD": "",
"AUTH_LDAP_3_CONNECTION_OPTIONS": {
"OPT_NETWORK_TIMEOUT": 30,
"OPT_REFERRALS": 0
},
"AUTH_LDAP_3_DENY_GROUP": null,
"AUTH_LDAP_3_GROUP_SEARCH": [],
"AUTH_LDAP_3_GROUP_TYPE": "MemberDNGroupType",
"AUTH_LDAP_3_GROUP_TYPE_PARAMS": {
"member_attr": "member",
"name_attr": "cn"
},
"AUTH_LDAP_3_ORGANIZATION_MAP": {},
"AUTH_LDAP_3_REQUIRE_GROUP": null,
"AUTH_LDAP_3_SERVER_URI": "",
"AUTH_LDAP_3_START_TLS": false,
"AUTH_LDAP_3_TEAM_MAP": {},
"AUTH_LDAP_3_USER_ATTR_MAP": {},
"AUTH_LDAP_3_USER_DN_TEMPLATE": null,
"AUTH_LDAP_3_USER_FLAGS_BY_GROUP": {},
"AUTH_LDAP_3_USER_SEARCH": [],
"AUTH_LDAP_4_BIND_DN": "",
"AUTH_LDAP_4_BIND_PASSWORD": "",
"AUTH_LDAP_4_CONNECTION_OPTIONS": {
"OPT_NETWORK_TIMEOUT": 30,
"OPT_REFERRALS": 0
},
"AUTH_LDAP_4_DENY_GROUP": null,
"AUTH_LDAP_4_GROUP_SEARCH": [],
"AUTH_LDAP_4_GROUP_TYPE": "MemberDNGroupType",
"AUTH_LDAP_4_GROUP_TYPE_PARAMS": {
"member_attr": "member",
"name_attr": "cn"
},
"AUTH_LDAP_4_ORGANIZATION_MAP": {},
"AUTH_LDAP_4_REQUIRE_GROUP": null,
"AUTH_LDAP_4_SERVER_URI": "",
"AUTH_LDAP_4_START_TLS": false,
"AUTH_LDAP_4_TEAM_MAP": {},
"AUTH_LDAP_4_USER_ATTR_MAP": {},
"AUTH_LDAP_4_USER_DN_TEMPLATE": null,
"AUTH_LDAP_4_USER_FLAGS_BY_GROUP": {},
"AUTH_LDAP_4_USER_SEARCH": [],
"AUTH_LDAP_5_BIND_DN": "",
"AUTH_LDAP_5_BIND_PASSWORD": "",
"AUTH_LDAP_5_CONNECTION_OPTIONS": {
"OPT_NETWORK_TIMEOUT": 30,
"OPT_REFERRALS": 0
},
"AUTH_LDAP_5_DENY_GROUP": null,
"AUTH_LDAP_5_GROUP_SEARCH": [],
"AUTH_LDAP_5_GROUP_TYPE": "MemberDNGroupType",
"AUTH_LDAP_5_GROUP_TYPE_PARAMS": {
"member_attr": "member",
"name_attr": "cn"
},
"AUTH_LDAP_5_ORGANIZATION_MAP": {},
"AUTH_LDAP_5_REQUIRE_GROUP": null,
"AUTH_LDAP_5_SERVER_URI": "",
"AUTH_LDAP_5_START_TLS": false,
"AUTH_LDAP_5_TEAM_MAP": {},
"AUTH_LDAP_5_USER_ATTR_MAP": {},
"AUTH_LDAP_5_USER_DN_TEMPLATE": null,
"AUTH_LDAP_5_USER_FLAGS_BY_GROUP": {},
"AUTH_LDAP_5_USER_SEARCH": [],
"AUTH_LDAP_BIND_DN": "",
"AUTH_LDAP_BIND_PASSWORD": "",
"AUTH_LDAP_CONNECTION_OPTIONS": {
"OPT_NETWORK_TIMEOUT": 30,
"OPT_REFERRALS": 0
},
"AUTH_LDAP_DENY_GROUP": null,
"AUTH_LDAP_GROUP_SEARCH": [],
"AUTH_LDAP_GROUP_TYPE": "MemberDNGroupType",
"AUTH_LDAP_GROUP_TYPE_PARAMS": {
"member_attr": "member",
"name_attr": "cn"
},
"AUTH_LDAP_ORGANIZATION_MAP": {},
"AUTH_LDAP_REQUIRE_GROUP": null,
"AUTH_LDAP_SERVER_URI": "",
"AUTH_LDAP_START_TLS": false,
"AUTH_LDAP_TEAM_MAP": {},
"AUTH_LDAP_USER_ATTR_MAP": {},
"AUTH_LDAP_USER_DN_TEMPLATE": null,
"AUTH_LDAP_USER_FLAGS_BY_GROUP": {},
"AUTH_LDAP_USER_SEARCH": []
}

View File

@ -109,7 +109,7 @@
"AUTH_LDAP_4_USER_FLAGS_BY_GROUP": {},
"AUTH_LDAP_4_ORGANIZATION_MAP": {},
"AUTH_LDAP_4_TEAM_MAP": {},
"AUTH_LDAP_5_SERVER_URI": "",
"AUTH_LDAP_5_SERVER_URI": "ldap://ldap5.example.com",
"AUTH_LDAP_5_BIND_DN": "",
"AUTH_LDAP_5_BIND_PASSWORD": "",
"AUTH_LDAP_5_START_TLS": false,