[Reporting] Kibana Application Privileges for Reporting (#94966)

* Implement Reporting features as subfeatures of applications

* add setting to the docker list

* update doc images

* finish docs

* Apply suggestions from code review

Co-authored-by: Kaarina Tungseth <kaarina.tungseth@elastic.co>

* Apply suggestions from code review

Co-authored-by: Kaarina Tungseth <kaarina.tungseth@elastic.co>

* Apply suggestions from code review

Co-authored-by: Kaarina Tungseth <kaarina.tungseth@elastic.co>

* typo fix

* "PDF / PNG Reports" => "Reporting"

* Update x-pack/plugins/reporting/server/config/index.ts

Co-authored-by: Larry Gregory <lgregorydev@gmail.com>

* Update x-pack/test/functional/apps/security/secure_roles_perm.js

Co-authored-by: Larry Gregory <lgregorydev@gmail.com>

* update ids of report privileges

* combine dashboard privileges into 1 group

* update jest snapshot

* fix tests

* fix tests

* updates from feedback

* add note

* update screenshot

* fix grammer

* fix bad link breaks in doc

* update doc heading

* Apply suggestions documentation feedback

Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com>

* simplify

* use const assertions

* Apply text change suggestion from code review

Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com>

* more test for oss_features and reporting subFeatures

* reduce loc diff

* fix snapshot

* fix flakiness in licensing plugin public functional tests

Co-authored-by: Kaarina Tungseth <kaarina.tungseth@elastic.co>
Co-authored-by: Larry Gregory <lgregorydev@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com>
This commit is contained in:
Tim Sullivan 2021-04-20 20:44:24 -07:00 committed by GitHub
parent e39b8c6d36
commit 5a6eda2b22
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
84 changed files with 2316 additions and 705 deletions

View file

@ -1,5 +1,461 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`buildOSSFeatures returns features excluding reporting subfeatures 1`] = `
Array [
Object {
"id": "discover",
"subFeatures": Array [
Object {
"name": "Short URLs",
"privilegeGroups": Array [
Object {
"groupType": "independent",
"privileges": Array [
Object {
"id": "url_create",
"includeIn": "all",
"name": "Create Short URLs",
"savedObject": Object {
"all": Array [
"url",
],
"read": Array [],
},
"ui": Array [
"createShortUrl",
],
},
],
},
],
},
Object {
"name": "Store Search Sessions",
"privilegeGroups": Array [
Object {
"groupType": "independent",
"privileges": Array [
Object {
"api": Array [
"store_search_session",
],
"id": "store_search_session",
"includeIn": "all",
"management": Object {
"kibana": Array [
"search_sessions",
],
},
"name": "Store Search Sessions",
"savedObject": Object {
"all": Array [
"search-session",
],
"read": Array [],
},
"ui": Array [
"storeSearchSession",
],
},
],
},
],
},
],
},
Object {
"id": "visualize",
"subFeatures": Array [
Object {
"name": "Short URLs",
"privilegeGroups": Array [
Object {
"groupType": "independent",
"privileges": Array [
Object {
"id": "url_create",
"includeIn": "all",
"name": "Create Short URLs",
"savedObject": Object {
"all": Array [
"url",
],
"read": Array [],
},
"ui": Array [
"createShortUrl",
],
},
],
},
],
},
],
},
Object {
"id": "dashboard",
"subFeatures": Array [
Object {
"name": "Short URLs",
"privilegeGroups": Array [
Object {
"groupType": "independent",
"privileges": Array [
Object {
"id": "url_create",
"includeIn": "all",
"name": "Create Short URLs",
"savedObject": Object {
"all": Array [
"url",
],
"read": Array [],
},
"ui": Array [
"createShortUrl",
],
},
],
},
],
},
Object {
"name": "Store Search Sessions",
"privilegeGroups": Array [
Object {
"groupType": "independent",
"privileges": Array [
Object {
"api": Array [
"store_search_session",
],
"id": "store_search_session",
"includeIn": "all",
"management": Object {
"kibana": Array [
"search_sessions",
],
},
"name": "Store Search Sessions",
"savedObject": Object {
"all": Array [
"search-session",
],
"read": Array [],
},
"ui": Array [
"storeSearchSession",
],
},
],
},
],
},
],
},
Object {
"id": "dev_tools",
"subFeatures": undefined,
},
Object {
"id": "advancedSettings",
"subFeatures": undefined,
},
Object {
"id": "indexPatterns",
"subFeatures": undefined,
},
Object {
"id": "savedObjectsManagement",
"subFeatures": undefined,
},
]
`;
exports[`buildOSSFeatures returns features including reporting subfeatures 1`] = `
Array [
Object {
"id": "discover",
"subFeatures": Array [
Object {
"name": "Short URLs",
"privilegeGroups": Array [
Object {
"groupType": "independent",
"privileges": Array [
Object {
"id": "url_create",
"includeIn": "all",
"name": "Create Short URLs",
"savedObject": Object {
"all": Array [
"url",
],
"read": Array [],
},
"ui": Array [
"createShortUrl",
],
},
],
},
],
},
Object {
"name": "Store Search Sessions",
"privilegeGroups": Array [
Object {
"groupType": "independent",
"privileges": Array [
Object {
"api": Array [
"store_search_session",
],
"id": "store_search_session",
"includeIn": "all",
"management": Object {
"kibana": Array [
"search_sessions",
],
},
"name": "Store Search Sessions",
"savedObject": Object {
"all": Array [
"search-session",
],
"read": Array [],
},
"ui": Array [
"storeSearchSession",
],
},
],
},
],
},
Object {
"name": "Reporting",
"privilegeGroups": Array [
Object {
"groupType": "independent",
"privileges": Array [
Object {
"api": Array [
"generateReport",
],
"id": "generate_report",
"includeIn": "all",
"management": Object {
"insightsAndAlerting": Array [
"reporting",
],
},
"name": "Generate CSV reports",
"savedObject": Object {
"all": Array [],
"read": Array [],
},
"ui": Array [
"generateCsv",
],
},
],
},
],
},
],
},
Object {
"id": "visualize",
"subFeatures": Array [
Object {
"name": "Short URLs",
"privilegeGroups": Array [
Object {
"groupType": "independent",
"privileges": Array [
Object {
"id": "url_create",
"includeIn": "all",
"name": "Create Short URLs",
"savedObject": Object {
"all": Array [
"url",
],
"read": Array [],
},
"ui": Array [
"createShortUrl",
],
},
],
},
],
},
Object {
"name": "Reporting",
"privilegeGroups": Array [
Object {
"groupType": "independent",
"privileges": Array [
Object {
"api": Array [
"generateReport",
],
"id": "generate_report",
"includeIn": "all",
"management": Object {
"insightsAndAlerting": Array [
"reporting",
],
},
"minimumLicense": "platinum",
"name": "Generate PDF or PNG reports",
"savedObject": Object {
"all": Array [],
"read": Array [],
},
"ui": Array [
"generateScreenshot",
],
},
],
},
],
},
],
},
Object {
"id": "dashboard",
"subFeatures": Array [
Object {
"name": "Short URLs",
"privilegeGroups": Array [
Object {
"groupType": "independent",
"privileges": Array [
Object {
"id": "url_create",
"includeIn": "all",
"name": "Create Short URLs",
"savedObject": Object {
"all": Array [
"url",
],
"read": Array [],
},
"ui": Array [
"createShortUrl",
],
},
],
},
],
},
Object {
"name": "Store Search Sessions",
"privilegeGroups": Array [
Object {
"groupType": "independent",
"privileges": Array [
Object {
"api": Array [
"store_search_session",
],
"id": "store_search_session",
"includeIn": "all",
"management": Object {
"kibana": Array [
"search_sessions",
],
},
"name": "Store Search Sessions",
"savedObject": Object {
"all": Array [
"search-session",
],
"read": Array [],
},
"ui": Array [
"storeSearchSession",
],
},
],
},
],
},
Object {
"name": "Reporting",
"privilegeGroups": Array [
Object {
"groupType": "independent",
"privileges": Array [
Object {
"api": Array [
"generateReport",
],
"id": "generate_report",
"includeIn": "all",
"management": Object {
"insightsAndAlerting": Array [
"reporting",
],
},
"minimumLicense": "platinum",
"name": "Generate PDF or PNG reports",
"savedObject": Object {
"all": Array [],
"read": Array [],
},
"ui": Array [
"generateScreenshot",
],
},
Object {
"api": Array [
"downloadCsv",
],
"id": "download_csv_report",
"includeIn": "all",
"management": Object {
"insightsAndAlerting": Array [
"reporting",
],
},
"name": "Download CSV reports from Saved Search panels",
"savedObject": Object {
"all": Array [],
"read": Array [],
},
"ui": Array [
"downloadCsv",
],
},
],
},
],
},
],
},
Object {
"id": "dev_tools",
"subFeatures": undefined,
},
Object {
"id": "advancedSettings",
"subFeatures": undefined,
},
Object {
"id": "indexPatterns",
"subFeatures": undefined,
},
Object {
"id": "savedObjectsManagement",
"subFeatures": undefined,
},
]
`;
exports[`buildOSSFeatures with a basic license returns the advancedSettings feature augmented with appropriate sub feature privileges 1`] = `
Array [
Object {

View file

@ -14,6 +14,7 @@ const createSetup = (): jest.Mocked<PluginSetupContract> => {
getFeaturesUICapabilities: jest.fn(),
registerKibanaFeature: jest.fn(),
registerElasticsearchFeature: jest.fn(),
enableReportingUiCapabilities: jest.fn(),
};
};

View file

@ -14,7 +14,11 @@ import { LicenseType } from '../../licensing/server';
describe('buildOSSFeatures', () => {
it('returns features including timelion', () => {
expect(
buildOSSFeatures({ savedObjectTypes: ['foo', 'bar'], includeTimelion: true }).map((f) => f.id)
buildOSSFeatures({
savedObjectTypes: ['foo', 'bar'],
includeTimelion: true,
includeReporting: false,
}).map((f) => f.id)
).toMatchInlineSnapshot(`
Array [
"discover",
@ -31,9 +35,11 @@ Array [
it('returns features excluding timelion', () => {
expect(
buildOSSFeatures({ savedObjectTypes: ['foo', 'bar'], includeTimelion: false }).map(
(f) => f.id
)
buildOSSFeatures({
savedObjectTypes: ['foo', 'bar'],
includeTimelion: false,
includeReporting: false,
}).map((f) => f.id)
).toMatchInlineSnapshot(`
Array [
"discover",
@ -47,7 +53,31 @@ Array [
`);
});
const features = buildOSSFeatures({ savedObjectTypes: ['foo', 'bar'], includeTimelion: true });
it('returns features including reporting subfeatures', () => {
expect(
buildOSSFeatures({
savedObjectTypes: ['foo', 'bar'],
includeTimelion: false,
includeReporting: true,
}).map(({ id, subFeatures }) => ({ id, subFeatures }))
).toMatchSnapshot();
});
it('returns features excluding reporting subfeatures', () => {
expect(
buildOSSFeatures({
savedObjectTypes: ['foo', 'bar'],
includeTimelion: false,
includeReporting: false,
}).map(({ id, subFeatures }) => ({ id, subFeatures }))
).toMatchSnapshot();
});
const features = buildOSSFeatures({
savedObjectTypes: ['foo', 'bar'],
includeTimelion: true,
includeReporting: false,
});
features.forEach((featureConfig) => {
(['enterprise', 'basic'] as LicenseType[]).forEach((licenseType) => {
describe(`with a ${licenseType} license`, () => {

View file

@ -6,15 +6,20 @@
*/
import { i18n } from '@kbn/i18n';
import { KibanaFeatureConfig } from '../common';
import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/server';
import type { KibanaFeatureConfig, SubFeatureConfig } from '../common';
export interface BuildOSSFeaturesParams {
savedObjectTypes: string[];
includeTimelion: boolean;
includeReporting: boolean;
}
export const buildOSSFeatures = ({ savedObjectTypes, includeTimelion }: BuildOSSFeaturesParams) => {
export const buildOSSFeatures = ({
savedObjectTypes,
includeTimelion,
includeReporting,
}: BuildOSSFeaturesParams): KibanaFeatureConfig[] => {
return [
{
id: 'discover',
@ -23,6 +28,7 @@ export const buildOSSFeatures = ({ savedObjectTypes, includeTimelion }: BuildOSS
}),
management: {
kibana: ['search_sessions'],
...(includeReporting ? { insightsAndAlerting: ['reporting'] } : {}),
},
order: 100,
category: DEFAULT_APP_CATEGORIES.kibana,
@ -107,6 +113,7 @@ export const buildOSSFeatures = ({ savedObjectTypes, includeTimelion }: BuildOSS
},
],
},
...(includeReporting ? [reportingFeatures.discoverReporting] : []),
],
},
{
@ -114,6 +121,9 @@ export const buildOSSFeatures = ({ savedObjectTypes, includeTimelion }: BuildOSS
name: i18n.translate('xpack.features.visualizeFeatureName', {
defaultMessage: 'Visualize Library',
}),
management: {
...(includeReporting ? { insightsAndAlerting: ['reporting'] } : {}),
},
order: 700,
category: DEFAULT_APP_CATEGORIES.kibana,
app: ['visualize', 'lens', 'kibana'],
@ -166,6 +176,7 @@ export const buildOSSFeatures = ({ savedObjectTypes, includeTimelion }: BuildOSS
},
],
},
...(includeReporting ? [reportingFeatures.visualizeReporting] : []),
],
},
{
@ -175,6 +186,7 @@ export const buildOSSFeatures = ({ savedObjectTypes, includeTimelion }: BuildOSS
}),
management: {
kibana: ['search_sessions'],
...(includeReporting ? { insightsAndAlerting: ['reporting'] } : {}),
},
order: 200,
category: DEFAULT_APP_CATEGORIES.kibana,
@ -279,6 +291,7 @@ export const buildOSSFeatures = ({ savedObjectTypes, includeTimelion }: BuildOSS
},
],
},
...(includeReporting ? [reportingFeatures.dashboardReporting] : []),
],
},
{
@ -468,3 +481,99 @@ const timelionFeature: 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: 'platinum',
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: 'platinum',
savedObject: { all: [], read: [] },
management: { insightsAndAlerting: ['reporting'] },
api: ['generateReport'],
ui: ['generateScreenshot'],
},
],
},
],
},
};

