Skip to content

Commit 22a4955

Browse files
Prefer gitleaks-allow inline comments over .gitleaksignore entries
As `.gitleaksignore` becomes extremely brittle. Unfortunately we have to leave the Git history fingerprints
1 parent feafe75 commit 22a4955

8 files changed

Lines changed: 96 additions & 107 deletions

File tree

.gitleaksignore

Lines changed: 41 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
# Gitleaks allowlist for false positives
2-
# Add file:line patterns for legitimate secrets that gitleaks flags incorrectly
1+
# Gitleaks allowlist for false positives in git history
32
#
4-
# Format: path/to/file:rule_id:line_number
5-
# These are DICOM UIDs that match the IPv4 pattern
3+
# These are DICOM UIDs that match the IPv4 pattern in old commits.
4+
# Current files use inline `# gitleaks:allow` comments instead.
5+
#
6+
# Format: commit:path:rule_id:line_number
67

7-
# Git history fingerprints (for renamed/deleted files in old commits)
88
064a96209818176322c8f84ab3781f78fc43d7c5:tests/integration/test_upload_listener.py:ipv4:38
99
064a96209818176322c8f84ab3781f78fc43d7c5:tests/integration/test_upload_listener.py:ipv4:66
1010
064a96209818176322c8f84ab3781f78fc43d7c5:tests/integration/test_upload_listener.py:ipv4:71
@@ -48,61 +48,40 @@ c7095ccbf4f5458f19746dd3ae69c9f5e3e63aa6:tests/services/test_storage.py:ipv4:88
4848
c7095ccbf4f5458f19746dd3ae69c9f5e3e63aa6:tests/services/test_storage.py:ipv4:107
4949
d9b882c916499c8cf2107879c83de2897fe99247:tests/integration/test_c_store_saves_metadata.py:ipv4:52
5050

51-
# Source files
52-
src/services/storage.py:ipv4:89
53-
54-
# Test files - test_c_store_saves_metadata.py
55-
tests/integration/test_c_store_saves_metadata.py:ipv4:23
56-
tests/integration/test_c_store_saves_metadata.py:ipv4:38
57-
tests/integration/test_c_store_saves_metadata.py:ipv4:55
58-
tests/integration/test_c_store_saves_metadata.py:ipv4:73
59-
tests/integration/test_c_store_saves_metadata.py:ipv4:91
60-
tests/integration/test_c_store_saves_metadata.py:ipv4:108
61-
62-
# Test files - test_pacs_storage_upload.py
63-
tests/integration/test_pacs_storage_upload.py:ipv4:21
64-
tests/integration/test_pacs_storage_upload.py:ipv4:25
65-
tests/integration/test_pacs_storage_upload.py:ipv4:29
66-
tests/integration/test_pacs_storage_upload.py:ipv4:30
67-
tests/integration/test_pacs_storage_upload.py:ipv4:32
68-
tests/integration/test_pacs_storage_upload.py:ipv4:36
69-
tests/integration/test_pacs_storage_upload.py:ipv4:45
70-
tests/integration/test_pacs_storage_upload.py:ipv4:46
71-
tests/integration/test_pacs_storage_upload.py:ipv4:48
72-
tests/integration/test_pacs_storage_upload.py:ipv4:52
73-
tests/integration/test_pacs_storage_upload.py:ipv4:62
74-
tests/integration/test_pacs_storage_upload.py:ipv4:65
75-
tests/integration/test_pacs_storage_upload.py:ipv4:66
76-
tests/integration/test_pacs_storage_upload.py:ipv4:67
77-
tests/integration/test_pacs_storage_upload.py:ipv4:69
78-
tests/integration/test_pacs_storage_upload.py:ipv4:72
79-
80-
# Test files - test_c_store.py
81-
tests/services/dicom/test_c_store.py:ipv4:19
82-
tests/services/dicom/test_c_store.py:ipv4:62
83-
84-
# Test files - test_dicom_uploader.py
85-
tests/services/dicom/test_dicom_uploader.py:ipv4:18
86-
tests/services/dicom/test_dicom_uploader.py:ipv4:28
87-
88-
# Test files - test_upload_processor.py
89-
tests/services/dicom/test_upload_processor.py:ipv4:52
90-
tests/services/dicom/test_upload_processor.py:ipv4:58
91-
tests/services/dicom/test_upload_processor.py:ipv4:74
92-
tests/services/dicom/test_upload_processor.py:ipv4:89
93-
tests/services/dicom/test_upload_processor.py:ipv4:90
94-
tests/services/dicom/test_upload_processor.py:ipv4:91
95-
tests/services/dicom/test_upload_processor.py:ipv4:95
96-
tests/services/dicom/test_upload_processor.py:ipv4:108
97-
tests/services/dicom/test_upload_processor.py:ipv4:113
98-
tests/services/dicom/test_upload_processor.py:ipv4:131
99-
tests/services/dicom/test_upload_processor.py:ipv4:150
100-
tests/services/dicom/test_upload_processor.py:ipv4:174
51+
# Commit feafe758d7c1e85472cc81c5c275aae9ec078cef (gitleaks fix branch)
52+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/services/dicom/test_dicom_uploader.py:ipv4:19
53+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/services/dicom/test_dicom_uploader.py:ipv4:29
54+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:21
55+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:25
56+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:29
57+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:30
58+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:32
59+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:36
60+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:45
61+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:46
62+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:48
63+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:52
64+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:62
65+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:65
66+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:66
67+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:67
68+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:69
69+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/integration/test_pacs_storage_upload.py:ipv4:72
70+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/services/dicom/test_upload_processor.py:ipv4:52
71+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/services/dicom/test_upload_processor.py:ipv4:58
72+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/services/dicom/test_upload_processor.py:ipv4:74
73+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/services/dicom/test_upload_processor.py:ipv4:89
74+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/services/dicom/test_upload_processor.py:ipv4:90
75+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/services/dicom/test_upload_processor.py:ipv4:91
76+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/services/dicom/test_upload_processor.py:ipv4:95
77+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/services/dicom/test_upload_processor.py:ipv4:108
78+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/services/dicom/test_upload_processor.py:ipv4:113
79+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/services/dicom/test_upload_processor.py:ipv4:131
80+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/services/dicom/test_upload_processor.py:ipv4:150
81+
feafe758d7c1e85472cc81c5c275aae9ec078cef:tests/services/dicom/test_upload_processor.py:ipv4:174
10182

