Skip to content

Commit

Permalink
[Cases] Removing spreads from connector mappings (#156622)
Browse files Browse the repository at this point in the history
This PR adds the decode within the service layer for the saved object
attributes.
  • Loading branch information
jonathan-buttner authored May 22, 2023
1 parent 6af77d6 commit e1523c1
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 24 deletions.
30 changes: 15 additions & 15 deletions x-pack/plugins/cases/common/api/connectors/mappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,48 @@

import * as rt from 'io-ts';

const ActionTypeRT = rt.union([
const ActionTypeRt = rt.union([
rt.literal('append'),
rt.literal('nothing'),
rt.literal('overwrite'),
]);
const CaseFieldRT = rt.union([
const CaseFieldRt = rt.union([
rt.literal('title'),
rt.literal('description'),
rt.literal('comments'),
rt.literal('tags'),
]);

const ThirdPartyFieldRT = rt.union([rt.string, rt.literal('not_mapped')]);
export type ActionType = rt.TypeOf<typeof ActionTypeRT>;
export type CaseField = rt.TypeOf<typeof CaseFieldRT>;
export type ThirdPartyField = rt.TypeOf<typeof ThirdPartyFieldRT>;
const ThirdPartyFieldRt = rt.union([rt.string, rt.literal('not_mapped')]);
export type ActionType = rt.TypeOf<typeof ActionTypeRt>;
export type CaseField = rt.TypeOf<typeof CaseFieldRt>;
export type ThirdPartyField = rt.TypeOf<typeof ThirdPartyFieldRt>;

export const ConnectorMappingsAttributesRT = rt.type({
action_type: ActionTypeRT,
source: CaseFieldRT,
target: ThirdPartyFieldRT,
const ConnectorMappingsAttributesRt = rt.type({
action_type: ActionTypeRt,
source: CaseFieldRt,
target: ThirdPartyFieldRt,
});

export const ConnectorMappingsRt = rt.type({
mappings: rt.array(ConnectorMappingsAttributesRT),
mappings: rt.array(ConnectorMappingsAttributesRt),
owner: rt.string,
});

export type ConnectorMappingsAttributes = rt.TypeOf<typeof ConnectorMappingsAttributesRT>;
export type ConnectorMappingsAttributes = rt.TypeOf<typeof ConnectorMappingsAttributesRt>;
export type ConnectorMappings = rt.TypeOf<typeof ConnectorMappingsRt>;

const FieldTypeRT = rt.union([rt.literal('text'), rt.literal('textarea')]);
const FieldTypeRt = rt.union([rt.literal('text'), rt.literal('textarea')]);

const ConnectorFieldRt = rt.type({
id: rt.string,
name: rt.string,
required: rt.boolean,
type: FieldTypeRT,
type: FieldTypeRt,
});

export type ConnectorField = rt.TypeOf<typeof ConnectorFieldRt>;

const GetDefaultMappingsResponseRt = rt.array(ConnectorMappingsAttributesRT);
const GetDefaultMappingsResponseRt = rt.array(ConnectorMappingsAttributesRt);

export type GetDefaultMappingsResponse = rt.TypeOf<typeof GetDefaultMappingsResponseRt>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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 { decodeOrThrow } from '../../../common/api/runtime_types';
import { ConnectorMappingsPartialRt } from './connector_mappings';

describe('mappings', () => {
describe('ConnectorMappingsPartialRt', () => {
it('strips excess fields from the object', () => {
const res = decodeOrThrow(ConnectorMappingsPartialRt)({ bananas: 'yes', owner: 'hi' });
expect(res).toMatchObject({
owner: 'hi',
});
});

it('does not throw when the object is empty', () => {
expect(() => decodeOrThrow(ConnectorMappingsPartialRt)({})).not.toThrow();
});
});
});
13 changes: 13 additions & 0 deletions x-pack/plugins/cases/server/common/types/connector_mappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
* 2.0.
*/

import * as rt from 'io-ts';

import type { SavedObject } from '@kbn/core/server';
import type { ConnectorMappings } from '../../../common/api';
import { ConnectorMappingsRt } from '../../../common/api';

export interface ConnectorMappingsPersistedAttributes {
mappings: Array<{
action_type: string;
Expand All @@ -13,3 +19,10 @@ export interface ConnectorMappingsPersistedAttributes {
}>;
owner: string;
}

export type ConnectorMappingsTransformed = ConnectorMappings;
export type ConnectorMappingsSavedObjectTransformed = SavedObject<ConnectorMappingsTransformed>;

export const ConnectorMappingsPartialRt = rt.exact(rt.partial(ConnectorMappingsRt.props));

export const ConnectorMappingsTransformedRt = ConnectorMappingsRt;
44 changes: 35 additions & 9 deletions x-pack/plugins/cases/server/services/connector_mappings/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import type {
Logger,
SavedObject,
SavedObjectsFindResponse,
SavedObjectsFindResult,
SavedObjectsUpdateResponse,
} from '@kbn/core/server';

Expand All @@ -18,16 +18,24 @@ import type {
PostConnectorMappingsArgs,
UpdateConnectorMappingsArgs,
} from './types';
import type { ConnectorMappingsPersistedAttributes } from '../../common/types/connector_mappings';
import type { ConnectorMappings } from '../../../common/api';
import type {
ConnectorMappingsPersistedAttributes,
ConnectorMappingsSavedObjectTransformed,
ConnectorMappingsTransformed,
} from '../../common/types/connector_mappings';
import {
ConnectorMappingsTransformedRt,
ConnectorMappingsPartialRt,
} from '../../common/types/connector_mappings';
import { decodeOrThrow } from '../../../common/api';

export class ConnectorMappingsService {
constructor(private readonly log: Logger) {}

public async find({
unsecuredSavedObjectsClient,
options,
}: FindConnectorMappingsArgs): Promise<SavedObjectsFindResponse<ConnectorMappings>> {
}: FindConnectorMappingsArgs): Promise<SavedObjectsFindResponse<ConnectorMappingsTransformed>> {
try {
this.log.debug(`Attempting to find all connector mappings`);
const connectorMappings =
Expand All @@ -36,7 +44,15 @@ export class ConnectorMappingsService {
type: CASE_CONNECTOR_MAPPINGS_SAVED_OBJECT,
});

return connectorMappings as SavedObjectsFindResponse<ConnectorMappings>;
const validatedMappings: Array<SavedObjectsFindResult<ConnectorMappingsTransformed>> = [];

for (const mapping of connectorMappings.saved_objects) {
const validatedMapping = decodeOrThrow(ConnectorMappingsTransformedRt)(mapping.attributes);

validatedMappings.push(Object.assign(mapping, { attributes: validatedMapping }));
}

return Object.assign(connectorMappings, { saved_objects: validatedMappings });
} catch (error) {
this.log.error(`Attempting to find all connector mappings: ${error}`);
throw error;
Expand All @@ -48,7 +64,7 @@ export class ConnectorMappingsService {
attributes,
references,
refresh,
}: PostConnectorMappingsArgs): Promise<SavedObject<ConnectorMappings>> {
}: PostConnectorMappingsArgs): Promise<ConnectorMappingsSavedObjectTransformed> {
try {
this.log.debug(`Attempting to POST a new connector mappings`);
const connectorMappings =
Expand All @@ -61,7 +77,11 @@ export class ConnectorMappingsService {
}
);

return connectorMappings as SavedObject<ConnectorMappings>;
const validatedAttributes = decodeOrThrow(ConnectorMappingsTransformedRt)(
connectorMappings.attributes
);

return Object.assign(connectorMappings, { attributes: validatedAttributes });
} catch (error) {
this.log.error(`Error on POST a new connector mappings: ${error}`);
throw error;
Expand All @@ -74,7 +94,9 @@ export class ConnectorMappingsService {
attributes,
references,
refresh,
}: UpdateConnectorMappingsArgs): Promise<SavedObjectsUpdateResponse<ConnectorMappings>> {
}: UpdateConnectorMappingsArgs): Promise<
SavedObjectsUpdateResponse<ConnectorMappingsTransformed>
> {
try {
this.log.debug(`Attempting to UPDATE connector mappings ${mappingId}`);
const updatedMappings =
Expand All @@ -88,7 +110,11 @@ export class ConnectorMappingsService {
}
);

return updatedMappings as SavedObjectsUpdateResponse<ConnectorMappings>;
const validatedAttributes = decodeOrThrow(ConnectorMappingsPartialRt)(
updatedMappings.attributes
);

return Object.assign(updatedMappings, { attributes: validatedAttributes });
} catch (error) {
this.log.error(`Error on UPDATE connector mappings ${mappingId}: ${error}`);
throw error;
Expand Down

0 comments on commit e1523c1

Please sign in to comment.