Use documentation links service provided by the core directly. (#88158)
This commit is contained in:
parent
91a23b7df0
commit
abfd8bb9d3
|
@ -108,12 +108,38 @@ readonly links: {
|
||||||
readonly ml: Record<string, string>;
|
readonly ml: Record<string, string>;
|
||||||
readonly transforms: Record<string, string>;
|
readonly transforms: Record<string, string>;
|
||||||
readonly visualize: Record<string, string>;
|
readonly visualize: Record<string, string>;
|
||||||
readonly apis: Record<string, string>;
|
readonly apis: Readonly<{
|
||||||
|
createIndex: string;
|
||||||
|
createSnapshotLifecyclePolicy: string;
|
||||||
|
createRoleMapping: string;
|
||||||
|
createRoleMappingTemplates: string;
|
||||||
|
createApiKey: string;
|
||||||
|
createPipeline: string;
|
||||||
|
createTransformRequest: string;
|
||||||
|
executeWatchActionModes: string;
|
||||||
|
openIndex: string;
|
||||||
|
putComponentTemplate: string;
|
||||||
|
painlessExecute: string;
|
||||||
|
putComponentTemplateMetadata: string;
|
||||||
|
putWatch: string;
|
||||||
|
updateTransform: string;
|
||||||
|
}>;
|
||||||
readonly observability: Record<string, string>;
|
readonly observability: Record<string, string>;
|
||||||
readonly alerting: Record<string, string>;
|
readonly alerting: Record<string, string>;
|
||||||
readonly maps: Record<string, string>;
|
readonly maps: Record<string, string>;
|
||||||
readonly monitoring: Record<string, string>;
|
readonly monitoring: Record<string, string>;
|
||||||
readonly security: Record<string, string>;
|
readonly security: Readonly<{
|
||||||
|
apiKeyServiceSettings: string;
|
||||||
|
clusterPrivileges: string;
|
||||||
|
elasticsearchSettings: string;
|
||||||
|
elasticsearchEnableSecurity: string;
|
||||||
|
indicesPrivileges: string;
|
||||||
|
kibanaTLS: string;
|
||||||
|
kibanaPrivileges: string;
|
||||||
|
mappingRoles: string;
|
||||||
|
mappingRolesFieldRules: string;
|
||||||
|
runAsPrivilege: string;
|
||||||
|
}>;
|
||||||
readonly watcher: Record<string, string>;
|
readonly watcher: Record<string, string>;
|
||||||
readonly ccs: Record<string, string>;
|
readonly ccs: Record<string, string>;
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -220,7 +220,7 @@ export class DocLinksService {
|
||||||
},
|
},
|
||||||
apis: {
|
apis: {
|
||||||
createIndex: `${ELASTICSEARCH_DOCS}indices-create-index.html`,
|
createIndex: `${ELASTICSEARCH_DOCS}indices-create-index.html`,
|
||||||
createSnapshotLifecylePolicy: `${ELASTICSEARCH_DOCS}slm-api-put-policy.html`,
|
createSnapshotLifecyclePolicy: `${ELASTICSEARCH_DOCS}slm-api-put-policy.html`,
|
||||||
createRoleMapping: `${ELASTICSEARCH_DOCS}security-api-put-role-mapping.html`,
|
createRoleMapping: `${ELASTICSEARCH_DOCS}security-api-put-role-mapping.html`,
|
||||||
createRoleMappingTemplates: `${ELASTICSEARCH_DOCS}security-api-put-role-mapping.html#_role_templates`,
|
createRoleMappingTemplates: `${ELASTICSEARCH_DOCS}security-api-put-role-mapping.html#_role_templates`,
|
||||||
createApiKey: `${ELASTICSEARCH_DOCS}security-api-create-api-key.html`,
|
createApiKey: `${ELASTICSEARCH_DOCS}security-api-create-api-key.html`,
|
||||||
|
@ -344,12 +344,38 @@ export interface DocLinksStart {
|
||||||
readonly ml: Record<string, string>;
|
readonly ml: Record<string, string>;
|
||||||
readonly transforms: Record<string, string>;
|
readonly transforms: Record<string, string>;
|
||||||
readonly visualize: Record<string, string>;
|
readonly visualize: Record<string, string>;
|
||||||
readonly apis: Record<string, string>;
|
readonly apis: Readonly<{
|
||||||
|
createIndex: string;
|
||||||
|
createSnapshotLifecyclePolicy: string;
|
||||||
|
createRoleMapping: string;
|
||||||
|
createRoleMappingTemplates: string;
|
||||||
|
createApiKey: string;
|
||||||
|
createPipeline: string;
|
||||||
|
createTransformRequest: string;
|
||||||
|
executeWatchActionModes: string;
|
||||||
|
openIndex: string;
|
||||||
|
putComponentTemplate: string;
|
||||||
|
painlessExecute: string;
|
||||||
|
putComponentTemplateMetadata: string;
|
||||||
|
putWatch: string;
|
||||||
|
updateTransform: string;
|
||||||
|
}>;
|
||||||
readonly observability: Record<string, string>;
|
readonly observability: Record<string, string>;
|
||||||
readonly alerting: Record<string, string>;
|
readonly alerting: Record<string, string>;
|
||||||
readonly maps: Record<string, string>;
|
readonly maps: Record<string, string>;
|
||||||
readonly monitoring: Record<string, string>;
|
readonly monitoring: Record<string, string>;
|
||||||
readonly security: Record<string, string>;
|
readonly security: Readonly<{
|
||||||
|
apiKeyServiceSettings: string;
|
||||||
|
clusterPrivileges: string;
|
||||||
|
elasticsearchSettings: string;
|
||||||
|
elasticsearchEnableSecurity: string;
|
||||||
|
indicesPrivileges: string;
|
||||||
|
kibanaTLS: string;
|
||||||
|
kibanaPrivileges: string;
|
||||||
|
mappingRoles: string;
|
||||||
|
mappingRolesFieldRules: string;
|
||||||
|
runAsPrivilege: string;
|
||||||
|
}>;
|
||||||
readonly watcher: Record<string, string>;
|
readonly watcher: Record<string, string>;
|
||||||
readonly ccs: Record<string, string>;
|
readonly ccs: Record<string, string>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -587,12 +587,38 @@ export interface DocLinksStart {
|
||||||
readonly ml: Record<string, string>;
|
readonly ml: Record<string, string>;
|
||||||
readonly transforms: Record<string, string>;
|
readonly transforms: Record<string, string>;
|
||||||
readonly visualize: Record<string, string>;
|
readonly visualize: Record<string, string>;
|
||||||
readonly apis: Record<string, string>;
|
readonly apis: Readonly<{
|
||||||
|
createIndex: string;
|
||||||
|
createSnapshotLifecyclePolicy: string;
|
||||||
|
createRoleMapping: string;
|
||||||
|
createRoleMappingTemplates: string;
|
||||||
|
createApiKey: string;
|
||||||
|
createPipeline: string;
|
||||||
|
createTransformRequest: string;
|
||||||
|
executeWatchActionModes: string;
|
||||||
|
openIndex: string;
|
||||||
|
putComponentTemplate: string;
|
||||||
|
painlessExecute: string;
|
||||||
|
putComponentTemplateMetadata: string;
|
||||||
|
putWatch: string;
|
||||||
|
updateTransform: string;
|
||||||
|
}>;
|
||||||
readonly observability: Record<string, string>;
|
readonly observability: Record<string, string>;
|
||||||
readonly alerting: Record<string, string>;
|
readonly alerting: Record<string, string>;
|
||||||
readonly maps: Record<string, string>;
|
readonly maps: Record<string, string>;
|
||||||
readonly monitoring: Record<string, string>;
|
readonly monitoring: Record<string, string>;
|
||||||
readonly security: Record<string, string>;
|
readonly security: Readonly<{
|
||||||
|
apiKeyServiceSettings: string;
|
||||||
|
clusterPrivileges: string;
|
||||||
|
elasticsearchSettings: string;
|
||||||
|
elasticsearchEnableSecurity: string;
|
||||||
|
indicesPrivileges: string;
|
||||||
|
kibanaTLS: string;
|
||||||
|
kibanaPrivileges: string;
|
||||||
|
mappingRoles: string;
|
||||||
|
mappingRolesFieldRules: string;
|
||||||
|
runAsPrivilege: string;
|
||||||
|
}>;
|
||||||
readonly watcher: Record<string, string>;
|
readonly watcher: Record<string, string>;
|
||||||
readonly ccs: Record<string, string>;
|
readonly ccs: Record<string, string>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,132 +1,123 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`APIKeysGridPage renders a callout when API keys are not enabled 1`] = `
|
exports[`APIKeysGridPage renders a callout when API keys are not enabled 1`] = `
|
||||||
<NotEnabled
|
<EuiCallOut
|
||||||
docLinks={
|
color="danger"
|
||||||
DocumentationLinksService {
|
iconType="alert"
|
||||||
"apiKeySettings": "https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-settings.html#api-key-service-settings",
|
title={
|
||||||
"createApiKey": "https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-api-create-api-key.html",
|
<FormattedMessage
|
||||||
}
|
defaultMessage="API keys not enabled in Elasticsearch"
|
||||||
|
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorTitle"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<EuiCallOut
|
<div
|
||||||
color="danger"
|
className="euiCallOut euiCallOut--danger"
|
||||||
iconType="alert"
|
|
||||||
title={
|
|
||||||
<FormattedMessage
|
|
||||||
defaultMessage="API keys not enabled in Elasticsearch"
|
|
||||||
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorTitle"
|
|
||||||
values={Object {}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="euiCallOut euiCallOut--danger"
|
className="euiCallOutHeader"
|
||||||
>
|
>
|
||||||
<div
|
<EuiIcon
|
||||||
className="euiCallOutHeader"
|
aria-hidden="true"
|
||||||
|
className="euiCallOutHeader__icon"
|
||||||
|
size="m"
|
||||||
|
type="alert"
|
||||||
>
|
>
|
||||||
<EuiIcon
|
<span
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
className="euiCallOutHeader__icon"
|
className="euiCallOutHeader__icon"
|
||||||
|
data-euiicon-type="alert"
|
||||||
size="m"
|
size="m"
|
||||||
type="alert"
|
/>
|
||||||
>
|
</EuiIcon>
|
||||||
<span
|
<span
|
||||||
aria-hidden="true"
|
className="euiCallOutHeader__title"
|
||||||
className="euiCallOutHeader__icon"
|
|
||||||
data-euiicon-type="alert"
|
|
||||||
size="m"
|
|
||||||
/>
|
|
||||||
</EuiIcon>
|
|
||||||
<span
|
|
||||||
className="euiCallOutHeader__title"
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
defaultMessage="API keys not enabled in Elasticsearch"
|
|
||||||
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorTitle"
|
|
||||||
values={Object {}}
|
|
||||||
>
|
|
||||||
API keys not enabled in Elasticsearch
|
|
||||||
</FormattedMessage>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<EuiText
|
|
||||||
size="s"
|
|
||||||
>
|
>
|
||||||
<div
|
<FormattedMessage
|
||||||
className="euiText euiText--small"
|
defaultMessage="API keys not enabled in Elasticsearch"
|
||||||
|
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorTitle"
|
||||||
|
values={Object {}}
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
API keys not enabled in Elasticsearch
|
||||||
defaultMessage="Contact your system administrator and refer to the {link} to enable API keys."
|
</FormattedMessage>
|
||||||
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorDescription"
|
</span>
|
||||||
values={
|
</div>
|
||||||
Object {
|
<EuiText
|
||||||
"link": <EuiLink
|
size="s"
|
||||||
href="https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-settings.html#api-key-service-settings"
|
>
|
||||||
target="_blank"
|
<div
|
||||||
>
|
className="euiText euiText--small"
|
||||||
<FormattedMessage
|
>
|
||||||
defaultMessage="docs"
|
<FormattedMessage
|
||||||
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorLinkText"
|
defaultMessage="Contact your system administrator and refer to the {link} to enable API keys."
|
||||||
values={Object {}}
|
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorDescription"
|
||||||
/>
|
values={
|
||||||
</EuiLink>,
|
Object {
|
||||||
}
|
"link": <EuiLink
|
||||||
}
|
|
||||||
>
|
|
||||||
Contact your system administrator and refer to the
|
|
||||||
<EuiLink
|
|
||||||
href="https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-settings.html#api-key-service-settings"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
className="euiLink euiLink--primary"
|
|
||||||
href="https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-settings.html#api-key-service-settings"
|
href="https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-settings.html#api-key-service-settings"
|
||||||
rel="noopener"
|
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
defaultMessage="docs"
|
defaultMessage="docs"
|
||||||
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorLinkText"
|
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorLinkText"
|
||||||
values={Object {}}
|
values={Object {}}
|
||||||
>
|
/>
|
||||||
docs
|
</EuiLink>,
|
||||||
</FormattedMessage>
|
}
|
||||||
<EuiIcon
|
}
|
||||||
|
>
|
||||||
|
Contact your system administrator and refer to the
|
||||||
|
<EuiLink
|
||||||
|
href="https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-settings.html#api-key-service-settings"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
className="euiLink euiLink--primary"
|
||||||
|
href="https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-settings.html#api-key-service-settings"
|
||||||
|
rel="noopener"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="docs"
|
||||||
|
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorLinkText"
|
||||||
|
values={Object {}}
|
||||||
|
>
|
||||||
|
docs
|
||||||
|
</FormattedMessage>
|
||||||
|
<EuiIcon
|
||||||
|
aria-label="External link"
|
||||||
|
className="euiLink__externalIcon"
|
||||||
|
size="s"
|
||||||
|
type="popout"
|
||||||
|
>
|
||||||
|
<span
|
||||||
aria-label="External link"
|
aria-label="External link"
|
||||||
className="euiLink__externalIcon"
|
className="euiLink__externalIcon"
|
||||||
|
data-euiicon-type="popout"
|
||||||
size="s"
|
size="s"
|
||||||
type="popout"
|
/>
|
||||||
|
</EuiIcon>
|
||||||
|
<EuiScreenReaderOnly>
|
||||||
|
<span
|
||||||
|
className="euiScreenReaderOnly"
|
||||||
>
|
>
|
||||||
<span
|
<EuiI18n
|
||||||
aria-label="External link"
|
default="(opens in a new tab or window)"
|
||||||
className="euiLink__externalIcon"
|
token="euiLink.newTarget.screenReaderOnlyText"
|
||||||
data-euiicon-type="popout"
|
|
||||||
size="s"
|
|
||||||
/>
|
|
||||||
</EuiIcon>
|
|
||||||
<EuiScreenReaderOnly>
|
|
||||||
<span
|
|
||||||
className="euiScreenReaderOnly"
|
|
||||||
>
|
>
|
||||||
<EuiI18n
|
(opens in a new tab or window)
|
||||||
default="(opens in a new tab or window)"
|
</EuiI18n>
|
||||||
token="euiLink.newTarget.screenReaderOnlyText"
|
</span>
|
||||||
>
|
</EuiScreenReaderOnly>
|
||||||
(opens in a new tab or window)
|
</a>
|
||||||
</EuiI18n>
|
</EuiLink>
|
||||||
</span>
|
to enable API keys.
|
||||||
</EuiScreenReaderOnly>
|
</FormattedMessage>
|
||||||
</a>
|
</div>
|
||||||
</EuiLink>
|
</EuiText>
|
||||||
to enable API keys.
|
</div>
|
||||||
</FormattedMessage>
|
</EuiCallOut>
|
||||||
</div>
|
|
||||||
</EuiText>
|
|
||||||
</div>
|
|
||||||
</EuiCallOut>
|
|
||||||
</NotEnabled>
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`APIKeysGridPage renders permission denied if user does not have required permissions 1`] = `
|
exports[`APIKeysGridPage renders permission denied if user does not have required permissions 1`] = `
|
||||||
|
|
|
@ -10,10 +10,10 @@ import { ReactWrapper } from 'enzyme';
|
||||||
import { EuiCallOut } from '@elastic/eui';
|
import { EuiCallOut } from '@elastic/eui';
|
||||||
import type { PublicMethodsOf } from '@kbn/utility-types';
|
import type { PublicMethodsOf } from '@kbn/utility-types';
|
||||||
|
|
||||||
|
import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public';
|
||||||
import { NotEnabled } from './not_enabled';
|
import { NotEnabled } from './not_enabled';
|
||||||
import { PermissionDenied } from './permission_denied';
|
import { PermissionDenied } from './permission_denied';
|
||||||
import { APIKeysAPIClient } from '../api_keys_api_client';
|
import { APIKeysAPIClient } from '../api_keys_api_client';
|
||||||
import { DocumentationLinksService } from '../documentation_links';
|
|
||||||
import { APIKeysGridPage } from './api_keys_grid_page';
|
import { APIKeysGridPage } from './api_keys_grid_page';
|
||||||
|
|
||||||
import { coreMock } from '../../../../../../../src/core/public/mocks';
|
import { coreMock } from '../../../../../../../src/core/public/mocks';
|
||||||
|
@ -66,21 +66,16 @@ describe('APIKeysGridPage', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const coreStart = coreMock.createStart();
|
const coreStart = coreMock.createStart();
|
||||||
|
const renderView = () => {
|
||||||
const getViewProperties = () => {
|
return mountWithIntl(
|
||||||
const { docLinks, notifications, application } = coreStart;
|
<KibanaContextProvider services={coreStart}>
|
||||||
return {
|
<APIKeysGridPage apiKeysAPIClient={apiClientMock} notifications={coreStart.notifications} />
|
||||||
docLinks: new DocumentationLinksService(docLinks),
|
</KibanaContextProvider>
|
||||||
navigateToApp: application.navigateToApp,
|
);
|
||||||
notifications,
|
|
||||||
apiKeysAPIClient: apiClientMock,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
it('renders a loading state when fetching API keys', async () => {
|
it('renders a loading state when fetching API keys', async () => {
|
||||||
const wrapper = mountWithIntl(<APIKeysGridPage {...getViewProperties()} />);
|
expect(renderView().find('[data-test-subj="apiKeysSectionLoading"]')).toHaveLength(1);
|
||||||
|
|
||||||
expect(wrapper.find('[data-test-subj="apiKeysSectionLoading"]')).toHaveLength(1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders a callout when API keys are not enabled', async () => {
|
it('renders a callout when API keys are not enabled', async () => {
|
||||||
|
@ -90,13 +85,12 @@ describe('APIKeysGridPage', () => {
|
||||||
areApiKeysEnabled: false,
|
areApiKeysEnabled: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const wrapper = mountWithIntl(<APIKeysGridPage {...getViewProperties()} />);
|
const wrapper = renderView();
|
||||||
|
|
||||||
await waitForRender(wrapper, (updatedWrapper) => {
|
await waitForRender(wrapper, (updatedWrapper) => {
|
||||||
return updatedWrapper.find(NotEnabled).length > 0;
|
return updatedWrapper.find(NotEnabled).length > 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(wrapper.find(NotEnabled)).toMatchSnapshot();
|
expect(wrapper.find(NotEnabled).find(EuiCallOut)).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders permission denied if user does not have required permissions', async () => {
|
it('renders permission denied if user does not have required permissions', async () => {
|
||||||
|
@ -106,8 +100,7 @@ describe('APIKeysGridPage', () => {
|
||||||
areApiKeysEnabled: true,
|
areApiKeysEnabled: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const wrapper = mountWithIntl(<APIKeysGridPage {...getViewProperties()} />);
|
const wrapper = renderView();
|
||||||
|
|
||||||
await waitForRender(wrapper, (updatedWrapper) => {
|
await waitForRender(wrapper, (updatedWrapper) => {
|
||||||
return updatedWrapper.find(PermissionDenied).length > 0;
|
return updatedWrapper.find(PermissionDenied).length > 0;
|
||||||
});
|
});
|
||||||
|
@ -118,8 +111,7 @@ describe('APIKeysGridPage', () => {
|
||||||
it('renders error callout if error fetching API keys', async () => {
|
it('renders error callout if error fetching API keys', async () => {
|
||||||
apiClientMock.getApiKeys.mockRejectedValue(mock500());
|
apiClientMock.getApiKeys.mockRejectedValue(mock500());
|
||||||
|
|
||||||
const wrapper = mountWithIntl(<APIKeysGridPage {...getViewProperties()} />);
|
const wrapper = renderView();
|
||||||
|
|
||||||
await waitForRender(wrapper, (updatedWrapper) => {
|
await waitForRender(wrapper, (updatedWrapper) => {
|
||||||
return updatedWrapper.find(EuiCallOut).length > 0;
|
return updatedWrapper.find(EuiCallOut).length > 0;
|
||||||
});
|
});
|
||||||
|
@ -130,7 +122,7 @@ describe('APIKeysGridPage', () => {
|
||||||
describe('Admin view', () => {
|
describe('Admin view', () => {
|
||||||
let wrapper: ReactWrapper<any>;
|
let wrapper: ReactWrapper<any>;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper = mountWithIntl(<APIKeysGridPage {...getViewProperties()} />);
|
wrapper = renderView();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders a callout indicating the user is an administrator', async () => {
|
it('renders a callout indicating the user is an administrator', async () => {
|
||||||
|
@ -165,7 +157,7 @@ describe('APIKeysGridPage', () => {
|
||||||
areApiKeysEnabled: true,
|
areApiKeysEnabled: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
wrapper = mountWithIntl(<APIKeysGridPage {...getViewProperties()} />);
|
wrapper = renderView();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does NOT render a callout indicating the user is an administrator', async () => {
|
it('does NOT render a callout indicating the user is an administrator', async () => {
|
||||||
|
|
|
@ -28,11 +28,10 @@ import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import type { PublicMethodsOf } from '@kbn/utility-types';
|
import type { PublicMethodsOf } from '@kbn/utility-types';
|
||||||
import moment from 'moment-timezone';
|
import moment from 'moment-timezone';
|
||||||
import { ApplicationStart, NotificationsStart } from 'src/core/public';
|
import type { NotificationsStart } from 'src/core/public';
|
||||||
import { SectionLoading } from '../../../../../../../src/plugins/es_ui_shared/public';
|
import { SectionLoading } from '../../../../../../../src/plugins/es_ui_shared/public';
|
||||||
import { ApiKey, ApiKeyToInvalidate } from '../../../../common/model';
|
import { ApiKey, ApiKeyToInvalidate } from '../../../../common/model';
|
||||||
import { APIKeysAPIClient } from '../api_keys_api_client';
|
import { APIKeysAPIClient } from '../api_keys_api_client';
|
||||||
import { DocumentationLinksService } from '../documentation_links';
|
|
||||||
import { PermissionDenied } from './permission_denied';
|
import { PermissionDenied } from './permission_denied';
|
||||||
import { EmptyPrompt } from './empty_prompt';
|
import { EmptyPrompt } from './empty_prompt';
|
||||||
import { NotEnabled } from './not_enabled';
|
import { NotEnabled } from './not_enabled';
|
||||||
|
@ -40,9 +39,7 @@ import { InvalidateProvider } from './invalidate_provider';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
notifications: NotificationsStart;
|
notifications: NotificationsStart;
|
||||||
docLinks: DocumentationLinksService;
|
|
||||||
apiKeysAPIClient: PublicMethodsOf<APIKeysAPIClient>;
|
apiKeysAPIClient: PublicMethodsOf<APIKeysAPIClient>;
|
||||||
navigateToApp: ApplicationStart['navigateToApp'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
@ -132,7 +129,7 @@ export class APIKeysGridPage extends Component<Props, State> {
|
||||||
if (!areApiKeysEnabled) {
|
if (!areApiKeysEnabled) {
|
||||||
return (
|
return (
|
||||||
<EuiPageContent>
|
<EuiPageContent>
|
||||||
<NotEnabled docLinks={this.props.docLinks} />
|
<NotEnabled />
|
||||||
</EuiPageContent>
|
</EuiPageContent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -140,11 +137,7 @@ export class APIKeysGridPage extends Component<Props, State> {
|
||||||
if (!isLoadingTable && apiKeys && apiKeys.length === 0) {
|
if (!isLoadingTable && apiKeys && apiKeys.length === 0) {
|
||||||
return (
|
return (
|
||||||
<EuiPageContent>
|
<EuiPageContent>
|
||||||
<EmptyPrompt
|
<EmptyPrompt isAdmin={isAdmin} />
|
||||||
isAdmin={isAdmin}
|
|
||||||
docLinks={this.props.docLinks}
|
|
||||||
navigateToApp={this.props.navigateToApp}
|
|
||||||
/>
|
|
||||||
</EuiPageContent>
|
</EuiPageContent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,72 +5,70 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import { ApplicationStart } from 'kibana/public';
|
|
||||||
|
|
||||||
import { EuiEmptyPrompt, EuiButton, EuiLink } from '@elastic/eui';
|
import { EuiEmptyPrompt, EuiButton, EuiLink } from '@elastic/eui';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import { DocumentationLinksService } from '../../documentation_links';
|
import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isAdmin: boolean;
|
isAdmin: boolean;
|
||||||
docLinks: DocumentationLinksService;
|
|
||||||
navigateToApp: ApplicationStart['navigateToApp'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EmptyPrompt: React.FunctionComponent<Props> = ({
|
export const EmptyPrompt: React.FunctionComponent<Props> = ({ isAdmin }) => {
|
||||||
isAdmin,
|
const { services } = useKibana();
|
||||||
docLinks,
|
const application = services.application!;
|
||||||
navigateToApp,
|
const docLinks = services.docLinks!;
|
||||||
}) => (
|
return (
|
||||||
<EuiEmptyPrompt
|
<EuiEmptyPrompt
|
||||||
iconType="managementApp"
|
iconType="managementApp"
|
||||||
title={
|
title={
|
||||||
<h1 data-test-subj="noApiKeysHeader">
|
<h1 data-test-subj="noApiKeysHeader">
|
||||||
{isAdmin ? (
|
{isAdmin ? (
|
||||||
|
<FormattedMessage
|
||||||
|
id="xpack.security.management.apiKeys.table.emptyPromptAdminTitle"
|
||||||
|
defaultMessage="No API keys"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<FormattedMessage
|
||||||
|
id="xpack.security.management.apiKeys.table.emptyPromptNonAdminTitle"
|
||||||
|
defaultMessage="You don't have any API keys"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</h1>
|
||||||
|
}
|
||||||
|
body={
|
||||||
|
<Fragment>
|
||||||
|
<p>
|
||||||
|
<FormattedMessage
|
||||||
|
id="xpack.security.management.apiKeys.table.emptyPromptDescription"
|
||||||
|
defaultMessage="You can create an {link} from Console."
|
||||||
|
values={{
|
||||||
|
link: (
|
||||||
|
<EuiLink href={docLinks.links.apis.createApiKey} target="_blank">
|
||||||
|
<FormattedMessage
|
||||||
|
id="xpack.security.management.apiKeys.table.emptyPromptDocsLinkMessage"
|
||||||
|
defaultMessage="API key"
|
||||||
|
/>
|
||||||
|
</EuiLink>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</Fragment>
|
||||||
|
}
|
||||||
|
actions={
|
||||||
|
<EuiButton
|
||||||
|
type="primary"
|
||||||
|
onClick={() => application.navigateToApp('dev_tools')}
|
||||||
|
data-test-subj="goToConsoleButton"
|
||||||
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id="xpack.security.management.apiKeys.table.emptyPromptAdminTitle"
|
id="xpack.security.management.apiKeys.table.emptyPromptConsoleButtonMessage"
|
||||||
defaultMessage="No API keys"
|
defaultMessage="Go to Console"
|
||||||
/>
|
/>
|
||||||
) : (
|
</EuiButton>
|
||||||
<FormattedMessage
|
}
|
||||||
id="xpack.security.management.apiKeys.table.emptyPromptNonAdminTitle"
|
data-test-subj="emptyPrompt"
|
||||||
defaultMessage="You don't have any API keys"
|
/>
|
||||||
/>
|
);
|
||||||
)}
|
};
|
||||||
</h1>
|
|
||||||
}
|
|
||||||
body={
|
|
||||||
<Fragment>
|
|
||||||
<p>
|
|
||||||
<FormattedMessage
|
|
||||||
id="xpack.security.management.apiKeys.table.emptyPromptDescription"
|
|
||||||
defaultMessage="You can create an {link} from Console."
|
|
||||||
values={{
|
|
||||||
link: (
|
|
||||||
<EuiLink href={`${docLinks.getCreateApiKeyDocUrl()}`} target="_blank">
|
|
||||||
<FormattedMessage
|
|
||||||
id="xpack.security.management.apiKeys.table.emptyPromptDocsLinkMessage"
|
|
||||||
defaultMessage="API key"
|
|
||||||
/>
|
|
||||||
</EuiLink>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
</Fragment>
|
|
||||||
}
|
|
||||||
actions={
|
|
||||||
<EuiButton
|
|
||||||
type="primary"
|
|
||||||
onClick={() => navigateToApp('dev_tools')}
|
|
||||||
data-test-subj="goToConsoleButton"
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id="xpack.security.management.apiKeys.table.emptyPromptConsoleButtonMessage"
|
|
||||||
defaultMessage="Go to Console"
|
|
||||||
/>
|
|
||||||
</EuiButton>
|
|
||||||
}
|
|
||||||
data-test-subj="emptyPrompt"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
|
@ -7,36 +7,35 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { EuiCallOut, EuiLink } from '@elastic/eui';
|
import { EuiCallOut, EuiLink } from '@elastic/eui';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import { DocumentationLinksService } from '../../documentation_links';
|
import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public';
|
||||||
|
|
||||||
interface Props {
|
export const NotEnabled: React.FunctionComponent = () => {
|
||||||
docLinks: DocumentationLinksService;
|
const docLinks = useKibana().services.docLinks!;
|
||||||
}
|
return (
|
||||||
|
<EuiCallOut
|
||||||
export const NotEnabled: React.FunctionComponent<Props> = ({ docLinks }) => (
|
title={
|
||||||
<EuiCallOut
|
<FormattedMessage
|
||||||
title={
|
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorTitle"
|
||||||
|
defaultMessage="API keys not enabled in Elasticsearch"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
color="danger"
|
||||||
|
iconType="alert"
|
||||||
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorTitle"
|
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorDescription"
|
||||||
defaultMessage="API keys not enabled in Elasticsearch"
|
defaultMessage="Contact your system administrator and refer to the {link} to enable API keys."
|
||||||
|
values={{
|
||||||
|
link: (
|
||||||
|
<EuiLink href={`${docLinks.links.security.apiKeyServiceSettings}`} target="_blank">
|
||||||
|
<FormattedMessage
|
||||||
|
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorLinkText"
|
||||||
|
defaultMessage="docs"
|
||||||
|
/>
|
||||||
|
</EuiLink>
|
||||||
|
),
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
</EuiCallOut>
|
||||||
color="danger"
|
);
|
||||||
iconType="alert"
|
};
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorDescription"
|
|
||||||
defaultMessage="Contact your system administrator and refer to the {link} to enable API keys."
|
|
||||||
values={{
|
|
||||||
link: (
|
|
||||||
<EuiLink href={`${docLinks.getApiKeyServiceSettingsDocUrl()}`} target="_blank">
|
|
||||||
<FormattedMessage
|
|
||||||
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorLinkText"
|
|
||||||
defaultMessage="docs"
|
|
||||||
/>
|
|
||||||
</EuiLink>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</EuiCallOut>
|
|
||||||
);
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ describe('apiKeysManagementApp', () => {
|
||||||
expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: '/', text: 'API Keys' }]);
|
expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: '/', text: 'API Keys' }]);
|
||||||
expect(container).toMatchInlineSnapshot(`
|
expect(container).toMatchInlineSnapshot(`
|
||||||
<div>
|
<div>
|
||||||
Page: {"notifications":{"toasts":{}},"docLinks":{"apiKeySettings":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-settings.html#api-key-service-settings","createApiKey":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-api-create-api-key.html"},"apiKeysAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}}}
|
Page: {"notifications":{"toasts":{}},"apiKeysAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}}}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ import { render, unmountComponentAtNode } from 'react-dom';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { StartServicesAccessor } from 'src/core/public';
|
import { StartServicesAccessor } from 'src/core/public';
|
||||||
import { RegisterManagementAppArgs } from '../../../../../../src/plugins/management/public';
|
import { RegisterManagementAppArgs } from '../../../../../../src/plugins/management/public';
|
||||||
|
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
|
||||||
import { PluginStartDependencies } from '../../plugin';
|
import { PluginStartDependencies } from '../../plugin';
|
||||||
import { DocumentationLinksService } from './documentation_links';
|
|
||||||
|
|
||||||
interface CreateParams {
|
interface CreateParams {
|
||||||
getStartServices: StartServicesAccessor<PluginStartDependencies>;
|
getStartServices: StartServicesAccessor<PluginStartDependencies>;
|
||||||
|
@ -35,25 +35,21 @@ export const apiKeysManagementApp = Object.freeze({
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const [
|
const [[core], { APIKeysGridPage }, { APIKeysAPIClient }] = await Promise.all([
|
||||||
[{ docLinks, http, notifications, i18n: i18nStart, application }],
|
|
||||||
{ APIKeysGridPage },
|
|
||||||
{ APIKeysAPIClient },
|
|
||||||
] = await Promise.all([
|
|
||||||
getStartServices(),
|
getStartServices(),
|
||||||
import('./api_keys_grid'),
|
import('./api_keys_grid'),
|
||||||
import('./api_keys_api_client'),
|
import('./api_keys_api_client'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<i18nStart.Context>
|
<KibanaContextProvider services={core}>
|
||||||
<APIKeysGridPage
|
<core.i18n.Context>
|
||||||
navigateToApp={application.navigateToApp}
|
<APIKeysGridPage
|
||||||
notifications={notifications}
|
notifications={core.notifications}
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
apiKeysAPIClient={new APIKeysAPIClient(core.http)}
|
||||||
apiKeysAPIClient={new APIKeysAPIClient(http)}
|
/>
|
||||||
/>
|
</core.i18n.Context>
|
||||||
</i18nStart.Context>,
|
</KibanaContextProvider>,
|
||||||
element
|
element
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { DocLinksStart } from 'src/core/public';
|
|
||||||
|
|
||||||
export class DocumentationLinksService {
|
|
||||||
private readonly apiKeySettings: string;
|
|
||||||
private readonly createApiKey: string;
|
|
||||||
|
|
||||||
constructor(docLinks: DocLinksStart) {
|
|
||||||
this.apiKeySettings = `${docLinks.links.security.apiKeyServiceSettings}`;
|
|
||||||
this.createApiKey = `${docLinks.links.apis.createApiKey}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getApiKeyServiceSettingsDocUrl() {
|
|
||||||
return `${this.apiKeySettings}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getCreateApiKeyDocUrl() {
|
|
||||||
return `${this.createApiKey}`;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,36 +7,35 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { EuiCallOut, EuiLink } from '@elastic/eui';
|
import { EuiCallOut, EuiLink } from '@elastic/eui';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import { DocumentationLinksService } from '../../documentation_links';
|
import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public';
|
||||||
|
|
||||||
interface Props {
|
export const NoCompatibleRealms: React.FunctionComponent = () => {
|
||||||
docLinks: DocumentationLinksService;
|
const docLinks = useKibana().services.docLinks!;
|
||||||
}
|
return (
|
||||||
|
<EuiCallOut
|
||||||
export const NoCompatibleRealms: React.FunctionComponent<Props> = ({ docLinks }: Props) => (
|
title={
|
||||||
<EuiCallOut
|
<FormattedMessage
|
||||||
title={
|
id="xpack.security.management.roleMappings.noCompatibleRealmsErrorTitle"
|
||||||
|
defaultMessage="No compatible realms are enabled in Elasticsearch"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
color="warning"
|
||||||
|
iconType="alert"
|
||||||
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id="xpack.security.management.roleMappings.noCompatibleRealmsErrorTitle"
|
id="xpack.security.management.roleMappings.noCompatibleRealmsErrorDescription"
|
||||||
defaultMessage="No compatible realms are enabled in Elasticsearch"
|
defaultMessage="Role mappings will not be applied to any users. Contact your system administrator and refer to the {link} for more information."
|
||||||
|
values={{
|
||||||
|
link: (
|
||||||
|
<EuiLink href={docLinks.links.security.mappingRoles} external target="_blank">
|
||||||
|
<FormattedMessage
|
||||||
|
id="xpack.security.management.roleMappings.noCompatibleRealmsErrorLinkText"
|
||||||
|
defaultMessage="docs"
|
||||||
|
/>
|
||||||
|
</EuiLink>
|
||||||
|
),
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
</EuiCallOut>
|
||||||
color="warning"
|
);
|
||||||
iconType="alert"
|
};
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id="xpack.security.management.roleMappings.noCompatibleRealmsErrorDescription"
|
|
||||||
defaultMessage="Role mappings will not be applied to any users. Contact your system administrator and refer to the {link} for more information."
|
|
||||||
values={{
|
|
||||||
link: (
|
|
||||||
<EuiLink href={docLinks.getRoleMappingDocUrl()} external={true} target="_blank">
|
|
||||||
<FormattedMessage
|
|
||||||
id="xpack.security.management.roleMappings.noCompatibleRealmsErrorLinkText"
|
|
||||||
defaultMessage="docs"
|
|
||||||
/>
|
|
||||||
</EuiLink>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</EuiCallOut>
|
|
||||||
);
|
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { DocLinksStart } from 'src/core/public';
|
|
||||||
|
|
||||||
export class DocumentationLinksService {
|
|
||||||
private readonly mappingRoles: string;
|
|
||||||
private readonly createRoleMapping: string;
|
|
||||||
private readonly createRoleMappingTemplates: string;
|
|
||||||
private readonly roleMappingFieldRules: string;
|
|
||||||
|
|
||||||
constructor(docLinks: DocLinksStart) {
|
|
||||||
this.mappingRoles = `${docLinks.links.security.mappingRoles}`;
|
|
||||||
this.createRoleMapping = `${docLinks.links.apis.createRoleMapping}`;
|
|
||||||
this.createRoleMappingTemplates = `${docLinks.links.apis.createRoleMappingTemplates}`;
|
|
||||||
this.roleMappingFieldRules = `${docLinks.links.security.mappingRolesFieldRules}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getRoleMappingDocUrl() {
|
|
||||||
return `${this.mappingRoles}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getRoleMappingAPIDocUrl() {
|
|
||||||
return `${this.createRoleMapping}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getRoleMappingTemplateDocUrl() {
|
|
||||||
return `${this.createRoleMappingTemplates}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getRoleMappingFieldRulesDocUrl() {
|
|
||||||
return `${this.roleMappingFieldRules}`;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -20,7 +20,7 @@ import { VisualRuleEditor } from './rule_editor_panel/visual_rule_editor';
|
||||||
import { JSONRuleEditor } from './rule_editor_panel/json_rule_editor';
|
import { JSONRuleEditor } from './rule_editor_panel/json_rule_editor';
|
||||||
import { RolesAPIClient } from '../../roles';
|
import { RolesAPIClient } from '../../roles';
|
||||||
import { Role } from '../../../../common/model';
|
import { Role } from '../../../../common/model';
|
||||||
import { DocumentationLinksService } from '../documentation_links';
|
import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public';
|
||||||
|
|
||||||
import { coreMock, scopedHistoryMock } from '../../../../../../../src/core/public/mocks';
|
import { coreMock, scopedHistoryMock } from '../../../../../../../src/core/public/mocks';
|
||||||
import { roleMappingsAPIClientMock } from '../role_mappings_api_client.mock';
|
import { roleMappingsAPIClientMock } from '../role_mappings_api_client.mock';
|
||||||
|
@ -31,6 +31,25 @@ describe('EditRoleMappingPage', () => {
|
||||||
const history = scopedHistoryMock.create();
|
const history = scopedHistoryMock.create();
|
||||||
let rolesAPI: PublicMethodsOf<RolesAPIClient>;
|
let rolesAPI: PublicMethodsOf<RolesAPIClient>;
|
||||||
|
|
||||||
|
const renderView = (
|
||||||
|
roleMappingsAPI: ReturnType<typeof roleMappingsAPIClientMock.create>,
|
||||||
|
name?: string
|
||||||
|
) => {
|
||||||
|
const coreStart = coreMock.createStart();
|
||||||
|
return mountWithIntl(
|
||||||
|
<KibanaContextProvider services={coreStart}>
|
||||||
|
<EditRoleMappingPage
|
||||||
|
name={name}
|
||||||
|
roleMappingsAPI={roleMappingsAPI}
|
||||||
|
rolesAPIClient={rolesAPI}
|
||||||
|
notifications={coreStart.notifications}
|
||||||
|
docLinks={coreStart.docLinks}
|
||||||
|
history={history}
|
||||||
|
/>
|
||||||
|
</KibanaContextProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
rolesAPI = rolesAPIClientMock.create();
|
rolesAPI = rolesAPIClientMock.create();
|
||||||
(rolesAPI as jest.Mocked<RolesAPIClient>).getRoles.mockResolvedValue([
|
(rolesAPI as jest.Mocked<RolesAPIClient>).getRoles.mockResolvedValue([
|
||||||
|
@ -50,17 +69,7 @@ describe('EditRoleMappingPage', () => {
|
||||||
canUseStoredScripts: true,
|
canUseStoredScripts: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI);
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<EditRoleMappingPage
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
rolesAPIClient={rolesAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
|
@ -112,18 +121,7 @@ describe('EditRoleMappingPage', () => {
|
||||||
canUseStoredScripts: true,
|
canUseStoredScripts: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI, 'foo');
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<EditRoleMappingPage
|
|
||||||
name="foo"
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
rolesAPIClient={rolesAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
|
@ -161,16 +159,7 @@ describe('EditRoleMappingPage', () => {
|
||||||
hasCompatibleRealms: true,
|
hasCompatibleRealms: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI);
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<EditRoleMappingPage
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
rolesAPIClient={rolesAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
expect(wrapper.find(SectionLoading)).toHaveLength(1);
|
expect(wrapper.find(SectionLoading)).toHaveLength(1);
|
||||||
expect(wrapper.find(PermissionDenied)).toHaveLength(0);
|
expect(wrapper.find(PermissionDenied)).toHaveLength(0);
|
||||||
|
|
||||||
|
@ -189,16 +178,7 @@ describe('EditRoleMappingPage', () => {
|
||||||
hasCompatibleRealms: false,
|
hasCompatibleRealms: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI);
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<EditRoleMappingPage
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
rolesAPIClient={rolesAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
expect(wrapper.find(SectionLoading)).toHaveLength(1);
|
expect(wrapper.find(SectionLoading)).toHaveLength(1);
|
||||||
expect(wrapper.find(NoCompatibleRealms)).toHaveLength(0);
|
expect(wrapper.find(NoCompatibleRealms)).toHaveLength(0);
|
||||||
|
|
||||||
|
@ -226,18 +206,7 @@ describe('EditRoleMappingPage', () => {
|
||||||
canUseStoredScripts: true,
|
canUseStoredScripts: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI, 'foo');
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<EditRoleMappingPage
|
|
||||||
name={'foo'}
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
rolesAPIClient={rolesAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(findTestSubject(wrapper, 'deprecatedRolesAssigned')).toHaveLength(0);
|
expect(findTestSubject(wrapper, 'deprecatedRolesAssigned')).toHaveLength(0);
|
||||||
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
@ -267,18 +236,7 @@ describe('EditRoleMappingPage', () => {
|
||||||
canUseStoredScripts: false,
|
canUseStoredScripts: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI, 'foo');
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<EditRoleMappingPage
|
|
||||||
name={'foo'}
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
rolesAPIClient={rolesAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(findTestSubject(wrapper, 'roleMappingInlineScriptsDisabled')).toHaveLength(0);
|
expect(findTestSubject(wrapper, 'roleMappingInlineScriptsDisabled')).toHaveLength(0);
|
||||||
expect(findTestSubject(wrapper, 'roleMappingStoredScriptsDisabled')).toHaveLength(0);
|
expect(findTestSubject(wrapper, 'roleMappingStoredScriptsDisabled')).toHaveLength(0);
|
||||||
|
|
||||||
|
@ -310,18 +268,7 @@ describe('EditRoleMappingPage', () => {
|
||||||
canUseStoredScripts: true,
|
canUseStoredScripts: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI, 'foo');
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<EditRoleMappingPage
|
|
||||||
name={'foo'}
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
rolesAPIClient={rolesAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(findTestSubject(wrapper, 'roleMappingInlineScriptsDisabled')).toHaveLength(0);
|
expect(findTestSubject(wrapper, 'roleMappingInlineScriptsDisabled')).toHaveLength(0);
|
||||||
expect(findTestSubject(wrapper, 'roleMappingStoredScriptsDisabled')).toHaveLength(0);
|
expect(findTestSubject(wrapper, 'roleMappingStoredScriptsDisabled')).toHaveLength(0);
|
||||||
|
|
||||||
|
@ -365,18 +312,7 @@ describe('EditRoleMappingPage', () => {
|
||||||
canUseStoredScripts: true,
|
canUseStoredScripts: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI, 'foo');
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<EditRoleMappingPage
|
|
||||||
name={'foo'}
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
rolesAPIClient={rolesAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
|
@ -421,18 +357,7 @@ describe('EditRoleMappingPage', () => {
|
||||||
canUseStoredScripts: true,
|
canUseStoredScripts: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI, 'foo');
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<EditRoleMappingPage
|
|
||||||
name={'foo'}
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
rolesAPIClient={rolesAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ import {
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import type { PublicMethodsOf } from '@kbn/utility-types';
|
import type { PublicMethodsOf } from '@kbn/utility-types';
|
||||||
import { NotificationsStart, ScopedHistory } from 'src/core/public';
|
import type { NotificationsStart, ScopedHistory, DocLinksStart } from 'src/core/public';
|
||||||
import { RoleMapping } from '../../../../common/model';
|
import { RoleMapping } from '../../../../common/model';
|
||||||
import { RuleEditorPanel } from './rule_editor_panel';
|
import { RuleEditorPanel } from './rule_editor_panel';
|
||||||
import {
|
import {
|
||||||
|
@ -32,7 +32,6 @@ import {
|
||||||
import { RolesAPIClient } from '../../roles';
|
import { RolesAPIClient } from '../../roles';
|
||||||
import { validateRoleMappingForSave } from './services/role_mapping_validation';
|
import { validateRoleMappingForSave } from './services/role_mapping_validation';
|
||||||
import { MappingInfoPanel } from './mapping_info_panel';
|
import { MappingInfoPanel } from './mapping_info_panel';
|
||||||
import { DocumentationLinksService } from '../documentation_links';
|
|
||||||
import { RoleMappingsAPIClient } from '../role_mappings_api_client';
|
import { RoleMappingsAPIClient } from '../role_mappings_api_client';
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
@ -54,7 +53,7 @@ interface Props {
|
||||||
roleMappingsAPI: PublicMethodsOf<RoleMappingsAPIClient>;
|
roleMappingsAPI: PublicMethodsOf<RoleMappingsAPIClient>;
|
||||||
rolesAPIClient: PublicMethodsOf<RolesAPIClient>;
|
rolesAPIClient: PublicMethodsOf<RolesAPIClient>;
|
||||||
notifications: NotificationsStart;
|
notifications: NotificationsStart;
|
||||||
docLinks: DocumentationLinksService;
|
docLinks: DocLinksStart;
|
||||||
history: ScopedHistory;
|
history: ScopedHistory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +162,7 @@ export class EditRoleMappingPage extends Component<Props, State> {
|
||||||
values={{
|
values={{
|
||||||
learnMoreLink: (
|
learnMoreLink: (
|
||||||
<EuiLink
|
<EuiLink
|
||||||
href={this.props.docLinks.getRoleMappingDocUrl()}
|
href={this.props.docLinks.links.security.mappingRoles}
|
||||||
external={true}
|
external={true}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
|
@ -180,7 +179,7 @@ export class EditRoleMappingPage extends Component<Props, State> {
|
||||||
{!this.state.hasCompatibleRealms && (
|
{!this.state.hasCompatibleRealms && (
|
||||||
<>
|
<>
|
||||||
<EuiSpacer size="s" />
|
<EuiSpacer size="s" />
|
||||||
<NoCompatibleRealms docLinks={this.props.docLinks} />
|
<NoCompatibleRealms />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
|
|
@ -10,7 +10,6 @@ import { mountWithIntl } from '@kbn/test/jest';
|
||||||
import { findTestSubject } from '@kbn/test/jest';
|
import { findTestSubject } from '@kbn/test/jest';
|
||||||
import { Role, RoleMapping } from '../../../../../common/model';
|
import { Role, RoleMapping } from '../../../../../common/model';
|
||||||
import { RolesAPIClient } from '../../../roles';
|
import { RolesAPIClient } from '../../../roles';
|
||||||
import { DocumentationLinksService } from '../../documentation_links';
|
|
||||||
import { RoleSelector } from '../role_selector';
|
import { RoleSelector } from '../role_selector';
|
||||||
import { RoleTemplateEditor } from '../role_selector/role_template_editor';
|
import { RoleTemplateEditor } from '../role_selector/role_template_editor';
|
||||||
import { MappingInfoPanel } from '.';
|
import { MappingInfoPanel } from '.';
|
||||||
|
@ -39,7 +38,7 @@ describe('MappingInfoPanel', () => {
|
||||||
metadata: {},
|
metadata: {},
|
||||||
} as RoleMapping,
|
} as RoleMapping,
|
||||||
mode: 'create',
|
mode: 'create',
|
||||||
docLinks: new DocumentationLinksService(coreMock.createStart().docLinks),
|
docLinks: coreMock.createStart().docLinks,
|
||||||
rolesAPIClient: rolesAPI,
|
rolesAPIClient: rolesAPI,
|
||||||
} as MappingInfoPanel['props'];
|
} as MappingInfoPanel['props'];
|
||||||
|
|
||||||
|
@ -86,7 +85,7 @@ describe('MappingInfoPanel', () => {
|
||||||
metadata: {},
|
metadata: {},
|
||||||
} as RoleMapping,
|
} as RoleMapping,
|
||||||
mode: 'edit',
|
mode: 'edit',
|
||||||
docLinks: new DocumentationLinksService(coreMock.createStart().docLinks),
|
docLinks: coreMock.createStart().docLinks,
|
||||||
rolesAPIClient: rolesAPI,
|
rolesAPIClient: rolesAPI,
|
||||||
} as MappingInfoPanel['props'];
|
} as MappingInfoPanel['props'];
|
||||||
|
|
||||||
|
@ -112,7 +111,7 @@ describe('MappingInfoPanel', () => {
|
||||||
canUseInlineScripts: true,
|
canUseInlineScripts: true,
|
||||||
canUseStoredScripts: false,
|
canUseStoredScripts: false,
|
||||||
validateForm: false,
|
validateForm: false,
|
||||||
docLinks: new DocumentationLinksService(coreMock.createStart().docLinks),
|
docLinks: coreMock.createStart().docLinks,
|
||||||
rolesAPIClient: rolesAPI,
|
rolesAPIClient: rolesAPI,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -153,7 +152,7 @@ describe('MappingInfoPanel', () => {
|
||||||
canUseInlineScripts: false,
|
canUseInlineScripts: false,
|
||||||
canUseStoredScripts: true,
|
canUseStoredScripts: true,
|
||||||
validateForm: false,
|
validateForm: false,
|
||||||
docLinks: new DocumentationLinksService(coreMock.createStart().docLinks),
|
docLinks: coreMock.createStart().docLinks,
|
||||||
rolesAPIClient: rolesAPI,
|
rolesAPIClient: rolesAPI,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -194,7 +193,7 @@ describe('MappingInfoPanel', () => {
|
||||||
canUseInlineScripts: false,
|
canUseInlineScripts: false,
|
||||||
canUseStoredScripts: false,
|
canUseStoredScripts: false,
|
||||||
validateForm: false,
|
validateForm: false,
|
||||||
docLinks: new DocumentationLinksService(coreMock.createStart().docLinks),
|
docLinks: coreMock.createStart().docLinks,
|
||||||
rolesAPIClient: rolesAPI,
|
rolesAPIClient: rolesAPI,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -219,7 +218,7 @@ describe('MappingInfoPanel', () => {
|
||||||
metadata: {},
|
metadata: {},
|
||||||
} as RoleMapping,
|
} as RoleMapping,
|
||||||
mode: 'edit',
|
mode: 'edit',
|
||||||
docLinks: new DocumentationLinksService(coreMock.createStart().docLinks),
|
docLinks: coreMock.createStart().docLinks,
|
||||||
rolesAPIClient: rolesAPI,
|
rolesAPIClient: rolesAPI,
|
||||||
} as MappingInfoPanel['props'];
|
} as MappingInfoPanel['props'];
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import {
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import type { PublicMethodsOf } from '@kbn/utility-types';
|
import type { PublicMethodsOf } from '@kbn/utility-types';
|
||||||
|
import type { DocLinksStart } from 'src/core/public';
|
||||||
import { RoleMapping } from '../../../../../common/model';
|
import { RoleMapping } from '../../../../../common/model';
|
||||||
import { RolesAPIClient } from '../../../roles';
|
import { RolesAPIClient } from '../../../roles';
|
||||||
import {
|
import {
|
||||||
|
@ -28,7 +29,6 @@ import {
|
||||||
validateRoleMappingRoleTemplates,
|
validateRoleMappingRoleTemplates,
|
||||||
} from '../services/role_mapping_validation';
|
} from '../services/role_mapping_validation';
|
||||||
import { RoleSelector } from '../role_selector';
|
import { RoleSelector } from '../role_selector';
|
||||||
import { DocumentationLinksService } from '../../documentation_links';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
roleMapping: RoleMapping;
|
roleMapping: RoleMapping;
|
||||||
|
@ -38,7 +38,7 @@ interface Props {
|
||||||
canUseInlineScripts: boolean;
|
canUseInlineScripts: boolean;
|
||||||
canUseStoredScripts: boolean;
|
canUseStoredScripts: boolean;
|
||||||
rolesAPIClient: PublicMethodsOf<RolesAPIClient>;
|
rolesAPIClient: PublicMethodsOf<RolesAPIClient>;
|
||||||
docLinks: DocumentationLinksService;
|
docLinks: DocLinksStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
@ -205,7 +205,7 @@ export class MappingInfoPanel extends Component<Props, State> {
|
||||||
defaultMessage="Create templates that describe the roles to assign to your users."
|
defaultMessage="Create templates that describe the roles to assign to your users."
|
||||||
/>{' '}
|
/>{' '}
|
||||||
<EuiLink
|
<EuiLink
|
||||||
href={this.props.docLinks.getRoleMappingTemplateDocUrl()}
|
href={this.props.docLinks.links.apis.createRoleMappingTemplates}
|
||||||
external={true}
|
external={true}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
|
|
|
@ -17,20 +17,24 @@ import { act } from 'react-dom/test-utils';
|
||||||
import { mountWithIntl } from '@kbn/test/jest';
|
import { mountWithIntl } from '@kbn/test/jest';
|
||||||
import { JSONRuleEditor } from './json_rule_editor';
|
import { JSONRuleEditor } from './json_rule_editor';
|
||||||
import { EuiCodeEditor } from '@elastic/eui';
|
import { EuiCodeEditor } from '@elastic/eui';
|
||||||
|
import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public';
|
||||||
import { AllRule, AnyRule, FieldRule, ExceptAnyRule, ExceptAllRule } from '../../model';
|
import { AllRule, AnyRule, FieldRule, ExceptAnyRule, ExceptAllRule } from '../../model';
|
||||||
import { DocumentationLinksService } from '../../documentation_links';
|
|
||||||
|
|
||||||
import { coreMock } from '../../../../../../../../src/core/public/mocks';
|
import { coreMock } from '../../../../../../../../src/core/public/mocks';
|
||||||
|
|
||||||
describe('JSONRuleEditor', () => {
|
describe('JSONRuleEditor', () => {
|
||||||
|
const renderView = (props: React.ComponentProps<typeof JSONRuleEditor>) => {
|
||||||
|
const coreStart = coreMock.createStart();
|
||||||
|
return mountWithIntl(
|
||||||
|
<KibanaContextProvider services={coreStart}>
|
||||||
|
<JSONRuleEditor {...props} />
|
||||||
|
</KibanaContextProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
it('renders an empty rule set', () => {
|
it('renders an empty rule set', () => {
|
||||||
const props = {
|
const props = { rules: null, onChange: jest.fn(), onValidityChange: jest.fn() };
|
||||||
rules: null,
|
const wrapper = renderView(props);
|
||||||
onChange: jest.fn(),
|
|
||||||
onValidityChange: jest.fn(),
|
|
||||||
docLinks: new DocumentationLinksService(coreMock.createStart().docLinks),
|
|
||||||
};
|
|
||||||
const wrapper = mountWithIntl(<JSONRuleEditor {...props} />);
|
|
||||||
|
|
||||||
expect(props.onChange).not.toHaveBeenCalled();
|
expect(props.onChange).not.toHaveBeenCalled();
|
||||||
expect(props.onValidityChange).not.toHaveBeenCalled();
|
expect(props.onValidityChange).not.toHaveBeenCalled();
|
||||||
|
@ -50,9 +54,8 @@ describe('JSONRuleEditor', () => {
|
||||||
]),
|
]),
|
||||||
onChange: jest.fn(),
|
onChange: jest.fn(),
|
||||||
onValidityChange: jest.fn(),
|
onValidityChange: jest.fn(),
|
||||||
docLinks: new DocumentationLinksService(coreMock.createStart().docLinks),
|
|
||||||
};
|
};
|
||||||
const wrapper = mountWithIntl(<JSONRuleEditor {...props} />);
|
const wrapper = renderView(props);
|
||||||
|
|
||||||
const { value } = wrapper.find(EuiCodeEditor).props();
|
const { value } = wrapper.find(EuiCodeEditor).props();
|
||||||
expect(JSON.parse(value as string)).toEqual({
|
expect(JSON.parse(value as string)).toEqual({
|
||||||
|
@ -80,13 +83,8 @@ describe('JSONRuleEditor', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('notifies when input contains invalid JSON', () => {
|
it('notifies when input contains invalid JSON', () => {
|
||||||
const props = {
|
const props = { rules: null, onChange: jest.fn(), onValidityChange: jest.fn() };
|
||||||
rules: null,
|
const wrapper = renderView(props);
|
||||||
onChange: jest.fn(),
|
|
||||||
onValidityChange: jest.fn(),
|
|
||||||
docLinks: new DocumentationLinksService(coreMock.createStart().docLinks),
|
|
||||||
};
|
|
||||||
const wrapper = mountWithIntl(<JSONRuleEditor {...props} />);
|
|
||||||
|
|
||||||
const allRule = JSON.stringify(new AllRule().toRaw());
|
const allRule = JSON.stringify(new AllRule().toRaw());
|
||||||
act(() => {
|
act(() => {
|
||||||
|
@ -99,13 +97,8 @@ describe('JSONRuleEditor', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('notifies when input contains an invalid rule set, even if it is valid JSON', () => {
|
it('notifies when input contains an invalid rule set, even if it is valid JSON', () => {
|
||||||
const props = {
|
const props = { rules: null, onChange: jest.fn(), onValidityChange: jest.fn() };
|
||||||
rules: null,
|
const wrapper = renderView(props);
|
||||||
onChange: jest.fn(),
|
|
||||||
onValidityChange: jest.fn(),
|
|
||||||
docLinks: new DocumentationLinksService(coreMock.createStart().docLinks),
|
|
||||||
};
|
|
||||||
const wrapper = mountWithIntl(<JSONRuleEditor {...props} />);
|
|
||||||
|
|
||||||
const invalidRule = JSON.stringify({
|
const invalidRule = JSON.stringify({
|
||||||
all: [
|
all: [
|
||||||
|
@ -127,13 +120,8 @@ describe('JSONRuleEditor', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fires onChange when a valid rule set is provided after being previously invalidated', () => {
|
it('fires onChange when a valid rule set is provided after being previously invalidated', () => {
|
||||||
const props = {
|
const props = { rules: null, onChange: jest.fn(), onValidityChange: jest.fn() };
|
||||||
rules: null,
|
const wrapper = renderView(props);
|
||||||
onChange: jest.fn(),
|
|
||||||
onValidityChange: jest.fn(),
|
|
||||||
docLinks: new DocumentationLinksService(coreMock.createStart().docLinks),
|
|
||||||
};
|
|
||||||
const wrapper = mountWithIntl(<JSONRuleEditor {...props} />);
|
|
||||||
|
|
||||||
const allRule = JSON.stringify(new AllRule().toRaw());
|
const allRule = JSON.stringify(new AllRule().toRaw());
|
||||||
act(() => {
|
act(() => {
|
||||||
|
|
|
@ -11,17 +11,17 @@ import 'brace/theme/github';
|
||||||
import { EuiCodeEditor, EuiFormRow, EuiButton, EuiSpacer, EuiLink, EuiText } from '@elastic/eui';
|
import { EuiCodeEditor, EuiFormRow, EuiButton, EuiSpacer, EuiLink, EuiText } from '@elastic/eui';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { DocumentationLinksService } from '../../documentation_links';
|
|
||||||
import { Rule, RuleBuilderError, generateRulesFromRaw } from '../../model';
|
import { Rule, RuleBuilderError, generateRulesFromRaw } from '../../model';
|
||||||
|
import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
rules: Rule | null;
|
rules: Rule | null;
|
||||||
onChange: (updatedRules: Rule | null) => void;
|
onChange: (updatedRules: Rule | null) => void;
|
||||||
onValidityChange: (isValid: boolean) => void;
|
onValidityChange: (isValid: boolean) => void;
|
||||||
docLinks: DocumentationLinksService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const JSONRuleEditor = (props: Props) => {
|
export const JSONRuleEditor = (props: Props) => {
|
||||||
|
const docLinks = useKibana().services.docLinks!;
|
||||||
const [rawRules, setRawRules] = useState(
|
const [rawRules, setRawRules] = useState(
|
||||||
JSON.stringify(props.rules ? props.rules.toRaw() : {}, null, 2)
|
JSON.stringify(props.rules ? props.rules.toRaw() : {}, null, 2)
|
||||||
);
|
);
|
||||||
|
@ -108,7 +108,7 @@ export const JSONRuleEditor = (props: Props) => {
|
||||||
values={{
|
values={{
|
||||||
roleMappingAPI: (
|
roleMappingAPI: (
|
||||||
<EuiLink
|
<EuiLink
|
||||||
href={props.docLinks.getRoleMappingAPIDocUrl()}
|
href={docLinks.links.apis.createRoleMapping}
|
||||||
external={true}
|
external={true}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
|
|
|
@ -17,20 +17,28 @@ import '@kbn/test/target/jest/utils/stub_web_worker';
|
||||||
|
|
||||||
import { AllRule, FieldRule } from '../../model';
|
import { AllRule, FieldRule } from '../../model';
|
||||||
import { EuiErrorBoundary } from '@elastic/eui';
|
import { EuiErrorBoundary } from '@elastic/eui';
|
||||||
import { DocumentationLinksService } from '../../documentation_links';
|
import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public';
|
||||||
|
|
||||||
import { coreMock } from '../../../../../../../../src/core/public/mocks';
|
import { coreMock } from '../../../../../../../../src/core/public/mocks';
|
||||||
|
|
||||||
describe('RuleEditorPanel', () => {
|
describe('RuleEditorPanel', () => {
|
||||||
|
const renderView = (props: Omit<React.ComponentProps<typeof RuleEditorPanel>, 'docLinks'>) => {
|
||||||
|
const coreStart = coreMock.createStart();
|
||||||
|
const viewProps = { ...props, docLinks: coreStart.docLinks };
|
||||||
|
return mountWithIntl(
|
||||||
|
<KibanaContextProvider services={coreStart}>
|
||||||
|
<RuleEditorPanel {...viewProps} />
|
||||||
|
</KibanaContextProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
it('renders the visual editor when no rules are defined', () => {
|
it('renders the visual editor when no rules are defined', () => {
|
||||||
const props = {
|
const props = {
|
||||||
rawRules: {},
|
rawRules: {},
|
||||||
onChange: jest.fn(),
|
onChange: jest.fn(),
|
||||||
onValidityChange: jest.fn(),
|
onValidityChange: jest.fn(),
|
||||||
validateForm: false,
|
validateForm: false,
|
||||||
docLinks: new DocumentationLinksService(coreMock.createStart().docLinks),
|
|
||||||
};
|
};
|
||||||
const wrapper = mountWithIntl(<RuleEditorPanel {...props} />);
|
const wrapper = renderView(props);
|
||||||
expect(wrapper.find(VisualRuleEditor)).toHaveLength(1);
|
expect(wrapper.find(VisualRuleEditor)).toHaveLength(1);
|
||||||
expect(wrapper.find(JSONRuleEditor)).toHaveLength(0);
|
expect(wrapper.find(JSONRuleEditor)).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
@ -49,9 +57,9 @@ describe('RuleEditorPanel', () => {
|
||||||
onChange: jest.fn(),
|
onChange: jest.fn(),
|
||||||
onValidityChange: jest.fn(),
|
onValidityChange: jest.fn(),
|
||||||
validateForm: false,
|
validateForm: false,
|
||||||
docLinks: new DocumentationLinksService(coreMock.createStart().docLinks),
|
docLinks: coreMock.createStart().docLinks,
|
||||||
};
|
};
|
||||||
const wrapper = mountWithIntl(<RuleEditorPanel {...props} />);
|
const wrapper = renderView(props);
|
||||||
expect(wrapper.find(VisualRuleEditor)).toHaveLength(1);
|
expect(wrapper.find(VisualRuleEditor)).toHaveLength(1);
|
||||||
expect(wrapper.find(JSONRuleEditor)).toHaveLength(0);
|
expect(wrapper.find(JSONRuleEditor)).toHaveLength(0);
|
||||||
|
|
||||||
|
@ -73,9 +81,8 @@ describe('RuleEditorPanel', () => {
|
||||||
onChange: jest.fn(),
|
onChange: jest.fn(),
|
||||||
onValidityChange: jest.fn(),
|
onValidityChange: jest.fn(),
|
||||||
validateForm: false,
|
validateForm: false,
|
||||||
docLinks: new DocumentationLinksService(coreMock.createStart().docLinks),
|
|
||||||
};
|
};
|
||||||
const wrapper = mountWithIntl(<RuleEditorPanel {...props} />);
|
const wrapper = renderView(props);
|
||||||
|
|
||||||
findTestSubject(wrapper, 'roleMappingsJSONRuleEditorButton').simulate('click');
|
findTestSubject(wrapper, 'roleMappingsJSONRuleEditorButton').simulate('click');
|
||||||
|
|
||||||
|
@ -109,9 +116,8 @@ describe('RuleEditorPanel', () => {
|
||||||
onChange: jest.fn(),
|
onChange: jest.fn(),
|
||||||
onValidityChange: jest.fn(),
|
onValidityChange: jest.fn(),
|
||||||
validateForm: false,
|
validateForm: false,
|
||||||
docLinks: new DocumentationLinksService(coreMock.createStart().docLinks),
|
|
||||||
};
|
};
|
||||||
const wrapper = mountWithIntl(<RuleEditorPanel {...props} />);
|
const wrapper = renderView(props);
|
||||||
|
|
||||||
wrapper.find(VisualRuleEditor).simulateError(new Error('Something awful happened here.'));
|
wrapper.find(VisualRuleEditor).simulateError(new Error('Something awful happened here.'));
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,12 @@ import {
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import type { DocLinksStart } from 'src/core/public';
|
||||||
import { RoleMapping } from '../../../../../common/model';
|
import { RoleMapping } from '../../../../../common/model';
|
||||||
import { VisualRuleEditor } from './visual_rule_editor';
|
import { VisualRuleEditor } from './visual_rule_editor';
|
||||||
import { JSONRuleEditor } from './json_rule_editor';
|
import { JSONRuleEditor } from './json_rule_editor';
|
||||||
import { VISUAL_MAX_RULE_DEPTH } from '../services/role_mapping_constants';
|
import { VISUAL_MAX_RULE_DEPTH } from '../services/role_mapping_constants';
|
||||||
import { Rule, generateRulesFromRaw } from '../../model';
|
import { Rule, generateRulesFromRaw } from '../../model';
|
||||||
import { DocumentationLinksService } from '../../documentation_links';
|
|
||||||
import { validateRoleMappingRules } from '../services/role_mapping_validation';
|
import { validateRoleMappingRules } from '../services/role_mapping_validation';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
@ -35,7 +35,7 @@ interface Props {
|
||||||
onChange: (rawRules: RoleMapping['rules']) => void;
|
onChange: (rawRules: RoleMapping['rules']) => void;
|
||||||
onValidityChange: (isValid: boolean) => void;
|
onValidityChange: (isValid: boolean) => void;
|
||||||
validateForm: boolean;
|
validateForm: boolean;
|
||||||
docLinks: DocumentationLinksService;
|
docLinks: DocLinksStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
@ -92,7 +92,7 @@ export class RuleEditorPanel extends Component<Props, State> {
|
||||||
values={{
|
values={{
|
||||||
learnMoreLink: (
|
learnMoreLink: (
|
||||||
<EuiLink
|
<EuiLink
|
||||||
href={this.props.docLinks.getRoleMappingFieldRulesDocUrl()}
|
href={this.props.docLinks.links.security.mappingRolesFieldRules}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
external={true}
|
external={true}
|
||||||
>
|
>
|
||||||
|
@ -215,7 +215,6 @@ export class RuleEditorPanel extends Component<Props, State> {
|
||||||
rules={this.state.rules}
|
rules={this.state.rules}
|
||||||
onChange={this.onRuleChange}
|
onChange={this.onRuleChange}
|
||||||
onValidityChange={this.onValidityChange}
|
onValidityChange={this.onValidityChange}
|
||||||
docLinks={this.props.docLinks}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { EmptyPrompt } from './empty_prompt';
|
||||||
import { findTestSubject } from '@kbn/test/jest';
|
import { findTestSubject } from '@kbn/test/jest';
|
||||||
import { EuiLink } from '@elastic/eui';
|
import { EuiLink } from '@elastic/eui';
|
||||||
import { act } from '@testing-library/react';
|
import { act } from '@testing-library/react';
|
||||||
import { DocumentationLinksService } from '../documentation_links';
|
import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public';
|
||||||
|
|
||||||
import { coreMock, scopedHistoryMock } from '../../../../../../../src/core/public/mocks';
|
import { coreMock, scopedHistoryMock } from '../../../../../../../src/core/public/mocks';
|
||||||
import { roleMappingsAPIClientMock } from '../role_mappings_api_client.mock';
|
import { roleMappingsAPIClientMock } from '../role_mappings_api_client.mock';
|
||||||
|
@ -23,6 +23,24 @@ describe('RoleMappingsGridPage', () => {
|
||||||
let history: ScopedHistory;
|
let history: ScopedHistory;
|
||||||
let coreStart: CoreStart;
|
let coreStart: CoreStart;
|
||||||
|
|
||||||
|
const renderView = (
|
||||||
|
roleMappingsAPI: ReturnType<typeof roleMappingsAPIClientMock.create>,
|
||||||
|
rolesAPI: ReturnType<typeof rolesAPIClientMock.create> = rolesAPIClientMock.create()
|
||||||
|
) => {
|
||||||
|
return mountWithIntl(
|
||||||
|
<KibanaContextProvider services={coreStart}>
|
||||||
|
<RoleMappingsGridPage
|
||||||
|
rolesAPIClient={rolesAPI}
|
||||||
|
roleMappingsAPI={roleMappingsAPI}
|
||||||
|
notifications={coreStart.notifications}
|
||||||
|
docLinks={coreStart.docLinks}
|
||||||
|
history={history}
|
||||||
|
navigateToApp={coreStart.application.navigateToApp}
|
||||||
|
/>
|
||||||
|
</KibanaContextProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
history = scopedHistoryMock.create();
|
history = scopedHistoryMock.create();
|
||||||
coreStart = coreMock.createStart();
|
coreStart = coreMock.createStart();
|
||||||
|
@ -36,17 +54,7 @@ describe('RoleMappingsGridPage', () => {
|
||||||
hasCompatibleRealms: true,
|
hasCompatibleRealms: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI);
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<RoleMappingsGridPage
|
|
||||||
rolesAPIClient={rolesAPIClientMock.create()}
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
navigateToApp={coreStart.application.navigateToApp}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
expect(wrapper.find(SectionLoading)).toHaveLength(1);
|
expect(wrapper.find(SectionLoading)).toHaveLength(1);
|
||||||
expect(wrapper.find(EmptyPrompt)).toHaveLength(0);
|
expect(wrapper.find(EmptyPrompt)).toHaveLength(0);
|
||||||
|
|
||||||
|
@ -65,17 +73,7 @@ describe('RoleMappingsGridPage', () => {
|
||||||
hasCompatibleRealms: true,
|
hasCompatibleRealms: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI);
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<RoleMappingsGridPage
|
|
||||||
rolesAPIClient={rolesAPIClientMock.create()}
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
navigateToApp={coreStart.application.navigateToApp}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
expect(wrapper.find(SectionLoading)).toHaveLength(1);
|
expect(wrapper.find(SectionLoading)).toHaveLength(1);
|
||||||
expect(wrapper.find(PermissionDenied)).toHaveLength(0);
|
expect(wrapper.find(PermissionDenied)).toHaveLength(0);
|
||||||
|
|
||||||
|
@ -102,17 +100,7 @@ describe('RoleMappingsGridPage', () => {
|
||||||
hasCompatibleRealms: false,
|
hasCompatibleRealms: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI);
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<RoleMappingsGridPage
|
|
||||||
rolesAPIClient={rolesAPIClientMock.create()}
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
navigateToApp={coreStart.application.navigateToApp}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
expect(wrapper.find(SectionLoading)).toHaveLength(1);
|
expect(wrapper.find(SectionLoading)).toHaveLength(1);
|
||||||
expect(wrapper.find(NoCompatibleRealms)).toHaveLength(0);
|
expect(wrapper.find(NoCompatibleRealms)).toHaveLength(0);
|
||||||
|
|
||||||
|
@ -138,17 +126,7 @@ describe('RoleMappingsGridPage', () => {
|
||||||
hasCompatibleRealms: true,
|
hasCompatibleRealms: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI);
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<RoleMappingsGridPage
|
|
||||||
rolesAPIClient={rolesAPIClientMock.create()}
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
navigateToApp={coreStart.application.navigateToApp}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
|
@ -172,17 +150,7 @@ describe('RoleMappingsGridPage', () => {
|
||||||
hasCompatibleRealms: true,
|
hasCompatibleRealms: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI);
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<RoleMappingsGridPage
|
|
||||||
rolesAPIClient={rolesAPIClientMock.create()}
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
navigateToApp={coreStart.application.navigateToApp}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
|
@ -212,17 +180,7 @@ describe('RoleMappingsGridPage', () => {
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI);
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<RoleMappingsGridPage
|
|
||||||
rolesAPIClient={rolesAPIClientMock.create()}
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
navigateToApp={coreStart.application.navigateToApp}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
|
@ -275,17 +233,7 @@ describe('RoleMappingsGridPage', () => {
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const { docLinks, notifications } = coreMock.createStart();
|
const wrapper = renderView(roleMappingsAPI, roleAPIClient);
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<RoleMappingsGridPage
|
|
||||||
rolesAPIClient={roleAPIClient}
|
|
||||||
roleMappingsAPI={roleMappingsAPI}
|
|
||||||
notifications={notifications}
|
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
|
||||||
history={history}
|
|
||||||
navigateToApp={coreStart.application.navigateToApp}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,12 @@ import {
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import type { PublicMethodsOf } from '@kbn/utility-types';
|
import type { PublicMethodsOf } from '@kbn/utility-types';
|
||||||
import { NotificationsStart, ApplicationStart, ScopedHistory } from 'src/core/public';
|
import type {
|
||||||
|
NotificationsStart,
|
||||||
|
ApplicationStart,
|
||||||
|
DocLinksStart,
|
||||||
|
ScopedHistory,
|
||||||
|
} from 'src/core/public';
|
||||||
import { RoleMapping, Role } from '../../../../common/model';
|
import { RoleMapping, Role } from '../../../../common/model';
|
||||||
import { EmptyPrompt } from './empty_prompt';
|
import { EmptyPrompt } from './empty_prompt';
|
||||||
import {
|
import {
|
||||||
|
@ -35,7 +40,6 @@ import {
|
||||||
SectionLoading,
|
SectionLoading,
|
||||||
} from '../components';
|
} from '../components';
|
||||||
import { EDIT_ROLE_MAPPING_PATH, getEditRoleMappingHref } from '../../management_urls';
|
import { EDIT_ROLE_MAPPING_PATH, getEditRoleMappingHref } from '../../management_urls';
|
||||||
import { DocumentationLinksService } from '../documentation_links';
|
|
||||||
import { RoleMappingsAPIClient } from '../role_mappings_api_client';
|
import { RoleMappingsAPIClient } from '../role_mappings_api_client';
|
||||||
import { RoleTableDisplay } from '../../role_table_display';
|
import { RoleTableDisplay } from '../../role_table_display';
|
||||||
import { RolesAPIClient } from '../../roles';
|
import { RolesAPIClient } from '../../roles';
|
||||||
|
@ -46,7 +50,7 @@ interface Props {
|
||||||
rolesAPIClient: PublicMethodsOf<RolesAPIClient>;
|
rolesAPIClient: PublicMethodsOf<RolesAPIClient>;
|
||||||
roleMappingsAPI: PublicMethodsOf<RoleMappingsAPIClient>;
|
roleMappingsAPI: PublicMethodsOf<RoleMappingsAPIClient>;
|
||||||
notifications: NotificationsStart;
|
notifications: NotificationsStart;
|
||||||
docLinks: DocumentationLinksService;
|
docLinks: DocLinksStart;
|
||||||
history: ScopedHistory;
|
history: ScopedHistory;
|
||||||
navigateToApp: ApplicationStart['navigateToApp'];
|
navigateToApp: ApplicationStart['navigateToApp'];
|
||||||
}
|
}
|
||||||
|
@ -148,7 +152,7 @@ export class RoleMappingsGridPage extends Component<Props, State> {
|
||||||
values={{
|
values={{
|
||||||
learnMoreLink: (
|
learnMoreLink: (
|
||||||
<EuiLink
|
<EuiLink
|
||||||
href={this.props.docLinks.getRoleMappingDocUrl()}
|
href={this.props.docLinks.links.security.mappingRoles}
|
||||||
external={true}
|
external={true}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
|
@ -179,7 +183,7 @@ export class RoleMappingsGridPage extends Component<Props, State> {
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{!this.state.hasCompatibleRealms && (
|
{!this.state.hasCompatibleRealms && (
|
||||||
<>
|
<>
|
||||||
<NoCompatibleRealms docLinks={this.props.docLinks} />
|
<NoCompatibleRealms />
|
||||||
<EuiSpacer />
|
<EuiSpacer />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -5,11 +5,21 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
jest.mock('./role_mappings_grid', () => ({
|
jest.mock('./role_mappings_grid', () => ({
|
||||||
RoleMappingsGridPage: (props: any) => `Role Mappings Page: ${JSON.stringify(props)}`,
|
RoleMappingsGridPage: (props: any) =>
|
||||||
|
// `docLinks` object is too big to include into test snapshot, so we just check its existence.
|
||||||
|
`Role Mappings Page: ${JSON.stringify({
|
||||||
|
...props,
|
||||||
|
docLinks: props.docLinks ? {} : undefined,
|
||||||
|
})}`,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('./edit_role_mapping', () => ({
|
jest.mock('./edit_role_mapping', () => ({
|
||||||
EditRoleMappingPage: (props: any) => `Role Mapping Edit Page: ${JSON.stringify(props)}`,
|
EditRoleMappingPage: (props: any) =>
|
||||||
|
// `docLinks` object is too big to include into test snapshot, so we just check its existence.
|
||||||
|
`Role Mapping Edit Page: ${JSON.stringify({
|
||||||
|
...props,
|
||||||
|
docLinks: props.docLinks ? {} : undefined,
|
||||||
|
})}`,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { roleMappingsManagementApp } from './role_mappings_management_app';
|
import { roleMappingsManagementApp } from './role_mappings_management_app';
|
||||||
|
@ -54,7 +64,7 @@ describe('roleMappingsManagementApp', () => {
|
||||||
expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: `/`, text: 'Role Mappings' }]);
|
expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: `/`, text: 'Role Mappings' }]);
|
||||||
expect(container).toMatchInlineSnapshot(`
|
expect(container).toMatchInlineSnapshot(`
|
||||||
<div>
|
<div>
|
||||||
Role Mappings Page: {"notifications":{"toasts":{}},"rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"roleMappingsAPI":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"docLinks":{"mappingRoles":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/mapping-roles.html","createRoleMapping":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-api-put-role-mapping.html","createRoleMappingTemplates":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-api-put-role-mapping.html#_role_templates","roleMappingFieldRules":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/role-mapping-resources.html#mapping-roles-rule-field"},"history":{"action":"PUSH","length":1,"location":{"pathname":"/","search":"","hash":""}}}
|
Role Mappings Page: {"notifications":{"toasts":{}},"rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"roleMappingsAPI":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"docLinks":{},"history":{"action":"PUSH","length":1,"location":{"pathname":"/","search":"","hash":""}}}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
@ -73,7 +83,7 @@ describe('roleMappingsManagementApp', () => {
|
||||||
]);
|
]);
|
||||||
expect(container).toMatchInlineSnapshot(`
|
expect(container).toMatchInlineSnapshot(`
|
||||||
<div>
|
<div>
|
||||||
Role Mapping Edit Page: {"roleMappingsAPI":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"notifications":{"toasts":{}},"docLinks":{"mappingRoles":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/mapping-roles.html","createRoleMapping":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-api-put-role-mapping.html","createRoleMappingTemplates":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-api-put-role-mapping.html#_role_templates","roleMappingFieldRules":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/role-mapping-resources.html#mapping-roles-rule-field"},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit","search":"","hash":""}}}
|
Role Mapping Edit Page: {"roleMappingsAPI":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"notifications":{"toasts":{}},"docLinks":{},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit","search":"","hash":""}}}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
@ -94,7 +104,7 @@ describe('roleMappingsManagementApp', () => {
|
||||||
]);
|
]);
|
||||||
expect(container).toMatchInlineSnapshot(`
|
expect(container).toMatchInlineSnapshot(`
|
||||||
<div>
|
<div>
|
||||||
Role Mapping Edit Page: {"name":"role@mapping","roleMappingsAPI":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"notifications":{"toasts":{}},"docLinks":{"mappingRoles":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/mapping-roles.html","createRoleMapping":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-api-put-role-mapping.html","createRoleMappingTemplates":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-api-put-role-mapping.html#_role_templates","roleMappingFieldRules":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/role-mapping-resources.html#mapping-roles-rule-field"},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit/role@mapping","search":"","hash":""}}}
|
Role Mapping Edit Page: {"name":"role@mapping","roleMappingsAPI":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"notifications":{"toasts":{}},"docLinks":{},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit/role@mapping","search":"","hash":""}}}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ import { i18n } from '@kbn/i18n';
|
||||||
import { StartServicesAccessor } from 'src/core/public';
|
import { StartServicesAccessor } from 'src/core/public';
|
||||||
import { RegisterManagementAppArgs } from '../../../../../../src/plugins/management/public';
|
import { RegisterManagementAppArgs } from '../../../../../../src/plugins/management/public';
|
||||||
import { PluginStartDependencies } from '../../plugin';
|
import { PluginStartDependencies } from '../../plugin';
|
||||||
import { DocumentationLinksService } from './documentation_links';
|
|
||||||
import { tryDecodeURIComponent } from '../url_utils';
|
import { tryDecodeURIComponent } from '../url_utils';
|
||||||
|
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
|
||||||
|
|
||||||
interface CreateParams {
|
interface CreateParams {
|
||||||
getStartServices: StartServicesAccessor<PluginStartDependencies>;
|
getStartServices: StartServicesAccessor<PluginStartDependencies>;
|
||||||
|
@ -39,7 +39,7 @@ export const roleMappingsManagementApp = Object.freeze({
|
||||||
];
|
];
|
||||||
|
|
||||||
const [
|
const [
|
||||||
[{ docLinks, http, notifications, i18n: i18nStart }],
|
[core],
|
||||||
{ RoleMappingsGridPage },
|
{ RoleMappingsGridPage },
|
||||||
{ EditRoleMappingPage },
|
{ EditRoleMappingPage },
|
||||||
{ RoleMappingsAPIClient },
|
{ RoleMappingsAPIClient },
|
||||||
|
@ -52,16 +52,15 @@ export const roleMappingsManagementApp = Object.freeze({
|
||||||
import('../roles'),
|
import('../roles'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const roleMappingsAPIClient = new RoleMappingsAPIClient(http);
|
const roleMappingsAPIClient = new RoleMappingsAPIClient(core.http);
|
||||||
const dockLinksService = new DocumentationLinksService(docLinks);
|
|
||||||
const RoleMappingsGridPageWithBreadcrumbs = () => {
|
const RoleMappingsGridPageWithBreadcrumbs = () => {
|
||||||
setBreadcrumbs(roleMappingsBreadcrumbs);
|
setBreadcrumbs(roleMappingsBreadcrumbs);
|
||||||
return (
|
return (
|
||||||
<RoleMappingsGridPage
|
<RoleMappingsGridPage
|
||||||
notifications={notifications}
|
notifications={core.notifications}
|
||||||
rolesAPIClient={new RolesAPIClient(http)}
|
rolesAPIClient={new RolesAPIClient(core.http)}
|
||||||
roleMappingsAPI={roleMappingsAPIClient}
|
roleMappingsAPI={roleMappingsAPIClient}
|
||||||
docLinks={dockLinksService}
|
docLinks={core.docLinks}
|
||||||
history={history}
|
history={history}
|
||||||
navigateToApp={coreStart.application.navigateToApp}
|
navigateToApp={coreStart.application.navigateToApp}
|
||||||
/>
|
/>
|
||||||
|
@ -90,27 +89,29 @@ export const roleMappingsManagementApp = Object.freeze({
|
||||||
<EditRoleMappingPage
|
<EditRoleMappingPage
|
||||||
name={decodedName}
|
name={decodedName}
|
||||||
roleMappingsAPI={roleMappingsAPIClient}
|
roleMappingsAPI={roleMappingsAPIClient}
|
||||||
rolesAPIClient={new RolesAPIClient(http)}
|
rolesAPIClient={new RolesAPIClient(core.http)}
|
||||||
notifications={notifications}
|
notifications={core.notifications}
|
||||||
docLinks={dockLinksService}
|
docLinks={core.docLinks}
|
||||||
history={history}
|
history={history}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<i18nStart.Context>
|
<KibanaContextProvider services={core}>
|
||||||
<Router history={history}>
|
<core.i18n.Context>
|
||||||
<Switch>
|
<Router history={history}>
|
||||||
<Route path={['/', '']} exact={true}>
|
<Switch>
|
||||||
<RoleMappingsGridPageWithBreadcrumbs />
|
<Route path={['/', '']} exact={true}>
|
||||||
</Route>
|
<RoleMappingsGridPageWithBreadcrumbs />
|
||||||
<Route path="/edit/:name?">
|
</Route>
|
||||||
<EditRoleMappingsPageWithBreadcrumbs />
|
<Route path="/edit/:name?">
|
||||||
</Route>
|
<EditRoleMappingsPageWithBreadcrumbs />
|
||||||
</Switch>
|
</Route>
|
||||||
</Router>
|
</Switch>
|
||||||
</i18nStart.Context>,
|
</Router>
|
||||||
|
</core.i18n.Context>
|
||||||
|
</KibanaContextProvider>,
|
||||||
element
|
element
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { DocLinksStart } from 'src/core/public';
|
|
||||||
|
|
||||||
export class DocumentationLinksService {
|
|
||||||
private readonly esClusterPrivileges: string;
|
|
||||||
private readonly esRunAsPrivilege: string;
|
|
||||||
private readonly esIndicesPrivileges: string;
|
|
||||||
|
|
||||||
constructor(docLinks: DocLinksStart) {
|
|
||||||
this.esClusterPrivileges = `${docLinks.links.security.clusterPrivileges}`;
|
|
||||||
this.esRunAsPrivilege = `${docLinks.links.security.runAsPrivilege}`;
|
|
||||||
this.esIndicesPrivileges = `${docLinks.links.security.indicesPrivileges}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getESClusterPrivilegesDocUrl() {
|
|
||||||
return `${this.esClusterPrivileges}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getESRunAsPrivilegesDocUrl() {
|
|
||||||
return `${this.esRunAsPrivilege}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getESIndicesPrivilegesDocUrl() {
|
|
||||||
return `${this.esIndicesPrivileges}`;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,7 +11,6 @@ import { mountWithIntl, nextTick } from '@kbn/test/jest';
|
||||||
import { Capabilities } from 'src/core/public';
|
import { Capabilities } from 'src/core/public';
|
||||||
import { KibanaFeature } from '../../../../../features/public';
|
import { KibanaFeature } from '../../../../../features/public';
|
||||||
import { Role } from '../../../../common/model';
|
import { Role } from '../../../../common/model';
|
||||||
import { DocumentationLinksService } from '../documentation_links';
|
|
||||||
import { EditRolePage } from './edit_role_page';
|
import { EditRolePage } from './edit_role_page';
|
||||||
import { SimplePrivilegeSection } from './privileges/kibana/simple_privilege_section';
|
import { SimplePrivilegeSection } from './privileges/kibana/simple_privilege_section';
|
||||||
|
|
||||||
|
@ -184,7 +183,7 @@ function getProps({
|
||||||
userAPIClient,
|
userAPIClient,
|
||||||
getFeatures: () => Promise.resolve(buildFeatures()),
|
getFeatures: () => Promise.resolve(buildFeatures()),
|
||||||
notifications,
|
notifications,
|
||||||
docLinks: new DocumentationLinksService(docLinks),
|
docLinks,
|
||||||
fatalErrors,
|
fatalErrors,
|
||||||
uiCapabilities: buildUICapabilities(canManageSpaces),
|
uiCapabilities: buildUICapabilities(canManageSpaces),
|
||||||
history: scopedHistoryMock.create(),
|
history: scopedHistoryMock.create(),
|
||||||
|
|
|
@ -38,7 +38,7 @@ import {
|
||||||
IHttpFetchError,
|
IHttpFetchError,
|
||||||
NotificationsStart,
|
NotificationsStart,
|
||||||
} from 'src/core/public';
|
} from 'src/core/public';
|
||||||
import { ScopedHistory } from 'kibana/public';
|
import type { DocLinksStart, ScopedHistory } from 'kibana/public';
|
||||||
import { FeaturesPluginStart } from '../../../../../features/public';
|
import { FeaturesPluginStart } from '../../../../../features/public';
|
||||||
import { KibanaFeature } from '../../../../../features/common';
|
import { KibanaFeature } from '../../../../../features/common';
|
||||||
import { IndexPatternsContract } from '../../../../../../../src/plugins/data/public';
|
import { IndexPatternsContract } from '../../../../../../../src/plugins/data/public';
|
||||||
|
@ -61,7 +61,6 @@ import { ElasticsearchPrivileges, KibanaPrivilegesRegion } from './privileges';
|
||||||
import { ReservedRoleBadge } from './reserved_role_badge';
|
import { ReservedRoleBadge } from './reserved_role_badge';
|
||||||
import { SecurityLicense } from '../../../../common/licensing';
|
import { SecurityLicense } from '../../../../common/licensing';
|
||||||
import { UserAPIClient } from '../../users';
|
import { UserAPIClient } from '../../users';
|
||||||
import { DocumentationLinksService } from '../documentation_links';
|
|
||||||
import { IndicesAPIClient } from '../indices_api_client';
|
import { IndicesAPIClient } from '../indices_api_client';
|
||||||
import { RolesAPIClient } from '../roles_api_client';
|
import { RolesAPIClient } from '../roles_api_client';
|
||||||
import { PrivilegesAPIClient } from '../privileges_api_client';
|
import { PrivilegesAPIClient } from '../privileges_api_client';
|
||||||
|
@ -77,7 +76,7 @@ interface Props {
|
||||||
rolesAPIClient: PublicMethodsOf<RolesAPIClient>;
|
rolesAPIClient: PublicMethodsOf<RolesAPIClient>;
|
||||||
privilegesAPIClient: PublicMethodsOf<PrivilegesAPIClient>;
|
privilegesAPIClient: PublicMethodsOf<PrivilegesAPIClient>;
|
||||||
getFeatures: FeaturesPluginStart['getFeatures'];
|
getFeatures: FeaturesPluginStart['getFeatures'];
|
||||||
docLinks: DocumentationLinksService;
|
docLinks: DocLinksStart;
|
||||||
http: HttpStart;
|
http: HttpStart;
|
||||||
license: SecurityLicense;
|
license: SecurityLicense;
|
||||||
uiCapabilities: Capabilities;
|
uiCapabilities: Capabilities;
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mountWithIntl, shallowWithIntl } from '@kbn/test/jest';
|
import { mountWithIntl, shallowWithIntl } from '@kbn/test/jest';
|
||||||
import { DocumentationLinksService } from '../../../documentation_links';
|
|
||||||
import { RoleValidator } from '../../validate_role';
|
import { RoleValidator } from '../../validate_role';
|
||||||
import { ClusterPrivileges } from './cluster_privileges';
|
import { ClusterPrivileges } from './cluster_privileges';
|
||||||
import { ElasticsearchPrivileges } from './elasticsearch_privileges';
|
import { ElasticsearchPrivileges } from './elasticsearch_privileges';
|
||||||
|
@ -45,7 +44,7 @@ function getProps() {
|
||||||
index: ['all', 'read', 'write', 'index'],
|
index: ['all', 'read', 'write', 'index'],
|
||||||
},
|
},
|
||||||
indicesAPIClient: indicesAPIClientMock.create(),
|
indicesAPIClient: indicesAPIClientMock.create(),
|
||||||
docLinks: new DocumentationLinksService(docLinks),
|
docLinks,
|
||||||
license,
|
license,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import type { PublicMethodsOf } from '@kbn/utility-types';
|
import type { PublicMethodsOf } from '@kbn/utility-types';
|
||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
|
import type { DocLinksStart } from 'src/core/public';
|
||||||
import { Role, BuiltinESPrivileges } from '../../../../../../common/model';
|
import { Role, BuiltinESPrivileges } from '../../../../../../common/model';
|
||||||
import { SecurityLicense } from '../../../../../../common/licensing';
|
import { SecurityLicense } from '../../../../../../common/licensing';
|
||||||
import { IndicesAPIClient } from '../../../indices_api_client';
|
import { IndicesAPIClient } from '../../../indices_api_client';
|
||||||
|
@ -26,13 +27,12 @@ import { RoleValidator } from '../../validate_role';
|
||||||
import { CollapsiblePanel } from '../../collapsible_panel';
|
import { CollapsiblePanel } from '../../collapsible_panel';
|
||||||
import { ClusterPrivileges } from './cluster_privileges';
|
import { ClusterPrivileges } from './cluster_privileges';
|
||||||
import { IndexPrivileges } from './index_privileges';
|
import { IndexPrivileges } from './index_privileges';
|
||||||
import { DocumentationLinksService } from '../../../documentation_links';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
role: Role;
|
role: Role;
|
||||||
editable: boolean;
|
editable: boolean;
|
||||||
indicesAPIClient: PublicMethodsOf<IndicesAPIClient>;
|
indicesAPIClient: PublicMethodsOf<IndicesAPIClient>;
|
||||||
docLinks: DocumentationLinksService;
|
docLinks: DocLinksStart;
|
||||||
license: SecurityLicense;
|
license: SecurityLicense;
|
||||||
onChange: (role: Role) => void;
|
onChange: (role: Role) => void;
|
||||||
runAsUsers: string[];
|
runAsUsers: string[];
|
||||||
|
@ -90,7 +90,7 @@ export class ElasticsearchPrivileges extends Component<Props, {}> {
|
||||||
id="xpack.security.management.editRole.elasticSearchPrivileges.manageRoleActionsDescription"
|
id="xpack.security.management.editRole.elasticSearchPrivileges.manageRoleActionsDescription"
|
||||||
defaultMessage="Manage the actions this role can perform against your cluster. "
|
defaultMessage="Manage the actions this role can perform against your cluster. "
|
||||||
/>
|
/>
|
||||||
{this.learnMore(docLinks.getESClusterPrivilegesDocUrl())}
|
{this.learnMore(docLinks.links.security.clusterPrivileges)}
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -120,7 +120,7 @@ export class ElasticsearchPrivileges extends Component<Props, {}> {
|
||||||
id="xpack.security.management.editRole.elasticSearchPrivileges.howToBeSubmittedOnBehalfOfOtherUsersDescription"
|
id="xpack.security.management.editRole.elasticSearchPrivileges.howToBeSubmittedOnBehalfOfOtherUsersDescription"
|
||||||
defaultMessage="Allow requests to be submitted on the behalf of other users. "
|
defaultMessage="Allow requests to be submitted on the behalf of other users. "
|
||||||
/>
|
/>
|
||||||
{this.learnMore(docLinks.getESRunAsPrivilegesDocUrl())}
|
{this.learnMore(docLinks.links.security.runAsPrivilege)}
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -164,7 +164,7 @@ export class ElasticsearchPrivileges extends Component<Props, {}> {
|
||||||
id="xpack.security.management.editRole.elasticSearchPrivileges.controlAccessToClusterDataDescription"
|
id="xpack.security.management.editRole.elasticSearchPrivileges.controlAccessToClusterDataDescription"
|
||||||
defaultMessage="Control access to the data in your cluster. "
|
defaultMessage="Control access to the data in your cluster. "
|
||||||
/>
|
/>
|
||||||
{this.learnMore(docLinks.getESIndicesPrivilegesDocUrl())}
|
{this.learnMore(docLinks.links.security.indicesPrivileges)}
|
||||||
</p>
|
</p>
|
||||||
</EuiText>
|
</EuiText>
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,9 @@ jest.mock('./roles_grid', () => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('./edit_role', () => ({
|
jest.mock('./edit_role', () => ({
|
||||||
EditRolePage: (props: any) => `Role Edit Page: ${JSON.stringify(props)}`,
|
// `docLinks` object is too big to include into test snapshot, so we just check its existence.
|
||||||
|
EditRolePage: (props: any) =>
|
||||||
|
`Role Edit Page: ${JSON.stringify({ ...props, docLinks: props.docLinks ? {} : undefined })}`,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { rolesManagementApp } from './roles_management_app';
|
import { rolesManagementApp } from './roles_management_app';
|
||||||
|
@ -87,7 +89,7 @@ describe('rolesManagementApp', () => {
|
||||||
expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: `/`, text: 'Roles' }, { text: 'Create' }]);
|
expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: `/`, text: 'Roles' }, { text: 'Create' }]);
|
||||||
expect(container).toMatchInlineSnapshot(`
|
expect(container).toMatchInlineSnapshot(`
|
||||||
<div>
|
<div>
|
||||||
Role Edit Page: {"action":"edit","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{"esClusterPrivileges":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#privileges-list-cluster","esRunAsPrivilege":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#_run_as_privilege","esIndicesPrivileges":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#privileges-list-indices"},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit","search":"","hash":""}}}
|
Role Edit Page: {"action":"edit","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit","search":"","hash":""}}}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
@ -108,7 +110,7 @@ describe('rolesManagementApp', () => {
|
||||||
]);
|
]);
|
||||||
expect(container).toMatchInlineSnapshot(`
|
expect(container).toMatchInlineSnapshot(`
|
||||||
<div>
|
<div>
|
||||||
Role Edit Page: {"action":"edit","roleName":"role@name","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{"esClusterPrivileges":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#privileges-list-cluster","esRunAsPrivilege":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#_run_as_privilege","esIndicesPrivileges":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#privileges-list-indices"},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit/role@name","search":"","hash":""}}}
|
Role Edit Page: {"action":"edit","roleName":"role@name","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit/role@name","search":"","hash":""}}}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
@ -126,7 +128,7 @@ describe('rolesManagementApp', () => {
|
||||||
expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: `/`, text: 'Roles' }, { text: 'Create' }]);
|
expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: `/`, text: 'Roles' }, { text: 'Create' }]);
|
||||||
expect(container).toMatchInlineSnapshot(`
|
expect(container).toMatchInlineSnapshot(`
|
||||||
<div>
|
<div>
|
||||||
Role Edit Page: {"action":"clone","roleName":"someRoleName","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{"esClusterPrivileges":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#privileges-list-cluster","esRunAsPrivilege":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#_run_as_privilege","esIndicesPrivileges":"https://www.elastic.co/guide/en/elasticsearch/reference/mocked-test-branch/security-privileges.html#privileges-list-indices"},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/clone/someRoleName","search":"","hash":""}}}
|
Role Edit Page: {"action":"clone","roleName":"someRoleName","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/clone/someRoleName","search":"","hash":""}}}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ import { StartServicesAccessor, FatalErrorsSetup } from 'src/core/public';
|
||||||
import { RegisterManagementAppArgs } from '../../../../../../src/plugins/management/public';
|
import { RegisterManagementAppArgs } from '../../../../../../src/plugins/management/public';
|
||||||
import { SecurityLicense } from '../../../common/licensing';
|
import { SecurityLicense } from '../../../common/licensing';
|
||||||
import { PluginStartDependencies } from '../../plugin';
|
import { PluginStartDependencies } from '../../plugin';
|
||||||
import { DocumentationLinksService } from './documentation_links';
|
|
||||||
import { tryDecodeURIComponent } from '../url_utils';
|
import { tryDecodeURIComponent } from '../url_utils';
|
||||||
|
|
||||||
interface CreateParams {
|
interface CreateParams {
|
||||||
|
@ -97,7 +96,7 @@ export const rolesManagementApp = Object.freeze({
|
||||||
notifications={notifications}
|
notifications={notifications}
|
||||||
fatalErrors={fatalErrors}
|
fatalErrors={fatalErrors}
|
||||||
license={license}
|
license={license}
|
||||||
docLinks={new DocumentationLinksService(docLinks)}
|
docLinks={docLinks}
|
||||||
uiCapabilities={application.capabilities}
|
uiCapabilities={application.capabilities}
|
||||||
indexPatterns={data.indexPatterns}
|
indexPatterns={data.indexPatterns}
|
||||||
history={history}
|
history={history}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import React, { useState } from 'react';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { I18nProvider, FormattedMessage } from '@kbn/i18n/react';
|
import { I18nProvider, FormattedMessage } from '@kbn/i18n/react';
|
||||||
import { render, unmountComponentAtNode } from 'react-dom';
|
import { render, unmountComponentAtNode } from 'react-dom';
|
||||||
import { MountPoint } from 'kibana/public';
|
import type { DocLinksStart, MountPoint } from 'kibana/public';
|
||||||
import {
|
import {
|
||||||
EuiCheckbox,
|
EuiCheckbox,
|
||||||
EuiText,
|
EuiText,
|
||||||
|
@ -16,7 +16,6 @@ import {
|
||||||
EuiFlexItem,
|
EuiFlexItem,
|
||||||
EuiButton,
|
EuiButton,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
import { DocumentationLinksService } from '../documentation_links';
|
|
||||||
|
|
||||||
export const insecureClusterAlertTitle = i18n.translate(
|
export const insecureClusterAlertTitle = i18n.translate(
|
||||||
'xpack.security.checkup.insecureClusterTitle',
|
'xpack.security.checkup.insecureClusterTitle',
|
||||||
|
@ -24,12 +23,15 @@ export const insecureClusterAlertTitle = i18n.translate(
|
||||||
);
|
);
|
||||||
|
|
||||||
export const insecureClusterAlertText = (
|
export const insecureClusterAlertText = (
|
||||||
getDocLinksService: () => DocumentationLinksService,
|
getDocLinks: () => DocLinksStart,
|
||||||
onDismiss: (persist: boolean) => void
|
onDismiss: (persist: boolean) => void
|
||||||
) =>
|
) =>
|
||||||
((e) => {
|
((e) => {
|
||||||
const AlertText = () => {
|
const AlertText = () => {
|
||||||
const [persist, setPersist] = useState(false);
|
const [persist, setPersist] = useState(false);
|
||||||
|
const enableSecurityDocLink = `${
|
||||||
|
getDocLinks().links.security.elasticsearchEnableSecurity
|
||||||
|
}?blade=kibanasecuritymessage`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<I18nProvider>
|
<I18nProvider>
|
||||||
|
@ -56,7 +58,7 @@ export const insecureClusterAlertText = (
|
||||||
size="s"
|
size="s"
|
||||||
color="primary"
|
color="primary"
|
||||||
fill
|
fill
|
||||||
href={getDocLinksService().getEnableSecurityDocUrl()}
|
href={enableSecurityDocLink}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
data-test-subj="learnMoreButton"
|
data-test-subj="learnMoreButton"
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { DocLinksStart } from 'src/core/public';
|
|
||||||
|
|
||||||
export class DocumentationLinksService {
|
|
||||||
private readonly esEnableSecurity: string;
|
|
||||||
|
|
||||||
constructor(docLinks: DocLinksStart) {
|
|
||||||
this.esEnableSecurity = `${docLinks.links.security.elasticsearchEnableSecurity}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getEnableSecurityDocUrl() {
|
|
||||||
return `${this.esEnableSecurity}?blade=kibanasecuritymessage`;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,14 +4,13 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { DocLinksStart } from 'kibana/public';
|
import type { DocLinksStart } from 'kibana/public';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
SecurityOssPluginSetup,
|
SecurityOssPluginSetup,
|
||||||
SecurityOssPluginStart,
|
SecurityOssPluginStart,
|
||||||
} from '../../../../../src/plugins/security_oss/public';
|
} from '../../../../../src/plugins/security_oss/public';
|
||||||
import { insecureClusterAlertTitle, insecureClusterAlertText } from './components';
|
import { insecureClusterAlertTitle, insecureClusterAlertText } from './components';
|
||||||
import { DocumentationLinksService } from './documentation_links';
|
|
||||||
|
|
||||||
interface SetupDeps {
|
interface SetupDeps {
|
||||||
securityOssSetup: SecurityOssPluginSetup;
|
securityOssSetup: SecurityOssPluginSetup;
|
||||||
|
@ -25,13 +24,13 @@ interface StartDeps {
|
||||||
export class SecurityCheckupService {
|
export class SecurityCheckupService {
|
||||||
private securityOssStart?: SecurityOssPluginStart;
|
private securityOssStart?: SecurityOssPluginStart;
|
||||||
|
|
||||||
private docLinksService?: DocumentationLinksService;
|
private docLinks?: DocLinksStart;
|
||||||
|
|
||||||
public setup({ securityOssSetup }: SetupDeps) {
|
public setup({ securityOssSetup }: SetupDeps) {
|
||||||
securityOssSetup.insecureCluster.setAlertTitle(insecureClusterAlertTitle);
|
securityOssSetup.insecureCluster.setAlertTitle(insecureClusterAlertTitle);
|
||||||
securityOssSetup.insecureCluster.setAlertText(
|
securityOssSetup.insecureCluster.setAlertText(
|
||||||
insecureClusterAlertText(
|
insecureClusterAlertText(
|
||||||
() => this.docLinksService!,
|
() => this.docLinks!,
|
||||||
(persist: boolean) => this.onDismiss(persist)
|
(persist: boolean) => this.onDismiss(persist)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -39,7 +38,7 @@ export class SecurityCheckupService {
|
||||||
|
|
||||||
public start({ securityOssStart, docLinks }: StartDeps) {
|
public start({ securityOssStart, docLinks }: StartDeps) {
|
||||||
this.securityOssStart = securityOssStart;
|
this.securityOssStart = securityOssStart;
|
||||||
this.docLinksService = new DocumentationLinksService(docLinks);
|
this.docLinks = docLinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private onDismiss(persist: boolean) {
|
private onDismiss(persist: boolean) {
|
||||||
|
|
Loading…
Reference in a new issue