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

[Reporting] Add deprecation messages for roles mapped to reporting_user #115125

Merged
Merged
2 changes: 1 addition & 1 deletion x-pack/plugins/reporting/server/config/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe('deprecations', () => {
const { messages } = applyReportingDeprecations({ roles: { enabled: true } });
expect(messages).toMatchInlineSnapshot(`
Array [
"Use Kibana application privileges to grant reporting privileges. Using \\"xpack.reporting.roles.allow\\" to grant reporting privileges prevents users from using API Keys to create reports. The \\"xpack.reporting.roles.enabled\\" setting will default to false in a future release.",
"Use Kibana application privileges to grant reporting privileges. Using \\"xpack.reporting.roles.allow\\" to grant reporting privileges is deprecated. The \\"xpack.reporting.roles.enabled\\" setting will default to false in a future release.",
]
`);
});
Expand Down
5 changes: 4 additions & 1 deletion x-pack/plugins/reporting/server/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const config: PluginConfigDescriptor<ReportingConfigType> = {
defaultMessage:
`Use Kibana application privileges to grant reporting privileges.` +
` Using "{fromPath}.roles.allow" to grant reporting privileges` +
` prevents users from using API Keys to create reports.` +
` is deprecated.` +
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unrelated to this PR, but the existing text in this config deprecation was really hard to read on the page.

` The "{fromPath}.roles.enabled" setting will default to false` +
` in a future release.`,
values: { fromPath },
Expand All @@ -74,6 +74,9 @@ export const config: PluginConfigDescriptor<ReportingConfigType> = {
i18n.translate('xpack.reporting.deprecations.reportingRoles.manualStepOne', {
defaultMessage: `Set "xpack.reporting.roles.enabled" to "false" in kibana.yml.`,
}),
i18n.translate('xpack.reporting.deprecations.reportingRoles.manualStepOnePartOne', {
defaultMessage: `Remove "xpack.reporting.roles.allow" to "false" in kibana.yml, if present.`,
}),
i18n.translate('xpack.reporting.deprecations.reportingRoles.manualStepTwo', {
defaultMessage:
`Create one or more roles that grant the Kibana application` +
Expand Down
9 changes: 5 additions & 4 deletions x-pack/plugins/reporting/server/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
BasePath,
IClusterClient,
KibanaRequest,
PackageInfo,
PluginInitializerContext,
SavedObjectsClientContract,
SavedObjectsServiceStart,
Expand Down Expand Up @@ -57,7 +58,7 @@ export interface ReportingInternalStart {
}

export class ReportingCore {
private kibanaVersion: string;
private packageInfo: PackageInfo;
private pluginSetupDeps?: ReportingInternalSetup;
private pluginStartDeps?: ReportingInternalStart;
private readonly pluginSetup$ = new Rx.ReplaySubject<boolean>(); // observe async background setupDeps and config each are done
Expand All @@ -72,7 +73,7 @@ export class ReportingCore {
public getContract: () => ReportingSetup;

constructor(private logger: LevelLogger, context: PluginInitializerContext<ReportingConfigType>) {
this.kibanaVersion = context.env.packageInfo.version;
this.packageInfo = context.env.packageInfo;
const syncConfig = context.config.get<ReportingConfigType>();
this.deprecatedAllowedRoles = syncConfig.roles.enabled ? syncConfig.roles.allow : false;
this.executeTask = new ExecuteReportTask(this, syncConfig, this.logger);
Expand All @@ -85,8 +86,8 @@ export class ReportingCore {
this.executing = new Set();
}

public getKibanaVersion() {
return this.kibanaVersion;
public getKibanaPackageInfo() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is to allow documentation links generated on the server to use the current branch.

return this.packageInfo;
}

/*
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

165 changes: 93 additions & 72 deletions x-pack/plugins/reporting/server/deprecations/reporting_role.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@
* 2.0.
*/

import { GetDeprecationsContext, IScopedClusterClient } from 'kibana/server';
import { elasticsearchServiceMock } from 'src/core/server/mocks';
import { ReportingCore } from '..';
import {
createMockConfigSchema,
createMockPluginSetup,
createMockReportingCore,
} from '../test_helpers';
import { getDeprecationsInfo } from './reporting_role';
import { createMockConfigSchema, createMockReportingCore } from '../test_helpers';
import { elasticsearchServiceMock } from 'src/core/server/mocks';
import { GetDeprecationsContext, IScopedClusterClient } from 'kibana/server';

let reportingCore: ReportingCore;
let context: GetDeprecationsContext;
Expand All @@ -18,6 +22,7 @@ let esClient: jest.Mocked<IScopedClusterClient>;
beforeEach(async () => {
const mockReportingConfig = createMockConfigSchema({ roles: { enabled: false } });
reportingCore = await createMockReportingCore(mockReportingConfig);

esClient = elasticsearchServiceMock.createScopedClusterClient();
esClient.asCurrentUser.security.getUser = jest.fn().mockResolvedValue({
body: { xyz: { username: 'normal_user', roles: ['data_analyst'] } },
Expand All @@ -26,95 +31,111 @@ beforeEach(async () => {
});

test('logs no deprecations when setup has no issues', async () => {
expect(
await getDeprecationsInfo(context, {
reportingCore,
})
).toMatchInlineSnapshot(`Array []`);
expect(await getDeprecationsInfo(context, { reportingCore })).toMatchInlineSnapshot(`Array []`);
});

test('logs a plain message when only a reporting_user role issue is found', async () => {
esClient.asCurrentUser.security.getUser = jest.fn().mockResolvedValue({
body: { reportron: { username: 'reportron', roles: ['kibana_admin', 'reporting_user'] } },
describe('users assigned to a deprecated role', () => {
test('logs a deprecation when a user was found with a deprecated reporting_user role', async () => {
esClient.asCurrentUser.security.getUser = jest.fn().mockResolvedValue({
body: { reportron: { username: 'reportron', roles: ['kibana_admin', 'reporting_user'] } },
});

const mockReportingConfig = createMockConfigSchema({ roles: { enabled: true } });
reportingCore = await createMockReportingCore(mockReportingConfig);

expect(await getDeprecationsInfo(context, { reportingCore })).toMatchSnapshot();
});
expect(
await getDeprecationsInfo(context, {
reportingCore,
})
).toMatchInlineSnapshot(`
Array [
Object {
"correctiveActions": Object {
"manualSteps": Array [
"Create one or more custom roles that provide Kibana application privileges to reporting features in **Management > Security > Roles**.",
"Assign the custom role(s) as desired, and remove the \\"reporting_user\\" role from the user(s).",
],
},
"documentationUrl": "https://www.elastic.co/guide/en/kibana/current/secure-reporting.html",
"level": "critical",
"message": "The deprecated \\"reporting_user\\" role has been found for 1 user(s): \\"reportron\\"",
"title": "Found deprecated reporting role",

test('logs a deprecation when a user was found with a deprecated custom role from the roles.allow setting', async () => {
reportingCore = await createMockReportingCore(
createMockConfigSchema({ roles: { enabled: true, allow: ['my_test_reporting_user'] } })
);
esClient.asCurrentUser.security.getUser = jest.fn().mockResolvedValue({
body: {
reportron: { username: 'reportron', roles: ['kibana_admin', 'my_test_reporting_user'] },
},
]
`);
});

expect(await getDeprecationsInfo(context, { reportingCore })).toMatchSnapshot();
});
});

test('logs multiple entries when multiple reporting_user role issues are found', async () => {
esClient.asCurrentUser.security.getUser = jest.fn().mockResolvedValue({
body: {
reportron: { username: 'reportron', roles: ['kibana_admin', 'reporting_user'] },
supercooluser: { username: 'supercooluser', roles: ['kibana_admin', 'reporting_user'] },
},
describe('roles mapped to a deprecated role', () => {
test('logs a deprecation when a role was found that maps to the deprecated reporting_user role', async () => {
esClient.asCurrentUser.security.getRoleMapping = jest.fn().mockResolvedValue({
body: { dungeon_master: { roles: ['reporting_user'] } },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😄

});

const mockReportingConfig = createMockConfigSchema({ roles: { enabled: true } });
reportingCore = await createMockReportingCore(mockReportingConfig);

expect(await getDeprecationsInfo(context, { reportingCore })).toMatchSnapshot();
});

expect(
await getDeprecationsInfo(context, {
reportingCore,
})
).toMatchInlineSnapshot(`
test('logs a deprecation when a role was found that maps to a deprecated custom role from the roles.allow setting', async () => {
reportingCore = await createMockReportingCore(
createMockConfigSchema({ roles: { enabled: true, allow: ['my_test_reporting_user'] } })
);
esClient.asCurrentUser.security.getRoleMapping = jest.fn().mockResolvedValue({
body: { dungeon_master: { roles: ['my_test_reporting_user'] } },
});

expect(await getDeprecationsInfo(context, { reportingCore })).toMatchSnapshot();
});
});

describe('check deprecations when security is disabled', () => {
test('logs no deprecations: roles not enabled', async () => {
const mockReportingConfig = createMockConfigSchema({ roles: { enabled: false } });
reportingCore = await createMockReportingCore(
mockReportingConfig,
createMockPluginSetup({ security: null })
);
expect(await getDeprecationsInfo(context, { reportingCore })).toMatchInlineSnapshot(`Array []`);
});

test('logs no deprecations: roles enabled', async () => {
const mockReportingConfig = createMockConfigSchema(); // roles.enabled: true is default in 7.x / 8.0
reportingCore = await createMockReportingCore(
mockReportingConfig,
createMockPluginSetup({ security: null })
);

expect(await getDeprecationsInfo(context, { reportingCore })).toMatchInlineSnapshot(`Array []`);
});
});

it('insufficient permissions', async () => {
const permissionsError = new Error('you shall not pass');
(permissionsError as unknown as { statusCode: number }).statusCode = 403;
esClient.asCurrentUser.security.getUser = jest.fn().mockRejectedValue(permissionsError);
esClient.asCurrentUser.security.getRoleMapping = jest.fn().mockRejectedValue(permissionsError);

expect(await getDeprecationsInfo(context, { reportingCore })).toMatchInlineSnapshot(`
Array [
Object {
"correctiveActions": Object {
"manualSteps": Array [
"Create one or more custom roles that provide Kibana application privileges to reporting features in **Management > Security > Roles**.",
"Assign the custom role(s) as desired, and remove the \\"reporting_user\\" role from the user(s).",
"Make sure you have a \\"manage_security\\" cluster privilege assigned.",
],
},
"documentationUrl": "https://www.elastic.co/guide/en/kibana/current/secure-reporting.html",
"level": "critical",
"message": "The deprecated \\"reporting_user\\" role has been found for 2 user(s): \\"reportron\\", \\"supercooluser\\"",
"title": "Found deprecated reporting role",
"deprecationType": "feature",
"documentationUrl": "https://www.elastic.co/guide/en/kibana/current/xpack-security.html#_required_permissions_7",
"level": "fetch_error",
"message": "You do not have enough permissions to fix this deprecation.",
"title": "The \\"reporting_user\\" role is deprecated: check user roles",
},
]
`);
});

test('logs an expanded message when a config issue and a reporting_user role issue is found', async () => {
esClient.asCurrentUser.security.getUser = jest.fn().mockResolvedValue({
body: { reportron: { username: 'reportron', roles: ['kibana_admin', 'reporting_user'] } },
});

const mockReportingConfig = createMockConfigSchema({ roles: { enabled: true } });
reportingCore = await createMockReportingCore(mockReportingConfig);

expect(
await getDeprecationsInfo(context, {
reportingCore,
})
).toMatchInlineSnapshot(`
Array [
Object {
"correctiveActions": Object {
"manualSteps": Array [
"Set \\"xpack.reporting.roles.enabled: false\\" in kibana.yml",
"Create one or more custom roles that provide Kibana application privileges to reporting features in **Management > Security > Roles**.",
"Assign the custom role(s) as desired, and remove the \\"reporting_user\\" role from the user(s).",
"Make sure you have a \\"manage_security\\" cluster privilege assigned.",
],
},
"documentationUrl": "https://www.elastic.co/guide/en/kibana/current/secure-reporting.html",
"level": "critical",
"message": "The deprecated \\"reporting_user\\" role has been found for 1 user(s): \\"reportron\\"",
"title": "Found deprecated reporting role",
"deprecationType": "feature",
"documentationUrl": "https://www.elastic.co/guide/en/kibana/current/xpack-security.html#_required_permissions_7",
"level": "fetch_error",
"message": "You do not have enough permissions to fix this deprecation.",
"title": "The \\"reporting_user\\" role is deprecated: check role mappings",
},
]
`);
Expand Down
Loading