fix: fix some sorting of Cluster, ClusterValue, ClusterValueMeta

pull/28/head
Christophe Vandeplas 2024-06-25 14:51:45 +02:00
parent 295d0d8bc3
commit d374cb0218
No known key found for this signature in database
GPG Key ID: BDC48619FFDC5A5B
2 changed files with 57 additions and 10 deletions

View File

@ -31,7 +31,12 @@ class EncodeGalaxies(JSONEncoder):
class EncodeClusters(JSONEncoder): class EncodeClusters(JSONEncoder):
def default(self, obj: Any) -> Dict[str, str]: def default(self, obj: Any) -> Dict[str, str]:
if isinstance(obj, (Cluster, ClusterValue, ClusterValueMeta)): if isinstance(obj, list):
obj.sort()
return JSONEncoder.default(self, obj)
elif isinstance(obj, set):
return JSONEncoder.default(self, sorted(list(obj)))
elif isinstance(obj, (Cluster, ClusterValue, ClusterValueMeta)):
return obj.to_dict() return obj.to_dict()
return JSONEncoder.default(self, obj) return JSONEncoder.default(self, obj)
@ -122,7 +127,7 @@ class Galaxy():
""" """
return json.dumps(self, cls=EncodeGalaxies, sort_keys=True) return json.dumps(self, cls=EncodeGalaxies, sort_keys=True)
def to_dict(self) -> Dict[str, str]: def to_dict(self) -> Dict[str, Any]:
""" """
Converts the galaxy object to a dictionary. Converts the galaxy object to a dictionary.
@ -229,7 +234,7 @@ class Galaxies(Mapping): # type: ignore
class ClusterValueMeta(): class ClusterValueMeta():
def __init__(self, m: Dict[str, str]): def __init__(self, m: Dict[str, Any]):
self.type = m.pop('type', None) self.type = m.pop('type', None)
self.complexity = m.pop('complexity', None) self.complexity = m.pop('complexity', None)
self.effectiveness = m.pop('effectiveness', None) self.effectiveness = m.pop('effectiveness', None)
@ -238,8 +243,9 @@ class ClusterValueMeta():
self.colour = m.pop('colour', None) self.colour = m.pop('colour', None)
self.motive = m.pop('motive', None) self.motive = m.pop('motive', None)
self.impact = m.pop('impact', None) self.impact = m.pop('impact', None)
self.refs = m.pop('refs', None) self.refs: Set[str] = set(m.pop('refs', []))
self.synonyms = m.pop('synonyms', None) self.official_refs: Set[str] = set(m.pop('official-refs', []))
self.synonyms: Set[str] = set(m.pop('synonyms', []))
self.derivated_from = m.pop('derivated_from', None) self.derivated_from = m.pop('derivated_from', None)
self.status = m.pop('status', None) self.status = m.pop('status', None)
self.date = m.pop('date', None) self.date = m.pop('date', None)
@ -253,7 +259,7 @@ class ClusterValueMeta():
def to_json(self) -> str: def to_json(self) -> str:
return json.dumps(self, cls=EncodeClusters, sort_keys=True) return json.dumps(self, cls=EncodeClusters, sort_keys=True)
def to_dict(self) -> Dict[str, str]: def to_dict(self) -> Dict[str, Any]:
to_return = {} to_return = {}
if self.type: if self.type:
to_return['type'] = self.type to_return['type'] = self.type
@ -272,9 +278,11 @@ class ClusterValueMeta():
if self.impact: if self.impact:
to_return['impact'] = self.impact to_return['impact'] = self.impact
if self.refs: if self.refs:
to_return['refs'] = self.refs to_return['refs'] = sorted(list(self.refs))
if self.official_refs:
to_return['official-refs'] = sorted(list(self.official_refs))
if self.synonyms: if self.synonyms:
to_return['synonyms'] = self.synonyms to_return['synonyms'] = sorted(list(self.synonyms))
if self.derivated_from: if self.derivated_from:
to_return['derivated_from'] = self.derivated_from to_return['derivated_from'] = self.derivated_from
if self.status: if self.status:
@ -288,7 +296,11 @@ class ClusterValueMeta():
if self.ransomnotes: if self.ransomnotes:
to_return['ransomnotes'] = self.ransomnotes to_return['ransomnotes'] = self.ransomnotes
if self.additional_properties: if self.additional_properties:
to_return.update(self.additional_properties) for key, value in self.additional_properties.items():
if isinstance(value, list):
to_return[key] = sorted(value)
else:
to_return[key] = value
return to_return return to_return
@ -397,7 +409,7 @@ class ClusterValue():
if self.meta: if self.meta:
to_return['meta'] = self.meta.to_dict() to_return['meta'] = self.meta.to_dict()
if self.related: if self.related:
to_return['related'] = self.related to_return['related'] = sorted(self.related, key=lambda x: x['dest-uuid'])
return to_return return to_return

View File

@ -82,3 +82,38 @@ class TestPyMISPGalaxiesApi(unittest.TestCase):
galaxy.description = 'new description' galaxy.description = 'new description'
self.assertTrue(galaxy.has_changed()) self.assertTrue(galaxy.has_changed())
def test_clustervalue_sort_related(self):
cv = ClusterValue({'value': 'test'})
item_1 = {
'dest-uuid': '1',
'type': 'subtechnique-of'
}
item_2 = {
'dest-uuid': '2',
'type': 'similar-to'
}
cv.related = []
cv.related.append(item_2)
cv.related.append(item_1)
self.assertListEqual(cv.related, [item_2, item_1])
d = cv.to_dict()
self.assertListEqual(d['related'], [item_1, item_2])
def test_cluster_sort_synonyms(self):
cv = ClusterValue({
'value': 'test',
'meta': {
'synonyms': ['b', 'a', 'c']
}})
d = cv.to_dict()
self.assertListEqual(d['meta']['synonyms'], ['a', 'b', 'c'])
def test_cluster_sort_additional_property(self):
cv = ClusterValue({
'value': 'test',
'meta': {
'hello_world': ['b', 'a', 'c']
}})
d = cv.to_dict()
self.assertListEqual(d['meta']['hello_world'], ['a', 'b', 'c'])