Skip to content

Commit

Permalink
Differentiating between saved object sources and lowercasing the string
Browse files Browse the repository at this point in the history
  • Loading branch information
ymao1 committed Mar 1, 2023
1 parent 4a548f6 commit 91209de
Show file tree
Hide file tree
Showing 15 changed files with 343 additions and 67 deletions.
6 changes: 3 additions & 3 deletions x-pack/plugins/actions/server/actions_client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2240,7 +2240,7 @@ describe('execute()', () => {
name: 'my name',
},
actionExecutionId,
sourceType: 'HTTP_REQUEST',
source: asHttpRequestExecutionSource(request),
});

await expect(
Expand Down Expand Up @@ -2274,7 +2274,7 @@ describe('execute()', () => {
},
],
actionExecutionId,
sourceType: 'HTTP_REQUEST',
source: asHttpRequestExecutionSource(request),
});

await expect(
Expand All @@ -2301,7 +2301,7 @@ describe('execute()', () => {
params: {
name: 'my name',
},
sourceType: 'HTTP_REQUEST',
source: asHttpRequestExecutionSource(request),
relatedSavedObjects: [
{
id: 'some-id',
Expand Down
15 changes: 5 additions & 10 deletions x-pack/plugins/actions/server/actions_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ import {
ConnectorTokenClientContract,
} from './types';
import { PreconfiguredActionDisabledModificationError } from './lib/errors/preconfigured_action_disabled_modification';
import { ExecuteOptions as ActionExecutorOptions } from './lib/action_executor';
import { ExecuteOptions } from './lib/action_executor';
import {
ExecutionEnqueuer,
ExecuteOptions as EnqueueExecutionOptions,
Expand Down Expand Up @@ -127,13 +127,6 @@ interface ConstructorOptions {
getEventLogClient: () => Promise<IEventLogClient>;
}

type ExecuteOptions = Omit<
ActionExecutorOptions,
'request' | 'actionExecutionId' | 'sourceType'
> & {
source: ActionExecutionSource<unknown>;
};

export interface UpdateOptions {
id: string;
action: ActionUpdate;
Expand Down Expand Up @@ -674,7 +667,9 @@ export class ActionsClient {
params,
source,
relatedSavedObjects,
}: ExecuteOptions): Promise<ActionTypeExecutorResult<unknown>> {
}: Omit<ExecuteOptions, 'request' | 'actionExecutionId'>): Promise<
ActionTypeExecutorResult<unknown>
> {
if (
(await getAuthorizationModeBySource(this.unsecuredSavedObjectsClient, source)) ===
AuthorizationMode.RBAC
Expand All @@ -687,7 +682,7 @@ export class ActionsClient {
return this.actionExecutor.execute({
actionId,
params,
sourceType: source.type,
source,
request: this.request,
relatedSavedObjects,
actionExecutionId: uuidv4(),
Expand Down
11 changes: 3 additions & 8 deletions x-pack/plugins/actions/server/create_execute_function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ import {
} from './types';
import { ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE } from './constants/saved_objects';
import { ExecuteOptions as ActionExecutorOptions } from './lib/action_executor';
import {
ActionExecutionSource,
extractSavedObjectReferences,
isSavedObjectExecutionSource,
} from './lib';
import { extractSavedObjectReferences, isSavedObjectExecutionSource } from './lib';

interface CreateExecuteFunctionOptions {
taskManager: TaskManagerStartContract;
Expand All @@ -29,12 +25,11 @@ interface CreateExecuteFunctionOptions {
}

export interface ExecuteOptions
extends Pick<ActionExecutorOptions, 'params' | 'relatedSavedObjects' | 'consumer'> {
extends Pick<ActionExecutorOptions, 'params' | 'source' | 'relatedSavedObjects' | 'consumer'> {
id: string;
spaceId: string;
apiKey: string | null;
executionId: string;
source?: ActionExecutionSource<unknown>;
}

interface ActionTaskParams
Expand Down Expand Up @@ -280,7 +275,7 @@ function validateCanActionBeUsed(action: PreConfiguredAction | RawAction) {
}
}

function executionSourceAsSavedObjectReferences(executionSource?: ActionExecutionSource<unknown>) {
function executionSourceAsSavedObjectReferences(executionSource: ActionExecutorOptions['source']) {
return isSavedObjectExecutionSource(executionSource)
? {
references: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ import {
} from './types';
import { ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE } from './constants/saved_objects';
import { ExecuteOptions as ActionExecutorOptions } from './lib/action_executor';
import {
extractSavedObjectReferences,
isSavedObjectExecutionSource,
ActionExecutionSource,
} from './lib';
import { extractSavedObjectReferences, isSavedObjectExecutionSource } from './lib';

// This allowlist should only contain connector types that don't require API keys for
// execution.
Expand All @@ -29,9 +25,8 @@ interface CreateBulkUnsecuredExecuteFunctionOptions {
}

export interface ExecuteOptions
extends Pick<ActionExecutorOptions, 'params' | 'relatedSavedObjects'> {
extends Pick<ActionExecutorOptions, 'params' | 'source' | 'relatedSavedObjects'> {
id: string;
source?: ActionExecutionSource<unknown>;
}

interface ActionTaskParams
Expand Down Expand Up @@ -140,7 +135,7 @@ export function createBulkUnsecuredExecutionEnqueuerFunction({
};
}

function executionSourceAsSavedObjectReferences(executionSource?: ActionExecutionSource<unknown>) {
function executionSourceAsSavedObjectReferences(executionSource: ActionExecutorOptions['source']) {
return isSavedObjectExecutionSource(executionSource)
? {
references: [
Expand Down
7 changes: 7 additions & 0 deletions x-pack/plugins/actions/server/lib/action_execution_source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ export function asHttpRequestExecutionSource(source: KibanaRequest): HttpRequest
};
}

export function asEmptySource(type: ActionExecutionSourceType): ActionExecutionSource<{}> {
return {
type,
source: {},
};
}

export function asSavedObjectExecutionSource(
source: Omit<SavedObjectReference, 'name'>
): SavedObjectExecutionSource {
Expand Down
156 changes: 150 additions & 6 deletions x-pack/plugins/actions/server/lib/action_executor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ import { schema } from '@kbn/config-schema';
import { ActionExecutor } from './action_executor';
import { actionTypeRegistryMock } from '../action_type_registry.mock';
import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks';
import { loggingSystemMock } from '@kbn/core/server/mocks';
import { httpServerMock, loggingSystemMock } from '@kbn/core/server/mocks';
import { eventLoggerMock } from '@kbn/event-log-plugin/server/mocks';
import { spacesServiceMock } from '@kbn/spaces-plugin/server/spaces_service/spaces_service.mock';
import { ActionType } from '../types';
import { actionsMock } from '../mocks';
import { ActionExecutionSourceType } from './action_execution_source';
import {
asHttpRequestExecutionSource,
asSavedObjectExecutionSource,
} from './action_execution_source';

const actionExecutor = new ActionExecutor({ isESOCanEncrypt: true });
const services = actionsMock.createServices();
Expand Down Expand Up @@ -201,7 +204,7 @@ test('successfully executes', async () => {
`);
});

test('successfully executes when sourceType is specified', async () => {
test('successfully executes when http_request source is specified', async () => {
const actionType: jest.Mocked<ActionType> = {
id: 'test',
name: 'Test',
Expand All @@ -228,7 +231,7 @@ test('successfully executes when sourceType is specified', async () => {
actionTypeRegistry.get.mockReturnValueOnce(actionType);
await actionExecutor.execute({
...executeParams,
sourceType: ActionExecutionSourceType.HTTP_REQUEST,
source: asHttpRequestExecutionSource(httpServerMock.createKibanaRequest()),
});

expect(encryptedSavedObjectsClient.getDecryptedAsInternalUser).toHaveBeenCalledWith(
Expand Down Expand Up @@ -267,7 +270,7 @@ test('successfully executes when sourceType is specified', async () => {
"kibana": Object {
"action": Object {
"execution": Object {
"source": "HTTP_REQUEST",
"source": "http_request",
"uuid": "2",
},
"id": "1",
Expand Down Expand Up @@ -306,7 +309,148 @@ test('successfully executes when sourceType is specified', async () => {
"kibana": Object {
"action": Object {
"execution": Object {
"source": "HTTP_REQUEST",
"source": "http_request",
"uuid": "2",
},
"id": "1",
"name": "1",
},
"alert": Object {
"rule": Object {
"execution": Object {
"uuid": "123abc",
},
},
},
"saved_objects": Array [
Object {
"id": "1",
"namespace": "some-namespace",
"rel": "primary",
"type": "action",
"type_id": "test",
},
],
"space_ids": Array [
"some-namespace",
],
},
"message": "action executed: test:1: 1",
},
],
]
`);
});

test('successfully executes when saved_object source is specified', async () => {
const actionType: jest.Mocked<ActionType> = {
id: 'test',
name: 'Test',
minimumLicenseRequired: 'basic',
supportedFeatureIds: ['alerting'],
executor: jest.fn(),
};
const actionSavedObject = {
id: '1',
type: 'action',
attributes: {
name: '1',
actionTypeId: 'test',
config: {
bar: true,
},
secrets: {
baz: true,
},
},
references: [],
};
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject);
actionTypeRegistry.get.mockReturnValueOnce(actionType);
await actionExecutor.execute({
...executeParams,
source: asSavedObjectExecutionSource({
id: '573891ae-8c48-49cb-a197-0cd5ec34a88b',
type: 'alert',
}),
});

expect(encryptedSavedObjectsClient.getDecryptedAsInternalUser).toHaveBeenCalledWith(
'action',
'1',
{ namespace: 'some-namespace' }
);

expect(actionTypeRegistry.get).toHaveBeenCalledWith('test');
expect(actionTypeRegistry.isActionExecutable).toHaveBeenCalledWith('1', 'test', {
notifyUsage: true,
});

expect(actionType.executor).toHaveBeenCalledWith({
actionId: '1',
services: expect.anything(),
config: {
bar: true,
},
secrets: {
baz: true,
},
params: { foo: true },
logger: loggerMock,
});

expect(loggerMock.debug).toBeCalledWith('executing action test:1: 1');
expect(eventLogger.logEvent.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
Object {
"event": Object {
"action": "execute-start",
"kind": "action",
},
"kibana": Object {
"action": Object {
"execution": Object {
"source": "alert",
"uuid": "2",
},
"id": "1",
"name": "1",
},
"alert": Object {
"rule": Object {
"execution": Object {
"uuid": "123abc",
},
},
},
"saved_objects": Array [
Object {
"id": "1",
"namespace": "some-namespace",
"rel": "primary",
"type": "action",
"type_id": "test",
},
],
"space_ids": Array [
"some-namespace",
],
},
"message": "action started: test:1: 1",
},
],
Array [
Object {
"event": Object {
"action": "execute",
"kind": "action",
"outcome": "success",
},
"kibana": Object {
"action": Object {
"execution": Object {
"source": "alert",
"uuid": "2",
},
"id": "1",
Expand Down
Loading

0 comments on commit 91209de

Please sign in to comment.