Module: PhiAttrs::PhiRecord
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/phi_attrs/phi_record.rb
Overview
Module for extending ActiveRecord models to handle PHI access logging and restrict access to attributes.
Instance Method Summary collapse
-
#__phi_extended_methods ⇒ Array<String>
Get all method names to be wrapped with PHI access extension.
-
#__phi_wrapped_methods ⇒ Array<String>
Get all method names to be wrapped with PHI access logging.
-
#allow_phi(user_id = nil, reason = nil) { ... } ⇒ Object
Enable PHI access for a single instance of this class inside the block.
-
#allow_phi!(user_id = nil, reason = nil) ⇒ Object
Enable PHI access for a single instance of this class.
-
#disallow_last_phi!(preserve_extensions: false) ⇒ Object
Revoke last PHI access for a single instance of this class.
-
#disallow_phi { ... } ⇒ Object
Dissables PHI access for a single instance of this class inside the block.
-
#disallow_phi! ⇒ Object
Revoke all PHI access for a single instance of this class.
-
#get_phi(user_id = nil, reason = nil) { ... } ⇒ Object
Enable PHI access for a single instance of this class inside the block.
-
#phi_access_reason ⇒ String
The access reason for allowing access to this instance.
-
#phi_allowed? ⇒ Boolean
Whether PHI access is allowed for a single instance of this class.
-
#phi_allowed_by ⇒ String
The unique identifier for whom access has been allowed on this instance.
- #reload ⇒ Object
-
#require_phi! ⇒ Object
Require phi access.
Instance Method Details
#__phi_extended_methods ⇒ Array<String>
Get all method names to be wrapped with PHI access extension
330 331 332 |
# File 'lib/phi_attrs/phi_record.rb', line 330 def __phi_extended_methods self.class.__phi_extend_methods.to_a end |
#__phi_wrapped_methods ⇒ Array<String>
Get all method names to be wrapped with PHI access logging
319 320 321 322 323 324 |
# File 'lib/phi_attrs/phi_record.rb', line 319 def __phi_wrapped_methods excluded_methods = self.class.__phi_exclude_methods.to_a included_methods = self.class.__phi_include_methods.to_a attribute_names - excluded_methods + included_methods - [self.class.primary_key] end |
#allow_phi(user_id = nil, reason = nil) { ... } ⇒ Object
Enable PHI access for a single instance of this class inside the block. Nested calls to allow_phi will log once per nested call
379 380 381 382 |
# File 'lib/phi_attrs/phi_record.rb', line 379 def allow_phi(user_id = nil, reason = nil, &block) get_phi(user_id, reason, &block) nil end |
#allow_phi!(user_id = nil, reason = nil) ⇒ Object
Enable PHI access for a single instance of this class.
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 |
# File 'lib/phi_attrs/phi_record.rb', line 343 def allow_phi!(user_id = nil, reason = nil) raise ArgumentError, 'block not allowed. use allow_phi with block' if block_given? user_id ||= self.class.current_user reason ||= self.class.i18n_reason raise ArgumentError, 'user_id and reason cannot be blank' if user_id.blank? || reason.blank? user_id = user_id.to_s.gsub(/[\r\n]/, " ") reason = reason.to_s.gsub(/[\r\n]/, " ") uuid = SecureRandom.uuid @__phi_access_stack.push(PhiStackEntry.new( phi_access_allowed: true, user_id: user_id, reason: reason, uuid: uuid, )) PhiAttrs::Logger.tagged(*phi_log_keys, uuid) do PhiAttrs::Logger.info("PHI Access Enabled for '#{user_id}': #{reason}") end end |
#disallow_last_phi!(preserve_extensions: false) ⇒ Object
Revoke last PHI access for a single instance of this class.
470 471 472 473 474 475 476 477 478 479 480 481 |
# File 'lib/phi_attrs/phi_record.rb', line 470 def disallow_last_phi!(preserve_extensions: false) raise ArgumentError, 'block not allowed' if block_given? removed_access = @__phi_access_stack.pop uuid = removed_access&.uuid PhiAttrs::Logger.tagged(*phi_log_keys, uuid) do revoke_extended_phi! unless preserve_extensions = removed_access.present? ? "PHI access disabled for #{removed_access.user_id}" : 'PHI access disabled. No instance level access was granted.' PhiAttrs::Logger.info() end end |
#disallow_phi { ... } ⇒ Object
Dissables PHI access for a single instance of this class inside the block. Nested calls to allow_phi will log once per nested call
451 452 453 454 455 456 457 458 459 460 461 462 |
# File 'lib/phi_attrs/phi_record.rb', line 451 def disallow_phi raise ArgumentError, 'block required. use disallow_phi! without block' unless block_given? add_disallow_flag! add_disallow_flag_to_extended_phi! begin yield ensure remove_disallow_flag_from_extended_phi! remove_disallow_flag! end end |
#disallow_phi! ⇒ Object
Revoke all PHI access for a single instance of this class.
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 |
# File 'lib/phi_attrs/phi_record.rb', line 421 def disallow_phi! raise ArgumentError, 'block not allowed. use disallow_phi with block' if block_given? removed_access_for_uuid = self.class.__uuid_string(@__phi_access_stack) PhiAttrs::Logger.tagged(*phi_log_keys, removed_access_for_uuid) do removed_access_for = self.class.__user_id_string(@__phi_access_stack) revoke_extended_phi! @__phi_access_stack = [] = removed_access_for.present? ? "PHI access disabled for #{removed_access_for}" : 'PHI access disabled. No instance level access was granted.' PhiAttrs::Logger.info() end end |
#get_phi(user_id = nil, reason = nil) { ... } ⇒ Object
Enable PHI access for a single instance of this class inside the block. Returns whatever is returned from the block. Nested calls to get_phi will log once per nested call s
400 401 402 403 404 405 406 407 408 409 410 411 412 413 |
# File 'lib/phi_attrs/phi_record.rb', line 400 def get_phi(user_id = nil, reason = nil) raise ArgumentError, 'block required' unless block_given? extended_instances = @__phi_relations_extended.clone begin allow_phi!(user_id, reason) yield ensure new_extensions = @__phi_relations_extended - extended_instances disallow_last_phi!(preserve_extensions: true) revoke_extended_phi!(new_extensions) if new_extensions.any? end end |
#phi_access_reason ⇒ String
The access reason for allowing access to this instance. This is what was passed in when PhiRecord#allow_phi! was called.
499 500 501 502 503 |
# File 'lib/phi_attrs/phi_record.rb', line 499 def phi_access_reason return 'new record' if new_record? phi_context&.reason end |
#phi_allowed? ⇒ Boolean
Whether PHI access is allowed for a single instance of this class
513 514 515 |
# File 'lib/phi_attrs/phi_record.rb', line 513 def phi_allowed? new_record? || (!phi_context.nil? && phi_context.phi_access_allowed) end |
#phi_allowed_by ⇒ String
The unique identifier for whom access has been allowed on this instance. This is what was passed in when PhiRecord#allow_phi! was called.
488 489 490 491 492 |
# File 'lib/phi_attrs/phi_record.rb', line 488 def phi_allowed_by return '__new_record__' if new_record? phi_context&.user_id end |
#reload ⇒ Object
529 530 531 532 |
# File 'lib/phi_attrs/phi_record.rb', line 529 def reload @__phi_relations_extended.clear super end |
#require_phi! ⇒ Object
Require phi access. Raises an error pre-emptively if it has not been granted.
525 526 527 |
# File 'lib/phi_attrs/phi_record.rb', line 525 def require_phi! raise PhiAttrs::Exceptions::PhiAccessException, 'PHI Access required, please call allow_phi or allow_phi! first' unless phi_allowed? end |