Skip to content

Commit

Permalink
feat(MISP Node): Rest search operations (#9196)
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-radency committed Apr 26, 2024
1 parent 9b3ac16 commit b694e77
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 1 deletion.
53 changes: 52 additions & 1 deletion packages/nodes-base/nodes/Misp/GenericFunctions.ts
Expand Up @@ -7,7 +7,7 @@ import type {
IHttpRequestMethods,
IRequestOptions,
} from 'n8n-workflow';
import { NodeApiError, NodeOperationError } from 'n8n-workflow';
import { NodeApiError, NodeOperationError, jsonParse } from 'n8n-workflow';

import type { MispCredentials } from './types';

Expand Down Expand Up @@ -79,6 +79,57 @@ export async function mispApiRequestAllItems(this: IExecuteFunctions, endpoint:
return responseData;
}

export async function mispApiRestSearch(
this: IExecuteFunctions,
resource: 'attributes' | 'events' | 'objects',
itemIndex: number,
) {
let body: IDataObject = {};
const useJson = this.getNodeParameter('useJson', itemIndex) as boolean;

if (useJson) {
const json = this.getNodeParameter('jsonOutput', itemIndex);
if (typeof json === 'string') {
body = jsonParse(json);
} else {
body = json as IDataObject;
}
} else {
const value = this.getNodeParameter('value', itemIndex) as string;
const additionalFields = this.getNodeParameter('additionalFields', itemIndex);

body.value = value;

if (Object.keys(additionalFields).length) {
if (additionalFields.tags) {
additionalFields.tags = (additionalFields.tags as string)
.split(',')
.map((tag) => tag.trim());
}
Object.assign(body, additionalFields);
}
}

const endpoint = `/${resource}/restSearch`;
const { response } = await mispApiRequest.call(this, 'POST', endpoint, body);

if (response) {
if (resource === 'attributes') {
return response.Attribute;
}

if (resource === 'events') {
return (response as IDataObject[]).map((event) => event.Event);
}

if (resource === 'objects') {
return (response as IDataObject[]).map((obj) => obj.Object);
}
} else {
return [];
}
}

export function throwOnEmptyUpdate(
this: IExecuteFunctions,
resource: string,
Expand Down
32 changes: 32 additions & 0 deletions packages/nodes-base/nodes/Misp/Misp.node.ts
Expand Up @@ -10,6 +10,7 @@ import type {
import {
mispApiRequest,
mispApiRequestAllItems,
mispApiRestSearch,
throwOnEmptyUpdate,
throwOnInvalidUrl,
throwOnMissingSharingGroup,
Expand All @@ -28,6 +29,8 @@ import {
galaxyOperations,
noticelistFields,
noticelistOperations,
objectOperations,
objectFields,
organisationFields,
organisationOperations,
tagFields,
Expand Down Expand Up @@ -91,6 +94,10 @@ export class Misp implements INodeType {
name: 'Noticelist',
value: 'noticelist',
},
{
name: 'Object',
value: 'object',
},
{
name: 'Organisation',
value: 'organisation',
Expand Down Expand Up @@ -122,6 +129,8 @@ export class Misp implements INodeType {
...galaxyFields,
...noticelistOperations,
...noticelistFields,
...objectOperations,
...objectFields,
...organisationOperations,
...organisationFields,
...tagOperations,
Expand Down Expand Up @@ -233,6 +242,12 @@ export class Misp implements INodeType {
// ----------------------------------------

responseData = await mispApiRequestAllItems.call(this, '/attributes');
} else if (operation === 'search') {
// ----------------------------------------
// attribute: search
// ----------------------------------------

responseData = await mispApiRestSearch.call(this, 'attributes', i);
} else if (operation === 'update') {
// ----------------------------------------
// attribute: update
Expand Down Expand Up @@ -300,6 +315,12 @@ export class Misp implements INodeType {
// ----------------------------------------

responseData = await mispApiRequestAllItems.call(this, '/events');
} else if (operation === 'search') {
// ----------------------------------------
// event: search
// ----------------------------------------

responseData = await mispApiRestSearch.call(this, 'events', i);
} else if (operation === 'publish') {
// ----------------------------------------
// event: publish
Expand Down Expand Up @@ -500,6 +521,17 @@ export class Misp implements INodeType {
}>;
responseData = responseData.map((entry) => entry.Noticelist);
}
} else if (resource === 'object') {
// **********************************************************************
// object
// **********************************************************************
if (operation === 'search') {
// ----------------------------------------
// attribute: search
// ----------------------------------------

responseData = await mispApiRestSearch.call(this, 'objects', i);
}
} else if (resource === 'organisation') {
// **********************************************************************
// organisation
Expand Down
@@ -1,4 +1,15 @@
import type { INodeProperties } from 'n8n-workflow';
import { updateDisplayOptions } from '../../../utils/utilities';
import { searchProperties } from './common.descriptions';

const searchDisplayOptions = {
show: {
resource: ['attribute'],
operation: ['search'],
},
};

const searchDescription = updateDisplayOptions(searchDisplayOptions, searchProperties);

export const attributeOperations: INodeProperties[] = [
{
Expand Down Expand Up @@ -32,6 +43,11 @@ export const attributeOperations: INodeProperties[] = [
value: 'getAll',
action: 'Get many attributes',
},
{
name: 'Search',
value: 'search',
action: 'Get a filtered list of attributes',
},
{
name: 'Update',
value: 'update',
Expand Down Expand Up @@ -226,6 +242,11 @@ export const attributeFields: INodeProperties[] = [
},
},

// ----------------------------------------
// attribute: search
// ----------------------------------------
...searchDescription,

// ----------------------------------------
// attribute: update
// ----------------------------------------
Expand Down
21 changes: 21 additions & 0 deletions packages/nodes-base/nodes/Misp/descriptions/EventDescription.ts
@@ -1,4 +1,15 @@
import type { INodeProperties } from 'n8n-workflow';
import { updateDisplayOptions } from '../../../utils/utilities';
import { searchProperties } from './common.descriptions';

const searchDisplayOptions = {
show: {
resource: ['event'],
operation: ['search'],
},
};

const searchDescription = updateDisplayOptions(searchDisplayOptions, searchProperties);

export const eventOperations: INodeProperties[] = [
{
Expand Down Expand Up @@ -37,6 +48,11 @@ export const eventOperations: INodeProperties[] = [
value: 'publish',
action: 'Publish an event',
},
{
name: 'Search',
value: 'search',
action: 'Get a filtered list of events',
},
{
name: 'Unpublish',
value: 'unpublish',
Expand Down Expand Up @@ -295,6 +311,11 @@ export const eventFields: INodeProperties[] = [
},
},

// ----------------------------------------
// event: search
// ----------------------------------------
...searchDescription,

// ----------------------------------------
// event: update
// ----------------------------------------
Expand Down
41 changes: 41 additions & 0 deletions packages/nodes-base/nodes/Misp/descriptions/ObjectDescription.ts
@@ -0,0 +1,41 @@
import type { INodeProperties } from 'n8n-workflow';
import { updateDisplayOptions } from '../../../utils/utilities';
import { searchProperties } from './common.descriptions';

const searchDisplayOptions = {
show: {
resource: ['object'],
operation: ['search'],
},
};

const searchDescription = updateDisplayOptions(searchDisplayOptions, searchProperties);

export const objectOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: ['object'],
},
},
noDataExpression: true,
options: [
{
name: 'Search',
value: 'search',
action: 'Get a filtered list of objects',
},
],
default: 'search',
},
];

export const objectFields: INodeProperties[] = [
// ----------------------------------------
// event: search
// ----------------------------------------
...searchDescription,
];
102 changes: 102 additions & 0 deletions packages/nodes-base/nodes/Misp/descriptions/common.descriptions.ts
@@ -0,0 +1,102 @@
import type { INodeProperties } from 'n8n-workflow';

export const searchProperties: INodeProperties[] = [
{
displayName: 'Use JSON to Specify Fields',
name: 'useJson',
type: 'boolean',
default: false,
description: 'Whether to use JSON to specify the fields for the search request',
},
{
displayName: 'JSON',
name: 'jsonOutput',
type: 'json',
description:
'Get more info at {YOUR_BASE_URL_SPECIFIED_IN_CREDENTIALS}/api/openapi#operation/restSearchAttributes',
typeOptions: {
rows: 5,
},
default: '{\n "value": "search value",\n "type": "text"\n}\n',
validateType: 'object',
displayOptions: {
show: {
useJson: [true],
},
},
},
{
displayName: 'Value',
name: 'value',
type: 'string',
required: true,
placeholder: 'e.g. 127.0.0.1',
default: '',
displayOptions: {
show: {
useJson: [false],
},
},
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
useJson: [false],
},
},
options: [
{
displayName: 'Category',
name: 'category',
type: 'string',
placeholder: 'e.g. Internal reference',
default: '',
},
{
displayName: 'Deleted',
name: 'deleted',
type: 'boolean',
default: false,
},
{
displayName: 'Search All',
name: 'searchall',
type: 'string',
description:
'Search by matching any tag names, event descriptions, attribute values or attribute comments',
default: '',
displayOptions: {
hide: {
'/resource': ['attribute'],
},
},
},
{
displayName: 'Tags',
name: 'tags',
type: 'string',
placeholder: 'e.g. tag1,tag2',
hint: 'Comma-separated list of tags',
default: '',
},
{
displayName: 'Type',
name: 'type',
type: 'string',
placeholder: 'e.g. text',
default: '',
},
{
displayName: 'Published',
name: 'published',
type: 'boolean',
default: false,
},
],
},
];
1 change: 1 addition & 0 deletions packages/nodes-base/nodes/Misp/descriptions/index.ts
Expand Up @@ -4,6 +4,7 @@ export * from './EventTagDescription';
export * from './FeedDescription';
export * from './GalaxyDescription';
export * from './NoticelistDescription';
export * from './ObjectDescription';
export * from './OrganisationDescription';
export * from './TagDescription';
export * from './UserDescription';
Expand Down

0 comments on commit b694e77

Please sign in to comment.