phi_attrs 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f6271ebbfae4a5ddad7aa1ad27b812cc4056a5a4958b1067ddf2aa717975b738
4
- data.tar.gz: '098ec65389f50bbe24876657a1ff9eb78bbbe17fb5192804ebbc2f75eedd97f4'
3
+ metadata.gz: 0c95e0078a0816fa79591bab794e8c423d70d8792354cbb09cb69cda60b93d4b
4
+ data.tar.gz: 7af031bbc1cc1aa2ba308dc778611b590faf33b4e572e9e264477dde4fb24ace
5
5
  SHA512:
6
- metadata.gz: a5832351881d96019071f9b77ac4e08b991104dca6f47c8a1917f5c3546002d7510c5d0fe7ceaa4fe37df7006ec71105acbbcc99a5c9928e57e78b43a7cd2d5d
7
- data.tar.gz: 3a153bd1a992dbbb94de889f8a82c22f969dd1bb9b9f36254485d0265f70cba89d89f1c8b424e30056aa1c23c5b8e8be3142d7b5ccfed05c970ec67aa3614d69
6
+ metadata.gz: a13b688097f56ad46044a7da0f91402565e582383e80f522f6ef3829fc75e677a5518a3190e261114713177ab6ab746783eb10bec4cc83215cf8089ca17cbc35
7
+ data.tar.gz: 323f3337e8d687e5e8e781324fd284008344a9ee8c15ff737840b736908face774331b762783076ffd5bb9e37a150452e4d712129a4a30fc169a33edde3abec9
@@ -0,0 +1,28 @@
1
+ name: Publish Gem
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - "main"
7
+ tags:
8
+ - v*
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - uses: actions/setup-ruby@v1
16
+ with:
17
+ ruby-version: '2.6'
18
+ - name: Install dependencies
19
+ run: |
20
+ gem install bundler:2.1.4
21
+ bundle install
22
+ - name: Release Gem
23
+ if: contains(github.ref, 'refs/tags/v')
24
+ uses: cadwallion/publish-rubygems-action@master
25
+ env:
26
+ GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
27
+ RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}}
28
+ RELEASE_COMMAND: bundle exec rake release
@@ -107,8 +107,32 @@ module PhiAttrs
107
107
  # end
108
108
  # # PHI Access Disallowed
109
109
  #
110
- def allow_phi(user_id = nil, reason = nil, allow_only: nil)
111
- raise ArgumentError, 'block required. use allow_phi! without block' unless block_given?
110
+ def allow_phi(user_id = nil, reason = nil, allow_only: nil, &block)
111
+ get_phi(user_id, reason, allow_only: allow_only, &block)
112
+ return
113
+ end
114
+
115
+
116
+ # Enable PHI access for any instance of this class in the block given only
117
+ # returning whatever the block returns.
118
+ #
119
+ # @param [String] user_id A unique identifier for the person accessing the PHI
120
+ # @param [String] reason The reason for accessing PHI
121
+ # @param [collection of PhiRecord] allow_only Specific PhiRecords to allow access to
122
+ # &block [block] The block in which PHI access is allowed for the class
123
+ #
124
+ # @example
125
+ # results = Foo.allow_phi('user@example.com', 'viewing patient record') do
126
+ # Foo.search(params)
127
+ # end
128
+ #
129
+ # @example
130
+ # loaded_foo = Foo.allow_phi('user@example.com', 'exporting patient list', allow_only: list_of_foos) do
131
+ # Bar.find_by(foo: list_of_foos).include(:foo)
132
+ # end
133
+ #
134
+ def get_phi(user_id = nil, reason = nil, allow_only: nil)
135
+ raise ArgumentError, 'block required' unless block_given?
112
136
 
113
137
  if allow_only.present?
114
138
  raise ArgumentError, 'allow_only must be iterable with each' unless allow_only.respond_to?(:each)
