swimlane / pyattck

A Python package to interact with the Mitre ATT&CK Framework

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RFE: subscriptable properties

jonathanunderwood opened this issue · comments

Is your feature request related to a problem? Please describe.
When I am using this library I find myself doing a lot of this sort of thing:

techniques = {t.id: t for t in attack.enterprise.techniques}
...
t1 = techniques["T12345"]

or

tt = [t for t in attack.enterprise.techniques if t.id == "T12345"]

etc. And similar for other lists of objects. I am aware of the ability to search, but that's quite heavy weight when I mainly just want to be able to subscript based on ATT&CK ID.

Describe the solution you'd like
It would be really helpful if the collection properties were subscriptable as well as iterable.

Describe alternatives you've considered
This is technically fairly simple to implement if we just wanted to return a dict instead of a list, breaking the old API. Personally, I'd be fine with that, but others probably have a different view.

So, the question is, does the existing iterable nature of these properties need to be preserved? And if so, how comfortable are you with breaking the existing API?

Options I can think of:

  1. Update the properties to return a dict (or IndexedOrderedDict from the indexed package) instead of a list - this changes the existing API.
  2. Add a subscriptable=False keyword argument to the Attck() constructor, which when True returns properties as dicts rather than lists. This maintains the existing API, but isn't particularly pythonic, as functions return types depending on arguments of a constructor is a undiscoverable pattern, and also makes reasoning about types difficult (for future use of type hinting)
  3. Add new properties that return dicts.

There may be others.

Add any other context or screenshots about the feature request here.
Note that since Python 3.7 insertion into dicts maintains order. Also note that the IndexedOrderedDict from the indexed package enables really fast index based lookups.

@MSAdministrator am happy to provide an implementation of this, but want to avoid taking a direction that wouldn't be acceptable. Here's my current thinking:

  • Create a decorator to add to all the properties that would take the result of the property method and creates a dict with keys being the object id fields.
  • This decorator function would only do this if the Attck object had been instantiated with subscriptable=True. The default would be subscriptable=False, in which case the decorator function would simply return the list of objects, preserving current behaviour.

WDYT of this implementation direction?

@jonathanunderwood Yeah that would be awesome and I like this approach as well. I would wait until #111 is merged though