# HG changeset patch # User Sebastien Jodogne # Date 1671461193 -3600 # Node ID 8638522eeda14f6a8270f216518d703019f1121c # Parent 77e20ce39d6fc2ce95148dae4e808c2133854c75 revert changeset df4a90a65af9 that removes features used elsewhere, and protect by Force the change of UIDs diff -r 77e20ce39d6f -r 8638522eeda1 NEWS --- a/NEWS Mon Dec 19 15:09:38 2022 +0100 +++ b/NEWS Mon Dec 19 15:46:33 2022 +0100 @@ -14,7 +14,7 @@ REST API -------- -* Loosen the sanity checks for DICOM modifications: +* Loosen the sanity checks for DICOM modifications, if "Force" option is given: - allow modification of PatientID at study level - allow modification of PatientID, StudyInstanceUID at series level - allow modification of PatientID, StudyInstanceUID, SeriesInstanceUID at instance level @@ -29,12 +29,6 @@ * Tolerance for "image/jpg" MIME type instead of "image/jpeg" in /tools/create-dicom * /system: added MaximumStorageMode and MaximumStorageSize -OrthancFramework (C++) ----------------------- - -* DicomModification::SetAllowManualIdentifiers() has been removed since it was always true -> code cleanup. - - Common plugins code (C++) ------------------------- diff -r 77e20ce39d6f -r 8638522eeda1 OrthancFramework/Sources/DicomParsing/DicomModification.cpp --- a/OrthancFramework/Sources/DicomParsing/DicomModification.cpp Mon Dec 19 15:09:38 2022 +0100 +++ b/OrthancFramework/Sources/DicomParsing/DicomModification.cpp Mon Dec 19 15:46:33 2022 +0100 @@ -522,6 +522,7 @@ DicomModification::DicomModification() : removePrivateTags_(false), level_(ResourceType_Instance), + allowManualIdentifiers_(true), keepStudyInstanceUid_(false), keepSeriesInstanceUid_(false), keepSopInstanceUid_(false), @@ -921,6 +922,56 @@ } + // Sanity checks at the patient level + if (!allowManualIdentifiers_) + { + if (level_ == ResourceType_Patient && IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID)) + { + throw OrthancException(ErrorCode_BadRequest, + "When modifying a patient, the StudyInstanceUID cannot be manually modified"); + } + + if (level_ == ResourceType_Patient && IsReplaced(DICOM_TAG_SERIES_INSTANCE_UID)) + { + throw OrthancException(ErrorCode_BadRequest, + "When modifying a patient, the SeriesInstanceUID cannot be manually modified"); + } + + if (level_ == ResourceType_Patient && IsReplaced(DICOM_TAG_SOP_INSTANCE_UID)) + { + throw OrthancException(ErrorCode_BadRequest, + "When modifying a patient, the SopInstanceUID cannot be manually modified"); + } + } + + + // Sanity checks at the study level + if (!allowManualIdentifiers_) + { + if (level_ == ResourceType_Study && IsReplaced(DICOM_TAG_SERIES_INSTANCE_UID)) + { + throw OrthancException(ErrorCode_BadRequest, + "When modifying a study, the SeriesInstanceUID cannot be manually modified"); + } + + if (level_ == ResourceType_Study && IsReplaced(DICOM_TAG_SOP_INSTANCE_UID)) + { + throw OrthancException(ErrorCode_BadRequest, + "When modifying a study, the SopInstanceUID cannot be manually modified"); + } + } + + + // Sanity checks at the series level + if (!allowManualIdentifiers_) + { + if (level_ == ResourceType_Series && IsReplaced(DICOM_TAG_SOP_INSTANCE_UID)) + { + throw OrthancException(ErrorCode_BadRequest, + "When modifying a series, the SopInstanceUID cannot be manually modified"); + } + } + // (0) Create a summary of the source file, if a custom generator // is provided @@ -1061,6 +1112,17 @@ } } + void DicomModification::SetAllowManualIdentifiers(bool check) + { + allowManualIdentifiers_ = check; + } + + bool DicomModification::AreAllowManualIdentifiers() const + { + return allowManualIdentifiers_; + } + + static bool IsDatabaseKey(const DicomTag& tag) { return (tag == DICOM_TAG_PATIENT_ID || @@ -1213,6 +1275,62 @@ { privateCreator_ = SerializationToolbox::ReadString(request, "PrivateCreator"); } + + if (!force) + { + /** + * Sanity checks about the manual replacement of DICOM + * identifiers. Those checks were part of + * "DicomModification::Apply()" in Orthanc <= 1.11.2, and + * couldn't be disabled even if using the "Force" flag. Check + * out: + * https://groups.google.com/g/orthanc-users/c/xMUUZAnBa5g/m/WCEu-U2NBQAJ + **/ + bool isReplacedPatientId = (IsReplaced(DICOM_TAG_PATIENT_ID) || + uids_.find(DICOM_TAG_PATIENT_ID) != uids_.end()); + + if (level_ == ResourceType_Patient && !isReplacedPatientId) + { + throw OrthancException(ErrorCode_BadRequest, + "When modifying a patient, her PatientID is required to be modified."); + } + + if (level_ == ResourceType_Study && isReplacedPatientId) + { + throw OrthancException(ErrorCode_BadRequest, + "When modifying a study, the parent PatientID cannot be manually modified"); + } + + if (level_ == ResourceType_Series && isReplacedPatientId) + { + throw OrthancException(ErrorCode_BadRequest, + "When modifying a series, the parent PatientID cannot be manually modified"); + } + + if (level_ == ResourceType_Series && IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID)) + { + throw OrthancException(ErrorCode_BadRequest, + "When modifying a series, the parent StudyInstanceUID cannot be manually modified"); + } + + if (level_ == ResourceType_Instance && isReplacedPatientId) + { + throw OrthancException(ErrorCode_BadRequest, + "When modifying an instance, the parent PatientID cannot be manually modified"); + } + + if (level_ == ResourceType_Instance && IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID)) + { + throw OrthancException(ErrorCode_BadRequest, + "When modifying an instance, the parent StudyInstanceUID cannot be manually modified"); + } + + if (level_ == ResourceType_Instance && IsReplaced(DICOM_TAG_SERIES_INSTANCE_UID)) + { + throw OrthancException(ErrorCode_BadRequest, + "When modifying an instance, the parent SeriesInstanceUID cannot be manually modified"); + } + } } @@ -1282,6 +1400,7 @@ static const char* REMOVE_PRIVATE_TAGS = "RemovePrivateTags"; static const char* LEVEL = "Level"; + static const char* ALLOW_MANUAL_IDENTIFIERS = "AllowManualIdentifiers"; static const char* KEEP_STUDY_INSTANCE_UID = "KeepStudyInstanceUID"; static const char* KEEP_SERIES_INSTANCE_UID = "KeepSeriesInstanceUID"; static const char* KEEP_SOP_INSTANCE_UID = "KeepSOPInstanceUID"; @@ -1313,6 +1432,7 @@ value = Json::objectValue; value[REMOVE_PRIVATE_TAGS] = removePrivateTags_; value[LEVEL] = EnumerationToString(level_); + value[ALLOW_MANUAL_IDENTIFIERS] = allowManualIdentifiers_; value[KEEP_STUDY_INSTANCE_UID] = keepStudyInstanceUid_; value[KEEP_SERIES_INSTANCE_UID] = keepSeriesInstanceUid_; value[KEEP_SOP_INSTANCE_UID] = keepSopInstanceUid_; @@ -1457,6 +1577,7 @@ { removePrivateTags_ = SerializationToolbox::ReadBoolean(serialized, REMOVE_PRIVATE_TAGS); level_ = StringToResourceType(SerializationToolbox::ReadString(serialized, LEVEL).c_str()); + allowManualIdentifiers_ = SerializationToolbox::ReadBoolean(serialized, ALLOW_MANUAL_IDENTIFIERS); keepStudyInstanceUid_ = SerializationToolbox::ReadBoolean(serialized, KEEP_STUDY_INSTANCE_UID); keepSeriesInstanceUid_ = SerializationToolbox::ReadBoolean(serialized, KEEP_SERIES_INSTANCE_UID); updateReferencedRelationships_ = SerializationToolbox::ReadBoolean diff -r 77e20ce39d6f -r 8638522eeda1 OrthancFramework/Sources/DicomParsing/DicomModification.h --- a/OrthancFramework/Sources/DicomParsing/DicomModification.h Mon Dec 19 15:09:38 2022 +0100 +++ b/OrthancFramework/Sources/DicomParsing/DicomModification.h Mon Dec 19 15:46:33 2022 +0100 @@ -133,6 +133,7 @@ ResourceType level_; UidMap uidMap_; SetOfTags privateTagsToKeep_; + bool allowManualIdentifiers_; bool keepStudyInstanceUid_; bool keepSeriesInstanceUid_; bool keepSopInstanceUid_; @@ -223,6 +224,10 @@ void Apply(ParsedDicomFile& toModify); + void SetAllowManualIdentifiers(bool check); + + bool AreAllowManualIdentifiers() const; + void ParseModifyRequest(const Json::Value& request); // "patientNameOverridden" is set to "true" iff. the PatientName diff -r 77e20ce39d6f -r 8638522eeda1 OrthancServer/Sources/OrthancRestApi/OrthancRestAnonymizeModify.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestAnonymizeModify.cpp Mon Dec 19 15:09:38 2022 +0100 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestAnonymizeModify.cpp Mon Dec 19 15:46:33 2022 +0100 @@ -269,6 +269,7 @@ } DicomModification modification; + modification.SetAllowManualIdentifiers(true); Json::Value request; ParseModifyRequest(request, modification, call); @@ -313,6 +314,7 @@ } DicomModification modification; + modification.SetAllowManualIdentifiers(true); Json::Value request; ParseAnonymizationRequest(request, modification, call); diff -r 77e20ce39d6f -r 8638522eeda1 OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.cpp --- a/OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.cpp Mon Dec 19 15:09:38 2022 +0100 +++ b/OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.cpp Mon Dec 19 15:46:33 2022 +0100 @@ -43,6 +43,8 @@ throw OrthancException(ErrorCode_NullPointer); } + modification_->SetAllowManualIdentifiers(true); + if (modification_->IsReplaced(DICOM_TAG_PATIENT_ID)) { modification_->SetLevel(ResourceType_Patient);