Skip to content

Commit

Permalink
Merge with master
Browse files Browse the repository at this point in the history
  • Loading branch information
mikecote committed Oct 8, 2019
2 parents f9ba6d5 + 69e7ee0 commit f0769d2
Show file tree
Hide file tree
Showing 58 changed files with 1,359 additions and 1,016 deletions.
2 changes: 1 addition & 1 deletion x-pack/legacy/plugins/actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ This module provides a Utilities for interacting with the configuration.

### Methods

**server.plugins.actions.registerType(options)**
**server.plugins.actions.setup.registerType(options)**

The following table describes the properties of the `options` object.

Expand Down
9 changes: 8 additions & 1 deletion x-pack/legacy/plugins/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ import { Root } from 'joi';
import mappings from './mappings.json';
import { init } from './server';

export { ActionsPlugin, ActionsClient, ActionType, ActionTypeExecutorOptions } from './server';
export {
ActionsPlugin,
ActionsClient,
ActionType,
ActionTypeExecutorOptions,
PluginSetupContract,
PluginStartContract,
} from './server';

export function actions(kibana: any) {
return new kibana.Plugin({
Expand Down
35 changes: 3 additions & 32 deletions x-pack/legacy/plugins/actions/server/action_type_registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,15 @@
* you may not use this file except in compliance with the Elastic License.
*/

jest.mock('./lib/get_create_task_runner_function', () => ({
getCreateTaskRunnerFunction: jest.fn(),
}));

import { taskManagerMock } from '../../task_manager/task_manager.mock';
import { encryptedSavedObjectsMock } from '../../encrypted_saved_objects/server/plugin.mock';
import { ActionTypeRegistry } from './action_type_registry';
import { ExecutorType } from './types';
import { SavedObjectsClientMock } from '../../../../../src/core/server/mocks';
import { ExecutorError } from './lib';
import { ActionExecutor, ExecutorError, TaskRunnerFactory } from './lib';

const mockTaskManager = taskManagerMock.create();

function getServices() {
return {
log: jest.fn(),
callCluster: jest.fn(),
savedObjectsClient: SavedObjectsClientMock.create(),
};
}
const actionTypeRegistryParams = {
getServices,
isSecurityEnabled: true,
taskManager: mockTaskManager,
encryptedSavedObjectsPlugin: encryptedSavedObjectsMock.create(),
spaceIdToNamespace: jest.fn().mockReturnValue(undefined),
getBasePath: jest.fn().mockReturnValue(undefined),
taskRunnerFactory: new TaskRunnerFactory(new ActionExecutor()),
};

beforeEach(() => jest.resetAllMocks());
Expand All @@ -41,9 +23,6 @@ const executor: ExecutorType = async options => {

describe('register()', () => {
test('able to register action types', () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { getCreateTaskRunnerFunction } = require('./lib/get_create_task_runner_function');
getCreateTaskRunnerFunction.mockReturnValueOnce(jest.fn());
const actionTypeRegistry = new ActionTypeRegistry(actionTypeRegistryParams);
actionTypeRegistry.register({
id: 'my-action-type',
Expand All @@ -56,7 +35,7 @@ describe('register()', () => {
Array [
Object {
"actions:my-action-type": Object {
"createTaskRunner": [MockFunction],
"createTaskRunner": [Function],
"getRetry": [Function],
"maxAttempts": 1,
"title": "My action type",
Expand All @@ -65,14 +44,6 @@ describe('register()', () => {
},
]
`);
expect(getCreateTaskRunnerFunction).toHaveBeenCalledWith({
actionTypeRegistry,
isSecurityEnabled: true,
encryptedSavedObjectsPlugin: actionTypeRegistryParams.encryptedSavedObjectsPlugin,
getServices: actionTypeRegistryParams.getServices,
getBasePath: actionTypeRegistryParams.getBasePath,
spaceIdToNamespace: actionTypeRegistryParams.spaceIdToNamespace,
});
});

test('throws error if action type already registered', () => {
Expand Down
45 changes: 11 additions & 34 deletions x-pack/legacy/plugins/actions/server/action_type_registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,24 @@

import Boom from 'boom';
import { i18n } from '@kbn/i18n';
import { TaskManager, TaskRunCreatorFunction } from '../../task_manager';
import { getCreateTaskRunnerFunction, ExecutorError } from './lib';
import { EncryptedSavedObjectsPlugin } from '../../encrypted_saved_objects';
import {
ActionType,
GetBasePathFunction,
GetServicesFunction,
SpaceIdToNamespaceFunction,
} from './types';
import { TaskManagerSetupContract } from './shim';
import { RunContext } from '../../task_manager';
import { ExecutorError, TaskRunnerFactory } from './lib';
import { ActionType } from './types';

interface ConstructorOptions {
isSecurityEnabled: boolean;
taskManager: TaskManager;
getServices: GetServicesFunction;
encryptedSavedObjectsPlugin: EncryptedSavedObjectsPlugin;
spaceIdToNamespace: SpaceIdToNamespaceFunction;
getBasePath: GetBasePathFunction;
taskManager: TaskManagerSetupContract;
taskRunnerFactory: TaskRunnerFactory;
}

export class ActionTypeRegistry {
private readonly taskRunCreatorFunction: TaskRunCreatorFunction;
private readonly taskManager: TaskManager;
private readonly taskManager: TaskManagerSetupContract;
private readonly actionTypes: Map<string, ActionType> = new Map();
private readonly taskRunnerFactory: TaskRunnerFactory;

constructor({
getServices,
taskManager,
encryptedSavedObjectsPlugin,
spaceIdToNamespace,
getBasePath,
isSecurityEnabled,
}: ConstructorOptions) {
constructor({ taskManager, taskRunnerFactory }: ConstructorOptions) {
this.taskManager = taskManager;
this.taskRunCreatorFunction = getCreateTaskRunnerFunction({
isSecurityEnabled,
getServices,
actionTypeRegistry: this,
encryptedSavedObjectsPlugin,
spaceIdToNamespace,
getBasePath,
});
this.taskRunnerFactory = taskRunnerFactory;
}

/**
Expand Down Expand Up @@ -86,7 +63,7 @@ export class ActionTypeRegistry {
// Don't retry other kinds of errors
return false;
},
createTaskRunner: this.taskRunCreatorFunction,
createTaskRunner: (context: RunContext) => this.taskRunnerFactory.create(context),
},
});
}
Expand Down
18 changes: 2 additions & 16 deletions x-pack/legacy/plugins/actions/server/actions_client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,17 @@ import { schema } from '@kbn/config-schema';
import { ActionTypeRegistry } from './action_type_registry';
import { ActionsClient } from './actions_client';
import { ExecutorType } from './types';
import { ActionExecutor, TaskRunnerFactory } from './lib';
import { taskManagerMock } from '../../task_manager/task_manager.mock';
import { SavedObjectsClientMock } from '../../../../../src/core/server/mocks';
import { encryptedSavedObjectsMock } from '../../encrypted_saved_objects/server/plugin.mock';

const savedObjectsClient = SavedObjectsClientMock.create();

const mockTaskManager = taskManagerMock.create();

const mockEncryptedSavedObjectsPlugin = encryptedSavedObjectsMock.create();

function getServices() {
return {
log: jest.fn(),
callCluster: jest.fn(),
savedObjectsClient: SavedObjectsClientMock.create(),
};
}

const actionTypeRegistryParams = {
getServices,
isSecurityEnabled: true,
taskManager: mockTaskManager,
encryptedSavedObjectsPlugin: mockEncryptedSavedObjectsPlugin,
spaceIdToNamespace: jest.fn().mockReturnValue(undefined),
getBasePath: jest.fn().mockReturnValue(undefined),
taskRunnerFactory: new TaskRunnerFactory(new ActionExecutor()),
};

const executor: ExecutorType = async options => {
Expand Down
35 changes: 16 additions & 19 deletions x-pack/legacy/plugins/actions/server/actions_config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/

import {
ActionsKibanaConfig,
getActionsConfigurationUtilities,
WhitelistedHosts,
} from './actions_config';
import { ActionsConfigType } from './types';
import { getActionsConfigurationUtilities, WhitelistedHosts } from './actions_config';

describe('ensureWhitelistedUri', () => {
test('returns true when "any" hostnames are allowed', () => {
const config: ActionsKibanaConfig = {
const config: ActionsConfigType = {
enabled: false,
whitelistedHosts: [WhitelistedHosts.Any],
};
Expand All @@ -24,7 +21,7 @@ describe('ensureWhitelistedUri', () => {
});

test('throws when the hostname in the requested uri is not in the whitelist', () => {
const config: ActionsKibanaConfig = { enabled: false, whitelistedHosts: [] };
const config: ActionsConfigType = { enabled: false, whitelistedHosts: [] };
expect(() =>
getActionsConfigurationUtilities(config).ensureWhitelistedUri(
'https://github.com/elastic/kibana'
Expand All @@ -35,7 +32,7 @@ describe('ensureWhitelistedUri', () => {
});

test('throws when the uri cannot be parsed as a valid URI', () => {
const config: ActionsKibanaConfig = { enabled: false, whitelistedHosts: [] };
const config: ActionsConfigType = { enabled: false, whitelistedHosts: [] };
expect(() =>
getActionsConfigurationUtilities(config).ensureWhitelistedUri('github.com/elastic')
).toThrowErrorMatchingInlineSnapshot(
Expand All @@ -44,7 +41,7 @@ describe('ensureWhitelistedUri', () => {
});

test('returns true when the hostname in the requested uri is in the whitelist', () => {
const config: ActionsKibanaConfig = { enabled: false, whitelistedHosts: ['github.com'] };
const config: ActionsConfigType = { enabled: false, whitelistedHosts: ['github.com'] };
expect(
getActionsConfigurationUtilities(config).ensureWhitelistedUri(
'https://github.com/elastic/kibana'
Expand All @@ -55,7 +52,7 @@ describe('ensureWhitelistedUri', () => {

describe('ensureWhitelistedHostname', () => {
test('returns true when "any" hostnames are allowed', () => {
const config: ActionsKibanaConfig = {
const config: ActionsConfigType = {
enabled: false,
whitelistedHosts: [WhitelistedHosts.Any],
};
Expand All @@ -65,7 +62,7 @@ describe('ensureWhitelistedHostname', () => {
});

test('throws when the hostname in the requested uri is not in the whitelist', () => {
const config: ActionsKibanaConfig = { enabled: false, whitelistedHosts: [] };
const config: ActionsConfigType = { enabled: false, whitelistedHosts: [] };
expect(() =>
getActionsConfigurationUtilities(config).ensureWhitelistedHostname('github.com')
).toThrowErrorMatchingInlineSnapshot(
Expand All @@ -74,7 +71,7 @@ describe('ensureWhitelistedHostname', () => {
});

test('returns true when the hostname in the requested uri is in the whitelist', () => {
const config: ActionsKibanaConfig = { enabled: false, whitelistedHosts: ['github.com'] };
const config: ActionsConfigType = { enabled: false, whitelistedHosts: ['github.com'] };
expect(
getActionsConfigurationUtilities(config).ensureWhitelistedHostname('github.com')
).toBeUndefined();
Expand All @@ -83,7 +80,7 @@ describe('ensureWhitelistedHostname', () => {

describe('isWhitelistedUri', () => {
test('returns true when "any" hostnames are allowed', () => {
const config: ActionsKibanaConfig = {
const config: ActionsConfigType = {
enabled: false,
whitelistedHosts: [WhitelistedHosts.Any],
};
Expand All @@ -93,21 +90,21 @@ describe('isWhitelistedUri', () => {
});

test('throws when the hostname in the requested uri is not in the whitelist', () => {
const config: ActionsKibanaConfig = { enabled: false, whitelistedHosts: [] };
const config: ActionsConfigType = { enabled: false, whitelistedHosts: [] };
expect(
getActionsConfigurationUtilities(config).isWhitelistedUri('https://github.com/elastic/kibana')
).toEqual(false);
});

test('throws when the uri cannot be parsed as a valid URI', () => {
const config: ActionsKibanaConfig = { enabled: false, whitelistedHosts: [] };
const config: ActionsConfigType = { enabled: false, whitelistedHosts: [] };
expect(getActionsConfigurationUtilities(config).isWhitelistedUri('github.com/elastic')).toEqual(
false
);
});

test('returns true when the hostname in the requested uri is in the whitelist', () => {
const config: ActionsKibanaConfig = { enabled: false, whitelistedHosts: ['github.com'] };
const config: ActionsConfigType = { enabled: false, whitelistedHosts: ['github.com'] };
expect(
getActionsConfigurationUtilities(config).isWhitelistedUri('https://github.com/elastic/kibana')
).toEqual(true);
Expand All @@ -116,7 +113,7 @@ describe('isWhitelistedUri', () => {

describe('isWhitelistedHostname', () => {
test('returns true when "any" hostnames are allowed', () => {
const config: ActionsKibanaConfig = {
const config: ActionsConfigType = {
enabled: false,
whitelistedHosts: [WhitelistedHosts.Any],
};
Expand All @@ -126,14 +123,14 @@ describe('isWhitelistedHostname', () => {
});

test('throws when the hostname in the requested uri is not in the whitelist', () => {
const config: ActionsKibanaConfig = { enabled: false, whitelistedHosts: [] };
const config: ActionsConfigType = { enabled: false, whitelistedHosts: [] };
expect(getActionsConfigurationUtilities(config).isWhitelistedHostname('github.com')).toEqual(
false
);
});

test('returns true when the hostname in the requested uri is in the whitelist', () => {
const config: ActionsKibanaConfig = { enabled: false, whitelistedHosts: ['github.com'] };
const config: ActionsConfigType = { enabled: false, whitelistedHosts: ['github.com'] };
expect(getActionsConfigurationUtilities(config).isWhitelistedHostname('github.com')).toEqual(
true
);
Expand Down
13 changes: 5 additions & 8 deletions x-pack/legacy/plugins/actions/server/actions_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { URL } from 'url';
import { curry } from 'lodash';
import { pipe } from 'fp-ts/lib/pipeable';

import { ActionsConfigType } from './types';

export enum WhitelistedHosts {
Any = '*',
}
Expand All @@ -19,11 +21,6 @@ enum WhitelistingField {
hostname = 'hostname',
}

export interface ActionsKibanaConfig {
enabled: boolean;
whitelistedHosts: string[];
}

export interface ActionsConfigurationUtilities {
isWhitelistedHostname: (hostname: string) => boolean;
isWhitelistedUri: (uri: string) => boolean;
Expand All @@ -45,7 +42,7 @@ function doesValueWhitelistAnyHostname(whitelistedHostname: string): boolean {
return whitelistedHostname === WhitelistedHosts.Any;
}

function isWhitelisted({ whitelistedHosts }: ActionsKibanaConfig, hostname: string): boolean {
function isWhitelisted({ whitelistedHosts }: ActionsConfigType, hostname: string): boolean {
return (
Array.isArray(whitelistedHosts) &&
isSome(
Expand All @@ -59,7 +56,7 @@ function isWhitelisted({ whitelistedHosts }: ActionsKibanaConfig, hostname: stri
);
}

function isWhitelistedHostnameInUri(config: ActionsKibanaConfig, uri: string): boolean {
function isWhitelistedHostnameInUri(config: ActionsConfigType, uri: string): boolean {
return pipe(
tryCatch(() => new URL(uri)),
map(url => url.hostname),
Expand All @@ -69,7 +66,7 @@ function isWhitelistedHostnameInUri(config: ActionsKibanaConfig, uri: string): b
}

export function getActionsConfigurationUtilities(
config: ActionsKibanaConfig
config: ActionsConfigType
): ActionsConfigurationUtilities {
const isWhitelistedHostname = curry(isWhitelisted)(config);
const isWhitelistedUri = curry(isWhitelistedHostnameInUri)(config);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const services = {
let actionType: ActionType;

beforeAll(() => {
const actionTypeRegistry = createActionTypeRegistry();
const { actionTypeRegistry } = createActionTypeRegistry();
actionType = actionTypeRegistry.get(ACTION_TYPE_ID);
});

Expand Down
Loading

0 comments on commit f0769d2

Please sign in to comment.