From bab9d28feb5a5a93bd852fbafd2591b58e62e3b9 Mon Sep 17 00:00:00 2001 From: Vrinda Date: Mon, 16 Sep 2024 17:27:04 +0200 Subject: [PATCH] Fix #4563 : Normalize validation checks for Update Study/Series/Instance REST APIs --- .../org/dcm4chee/arc/iocm/rs/StudyMgtRS.java | 69 ++++++++++++------- docs/swagger/paths/wado.json | 6 +- 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/dcm4chee-arc-iocm-rs/src/main/java/org/dcm4chee/arc/iocm/rs/StudyMgtRS.java b/dcm4chee-arc-iocm-rs/src/main/java/org/dcm4chee/arc/iocm/rs/StudyMgtRS.java index f27eb66137..c1cec8deac 100644 --- a/dcm4chee-arc-iocm-rs/src/main/java/org/dcm4chee/arc/iocm/rs/StudyMgtRS.java +++ b/dcm4chee-arc-iocm-rs/src/main/java/org/dcm4chee/arc/iocm/rs/StudyMgtRS.java @@ -84,6 +84,7 @@ import java.io.*; import java.nio.charset.StandardCharsets; +import java.text.MessageFormat; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; @@ -100,6 +101,9 @@ public class StudyMgtRS { private static final Logger LOG = LoggerFactory.getLogger(StudyMgtRS.class); private static final String SUPER_USER_ROLE = "super-user-role"; + private static final String UPDATE_STUDY_CONFLICTING_UIDS_MSG = "[StudyUID={}] in request URL does not match [StudyUID={}] in request payload"; + private static final String UPDATE_SERIES_CONFLICTING_UIDS_MSG = "[StudyUID={}, SeriesUID={}] in request URL do not match [StudyUID={}, SeriesUID={}] in request payload"; + private static final String UPDATE_INSTANCE_CONFLICTING_UIDS_MSG = "[StudyUID={}, SeriesUID={}, SOPUID={}] in request URL do not match [StudyUID={}, SeriesUID={}, SOPUID={}] in request payload"; @Inject private Device device; @@ -192,16 +196,21 @@ public Response updateStudy( validateWebAppServiceClass(); final Attributes attrs = toAttributes(in); - Collection patientIDs = IDWithIssuer.pidsOf(attrs); - if (patientIDs.isEmpty() || !attrs.containsValue(Tag.StudyInstanceUID) - || !studyUID.equals(attrs.getString(Tag.StudyInstanceUID))) - return errResponse("Missing Patient ID or Study Instance UID in request payload or Study UID in request does not match Study UID in request payload", - Response.Status.BAD_REQUEST); + Set patientIDs = IDWithIssuer.pidsOf(attrs); + Collection trustedPatientIDs = arcAE.getArchiveDeviceExtension().retainTrustedPatientIDs(patientIDs); + if (trustedPatientIDs.isEmpty()) + return errResponse("Missing patient identifiers with trusted assigning authority in " + patientIDs, + Response.Status.BAD_REQUEST); + + if (!studyUID.equals(attrs.getString(Tag.StudyInstanceUID))) + return errResponse(MessageFormat.format(UPDATE_STUDY_CONFLICTING_UIDS_MSG, studyUID, attrs.getString(Tag.StudyInstanceUID)), + Response.Status.BAD_REQUEST); try { - Patient patient = patientService.findPatient(patientIDs); + Patient patient = patientService.findPatient(trustedPatientIDs); if (patient == null) - return errResponse("Patient[id=" + patientIDs + "] does not exist.", Response.Status.NOT_FOUND); + return errResponse("Patient with patient identifiers " + trustedPatientIDs + " not found.", + Response.Status.NOT_FOUND); StudyMgtContext ctx = studyService.createStudyMgtContextWEB( HttpServletRequestInfo.valueOf(request), arcAE.getApplicationEntity()); @@ -247,19 +256,25 @@ public Response updateSeries( validateWebAppServiceClass(); final Attributes attrs = toAttributes(in); - Collection patientIDs = IDWithIssuer.pidsOf(attrs); - if (patientIDs.isEmpty() || !attrs.containsValue(Tag.SeriesInstanceUID)) - return errResponse("Missing patient identifier or Series Instance UID in request payload", - Response.Status.BAD_REQUEST); + Set patientIDs = IDWithIssuer.pidsOf(attrs); + Collection trustedPatientIDs = arcAE.getArchiveDeviceExtension().retainTrustedPatientIDs(patientIDs); + if (trustedPatientIDs.isEmpty()) + return errResponse("Missing patient identifiers with trusted assigning authority in " + patientIDs, + Response.Status.BAD_REQUEST); - if (!seriesUID.equals(attrs.getString(Tag.SeriesInstanceUID))) - return errResponse("Series UID in request does not match Series UID in request payload", - Response.Status.BAD_REQUEST); + if (!seriesUID.equals(attrs.getString(Tag.SeriesInstanceUID)) + || !studyUID.equals(attrs.getString(Tag.StudyInstanceUID))) + return errResponse(MessageFormat.format(UPDATE_SERIES_CONFLICTING_UIDS_MSG, + studyUID, seriesUID, + attrs.getString(Tag.StudyInstanceUID), + attrs.getString(Tag.SeriesInstanceUID)), + Response.Status.BAD_REQUEST); try { - Patient patient = patientService.findPatient(patientIDs); + Patient patient = patientService.findPatient(trustedPatientIDs); if (patient == null) - return errResponse("Patient[id=" + patientIDs + "] does not exist.", Response.Status.NOT_FOUND); + return errResponse("Patient with patient identifiers " + trustedPatientIDs + " not found.", + Response.Status.NOT_FOUND); StudyMgtContext ctx = studyService.createStudyMgtContextWEB( HttpServletRequestInfo.valueOf(request), arcAE.getApplicationEntity()); @@ -308,19 +323,27 @@ public Response updateInstance( validateWebAppServiceClass(); final Attributes attrs = toAttributes(in); - Collection patientIDs = IDWithIssuer.pidsOf(attrs); - if (patientIDs.isEmpty() || !attrs.containsValue(Tag.SOPInstanceUID)) - return errResponse("Missing patient identifier or SOP Instance UID in request payload", + Set patientIDs = IDWithIssuer.pidsOf(attrs); + Collection trustedPatientIDs = arcAE.getArchiveDeviceExtension().retainTrustedPatientIDs(patientIDs); + if (trustedPatientIDs.isEmpty()) + return errResponse("Missing patient identifiers with trusted assigning authority in " + patientIDs, Response.Status.BAD_REQUEST); - if (!sopUID.equals(attrs.getString(Tag.SOPInstanceUID))) - return errResponse("SOP Instance UID in request does not match SOP Instance UID in request payload", + if (!sopUID.equals(attrs.getString(Tag.SOPInstanceUID)) + || !seriesUID.equals(attrs.getString(Tag.SeriesInstanceUID)) + || !studyUID.equals(attrs.getString(Tag.StudyInstanceUID))) + return errResponse(MessageFormat.format(UPDATE_INSTANCE_CONFLICTING_UIDS_MSG, + studyUID, seriesUID, sopUID, + attrs.getString(Tag.StudyInstanceUID), + attrs.getString(Tag.SeriesInstanceUID), + attrs.getString(Tag.SOPInstanceUID)), Response.Status.BAD_REQUEST); try { - Patient patient = patientService.findPatient(patientIDs); + Patient patient = patientService.findPatient(trustedPatientIDs); if (patient == null) - return errResponse("Patient[id=" + patientIDs + "] does not exist.", Response.Status.NOT_FOUND); + return errResponse("Patient with patient identifiers " + trustedPatientIDs + " not found.", + Response.Status.NOT_FOUND); restoreInstances(studyUID, seriesUID, arcAE); StudyMgtContext ctx = studyService.createStudyMgtContextWEB( diff --git a/docs/swagger/paths/wado.json b/docs/swagger/paths/wado.json index 0dea19c325..3698bbde68 100644 --- a/docs/swagger/paths/wado.json +++ b/docs/swagger/paths/wado.json @@ -120,7 +120,7 @@ } }, "400": { - "description": "JSON request body not well formed or Missing Patient ID or Study Instance UID in request payload or Study UID in request does not match Study UID in request payload or Patient found using patient identifiers sent in request payload does not match with patient of study" + "description": "JSON request body not well formed or Missing patient identifiers with trusted assigning authority in patient identifiers in request payload or Study UID in request URL does not match Study UID in request payload or Patient found using identifiers in request payload does not match with patient associated with study" }, "403": { "description": "Update study forbidden for already merged patients" @@ -314,7 +314,7 @@ } }, "400": { - "description": "JSON request body not well formed or Missing Patient ID or Series Instance UID in request body or Series UID in request does not match Series UID in request payload or Patient found using patient identifiers sent in request payload does not match with patient of series" + "description": "JSON request body not well formed or Missing patient identifiers with trusted assigning authority in patient identifiers in request payload or Study / Series UIDs in request URL does not match Study / Series UIDs in request payload or Patient found using identifiers in request payload does not match with patient associated with series of study" }, "403": { "description": "Update series forbidden for already merged patients" @@ -488,7 +488,7 @@ } }, "400": { - "description": "JSON request body not well formed or Missing Patient ID or SOP IUID in request body or SOP IUID in request does not match SOP IUID in request payload or Patient found using patient identifiers sent in request payload does not match with patient of instance" + "description": "JSON request body not well formed or Missing patient identifiers with trusted assigning authority in patient identifiers in request payload or Study / Series / SOP UIDs in request URL does not match Study / Series / SOP UIDs in request payload or Patient found using identifiers in request payload does not match with patient associated with instance of series of study" }, "403": { "description": "Update instance forbidden for already merged patients"