Skip to content

Commit

Permalink
feat: datasource misp events (#264)
Browse files Browse the repository at this point in the history
  • Loading branch information
anasmuhmd authored Dec 3, 2024
1 parent 379e2f8 commit 2554867
Show file tree
Hide file tree
Showing 14 changed files with 951 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ packages:
SpotVulnerabilitiesClient:
IntelClient:
DiscoverClient:
github.com/blackstork-io/fabric/internal/misp:
config:
interfaces:
Client:
github.com/blackstork-io/fabric/plugin/resolver:
config:
inpackage: true
Expand Down
31 changes: 31 additions & 0 deletions docs/plugins/misp/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
title: blackstork/misp
weight: 20
plugin:
name: blackstork/misp
description: ""
tags: []
version: "v0.4.2"
source_github: "https://github.com/blackstork-io/fabric/tree/main/internal/misp/"
type: docs
hideInMenu: true
---

{{< plugin-header "blackstork/misp" "misp" "v0.4.2" >}}

## Installation

To install the plugin, add it to `plugin_versions` map in the Fabric global configuration block (see [Global configuration]({{< ref "configs.md#global-configuration" >}}) for more details), with a version constraint restricting which available versions of the plugin the codebase is compatible with:

```hcl
fabric {
plugin_versions = {
"blackstork/misp" = ">= v0.4.2"
}
}
```


## Data sources

{{< plugin-resources "misp" "data-source" >}}
143 changes: 143 additions & 0 deletions docs/plugins/misp/data-sources/misp_events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
---
title: "`misp_events` data source"
plugin:
name: blackstork/misp
description: "The `misp_events` data source fetches MISP events"
tags: []
version: "v0.4.2"
source_github: "https://github.com/blackstork-io/fabric/tree/main/internal/misp/"
resource:
type: data-source
type: docs
---

{{< breadcrumbs 2 >}}

{{< plugin-resource-header "blackstork/misp" "misp" "v0.4.2" "misp_events" "data source" >}}

## Description
The `misp_events` data source fetches MISP events

## Installation

To use `misp_events` data source, you must install the plugin `blackstork/misp`.

To install the plugin, add the full plugin name to the `plugin_versions` map in the Fabric global configuration block (see [Global configuration]({{< ref "configs.md#global-configuration" >}}) for more details), as shown below:

```hcl
fabric {
plugin_versions = {
"blackstork/misp" = ">= v0.4.2"
}
}
```

Note the version constraint set for the plugin.

## Configuration

The data source supports the following configuration arguments:

```hcl
config data misp_events {
# misp api key
#
# Required string.
# Must be non-empty
# For example:
api_key = "some string"
# misp base url
#
# Required string.
# Must be non-empty
# For example:
base_url = "some string"
# skip ssl verification
#
# Optional bool.
# Default value:
skip_ssl = false
}
```

## Usage

The data source supports the following execution arguments:

```hcl
data misp_events {
# Required string.
# For example:
value = "some string"
# Optional string.
# Default value:
type = null
# Optional string.
# Default value:
category = null
# Optional string.
# Default value:
org = null
# Optional list of string.
# Default value:
tags = null
# Optional list of string.
# Default value:
event_tags = null
# Optional string.
# Default value:
searchall = null
# Optional string.
# Default value:
from = null
# Optional string.
# Default value:
to = null
# Optional string.
# Default value:
last = null
# Optional number.
# Default value:
event_id = null
# Optional bool.
# Default value:
with_attachments = null
# Optional list of string.
# Default value:
sharing_groups = null
# Optional bool.
# Default value:
only_metadata = null
# Optional string.
# Default value:
uuid = null
# Optional bool.
# Default value:
include_sightings = null
# Optional number.
# Default value:
threat_level_id = null
# Optional number.
# Default value:
limit = 10
}
```
36 changes: 36 additions & 0 deletions docs/plugins/plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,42 @@
}
]
},
{
"name": "blackstork/misp",
"version": "v0.4.2",
"shortname": "misp",
"resources": [
{
"name": "misp_events",
"type": "data-source",
"config_params": [
"api_key",
"base_url",
"skip_ssl"
],
"arguments": [
"category",
"event_id",
"event_tags",
"from",
"include_sightings",
"last",
"limit",
"only_metadata",
"org",
"searchall",
"sharing_groups",
"tags",
"threat_level_id",
"to",
"type",
"uuid",
"value",
"with_attachments"
]
}
]
},
{
"name": "blackstork/nist_nvd",
"version": "v0.4.2",
Expand Down
40 changes: 40 additions & 0 deletions examples/templates/misp/misp_events.fabric
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
fabric {
plugin_versions = {
"blackstork/misp" = ">= 0.4 < 1.0 || 0.4.0-rev0"
}
}

document "misp_events" {
meta {
name = "example_document"
}

data misp_events "events" {
value = ""
config {
api_key = "<key>"
base_url = "https://localhost"
skip_ssl = true
}

limit = 100
}

title = "List of Events"

content table {
rows = query_jq(".data.misp_events.events.response")
columns = [
{
"header" = "Id"
"value" = "{{.row.value.Event.id}}"
},
{
"header" = "Date"
"value" = "{{.row.value.Event.date}}"
}
]
}

}

88 changes: 88 additions & 0 deletions internal/misp/client/misp_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package client

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
)

type Client struct {
baseUrl string
apiKey string

client *http.Client
}

type ClientOption func(*Client)

func WithHTTPClient(httpClient *http.Client) ClientOption {
return func(c *Client) {
c.client = httpClient
}
}

func NewClient(baseUrl string, apiKey string, opts ...ClientOption) *Client {
c := &Client{
baseUrl: baseUrl,
apiKey: apiKey,
}
for _, opt := range opts {
opt(c)
}
if c.client == nil {
c.client = &http.Client{}
}
return c
}

func (c *Client) auth(r *http.Request) {
r.Header.Set("Authorization", c.apiKey)
}

func (client *Client) Do(ctx context.Context, method, path string, payload interface{}) (resp *http.Response, err error) {
var body io.Reader
if payload != nil {
jsonBuf, err := json.Marshal(payload)
if err != nil {
return nil, err
}
reader := bytes.NewReader(jsonBuf)
body = io.NopCloser(reader)
}

req, err := http.NewRequest(method, client.baseUrl+path, body)
if err != nil {
return
}
req = req.WithContext(ctx)

req.Header = make(http.Header)
req.Header.Set("Content-Type", "application/json")
client.auth(req)
resp, err = client.client.Do(req)
if err != nil {
return nil, err
}

if resp.StatusCode != http.StatusOK {
return resp, fmt.Errorf("MISP server replied status=%d", resp.StatusCode)
}

return resp, nil
}

func (client *Client) RestSearchEvents(ctx context.Context, req RestSearchEventsRequest) (events RestSearchEventsResponse, err error) {
resp, err := client.Do(ctx, http.MethodPost, "/events/restSearch", req)
if err != nil {
return
}
defer resp.Body.Close()
err = json.NewDecoder(resp.Body).Decode(&events)
if err != nil {
return
}
return
}
Loading

0 comments on commit 2554867

Please sign in to comment.