Skip to content

Commit

Permalink
Merge branch '7.x' into backport/7.x/pr-51505
Browse files Browse the repository at this point in the history
  • Loading branch information
elasticmachine authored Nov 25, 2019
2 parents a7bc385 + 3c93c3a commit f813c22
Show file tree
Hide file tree
Showing 98 changed files with 1,791 additions and 1,448 deletions.
14 changes: 12 additions & 2 deletions docs/migration/migrate_7_0.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,20 @@ Kibana 7.0 will only use the Node.js distribution included in the package.
[float]
==== Removed support for users relying on direct index privileges to the Kibana index in Elasticsearch
*Details:* With the introduction of Kibana RBAC in 6.4, users no longer require privileges to the Kibana index in Elasticsearch. Instead, users
should be granted <<kibana-privileges>>. Prior to 7.0, when a user that relies upon direct index privileges logs into Kibana, a deprecation warning is logged. If you are using the `kibana_user` or `kibana_dashboard_only_user` role to grant access to Kibana, or a custom role using <<kibana-privileges>>, no changes are required.
should be granted <<kibana-privileges>>. Prior to 7.0, when a user who relies upon direct index privileges logged into Kibana, a deprecation warning was logged.

*Impact:* You must change any roles which grant access to Kibana using index privileges to instead use <<kibana-privileges>>. Watcher jobs using the Reporting attachment type must be updated as well.
*Impact:* You must change any roles that grant access to Kibana using index privileges to use <<kibana-privileges>> instead.
Watcher jobs using the Reporting attachment type must also be updated.

If you use a custom `kibana.index` for multitenancy, you can
no longer use `kibana_user` or `kibana_dashboard_only_user` to provide access,
and will have to start using {kib} privileges.

In addition, roles cannot be shared across Kibana tenants when granting access to Kibana privileges.
For example, a tenant using `kibana.index: .kibana` will have its own set
of roles created to grant access to Kibana. If you create another tenant
at `kibana.index: .some-other-index`, it will need its own set of roles
to grant access to that tenant.

[float]
[[breaking_70_setting_changes]]
Expand Down
9 changes: 8 additions & 1 deletion docs/setup/settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,16 @@ Visualize.
`kibana.defaultAppId:`:: *Default: "home"* The default application to load.

`kibana.index:`:: *Default: ".kibana"* Kibana uses an index in Elasticsearch to
store saved searches, visualizations and dashboards. Kibana creates a new index
store saved searches, visualizations, and dashboards. Kibana creates a new index
if the index doesn’t already exist. If you configure a custom index, the name must
be lowercase, and conform to {es} {ref}/indices-create-index.html[index name limitations].
+
When running multiple tenants of {kib} by changing the `kibana.index` in your `kibana.yml`,
you cannot use the `kibana_user` or `kibana_dashboard_only_user` roles
to grant access to {kib}.
You must create custom roles that authorize the user for that specific tenant.
Although multi-tenant installations are supported, the recommended approach
to securing access to {kib} segments is to grant users access to specific spaces.

