onc_certification_g10_test_kit 7.1.0 → 7.2.0

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/config/presets/g10_reference_server_preset.json +708 -532
  3. data/lib/onc_certification_g10_test_kit/bulk_data_authorization.rb +73 -67
  4. data/lib/onc_certification_g10_test_kit/bulk_data_group_export_cancel_stu1.rb +1 -2
  5. data/lib/onc_certification_g10_test_kit/bulk_data_group_export_cancel_stu2.rb +7 -1
  6. data/lib/onc_certification_g10_test_kit/bulk_data_group_export_parameters.rb +1 -1
  7. data/lib/onc_certification_g10_test_kit/bulk_data_group_export_stu1.rb +10 -2
  8. data/lib/onc_certification_g10_test_kit/bulk_data_group_export_validation.rb +6 -2
  9. data/lib/onc_certification_g10_test_kit/bulk_export_validation_tester.rb +4 -0
  10. data/lib/onc_certification_g10_test_kit/configuration_checker.rb +1 -1
  11. data/lib/onc_certification_g10_test_kit/encounter_context_test.rb +3 -3
  12. data/lib/onc_certification_g10_test_kit/export_kick_off_performer.rb +7 -3
  13. data/lib/onc_certification_g10_test_kit/multi_patient_api_stu1.rb +0 -4
  14. data/lib/onc_certification_g10_test_kit/multi_patient_api_stu2.rb +8 -4
  15. data/lib/onc_certification_g10_test_kit/patient_context_test.rb +3 -3
  16. data/lib/onc_certification_g10_test_kit/restricted_resource_type_access_group.rb +3 -10
  17. data/lib/onc_certification_g10_test_kit/scope_constants.rb +52 -0
  18. data/lib/onc_certification_g10_test_kit/short_id_map.yml +11 -20
  19. data/lib/onc_certification_g10_test_kit/single_patient_api_group.rb +4 -4
  20. data/lib/onc_certification_g10_test_kit/single_patient_us_core_4_api_group.rb +4 -4
  21. data/lib/onc_certification_g10_test_kit/single_patient_us_core_5_api_group.rb +4 -4
  22. data/lib/onc_certification_g10_test_kit/single_patient_us_core_6_api_group.rb +4 -4
  23. data/lib/onc_certification_g10_test_kit/single_patient_us_core_7_api_group.rb +4 -4
  24. data/lib/onc_certification_g10_test_kit/smart_app_launch_invalid_aud_group.rb +107 -64
  25. data/lib/onc_certification_g10_test_kit/smart_asymmetric_launch_group.rb +41 -88
  26. data/lib/onc_certification_g10_test_kit/smart_ehr_patient_launch_group.rb +31 -41
  27. data/lib/onc_certification_g10_test_kit/smart_ehr_patient_launch_group_stu2.rb +30 -52
  28. data/lib/onc_certification_g10_test_kit/smart_ehr_patient_launch_group_stu2_2.rb +32 -53
  29. data/lib/onc_certification_g10_test_kit/smart_ehr_practitioner_app_group.rb +99 -142
  30. data/lib/onc_certification_g10_test_kit/smart_fine_grained_scopes_group.rb +16 -54
  31. data/lib/onc_certification_g10_test_kit/smart_fine_grained_scopes_group_stu2_2.rb +16 -54
  32. data/lib/onc_certification_g10_test_kit/smart_fine_grained_scopes_us_core_7_group.rb +16 -54
  33. data/lib/onc_certification_g10_test_kit/smart_fine_grained_scopes_us_core_7_group_stu2_2.rb +16 -54
  34. data/lib/onc_certification_g10_test_kit/smart_granular_scope_selection_group.rb +29 -64
  35. data/lib/onc_certification_g10_test_kit/smart_granular_scope_selection_test.rb +4 -3
  36. data/lib/onc_certification_g10_test_kit/smart_invalid_pkce_group.rb +39 -83
  37. data/lib/onc_certification_g10_test_kit/smart_invalid_token_group.rb +42 -86
  38. data/lib/onc_certification_g10_test_kit/smart_invalid_token_group_stu2.rb +50 -88
  39. data/lib/onc_certification_g10_test_kit/smart_invalid_token_refresh_test.rb +9 -6
  40. data/lib/onc_certification_g10_test_kit/smart_limited_app_group.rb +86 -278
  41. data/lib/onc_certification_g10_test_kit/smart_public_standalone_launch_group.rb +30 -57
  42. data/lib/onc_certification_g10_test_kit/smart_public_standalone_launch_group_stu2.rb +34 -73
  43. data/lib/onc_certification_g10_test_kit/smart_public_standalone_launch_group_stu2_2.rb +34 -73
  44. data/lib/onc_certification_g10_test_kit/smart_scopes_test.rb +6 -1
  45. data/lib/onc_certification_g10_test_kit/smart_standalone_patient_app_group.rb +88 -116
  46. data/lib/onc_certification_g10_test_kit/smart_v1_scopes_group.rb +60 -114
  47. data/lib/onc_certification_g10_test_kit/tasks/generate_matrix.rb +2 -11
  48. data/lib/onc_certification_g10_test_kit/token_introspection_group.rb +12 -25
  49. data/lib/onc_certification_g10_test_kit/token_introspection_group_stu2_2.rb +12 -14
  50. data/lib/onc_certification_g10_test_kit/token_revocation_group.rb +44 -33
  51. data/lib/onc_certification_g10_test_kit/unrestricted_resource_type_access_group.rb +3 -3
  52. data/lib/onc_certification_g10_test_kit/version.rb +2 -2
  53. data/lib/onc_certification_g10_test_kit.rb +104 -40
  54. metadata +9 -8
