Skip to content

Commit

Permalink
Merge branch 'master' of github.com:elastic/kibana into timeline-impo…
Browse files Browse the repository at this point in the history
…rt-validation
  • Loading branch information
XavierM committed Sep 2, 2020
2 parents 8badaec + 71b9ded commit f2a6874
Show file tree
Hide file tree
Showing 61 changed files with 399 additions and 267 deletions.
4 changes: 2 additions & 2 deletions docs/settings/alert-action-settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ You can configure the following settings in the `kibana.yml` file.
[cols="2*<"]
|===

| `xpack.actions.whitelistedHosts`
| `xpack.actions.whitelistedHosts` {ess-icon}
| A list of hostnames that {kib} is allowed to connect to when built-in actions are triggered. It defaults to `[*]`, allowing any host, but keep in mind the potential for SSRF attacks when hosts are not explicitly whitelisted. An empty list `[]` can be used to block built-in actions from making any external connections. +
+
Note that hosts associated with built-in actions, such as Slack and PagerDuty, are not automatically whitelisted. If you are not using the default `[*]` setting, you must ensure that the corresponding endpoints are whitelisted as well.

| `xpack.actions.enabledActionTypes`
| `xpack.actions.enabledActionTypes` {ess-icon}
| A list of action types that are enabled. It defaults to `[*]`, enabling all types. The names for built-in {kib} action types are prefixed with a `.` and include: `.server-log`, `.slack`, `.email`, `.index`, `.pagerduty`, and `.webhook`. An empty list `[]` will disable all action types. +
+
Disabled action types will not appear as an option when creating new connectors, but existing connectors and actions of that type will remain in {kib} and will not function.
Expand Down
4 changes: 4 additions & 0 deletions x-pack/plugins/enterprise_search/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const APP_SEARCH_PLUGIN = {
'Leverage dashboards, analytics, and APIs for advanced application search made simple.',
}),
URL: '/app/enterprise_search/app_search',
SUPPORT_URL: 'https://discuss.elastic.co/c/enterprise-search/app-search/',
};

export const WORKPLACE_SEARCH_PLUGIN = {
Expand All @@ -36,8 +37,11 @@ export const WORKPLACE_SEARCH_PLUGIN = {
'Search all documents, files, and sources available across your virtual workplace.',
}),
URL: '/app/enterprise_search/workplace_search',
SUPPORT_URL: 'https://discuss.elastic.co/c/enterprise-search/workplace-search/',
};

export const LICENSED_SUPPORT_URL = 'https://support.elastic.co';

export const JSON_HEADER = { 'Content-Type': 'application/json' }; // This needs specific casing or Chrome throws a 415 error