`kibana.autocompleteTimeout:`:: *Default: "1000"* Time in milliseconds to wait
for autocomplete suggestions from Elasticsearch. This value must be a whole number
Expand Down
3 changes: 2 additions & 1 deletion docs/user/security/authorization/index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ The Elastic Stack comes with the `kibana_user` {ref}/built-in-roles.html[built-i

When you assign a user multiple roles, the user receives a union of the roles’ privileges. Therefore, assigning the `kibana_user` role in addition to a custom role that grants Kibana privileges is ineffective because `kibana_user` has access to all the features in all spaces.

NOTE: When running multiple tenants of Kibana by changing the `kibana.index` in your `kibana.yml`, you cannot use `kibana_user` to grant access. You must create custom roles that authorize the user for that specific tenant. Although multi-tenant installations are supported, the recommended approach to securing access to Kibana segments is to grant users access to specific spaces.
NOTE: When running multiple tenants of Kibana by changing the `kibana.index` in your `kibana.yml`,
you cannot use `kibana_user` or `kibana_dashboard_only_user` to grant access. You must create custom roles that authorize the user for that specific tenant. Although multi-tenant installations are supported, the recommended approach to securing access to Kibana segments is to grant users access to specific spaces.

[role="xpack"]
[[kibana-role-management]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,21 @@ describe(`running the plugin-generator via 'node scripts/generate_plugin.js plug

describe(`then running`, () => {
it(`'yarn test:browser' should exit 0`, async () => {
await execa('yarn', ['test:browser'], { cwd: generatedPath });
await execa('yarn', ['test:browser'], {
cwd: generatedPath,
env: {
DISABLE_JUNIT_REPORTER: '1',
},
});
});

it(`'yarn test:server' should exit 0`, async () => {
await execa('yarn', ['test:server'], { cwd: generatedPath });
await execa('yarn', ['test:server'], {
cwd: generatedPath,
env: {
DISABLE_JUNIT_REPORTER: '1',
},
});
});

it(`'yarn build' should exit 0`, async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export const schema = Joi.object()

junit: Joi.object()
.keys({
enabled: Joi.boolean().default(!!process.env.CI),
enabled: Joi.boolean().default(!!process.env.CI && !process.env.DISABLE_JUNIT_REPORTER),
reportName: Joi.string(),
})
.default(),
Expand Down
2 changes: 1 addition & 1 deletion src/dev/jest/junit_reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default class JestJUnitReporter {
* @return {undefined}
*/
onRunComplete(contexts, results) {
if (!process.env.CI || !results.testResults.length) {
if (!process.env.CI || process.env.DISABLE_JUNIT_REPORTER || !results.testResults.length) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/dev/mocha/auto_junit_reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function createAutoJUnitReporter(junitReportOptions) {
new MochaSpecReporter(runner, options);

// in CI we also setup the JUnit reporter
if (process.env.CI) {
if (process.env.CI && !process.env.DISABLE_JUNIT_REPORTER) {
setupJUnitReportGeneration(runner, junitReportOptions);
}
}
Expand Down
11 changes: 10 additions & 1 deletion src/dev/mocha/run_mocha_cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,16 @@ export function runMochaCli() {
if (!opts._.length) {
globby
.sync(
['src/**/__tests__/**/*.js', 'packages/**/__tests__/**/*.js', 'tasks/**/__tests__/**/*.js'],
[
'src/**/__tests__/**/*.js',
'packages/**/__tests__/**/*.js',
'tasks/**/__tests__/**/*.js',
'x-pack/common/**/__tests__/**/*.js',
'x-pack/server/**/__tests__/**/*.js',
`x-pack/legacy/plugins/*/__tests__/**/*.js`,
`x-pack/legacy/plugins/*/common/**/__tests__/**/*.js`,
`x-pack/legacy/plugins/*/**/server/**/__tests__/**/*.js`,
],
{
cwd: REPO_ROOT,
onlyFiles: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ import {
import { FormattedMessage } from '@kbn/i18n/react';
import React, { Component } from 'react';
import { IndexPattern } from '../../index_patterns';
import { FilterLabel } from '../filter_bar/filter_editor/lib/filter_label';
import { mapAndFlattenFilters, esFilters, utils } from '../../../../../../plugins/data/public';
import {
mapAndFlattenFilters,
esFilters,
utils,
FilterLabel,
} from '../../../../../../plugins/data/public';

interface Props {
filters: esFilters.Filter[];
Expand Down
Empty file.
2 changes: 0 additions & 2 deletions src/legacy/core_plugins/data/public/filter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,4 @@
* under the License.
*/

export { FilterBar } from './filter_bar';

export { ApplyFiltersPopover } from './apply_filters';
2 changes: 1 addition & 1 deletion src/legacy/core_plugins/data/public/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

@import './query/query_bar/index';

@import './filter/filter_bar/index';
@import 'src/plugins/data/public/ui/filter_bar/index';

@import './search/search_bar/index';
2 changes: 1 addition & 1 deletion src/legacy/core_plugins/data/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function plugin() {
/** @public types */
export { DataSetup, DataStart };

export { FilterBar, ApplyFiltersPopover } from './filter';
export { ApplyFiltersPopover } from './filter';
export {
Field,
FieldType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,14 @@ const mockTimeHistory = {
},
};

jest.mock('../../../../../data/public', () => {
jest.mock('../../../../../../../plugins/data/public', () => {
return {
FilterBar: () => <div className="filterBar" />,
};
});

jest.mock('../../../../../data/public', () => {
return {
QueryBarInput: () => <div className="queryBar" />,
};
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import React, { Component } from 'react';
import ResizeObserver from 'resize-observer-polyfill';
import { get, isEqual } from 'lodash';

import { IndexPattern, FilterBar } from '../../../../../data/public';
import { IndexPattern } from '../../../../../data/public';
import { QueryBarTopRow } from '../../../query';
import { SavedQuery, SavedQueryAttributes } from '../index';
import { SavedQueryMeta, SaveQueryForm } from './saved_query_management/save_query_form';
Expand All @@ -41,6 +41,7 @@ import {
Query,
esFilters,
TimeHistoryContract,
FilterBar,
} from '../../../../../../../plugins/data/public';

interface SearchBarInjectedDeps {
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/data/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ export * from './types';
export { IRequestTypesMap, IResponseTypesMap } from './search';
export * from './search';
export * from './query';

export * from './ui';
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import React, { useState } from 'react';
import { FilterEditor } from './filter_editor';
import { FilterItem } from './filter_item';
import { FilterOptions } from './filter_options';
import { useKibana } from '../../../../../../plugins/kibana_react/public';
import { IIndexPattern, esFilters } from '../../../../../../plugins/data/public';
import { useKibana } from '../../../../kibana_react/public';
import { IIndexPattern, esFilters } from '../..';

interface Props {
filters: esFilters.Filter[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,7 @@ import { Operator } from './lib/filter_operators';
import { PhraseValueInput } from './phrase_value_input';
import { PhrasesValuesInput } from './phrases_values_input';
import { RangeValueInput } from './range_value_input';
import {
esFilters,
utils,
IIndexPattern,
IFieldType,
} from '../../../../../../../plugins/data/public';
import { esFilters, utils, IIndexPattern, IFieldType } from '../../..';

interface Props {
filter: esFilters.Filter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,15 @@
* under the License.
*/

/* eslint-disable @kbn/eslint/no-restricted-paths */
import {
existsFilter,
phraseFilter,
phrasesFilter,
rangeFilter,
stubIndexPattern,
stubFields,
} from '../../../../../../../../plugins/data/public/stubs';
import { IndexPattern, Field } from '../../../../index';
} from '../../../../stubs';
import { esFilters } from '../../../../index';
import {
getFieldFromFilter,
getFilterableFields,
Expand All @@ -37,17 +36,12 @@ import {

import { existsOperator, isBetweenOperator, isOneOfOperator, isOperator } from './filter_operators';

import { esFilters } from '../../../../../../../../plugins/data/public';

jest.mock('ui/new_platform');

const mockedFields = stubFields as Field[];
const mockedIndexPattern = stubIndexPattern as IndexPattern;

describe('Filter editor utils', () => {
describe('getFieldFromFilter', () => {
it('should return the field from the filter', () => {
const field = getFieldFromFilter(phraseFilter, mockedIndexPattern);
const field = getFieldFromFilter(phraseFilter, stubIndexPattern);
expect(field).not.toBeUndefined();
expect(field && field.name).toBe(phraseFilter.meta.key);
});
Expand Down Expand Up @@ -117,12 +111,12 @@ describe('Filter editor utils', () => {

describe('getFilterableFields', () => {
it('returns the list of fields from the given index pattern', () => {
const fieldOptions = getFilterableFields(mockedIndexPattern);
const fieldOptions = getFilterableFields(stubIndexPattern);
expect(fieldOptions.length).toBeGreaterThan(0);
});

it('limits the fields to the filterable fields', () => {
const fieldOptions = getFilterableFields(mockedIndexPattern);
const fieldOptions = getFilterableFields(stubIndexPattern);
const nonFilterableFields = fieldOptions.filter(field => !field.filterable);
expect(nonFilterableFields.length).toBe(0);
});
Expand All @@ -131,72 +125,67 @@ describe('Filter editor utils', () => {
describe('getOperatorOptions', () => {
it('returns range for number fields', () => {
const [field] = stubFields.filter(({ type }) => type === 'number');
const operatorOptions = getOperatorOptions(field as Field);
const operatorOptions = getOperatorOptions(field);
const rangeOperator = operatorOptions.find(operator => operator.type === 'range');
expect(rangeOperator).not.toBeUndefined();
});

it('does not return range for string fields', () => {
const [field] = stubFields.filter(({ type }) => type === 'string');
const operatorOptions = getOperatorOptions(field as Field);
const operatorOptions = getOperatorOptions(field);
const rangeOperator = operatorOptions.find(operator => operator.type === 'range');
expect(rangeOperator).toBeUndefined();
});
});

describe('isFilterValid', () => {
it('should return false if index pattern is not provided', () => {
const isValid = isFilterValid(undefined, mockedFields[0], isOperator, 'foo');
const isValid = isFilterValid(undefined, stubFields[0], isOperator, 'foo');
expect(isValid).toBe(false);
});

it('should return false if field is not provided', () => {
const isValid = isFilterValid(mockedIndexPattern, undefined, isOperator, 'foo');
const isValid = isFilterValid(stubIndexPattern, undefined, isOperator, 'foo');
expect(isValid).toBe(false);
});

it('should return false if operator is not provided', () => {
const isValid = isFilterValid(mockedIndexPattern, mockedFields[0], undefined, 'foo');
const isValid = isFilterValid(stubIndexPattern, stubFields[0], undefined, 'foo');
expect(isValid).toBe(false);
});

it('should return false for phrases filter without phrases', () => {
const isValid = isFilterValid(mockedIndexPattern, mockedFields[0], isOneOfOperator, []);
const isValid = isFilterValid(stubIndexPattern, stubFields[0], isOneOfOperator, []);
expect(isValid).toBe(false);
});

it('should return true for phrases filter with phrases', () => {
const isValid = isFilterValid(mockedIndexPattern, mockedFields[0], isOneOfOperator, ['foo']);
const isValid = isFilterValid(stubIndexPattern, stubFields[0], isOneOfOperator, ['foo']);
expect(isValid).toBe(true);
});

it('should return false for range filter without range', () => {
const isValid = isFilterValid(
mockedIndexPattern,
mockedFields[0],
isBetweenOperator,
undefined
);
const isValid = isFilterValid(stubIndexPattern, stubFields[0], isBetweenOperator, undefined);
expect(isValid).toBe(false);
});

it('should return true for range filter with from', () => {
const isValid = isFilterValid(mockedIndexPattern, mockedFields[0], isBetweenOperator, {
const isValid = isFilterValid(stubIndexPattern, stubFields[0], isBetweenOperator, {
from: 'foo',
});
expect(isValid).toBe(true);
});

it('should return true for range filter with from/to', () => {
const isValid = isFilterValid(mockedIndexPattern, mockedFields[0], isBetweenOperator, {
const isValid = isFilterValid(stubIndexPattern, stubFields[0], isBetweenOperator, {
from: 'foo',
too: 'goo',
});
expect(isValid).toBe(true);
});

it('should return true for exists filter without params', () => {
const isValid = isFilterValid(mockedIndexPattern, mockedFields[0], existsOperator);
const isValid = isFilterValid(stubIndexPattern, stubFields[0], existsOperator);
expect(isValid).toBe(true);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,9 @@
*/

import dateMath from '@elastic/datemath';
import { Ipv4Address } from '../../../../../../../../plugins/kibana_utils/public';
import { Ipv4Address } from '../../../../../../kibana_utils/public';
import { FILTER_OPERATORS, Operator } from './filter_operators';
import {
esFilters,
IIndexPattern,
IFieldType,
isFilterable,
} from '../../../../../../../../plugins/data/public';
import { esFilters, IIndexPattern, IFieldType, isFilterable } from '../../../..';

export function getFieldFromFilter(filter: esFilters.FieldFilter, indexPattern: IIndexPattern) {
return indexPattern.fields.find(field => field.name === filter.meta.key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@
import React from 'react';
import { FilterLabel } from './filter_label';
import { shallow } from 'enzyme';

/* eslint-disable @kbn/eslint/no-restricted-paths */
import { phraseFilter } from '../../../../../../../../plugins/data/public/stubs';
/* eslint-enable @kbn/eslint/no-restricted-paths */
import { phraseFilter } from '../../../../stubs';

test('alias', () => {
const filter = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import React, { Fragment } from 'react';
import { EuiTextColor } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { existsOperator, isOneOfOperator } from './filter_operators';
import { esFilters } from '../../../../../../../../plugins/data/public';
import { esFilters } from '../../../..';

interface Props {
filter: esFilters.Filter;
Expand Down
Loading

0 comments on commit f813c22

Please sign in to comment.