kibana/x-pack/plugins/features/server/oss_features.ts
Julia Rechkunova 7fa04e92bc
[Kibana] New "Saved Query Management" privilege to allow saving queries across Kibana (#166937)
- Resolves https://github.com/elastic/kibana/issues/158173

Based on PoC https://github.com/elastic/kibana/pull/166260

## Summary

This PR adds a new "Saved Query Management" privilege with 2 options:
- `All` will override any per app privilege and will allow users to save
queries from any Kibana page
- `None` will default to per app privileges (backward-compatible option)

<img width="600" alt="Screenshot 2023-09-21 at 15 26 25"
src="6d53548e-5c5a-4d6d-a86a-1e639cb77202">

### Checklist

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

---------

Co-authored-by: Matthias Wilhelm <matthias.wilhelm@elastic.co>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Stratoula Kalafateli <efstratia.kalafateli@elastic.co>
2023-09-29 11:52:39 +02:00

643 lines
18 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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { i18n } from '@kbn/i18n';
import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server';
import type { KibanaFeatureConfig, SubFeatureConfig } from '../common';
export interface BuildOSSFeaturesParams {
savedObjectTypes: string[];
includeReporting: boolean;
}
export const buildOSSFeatures = ({
savedObjectTypes,
includeReporting,
}: BuildOSSFeaturesParams): KibanaFeatureConfig[] => {
return [
{
id: 'discover',
name: i18n.translate('xpack.features.discoverFeatureName', {
defaultMessage: 'Discover',
}),
management: {
kibana: ['search_sessions'],
...(includeReporting ? { insightsAndAlerting: ['reporting'] } : {}),
},
order: 100,
category: DEFAULT_APP_CATEGORIES.kibana,
app: ['discover', 'kibana'],
catalogue: ['discover'],
privileges: {
all: {
app: ['discover', 'kibana'],
api: ['fileUpload:analyzeFile'],
catalogue: ['discover'],
savedObject: {
all: ['search', 'query'],
read: ['index-pattern'],
},
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'],
},
],
},
],
},
{
name: i18n.translate('xpack.features.ossFeatures.discoverSearchSessionsFeatureName', {
defaultMessage: 'Store Search Sessions',
}),
privilegeGroups: [
{
groupType: 'independent',
privileges: [
{
id: 'store_search_session',
name: i18n.translate(
'xpack.features.ossFeatures.discoverStoreSearchSessionsPrivilegeName',
{
defaultMessage: 'Store Search Sessions',
}
),
includeIn: 'all',
savedObject: {
all: ['search-session'],
read: [],
},
ui: ['storeSearchSession'],
management: {
kibana: ['search_sessions'],
},
api: ['store_search_session'],
},
],
},
],
},
...(includeReporting ? [reportingFeatures.discoverReporting] : []),
],
},
{
id: 'visualize',
name: i18n.translate('xpack.features.visualizeFeatureName', {
defaultMessage: 'Visualize Library',
}),
management: {
...(includeReporting ? { insightsAndAlerting: ['reporting'] } : {}),
},
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'],
},
],
},
],
},
...(includeReporting ? [reportingFeatures.visualizeReporting] : []),
],
},
{
id: 'dashboard',
name: i18n.translate('xpack.features.dashboardFeatureName', {
defaultMessage: 'Dashboard',
}),
management: {
kibana: ['search_sessions'],
...(includeReporting ? { insightsAndAlerting: ['reporting'] } : {}),
},
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',
'canvas-workpad',
'lens',
'map',
'tag',
],
},
ui: ['createNew', 'show', 'showWriteControls', 'saveQuery'],
},
read: {
app: ['dashboards', 'kibana'],
catalogue: ['dashboard'],
savedObject: {
all: [],
read: [
'index-pattern',
'search',
'visualization',
'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'],
},
],
},
],
},
{
name: i18n.translate('xpack.features.ossFeatures.dashboardSearchSessionsFeatureName', {
defaultMessage: 'Store Search Sessions',
}),
privilegeGroups: [
{
groupType: 'independent',
privileges: [
{
id: 'store_search_session',
name: i18n.translate(
'xpack.features.ossFeatures.dashboardStoreSearchSessionsPrivilegeName',
{
defaultMessage: 'Store Search Sessions',
}
),
includeIn: 'all',
savedObject: {
all: ['search-session'],
read: [],
},
ui: ['storeSearchSession'],
management: {
kibana: ['search_sessions'],
},
api: ['store_search_session'],
},
],
},
],
},
...(includeReporting ? [reportingFeatures.dashboardReporting] : []),
],
},
{
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.dataViewFeatureName', {
defaultMessage: 'Data View 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: 'filesManagement',
name: i18n.translate('xpack.features.filesManagementFeatureName', {
defaultMessage: 'Files Management',
}),
order: 1600,
category: DEFAULT_APP_CATEGORIES.management,
app: ['kibana'],
catalogue: [],
management: {
kibana: ['filesManagement'],
},
privileges: {
all: {
app: ['kibana'],
management: {
kibana: ['filesManagement'],
},
savedObject: {
all: ['file', 'fileShare'],
read: [],
},
ui: [],
api: ['files:manageFiles', 'files:defaultImage'],
},
read: {
app: ['kibana'],
management: {
kibana: ['filesManagement'],
},
savedObject: {
all: [],
read: ['file', 'fileShare'],
},
ui: [],
api: ['files:manageFiles', 'files:defaultImage'],
},
},
},
{
id: 'filesSharedImage',
name: i18n.translate('xpack.features.filesSharedImagesFeatureName', {
defaultMessage: 'Shared images',
}),
order: 1600,
category: DEFAULT_APP_CATEGORIES.management,
app: ['kibana'],
catalogue: [],
privilegesTooltip: i18n.translate('xpack.features.filesSharedImagesPrivilegesTooltip', {
defaultMessage: 'Required to access images stored in Kibana.',
}),
privileges: {
all: {
app: ['kibana'],
savedObject: {
all: ['file'],
read: [],
},
ui: [],
api: ['files:defaultImage'],
},
read: {
app: ['kibana'],
savedObject: {
all: [],
read: ['file'],
},
ui: [],
api: ['files:defaultImage'],
},
},
},
{
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'],
},
},
},
{
id: 'savedQueryManagement',
name: i18n.translate('xpack.features.savedQueryManagementFeatureName', {
defaultMessage: 'Saved Query Management',
}),
order: 1750,
category: DEFAULT_APP_CATEGORIES.management,
app: ['kibana'],
catalogue: [],
privilegesTooltip: i18n.translate('xpack.features.savedQueryManagementTooltip', {
defaultMessage:
'If set to "All", saved queries can be managed across Kibana in all applications that support them. If set to "None", saved query privileges will be determined independently by each application.',
}),
privileges: {
all: {
app: ['kibana'],
catalogue: [],
savedObject: {
all: ['query'],
read: [],
},
ui: ['saveQuery'],
}, // No read-only mode supported
},
},
] as KibanaFeatureConfig[];
};
const reportingPrivilegeGroupName = i18n.translate(
'xpack.features.ossFeatures.reporting.reportingTitle',
{
defaultMessage: 'Reporting',
}
);
const reportingFeatures: {
discoverReporting: SubFeatureConfig;
dashboardReporting: SubFeatureConfig;
visualizeReporting: SubFeatureConfig;
} = {
discoverReporting: {
name: reportingPrivilegeGroupName,
privilegeGroups: [
{
groupType: 'independent',
privileges: [
{
id: 'generate_report',
name: i18n.translate('xpack.features.ossFeatures.reporting.discoverGenerateCSV', {
defaultMessage: 'Generate CSV reports',
}),
includeIn: 'all',
savedObject: { all: [], read: [] },
management: { insightsAndAlerting: ['reporting'] },
api: ['generateReport'],
ui: ['generateCsv'],
},
],
},
],
},
dashboardReporting: {
name: reportingPrivilegeGroupName,
privilegeGroups: [
{
groupType: 'independent',
privileges: [
{
id: 'generate_report',
name: i18n.translate(
'xpack.features.ossFeatures.reporting.dashboardGenerateScreenshot',
{
defaultMessage: 'Generate PDF or PNG reports',
}
),
includeIn: 'all',
minimumLicense: 'gold',
savedObject: { all: [], read: [] },
management: { insightsAndAlerting: ['reporting'] },
api: ['generateReport'],
ui: ['generateScreenshot'],
},
{
id: 'download_csv_report',
name: i18n.translate('xpack.features.ossFeatures.reporting.dashboardDownloadCSV', {
defaultMessage: 'Download CSV reports from Saved Search panels',
}),
includeIn: 'all',
savedObject: { all: [], read: [] },
management: { insightsAndAlerting: ['reporting'] },
api: ['downloadCsv'],
ui: ['downloadCsv'],
},
],
},
],
},
visualizeReporting: {
name: reportingPrivilegeGroupName,
privilegeGroups: [
{
groupType: 'independent',
privileges: [
{
id: 'generate_report',
name: i18n.translate(
'xpack.features.ossFeatures.reporting.visualizeGenerateScreenshot',
{
defaultMessage: 'Generate PDF or PNG reports',
}
),
includeIn: 'all',
minimumLicense: 'gold',
savedObject: { all: [], read: [] },
management: { insightsAndAlerting: ['reporting'] },
api: ['generateReport'],
ui: ['generateScreenshot'],
},
],
},
],
},
};