# HG changeset patch # User Alain Mazy # Date 1752591616 -7200 # Node ID a8c0be03dae39508f0f5387f66c4093d5175b516 # Parent d70e4de0c84743d77e33220d2c736c21e3eda3c1# Parent afc746c090f6efd862fb5b509516fc8db203b055 merged sql-opti -> default diff -r d70e4de0c847 -r a8c0be03dae3 NEWS --- a/NEWS Mon Jul 14 16:10:24 2025 +0200 +++ b/NEWS Tue Jul 15 17:00:16 2025 +0200 @@ -32,8 +32,8 @@ DICOM resource from a plugin. - "OrthancPluginRegisterHttpAuthentication()" to install a custom callback to authenticate HTTP requests. - - "OrthancPluginRecordAuditLog()" to record an audit log in DB, provided - that the DB plugin supports it. + - "OrthancPluginAuditLog()" to generate an audit log. + - "OrthancPluginRegisterAuditLogHandler()" to handle audit logs. * The OrthancPluginHttpRequest structure provides the payload of the possible HTTP authentication callback. * OrthancPluginCallRestApi() now also returns the body of DELETE requests: diff -r d70e4de0c847 -r a8c0be03dae3 OrthancFramework/Sources/MultiThreading/SharedMessageQueue.h --- a/OrthancFramework/Sources/MultiThreading/SharedMessageQueue.h Mon Jul 14 16:10:24 2025 +0200 +++ b/OrthancFramework/Sources/MultiThreading/SharedMessageQueue.h Tue Jul 15 17:00:16 2025 +0200 @@ -52,7 +52,7 @@ // This transfers the ownership of the message void Enqueue(IDynamicObject* message); - // The caller is responsible to delete the dequeud message! + // The caller is responsible to delete the dequeued message! IDynamicObject* Dequeue(int32_t millisecondsTimeout); bool WaitEmpty(int32_t millisecondsTimeout); diff -r d70e4de0c847 -r a8c0be03dae3 OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp --- a/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp Mon Jul 14 16:10:24 2025 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp Tue Jul 15 17:00:16 2025 +0200 @@ -1511,16 +1511,6 @@ { throw OrthancException(ErrorCode_NotImplemented); // Not supported } - - virtual void RecordAuditLog(const std::string& userId, - ResourceType resourceType, - const std::string& resourceId, - const std::string& action, - const void* logData, - size_t logDataSize) ORTHANC_OVERRIDE - { - throw OrthancException(ErrorCode_NotImplemented); // Not supported - } }; diff -r d70e4de0c847 -r a8c0be03dae3 OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp --- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp Mon Jul 14 16:10:24 2025 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp Tue Jul 15 17:00:16 2025 +0200 @@ -1123,17 +1123,6 @@ { throw OrthancException(ErrorCode_NotImplemented); // Not supported } - - virtual void RecordAuditLog(const std::string& userId, - ResourceType resourceType, - const std::string& resourceId, - const std::string& action, - const void* logData, - size_t logDataSize) ORTHANC_OVERRIDE - { - throw OrthancException(ErrorCode_NotImplemented); // Not supported - } - }; diff -r d70e4de0c847 -r a8c0be03dae3 OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp --- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp Mon Jul 14 16:10:24 2025 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp Tue Jul 15 17:00:16 2025 +0200 @@ -2051,39 +2051,6 @@ throw OrthancException(ErrorCode_InternalError); } } - - virtual void RecordAuditLog(const std::string& userId, - ResourceType resourceType, - const std::string& resourceId, - const std::string& action, - const void* logData, - size_t logDataSize) ORTHANC_OVERRIDE - { - // In protobuf, bytes "may contain any arbitrary sequence of bytes no longer than 2^32" - // https://protobuf.dev/programming-guides/proto3/ - if (logDataSize > std::numeric_limits::max()) - { - throw OrthancException(ErrorCode_NotEnoughMemory); - } - - if (database_.GetDatabaseCapabilities().HasAuditLogsSupport()) - { - DatabasePluginMessages::TransactionRequest request; - request.mutable_record_audit_log()->set_user_id(userId); - request.mutable_record_audit_log()->set_resource_type(Convert(resourceType)); - request.mutable_record_audit_log()->set_resource_id(resourceId); - request.mutable_record_audit_log()->set_action(action); - request.mutable_record_audit_log()->set_log_data(logData, logDataSize); - - ExecuteTransaction(DatabasePluginMessages::OPERATION_ENQUEUE_VALUE, request); - } - else - { - // This method shouldn't have been called - throw OrthancException(ErrorCode_InternalError); - } - } - }; @@ -2177,7 +2144,6 @@ dbCapabilities_.SetKeyValueStoresSupport(systemInfo.supports_key_value_stores()); dbCapabilities_.SetQueuesSupport(systemInfo.supports_queues()); dbCapabilities_.SetAttachmentCustomDataSupport(systemInfo.has_attachment_custom_data()); - dbCapabilities_.SetAuditLogsSupport(systemInfo.supports_audit_logs()); } open_ = true; diff -r d70e4de0c847 -r a8c0be03dae3 OrthancServer/Plugins/Engine/OrthancPlugins.cpp --- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Mon Jul 14 16:10:24 2025 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Tue Jul 15 17:00:16 2025 +0200 @@ -1716,6 +1716,7 @@ typedef std::list StorageCommitmentScpCallbacks; typedef std::map Properties; typedef std::list WebDavCollections; + typedef std::list AuditLogHandlers; PluginsManager manager_; @@ -1740,6 +1741,7 @@ std::unique_ptr storageArea_; std::set authorizationTokens_; OrthancPluginHttpAuthentication httpAuthentication_; // New in Orthanc 1.12.9 + AuditLogHandlers auditLogHandlers_; // New in Orthanc 1.12.9 boost::recursive_mutex restCallbackInvokationMutex_; boost::shared_mutex restCallbackRegistrationMutex_; // New in Orthanc 1.9.0 @@ -1753,6 +1755,7 @@ boost::mutex storageCommitmentScpMutex_; boost::recursive_mutex invokeServiceMutex_; boost::shared_mutex incomingHttpRequestFilterMutex_; // New in Orthanc 1.8.2 + boost::recursive_mutex auditLogHandlersMutex_; // New in Orthanc 1.12.9 Properties properties_; int argc_; @@ -3129,6 +3132,18 @@ } + void OrthancPlugins::RegisterAuditLogHandler(const void* parameters) + { + boost::recursive_mutex::scoped_lock lock(pimpl_->auditLogHandlersMutex_); + + const _OrthancPluginAuditLogHandler& p = + *reinterpret_cast(parameters); + + CLOG(INFO, PLUGINS) << "Plugin has registered an AuditLog handler"; + pimpl_->auditLogHandlers_.push_back(p.handler); + } + + void OrthancPlugins::AnswerBuffer(const void* parameters) { const _OrthancPluginAnswerBuffer& p = @@ -4768,16 +4783,20 @@ } } - void OrthancPlugins::ApplyRecordAuditLog(const _OrthancPluginRecordAuditLog& parameters) + void OrthancPlugins::ApplyAuditLog(const _OrthancPluginAuditLog& parameters) { PImpl::ServerContextReference lock(*pimpl_); - if (!lock.GetContext().GetIndex().HasAuditLogsSupport()) - { - throw OrthancException(ErrorCode_NotImplemented, "The database engine does not support audit logs"); - } - - lock.GetContext().GetIndex().RecordAuditLog(parameters.userId, Plugins::Convert(parameters.resourceType), parameters.resourceId, parameters.action, parameters.logData, parameters.logDataSize); + for (PImpl::AuditLogHandlers::const_iterator handler = pimpl_->auditLogHandlers_.begin(); handler != pimpl_->auditLogHandlers_.end(); ++handler) + { + OrthancPluginErrorCode error = (*handler) (parameters.userId, parameters.resourceType, parameters.resourceId, parameters.action, parameters.logData, parameters.logDataSize); + + if (error != OrthancPluginErrorCode_Success) + { + GetErrorDictionary().LogError(error, true); + throw OrthancException(static_cast(error)); + } + } } void OrthancPlugins::ApplyLoadDicomInstance(const _OrthancPluginLoadDicomInstance& params) @@ -5910,10 +5929,11 @@ return true; } - case _OrthancPluginService_RecordAuditLog: - { - const _OrthancPluginRecordAuditLog& p = *reinterpret_cast(parameters); - ApplyRecordAuditLog(p); + case _OrthancPluginService_AuditLog: + { + const _OrthancPluginAuditLog& p = *reinterpret_cast(parameters); + + ApplyAuditLog(p); return true; } @@ -6002,6 +6022,10 @@ RegisterHttpAuthentication(parameters); return true; + case _OrthancPluginService_RegisterAuditLogHandler: + RegisterAuditLogHandler(parameters); + return true; + case _OrthancPluginService_RegisterStorageArea: case _OrthancPluginService_RegisterStorageArea2: case _OrthancPluginService_RegisterStorageArea3: diff -r d70e4de0c847 -r a8c0be03dae3 OrthancServer/Plugins/Engine/OrthancPlugins.h --- a/OrthancServer/Plugins/Engine/OrthancPlugins.h Mon Jul 14 16:10:24 2025 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPlugins.h Tue Jul 15 17:00:16 2025 +0200 @@ -141,6 +141,8 @@ void RegisterHttpAuthentication(const void* parameters); + void RegisterAuditLogHandler(const void* parameters); + void AnswerBuffer(const void* parameters); void Redirect(const void* parameters); @@ -249,7 +251,7 @@ void ApplySetStableStatus(const _OrthancPluginSetStableStatus& parameters); - void ApplyRecordAuditLog(const _OrthancPluginRecordAuditLog& parameters); + void ApplyAuditLog(const _OrthancPluginAuditLog& parameters); void ComputeHash(_OrthancPluginService service, const void* parameters); diff -r d70e4de0c847 -r a8c0be03dae3 OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h --- a/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Mon Jul 14 16:10:24 2025 +0200 +++ b/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Tue Jul 15 17:00:16 2025 +0200 @@ -32,6 +32,7 @@ * - Possibly register a callback to discard instances received through DICOM C-STORE using OrthancPluginRegisterIncomingCStoreInstanceFilter(). * - Possibly register a callback to branch a WebDAV virtual filesystem using OrthancPluginRegisterWebDavCollection(). * - Possibly register a callback to authenticate HTTP requests using OrthancPluginRegisterHttpAuthentication(). + * - Possibly register a callback to store audit logs using OrthancPluginRegisterAuditLogHandler(). * -# void OrthancPluginFinalize(): * This function is invoked by Orthanc during its shutdown. The plugin * must free all its memory. @@ -502,7 +503,7 @@ _OrthancPluginService_DequeueValue = 58, /* New in Orthanc 1.12.8 */ _OrthancPluginService_GetQueueSize = 59, /* New in Orthanc 1.12.8 */ _OrthancPluginService_SetStableStatus = 60, /* New in Orthanc 1.12.9 */ - _OrthancPluginService_RecordAuditLog = 61, /* New in Orthanc 1.12.9 */ + _OrthancPluginService_AuditLog = 61, /* New in Orthanc 1.12.9 */ /* Registration of callbacks */ _OrthancPluginService_RegisterRestCallback = 1000, @@ -527,6 +528,7 @@ _OrthancPluginService_RegisterWebDavCollection = 1019, /* New in Orthanc 1.10.1 */ _OrthancPluginService_RegisterStorageArea3 = 1020, /* New in Orthanc 1.12.8 */ _OrthancPluginService_RegisterHttpAuthentication = 1021, /* New in Orthanc 1.12.9 */ + _OrthancPluginService_RegisterAuditLogHandler = 1022, /* New in Orthanc 1.12.9 */ /* Sending answers to REST calls */ _OrthancPluginService_AnswerBuffer = 2000, @@ -10479,13 +10481,13 @@ const char* action; const void* logData; uint32_t logDataSize; - } _OrthancPluginRecordAuditLog; - - - /** - * @brief Record an audit log - * - * Record an audit log (provided that a database plugin provides the feature). + } _OrthancPluginAuditLog; + + + /** + * @brief Generate an audit log + * + * Generate an audit log that might be handled by plugins that have registered an handler. * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param userId A string uniquely identifying the user or entity that is executing the action on the resource. @@ -10495,8 +10497,8 @@ * @param logData A pointer to custom log data. * @param logDataSize The size of custom log data. **/ - ORTHANC_PLUGIN_INLINE void OrthancPluginRecordAuditLog( - OrthancPluginContext* context, + ORTHANC_PLUGIN_INLINE void OrthancPluginAuditLog( + OrthancPluginContext* context, const char* userId, OrthancPluginResourceType resourceType, const char* resourceId, @@ -10504,14 +10506,63 @@ const void* logData, uint32_t logDataSize) { - _OrthancPluginRecordAuditLog m; + _OrthancPluginAuditLog m; m.userId = userId; m.resourceType = resourceType; m.resourceId = resourceId; m.action = action; m.logData = logData; m.logDataSize = logDataSize; - context->InvokeService(context, _OrthancPluginService_RecordAuditLog, &m); + context->InvokeService(context, _OrthancPluginService_AuditLog, &m); + } + + + /** + * @brief Callback to handle an audit log. + * + * Signature of a callback function that handles an audit log. + * + * @param userId A string uniquely identifying the user or entity that is executing the action on the resource. + * @param resourceType The type of the resource this log relates to. + * @param resourceId The resource this log relates to. + * @param action The action that is performed on the resource. + * @param logData A pointer to custom log data. + * @param logDataSize The size of custom log data. + * @return 0 if success, other value if error. + * @ingroup Callbacks + **/ + typedef OrthancPluginErrorCode (*OrthancPluginAuditLogHandler) ( + const char* userId, + OrthancPluginResourceType resourceType, + const char* resourceId, + const char* action, + const void* logData, + uint32_t logDataSize); + + typedef struct + { + OrthancPluginAuditLogHandler handler; + } _OrthancPluginAuditLogHandler; + + /** + * @brief Register a callback to handle audit logs + * + * This function installs a callback that is executed for each + * audit logs that is generated by a plugin. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param handler The audit log handler. + * @return 0 if success, other value if error. + * @ingroup Callbacks + **/ + ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginRegisterAuditLogHandler( + OrthancPluginContext* context, + OrthancPluginAuditLogHandler handler) + { + _OrthancPluginAuditLogHandler params; + params.handler = handler; + + return context->InvokeService(context, _OrthancPluginService_RegisterAuditLogHandler, ¶ms); } diff -r d70e4de0c847 -r a8c0be03dae3 OrthancServer/Plugins/Include/orthanc/OrthancDatabasePlugin.proto --- a/OrthancServer/Plugins/Include/orthanc/OrthancDatabasePlugin.proto Mon Jul 14 16:10:24 2025 +0200 +++ b/OrthancServer/Plugins/Include/orthanc/OrthancDatabasePlugin.proto Tue Jul 15 17:00:16 2025 +0200 @@ -175,7 +175,6 @@ bool supports_key_value_stores = 10; // New in Orthanc 1.12.8 bool supports_queues = 11; // New in Orthanc 1.12.8 bool has_attachment_custom_data = 12; // New in Orthanc 1.12.8 - bool supports_audit_logs = 13; // New in Orthanc 1.12.9 } } @@ -340,7 +339,6 @@ OPERATION_GET_QUEUE_SIZE = 59; // New in Orthanc 1.12.8 OPERATION_GET_ATTACHMENT_CUSTOM_DATA = 60; // New in Orthanc 1.12.8 OPERATION_SET_ATTACHMENT_CUSTOM_DATA = 61; // New in Orthanc 1.12.8 - OPERATION_RECORD_AUDIT_LOG = 62; // New in Orthanc 1.12.9 } @@ -1097,19 +1095,6 @@ } } -message RecordAuditLog { - message Request { - string user_id = 1; - ResourceType resource_type = 2; - string resource_id = 3; - string action = 4; - bytes log_data = 5; - } - - message Response { - } -} - message TransactionRequest { sfixed64 transaction = 1; @@ -1177,7 +1162,6 @@ GetQueueSize.Request get_queue_size = 159; GetAttachmentCustomData.Request get_attachment_custom_data = 160; SetAttachmentCustomData.Request set_attachment_custom_data = 161; - RecordAuditLog.Request record_audit_log = 162; } message TransactionResponse { @@ -1243,7 +1227,6 @@ GetQueueSize.Response get_queue_size = 159; GetAttachmentCustomData.Response get_attachment_custom_data = 160; SetAttachmentCustomData.Response set_attachment_custom_data = 161; - RecordAuditLog.Response record_audit_log = 162; } enum RequestType { diff -r d70e4de0c847 -r a8c0be03dae3 OrthancServer/Sources/Database/IDatabaseWrapper.h --- a/OrthancServer/Sources/Database/IDatabaseWrapper.h Mon Jul 14 16:10:24 2025 +0200 +++ b/OrthancServer/Sources/Database/IDatabaseWrapper.h Tue Jul 15 17:00:16 2025 +0200 @@ -59,7 +59,6 @@ bool hasAttachmentCustomDataSupport_; bool hasKeyValueStoresSupport_; bool hasQueuesSupport_; - bool hasAuditLogsSupport_; public: Capabilities() : @@ -73,8 +72,7 @@ hasExtendedChanges_(false), hasAttachmentCustomDataSupport_(false), hasKeyValueStoresSupport_(false), - hasQueuesSupport_(false), - hasAuditLogsSupport_(false) + hasQueuesSupport_(false) { } @@ -188,16 +186,6 @@ return hasQueuesSupport_; } - void SetAuditLogsSupport(bool value) - { - hasAuditLogsSupport_ = value; - } - - bool HasAuditLogsSupport() const - { - return hasAuditLogsSupport_; - } - }; @@ -483,14 +471,6 @@ // New in Orthanc 1.12.8, for statistics only virtual uint64_t GetQueueSize(const std::string& queueId) = 0; - // New in Orthanc 1.12.9 - virtual void RecordAuditLog(const std::string& userId, - ResourceType resourceType, - const std::string& resourceId, - const std::string& action, - const void* logData, - size_t logDataSize) = 0; - }; diff -r d70e4de0c847 -r a8c0be03dae3 OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp --- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp Mon Jul 14 16:10:24 2025 +0200 +++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp Tue Jul 15 17:00:16 2025 +0200 @@ -2340,17 +2340,6 @@ s.Step(); return s.ColumnInt64(0); } - - virtual void RecordAuditLog(const std::string& userId, - ResourceType resourceType, - const std::string& resourceId, - const std::string& action, - const void* logData, - size_t logDataSize) ORTHANC_OVERRIDE - { - throw OrthancException(ErrorCode_NotImplemented); // Not supported - } - }; @@ -2598,7 +2587,6 @@ dbCapabilities_.SetKeyValueStoresSupport(true); dbCapabilities_.SetQueuesSupport(true); dbCapabilities_.SetAttachmentCustomDataSupport(true); - dbCapabilities_.SetAuditLogsSupport(false); db_.Open(path); } @@ -2616,7 +2604,6 @@ dbCapabilities_.SetKeyValueStoresSupport(true); dbCapabilities_.SetQueuesSupport(true); dbCapabilities_.SetAttachmentCustomDataSupport(true); - dbCapabilities_.SetAuditLogsSupport(false); db_.OpenInMemory(); } diff -r d70e4de0c847 -r a8c0be03dae3 OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp --- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp Mon Jul 14 16:10:24 2025 +0200 +++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp Tue Jul 15 17:00:16 2025 +0200 @@ -3226,12 +3226,6 @@ return db_.GetDatabaseCapabilities().HasQueuesSupport(); } - bool StatelessDatabaseOperations::HasAuditLogsSupport() - { - boost::shared_lock lock(mutex_); - return db_.GetDatabaseCapabilities().HasAuditLogsSupport(); - } - void StatelessDatabaseOperations::ExecuteCount(uint64_t& count, const FindRequest& request) { @@ -3761,48 +3755,4 @@ throw OrthancException(ErrorCode_BadSequenceOfCalls); } } - - void StatelessDatabaseOperations::RecordAuditLog(const std::string& userId, - ResourceType resourceType, - const std::string& resourceId, - const std::string& action, - const void* logData, - size_t logDataSize) - { - class Operations : public IReadWriteOperations - { - private: - const std::string& userId_; - ResourceType resourceType_; - const std::string& resourceId_; - const std::string& action_; - const void* logData_; - size_t logDataSize_; - - public: - Operations(const std::string& userId, - ResourceType resourceType, - const std::string& resourceId, - const std::string& action, - const void* logData, - size_t logDataSize) : - userId_(userId), - resourceType_(resourceType), - resourceId_(resourceId), - action_(action), - logData_(logData), - logDataSize_(logDataSize) - { - } - - virtual void Apply(ReadWriteTransaction& transaction) ORTHANC_OVERRIDE - { - transaction.RecordAuditLog(userId_, resourceType_, resourceId_, action_, logData_, logDataSize_); - } - }; - - Operations operations(userId, resourceType, resourceId, action, logData, logDataSize); - Apply(operations); - } - } diff -r d70e4de0c847 -r a8c0be03dae3 OrthancServer/Sources/Database/StatelessDatabaseOperations.h --- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.h Mon Jul 14 16:10:24 2025 +0200 +++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.h Tue Jul 15 17:00:16 2025 +0200 @@ -492,16 +492,6 @@ return transaction_.SetAttachmentCustomData(attachmentUuid, customData, customDataSize); } - void RecordAuditLog(const std::string& userId, - ResourceType resourceType, - const std::string& resourceId, - const std::string& action, - const void* logData, - size_t logDataSize) - { - return transaction_.RecordAuditLog(userId, resourceType, resourceId, action, logData, logDataSize); - } - }; @@ -632,8 +622,6 @@ bool HasQueuesSupport(); - bool HasAuditLogsSupport(); - void GetExportedResources(Json::Value& target, int64_t since, uint32_t limit); @@ -893,11 +881,5 @@ const std::string& GetValue() const; }; - void RecordAuditLog(const std::string& userId, - ResourceType resourceType, - const std::string& resourceId, - const std::string& action, - const void* logData, - size_t logDataSize); }; } diff -r d70e4de0c847 -r a8c0be03dae3 OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp Mon Jul 14 16:10:24 2025 +0200 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp Tue Jul 15 17:00:16 2025 +0200 @@ -97,7 +97,6 @@ static const char* const HAS_EXTENDED_CHANGES = "HasExtendedChanges"; static const char* const HAS_KEY_VALUE_STORES = "HasKeyValueStores"; static const char* const HAS_QUEUES = "HasQueues"; - static const char* const HAS_AUDITS_LOGS = "HasAuditLogs"; static const char* const HAS_EXTENDED_FIND = "HasExtendedFind"; static const char* const READ_ONLY = "ReadOnly"; @@ -216,7 +215,6 @@ result[CAPABILITIES][HAS_EXTENDED_FIND] = OrthancRestApi::GetIndex(call).HasFindSupport(); result[CAPABILITIES][HAS_KEY_VALUE_STORES] = OrthancRestApi::GetIndex(call).HasKeyValueStoresSupport(); result[CAPABILITIES][HAS_QUEUES] = OrthancRestApi::GetIndex(call).HasQueuesSupport(); - result[CAPABILITIES][HAS_AUDITS_LOGS] = OrthancRestApi::GetIndex(call).HasAuditLogsSupport(); call.GetOutput().AnswerJson(result); } diff -r d70e4de0c847 -r a8c0be03dae3 OrthancServer/Sources/ServerEnumerations.cpp --- a/OrthancServer/Sources/ServerEnumerations.cpp Mon Jul 14 16:10:24 2025 +0200 +++ b/OrthancServer/Sources/ServerEnumerations.cpp Tue Jul 15 17:00:16 2025 +0200 @@ -64,6 +64,8 @@ dictMetadataType_.Add(MetadataType_MainDicomTagsSignature, "MainDicomTagsSignature"); dictMetadataType_.Add(MetadataType_MainDicomSequences, "MainDicomSequences"); dictMetadataType_.Add(MetadataType_Instance_PixelDataVR, "PixelDataVR"); + dictMetadataType_.Add(MetadataType_Patient_IsProtected, "IsProtected"); + dictMetadataType_.Add(MetadataType_Patient_PatientRecyclingOrder, "PatientRecyclingOrder"); dictContentType_.Add(FileContentType_Dicom, "dicom"); dictContentType_.Add(FileContentType_DicomAsJson, "dicom-as-json"); diff -r d70e4de0c847 -r a8c0be03dae3 OrthancServer/Sources/ServerEnumerations.h --- a/OrthancServer/Sources/ServerEnumerations.h Mon Jul 14 16:10:24 2025 +0200 +++ b/OrthancServer/Sources/ServerEnumerations.h Tue Jul 15 17:00:16 2025 +0200 @@ -210,6 +210,8 @@ MetadataType_MainDicomTagsSignature = 15, // New in Orthanc 1.11.0 MetadataType_MainDicomSequences = 16, // New in Orthanc 1.11.1 MetadataType_Instance_PixelDataVR = 17, // New in Orthanc 1.12.1 + MetadataType_Patient_IsProtected = 18, // New in Orthanc 1.12.99 (used only by DB plugins) + MetadataType_Patient_PatientRecyclingOrder = 19, // New in Orthanc 1.12.99 (used only by DB plugins) // Make sure that the value "65535" can be stored into this enumeration MetadataType_StartUser = 1024,