@@ -92,6 +92,22 @@ module ONCCertificationG10TestKit
92
92
 
93
93
  input :url
94
94
 
95
+ config(
96
+ inputs: {
97
+ smart_auth_info: {
98
+ options: {
99
+ components: [
100
+ Inferno::DSL::AuthInfo.default_auth_type_component_without_backend_services,
101
+ {
102
+ name: :jwks,
103
+ locked: true
104
+ }
105
+ ]
106
+ }
107
+ }
108
+ }
109
+ )
110
+
95
111
  children.each(&:run_as_group)
96
112
 
97
113
  # Replace generic finer-grained scope auth group with which allows standalone or
@@ -125,64 +141,10 @@ module ONCCertificationG10TestKit
125
141
 
126
142
  config(
127
143
  inputs: {
128
- authorization_method: {
129
- name: :granular_scopes_authorization_method,
130
- title: 'Granular Scopes Authorization Request Method'
131
- },
132
- client_auth_type: {
133
- name: :granular_scopes_client_auth_type,
134
- title: 'Granular Scopes Client Authentication Type'
135
- },
136
144
  received_scopes: {
137
145
  name: :standalone_received_scopes
138
146
  }
139
147
  }
140
148
  )
141
-
142
- granular_scopes_group1.config(
143
- inputs: {
144
- client_id: {
145
- name: :granular_scopes1_client_id,
146
- title: 'Granular Scopes Group 1 Client ID'
147
- },
148
- client_secret: {
149
- name: :granular_scopes1_client_secret,
150
- title: 'Granular Scopes Group 1 Client Secret'
151
- },
152
- requested_scopes: {
153
- title: 'Granular Scopes Group 1 Scopes'
154
- }
155
- }
156
- )
157
-
158
- granular_scopes_group2.config(
159
- inputs: {
160
- client_id: {
161
- name: :granular_scopes2_client_id,
162
- title: 'Granular Scopes Group 2 Client ID'
163
- },
164
- client_secret: {
165
- name: :granular_scopes2_client_secret,
166
- title: 'Granular Scopes Group 2 Client Secret'
167
- },
168
- requested_scopes: {
169
- title: 'Granular Scopes Group 2 Scopes'
170
- }
171
- }
172
- )
173
-
174
- input_order :url,
175
- :granular_scopes1_client_id,
176
- :requested_scopes_group1,
177
- :granular_scopes_authorization_method,
178
- :granular_scopes_client_auth_type,
179
- :granular_scopes1_client_secret,
180
- :client_auth_encryption_method,
181
- :granular_scopes2_client_id,
182
- :requested_scopes_group2,
183
- :granular_scopes2_client_secret,
184
- :use_pkce,
185
- :pkce_code_challenge_method,
186
- :patient_ids
187
149
  end
