Skip to content

Commit b34fa68

Browse files
committed
Disable creating alerts client instances when ESO plugin is using an ephemeral encryption key
1 parent d73e15f commit b34fa68

4 files changed

Lines changed: 131 additions & 7 deletions

File tree

x-pack/legacy/plugins/alerting/server/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7+
import { AlertsClient as AlertsClientClass } from './alerts_client';
8+
9+
export type AlertsClient = PublicMethodsOf<AlertsClientClass>;
10+
711
export { init } from './init';
812
export { AlertType, AlertingPlugin, AlertExecutorOptions } from './types';
9-
export { AlertsClient } from './alerts_client';
1013
export { PluginSetupContract, PluginStartContract } from './plugin';
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import { Plugin } from './plugin';
8+
import { coreMock } from '../../../../../src/core/server/mocks';
9+
import { licensingMock } from '../../../../plugins/licensing/server/mocks';
10+
import { encryptedSavedObjectsMock } from '../../../../plugins/encrypted_saved_objects/server/mocks';
11+
12+
describe('Alerting Plugin', () => {
13+
describe('start()', () => {
14+
/**
15+
* HACK: This test has put together to ensuire the function "getAlertsClientWithRequest"
16+
* throws when needed. There's a lot of blockers for writing a proper test like
17+
* misisng plugin start/setup mocks for taskManager and actions plugin, core.http.route
18+
* is actually not a function in Kibana Platform, etc. This test contains what is needed
19+
* to get to the necessary function within start().
20+
*/
21+
describe('getAlertsClientWithRequest()', () => {
22+
it('throws error when encryptedSavedObjects plugin has usingEphemeralEncryptionKey set to true', async () => {
23+
const context = coreMock.createPluginInitializerContext();
24+
const plugin = new Plugin(context);
25+
26+
const coreSetup = coreMock.createSetup();
27+
const encryptedSavedObjectsSetup = encryptedSavedObjectsMock.createSetup();
28+
await plugin.setup(
29+
{
30+
...coreSetup,
31+
http: {
32+
...coreSetup.http,
33+
route: jest.fn(),
34+
},
35+
} as any,
36+
{
37+
licensing: licensingMock.createSetup(),
38+
encryptedSavedObjects: encryptedSavedObjectsSetup,
39+
} as any
40+
);
41+
42+
const startContract = plugin.start(
43+
coreMock.createStart() as any,
44+
{
45+
actions: {
46+
execute: jest.fn(),
47+
getActionsClientWithRequest: jest.fn(),
48+
},
49+
} as any
50+
);
51+
52+
expect(encryptedSavedObjectsSetup.usingEphemeralEncryptionKey).toEqual(true);
53+
expect(() =>
54+
startContract.getAlertsClientWithRequest({} as any)
55+
).toThrowErrorMatchingInlineSnapshot(
56+
`"Unable to create alerts client due to the Encrypted Saved Objects plugin using an ephemeral encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in kibana.yml"`
57+
);
58+
});
59+
60+
it(`doesn't throw error when encryptedSavedObjects plugin has usingEphemeralEncryptionKey set to false`, async () => {
61+
const context = coreMock.createPluginInitializerContext();
62+
const plugin = new Plugin(context);
63+
64+
const coreSetup = coreMock.createSetup();
65+
const encryptedSavedObjectsSetup = {
66+
...encryptedSavedObjectsMock.createSetup(),
67+
usingEphemeralEncryptionKey: false,
68+
};
69+
await plugin.setup(
70+
{
71+
...coreSetup,
72+
http: {
73+
...coreSetup.http,
74+
route: jest.fn(),
75+
},
76+
} as any,
77+
{
78+
licensing: licensingMock.createSetup(),
79+
encryptedSavedObjects: encryptedSavedObjectsSetup,
80+
} as any
81+
);
82+
83+
const startContract = plugin.start(
84+
coreMock.createStart() as any,
85+
{
86+
actions: {
87+
execute: jest.fn(),
88+
getActionsClientWithRequest: jest.fn(),
89+
},
90+
spaces: () => null,
91+
} as any
92+
);
93+
94+
const fakeRequest = {
95+
headers: {},
96+
getBasePath: () => '',
97+
path: '/',
98+
route: { settings: {} },
99+
url: {
100+
href: '/',
101+
},
102+
raw: {
103+
req: {
104+
url: '/',
105+
},
106+
},
107+
getSavedObjectsClient: jest.fn(),
108+
};
109+
await startContract.getAlertsClientWithRequest(fakeRequest as any);
110+
});
111+
});
112+
});
113+
});