View file

@ -46,6 +46,14 @@ export interface PluginSetupContract {
* */
getElasticsearchFeatures(): ElasticsearchFeature[];
getFeaturesUICapabilities(): UICapabilities;
/*
* In the future, OSS features should register their own subfeature
* privileges. This can be done when parts of Reporting are moved to
* src/plugins. For now, this method exists for `reporting` to tell
* `features` to include Reporting when registering OSS features.
*/
enableReportingUiCapabilities(): void;
}
export interface PluginStartContract {
@ -66,6 +74,7 @@ export class FeaturesPlugin
private readonly logger: Logger;
private readonly featureRegistry: FeatureRegistry = new FeatureRegistry();
private isTimelionEnabled: boolean = false;
private isReportingEnabled: boolean = false;
constructor(private readonly initializerContext: PluginInitializerContext) {
this.logger = this.initializerContext.logger.get();
@ -100,6 +109,7 @@ export class FeaturesPlugin
this.featureRegistry
),
getFeaturesUICapabilities,
enableReportingUiCapabilities: this.enableReportingUiCapabilities.bind(this),
});
}
@ -128,10 +138,18 @@ export class FeaturesPlugin
const features = buildOSSFeatures({
savedObjectTypes,
includeTimelion: this.isTimelionEnabled,
includeReporting: this.isReportingEnabled,
});
for (const feature of features) {
this.featureRegistry.registerKibanaFeature(feature);
}
}
private enableReportingUiCapabilities() {
this.logger.debug(
`Feature controls for Reporting plugin are enabled. Please assign access to Reporting use Kibana feature controls for applications.`
);
this.isReportingEnabled = true;
}
}