From 43d8cdff4a4d355cbcef98d04355ce2902f1a9c1 Mon Sep 17 00:00:00 2001 From: Tom King Date: Mon, 4 Oct 2021 11:39:43 +0100 Subject: [PATCH 1/2] chg: Add ability to search against orgs and users by freetext search (both) or organisation (users) --- pymisp/api.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/pymisp/api.py b/pymisp/api.py index c41edd5..fe08119 100644 --- a/pymisp/api.py +++ b/pymisp/api.py @@ -2030,13 +2030,18 @@ class PyMISP: # ## BEGIN Organisation ### - def organisations(self, scope="local", pythonify: bool = False) -> Union[Dict, List[MISPOrganisation]]: + def organisations(self, scope="local", search: str = None, pythonify: bool = False) -> Union[Dict, List[MISPOrganisation]]: """Get all the organisations :param scope: scope of organizations to get + :param search: The search to make against the list of organisations :param pythonify: Returns a list of PyMISP Objects instead of the plain json output. Warning: it might use a lot of RAM """ - r = self._prepare_request('GET', f'organisations/index/scope:{scope}') + url_path = f'organisations/index/scope:{scope}' + if search: + url_path += f"/searchall:{search}" + + r = self._prepare_request('GET', url_path) organisations = self._check_json_response(r) if not (self.global_pythonify or pythonify) or 'errors' in organisations: return organisations @@ -2118,12 +2123,20 @@ class PyMISP: # ## BEGIN User ### - def users(self, pythonify: bool = False) -> Union[Dict, List[MISPUser]]: - """Get all the users + def users(self, search: str = None, organisation: int = None, pythonify: bool = False) -> Union[Dict, List[MISPUser]]: + """Get all the users, or a filtered set of users + :param search: The search to make against the list of users + :param organisation: The ID of an organisation to filter against :param pythonify: Returns a list of PyMISP Objects instead of the plain json output. Warning: it might use a lot of RAM """ - r = self._prepare_request('GET', 'admin/users/index') + urlpath = 'admin/users/index' + if search: + urlpath += f'/value:{search}' + if organisation: + organisation_id = get_uuid_or_id_from_abstract_misp(organisation) + urlpath += f"/searchorg:{organisation_id}" + r = self._prepare_request('GET', urlpath) users = self._check_json_response(r) if not (self.global_pythonify or pythonify) or 'errors' in users: return users From 1248dd459fc4e21964f042811d1c3d62cb6a52a2 Mon Sep 17 00:00:00 2001 From: Tom King Date: Wed, 13 Oct 2021 11:33:07 +0100 Subject: [PATCH 2/2] chg: Add in test case for searching against orgs and users --- tests/testlive_comprehensive.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/testlive_comprehensive.py b/tests/testlive_comprehensive.py index f372ec7..d969ecc 100644 --- a/tests/testlive_comprehensive.py +++ b/tests/testlive_comprehensive.py @@ -1771,6 +1771,33 @@ class TestComprehensive(unittest.TestCase): organisation = self.admin_misp_connector.update_organisation(organisation, pythonify=True) self.assertEqual(organisation.name, 'blah', organisation) + def test_org_search(self): + orgs = self.admin_misp_connector.organisations(pythonify=True) + org_name = 'ORGNAME' + # Search by the org name + orgs = self.admin_misp_connector.organisations(search=org_name, pythonify=True) + # There should be one org returned + self.assertTrue(len(orgs) == 1) + + # This org should have the name ORGNAME + self.assertEqual(orgs[0].name, org_name) + + def test_user_search(self): + users = self.admin_misp_connector.users(pythonify=True) + emailAddr = users[0].email + + users = self.admin_misp_connector.users(search=emailAddr) + self.assertTrue(len(users) == 1) + self.assertEqual(users[0]['User']['email'], emailAddr) + + users = self.admin_misp_connector.users( + search=emailAddr, + organisation=users[0]['Organisation']['id'], + pythonify=True + ) + self.assertTrue(len(users) == 1) + self.assertEqual(users[0].email, emailAddr) + def test_attribute(self): first = self.create_simple_event() second = self.create_simple_event()