Skip to content

Commit

Permalink
added integration tests for legacy rejectUnauthorized fale
Browse files Browse the repository at this point in the history
  • Loading branch information
YulNaumenko committed May 26, 2021
1 parent 6ac9f5e commit 291385e
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 0 deletions.
3 changes: 3 additions & 0 deletions x-pack/test/alerting_api_integration/common/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ interface CreateTestConfigOptions {
publicBaseUrl?: boolean;
preconfiguredAlertHistoryEsIndex?: boolean;
customizeLocalHostTls?: boolean;
rejectUnauthorized?: boolean; // legacy
}

// test.not-enabled is specifically not enabled
Expand Down Expand Up @@ -52,6 +53,7 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions)
verificationMode = 'full',
preconfiguredAlertHistoryEsIndex = false,
customizeLocalHostTls = false,
rejectUnauthorized = true, // legacy
} = options;

return async ({ readConfigFile }: FtrConfigProviderContext) => {
Expand Down Expand Up @@ -150,6 +152,7 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions)
'--xpack.encryptedSavedObjects.encryptionKey="wuGNaIhoMpk5sO4UBxgr3NyW1sFcLgIf"',
'--xpack.alerting.invalidateApiKeysTask.interval="15s"',
`--xpack.actions.enabledActionTypes=${JSON.stringify(enabledActionTypes)}`,
`--xpack.actions.rejectUnauthorized=${rejectUnauthorized}`,
`--xpack.actions.tls.verificationMode=${verificationMode}`,
...actionsProxyUrl,
...customHostSettings,
Expand Down
19 changes: 19 additions & 0 deletions x-pack/test/alerting_api_integration/spaces_only_legacy/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* 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 { createTestConfig } from '../common/config';

