Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure IIndexPattern doesn't allow arbitrary properties. #63809

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import React from 'react';
import { shallow } from 'enzyme';
import { IndexPatternField, IIndexPattern } from '../../../../../../../../../plugins/data/public';
import { IndexPatternField, IndexPattern } from '../../../../../../../../../plugins/data/public';
import { IndexedFieldsTable } from './indexed_fields_table';

jest.mock('@elastic/eui', () => ({
Expand Down Expand Up @@ -54,7 +54,7 @@ const fields = [

const indexPattern = ({
getNonScriptedFields: () => fields,
} as unknown) as IIndexPattern;
} as unknown) as IndexPattern;

describe('IndexedFieldsTable', () => {
test('should render normally', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@

import React, { Component } from 'react';
import { createSelector } from 'reselect';
import { IndexPatternField, IIndexPattern } from '../../../../../../../../../plugins/data/public';
import { IndexPatternField, IndexPattern } from '../../../../../../../../../plugins/data/public';
import { Table } from './components/table';
import { getFieldFormat } from './lib';
import { IndexedFieldItem } from './types';

interface IndexedFieldsTableProps {
fields: IndexPatternField[];
indexPattern: IIndexPattern;
indexPattern: IndexPattern;
fieldFilter?: string;
indexedFieldTypeFilter?: string;
helpers: {
redirectToRoute: (obj: any) => void;
getFieldInfo: (indexPattern: IIndexPattern, field: string) => string[];
getFieldInfo: (indexPattern: IndexPattern, field: string) => string[];
};
fieldWildcardMatcher: (filters: any[]) => (val: any) => boolean;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('DeleteScritpedFieldConfirmationModal', () => {
test('should render normally', () => {
const component = shallow(
<DeleteScritpedFieldConfirmationModal
field={{ name: '', script: '', lang: '' }}
field={{ name: '', script: '', lang: '', type: '' }}
deleteField={() => {}}
hideDeleteConfirmationModal={() => {}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { IIndexPattern } from '../../../../../../../../../../../plugins/data/pub

const getIndexPatternMock = (mockedFields: any = {}) => ({ ...mockedFields } as IIndexPattern);

const items: ScriptedFieldItem[] = [{ name: '1', lang: 'Elastic', script: '' }];
const items: ScriptedFieldItem[] = [{ name: '1', lang: 'Elastic', script: '', type: '' }];

describe('Table', () => {
let indexPattern: IIndexPattern;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@ import { get } from 'lodash';
import { i18n } from '@kbn/i18n';
import { EuiInMemoryTable, EuiBasicTableColumn } from '@elastic/eui';

import { ScriptedFieldItem } from '../../types';
import { IIndexPattern } from '../../../../../../../../../../../plugins/data/public';
import { IIndexPattern, IFieldType } from '../../../../../../../../../../../plugins/data/public';

interface TableProps {
indexPattern: IIndexPattern;
items: ScriptedFieldItem[];
editField: (field: ScriptedFieldItem) => void;
deleteField: (field: ScriptedFieldItem) => void;
items: IFieldType[];
editField: (field: IFieldType) => void;
deleteField: (field: IFieldType) => void;
}

export class Table extends PureComponent<TableProps> {
Expand All @@ -43,7 +42,7 @@ export class Table extends PureComponent<TableProps> {
render() {
const { items, editField, deleteField } = this.props;

const columns: Array<EuiBasicTableColumn<ScriptedFieldItem>> = [
const columns: Array<EuiBasicTableColumn<IFieldType>> = [
{
field: 'displayName',
name: i18n.translate('kbn.management.editIndexPattern.scripted.table.nameHeader', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import React from 'react';
import { shallow } from 'enzyme';

import { ScriptedFieldsTable } from '../scripted_fields_table';
import { IIndexPattern } from '../../../../../../../../../plugins/data/common/index_patterns';
import { IndexPattern } from '../../../../../../../../../plugins/data/public';

jest.mock('@elastic/eui', () => ({
EuiTitle: 'eui-title',
Expand Down Expand Up @@ -64,10 +64,10 @@ const helpers = {
getRouteHref: () => '#',
};

const getIndexPatternMock = (mockedFields: any = {}) => ({ ...mockedFields } as IIndexPattern);
const getIndexPatternMock = (mockedFields: any = {}) => ({ ...mockedFields } as IndexPattern);

describe('ScriptedFieldsTable', () => {
let indexPattern: IIndexPattern;
let indexPattern: IndexPattern;

beforeEach(() => {
indexPattern = getIndexPatternMock({
Expand Down Expand Up @@ -156,7 +156,9 @@ describe('ScriptedFieldsTable', () => {
);

await component.update(); // Fire `componentWillMount()`
component.instance().startDeleteField({ name: 'ScriptedField', lang: '', script: '' });
component
.instance()
.startDeleteField({ name: 'ScriptedField', lang: '', script: '', type: '' });
await component.update();

// Ensure the modal is visible
Expand All @@ -165,18 +167,15 @@ describe('ScriptedFieldsTable', () => {

test('should delete a field', async () => {
const removeScriptedField = jest.fn();
const pattern = ({ ...indexPattern, removeScriptedField } as unknown) as IndexPattern;
const component = shallow<ScriptedFieldsTable>(
<ScriptedFieldsTable
indexPattern={{
...indexPattern,
removeScriptedField,
}}
helpers={helpers}
/>
<ScriptedFieldsTable indexPattern={pattern} helpers={helpers} />
);

await component.update(); // Fire `componentWillMount()`
component.instance().startDeleteField({ name: 'ScriptedField', lang: '', script: '' });
component
.instance()
.startDeleteField({ name: 'ScriptedField', lang: '', script: '', type: '' });

await component.update();
await component.instance().deleteField();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ import { EuiSpacer } from '@elastic/eui';
import { Table, Header, CallOuts, DeleteScritpedFieldConfirmationModal } from './components';
import { ScriptedFieldItem } from './types';

import { IIndexPattern } from '../../../../../../../../../plugins/data/public';
import { IndexPattern } from '../../../../../../../../../plugins/data/public';

interface ScriptedFieldsTableProps {
indexPattern: IIndexPattern;
indexPattern: IndexPattern;
fieldFilter?: string;
scriptedFieldLanguageFilter?: string;
helpers: {
Expand Down Expand Up @@ -76,8 +76,8 @@ export class ScriptedFieldsTable extends Component<
const supportedLangs = getSupportedScriptingLanguages();

for (const field of fields) {
const lang: string = field.lang;
if (deprecatedLangs.includes(lang) || !supportedLangs.includes(lang)) {
const lang = field.lang;
if (lang && (deprecatedLangs.includes(lang) || !supportedLangs.includes(lang))) {
deprecatedLangsInUse.push(lang);
}
}
Expand Down Expand Up @@ -125,7 +125,9 @@ export class ScriptedFieldsTable extends Component<
const { indexPattern, onRemoveField } = this.props;
const { fieldToDelete } = this.state;

indexPattern.removeScriptedField(fieldToDelete);
if (fieldToDelete) {
indexPattern.removeScriptedField(fieldToDelete);
}

if (onRemoveField) {
onRemoveField();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
* under the License.
*/

import { IFieldType } from 'src/plugins/data/public';

/** @internal **/
export interface ScriptedFieldItem {
name: string;
lang: string;
script: string;
}
export type ScriptedFieldItem = IFieldType;
// export interface ScriptedFieldItem {
// name: string;
// lang: string;
// script: string;
// }
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ import { shallow, ShallowWrapper } from 'enzyme';

import { Table, TableProps, TableState } from './table';
import { EuiTableFieldDataColumnType, keyCodes } from '@elastic/eui';
import { IIndexPattern } from '../../../../../../../../../../../plugins/data/public';
import { IndexPattern } from '../../../../../../../../../../../plugins/data/public';
import { SourceFiltersTableFilter } from '../../types';

const indexPattern = {} as IIndexPattern;
const indexPattern = {} as IndexPattern;
const items: SourceFiltersTableFilter[] = [{ value: 'tim*', clientId: '' }];

const getIndexPatternMock = (mockedFields: any = {}) => ({ ...mockedFields } as IIndexPattern);
const getIndexPatternMock = (mockedFields: any = {}) => ({ ...mockedFields } as IndexPattern);

const getTableColumnRender = (
component: ShallowWrapper<TableProps, TableState, Table>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { SourceFiltersTableFilter } from '../../types';

import { IIndexPattern } from '../../../../../../../../../../../plugins/data/public';
import { IndexPattern } from '../../../../../../../../../../../plugins/data/public';

const filterHeader = i18n.translate('kbn.management.editIndexPattern.source.table.filterHeader', {
defaultMessage: 'Filter',
Expand Down Expand Up @@ -69,7 +69,7 @@ const cancelAria = i18n.translate('kbn.management.editIndexPattern.source.table.
});

export interface TableProps {
indexPattern: IIndexPattern;
indexPattern: IndexPattern;
items: SourceFiltersTableFilter[];
deleteFilter: Function;
fieldWildcardMatcher: Function;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import React from 'react';
import { shallow } from 'enzyme';

import { SourceFiltersTable } from './source_filters_table';
import { IIndexPattern } from '../../../../../../../../../plugins/data/public';
import { IndexPattern } from '../../../../../../../../../plugins/data/public';

jest.mock('@elastic/eui', () => ({
EuiButton: 'eui-button',
Expand Down Expand Up @@ -52,7 +52,7 @@ const getIndexPatternMock = (mockedFields: any = {}) =>
({
sourceFilters: [{ value: 'time*' }, { value: 'nam*' }, { value: 'age*' }],
...mockedFields,
} as IIndexPattern);
} as IndexPattern);

describe('SourceFiltersTable', () => {
test('should render normally', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ import { createSelector } from 'reselect';

import { EuiSpacer } from '@elastic/eui';
import { AddFilter, Table, Header, DeleteFilterConfirmationModal } from './components';
import { IIndexPattern } from '../../../../../../../../../plugins/data/public';
import { IndexPattern } from '../../../../../../../../../plugins/data/public';
import { SourceFiltersTableFilter } from './types';

export interface SourceFiltersTableProps {
indexPattern: IIndexPattern;
indexPattern: IndexPattern;
filterFilter: string;
fieldWildcardMatcher: Function;
onAddOrRemoveFilter?: Function;
Expand Down
5 changes: 4 additions & 1 deletion src/plugins/data/common/index_patterns/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
import { IFieldType } from './fields';

export interface IIndexPattern {
[key: string]: any;
// TODO: IIndexPattern shouldn't include attributes.
// We need a dedicated type for index patterns inside a saved object
// as described in https://github.com/elastic/kibana/issues/54894
attributes: any;
fields: IFieldType[];
title: string;
id?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@

import { IndexPattern } from './index_pattern';

interface PatternCache {
/** @internal */
export interface PatternCache {
get: (id: string) => IndexPattern;
set: (id: string, value: IndexPattern) => IndexPattern;
clear: (id: string) => void;
clearAll: () => void;
}

/** @internal */
export function createIndexPatternCache(): PatternCache {
const vals: Record<string, any> = {};
const cache: PatternCache = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ function create(id: string, payload?: any): Promise<IndexPattern> {
(cfg: any) => config.get(cfg),
savedObjectsClient as any,
apiClient,
patternCache
patternCache as any
);

setDocsourcePayload(id, payload);
Expand Down Expand Up @@ -374,7 +374,7 @@ describe('IndexPattern', () => {
(cfg: any) => config.get(cfg),
savedObjectsClient as any,
apiClient,
patternCache
patternCache as any
);
await pattern.init();

Expand All @@ -386,7 +386,7 @@ describe('IndexPattern', () => {
(cfg: any) => config.get(cfg),
savedObjectsClient as any,
apiClient,
patternCache
patternCache as any
);
await samePattern.init();

Expand Down
Loading