188
150
  end
@@ -92,6 +92,22 @@ module ONCCertificationG10TestKit
92
92
 
93
93
  input :url
94
94
 
95
+ config(
96
+ inputs: {
97
+ smart_auth_info: {
98
+ options: {
99
+ components: [
100
+ Inferno::DSL::AuthInfo.default_auth_type_component_without_backend_services,
101
+ {
102
+ name: :jwks,
103
+ locked: true
104
+ }
105
+ ]
106
+ }
107
+ }
108
+ }
109
+ )
110
+
95
111
  children.each(&:run_as_group)
96
112
 
97
113
  # Replace generic finer-grained scope auth group with which allows standalone or
@@ -125,64 +141,10 @@ module ONCCertificationG10TestKit
125
141
 
126
142
  config(
127
143
  inputs: {
128
- authorization_method: {
129
- name: :granular_scopes_authorization_method,
130
- title: 'Granular Scopes Authorization Request Method'
131
- },
132
- client_auth_type: {
133
- name: :granular_scopes_client_auth_type,
134
- title: 'Granular Scopes Client Authentication Type'
135
- },
136
144
  received_scopes: {
137
145
  name: :standalone_received_scopes
138
146
  }
139
147
  }
140
148
  )
141
-
142
- granular_scopes_group1.config(
143
- inputs: {
144
- client_id: {
145
- name: :granular_scopes1_client_id,
146
- title: 'Granular Scopes Group 1 Client ID'
147
- },
148
- client_secret: {
149
- name: :granular_scopes1_client_secret,
150
- title: 'Granular Scopes Group 1 Client Secret'
151
- },
152
- requested_scopes: {
153
- title: 'Granular Scopes Group 1 Scopes'
154
- }
155
- }
156
- )
157
-
158
- granular_scopes_group2.config(
159
- inputs: {
160
- client_id: {
161
- name: :granular_scopes2_client_id,
162
- title: 'Granular Scopes Group 2 Client ID'
163
- },
164
- client_secret: {
165
- name: :granular_scopes2_client_secret,
166
- title: 'Granular Scopes Group 2 Client Secret'
167
- },
168
- requested_scopes: {
169
- title: 'Granular Scopes Group 2 Scopes'
170
- }
171
- }
172
- )
173
-
174
- input_order :url,
175
- :granular_scopes1_client_id,
176
- :requested_scopes_group1,
177
- :granular_scopes_authorization_method,
178
- :granular_scopes_client_auth_type,
179
- :granular_scopes1_client_secret,
180
- :client_auth_encryption_method,
181
- :granular_scopes2_client_id,
182
- :requested_scopes_group2,
183
- :granular_scopes2_client_secret,
184
- :use_pkce,
185
- :pkce_code_challenge_method,
186
- :patient_ids
187
149
  end
188
150
  end
@@ -66,21 +66,36 @@ module ONCCertificationG10TestKit
66
66
 
