Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6e9ed11
adding pseudonym to wador views
chinacat567 May 16, 2025
cd86735
using pydicomweb-client
chinacat567 May 16, 2025
fd6c6b5
Merge branch 'main' into adit-pseudonym
chinacat567 May 16, 2025
32a21bb
lint fix, lockfile update
chinacat567 May 16, 2025
3ec96a7
fixing formatting
chinacat567 May 18, 2025
0524510
fixing merge conflicts
chinacat567 May 18, 2025
1c24d03
fixing formatting errors
chinacat567 May 18, 2025
1932e62
more formatting fixes
chinacat567 May 18, 2025
0cf5bff
parsing pseudonym
chinacat567 May 19, 2025
325470d
Merge branch 'main' into adit-pseudonym
chinacat567 May 19, 2025
83e29ea
adding char limit, wildcard validation and tests
chinacat567 May 20, 2025
3caa6ef
validator and test refac
chinacat567 May 21, 2025
c3ad5a4
shared pseudnymizer, test changes
chinacat567 May 23, 2025
aaf8340
bug fix
chinacat567 May 23, 2025
0e219c3
adit client deadcode removal
chinacat567 May 23, 2025
4daa0b5
pseudonymizer changes
chinacat567 May 23, 2025
7f2136e
refac validate_pseudonym -> _get_pseudonym
chinacat567 May 24, 2025
ba3e6ee
passing pseudonym through adit client and changing acceptance tests t…
chinacat567 May 24, 2025
0928602
reorg validator directory
chinacat567 May 25, 2025
8f4456d
adding metadata functions to adit_client
chinacat567 May 25, 2025
b40a44a
unit test fix
chinacat567 May 25, 2025
5bca9eb
Merge branch 'main' into adit-pseudonym
chinacat567 May 25, 2025
22a9d74
pydicomweb-client => dicomweb-client
chinacat567 May 25, 2025
9bd49c3
<broken> : pseduonymizer changes, pytest changes
chinacat567 May 27, 2025
2631705
bug fix
chinacat567 May 27, 2025
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
4 changes: 4 additions & 0 deletions adit/core/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
inverse_match=True,
)

char_limit_validator = RegexValidator(
regex=r".{0,64}", message="String too long (max 64 characters)."
)

uid_chars_validator = RegexValidator(regex=r"^[\d\.]+$", message="Invalid character in UID.")