// eslint-disable-next-line import/no-default-export
export default createTestConfig('spaces_only', {
disabledPlugins: ['security'],
license: 'trial',
enableActionsProxy: false,
rejectUnauthorized: false,
verificationMode: undefined,
customizeLocalHostTls: true,
preconfiguredAlertHistoryEsIndex: true,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* 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 { Space } from '../common/types';

const Space1: Space = {
id: 'space1',
namespace: 'space1',
name: 'Space 1',
disabledFeatures: [],
};

const Other: Space = {
id: 'other',
namespace: 'other',
name: 'Other',
disabledFeatures: [],
};

const Default: Space = {
id: 'default',
namespace: undefined,
name: 'Default',
disabledFeatures: [],
};

export const Spaces = {
space1: Space1,
other: Other,
default: Default,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/*
* 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 http from 'http';
import https from 'https';
import getPort from 'get-port';
import expect from '@kbn/expect';
import { URL, format as formatUrl } from 'url';
import { FtrProviderContext } from '../../../../common/ftr_provider_context';
import {
getWebhookServer,
getHttpsWebhookServer,
} from '../../../../common/fixtures/plugins/actions_simulators/server/plugin';
import { createTlsWebhookServer } from '../../../../common/lib/get_tls_webhook_servers';

// eslint-disable-next-line import/no-default-export
export default function webhookTest({ getService }: FtrProviderContext) {
const supertest = getService('supertest');

async function createWebhookAction(
webhookSimulatorURL: string,
config: Record<string, string | Record<string, string>> = {}
): Promise<string> {
const url = formatUrl(new URL(webhookSimulatorURL), { auth: false });
const composedConfig = {
headers: {
'Content-Type': 'text/plain',
},
...config,
url,
};

const { body: createdAction } = await supertest
.post('/api/actions/action')
.set('kbn-xsrf', 'test')
.send({
name: 'A generic Webhook action',
actionTypeId: '.webhook',
secrets: {},
config: composedConfig,
})
.expect(200);

return createdAction.id;
}

async function getPortOfConnector(connectorId: string): Promise<string> {
const response = await supertest.get(`/api/actions/connectors`).expect(200);
const connector = response.body.find((conn: { id: string }) => conn.id === connectorId);
if (connector === undefined) {
throw new Error(`unable to find connector with id ${connectorId}`);
}

// server URL is the connector name
const url = connector.name;
const parsedUrl = new URL(url);
return parsedUrl.port;
}

describe('webhook action', () => {
describe('with http endpoint', () => {
let webhookSimulatorURL: string = '';
let webhookServer: http.Server;
before(async () => {
webhookServer = await getWebhookServer();
const availablePort = await getPort({ port: 9000 });
webhookServer.listen(availablePort);
webhookSimulatorURL = `http://localhost:${availablePort}`;
});

it('webhook can be executed without username and password', async () => {
const webhookActionId = await createWebhookAction(webhookSimulatorURL);
const { body: result } = await supertest
.post(`/api/actions/action/${webhookActionId}/_execute`)
.set('kbn-xsrf', 'test')
.send({
params: {
body: 'success',
},
})
.expect(200);

expect(result.status).to.eql('ok');
});

after(() => {
webhookServer.close();
});
});

describe('with https endpoint and rejectUnauthorized=false', () => {
let webhookSimulatorURL: string = '';
let webhookServer: https.Server;

before(async () => {
webhookServer = await getHttpsWebhookServer();
const availablePort = await getPort({ port: getPort.makeRange(9000, 9100) });
webhookServer.listen(availablePort);
webhookSimulatorURL = `https://localhost:${availablePort}`;
});

it('should support the POST method against webhook target', async () => {
const webhookActionId = await createWebhookAction(webhookSimulatorURL, { method: 'post' });
const { body: result } = await supertest
.post(`/api/actions/action/${webhookActionId}/_execute`)
.set('kbn-xsrf', 'test')
.send({
params: {
body: 'success_post_method',
},
})
.expect(200);

expect(result.status).to.eql('ok');
});

after(() => {
webhookServer.close();
});
});

describe('tls customization', () => {
it('should handle the xpack.actions.rejectUnauthorized: false', async () => {
const connectorId = 'custom.tls.noCustom';
const port = await getPortOfConnector(connectorId);
const server = await createTlsWebhookServer(port);
const { status, body } = await supertest
.post(`/api/actions/connector/${connectorId}/_execute`)
.set('kbn-xsrf', 'test')
.send({
params: {
body: 'foo',
},
});
expect(status).to.eql(200);
server.close();

expect(body.status).to.eql('ok');
});

it('should handle the customized rejectUnauthorized: false', async () => {
const connectorId = 'custom.tls.rejectUnauthorizedFalse';
const port = await getPortOfConnector(connectorId);
const server = await createTlsWebhookServer(port);
const { status, body } = await supertest
.post(`/api/actions/connector/custom.tls.rejectUnauthorizedFalse/_execute`)
.set('kbn-xsrf', 'test')
.send({
params: {
body: 'foo',
},
});
expect(status).to.eql(200);
server.close();

expect(body.status).to.eql('ok');
});

it('should handle the customized rejectUnauthorized: true', async () => {
const connectorId = 'custom.tls.rejectUnauthorizedTrue';
const port = await getPortOfConnector(connectorId);
const server = await createTlsWebhookServer(port);
const { status, body } = await supertest
.post(`/api/actions/connector/custom.tls.rejectUnauthorizedTrue/_execute`)
.set('kbn-xsrf', 'test')
.send({
params: {
body: 'foo',
},
});
expect(status).to.eql(200);
server.close();

expect(body.status).to.eql('error');
expect(body.service_message.indexOf('certificate')).to.be.greaterThan(0);
});

it('should handle the customized ca file', async () => {
const connectorId = 'custom.tls.caFile';
const port = await getPortOfConnector(connectorId);
const server = await createTlsWebhookServer(port);
const { status, body } = await supertest
.post(`/api/actions/connector/custom.tls.caFile/_execute`)
.set('kbn-xsrf', 'test')
.send({
params: {
body: 'foo',
},
});
expect(status).to.eql(200);
server.close();

expect(body.status).to.eql('ok');
});
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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 { FtrProviderContext } from '../../common/ftr_provider_context';
import { Spaces } from '../scenarios';

// eslint-disable-next-line import/no-default-export
export default function alertingApiIntegrationTests({ loadTestFile }: FtrProviderContext) {
describe('alerting api integration spaces only legacy configuration', function () {
this.tags('ciGroup12');

loadTestFile(require.resolve('./actions/webhook'));
});
}

export async function buildUp(getService: FtrProviderContext['getService']) {
const spacesService = getService('spaces');
for (const space of Object.values(Spaces)) {
if (space.id === 'default') continue;

const { id, name, disabledFeatures } = space;
await spacesService.create({ id, name, disabledFeatures });
}
}

export async function tearDown(getService: FtrProviderContext['getService']) {
const esArchiver = getService('esArchiver');
await esArchiver.unload('empty_kibana');
}

0 comments on commit 291385e

Please sign in to comment.