Skip to content

Commit f3cbef0

Browse files
committed
feat(client): add all_secrets option to content_scan and multi_content_scan
1 parent 90a4f88 commit f3cbef0

File tree

3 files changed

+57
-10
lines changed

3 files changed

+57
-10
lines changed

changelog.d/20241014_101918_mathias.millet_handle_excluded_policy_breaks.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Uncomment the section that is right (remove the HTML comment wrapper).
1919

2020
### Changed
2121

22+
- `content_scan` and `multi_content_scan` now accept `all_secrets` parameter.
2223
- `PolicyBreak` now contains two new fields: `is_excluded` and `exclude_reason`.
2324
<!--
2425

pygitguardian/client.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ def content_scan(
358358
document: str,
359359
filename: Optional[str] = None,
360360
extra_headers: Optional[Dict[str, str]] = None,
361+
*,
362+
all_secrets: Optional[bool] = None,
361363
) -> Union[Detail, ScanResult]:
362364
"""
363365
content_scan handles the /scan endpoint of the API.
@@ -368,6 +370,7 @@ def content_scan(
368370
:param filename: name of file, example: "intro.py"
369371
:param document: content of file
370372
:param extra_headers: additional headers to add to the request
373+
:param all_secrets: indicates whether all secrets should be returned
371374
:return: Detail or ScanResult response and status code
372375
"""
373376

@@ -379,11 +382,15 @@ def content_scan(
379382
DocumentSchema.validate_size(
380383
request_obj, self.secret_scan_preferences.maximum_document_size
381384
)
385+
params = {}
386+
if all_secrets is not None:
387+
params["all_secrets"] = all_secrets
382388

383389
resp = self.post(
384390
endpoint="scan",
385391
data=request_obj,
386392
extra_headers=extra_headers,
393+
params=params,
387394
)
388395

389396
obj: Union[Detail, ScanResult]
@@ -401,6 +408,8 @@ def multi_content_scan(
401408
documents: List[Dict[str, str]],
402409
extra_headers: Optional[Dict[str, str]] = None,
403410
ignore_known_secrets: Optional[bool] = None,
411+
*,
412+
all_secrets: Optional[bool] = None,
404413
) -> Union[Detail, MultiScanResult]:
405414
"""
406415
multi_content_scan handles the /multiscan endpoint of the API.
@@ -413,6 +422,7 @@ def multi_content_scan(
413422
example: [{"document":"example content","filename":"intro.py"}]
414423
:param extra_headers: additional headers to add to the request
415424
:param ignore_known_secrets: indicates whether known secrets should be ignored
425+
:param all_secrets: indicates whether all secrets should be returned
416426
:return: Detail or ScanResult response and status code
417427
"""
418428
max_documents = self.secret_scan_preferences.maximum_documents_per_scan
@@ -433,11 +443,12 @@ def multi_content_scan(
433443
document, self.secret_scan_preferences.maximum_document_size
434444
)
435445

436-
params = (
437-
{"ignore_known_secrets": ignore_known_secrets}
438-
if ignore_known_secrets
439-
else {}
440-
)
446+
params = {}
447+
if ignore_known_secrets is not None:
448+
params["ignore_known_secrets"] = ignore_known_secrets
449+
if all_secrets is not None:
450+
params["all_secrets"] = all_secrets
451+
441452
resp = self.post(
442453
endpoint="multiscan",
443454
data=request_obj,

tests/test_client.py

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -575,19 +575,53 @@ def test_extra_headers(
575575

576576

577577
@responses.activate
578-
def test_multiscan_parameters(
579-
client: GGClient,
580-
):
578+
@pytest.mark.parametrize("all_secrets", (None, True, False))
579+
def test_scan_parameters(client: GGClient, all_secrets):
580+
"""
581+
GIVEN a ggclient
582+
WHEN calling content_scan with parameters
583+
THEN the parameters are passed in the request
584+
"""
585+
586+
to_match = {}
587+
if all_secrets is not None:
588+
to_match["all_secrets"] = all_secrets
589+
590+
mock_response = responses.post(
591+
url=client._url_from_endpoint("scan", "v1"),
592+
status=200,
593+
match=[matchers.query_param_matcher(to_match)],
594+
)
595+
596+
client.content_scan(
597+
DOCUMENT,
598+
FILENAME,
599+
all_secrets=all_secrets,
600+
)
601+
602+
assert mock_response.call_count == 1
603+
604+
605+
@responses.activate
606+
@pytest.mark.parametrize("ignore_known_secrets", (None, True, False))
607+
@pytest.mark.parametrize("all_secrets", (None, True, False))
608+
def test_multiscan_parameters(client: GGClient, ignore_known_secrets, all_secrets):
581609
"""
582610
GIVEN a ggclient
583611
WHEN calling multi_content_scan with parameters
584612
THEN the parameters are passed in the request
585613
"""
586614

615+
to_match = {}
616+
if ignore_known_secrets is not None:
617+
to_match["ignore_known_secrets"] = ignore_known_secrets
618+
if all_secrets is not None:
619+
to_match["all_secrets"] = all_secrets
620+
587621
mock_response = responses.post(
588622
url=client._url_from_endpoint("multiscan", "v1"),
589623
status=200,
590-
match=[matchers.query_param_matcher({"ignore_known_secrets": True})],
624+
match=[matchers.query_param_matcher(to_match)],
591625
json=[
592626
{
593627
"policy_break_count": 1,
@@ -610,7 +644,8 @@ def test_multiscan_parameters(
610644

611645
client.multi_content_scan(
612646
[{"filename": FILENAME, "document": DOCUMENT}],
613-
ignore_known_secrets=True,
647+
ignore_known_secrets=ignore_known_secrets,
648+
all_secrets=all_secrets,
614649
)
615650

616651
assert mock_response.call_count == 1

0 commit comments

Comments
 (0)