Skip to content

Commit fa1e929

Browse files
committed
72 add uuid tags to all messages for tracing
1 parent 7f6bd87 commit fa1e929

File tree

3 files changed

+37
-20
lines changed

3 files changed

+37
-20
lines changed

lib/phi_attrs.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require 'rails'
44
require 'active_support'
55
require 'request_store'
6+
require 'securerandom'
67

78
require 'phi_attrs/version'
89
require 'phi_attrs/configure'

lib/phi_attrs/phi_record.rb

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,15 @@ def allow_phi!(user_id = nil, reason = nil)
7777
reason ||= i18n_reason
7878
raise ArgumentError, 'user_id and reason cannot be blank' if user_id.blank? || reason.blank?
7979

80+
uuid = SecureRandom.uuid
8081
__phi_stack.push({
81-
phi_access_allowed: true,
82-
user_id: user_id,
83-
reason: reason
82+
phi_access_allowed: true,
83+
user_id: user_id,
84+
reason: reason,
85+
uuid: uuid
8486
})
8587

86-
PhiAttrs::Logger.tagged(PHI_ACCESS_LOG_TAG, name) do
88+
PhiAttrs::Logger.tagged(PHI_ACCESS_LOG_TAG, name, uuid) do
8789
PhiAttrs::Logger.info("PHI Access Enabled for '#{user_id}': #{reason}")
8890
end
8991
end
@@ -210,11 +212,12 @@ def disallow_phi
210212
def disallow_phi!
211213
raise ArgumentError, 'block not allowed. use disallow_phi with block' if block_given?
212214

215+
uuid = __uuid_string(__phi_stack)
213216
message = __phi_stack.present? ? "PHI access disabled for #{__user_id_string(__phi_stack)}" : 'PHI access disabled. No class level access was granted.'
214217

215218
__reset_phi_stack
216219

217-
PhiAttrs::Logger.tagged(PHI_ACCESS_LOG_TAG, name) do
220+
PhiAttrs::Logger.tagged(PHI_ACCESS_LOG_TAG, name, uuid) do
218221
PhiAttrs::Logger.info(message)
219222
end
220223
end
@@ -228,9 +231,10 @@ def disallow_last_phi!
228231
raise ArgumentError, 'block not allowed' if block_given?
229232

230233
removed_access = __phi_stack.pop
234+
uuid = __uuid_string(removed_access)
231235
message = removed_access.present? ? "PHI access disabled for #{removed_access[:user_id]}" : 'PHI access disabled. No class level access was granted.'
232236

233-
PhiAttrs::Logger.tagged(PHI_ACCESS_LOG_TAG, name) do
237+
PhiAttrs::Logger.tagged(PHI_ACCESS_LOG_TAG, name, uuid) do
234238
PhiAttrs::Logger.info(message)
235239
end
236240
end
@@ -265,6 +269,11 @@ def __user_id_string(access_list)
265269
access_list.map { |c| "'#{c[:user_id]}'" }.join(',')
266270
end
267271

272+
def __uuid_string(access_list)
273+
access_list ||= []
274+
Array.wrap(access_list).map { |c| c[:uuid] }.join(',').presence || 'none'
275+
end
276+
268277
def current_user
269278
RequestStore.store[:phi_attrs_current_user]
270279
end
@@ -335,13 +344,15 @@ def allow_phi!(user_id = nil, reason = nil)
335344
reason ||= self.class.i18n_reason
336345
raise ArgumentError, 'user_id and reason cannot be blank' if user_id.blank? || reason.blank?
337346

338-
PhiAttrs::Logger.tagged(*phi_log_keys) do
339-
@__phi_access_stack.push({
340-
phi_access_allowed: true,
341-
user_id: user_id,
342-
reason: reason
343-
})
347+
uuid = SecureRandom.uuid
348+
@__phi_access_stack.push({
349+
phi_access_allowed: true,
350+
user_id: user_id,
351+
reason: reason,
352+
uuid: uuid,
353+
})
344354

355+
PhiAttrs::Logger.tagged(*phi_log_keys, uuid) do
345356
PhiAttrs::Logger.info("PHI Access Enabled for '#{user_id}': #{reason}")
346357
end
347358
end
@@ -405,7 +416,9 @@ def get_phi(user_id = nil, reason = nil)
405416
def disallow_phi!
406417
raise ArgumentError, 'block not allowed. use disallow_phi with block' if block_given?
407418

408-
PhiAttrs::Logger.tagged(*phi_log_keys) do
419+
removed_access_for_uuid = self.class.__uuid_string(@__phi_access_stack)
420+
421+
PhiAttrs::Logger.tagged(*phi_log_keys, removed_access_for_uuid) do
409422
removed_access_for = self.class.__user_id_string(@__phi_access_stack)
410423