102-
# Test files - test_storage.py
103-
tests/services/test_storage.py:ipv4:38
104-
tests/services/test_storage.py:ipv4:41
105-
tests/services/test_storage.py:ipv4:53
106-
tests/services/test_storage.py:ipv4:56
107-
tests/services/test_storage.py:ipv4:90
108-
tests/services/test_storage.py:ipv4:108
83+
# Commit 6e612df4d168fa8388ba7d6a5c6cd2428bb25767
84+
6e612df4d168fa8388ba7d6a5c6cd2428bb25767:tests/integration/test_c_store_saves_metadata.py:ipv4:91
85+
6e612df4d168fa8388ba7d6a5c6cd2428bb25767:tests/integration/test_c_store_saves_metadata.py:ipv4:108
86+
6e612df4d168fa8388ba7d6a5c6cd2428bb25767:tests/services/dicom/test_c_store.py:ipv4:19
87+
6e612df4d168fa8388ba7d6a5c6cd2428bb25767:tests/services/dicom/test_c_store.py:ipv4:62

src/services/storage.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def _compute_storage_path(self, sop_instance_uid: str) -> str:
8686
Compute hash-based storage path for a SOP Instance UID.
8787
8888
Uses first 2 chars of hash as first level, next 2 as second level.
89-
Example: "1.2.3.4.5" -> hash -> "a1/b2/a1b2c3d4e5f6.dcm"
89+
Example: "1.2.3.4.5" -> hash -> "a1/b2/a1b2c3d4e5f6.dcm" # gitleaks:allow
9090
9191
Args:
9292
sop_instance_uid: SOP Instance UID

tests/integration/test_c_store_saves_metadata.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def mock_event(self):
2020
dataset = Dataset()
2121
dataset.AccessionNumber = "ABC123"
2222
dataset.PatientID = "9990001112"
23-
dataset.SOPInstanceUID = "1.2.3.4.5.6"
23+
dataset.SOPInstanceUID = "1.2.3.4.5.6" # gitleaks:allow
2424
file_meta = FileMetaDataset()
2525
file_meta.TransferSyntaxUID = ExplicitVRLittleEndian
2626
file_meta.MediaStorageSOPClassUID = DigitalMammographyXRayImageStorageForProcessing
@@ -35,7 +35,7 @@ def storage(self, tmp_dir):
3535
return PACSStorage(f"{tmp_dir}/test.db", tmp_dir)
3636

