Decorator Plugins

Overview

Decorator plugins are the last plugins run just before saving results. This plugin class allows for the analysis of all results from each plugin, the original payload, and any extracted payloads. Multiple decorator plugins can be loaded, but each plugin is only passed the results once. Decorator plugins are extremely useful when post-processing is required of the collective results from the entire stoQ workflow.

Decorator plugins can be defined multiple ways. In these examples, we will use the test_decorator decorator plugin.

From stoq.cfg:

[core]
decorators = test_decorator

Note

Multiple plugins can be defined separated by a comma.

From the command line:

$ stoq run -D yara [...]

Note

Multiple plugins can be defined by simply adding the plugin name

Or, when instantiating the Stoq() class:

>>> import stoq
>>> decorators = ['test_decorator']
>>> s = Stoq(decorators=decorators, [...])

Writing a plugin

A decorator plugin must be a subclass of the DecoratorPlugin class. Results from a decorator are appended to the final StoqResponse object.

As with any plugin, a configuration file must also exist and be properly configured.

Example

from typing import Dict, Optional

from stoq.plugins import DecoratorPlugin
from stoq.helpers import StoqConfigParser
from stoq.data_classes import StoqResponse, DecoratorResponse


class ExampleDecorator(DecoratorPlugin):
    def __init__(self, config: StoqConfigParser) -> None:
        super().__init__(config)
        self.msg = config.get('options', 'msg', fallback='do_more msg')

    async def decorate(self, response: StoqResponse) -> Optional[DecoratorResponse]:
        do_more = False
        if 'yara' in response.results[0].plugins_run:
            do_more = True
        dr = DecoratorResponse({'do_more': do_more, 'msg': self.msg})
        return dr

API

class stoq.plugins.decorator.DecoratorPlugin(config)[source]
abstract async decorate(response)[source]
Return type

Optional[DecoratorResponse]

Response

class stoq.data_classes.DecoratorResponse(results=None, errors=None)[source]

Object containing response from decorator plugins

Parameters
  • results (Optional[Dict]) – Results from decorator plugin

  • errors (Optional[List[Error]]) – Errors that occurred

>>> from stoq import DecoratorResponse
>>> results = {'decorator_key': 'decorator_value'}
>>> errors = ['This plugin failed for a reason']
>>> response = DecoratorResponse(results=results, errors=errors)