changeset 6249:a8c0be03dae3

merged sql-opti -> default
author Alain Mazy <am@orthanc.team>
date Tue, 15 Jul 2025 17:00:16 +0200
parents d70e4de0c847 (current diff) afc746c090f6 (diff)
children 390a09b5b6bf
files
diffstat 16 files changed, 109 insertions(+), 203 deletions(-) [+]
line wrap: on
line diff
--- 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:
--- 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);
--- 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
-    }
   };
 
 
--- 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
-    }
-
   };
 
   
--- 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<uint32_t>::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;
--- 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<StorageCommitmentScp*>  StorageCommitmentScpCallbacks;
     typedef std::map<Property, std::string>  Properties;
     typedef std::list<WebDavCollection*>  WebDavCollections;
+    typedef std::list<OrthancPluginAuditLogHandler>  AuditLogHandlers;
 
     PluginsManager manager_;
 
@@ -1740,6 +1741,7 @@
     std::unique_ptr<StorageAreaFactory>  storageArea_;
     std::set<std::string> 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<const _OrthancPluginAuditLogHandler*>(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<ErrorCode>(error));
+      }
+    }
   }
 
   void OrthancPlugins::ApplyLoadDicomInstance(const _OrthancPluginLoadDicomInstance& params)
@@ -5910,10 +5929,11 @@
         return true;
       }
 
-      case _OrthancPluginService_RecordAuditLog:
-      {
-        const _OrthancPluginRecordAuditLog& p = *reinterpret_cast<const _OrthancPluginRecordAuditLog*>(parameters);
-        ApplyRecordAuditLog(p);
+      case _OrthancPluginService_AuditLog:
+      {
+        const _OrthancPluginAuditLog& p = *reinterpret_cast<const _OrthancPluginAuditLog*>(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:
--- 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);
--- 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().
  * -# <tt>void OrthancPluginFinalize()</tt>:
  *    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, &params);
   }
 
 
--- 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 {
--- 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;
-
     };
 
 
--- 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();
   }
 
--- 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<boost::shared_mutex> 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);
-  }
-
 }
--- 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);
   };
 }
--- 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);
   }
--- 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");
--- 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,