67
67
  config(
68
68
  inputs: {
69
- use_pkce: {
70
- default: 'true',
71
- locked: true
72
- },
73
- pkce_code_challenge_method: {
74
- locked: true
75
- },
76
- granular_scope_selection_authorization_method: {
77
- name: :granular_scope_selection_authorization_method,
78
- default: 'get'
79
- },
80
- client_auth_type: {
81
- name: :granular_scope_selection_client_auth_type,
82
- default: 'confidential_asymmetric'
69
+ received_scopes: { name: :granular_scope_selection_v2_received_scopes },
70
+ smart_auth_info: {
71
+ name: :granular_scopes_selection_smart_auth_info,
72
+ title: 'Granular Scope Selection Credentials',
73
+ options: {
74
+ mode: 'auth',
75
+ components: [
76
+ Inferno::DSL::AuthInfo.default_auth_type_component_without_backend_services,
77
+ {
78
+ name: :use_discovery,
79
+ locked: true
80
+ },
81
+ {
82
+ name: :requested_scopes,
83
+ default: %(
84
+ launch/patient openid fhirUser offline_access patient/Condition.rs
85
+ patient/Observation.rs patient/Patient.rs
86
+ ).gsub(/\s{2,}/, ' ').strip
87
+ },
88
+ {
89
+ name: :jwks,
90
+ locked: true
91
+ }
92
+ ]
93
+ }
83
94
  }
95
+ },
96
+ outputs: {
97
+ smart_auth_info: { name: :granular_scopes_selection_smart_auth_info },
98
+ received_scopes: { name: :granular_scope_selection_v2_received_scopes }
84
99
  }
85
100
  )
86
101
 
@@ -95,31 +110,6 @@ module ONCCertificationG10TestKit
95
110
  title 'Granular Scope Selection with v2 Scopes'
96
111
 
97
112
  config(
98
- inputs: {
99
- client_id: {
100
- name: :granular_scope_selection_v2_client_id,
101
- title: 'Granular Scope Selection w/v2 Scopes Client ID'
102
- },
103
- client_secret: {
104
- name: :granular_scope_selection_v2_client_secret,
105
- title: 'Granular Scope Selection w/v2 Scopes Client Secret',
106
- default: nil,
107
- optional: true
108
- },
109
- requested_scopes: {
110
- name: :granular_scope_selection_v2_requested_scopes,
111
- title: 'Granular Scope Selection v2 Scopes',
112
- default: %(
113
- launch/patient openid fhirUser offline_access patient/Condition.rs
114
- patient/Observation.rs patient/Patient.rs
115
- ).gsub(/\s{2,}/, ' ').strip
116
- },
117
- received_scopes: { name: :granular_scope_selection_v2_received_scopes }
118
- },
119
- outputs: {
120
- requested_scopes: { name: :granular_scope_selection_v2_requested_scopes },
121
- received_scopes: { name: :granular_scope_selection_v2_received_scopes }
122
- },
123
113
  options: {
124
114
  redirect_message_proc: proc do |auth_url|
125
115
  %(
@@ -157,31 +147,6 @@ module ONCCertificationG10TestKit
157
147
  title 'Granular Scope Selection with v2 Scopes'
158
148
 
159
149
  config(
160
- inputs: {
161
- client_id: {
162
- name: :granular_scope_selection_v2_client_id,
163
- title: 'Granular Scope Selection w/v2 Scopes Client ID'
164
- },
165
- client_secret: {
166
- name: :granular_scope_selection_v2_client_secret,
167
- title: 'Granular Scope Selection w/v2 Scopes Client Secret',
168
- default: nil,
169
- optional: true
170
- },
171
- requested_scopes: {
172
- name: :granular_scope_selection_v2_requested_scopes,
173
- title: 'Granular Scope Selection v2 Scopes',
174
- default: %(
175
- launch/patient openid fhirUser offline_access patient/Condition.rs
176
- patient/Observation.rs patient/Patient.rs
177
- ).gsub(/\s{2,}/, ' ').strip
178
- },
179
- received_scopes: { name: :granular_scope_selection_v2_received_scopes }
180
- },
181
- outputs: {
182
- requested_scopes: { name: :granular_scope_selection_v2_requested_scopes },
183
- received_scopes: { name: :granular_scope_selection_v2_received_scopes }
184
- },
185
150
  options: {
186
151
  redirect_message_proc: proc do |auth_url|
187
152
  %(
@@ -7,7 +7,8 @@ module ONCCertificationG10TestKit
7
7
  Patient resource.
8
8
  )
9
9
  id :g10_smart_granular_scope_selection
10
- input :requested_scopes, :received_scopes
10
+ input :received_scopes
11
+ input :smart_auth_info, type: :auth_info
11
12
 
12
13
  def resources_with_granular_scopes
13
14
  ['Condition', 'Observation']
@@ -26,8 +27,8 @@ module ONCCertificationG10TestKit
26
27
  end
27
28
 
28
29
  run do
29
- assert requested_scopes.present?
30
- requested_scopes = self.requested_scopes.split
30
+ assert smart_auth_info.requested_scopes.present?
31
+ requested_scopes = smart_auth_info.requested_scopes.split
31
32
  (resources_with_granular_scopes + ['Patient']).each do |resource_type|
32
33
  assert requested_scopes.any? { |scope| scope.match(resource_level_scope_regex(resource_type)) },
33
34
  "No resource-level scope was requested for #{resource_type}"
@@ -1,3 +1,5 @@
1
+ require_relative 'scope_constants'
2
+
1
3
  module ONCCertificationG10TestKit
2
4
  class InvalidSMARTTokenRequestTest < Inferno::Test
3
5
  title 'OAuth token exchange fails when supplied invalid code_verifier'
@@ -8,7 +10,8 @@ module ONCCertificationG10TestKit
8
10
  uses_request :redirect
9
11
  id :invalid_pkce_request
10
12
 
11
- input :code, :use_pkce, :pkce_code_verifier, :client_id, :client_secret, :smart_token_url
13
+ input :code, :pkce_code_verifier
14
+ input :smart_auth_info, type: :auth_info
12
15
 
13
16
  def modify_oauth_params(oauth_params)
14
17
  oauth_params
@@ -25,22 +28,24 @@ module ONCCertificationG10TestKit
25
28
 
26
29
  oauth2_headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
27
30
 
28
- if client_secret.present?
29
- client_credentials = "#{client_id}:#{client_secret}"
31
+ if smart_auth_info.symmetric_auth?
32
+ client_credentials = "#{smart_auth_info.client_id}:#{smart_auth_info.client_secret}"
30
33
  oauth2_headers['Authorization'] = "Basic #{Base64.strict_encode64(client_credentials)}"
31
34
  else
32
- oauth2_params[:client_id] = client_id
35
+ oauth2_params[:client_id] = smart_auth_info.client_id
33
36
  end
34
37
 
35
38
  modify_oauth_params(oauth2_params)
36
39
 
37
- post(smart_token_url, body: oauth2_params, name: :token, headers: oauth2_headers)
40
+ post(smart_auth_info.token_url, body: oauth2_params, name: :token, headers: oauth2_headers)
38
41
 
39
42
  assert_response_status([400, 401])
40
43
  end
41
44
  end
42
45
 
43
46
  class SMARTInvalidPKCEGroup < Inferno::TestGroup
47
+ include ScopeConstants
48
+
44
49
  title 'Invalid PKCE Code Verifier'
45
50
  short_title 'Invalid PKCE Code Verifier'
46
51
  input_instructions %(
@@ -70,80 +75,41 @@ module ONCCertificationG10TestKit
70
75
  id :g10_smart_invalid_pkce_code_verifier_group
71
76
  run_as_group
72
77
 
73
- input :use_pkce,
74
- title: 'Proof Key for Code Exchange (PKCE)',
75
- type: 'radio',
76
- default: 'true',
77
- locked: true,
78
+ input :smart_auth_info, type: :auth_info
79
+
80
+ config(
81
+ inputs: {
82
+ smart_auth_info: {
83
+ name: :standalone_smart_auth_info,
84
+ title: 'Standalone Launch Credentials',
78
85
  options: {
79
- list_options: [
86
+ mode: 'auth',
87
+ components: [
80
88
  {
81
- label: 'Enabled',
82
- value: 'true'
89
+ name: :requested_scopes,
90
+ default: STANDALONE_SMART_1_SCOPES
83
91
  },
84
92
  {
85
- label: 'Disabled',
86
- value: 'false'
87
- }
88
- ]
89
- }
90
- input :pkce_code_challenge_method,
91
- optional: true,
92
- title: 'PKCE Code Challenge Method',
93
- type: 'radio',
94
- default: 'S256',
95
- locked: true,
96
- options: {
97
- list_options: [
93
+ name: :auth_type,
94
+ default: 'symmetric',
95
+ locked: true
96
+ },
97
+ {
98
+ name: :use_discovery,
99
+ locked: true
100
+ },
98
101
  {
99
- label: 'S256',
100
- value: 'S256'
102
+ name: :pkce_support,
103
+ default: 'enabled',
104
+ locked: true
101
105
  },
102
106
  {
103
- label: 'Plain',
104
- value: 'plain'
107
+ name: :pkce_code_challenge_method,
108
+ default: 'S256',
109
+ locked: true
105
110
  }
106
111
  ]
107
112
  }
108
-
109
- input_order :url,
110
- :standalone_client_id,
111
- :standalone_client_secret,
112
- :standalone_requested_scopes,
113
- :use_pkce,
114
- :pkce_code_challenge_method,
115
- :smart_authorization_url,
116
- :smart_token_url
117
-
118
- config(
119
- inputs: {
120
- client_id: {
121
- name: :standalone_client_id,
122
- title: 'Standalone Client ID',
123
- description: 'Client ID provided during registration of Inferno as a standalone application'
124
- },
125
- client_secret: {
126
- name: :standalone_client_secret,
127
- title: 'Standalone Client Secret',
128
- description: 'Client Secret provided during registration of Inferno as a standalone application'
129
- },
130
- requested_scopes: {
131
- name: :standalone_requested_scopes,
132
- title: 'Standalone Scope',
133
- description: 'OAuth 2.0 scope provided by system to enable all required functionality',
134
- type: 'textarea',
135
- default: %(
136
- launch/patient openid fhirUser offline_access
137
- patient/Medication.read patient/AllergyIntolerance.read
138
- patient/CarePlan.read patient/CareTeam.read patient/Condition.read
139
- patient/Device.read patient/DiagnosticReport.read
140
- patient/DocumentReference.read patient/Encounter.read
141
- patient/Goal.read patient/Immunization.read patient/Location.read
142
- patient/MedicationRequest.read patient/Observation.read
143
- patient/Organization.read patient/Patient.read
144
- patient/Practitioner.read patient/Procedure.read
145
- patient/Provenance.read patient/PractitionerRole.read
146
- ).gsub(/\s{2,}/, ' ').strip
147
113
  },
148
114
  url: {
149
115
  title: 'Standalone FHIR Endpoint',
@@ -155,31 +121,19 @@ module ONCCertificationG10TestKit
155
121
  state: {
156
122
  name: :invalid_token_state
157
123
  },
158
- smart_authorization_url: {
159
- title: 'OAuth 2.0 Authorize Endpoint',
160
- description: 'OAuth 2.0 Authorize Endpoint provided during the patient standalone launch'
161
- },
162
- smart_token_url: {
163
- title: 'OAuth 2.0 Token Endpoint',
164
- description: 'OAuth 2.0 Token Endpoint provided during the patient standalone launch'
165
- },
166
124
  pkce_code_challenge: {
167
125
  name: :invalid_token_pkce_code_challenge
168
126
  },
169
127
  pkce_code_verifier: {
170
128
  name: :invalid_token_pkce_code_verifier
171
- },
172
- client_auth_type: {
173
- locked: true,
174
- default: 'confidential_symmetric'
175
129
  }
176
130
  },
177
131
  outputs: {
178
132
  code: { name: :invalid_token_code },
179
133
  state: { name: :invalid_token_state },
180
- expires_in: { name: :invalid_token_expires_in },
181
134
  pkce_code_challenge: { name: :invalid_token_pkce_code_challenge },
182
- pkce_code_verifier: { name: :invalid_token_pkce_code_verifier }
135
+ pkce_code_verifier: { name: :invalid_token_pkce_code_verifier },
136
+ smart_auth_info: { name: :standalone_smart_auth_info }
183
137
  },
184
138
  requests: {
185
139
  redirect: { name: :invalid_token_redirect },
@@ -187,6 +141,8 @@ module ONCCertificationG10TestKit
187
141
  }
188
142
  )
189
143
 
144
+ test from: :well_known_endpoint
145
+
190
146
  test from: :smart_app_redirect_stu2,
191
147
  id: :smart_no_code_verifier_redirect,
192
148
  config: {