kibana/x-pack/plugins/features/server/oss_features.ts
Pierre Gayvallet d4b2a5145a
SavedObjects tagging MVP (#79096)
* create xpack plugin skeleton, start to implement management section

* add tag creation modal

* first implementation of the tags table

* use InMemoryTable

* add edit modal and delete action

* update plugin list

* add tag list, fix types

* add capabilities check on client-side

* add tag combo box component

* add missing i18n keys

* fix privilege FTR tests

* add base structure for FTR tests

* fix feature ftr test

* use string literals for i18n

* create savedObjectsTaggingOss plugin, move API types to oss plugin, start to wire to SO management page.

* update plugin list

* fix types

* allow to use `_find` with multiple references

* add FTR test for _find API on references fields

* add _find integration tests

* update generated doc

* start to implement tag filtering on SO management section

* update generated docs

* wire tagging API to dashboard listing page

* fix i18n namespace

* fix type & tests

* update dashboard listing snapshots

* adapt FTR listingTable service to search for parsable queries

* wite tagging API to visualize listing

* update tagging plugin limits

* add server-side and client-side validation for tag create/edit

* rename title field to name

* fix types

* fix types bis

* add removeReferencesTo API to SOR/SOC

* update generated doc

* add server-side unit test for `savedObjectsTagging` plugin

* move tagging API types to its own file

* add savedObjectsTaggingOss mock

* add tags_cache tests

* add tests for client-side tag client

* extract uiApi to distinct files

* various API improvements

* add more tests

* add link between tag and so management sections + add connection counts

* add base functional test suite for tagging

* add more FTR tests

* improve feature control func test

* update codeowners

* update generated doc

* fix access to proxy modal

* adapt SO save modal to allow to add tag field

* add SO decorator registry and tag implementation

* add unit tests for SO tag decorator

* add functional tests for visualize integration

* add tag SO read permission for vis/dash feature

* add RBAC api integ tests

* add API integration tests

* add test for getTagConnectionsUrl

* add SOM test suite

* add dashboard integration suite

* remove test line

* add missing unit tests

* improve API types doc

* fix create modal save button label

* remove console.log

* improve doc

* self review

* add refresh interval for tag cache

* improve page object doc

* minor cleanup

* address review comments

* small layout fixes

* add initial focus

* use lazy accessor for tag request handler context

* adapt SOM export and export route to handle references

* remove icon from feature config due to master changes

* fix SO table tests

* update generated docs

* sort tags by name in filter dropdown and listing component

* wire SO tagging to dashboard save modal

* fix types

* - add 'create tag' action in tag selector
- add notifications on update/create/delete from management
- delete modal wording

* add description max length validation

* remove real-time validation

* fix i18n bundle id

* update expected size of savedObjectsTagging plugin

* use own useIfMounted

* update limit again, contract components cannot be lazy loaded atm.

* math is hard

* remove single usage of lodash for bundle size

* add async imports for create/edit modal

* add FTR test for 'create tag' action from tag selector

* allow 'create new' option to prepopulate name field

* extract savedObjectToTag

* add advancedSettings read user for security api_integ suite

* add audit login for security client wrapper

* use import type when possible

* wire SO tagging to lens visualization

* fix lens jest test

* Fix `create tag` option being selected when closing the selector dropdown

* add sorting to tag column from getTableColumnDef

* address some of restrry comments

* rename tag selector's setSelected option to onTagsSelected

* fix audit logging even type for saved_object_remove_references

* update plugin size limit to current size

* adapt maxlength validation wording

* remove selection column until we have batch action menu

* remove connections link when user lack read privilege to savedObjectManagement

* forbid registering multiple SO decorators with the same priority

* add so decorator test

* extract getTagFindReferences and create API mock

* update audit-logging ascidoc

* doc nit

* throw conflict error if update returns any failure

* use refresh=true as default

* wording nits

* export: rename `references` to `hasReference`

* update generated doc

* set description max length to 100

* do not initialize tag cache on anonymous pages

* split fetchObjectsToExport into two distinct functions

* change tag client `delete` call order

* tsdoc nits

* more nits

* add README for oss plugin

* add oss plugin start tests

* SavedObject.find: rename `references` to `hasReference`

* change section description label

* remove url prefix constants

* last nits and comments

* update generated doc
2020-11-03 10:33:18 +01:00

400 lines
11 KiB
TypeScript

/*
* 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 { i18n } from '@kbn/i18n';
import { KibanaFeatureConfig } from '../common';
import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/server';
export interface BuildOSSFeaturesParams {
savedObjectTypes: string[];
includeTimelion: boolean;
}
export const buildOSSFeatures = ({ savedObjectTypes, includeTimelion }: BuildOSSFeaturesParams) => {
return [
{
id: 'discover',
name: i18n.translate('xpack.features.discoverFeatureName', {
defaultMessage: 'Discover',
}),
order: 100,
category: DEFAULT_APP_CATEGORIES.kibana,
app: ['discover', 'kibana'],
catalogue: ['discover'],
privileges: {
all: {
app: ['discover', 'kibana'],
catalogue: ['discover'],
savedObject: {
all: ['search', 'query', 'index-pattern'],
read: [],
},
ui: ['show', 'save', 'saveQuery'],
},
read: {
app: ['discover', 'kibana'],
catalogue: ['discover'],
savedObject: {
all: [],
read: ['index-pattern', 'search', 'query'],
},
ui: ['show'],
},
},
subFeatures: [
{
name: i18n.translate('xpack.features.ossFeatures.discoverShortUrlSubFeatureName', {
defaultMessage: 'Short URLs',
}),
privilegeGroups: [
{
groupType: 'independent',
privileges: [
{
id: 'url_create',
name: i18n.translate(
'xpack.features.ossFeatures.discoverCreateShortUrlPrivilegeName',
{
defaultMessage: 'Create Short URLs',
}
),
includeIn: 'all',
savedObject: {
all: ['url'],
read: [],
},
ui: ['createShortUrl'],
},
],
},
],
},
],
},
{
id: 'visualize',
name: i18n.translate('xpack.features.visualizeFeatureName', {
defaultMessage: 'Visualize',
}),
order: 700,
category: DEFAULT_APP_CATEGORIES.kibana,
app: ['visualize', 'lens', 'kibana'],
catalogue: ['visualize'],
privileges: {
all: {
app: ['visualize', 'lens', 'kibana'],
catalogue: ['visualize'],
savedObject: {
all: ['visualization', 'query', 'lens'],
read: ['index-pattern', 'search', 'tag'],
},
ui: ['show', 'delete', 'save', 'saveQuery'],
},
read: {
app: ['visualize', 'lens', 'kibana'],
catalogue: ['visualize'],
savedObject: {
all: [],
read: ['index-pattern', 'search', 'visualization', 'query', 'lens', 'tag'],
},
ui: ['show'],
},
},
subFeatures: [
{
name: i18n.translate('xpack.features.ossFeatures.visualizeShortUrlSubFeatureName', {
defaultMessage: 'Short URLs',
}),
privilegeGroups: [
{
groupType: 'independent',
privileges: [
{
id: 'url_create',
name: i18n.translate(
'xpack.features.ossFeatures.visualizeCreateShortUrlPrivilegeName',
{
defaultMessage: 'Create Short URLs',
}
),
includeIn: 'all',
savedObject: {
all: ['url'],
read: [],
},
ui: ['createShortUrl'],
},
],
},
],
},
],
},
{
id: 'dashboard',
name: i18n.translate('xpack.features.dashboardFeatureName', {
defaultMessage: 'Dashboard',
}),
order: 200,
category: DEFAULT_APP_CATEGORIES.kibana,
app: ['dashboards', 'kibana'],
catalogue: ['dashboard'],
privileges: {
all: {
app: ['dashboards', 'kibana'],
catalogue: ['dashboard'],
savedObject: {
all: ['dashboard', 'query'],
read: [
'index-pattern',
'search',
'visualization',
'timelion-sheet',
'canvas-workpad',
'lens',
'map',
'tag',
],
},
ui: ['createNew', 'show', 'showWriteControls', 'saveQuery'],
},
read: {
app: ['dashboards', 'kibana'],
catalogue: ['dashboard'],
savedObject: {
all: [],
read: [
'index-pattern',
'search',
'visualization',
'timelion-sheet',
'canvas-workpad',
'lens',
'map',
'dashboard',
'query',
'tag',
],
},
ui: ['show'],
},
},
subFeatures: [
{
name: i18n.translate('xpack.features.ossFeatures.dashboardShortUrlSubFeatureName', {
defaultMessage: 'Short URLs',
}),
privilegeGroups: [
{
groupType: 'independent',
privileges: [
{
id: 'url_create',
name: i18n.translate(
'xpack.features.ossFeatures.dashboardCreateShortUrlPrivilegeName',
{
defaultMessage: 'Create Short URLs',
}
),
includeIn: 'all',
savedObject: {
all: ['url'],
read: [],
},
ui: ['createShortUrl'],
},
],
},
],
},
],
},
{
id: 'dev_tools',
name: i18n.translate('xpack.features.devToolsFeatureName', {
defaultMessage: 'Dev Tools',
}),
order: 1300,
category: DEFAULT_APP_CATEGORIES.management,
app: ['dev_tools', 'kibana'],
catalogue: ['console', 'searchprofiler', 'grokdebugger'],
privileges: {
all: {
app: ['dev_tools', 'kibana'],
catalogue: ['console', 'searchprofiler', 'grokdebugger'],
api: ['console'],
savedObject: {
all: [],
read: [],
},
ui: ['show', 'save'],
},
read: {
app: ['dev_tools', 'kibana'],
catalogue: ['console', 'searchprofiler', 'grokdebugger'],
api: ['console'],
savedObject: {
all: [],
read: [],
},
ui: ['show'],
},
},
privilegesTooltip: i18n.translate('xpack.features.devToolsPrivilegesTooltip', {
defaultMessage:
'User should also be granted the appropriate Elasticsearch cluster and index privileges',
}),
},
{
id: 'advancedSettings',
name: i18n.translate('xpack.features.advancedSettingsFeatureName', {
defaultMessage: 'Advanced Settings',
}),
order: 1500,
category: DEFAULT_APP_CATEGORIES.management,
app: ['kibana'],
catalogue: ['advanced_settings'],
management: {
kibana: ['settings'],
},
privileges: {
all: {
app: ['kibana'],
catalogue: ['advanced_settings'],
management: {
kibana: ['settings'],
},
savedObject: {
all: ['config'],
read: [],
},
ui: ['save'],
},
read: {
app: ['kibana'],
catalogue: ['advanced_settings'],
management: {
kibana: ['settings'],
},
savedObject: {
all: [],
read: [],
},
ui: [],
},
},
},
{
id: 'indexPatterns',
name: i18n.translate('xpack.features.indexPatternFeatureName', {
defaultMessage: 'Index Pattern Management',
}),
order: 1600,
category: DEFAULT_APP_CATEGORIES.management,
app: ['kibana'],
catalogue: ['indexPatterns'],
management: {
kibana: ['indexPatterns'],
},
privileges: {
all: {
app: ['kibana'],
catalogue: ['indexPatterns'],
management: {
kibana: ['indexPatterns'],
},
savedObject: {
all: ['index-pattern'],
read: [],
},
ui: ['save'],
},
read: {
app: ['kibana'],
catalogue: ['indexPatterns'],
management: {
kibana: ['indexPatterns'],
},
savedObject: {
all: [],
read: ['index-pattern'],
},
ui: [],
},
},
},
{
id: 'savedObjectsManagement',
name: i18n.translate('xpack.features.savedObjectsManagementFeatureName', {
defaultMessage: 'Saved Objects Management',
}),
order: 1700,
category: DEFAULT_APP_CATEGORIES.management,
app: ['kibana'],
catalogue: ['saved_objects'],
management: {
kibana: ['objects'],
},
privileges: {
all: {
app: ['kibana'],
catalogue: ['saved_objects'],
management: {
kibana: ['objects'],
},
api: ['copySavedObjectsToSpaces'],
savedObject: {
all: [...savedObjectTypes],
read: [],
},
ui: ['read', 'edit', 'delete', 'copyIntoSpace', 'shareIntoSpace'],
},
read: {
app: ['kibana'],
catalogue: ['saved_objects'],
management: {
kibana: ['objects'],
},
api: ['copySavedObjectsToSpaces'],
savedObject: {
all: [],
read: [...savedObjectTypes],
},
ui: ['read'],
},
},
},
...(includeTimelion ? [timelionFeature] : []),
] as KibanaFeatureConfig[];
};
const timelionFeature: KibanaFeatureConfig = {
id: 'timelion',
name: 'Timelion',
order: 350,
category: DEFAULT_APP_CATEGORIES.kibana,
app: ['timelion', 'kibana'],
catalogue: ['timelion'],
privileges: {
all: {
app: ['timelion', 'kibana'],
catalogue: ['timelion'],
savedObject: {
all: ['timelion-sheet'],
read: ['index-pattern'],
},
ui: ['save'],
},
read: {
app: ['timelion', 'kibana'],
catalogue: ['timelion'],
savedObject: {
all: [],
read: ['index-pattern', 'timelion-sheet'],
},
ui: [],
},
},
};