export const ENGINES_PAGE_SIZE = 10;
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {

import { SetupGuide } from './components/setup_guide';
import { ErrorConnecting } from './components/error_connecting';
import { NotFound } from '../shared/not_found';
import { EngineOverview } from './components/engine_overview';

export const AppSearch: React.FC<IInitialAppData> = (props) => {
Expand Down Expand Up @@ -73,6 +74,9 @@ export const AppSearchConfigured: React.FC<IInitialAppData> = (props) => {
<Route exact path={ENGINES_PATH}>
<EngineOverview />
</Route>
<Route>
<NotFound product={APP_SEARCH_PLUGIN} />
</Route>
</Switch>
)}
</Layout>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
*/

export { LicenseContext, LicenseProvider, ILicenseContext } from './license_context';
export { hasPlatinumLicense } from './license_checks';
export { hasPlatinumLicense, hasGoldLicense } from './license_checks';
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { hasPlatinumLicense } from './license_checks';
import { hasPlatinumLicense, hasGoldLicense } from './license_checks';

describe('hasPlatinumLicense', () => {
it('is true for platinum licenses', () => {
Expand All @@ -31,3 +31,24 @@ describe('hasPlatinumLicense', () => {
expect(hasPlatinumLicense({ isActive: true, type: 'gold' } as any)).toEqual(false);
});
});

describe('hasGoldLicense', () => {
it('is true for gold+ and trial licenses', () => {
expect(hasGoldLicense({ isActive: true, type: 'gold' } as any)).toEqual(true);
expect(hasGoldLicense({ isActive: true, type: 'platinum' } as any)).toEqual(true);
expect(hasGoldLicense({ isActive: true, type: 'enterprise' } as any)).toEqual(true);
expect(hasGoldLicense({ isActive: true, type: 'trial' } as any)).toEqual(true);
});

it('is false if the current license is expired', () => {
expect(hasGoldLicense({ isActive: false, type: 'gold' } as any)).toEqual(false);
expect(hasGoldLicense({ isActive: false, type: 'platinum' } as any)).toEqual(false);
expect(hasGoldLicense({ isActive: false, type: 'enterprise' } as any)).toEqual(false);
expect(hasGoldLicense({ isActive: false, type: 'trial' } as any)).toEqual(false);
});

it('is false for licenses below gold', () => {
expect(hasGoldLicense({ isActive: true, type: 'basic' } as any)).toEqual(false);
expect(hasGoldLicense({ isActive: false, type: 'standard' } as any)).toEqual(false);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,11 @@
import { ILicense } from '../../../../../licensing/public';

export const hasPlatinumLicense = (license?: ILicense) => {
return license?.isActive && ['platinum', 'enterprise', 'trial'].includes(license?.type as string);
const qualifyingLicenses = ['platinum', 'enterprise', 'trial'];
return license?.isActive && qualifyingLicenses.includes(license?.type as string);
};

export const hasGoldLicense = (license?: ILicense) => {
const qualifyingLicenses = ['gold', 'platinum', 'enterprise', 'trial'];
return license?.isActive && qualifyingLicenses.includes(license?.type as string);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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 React from 'react';

export const AppSearchLogo: React.FC = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="136"
height="136"
viewBox="0 0 136 136"
className="logo404"
aria-hidden="true"
>
<rect x="1" y="1" width="134" height="134" rx="67" strokeWidth="2" strokeDasharray="8 4" />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M105.305 43.282l2.934-1.692c3.015 3.693 4.761 8.35 4.761 13.267V82.57a21 21 0 01-10.5 18.186L80 113.747V73.934c0-4.93-1.753-9.588-4.774-13.284l30.079-17.367zM66.5 55.747A21 21 0 0056 73.933v39.817l-22.5-12.993A21.001 21.001 0 0123 82.57V54.86c0-7.503 4.002-14.44 10.5-18.19l1.478-.853.022.014 33 19.05-1.5.867z"
className="logo404__light"
/>
<path
d="M78.5 22.813a21.007 21.007 0 00-21 0L35 35.83l33 19.05 33.001-19.05-22.5-13.017z"
fillRule="evenodd"
clipRule="evenodd"
className="logo404__dark"
/>
</svg>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* 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.
*/

.logo404 {
width: $euiSize * 8;
height: $euiSize * 8;

fill: $euiColorEmptyShade;
stroke: $euiColorLightShade;

&__light {
fill: $euiColorLightShade;
}

&__dark {
fill: $euiColorMediumShade;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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 React from 'react';

export const WorkplaceSearchLogo: React.FC = () => (
<svg
fill="none"
xmlns="http://www.w3.org/2000/svg"
width="137"
height="137"
viewBox="0 0 137 137"
className="logo404"
aria-hidden="true"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M136.886 72.486l-1.997-.115a67.11 67.11 0 000-7.742l1.997-.115a69.278 69.278 0 010 7.972zm-.343-11.943l-1.987.23a66.084 66.084 0 00-1.335-7.617l1.947-.46a68.478 68.478 0 011.375 7.847zm-2.404-11.696l-1.916.573a65.939 65.939 0 00-2.645-7.265l1.836-.794a67.996 67.996 0 012.725 7.486zm-4.412-11.096l-1.786.899a66.668 66.668 0 00-3.873-6.694l1.67-1.101a68.365 68.365 0 013.989 6.896zm-6.278-10.158l-1.603 1.195a66.966 66.966 0 00-4.975-5.923l1.454-1.372a68.733 68.733 0 015.124 6.1zm-7.941-8.918l-1.373 1.454a66.818 66.818 0 00-5.924-4.975l1.196-1.603a68.803 68.803 0 016.101 5.124zm-9.363-7.413l-1.101 1.67A66.34 66.34 0 0098.35 9.06l.9-1.786a68.38 68.38 0 016.895 3.99zM95.638 5.586l-.793 1.836a66 66 0 00-7.265-2.645l.573-1.916a67.995 67.995 0 017.485 2.725zM84.304 1.832l-.46 1.947a66.263 66.263 0 00-7.617-1.335l.23-1.987c2.665.309 5.284.77 7.847 1.375zM72.486.114l-.115 1.997a67.582 67.582 0 00-7.742 0L64.514.114a69.582 69.582 0 017.972 0zM60.543.457l.23 1.987c-2.588.3-5.13.747-7.617 1.335l-.46-1.947A68.267 68.267 0 0160.543.457zM48.847 2.861l.573 1.916a65.986 65.986 0 00-7.265 2.645l-.794-1.836a67.995 67.995 0 017.486-2.725zM37.75 7.273l.899 1.786a66.406 66.406 0 00-6.694 3.873l-1.101-1.67a68.42 68.42 0 016.896-3.99zM27.593 13.55l1.195 1.603a66.85 66.85 0 00-5.923 4.975l-1.372-1.454a68.853 68.853 0 016.1-5.124zm-8.918 7.941l1.454 1.373a66.866 66.866 0 00-4.975 5.924l-1.603-1.196a68.855 68.855 0 015.124-6.1zm-7.413 9.363l1.67 1.1A66.423 66.423 0 009.06 38.65l-1.786-.9a68.424 68.424 0 013.99-6.895zM5.586 41.361l1.836.794a66 66 0 00-2.645 7.265l-1.916-.573a67.995 67.995 0 012.725-7.486zM1.832 52.697l1.947.46a66.263 66.263 0 00-1.335 7.617l-1.987-.23c.309-2.665.77-5.284 1.375-7.847zM.114 64.514a69.582 69.582 0 000 7.972l1.997-.115a67.582 67.582 0 010-7.742l-1.997-.115zm.343 11.943l1.987-.23c.3 2.588.747 5.13 1.335 7.617l-1.947.46a68.267 68.267 0 01-1.375-7.847zm2.404 11.696l1.916-.573a66 66 0 002.645 7.266l-1.836.792a67.995 67.995 0 01-2.725-7.485zM7.273 99.25l1.786-.898a66.323 66.323 0 003.873 6.693l-1.67 1.101a68.378 68.378 0 01-3.99-6.895zm6.278 10.158l1.603-1.196a66.801 66.801 0 004.975 5.924l-1.454 1.373a68.803 68.803 0 01-5.124-6.101zm7.941 8.918l1.373-1.454a66.966 66.966 0 005.924 4.975l-1.196 1.603a68.734 68.734 0 01-6.1-5.124zm9.363 7.413l1.1-1.67a66.668 66.668 0 006.695 3.873l-.9 1.786a68.354 68.354 0 01-6.895-3.989zm10.506 5.676l.794-1.836a65.953 65.953 0 007.265 2.645l-.573 1.916a67.996 67.996 0 01-7.486-2.725zm11.335 3.754l.46-1.947a66.084 66.084 0 007.617 1.335l-.23 1.987a68.478 68.478 0 01-7.847-1.375zm11.818 1.718l.115-1.997a67.11 67.11 0 007.742 0l.115 1.997a69.278 69.278 0 01-7.972 0zm11.943-.343l-.23-1.987a66.084 66.084 0 007.617-1.335l.46 1.947a68.478 68.478 0 01-7.847 1.375zm11.696-2.404l-.573-1.916a65.953 65.953 0 007.266-2.645l.792 1.836a67.996 67.996 0 01-7.485 2.725zm11.096-4.412l-.898-1.786a66.584 66.584 0 006.693-3.873l1.101 1.67a68.31 68.31 0 01-6.895 3.989zm10.158-6.278l-1.196-1.603a66.918 66.918 0 005.924-4.975l1.373 1.454a68.682 68.682 0 01-6.101 5.124zm8.918-7.941l-1.454-1.373a66.918 66.918 0 004.975-5.924l1.603 1.196a68.682 68.682 0 01-5.124 6.101zm7.413-9.363l-1.67-1.101a66.584 66.584 0 003.873-6.694l1.786.9a68.31 68.31 0 01-3.989 6.895zm5.676-10.507l-1.836-.793a65.953 65.953 0 002.645-7.265l1.916.573a67.996 67.996 0 01-2.725 7.485zm3.754-11.334l-1.947-.46a66.084 66.084 0 001.335-7.617l1.987.23a68.478 68.478 0 01-1.375 7.847zM72.406 44.047c.372-.442 1-1.12 1.881-2.034 2.332-2.413 7.462-6.825 11.778-6.825h13.56v65.624H86.062c-4.313 0-8.739-3.17-11.775-6.794l-1.671-2.301 6.016-7.606c7.573-9.573 7.575-22.601.002-32.172l-6.228-7.892z"
className="logo404__light"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M38.375 100.812V35.188h12.71c3.74 0 7.328 1.719 9.596 4.593l12.808 16.232c5.683 7.181 5.683 16.839-.005 24.025L60.677 96.232c-2.269 2.868-5.852 4.58-9.582 4.58h-12.72z"
className="logo404__light"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M67.653 87.447l-7.075-6.978c-6.274-7.258-6.274-17.981.005-24.767 3.357-3.585 5.711-5.946 7.065-7.083l5.84 7.083c5.77 7.405 5.634 17.471-.135 24.88l-5.703 6.863.002.002z"
className="logo404__dark"
/>
</svg>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* 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.
*/

export { NotFound } from './not_found';
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* 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 '../../__mocks__/shallow_usecontext.mock';

import React, { useContext } from 'react';
import { shallow } from 'enzyme';

import { EuiButton as EuiButtonExternal, EuiEmptyPrompt } from '@elastic/eui';

import { APP_SEARCH_PLUGIN, WORKPLACE_SEARCH_PLUGIN } from '../../../../common/constants';
import { AppSearchLogo } from './assets/app_search_logo';
import { WorkplaceSearchLogo } from './assets/workplace_search_logo';

import { NotFound } from './';

describe('NotFound', () => {
const basicLicense = { isActive: true, type: 'basic' };
const goldLicense = { isActive: true, type: 'gold' };

beforeEach(() => {
(useContext as jest.Mock).mockImplementation(() => ({ license: basicLicense }));
});

it('renders an App Search 404 view', () => {
const wrapper = shallow(<NotFound product={APP_SEARCH_PLUGIN} />);
const prompt = wrapper.find(EuiEmptyPrompt).dive().shallow();

expect(prompt.find('h2').text()).toEqual('404 error');
expect(prompt.find(EuiButtonExternal).prop('href')).toEqual(APP_SEARCH_PLUGIN.SUPPORT_URL);

const logo = prompt.find(AppSearchLogo).dive().shallow();
expect(logo.type()).toEqual('svg');
});

it('renders a Workplace Search 404 view', () => {
const wrapper = shallow(<NotFound product={WORKPLACE_SEARCH_PLUGIN} />);
const prompt = wrapper.find(EuiEmptyPrompt).dive().shallow();

expect(prompt.find('h2').text()).toEqual('404 error');
expect(prompt.find(EuiButtonExternal).prop('href')).toEqual(
WORKPLACE_SEARCH_PLUGIN.SUPPORT_URL
);

const logo = prompt.find(WorkplaceSearchLogo).dive().shallow();
expect(logo.type()).toEqual('svg');
});

it('changes the support URL if the user has a gold+ license', () => {
(useContext as jest.Mock).mockImplementation(() => ({ license: goldLicense }));
const wrapper = shallow(<NotFound product={APP_SEARCH_PLUGIN} />);
const prompt = wrapper.find(EuiEmptyPrompt).dive().shallow();

expect(prompt.find(EuiButtonExternal).prop('href')).toEqual('https://support.elastic.co');
});

it('does not render anything without a valid product', () => {
const wrapper = shallow(<NotFound product={undefined as any} />);

expect(wrapper.isEmptyRender()).toBe(true);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* 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 React, { useContext } from 'react';
import { i18n } from '@kbn/i18n';
import {
EuiPageContent,
EuiEmptyPrompt,
EuiTitle,
EuiFlexGroup,
EuiFlexItem,
EuiButton as EuiButtonExternal,
} from '@elastic/eui';

import {
APP_SEARCH_PLUGIN,
WORKPLACE_SEARCH_PLUGIN,
LICENSED_SUPPORT_URL,
} from '../../../../common/constants';

import { EuiButton } from '../react_router_helpers';
import { SetAppSearchChrome, SetWorkplaceSearchChrome } from '../kibana_chrome';
import { SendAppSearchTelemetry, SendWorkplaceSearchTelemetry } from '../telemetry';
import { LicenseContext, ILicenseContext, hasGoldLicense } from '../licensing';

import { AppSearchLogo } from './assets/app_search_logo';
import { WorkplaceSearchLogo } from './assets/workplace_search_logo';
import './assets/logo.scss';

interface NotFoundProps {
// Expects product plugin constants (@see common/constants.ts)
product: {
ID: string;
SUPPORT_URL: string;
};
}

export const NotFound: React.FC<NotFoundProps> = ({ product = {} }) => {
const { license } = useContext(LicenseContext) as ILicenseContext;
const supportUrl = hasGoldLicense(license) ? LICENSED_SUPPORT_URL : product.SUPPORT_URL;

let Logo;
let SetPageChrome;
let SendTelemetry;

switch (product.ID) {
case APP_SEARCH_PLUGIN.ID:
Logo = AppSearchLogo;
SetPageChrome = SetAppSearchChrome;
SendTelemetry = SendAppSearchTelemetry;
break;
case WORKPLACE_SEARCH_PLUGIN.ID:
Logo = WorkplaceSearchLogo;
SetPageChrome = SetWorkplaceSearchChrome;
SendTelemetry = SendWorkplaceSearchTelemetry;
break;
default:
return null;
}

return (
<>
<SetPageChrome isRoot />
<SendTelemetry action="error" metric="not_found" />

<EuiPageContent>
<EuiEmptyPrompt
title={<Logo />}
body={
<>
<EuiTitle>
<h2>
{i18n.translate('xpack.enterpriseSearch.notFound.title', {
defaultMessage: '404 error',
})}
</h2>
</EuiTitle>
<p>
{i18n.translate('xpack.enterpriseSearch.notFound.description', {
defaultMessage: 'The page you’re looking for was not found.',
})}
</p>
</>
}
actions={
<EuiFlexGroup>
<EuiFlexItem>
<EuiButton to="/" color="primary" fill>
{i18n.translate('xpack.enterpriseSearch.notFound.action1', {
defaultMessage: 'Back to your dashboard',
})}
</EuiButton>
</EuiFlexItem>
<EuiFlexItem>
<EuiButtonExternal href={supportUrl} target="_blank">
{i18n.translate('xpack.enterpriseSearch.notFound.action2', {
defaultMessage: 'Contact support',
})}
</EuiButtonExternal>
</EuiFlexItem>
</EuiFlexGroup>
}
/>
</EuiPageContent>
</>
);
};
Loading

0 comments on commit f2a6874

Please sign in to comment.