Expand Down
240 changes: 142 additions & 98 deletions adit/dicom_web/tests/acceptance/test_wadors.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,24 +83,31 @@ def test_retrieve_study_with_invalid_pseudonym(channels_live_server: ChannelsLiv

metadata = load_sample_dicoms_metadata("1001")
study_uid: str = metadata.iloc[0]["StudyInstanceUID"]
test_pseudonym = "Test\\Pseudonym"
additional_params = {
"pseudonym": test_pseudonym,
}
test_pseudonyms = [
"Test\\Pseudonym1", # Invalid due to backslash
"Test\u0001Pseudonym2", # Invalid due to control character
"Test*Pseudonym3", # Invalid due to wildcard character
"T" * 65, # Invalid due to exceeding character limit
]

for test_pseudonym in test_pseudonyms:
additional_params = {
"pseudonym": test_pseudonym,
}

try:
orthanc1_client.retrieve_study(study_uid, additional_params=additional_params)
except HTTPError as e:
response = e.response
assert response is not None
assert response.status_code == HTTPStatus.BAD_REQUEST
try:
error = response.json()
assert "pseudonym" in error or "invalid" in str(error).lower(), (
f"Unexpected error: {error}"
)
except Exception:
assert "invalid" in response.text.lower(), f"Unexpected response: {response.text}"
orthanc1_client.retrieve_study(study_uid, additional_params=additional_params)
except HTTPError as e:
response = e.response
assert response is not None
assert response.status_code == HTTPStatus.BAD_REQUEST
try:
error = response.json()
assert "pseudonym" in error or "invalid" in str(error).lower(), (
f"Unexpected error: {error}"
)
except Exception:
assert "invalid" in response.text.lower(), f"Unexpected response: {response.text}"


@pytest.mark.acceptance
Expand Down Expand Up @@ -180,24 +187,31 @@ def test_retrieve_study_metadata_with_invalid_pseudonym(

metadata = load_sample_dicoms_metadata("1001")
study_uid: str = metadata["StudyInstanceUID"].iloc[0]
test_pseudonym = "Test\\Pseudonym"
additional_params = {
"pseudonym": test_pseudonym,
}
test_pseudonyms = [
"Test\\Pseudonym1", # Invalid due to backslash
"Test\u0001Pseudonym2", # Invalid due to control character
"Test*Pseudonym3", # Invalid due to wildcard character
"T" * 65, # Invalid due to exceeding character limit
]

for test_pseudonym in test_pseudonyms:
additional_params = {
"pseudonym": test_pseudonym,
}

try:
orthanc1_client.retrieve_study_metadata(study_uid, additional_params=additional_params)
except HTTPError as e:
response = e.response
assert response is not None
assert response.status_code == HTTPStatus.BAD_REQUEST
try:
error = response.json()
assert "pseudonym" in error or "invalid" in str(error).lower(), (
f"Unexpected error: {error}"
)
except Exception:
assert "invalid" in response.text.lower(), f"Unexpected response: {response.text}"
orthanc1_client.retrieve_study_metadata(study_uid, additional_params=additional_params)
except HTTPError as e:
response = e.response
assert response is not None
assert response.status_code == HTTPStatus.BAD_REQUEST
try:
error = response.json()
assert "pseudonym" in error or "invalid" in str(error).lower(), (
f"Unexpected error: {error}"
)
except Exception:
assert "invalid" in response.text.lower(), f"Unexpected response: {response.text}"


@pytest.mark.acceptance
Expand Down Expand Up @@ -266,24 +280,33 @@ def test_retrieve_series_with_invalid_pseudonym(channels_live_server: ChannelsLi
metadata = load_sample_dicoms_metadata("1001")
study_uid: str = metadata.iloc[0]["StudyInstanceUID"]
series_uid: str = metadata.iloc[0]["SeriesInstanceUID"]
test_pseudonym = "TestPseudonym"
additional_params = {
"pseudonym": test_pseudonym,
}
test_pseudonyms = [
"Test\\Pseudonym1", # Invalid due to backslash
"Test\u0001Pseudonym2", # Invalid due to control character
"Test*Pseudonym3", # Invalid due to wildcard character
"T" * 65, # Invalid due to exceeding character limit
]

for test_pseudonym in test_pseudonyms:
additional_params = {
"pseudonym": test_pseudonym,
}

try:
orthanc1_client.retrieve_series(study_uid, series_uid, additional_params=additional_params)
except HTTPError as e:
response = e.response
assert response is not None
assert response.status_code == HTTPStatus.BAD_REQUEST
try:
error = response.json()
assert "pseudonym" in error or "invalid" in str(error).lower(), (
f"Unexpected error: {error}"
orthanc1_client.retrieve_series(
study_uid, series_uid, additional_params=additional_params
)
except Exception:
assert "invalid" in response.text.lower(), f"Unexpected response: {response.text}"
except HTTPError as e:
response = e.response
assert response is not None
assert response.status_code == HTTPStatus.BAD_REQUEST
try:
error = response.json()
assert "pseudonym" in error or "invalid" in str(error).lower(), (
f"Unexpected error: {error}"
)
except Exception:
assert "invalid" in response.text.lower(), f"Unexpected response: {response.text}"


@pytest.mark.acceptance
Expand Down Expand Up @@ -358,26 +381,33 @@ def test_retrieve_series_metadata_with_invalid_pseudonym(
metadata = load_sample_dicoms_metadata("1001")
study_uid: str = metadata["StudyInstanceUID"].iloc[0]
series_uid: str = metadata["SeriesInstanceUID"].iloc[0]
test_pseudonym = "TestPseudonym"
additional_params = {
"pseudonym": test_pseudonym,
}
test_pseudonyms = [
"Test\\Pseudonym1", # Invalid due to backslash
"Test\u0001Pseudonym2", # Invalid due to control character
"Test*Pseudonym3", # Invalid due to wildcard character
"T" * 65, # Invalid due to exceeding character limit
]

for test_pseudonym in test_pseudonyms:
additional_params = {
"pseudonym": test_pseudonym,
}

try:
orthanc1_client.retrieve_series_metadata(
study_uid, series_uid, additional_params=additional_params
)
except HTTPError as e:
response = e.response
assert response is not None
assert response.status_code == HTTPStatus.BAD_REQUEST
try:
error = response.json()
assert "pseudonym" in error or "invalid" in str(error).lower(), (
f"Unexpected error: {error}"
orthanc1_client.retrieve_series_metadata(
study_uid, series_uid, additional_params=additional_params
)
except Exception:
assert "invalid" in response.text.lower(), f"Unexpected response: {response.text}"
except HTTPError as e:
response = e.response
assert response is not None
assert response.status_code == HTTPStatus.BAD_REQUEST
try:
error = response.json()
assert "pseudonym" in error or "invalid" in str(error).lower(), (
f"Unexpected error: {error}"
)
except Exception:
assert "invalid" in response.text.lower(), f"Unexpected response: {response.text}"


@pytest.mark.acceptance
Expand Down Expand Up @@ -449,26 +479,33 @@ def test_retrieve_image_with_invalid_pseudonym(channels_live_server: ChannelsLiv
study_uid: str = metadata["StudyInstanceUID"].iloc[0]
series_uid: str = metadata["SeriesInstanceUID"].iloc[0]
image_uid: str = metadata["SOPInstanceUID"].iloc[0]
test_pseudonym = "Test\\Pseudonym"
additional_params = {
"pseudonym": test_pseudonym,
}
test_pseudonyms = [
"Test\\Pseudonym1", # Invalid due to backslash
"Test\u0001Pseudonym2", # Invalid due to control character
"Test*Pseudonym3", # Invalid due to wildcard character
"T" * 65, # Invalid due to exceeding character limit
]

for test_pseudonym in test_pseudonyms:
additional_params = {
"pseudonym": test_pseudonym,
}

try:
orthanc1_client.retrieve_instance(
study_uid, series_uid, image_uid, additional_params=additional_params
)
except HTTPError as e:
response = e.response
assert response is not None
assert response.status_code == HTTPStatus.BAD_REQUEST
try:
error = response.json()
assert "pseudonym" in error or "invalid" in str(error).lower(), (
f"Unexpected error: {error}"
orthanc1_client.retrieve_instance(
study_uid, series_uid, image_uid, additional_params=additional_params
)
except Exception:
assert "invalid" in response.text.lower(), f"Unexpected response: {response.text}"
except HTTPError as e:
response = e.response
assert response is not None
assert response.status_code == HTTPStatus.BAD_REQUEST
try:
error = response.json()
assert "pseudonym" in error or "invalid" in str(error).lower(), (
f"Unexpected error: {error}"
)
except Exception:
assert "invalid" in response.text.lower(), f"Unexpected response: {response.text}"


@pytest.mark.acceptance
Expand Down Expand Up @@ -546,23 +583,30 @@ def test_retrieve_image_metadata_with_invalid_pseudonym(
study_uid: str = metadata["StudyInstanceUID"].iloc[0]
series_uid: str = metadata["SeriesInstanceUID"].iloc[0]
image_uid: str = metadata["SOPInstanceUID"].iloc[0]
test_pseudonym = "Test\\Pseudonym"
additional_params = {
"pseudonym": test_pseudonym,
}
test_pseudonyms = [
"Test\\Pseudonym1", # Invalid due to backslash
"Test\u0001Pseudonym2", # Invalid due to control character
"Test*Pseudonym3", # Invalid due to wildcard character
"T" * 65, # Invalid due to exceeding character limit
]

for test_pseudonym in test_pseudonyms:
additional_params = {
"pseudonym": test_pseudonym,
}

try:
orthanc1_client.retrieve_instance_metadata(
study_uid, series_uid, image_uid, additional_params=additional_params
)
except HTTPError as e:
response = e.response
assert response is not None
assert response.status_code == HTTPStatus.BAD_REQUEST
try:
error = response.json()
assert "pseudonym" in error or "invalid" in str(error).lower(), (
f"Unexpected error: {error}"
orthanc1_client.retrieve_instance_metadata(
study_uid, series_uid, image_uid, additional_params=additional_params
)
except Exception:
assert "invalid" in response.text.lower(), f"Unexpected response: {response.text}"
except HTTPError as e:
response = e.response
assert response is not None
assert response.status_code == HTTPStatus.BAD_REQUEST
try:
error = response.json()
assert "pseudonym" in error or "invalid" in str(error).lower(), (
f"Unexpected error: {error}"
)
except Exception:
assert "invalid" in response.text.lower(), f"Unexpected response: {response.text}"
2 changes: 2 additions & 0 deletions adit/dicom_web/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,5 +423,7 @@ def is_valid_pseudonym(pseudonym: str) -> None:
try:
validators.no_backslash_char_validator(pseudonym)
validators.no_control_chars_validator(pseudonym)
validators.no_wildcard_chars_validator(pseudonym)
validators.char_limit_validator(pseudonym)
except DjangoValidationError as e:
raise ValidationError({"pseudonym": e.messages})