diff --git a/pymisp/api.py b/pymisp/api.py index 0ce9eaf..b658c98 100644 --- a/pymisp/api.py +++ b/pymisp/api.py @@ -120,14 +120,7 @@ class PyMISP(object): raise PyMISPError('Unable to connect to MISP ({}). Please make sure the API key and the URL are correct (http/https is required): {}'.format(self.root_url, e)) try: - response = self.__prepare_request('GET', urljoin(self.root_url, 'attributes/describeTypes.json')) - describe_types = self._check_response(response) - if describe_types.get('error'): - for e in describe_types.get('error'): - raise PyMISPError('Failed: {}'.format(e)) - self.describe_types = describe_types['result'] - if not self.describe_types.get('sane_defaults'): - raise PyMISPError('The MISP server your are trying to reach is outdated (<2.4.52). Please use PyMISP v2.4.51.1 (pip install -I PyMISP==v2.4.51.1) and/or contact your administrator.') + self.describe_types = self.get_live_describe_types() except Exception: with open(os.path.join(self.resources_path, 'describeTypes.json'), 'r') as f: describe_types = json.load(f) @@ -138,6 +131,17 @@ class PyMISP(object): self.category_type_mapping = self.describe_types['category_type_mappings'] self.sane_default = self.describe_types['sane_defaults'] + def get_live_describe_types(self): + response = self.__prepare_request('GET', urljoin(self.root_url, 'attributes/describeTypes.json')) + describe_types = self._check_response(response) + if describe_types.get('error'): + for e in describe_types.get('error'): + raise PyMISPError('Failed: {}'.format(e)) + describe_types = describe_types['result'] + if not describe_types.get('sane_defaults'): + raise PyMISPError('The MISP server your are trying to reach is outdated (<2.4.52). Please use PyMISP v2.4.51.1 (pip install -I PyMISP==v2.4.51.1) and/or contact your administrator.') + return describe_types + def __prepare_request(self, request_type, url, data=None, background_callback=None, output_type='json'): if logger.isEnabledFor(logging.DEBUG): diff --git a/tests/test.py b/tests/test.py index 3910725..a8f22da 100755 --- a/tests/test.py +++ b/tests/test.py @@ -12,6 +12,7 @@ class TestBasic(unittest.TestCase): def setUp(self): self.maxDiff = None self.misp = PyMISP(url, key, True, 'json') + self.live_describe_types = self.misp.get_live_describe_types() def _clean_event(self, event): event['Event'].pop('orgc_id', None) @@ -253,5 +254,34 @@ class TestBasic(unittest.TestCase): def test_create_organisation(self): self.add_organisation() + def test_describeTypes_sane_default(self): + sane_default = self.live_describe_types['sane_defaults'] + self.assertEqual(sorted(sane_default.keys()), sorted(self.live_describe_types['types'])) + + def test_describeTypes_categories(self, m): + category_type_mappings = self.live_describe_types['category_type_mappings'] + self.assertEqual(sorted(category_type_mappings.keys()), sorted(self.live_describe_types['categories'])) + + def test_describeTypes_types_in_categories(self, m): + category_type_mappings = self.live_describe_types['category_type_mappings'] + for category, types in category_type_mappings.items(): + existing_types = [t for t in types if t in self.live_describe_types['types']] + self.assertEqual(sorted(existing_types), sorted(types)) + + def test_describeTypes_types_have_category(self, m): + category_type_mappings = self.live_describe_types['category_type_mappings'] + all_types = set() + for category, types in category_type_mappings.items(): + all_types.update(types) + self.assertEqual(sorted(list(all_types)), sorted(self.live_describe_types['types'])) + + def test_describeTypes_sane_default_valid_category(self, m): + sane_default = self.live_describe_types['sane_defaults'] + categories = self.live_describe_types['categories'] + for t, sd in sane_default.items(): + self.assertTrue(sd['to_ids'] in [0, 1]) + self.assertTrue(sd['default_category'] in categories) + + if __name__ == '__main__': unittest.main()