Skip to content

Commit d014e93

Browse files
committed
ENH: add support for tagging
1 parent 3c86980 commit d014e93

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

intelmq/bots/outputs/misp/output_feed.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from intelmq.lib.utils import parse_relative
1717

1818
try:
19-
from pymisp import MISPEvent, MISPObject, MISPOrganisation, NewAttributeError
19+
from pymisp import MISPEvent, MISPObject, MISPOrganisation, MISPTag, NewAttributeError
2020
from pymisp.tools import feed_meta_generator
2121
except ImportError:
2222
# catching SyntaxError because of https://github.com/MISP/PyMISP/issues/501
@@ -38,6 +38,10 @@ class MISPFeedOutputBot(OutputBot, CacheMixin):
3838
attribute_mapping: dict = None
3939
event_separator: str = None
4040
additional_info: str = None
41+
tagging: dict = None
42+
# A structure like:
43+
# __all__: list of tag kwargs for all events
44+
# <key>: list of tag kwargs per separator key
4145

4246
@staticmethod
4347
def check_output_dir(dirname):
@@ -95,6 +99,18 @@ def init(self):
9599
self.max_time_current = self.min_time_current + self.timedelta
96100
self.current_events = {}
97101

102+
self._tagging_objects = {}
103+
if self.tagging:
104+
for key, tag_list in self.tagging.items():
105+
self._tagging_objects[key] = list()
106+
for kw in tag_list:
107+
# For some reason, PyMISP do not uses classmethod, and from_dict requires
108+
# unpacking. So this is really the way to initialize tag objects.
109+
tag = MISPTag()
110+
tag.from_dict(**kw)
111+
self._tagging_objects[key].append(tag)
112+
self.logger.debug("Generated tags: %r.", self._tagging_objects)
113+
98114
def _load_event(self, file_path: Path, key: str):
99115
if file_path.exists():
100116
self.current_events[key] = MISPEvent()
@@ -140,6 +156,14 @@ def process(self):
140156

141157
def _generate_new_event(self, key):
142158
self.current_events[key] = MISPEvent()
159+
160+
tags: list[MISPTag] = []
161+
if "__all__" in self._tagging_objects:
162+
tags.extend(self._tagging_objects["__all__"])
163+
if key in self._tagging_objects:
164+
tags.extend(self._tagging_objects[key])
165+
self.current_events[key].tags = tags
166+
143167
info = "IntelMQ event {begin} - {end}" "".format(
144168
begin=self.min_time_current.isoformat(),
145169
end=self.max_time_current.isoformat(),
@@ -195,6 +219,9 @@ def _default_mapping(self, obj: "MISPObject", message: dict):
195219
)
196220

197221
def _extract_misp_attribute_kwargs(self, message: dict, definition: dict) -> dict:
222+
"""
223+
Creates a
224+
"""
198225
# For caching and default mapping, the serialized version is the right format to work on.
199226
# However, for any custom mapping the Message object is more sufficient as it handles
200227
# subfields.

intelmq/tests/bots/outputs/misp/test_output_feed.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,19 @@ def test_event_separation_with_extra_and_bulk_save(self):
257257
objects = json.load(f).get("Event", {}).get("Object", [])
258258
assert len(objects) == 2
259259

260+
def test_tagging(self):
261+
self.run_bot(
262+
parameters={
263+
"tagging": {"__all__": [{"name": "tlp:unclear", "colour": "#7e7eae"}]}
264+
}
265+
)
266+
267+
current_event = open(f"{self.directory.name}/.current").read()
268+
with open(current_event) as f:
269+
objects = json.load(f).get("Event", {}).get("Object", [])
270+
assert len(objects) == 1
271+
272+
260273
def tearDown(self):
261274
self.cache.delete(self.bot_id)
262275
self.directory.cleanup()

0 commit comments

Comments
 (0)