x-pack/legacy/plugins/alerting/server/plugin.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export interface PluginSetupContract {
4242
}
4343
export interface PluginStartContract {
4444
listTypes: AlertTypeRegistry['list'];
45-
getAlertsClientWithRequest(request: Hapi.Request): AlertsClient;
45+
getAlertsClientWithRequest(request: Hapi.Request): PublicMethodsOf<AlertsClient>;
4646
}
4747

4848
export class Plugin {
@@ -52,6 +52,7 @@ export class Plugin {
5252
private adminClient?: IClusterClient;
5353
private serverBasePath?: string;
5454
private licenseState: LicenseState | null = null;
55+
private isESOUsingEphemeralEncryptionKey?: boolean;
5556

5657
constructor(initializerContext: AlertingPluginInitializerContext) {
5758
this.logger = initializerContext.logger.get('plugins', 'alerting');
@@ -63,8 +64,9 @@ export class Plugin {
6364
plugins: AlertingPluginsSetup
6465
): Promise<PluginSetupContract> {
6566
this.adminClient = core.elasticsearch.adminClient;
66-
6767
this.licenseState = new LicenseState(plugins.licensing.license$);
68+
this.isESOUsingEphemeralEncryptionKey =
69+
plugins.encryptedSavedObjects.usingEphemeralEncryptionKey;
6870

6971
// Encrypted attributes
7072
plugins.encryptedSavedObjects.registerType({
@@ -106,7 +108,7 @@ export class Plugin {
106108
}
107109

108110
public start(core: AlertingCoreStart, plugins: AlertingPluginsStart): PluginStartContract {
109-
const { adminClient, serverBasePath } = this;
111+
const { adminClient, serverBasePath, isESOUsingEphemeralEncryptionKey } = this;
110112

111113
function spaceIdToNamespace(spaceId?: string): string | undefined {
112114
const spacesPlugin = plugins.spaces();
@@ -147,8 +149,14 @@ export class Plugin {
147149

148150
return {
149151
listTypes: this.alertTypeRegistry!.list.bind(this.alertTypeRegistry!),
150-
getAlertsClientWithRequest: (request: Hapi.Request) =>
151-
alertsClientFactory!.create(KibanaRequest.from(request), request),
152+
getAlertsClientWithRequest: (request: Hapi.Request) => {
153+
if (isESOUsingEphemeralEncryptionKey === true) {
154+
throw new Error(
155+
`Unable to create alerts client due to the Encrypted Saved Objects plugin using an ephemeral encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in kibana.yml`
156+
);
157+
}
158+
return alertsClientFactory!.create(KibanaRequest.from(request), request);
159+
},
152160
};
153161
}
154162

x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
SavedObjectsClientContract,
1515
} from 'kibana/server';
1616
import { SIGNALS_ID } from '../../../../common/constants';
17-
import { AlertsClient } from '../../../../../alerting/server/alerts_client';
17+
import { AlertsClient } from '../../../../../alerting/server';
1818
import { ActionsClient } from '../../../../../../../plugins/actions/server';
1919
import { RuleAlertParams, RuleTypeParams, RuleAlertParamsRest } from '../types';
2020
import { RequestFacade } from '../../../types';

0 commit comments

Comments
 (0)