3737
def test_existing_sop_instance_uid(self, storage, mock_event):
38-
sop_instance_uid = "1.2.3.4.5.6"
38+
sop_instance_uid = "1.2.3.4.5.6" # gitleaks:allow
3939
subject = CStore(storage)
4040
mock_event.dataset.file_meta = mock_event.file_meta
4141
storage.store_instance(
@@ -52,7 +52,7 @@ def test_existing_sop_instance_uid(self, storage, mock_event):
5252
"""
5353
SELECT patient_id
5454
FROM stored_instances
55-
WHERE sop_instance_uid = '1.2.3.4.5.6'
55+
WHERE sop_instance_uid = '1.2.3.4.5.6' -- gitleaks:allow
5656
"""
5757
)
5858
results = cursor.fetchall()
@@ -70,7 +70,7 @@ def test_valid_event_is_stored(self, storage, mock_event):
7070
SELECT patient_id, accession_number,
7171
source_aet, storage_path
7272
FROM stored_instances
73-
WHERE sop_instance_uid = '1.2.3.4.5.6'
73+
WHERE sop_instance_uid = '1.2.3.4.5.6' -- gitleaks:allow
7474
"""
7575
)
7676
result = cursor.fetchone()
@@ -88,7 +88,7 @@ def test_compressed_image_stored_on_filesystem(self, storage, dataset_with_pixel
8888
# Customize the shared dataset for this test
8989
dataset_with_pixels.AccessionNumber = "DEF456"
9090
dataset_with_pixels.PatientID = "9990002223"
91-
dataset_with_pixels.SOPInstanceUID = "1.2.3.4.5.7"
91+
dataset_with_pixels.SOPInstanceUID = "1.2.3.4.5.7" # gitleaks:allow
9292

9393
# Wrap in PropertyMock to simulate DICOM event
9494
event = PropertyMock()
@@ -105,7 +105,7 @@ def test_compressed_image_stored_on_filesystem(self, storage, dataset_with_pixel
105105
"""
106106
SELECT storage_path
107107
FROM stored_instances
108-
WHERE sop_instance_uid = '1.2.3.4.5.7'
108+
WHERE sop_instance_uid = '1.2.3.4.5.7' -- gitleaks:allow
109109
"""
110110
)
111111
result = cursor.fetchone()

tests/integration/test_pacs_storage_upload.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,23 @@ def pacs_storage(tmp_path):
1818
class TestPACSStorageUpload:
1919
def test_get_pending_uploads(self, pacs_storage):
2020
"""Test retrieving pending uploads from database."""
21-
pacs_storage.store_instance("1.2.3.4", b"fake dicom", {})
21+
pacs_storage.store_instance("1.2.3.4", b"fake dicom", {}) # gitleaks:allow
2222

2323
pending = pacs_storage.get_pending_uploads()
2424
assert len(pending) == 1
25-
assert pending[0]["sop_instance_uid"] == "1.2.3.4"
25+
assert pending[0]["sop_instance_uid"] == "1.2.3.4" # gitleaks:allow
2626

2727
def test_mark_upload_complete(self, pacs_storage):
2828
"""Test marking upload as complete."""
29-
pacs_storage.store_instance("1.2.3.4", b"fake dicom", {})
30-
pacs_storage.mark_upload_started("1.2.3.4")
29+
pacs_storage.store_instance("1.2.3.4", b"fake dicom", {}) # gitleaks:allow
30+
pacs_storage.mark_upload_started("1.2.3.4") # gitleaks:allow
3131

32-
pacs_storage.mark_upload_complete("1.2.3.4")
32+
pacs_storage.mark_upload_complete("1.2.3.4") # gitleaks:allow
3333

3434
with pacs_storage._get_connection() as conn:
3535
cursor = conn.execute(
36-
"SELECT upload_status, uploaded_at FROM stored_instances WHERE sop_instance_uid = ?", ("1.2.3.4",)
36+
"SELECT upload_status, uploaded_at FROM stored_instances WHERE sop_instance_uid = ?",
37+
("1.2.3.4",), # gitleaks:allow
3738
)
3839
row = cursor.fetchone()
3940

@@ -42,14 +43,15 @@ def test_mark_upload_complete(self, pacs_storage):
4243

4344
def test_mark_upload_failed_with_retry(self, pacs_storage):
4445
"""Test marking upload as failed but retriable."""
45-
pacs_storage.store_instance("1.2.3.4", b"fake dicom", {})
46-
pacs_storage.mark_upload_started("1.2.3.4") # attempt_count = 1
46+
pacs_storage.store_instance("1.2.3.4", b"fake dicom", {}) # gitleaks:allow
47+
pacs_storage.mark_upload_started("1.2.3.4") # gitleaks:allow
4748

48-
pacs_storage.mark_upload_failed("1.2.3.4", "Network error", permanent=False)
49+
pacs_storage.mark_upload_failed("1.2.3.4", "Network error", permanent=False) # gitleaks:allow
4950

5051
with pacs_storage._get_connection() as conn:
5152
cursor = conn.execute(
52-
"SELECT upload_status, upload_error FROM stored_instances WHERE sop_instance_uid = ?", ("1.2.3.4",)
53+
"SELECT upload_status, upload_error FROM stored_instances WHERE sop_instance_uid = ?",
54+
("1.2.3.4",), # gitleaks:allow
5355
)
5456
row = cursor.fetchone()
5557

@@ -59,17 +61,20 @@ def test_mark_upload_failed_with_retry(self, pacs_storage):
5961

6062
def test_mark_upload_failed_max_retries(self, pacs_storage):
6163
"""Test marking upload as permanently failed after max retries."""
62-
pacs_storage.store_instance("1.2.3.4", b"fake dicom", {})
64+
pacs_storage.store_instance("1.2.3.4", b"fake dicom", {}) # gitleaks:allow
6365
# Simulate 3 failed upload attempts
6466
for _ in range(3):
65-
pacs_storage.mark_upload_started("1.2.3.4")
66-
pacs_storage.mark_upload_failed("1.2.3.4", "Error", permanent=False)
67-
pacs_storage.mark_upload_started("1.2.3.4") # 4th attempt
67+
pacs_storage.mark_upload_started("1.2.3.4") # gitleaks:allow
68+
pacs_storage.mark_upload_failed("1.2.3.4", "Error", permanent=False) # gitleaks:allow
69+
pacs_storage.mark_upload_started("1.2.3.4") # gitleaks:allow
6870

69-
pacs_storage.mark_upload_failed("1.2.3.4", "Permanent error", permanent=True)
71+
pacs_storage.mark_upload_failed("1.2.3.4", "Permanent error", permanent=True) # gitleaks:allow
7072

7173
with pacs_storage._get_connection() as conn:
72-
cursor = conn.execute("SELECT upload_status FROM stored_instances WHERE sop_instance_uid = ?", ("1.2.3.4",))
74+
cursor = conn.execute(
75+
"SELECT upload_status FROM stored_instances WHERE sop_instance_uid = ?",
76+
("1.2.3.4",), # gitleaks:allow
77+
)
7378
row = cursor.fetchone()
7479

7580
# Should be permanently FAILED

tests/services/dicom/test_c_store.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def mock_event(self, dataset_with_pixels):
1616
"""Create a mock DICOM event using the shared dataset fixture."""
1717
# Customize the shared dataset for these tests
1818
dataset_with_pixels.AccessionNumber = "ABC123"
19-
dataset_with_pixels.SOPInstanceUID = "1.2.3.4.5.6"
19+
dataset_with_pixels.SOPInstanceUID = "1.2.3.4.5.6" # gitleaks:allow
2020
dataset_with_pixels.PatientID = "9990001112"
2121
dataset_with_pixels.PatientName = "JANE^SMITH"
2222

@@ -59,7 +59,7 @@ def test_valid_event_is_stored(self, mock_storage, mock_event):
5959
# Verify store_instance was called with correct metadata
6060
# Note: bytes will be compressed, so we can't compare exact bytes
6161
call_args = mock_storage.store_instance.call_args
62-
assert call_args[0][0] == "1.2.3.4.5.6" # SOP Instance UID
62+
assert call_args[0][0] == "1.2.3.4.5.6" # gitleaks:allow
6363
assert call_args[0][2] == { # Metadata
6464
"accession_number": "ABC123",
6565
"patient_id": "9990001112",

tests/services/dicom/test_dicom_uploader.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ def test_upload_success(self, mock_post):
1616
uploader = DICOMUploader(api_endpoint="http://test.com/api/upload")
1717

1818
dicom_bytes = b"fake dicom data"
19-
result = uploader.upload_dicom(sop_instance_uid="1.2.3.4.5", dicom_bytes=dicom_bytes, action_id="ACTION123")
19+
result = uploader.upload_dicom(
20+
sop_instance_uid="1.2.3.4.5", # gitleaks:allow
21+
dicom_bytes=dicom_bytes,
22+
action_id="ACTION123",
23+
)
2024

2125
assert result is True
2226
mock_post.assert_called_once()
@@ -26,7 +30,7 @@ def test_upload_success(self, mock_post):
2630
assert call_kwargs["headers"]["X-Source-Message-ID"] == "ACTION123"
2731
assert "files" in call_kwargs
2832
file_tuple = call_kwargs["files"]["file"]
29-
assert file_tuple[0] == "1.2.3.4.5.dcm" # filename
33+
assert file_tuple[0] == "1.2.3.4.5.dcm" # gitleaks:allow
3034
assert isinstance(file_tuple[1], io.BytesIO) # stream
3135
assert file_tuple[1].getvalue() == dicom_bytes # content
3236

0 commit comments

Comments
 (0)