Make indexPattern only read only in Discover permission (#108376)

* Make indexPattern only read only in Discover permission

* Fix test failures

* Address review comments

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Tim Roes 2021-08-17 16:47:43 +02:00 committed by GitHub
parent f243b0540d
commit 6f4a615860
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 74 additions and 22 deletions

View file

@ -78,9 +78,7 @@ export function getStateColumnActions({
state: DiscoverState | ContextState;
}) {
function onAddColumn(columnName: string) {
if (capabilities.discover.save) {
popularizeField(indexPattern, columnName, indexPatterns);
}
popularizeField(indexPattern, columnName, indexPatterns, capabilities);
const columns = addColumn(state.columns || [], columnName, useNewFieldsApi);
const defaultOrder = config.get(SORT_DEFAULT_ORDER_SETTING);
const sort =
@ -89,9 +87,7 @@ export function getStateColumnActions({
}
function onRemoveColumn(columnName: string) {
if (capabilities.discover.save) {
popularizeField(indexPattern, columnName, indexPatterns);
}
popularizeField(indexPattern, columnName, indexPatterns, capabilities);
const columns = removeColumn(state.columns || [], columnName, useNewFieldsApi);
// The state's sort property is an array of [sortByColumn,sortDirection]
const sort =

View file

@ -122,7 +122,7 @@ export function DiscoverLayout({
const onAddFilter = useCallback(
(field: IndexPatternField | string, values: string, operation: '+' | '-') => {
const fieldName = typeof field === 'string' ? field : field.name;
popularizeField(indexPattern, fieldName, indexPatterns);
popularizeField(indexPattern, fieldName, indexPatterns, capabilities);
const newFilters = esFilters.generateFilters(
filterManager,
field,
@ -135,7 +135,7 @@ export function DiscoverLayout({
}
return filterManager.addFilters(newFilters);
},
[filterManager, indexPattern, indexPatterns, trackUiMetric]
[filterManager, indexPattern, indexPatterns, trackUiMetric, capabilities]
);
const onEditRuntimeField = useCallback(() => {

View file

@ -54,6 +54,9 @@ describe('ContextApp test', () => {
discover: {
save: true,
},
indexPatterns: {
save: true,
},
},
indexPatterns: indexPatternsMock,
toastNotifications: { addDanger: () => {} },

View file

@ -109,10 +109,10 @@ export const ContextApp = ({ indexPattern, indexPatternId, anchorId }: ContextAp
filterManager.addFilters(newFilters);
if (indexPatterns) {
const fieldName = typeof field === 'string' ? field : field.name;
await popularizeField(indexPattern, fieldName, indexPatterns);
await popularizeField(indexPattern, fieldName, indexPatterns, capabilities);
}
},
[filterManager, indexPatternId, indexPatterns, indexPattern]
[filterManager, indexPatternId, indexPatterns, indexPattern, capabilities]
);
const TopNavMenu = navigation.ui.TopNavMenu;

View file

@ -6,15 +6,27 @@
* Side Public License, v 1.
*/
import { Capabilities } from 'kibana/public';
import { IndexPattern, IndexPatternsService } from '../../../../data/public';
import { popularizeField } from './popularize_field';
const capabilities = ({
indexPatterns: {
save: true,
},
} as unknown) as Capabilities;
describe('Popularize field', () => {
test('returns undefined if index pattern lacks id', async () => {
const indexPattern = ({} as unknown) as IndexPattern;
const fieldName = '@timestamp';
const indexPatternsService = ({} as unknown) as IndexPatternsService;
const result = await popularizeField(indexPattern, fieldName, indexPatternsService);
const result = await popularizeField(
indexPattern,
fieldName,
indexPatternsService,
capabilities
);
expect(result).toBeUndefined();
});
@ -26,7 +38,12 @@ describe('Popularize field', () => {
} as unknown) as IndexPattern;
const fieldName = '@timestamp';
const indexPatternsService = ({} as unknown) as IndexPatternsService;
const result = await popularizeField(indexPattern, fieldName, indexPatternsService);
const result = await popularizeField(
indexPattern,
fieldName,
indexPatternsService,
capabilities
);
expect(result).toBeUndefined();
});
@ -44,7 +61,12 @@ describe('Popularize field', () => {
const indexPatternsService = ({
updateSavedObject: async () => {},
} as unknown) as IndexPatternsService;
const result = await popularizeField(indexPattern, fieldName, indexPatternsService);
const result = await popularizeField(
indexPattern,
fieldName,
indexPatternsService,
capabilities
);
expect(result).toBeUndefined();
expect(field.count).toEqual(1);
});
@ -65,7 +87,34 @@ describe('Popularize field', () => {
throw new Error('unknown error');
},
} as unknown) as IndexPatternsService;
const result = await popularizeField(indexPattern, fieldName, indexPatternsService);
const result = await popularizeField(
indexPattern,
fieldName,
indexPatternsService,
capabilities
);
expect(result).toBeUndefined();
});
test('should not try to update index pattern without permissions', async () => {
const field = {
count: 0,
};
const indexPattern = ({
id: 'id',
fields: {
getByName: () => field,
},
} as unknown) as IndexPattern;
const fieldName = '@timestamp';
const indexPatternsService = ({
updateSavedObject: jest.fn(),
} as unknown) as IndexPatternsService;
const result = await popularizeField(indexPattern, fieldName, indexPatternsService, ({
indexPatterns: { save: false },
} as unknown) as Capabilities);
expect(result).toBeUndefined();
expect(indexPatternsService.updateSavedObject).not.toHaveBeenCalled();
expect(field.count).toEqual(0);
});
});

View file

@ -6,14 +6,16 @@
* Side Public License, v 1.
*/
import type { Capabilities } from 'kibana/public';
import { IndexPattern, IndexPatternsContract } from '../../../../data/public';
async function popularizeField(
indexPattern: IndexPattern,
fieldName: string,
indexPatternsService: IndexPatternsContract
indexPatternsService: IndexPatternsContract,
capabilities: Capabilities
) {
if (!indexPattern.id) return;
if (!indexPattern.id || !capabilities?.indexPatterns?.save) return;
const field = indexPattern.fields.getByName(fieldName);
if (!field) {
return;

View file

@ -694,11 +694,12 @@ Array [
"all": Array [
"search",
"query",
"index-pattern",
"url",
"search-session",
],
"read": Array [],
"read": Array [
"index-pattern",
],
},
"ui": Array [
"show",
@ -1223,11 +1224,12 @@ Array [
"all": Array [
"search",
"query",
"index-pattern",
"url",
"search-session",
],
"read": Array [],
"read": Array [
"index-pattern",
],
},
"ui": Array [
"show",

View file

@ -40,8 +40,8 @@ export const buildOSSFeatures = ({
api: ['fileUpload:analyzeFile'],
catalogue: ['discover'],
savedObject: {
all: ['search', 'query', 'index-pattern'],
read: [],
all: ['search', 'query'],
read: ['index-pattern'],
},
ui: ['show', 'save', 'saveQuery'],
},