@@ -125,7 +149,7 @@ module PhiAttrs
125
149
  allow_only.each { |t| t.allow_phi!(user_id, reason) }
126
150
  end
127
151
 
128
- yield if block_given?
152
+ result = yield if block_given?
129
153
 
130
154
  __instances_with_extended_phi.each do |obj|
131
155
  if frozen_instances.include?(obj)
@@ -143,6 +167,8 @@ module PhiAttrs
143
167
  allow_only.each { |t| t.disallow_last_phi!(preserve_extensions: true) }
144
168
  # We've handled any newly extended allowances ourselves above
145
169
  end
170
+
171
+ result
146
172
  end
147
173
 
148
174
  # Explicitly disallow phi access in a specific area of code. This does not
@@ -335,17 +361,41 @@ module PhiAttrs
335
361
  # end
336
362
  # # PHI Access Disallowed Here
337
363
  #
338
- def allow_phi(user_id = nil, reason = nil)
339
- raise ArgumentError, 'block required. use allow_phi! without block' unless block_given?
364
+ def allow_phi(user_id = nil, reason = nil, &block)
365
+ get_phi(user_id, reason, &block)
366
+ return
367
+ end
368
+
369
+
370
+ # Enable PHI access for a single instance of this class inside the block.
371
+ # Returns whatever is returned from the block.
372
+ # Nested calls to get_phi will log once per nested call
373
+ #s
374
+ # @param [String] user_id A unique identifier for the person accessing the PHI
375
+ # @param [String] reason The reason for accessing PHI
376
+ # @yield The block in which phi access is allowed
377
+ #
378
+ # @return PHI
379
+ #
380
+ # @example
381
+ # foo = Foo.find(1)
382
+ # phi_data = foo.get_phi('user@example.com', 'viewing patient record') do
383
+ # foo.phi_field
384
+ # end
385
+ #
386
+ def get_phi(user_id = nil, reason = nil)
387
+ raise ArgumentError, 'block required' unless block_given?
340
388
 
341
389
  extended_instances = @__phi_relations_extended.clone
342
390
  allow_phi!(user_id, reason)
343
391
 
344
- yield if block_given?
392
+ result = yield if block_given?
345
393
 
346
394
  new_extensions = @__phi_relations_extended - extended_instances
347
395
  disallow_last_phi!(preserve_extensions: true)
348
396
  revoke_extended_phi!(new_extensions) if new_extensions.any?
397
+
398
+ result
349
399
  end
350
400
 
351
401
  # Revoke all PHI access for a single instance of this class.
@@ -412,6 +462,25 @@ module PhiAttrs
412
462
  end
413
463
  end
414
464
 
465
+
466
+ # The unique identifier for whom access has been allowed on this instance.
467
+ # This is what was passed in when PhiRecord#allow_phi! was called.
468
+ #
469
+ # @return [String] the user_id passed in to allow_phi!
470
+ #
471
+ def phi_allowed_by
472
+ phi_context[:user_id]
473
+ end
474
+
475
+ # The access reason for allowing access to this instance.
476
+ # This is what was passed in when PhiRecord#allow_phi! was called.
477
+ #
478
+ # @return [String] the reason passed in to allow_phi!
479
+ #
480
+ def phi_access_reason
481
+ phi_context[:reason]
482
+ end
483
+
415
484
  # Whether PHI access is allowed for a single instance of this class
416
485
  #
417
486
  # @example
@@ -424,6 +493,18 @@ module PhiAttrs
424
493
  !phi_context.nil? && phi_context[:phi_access_allowed]
425
494
  end
426
495
 
496
+ # Require phi access. Raises an error pre-emptively if it has not been granted.
497
+ #
498
+ # @example
499
+ # def use_phi(patient_record)
500
+ # patient_record.require_phi!
501
+ # # ...use PHI Freely
502
+ # end
503
+ #
504
+ def require_phi!
505
+ raise PhiAccessException, 'PHI Access required, please call allow_phi or allow_phi! first' unless phi_allowed?
506
+ end
507
+
427
508
  def reload
