PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
atna_audit_logger.h
Go to the documentation of this file.
1
16#ifndef PACS_SECURITY_ATNA_AUDIT_LOGGER_HPP
17#define PACS_SECURITY_ATNA_AUDIT_LOGGER_HPP
18
19#include <chrono>
20#include <cstdint>
21#include <string>
22#include <vector>
23
24namespace kcenon::pacs::security {
25
26// =============================================================================
27// RFC 3881 Coded Value
28// =============================================================================
29
37 std::string code;
38
40 std::string code_system_name;
41
43 std::string display_name;
44};
45
46// =============================================================================
47// Event Action Code (RFC 3881 Section 5.1)
48// =============================================================================
49
53enum class atna_event_action : char {
54 create = 'C',
55 read = 'R',
56 update = 'U',
57 delete_action = 'D',
58 execute = 'E'
59};
60
61// =============================================================================
62// Event Outcome Indicator (RFC 3881 Section 5.1)
63// =============================================================================
64
68enum class atna_event_outcome : uint8_t {
69 success = 0,
70 minor_failure = 4,
72 major_failure = 12
73};
74
75// =============================================================================
76// Network Access Point Type Code (RFC 3881 Section 5.2)
77// =============================================================================
78
82enum class atna_network_access_type : uint8_t {
83 machine_name = 1,
84 ip_address = 2,
85 phone_number = 3
86};
87
88// =============================================================================
89// Participant Object Type Code (RFC 3881 Section 5.5)
90// =============================================================================
91
95enum class atna_object_type : uint8_t {
96 person = 1,
97 system_object = 2,
98 organization = 3,
99 other = 4
100};
101
105enum class atna_object_role : uint8_t {
106 patient = 1,
107 location = 2,
108 report = 3,
109 resource = 4,
110 master_file = 5,
111 user = 6,
112 list = 7,
113 doctor = 8,
114 subscriber = 9,
115 guarantor = 10,
120 provider = 15,
121 data_destination = 16,
122 data_repository = 17,
123 schedule = 18,
124 customer = 19,
125 job = 20,
126 job_stream = 21,
127 table = 22,
128 routing_criteria = 23,
129 query = 24
130};
131
132// =============================================================================
133// Active Participant (RFC 3881 Section 5.2)
134// =============================================================================
135
143 std::string user_id;
144
147
149 std::string user_name;
150
152 bool user_is_requestor{false};
153
156
160
162 std::vector<atna_coded_value> role_id_codes;
163};
164
165// =============================================================================
166// Audit Source Identification (RFC 3881 Section 5.4)
167// =============================================================================
168
174 std::string audit_source_id;
175
178
180 std::vector<uint8_t> audit_source_type_codes;
181};
182
183// =============================================================================
184// Participant Object Detail (RFC 3881 Section 5.5)
185// =============================================================================
186
192 std::string type;
193
195 std::string value;
196};
197
198// =============================================================================
199// Participant Object Identification (RFC 3881 Section 5.5)
200// =============================================================================
201
227
228// =============================================================================
229// Audit Message (RFC 3881 Section 5)
230// =============================================================================
231
236 // -- Event Identification --
237
240
242 std::vector<atna_coded_value> event_type_codes;
243
246
248 std::chrono::system_clock::time_point event_date_time;
249
252
253 // -- Participants --
254
256 std::vector<atna_active_participant> active_participants;
257
260
262 std::vector<atna_participant_object> participant_objects;
263};
264
265// =============================================================================
266// Well-Known DCM Event IDs (DICOM PS3.15 A.5.3)
267// =============================================================================
268
269namespace atna_event_ids {
270
273 "110100", "DCM", "Application Activity"};
274
277 "110101", "DCM", "Audit Log Used"};
278
281 "110102", "DCM", "Begin Transferring DICOM Instances"};
282
285 "110103", "DCM", "DICOM Instances Accessed"};
286
289 "110104", "DCM", "DICOM Instances Transferred"};
290
293 "110105", "DCM", "DICOM Study Deleted"};
294
297 "110106", "DCM", "Export"};
298
301 "110107", "DCM", "Import"};
302
305 "110108", "DCM", "Network Entry"};
306
309 "110109", "DCM", "Order Record"};
310
312inline const atna_coded_value patient_record{
313 "110110", "DCM", "Patient Record"};
314
317 "110111", "DCM", "Procedure Record"};
318
321 "110112", "DCM", "Query"};
322
325 "110113", "DCM", "Security Alert"};
326
329 "110114", "DCM", "User Authentication"};
330
331} // namespace atna_event_ids
332
333// =============================================================================
334// Well-Known Event Type Codes
335// =============================================================================
336
337namespace atna_event_types {
338
341 "110120", "DCM", "Application Start"};
342
345 "110121", "DCM", "Application Stop"};
346
349 "110122", "DCM", "Login"};
350
353 "110123", "DCM", "Logout"};
354
355} // namespace atna_event_types
356
357// =============================================================================
358// Well-Known Role ID Codes
359// =============================================================================
360
361namespace atna_role_ids {
362
365 "110150", "DCM", "Application"};
366
369 "110151", "DCM", "Application Launcher"};
370
373 "110152", "DCM", "Destination Role ID"};
374
377 "110153", "DCM", "Source Role ID"};
378
381 "110154", "DCM", "Destination Media"};
382
385 "110155", "DCM", "Source Media"};
386
387} // namespace atna_role_ids
388
389// =============================================================================
390// Well-Known Participant Object ID Type Codes
391// =============================================================================
392
393namespace atna_object_id_types {
394
397 "2", "RFC-3881", "Patient Number"};
398
401 "110180", "DCM", "Study Instance UID"};
402
405 "110181", "DCM", "SOP Class UID"};
406
409 "110182", "DCM", "Node ID"};
410
411} // namespace atna_object_id_types
412
413// =============================================================================
414// ATNA Audit Logger
415// =============================================================================
416
424public:
425 // =========================================================================
426 // XML Generation
427 // =========================================================================
428
435 [[nodiscard]] static std::string to_xml(const atna_audit_message& message);
436
437 // =========================================================================
438 // Event Factory Methods
439 // =========================================================================
440
451 const std::string& source_id,
452 const std::string& app_name,
453 bool is_start,
455
468 const std::string& source_id,
469 const std::string& user_id,
470 const std::string& user_ip,
471 const std::string& study_uid,
472 const std::string& patient_id = "",
474
490 const std::string& source_id,
491 const std::string& source_ae,
492 const std::string& source_ip,
493 const std::string& dest_ae,
494 const std::string& dest_ip,
495 const std::string& study_uid,
496 const std::string& patient_id = "",
497 bool is_import = true,
499
511 [[nodiscard]] static atna_audit_message build_study_deleted(
512 const std::string& source_id,
513 const std::string& user_id,
514 const std::string& user_ip,
515 const std::string& study_uid,
516 const std::string& patient_id = "",
518
529 [[nodiscard]] static atna_audit_message build_security_alert(
530 const std::string& source_id,
531 const std::string& user_id,
532 const std::string& user_ip,
533 const std::string& alert_description,
535
547 const std::string& source_id,
548 const std::string& user_id,
549 const std::string& user_ip,
550 bool is_login,
552
564 [[nodiscard]] static atna_audit_message build_query(
565 const std::string& source_id,
566 const std::string& user_id,
567 const std::string& user_ip,
568 const std::string& query_data,
569 const std::string& patient_id = "",
571
584 [[nodiscard]] static atna_audit_message build_export(
585 const std::string& source_id,
586 const std::string& user_id,
587 const std::string& user_ip,
588 const std::string& dest_id,
589 const std::string& study_uid,
590 const std::string& patient_id = "",
592
593private:
594 // =========================================================================
595 // XML Helpers
596 // =========================================================================
597
598 [[nodiscard]] static std::string xml_escape(const std::string& str);
599
600 [[nodiscard]] static std::string format_datetime(
601 std::chrono::system_clock::time_point tp);
602
603 [[nodiscard]] static std::string format_coded_value_attrs(
604 const atna_coded_value& cv);
605};
606
607} // namespace kcenon::pacs::security
608
609#endif // PACS_SECURITY_ATNA_AUDIT_LOGGER_HPP
RFC 3881 XML audit message generator.
static atna_audit_message build_dicom_instances_transferred(const std::string &source_id, const std::string &source_ae, const std::string &source_ip, const std::string &dest_ae, const std::string &dest_ip, const std::string &study_uid, const std::string &patient_id="", bool is_import=true, atna_event_outcome outcome=atna_event_outcome::success)
Build DICOM Instances Transferred audit message (C-STORE, C-MOVE)
static std::string format_coded_value_attrs(const atna_coded_value &cv)
static std::string to_xml(const atna_audit_message &message)
Serialize an audit message to RFC 3881 XML.
static atna_audit_message build_study_deleted(const std::string &source_id, const std::string &user_id, const std::string &user_ip, const std::string &study_uid, const std::string &patient_id="", atna_event_outcome outcome=atna_event_outcome::success)
Build Study Deleted audit message.
static std::string xml_escape(const std::string &str)
static atna_audit_message build_application_activity(const std::string &source_id, const std::string &app_name, bool is_start, atna_event_outcome outcome=atna_event_outcome::success)
Build Application Activity audit message (start/stop)
static atna_audit_message build_export(const std::string &source_id, const std::string &user_id, const std::string &user_ip, const std::string &dest_id, const std::string &study_uid, const std::string &patient_id="", atna_event_outcome outcome=atna_event_outcome::success)
Build Export audit message (media/network export)
static std::string format_datetime(std::chrono::system_clock::time_point tp)
static atna_audit_message build_security_alert(const std::string &source_id, const std::string &user_id, const std::string &user_ip, const std::string &alert_description, atna_event_outcome outcome=atna_event_outcome::serious_failure)
Build Security Alert audit message.
static atna_audit_message build_user_authentication(const std::string &source_id, const std::string &user_id, const std::string &user_ip, bool is_login, atna_event_outcome outcome=atna_event_outcome::success)
Build User Authentication audit message (login/logout)
static atna_audit_message build_query(const std::string &source_id, const std::string &user_id, const std::string &user_ip, const std::string &query_data, const std::string &patient_id="", atna_event_outcome outcome=atna_event_outcome::success)
Build Query audit message (C-FIND, QIDO-RS)
static atna_audit_message build_dicom_instances_accessed(const std::string &source_id, const std::string &user_id, const std::string &user_ip, const std::string &study_uid, const std::string &patient_id="", atna_event_outcome outcome=atna_event_outcome::success)
Build DICOM Instances Accessed audit message (C-FIND, QIDO-RS)
const atna_coded_value dicom_instances_accessed
DICOM Instances Accessed (110103)
const atna_coded_value query
Query (110112)
const atna_coded_value begin_transferring
Begin Transferring DICOM Instances (110102)
const atna_coded_value user_authentication
User Authentication (110114)
const atna_coded_value data_import
Import (110107)
const atna_coded_value security_alert
Security Alert (110113)
const atna_coded_value network_entry
Network Entry (110108)
const atna_coded_value order_record
Order Record (110109)
const atna_coded_value procedure_record
Procedure Record (110111)
const atna_coded_value dicom_instances_transferred
DICOM Instances Transferred (110104)
const atna_coded_value audit_log_used
Audit Log Used (110101)
const atna_coded_value dicom_study_deleted
DICOM Study Deleted (110105)
const atna_coded_value data_export
Export (110106)
const atna_coded_value application_activity
Application Activity (110100) — Start/Stop.
const atna_coded_value application_start
Application Start.
const atna_coded_value application_stop
Application Stop.
const atna_coded_value sop_class_uid
SOP Class UID.
const atna_coded_value study_instance_uid
Study Instance UID.
const atna_coded_value patient_number
Patient Number (RFC 3881 defined)
const atna_coded_value application_launcher
Application Launcher (110151)
const atna_coded_value source_media
Source Media (110155)
const atna_coded_value application
Application (110150)
const atna_coded_value source
Source Role ID (110153)
const atna_coded_value destination
Destination Role ID (110152)
const atna_coded_value destination_media
Destination Media (110154)
atna_object_role
Role of the participant object in the event.
atna_object_type
Type of participant object.
atna_network_access_type
Type of network access point identifier.
atna_event_action
Action that triggered the audit event.
atna_event_outcome
Outcome of the audited event.
An active participant in the audit event.
std::string network_access_point_id
Network access point (hostname or IP)
std::string user_id
User or process identifier.
bool user_is_requestor
Whether this participant initiated the event.
std::vector< atna_coded_value > role_id_codes
Role(s) of this participant.
atna_network_access_type network_access_point_type
Type of network access point.
std::string alternative_user_id
Alternative user ID (e.g., process name)
std::string user_name
Human-readable user name.
atna_event_action event_action
Action that triggered the event.
std::vector< atna_participant_object > participant_objects
Participant objects (patients/studies/queries)
std::vector< atna_coded_value > event_type_codes
Event type codes for sub-classification.
atna_event_outcome event_outcome
Outcome of the event.
atna_coded_value event_id
Event ID coded value (e.g., DCM 110114 = UserAuthentication)
atna_audit_source audit_source
Audit source identification.
std::vector< atna_active_participant > active_participants
Active participants (users/processes)
std::chrono::system_clock::time_point event_date_time
When the event occurred.
Identifies the audit source system.
std::string audit_source_id
Unique identifier for the audit source.
std::vector< uint8_t > audit_source_type_codes
Audit source type codes (optional)
std::string audit_enterprise_site_id
Enterprise site identifier (optional)
A coded value with code, code system name, and display name.
std::string code
Code value (e.g., "110114")
std::string code_system_name
Code system name (e.g., "DCM" for DICOM)
std::string display_name
Human-readable display name (e.g., "UserAuthentication")
Additional detail about a participant object.
An object (patient, study, query) involved in the event.
std::string object_id
Object identifier (e.g., Patient ID, Study UID)
std::vector< atna_object_detail > object_details
Additional details.
std::string object_query
Query data (base64 encoded, for query events)
atna_object_role object_role
Role of the object in the event.
atna_coded_value object_id_type_code
Object ID type code.
std::string object_name
Human-readable object name.