411424
revoke_extended_phi!
@@ -451,8 +464,10 @@ def disallow_phi
451464
def disallow_last_phi!(preserve_extensions: false)
452465
raise ArgumentError, 'block not allowed' if block_given?
453466

454-
PhiAttrs::Logger.tagged(*phi_log_keys) do
455-
removed_access = @__phi_access_stack.pop
467+
removed_access = @__phi_access_stack.pop
468+
uuid = removed_access.present? ? removed_access[:uuid] : nil
469+
470+
PhiAttrs::Logger.tagged(*phi_log_keys, uuid) do
456471

457472
revoke_extended_phi! unless preserve_extensions
458473
message = removed_access.present? ? "PHI access disabled for #{removed_access[:user_id]}" : 'PHI access disabled. No instance level access was granted.'
@@ -634,7 +649,8 @@ def phi_wrap_method(method_name)
634649
unwrapped_method = :"__#{method_name}_phi_unwrapped"
635650

636651
self.class.send(:define_method, wrapped_method) do |*args, **kwargs, &block|
637-
PhiAttrs::Logger.tagged(*phi_log_keys) do
652+
uuid = self.class.__uuid_string(@__phi_access_stack)
653+
PhiAttrs::Logger.tagged(*phi_log_keys, uuid) do
638654
unless phi_allowed?
639655
raise PhiAttrs::Exceptions::PhiAccessException, "Attempted PHI access for #{self.class.name} #{@__phi_user_id}"
640656
end

spec/phi_attrs/logger_spec.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
context 'allowed' do
6969
it 'object_id for unpersisted' do |t|
7070
PatientInfo.allow_phi!(file_name, t.full_description)
71-
expect(PhiAttrs::Logger.logger).to receive(:tagged).with(PhiAttrs::PHI_ACCESS_LOG_TAG, PatientInfo.name, "Object: #{patient_jane.object_id}").and_call_original
71+
expect(PhiAttrs::Logger.logger).to receive(:tagged).with(PhiAttrs::PHI_ACCESS_LOG_TAG, PatientInfo.name, "Object: #{patient_jane.object_id}", 'none').and_call_original
7272
expect(PhiAttrs::Logger.logger).to receive(:info)
7373
patient_jane.first_name
7474
end
@@ -77,15 +77,15 @@
7777
PatientInfo.allow_phi!(file_name, t.full_description)
7878
patient_jane.save
7979
expect(patient_jane.persisted?).to be true
80-
expect(PhiAttrs::Logger.logger).to receive(:tagged).with(PhiAttrs::PHI_ACCESS_LOG_TAG, PatientInfo.name, "Key: #{patient_jane.id}").and_call_original
80+
expect(PhiAttrs::Logger.logger).to receive(:tagged).with(PhiAttrs::PHI_ACCESS_LOG_TAG, PatientInfo.name, "Key: #{patient_jane.id}", 'none').and_call_original
8181
expect(PhiAttrs::Logger.logger).to receive(:info)
8282
patient_jane.first_name
8383
end
8484
end
8585

8686
context 'unauthorized' do
8787
it 'object_id for unpersisted' do
88-
expect(PhiAttrs::Logger.logger).to receive(:tagged).with(PhiAttrs::PHI_ACCESS_LOG_TAG, PatientInfo.name, "Object: #{patient_jane.object_id}").and_call_original
88+
expect(PhiAttrs::Logger.logger).to receive(:tagged).with(PhiAttrs::PHI_ACCESS_LOG_TAG, PatientInfo.name, "Object: #{patient_jane.object_id}", 'none').and_call_original
8989
expect(PhiAttrs::Logger.logger).to receive(:tagged).with(PhiAttrs::Exceptions::PhiAccessException::TAG).and_call_original
9090
expect(PhiAttrs::Logger.logger).to receive(:error)
9191
expect { patient_jane.first_name }.to raise_error(access_error)
@@ -94,7 +94,7 @@
9494
it 'id for persisted' do
9595
patient_jane.save
9696
# expect(patient_jane.persisted?).to be true
97-
expect(PhiAttrs::Logger.logger).to receive(:tagged).with(PhiAttrs::PHI_ACCESS_LOG_TAG, PatientInfo.name, "Key: #{patient_jane.id}").and_call_original
97+
expect(PhiAttrs::Logger.logger).to receive(:tagged).with(PhiAttrs::PHI_ACCESS_LOG_TAG, PatientInfo.name, "Key: #{patient_jane.id}", 'none').and_call_original
9898
expect(PhiAttrs::Logger.logger).to receive(:tagged).with(PhiAttrs::Exceptions::PhiAccessException::TAG).and_call_original
9999
expect(PhiAttrs::Logger.logger).to receive(:error)
100100
expect { patient_jane.first_name }.to raise_error(access_error)

0 commit comments

Comments
 (0)