428
509
  @__phi_relations_extended.clear
429
510
  super
@@ -479,28 +560,6 @@ module PhiAttrs
479
560
  @__phi_log_keys = [PHI_ACCESS_LOG_TAG, self.class.name, @__phi_log_id]
480
561
  end
481
562
 
482
- # The unique identifier for whom access has been allowed on this instance.
483
- # This is what was passed in when PhiRecord#allow_phi! was called.
484
- #
485
- # @private
486
- #
487
- # @return [String] the user_id passed in to allow_phi!
488
- #
489
- def phi_allowed_by
490
- phi_context[:user_id]
491
- end
492
-
493
- # The access reason for allowing access to this instance.
494
- # This is what was passed in when PhiRecord#allow_phi! was called.
495
- #
496
- # @private
497
- #
498
- # @return [String] the reason passed in to allow_phi!
499
- #
500
- def phi_access_reason
501
- phi_context[:reason]
502
- end
503
-
504
563
  def phi_context
505
564
  instance_phi_context || class_phi_context
506
565
  end
@@ -0,0 +1,43 @@
1
+ require 'rspec/expectations'
2
+
3
+ DO_NOT_SPECIFY = "do not specify `allowed_by` or `with_access_reason` for negated `allow_phi_access`"
4
+
5
+ RSpec::Matchers.define :allow_phi_access do
6
+ match do |result|
7
+ @allowed = result.phi_allowed?
8
+ @user_id_matches = @user_id.nil? || @user_id == result.phi_allowed_by
9
+ @reason_matches = @reason.nil? || @reason == result.phi_access_reason
10
+
11
+ @allowed && @user_id_matches && @reason_matches
12
+ end
13
+
14
+ match_when_negated do |result|
15
+ raise ArgumentError, DO_NOT_SPECIFY unless @user_id.nil? && @reason.nil?
16
+
17
+ !result.phi_allowed?
18
+ end
19
+
20
+ chain :allowed_by do |user_id|
21
+ @user_id = user_id
22
+ end
23
+
24
+ chain :with_access_reason do |reason|
25
+ @reason = reason
26
+ end
27
+
28
+ # :nocov:
29
+ failure_message do |result|
30
+ msgs = []
31
+
32
+ msgs = ['PHI Access was not allowed.'] unless @allowed
33
+ msgs << "PHI Access was allowed by '#{result.phi_allowed_by}' (not '#{@user_id}')." unless @user_id_matches
34
+ msgs << "PHI Access was allowed because '#{result.phi_access_reason}' (not because '#{@reason}')." unless @reason_matches
35
+
36
+ msgs.join "\n"
37
+ end
38
+
39
+ failure_message_when_negated do |result|
40
+ "PHI access was allowed by '#{result.phi_allowed_by}', because '#{result.phi_access_reason}'"
41
+ end
42
+ # :nocov:
43
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PhiAttrs
4
- VERSION = '0.2.1'
4
+ VERSION = '0.2.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phi_attrs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wyatt Kirby
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-10 00:00:00.000000000 Z
11
+ date: 2020-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -228,6 +228,7 @@ extensions: []
228
228
  extra_rdoc_files: []
229
229
  files:
230
230
  - ".github/workflows/build.yml"
231
+ - ".github/workflows/publish.yml"
231
232
  - ".gitignore"
232
233
  - ".rspec"
233
234
  - ".rubocop.yml"
@@ -259,6 +260,7 @@ files:
259
260
  - lib/phi_attrs/logger.rb
260
261
  - lib/phi_attrs/phi_record.rb
261
262
  - lib/phi_attrs/railtie.rb
263
+ - lib/phi_attrs/rspec.rb
262
264
  - lib/phi_attrs/version.rb
263
265
  - phi_attrs.gemspec
264
266
  homepage: http://www.apsis.io