Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/falconpy/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

For more information, please refer to <https://unlicense.org>
"""
_VERSION = '1.5.5'
_VERSION = '1.6.0'
_HEC_VERSION = '1.0.0'
_MAINTAINER = 'Joshua Hiller'
_AUTHOR = 'CrowdStrike'
Expand Down
14 changes: 9 additions & 5 deletions src/falconpy/ngsiem.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,9 @@ def stop_search(self: object,
"""Stop search.

Keyword arguments:
repository -- name of repository
id -- id of query
repository -- Name of repository. String.
id -- ID of the query. String. Can be used instead of search_id keyword.
search_id -- ID of the query. String. Can be used instead of id keyword.
parameters -- Full parameters payload dictionary. Not required if using other keywords.

This method only supports keywords for providing arguments.
Expand All @@ -422,12 +423,15 @@ def stop_search(self: object,
https://assets.falcon.crowdstrike.com/support/api/swagger.html#/humio-auth-proxy/StopSearchV1
"""
repository = kwargs.get("repository", None)
search_id = kwargs.get("search_id", None)
search_id = kwargs.get("id", kwargs.get("search_id", None))
if repository and search_id:
# Pop the path variables from the keywords dictionary
# before processing query string arguments.
kwargs.pop("repository")
kwargs.pop("search_id")
if "id" in kwargs:
kwargs.pop("id")
if "search_id" in kwargs:
kwargs.pop("search_id")
returned = process_service_request(
calling_object=self,
endpoints=Endpoints,
Expand All @@ -438,7 +442,7 @@ def stop_search(self: object,
search_id=search_id
)
else:
returned = generate_error_result("You must provide a repository and search_id "
returned = generate_error_result("You must provide a repository and id "
"argument in order to use this operation."
)
return returned
Expand Down
19 changes: 17 additions & 2 deletions tests/test_authentications.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
_DEBUG = os.getenv("FALCONPY_UNIT_TEST_DEBUG", None)
if _DEBUG:
_DEBUG = True
_MSSP = None


class TestAuthentications:
Expand Down Expand Up @@ -107,7 +108,7 @@ def serviceAny_checkRegionNameLookups(self):
base_url="usgov1", debug=_DEBUG
)
result = falcon.token()
if result["status_code"] == 400:
if result["status_code"] in [400, 403]:
return True
elif result["status_code"] == 429:
pytest.skip("Rate limit hit")
Expand Down Expand Up @@ -362,4 +363,18 @@ def test_child_login_logout(self):
failed_child_login = test_object.child_logout(login_as_parent=False)
if not failed_child_login:
_success = True
assert _success
assert _success


def test_mssp_login(self):
global _MSSP
_success = False
_MSSP = Hosts(client_id=auth.config["falcon_client_id"], client_secret=auth.config["falcon_client_secret"], debug=_DEBUG)
if not _MSSP.child_login(member_cid="1234567890"):
_success = True
_MSSP.auth_object.creds["member_cid"] = "1234567890"
assert(_success)

def test_mssp_logout(self):
#_MSSP = Hosts(client_id=auth.config["falcon_client_id"], client_secret=auth.config["falcon_client_secret"], debug=_DEBUG)
print(_MSSP.child_logout(login_as_parent=False))
12 changes: 6 additions & 6 deletions tests/test_case_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,33 +26,33 @@ def test_all_code_paths(self):
"aggregates_file_details_post_v1": falcon.aggregates_file_details_post_v1(),
"combined_file_details_get_v1": falcon.query_file_details(),
"entities_file_details_get_v1": falcon.get_file_details(ids="1234567890"),
#"entities_file_details_patch_v1": falcon.update_file_details(body={}),
"entities_file_details_patch_v1": falcon.update_file_details(id="12345678"),
"entities_files_bulk_download_post_v1": falcon.bulk_download_files(body={}),
"entities_files_download_get_v1": falcon.download_existing_files(id="1234567890"),
#"entities_files_upload_post_v1": falcon.CHECKTHIS_upload_file(),
"entities_files_delete_v1": falcon.delete_file_details(ids="1234567890"),
"queries_file_details_get_v1": falcon.query_file_detail_ids(),
"aggregates_notification_groups_post_v1": falcon.get_notification_groups(body={}),
"aggregates_notification_groups_post_v1": falcon.get_notification_groups(date_ranges={"from": "whenever", "to": "whenever"}),
"aggregates_notification_groups_post_v2": falcon.get_notification_groups_v2(body={}),
"aggregates_slas_post_v1": falcon.get_sla_aggregations(body={}),
"aggregates_templates_post_v1": falcon.get_template_aggregations(body={}),
"entities_fields_get_v1": falcon.get_fields(ids=["1234567890"]),
"entities_notification_groups_get_v1": falcon.get_notification_groups(ids=["1234567890"]),
"entities_notification_groups_post_v1": falcon.create_notification_group(body={}),
"entities_notification_groups_post_v1": falcon.create_notification_group(name="whatever"),
"entities_notification_groups_patch_v1": falcon.update_notification_group(body={}),
"entities_notification_groups_delete_v1": falcon.delete_notification_group(ids=["1234567890"]),
"entities_notification_groups_post_v2": falcon.create_notification_group_v2(body={}),
"entities_notification_groups_patch_v2": falcon.update_notification_group_v2(body={}),
"entities_notification_groups_delete_v2": falcon.delete_notification_group_v2(ids=["1234567890"]),
"entities_slas_get_v1": falcon.get_slas(ids="1234567890"),
"entities_slas_post_v1": falcon.create_sla(body={}),
"entities_slas_post_v1": falcon.create_sla(description="whatever"),
"entities_slas_patch_v1": falcon.update_sla(body={}),
"entities_slas_delete_v1": falcon.delete_sla(ids="1234567890"),
"entities_template_snapshots_get_v1": falcon.get_template_snapshots(template_ids="1234567890"),
"entities_templates_export_get_v1": falcon.export_templates(ids="1234567890"),
"entities_templates_import_post_v1": falcon.import_template(file="README.md"),
"entities_templates_get_v1": falcon.get_templates(ids="1234567890"),
"entities_templates_post_v1": falcon.create_template(body={}),
"entities_templates_post_v1": falcon.create_template(description="whatever"),
"entities_templates_patch_v1": falcon.update_template(body={}),
"entities_templates_delete_v1": falcon.delete_templates(ids="1234567890"),
"queries_fields_get_v1": falcon.query_fields(),
Expand All @@ -67,7 +67,7 @@ def test_all_code_paths(self):
"entities_cases_put_v2": falcon.create_case(body={}),
"entities_cases_post_v2": falcon.get_cases(ids="1234567890"),
"entities_cases_patch_v2": falcon.update_case_fields(body={}),
"entities_event_evidence_post_v1": falcon.add_case_event_evidence(body={}),
"entities_event_evidence_post_v1": falcon.add_case_event_evidence(id="12345678"),
"queries_cases_get_v1": falcon.query_case_ids()
}
for key in tests:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_cloud_azure_registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class TestCloudAzureRegistration:
def test_all_code_paths(self):
error_checks = True
tests = {
"cloud_registration_azure_delete_legacy_subscription": falcon.delete_legacy_subscription(body={}),
"cloud_registration_azure_delete_legacy_subscription": falcon.delete_legacy_subscription(subscription_id="12345678"),
"cloud_registration_azure_trigger_health_check": falcon.health_check(tenant_id="12345678"),
"cloud_registration_azure_get_registration": falcon.get_registration(tenant_id="12345678"),
"cloud_registration_azure_create_registration": falcon.create_registration(**AZURE_PAYLOAD["resource"]),
Expand Down
2 changes: 1 addition & 1 deletion tests/test_downloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
auth = Authorization.TestAuthorization()
config = auth.getConfigObject()
falcon = Downloads(auth_object=config)
AllowedResponses = [200, 201, 207, 404, 429]
AllowedResponses = [200, 201, 207, 403, 404, 429]

class TestDownloads:
def test_all_code_paths(self):
Expand Down
19 changes: 17 additions & 2 deletions tests/test_ngsiem.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ def run_all_tests(self):

follow_up_tests = {
"GetSearchStatusV1": falcon.get_search_status(repository="search-all", search_id=search_id),
"GetSearchStatusV1": falcon.get_search_status(repository="search-all", id=search_id),
"StopSearchV1": falcon.stop_search(repository="search-all", search_id=search_id)
"GetSearchStatusV1-id": falcon.get_search_status(repository="search-all", id=search_id),
"StopSearchV1-search_id": falcon.stop_search(repository="search-all", search_id=search_id),
"StopSearchV1-id": falcon.stop_search(repository="search-all", id=search_id)
}
for follow_key in follow_up_tests:
if follow_up_tests[follow_key]["status_code"] not in AllowedResponses:
Expand Down Expand Up @@ -132,5 +133,19 @@ def run_all_tests(self):
error_checks = False
return error_checks

def test_stop_search_parameter_handling(self):
"""Test that stop_search accepts both 'id' and 'search_id' parameters (Issue #1398)."""
# Test with search_id parameter
result_search_id = falcon.stop_search(repository="search-all", search_id="test-id-123")
assert result_search_id["status_code"] in AllowedResponses

# Test with id parameter (should also work)
result_id = falcon.stop_search(repository="search-all", id="test-id-456")
assert result_id["status_code"] in AllowedResponses

# Test error case - missing search_id
result_error = falcon.stop_search(repository="search-all")
assert result_error["status_code"] == 500

def test_all_functionality(self):
assert self.run_all_tests() is True