onc_certification_g10_test_kit 2.3.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/inferno/terminology/expected_manifest.yml +242 -29
- data/lib/inferno/terminology/fhir_package_manager.rb +27 -0
- data/lib/inferno/terminology/loader.rb +22 -1
- data/lib/inferno/terminology/tasks/create_value_set_validators.rb +1 -1
- data/lib/inferno/terminology/tasks/download_fhir_terminology.rb +5 -0
- data/lib/inferno/terminology/value_set.rb +51 -5
- data/lib/onc_certification_g10_test_kit/base_token_refresh_group.rb +5 -4
- data/lib/onc_certification_g10_test_kit/bulk_data_group_export_stu1.rb +5 -0
- data/lib/onc_certification_g10_test_kit/bulk_data_group_export_stu2.rb +2 -0
- data/lib/onc_certification_g10_test_kit/bulk_data_group_export_validation.rb +206 -28
- data/lib/onc_certification_g10_test_kit/bulk_export_validation_tester.rb +25 -40
- data/lib/onc_certification_g10_test_kit/encounter_context_test.rb +30 -0
- data/lib/onc_certification_g10_test_kit/feature.rb +5 -8
- data/lib/onc_certification_g10_test_kit/limited_scope_grant_test.rb +18 -5
- data/lib/onc_certification_g10_test_kit/profile_selector.rb +175 -0
- data/lib/onc_certification_g10_test_kit/restricted_resource_type_access_group.rb +54 -4
- data/lib/onc_certification_g10_test_kit/single_patient_us_core_5_api_group.rb +93 -0
- data/lib/onc_certification_g10_test_kit/smart_app_launch_invalid_aud_group.rb +50 -5
- data/lib/onc_certification_g10_test_kit/smart_ehr_patient_launch_group.rb +94 -0
- data/lib/onc_certification_g10_test_kit/smart_ehr_patient_launch_group_stu2.rb +94 -0
- data/lib/onc_certification_g10_test_kit/smart_ehr_practitioner_app_group.rb +197 -13
- data/lib/onc_certification_g10_test_kit/smart_invalid_pkce_group.rb +310 -0
- data/lib/onc_certification_g10_test_kit/smart_invalid_token_group_stu2.rb +211 -0
- data/lib/onc_certification_g10_test_kit/smart_limited_app_group.rb +135 -9
- data/lib/onc_certification_g10_test_kit/smart_public_standalone_launch_group.rb +16 -4
- data/lib/onc_certification_g10_test_kit/smart_public_standalone_launch_group_stu2.rb +130 -0
- data/lib/onc_certification_g10_test_kit/smart_scopes_test.rb +134 -67
- data/lib/onc_certification_g10_test_kit/smart_standalone_patient_app_group.rb +166 -11
- data/lib/onc_certification_g10_test_kit/unrestricted_resource_type_access_group.rb +119 -135
- data/lib/onc_certification_g10_test_kit/version.rb +1 -1
- data/lib/onc_certification_g10_test_kit/visual_inspection_and_attestations_group.rb +19 -0
- data/lib/onc_certification_g10_test_kit/well_known_capabilities_test.rb +7 -1
- data/lib/onc_certification_g10_test_kit.rb +115 -74
- metadata +19 -11
- data/lib/onc_certification_g10_test_kit/profile_guesser.rb +0 -72
@@ -0,0 +1,211 @@
|
|
1
|
+
module ONCCertificationG10TestKit
|
2
|
+
class SMARTInvalidTokenGroupSTU2 < Inferno::TestGroup
|
3
|
+
title 'SMART App Launch Error: Invalid Access Token Request'
|
4
|
+
short_title 'SMART Invalid Token Request'
|
5
|
+
input_instructions %(
|
6
|
+
Register Inferno as a standalone application using the following information:
|
7
|
+
|
8
|
+
* Redirect URI: `#{SMARTAppLaunch::AppRedirectTest.config.options[:redirect_uri]}`
|
9
|
+
)
|
10
|
+
description %(
|
11
|
+
# Background
|
12
|
+
|
13
|
+
The Invalid Access Token Request Sequence verifies that a SMART Launch
|
14
|
+
Sequence, specifically the [Standalone
|
15
|
+
Launch](http://hl7.org/fhir/smart-app-launch/STU2/app-launch.html#launch-app-standalone-launch)
|
16
|
+
Sequence, does not work in the case where the client sends an invalid
|
17
|
+
Authorization code or client ID during the code exchange step. This must
|
18
|
+
not result in a successful launch.
|
19
|
+
|
20
|
+
This test is not included as part of a regular SMART Launch Sequence
|
21
|
+
because some servers may not accept an authorization code after it has
|
22
|
+
been used unsuccessfully in this manner.
|
23
|
+
)
|
24
|
+
id :g10_smart_invalid_token_request_stu2
|
25
|
+
run_as_group
|
26
|
+
|
27
|
+
input :use_pkce,
|
28
|
+
title: 'Proof Key for Code Exchange (PKCE)',
|
29
|
+
type: 'radio',
|
30
|
+
default: 'true',
|
31
|
+
locked: true,
|
32
|
+
options: {
|
33
|
+
list_options: [
|
34
|
+
{
|
35
|
+
label: 'Enabled',
|
36
|
+
value: 'true'
|
37
|
+
},
|
38
|
+
{
|
39
|
+
label: 'Disabled',
|
40
|
+
value: 'false'
|
41
|
+
}
|
42
|
+
]
|
43
|
+
}
|
44
|
+
input :pkce_code_challenge_method,
|
45
|
+
optional: true,
|
46
|
+
title: 'PKCE Code Challenge Method',
|
47
|
+
type: 'radio',
|
48
|
+
default: 'S256',
|
49
|
+
locked: true,
|
50
|
+
options: {
|
51
|
+
list_options: [
|
52
|
+
{
|
53
|
+
label: 'S256',
|
54
|
+
value: 'S256'
|
55
|
+
},
|
56
|
+
{
|
57
|
+
label: 'Plain',
|
58
|
+
value: 'plain'
|
59
|
+
}
|
60
|
+
]
|
61
|
+
}
|
62
|
+
|
63
|
+
input_order :url,
|
64
|
+
:standalone_client_id,
|
65
|
+
:standalone_client_secret,
|
66
|
+
:standalone_requested_scopes,
|
67
|
+
:use_pkce,
|
68
|
+
:pkce_code_challenge_method,
|
69
|
+
:smart_authorization_url,
|
70
|
+
:smart_token_url
|
71
|
+
|
72
|
+
config(
|
73
|
+
inputs: {
|
74
|
+
client_id: {
|
75
|
+
name: :standalone_client_id,
|
76
|
+
title: 'Standalone Client ID',
|
77
|
+
description: 'Client ID provided during registration of Inferno as a standalone application'
|
78
|
+
},
|
79
|
+
client_secret: {
|
80
|
+
name: :standalone_client_secret,
|
81
|
+
title: 'Standalone Client Secret',
|
82
|
+
description: 'Client Secret provided during registration of Inferno as a standalone application'
|
83
|
+
},
|
84
|
+
requested_scopes: {
|
85
|
+
name: :standalone_requested_scopes,
|
86
|
+
title: 'Standalone Scope',
|
87
|
+
description: 'OAuth 2.0 scope provided by system to enable all required functionality',
|
88
|
+
type: 'textarea',
|
89
|
+
default: %(
|
90
|
+
launch/patient openid fhirUser offline_access
|
91
|
+
patient/Medication.read patient/AllergyIntolerance.read
|
92
|
+
patient/CarePlan.read patient/CareTeam.read patient/Condition.read
|
93
|
+
patient/Device.read patient/DiagnosticReport.read
|
94
|
+
patient/DocumentReference.read patient/Encounter.read
|
95
|
+
patient/Goal.read patient/Immunization.read patient/Location.read
|
96
|
+
patient/MedicationRequest.read patient/Observation.read
|
97
|
+
patient/Organization.read patient/Patient.read
|
98
|
+
patient/Practitioner.read patient/Procedure.read
|
99
|
+
patient/Provenance.read patient/PractitionerRole.read
|
100
|
+
).gsub(/\s{2,}/, ' ').strip
|
101
|
+
},
|
102
|
+
url: {
|
103
|
+
title: 'Standalone FHIR Endpoint',
|
104
|
+
description: 'URL of the FHIR endpoint used by standalone applications'
|
105
|
+
},
|
106
|
+
code: {
|
107
|
+
name: :invalid_token_code
|
108
|
+
},
|
109
|
+
state: {
|
110
|
+
name: :invalid_token_state
|
111
|
+
},
|
112
|
+
smart_authorization_url: {
|
113
|
+
title: 'OAuth 2.0 Authorize Endpoint',
|
114
|
+
description: 'OAuth 2.0 Authorize Endpoint provided during the patient standalone launch'
|
115
|
+
},
|
116
|
+
smart_token_url: {
|
117
|
+
title: 'OAuth 2.0 Token Endpoint',
|
118
|
+
description: 'OAuth 2.0 Token Endpoint provided during the patient standalone launch'
|
119
|
+
},
|
120
|
+
pkce_code_verifier: {
|
121
|
+
name: :invalid_token_pkce_code_verifier
|
122
|
+
}
|
123
|
+
},
|
124
|
+
outputs: {
|
125
|
+
code: { name: :invalid_token_code },
|
126
|
+
state: { name: :invalid_token_state },
|
127
|
+
expires_in: { name: :invalid_token_expires_in },
|
128
|
+
pkce_code_verifier: { name: :invalid_token_pkce_code_verifier }
|
129
|
+
},
|
130
|
+
requests: {
|
131
|
+
redirect: { name: :invalid_token_redirect },
|
132
|
+
token: { name: :invalid_token_token }
|
133
|
+
}
|
134
|
+
)
|
135
|
+
|
136
|
+
test from: :smart_app_redirect_stu2
|
137
|
+
test from: :smart_code_received
|
138
|
+
|
139
|
+
test do
|
140
|
+
title ' OAuth token exchange fails when supplied invalid code'
|
141
|
+
description %(
|
142
|
+
If the request failed verification or is invalid, the authorization
|
143
|
+
server returns an error response.
|
144
|
+
)
|
145
|
+
uses_request :redirect
|
146
|
+
|
147
|
+
input :use_pkce, :pkce_code_verifier, :client_id, :client_secret, :smart_token_url
|
148
|
+
|
149
|
+
run do
|
150
|
+
skip_if request.query_parameters['error'].present?, 'Error during authorization request'
|
151
|
+
|
152
|
+
oauth2_params = {
|
153
|
+
grant_type: 'authorization_code',
|
154
|
+
code: 'BAD_CODE',
|
155
|
+
redirect_uri: config.options[:redirect_uri]
|
156
|
+
}
|
157
|
+
oauth2_headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
|
158
|
+
|
159
|
+
if client_secret.present?
|
160
|
+
client_credentials = "#{client_id}:#{client_secret}"
|
161
|
+
oauth2_headers['Authorization'] = "Basic #{Base64.strict_encode64(client_credentials)}"
|
162
|
+
else
|
163
|
+
oauth2_params[:client_id] = client_id
|
164
|
+
end
|
165
|
+
|
166
|
+
oauth2_params[:code_verifier] = pkce_code_verifier if use_pkce == 'true'
|
167
|
+
|
168
|
+
post(smart_token_url, body: oauth2_params, name: :token, headers: oauth2_headers)
|
169
|
+
|
170
|
+
assert_response_status(400)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
test do
|
175
|
+
title 'OAuth token exchange fails when supplied invalid client ID'
|
176
|
+
description %(
|
177
|
+
If the request failed verification or is invalid, the authorization
|
178
|
+
server returns an error response.
|
179
|
+
)
|
180
|
+
uses_request :redirect
|
181
|
+
|
182
|
+
input :use_pkce, :pkce_code_verifier, :code, :smart_token_url, :client_secret
|
183
|
+
|
184
|
+
run do
|
185
|
+
skip_if request.query_parameters['error'].present?, 'Error during authorization request'
|
186
|
+
|
187
|
+
client_id = 'BAD_CLIENT_ID'
|
188
|
+
|
189
|
+
oauth2_params = {
|
190
|
+
grant_type: 'authorization_code',
|
191
|
+
code: code,
|
192
|
+
redirect_uri: config.options[:redirect_uri]
|
193
|
+
}
|
194
|
+
oauth2_headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
|
195
|
+
|
196
|
+
if client_secret.present?
|
197
|
+
client_credentials = "#{client_id}:#{client_secret}"
|
198
|
+
oauth2_headers['Authorization'] = "Basic #{Base64.strict_encode64(client_credentials)}"
|
199
|
+
else
|
200
|
+
oauth2_params[:client_id] = client_id
|
201
|
+
end
|
202
|
+
|
203
|
+
oauth2_params[:code_verifier] = pkce_code_verifier if use_pkce == 'true'
|
204
|
+
|
205
|
+
post(smart_token_url, body: oauth2_params, name: :token, headers: oauth2_headers)
|
206
|
+
|
207
|
+
assert_response_status([400, 401])
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
@@ -20,13 +20,17 @@ module ONCCertificationG10TestKit
|
|
20
20
|
|
21
21
|
description %(
|
22
22
|
This scenario demonstrates the ability to perform a Patient Standalone
|
23
|
-
Launch to a
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
Launch to a SMART on FHIR confidential client with limited access granted
|
24
|
+
to the app based on user input. The tester is expected to grant the
|
25
|
+
application access to a subset of desired resource types. The launch is
|
26
|
+
performed using the same app configuration as in the Standalone Patient
|
27
|
+
App test, demonstrating that the user is control over what scopes are
|
28
|
+
granted to the app as required in the (g)(10) Standardized API criterion.
|
29
|
+
|
30
|
+
* [SMART on FHIR
|
31
|
+
(STU1)](http://www.hl7.org/fhir/smart-app-launch/1.0.0/)
|
32
|
+
* [SMART on FHIR
|
33
|
+
(STU2)](http://hl7.org/fhir/smart-app-launch/STU2)
|
30
34
|
)
|
31
35
|
id :g10_smart_limited_app
|
32
36
|
run_as_group
|
@@ -76,14 +80,14 @@ module ONCCertificationG10TestKit
|
|
76
80
|
Sequence](http://hl7.org/fhir/smart-app-launch/1.0.0/index.html#standalone-launch-sequence)
|
77
81
|
)
|
78
82
|
|
83
|
+
required_suite_options smart_app_launch_version: 'smart_app_launch_1'
|
84
|
+
|
79
85
|
config(
|
80
86
|
inputs: {
|
81
87
|
client_id: { locked: true },
|
82
88
|
client_secret: { locked: true, optional: false },
|
83
89
|
url: { locked: true },
|
84
90
|
requested_scopes: { locked: true },
|
85
|
-
use_pkce: { locked: true },
|
86
|
-
pkce_code_challenge_method: { locked: true },
|
87
91
|
code: { name: :limited_code },
|
88
92
|
state: { name: :limited_state },
|
89
93
|
patient_id: { name: :limited_patient_id },
|
@@ -161,6 +165,128 @@ module ONCCertificationG10TestKit
|
|
161
165
|
end
|
162
166
|
end
|
163
167
|
|
168
|
+
group from: :smart_standalone_launch_stu2,
|
169
|
+
config: {
|
170
|
+
inputs: {
|
171
|
+
use_pkce: {
|
172
|
+
default: 'true',
|
173
|
+
locked: true
|
174
|
+
},
|
175
|
+
pkce_code_challenge_method: {
|
176
|
+
locked: true
|
177
|
+
}
|
178
|
+
}
|
179
|
+
} do
|
180
|
+
title 'Standalone Launch With Limited Scope'
|
181
|
+
description %(
|
182
|
+
# Background
|
183
|
+
|
184
|
+
The [Standalone
|
185
|
+
Launch Sequence](http://hl7.org/fhir/smart-app-launch/STU2/app-launch.html#launch-app-standalone-launch)
|
186
|
+
allows an app, like Inferno, to be launched independent of an
|
187
|
+
existing EHR session. It is one of the two launch methods described in
|
188
|
+
the SMART App Launch Framework alongside EHR Launch. The app will
|
189
|
+
request authorization for the provided scope from the authorization
|
190
|
+
endpoint, ultimately receiving an authorization token which can be used
|
191
|
+
to gain access to resources on the FHIR server.
|
192
|
+
|
193
|
+
# Test Methodology
|
194
|
+
|
195
|
+
Inferno will redirect the user to the the authorization endpoint so that
|
196
|
+
they may provide any required credentials and authorize the application.
|
197
|
+
Upon successful authorization, Inferno will exchange the authorization
|
198
|
+
code provided for an access token.
|
199
|
+
|
200
|
+
For more information on the #{title}:
|
201
|
+
|
202
|
+
* [Standalone Launch
|
203
|
+
Sequence](http://hl7.org/fhir/smart-app-launch/STU2/app-launch.html#launch-app-standalone-launch)
|
204
|
+
)
|
205
|
+
|
206
|
+
required_suite_options smart_app_launch_version: 'smart_app_launch_2'
|
207
|
+
|
208
|
+
config(
|
209
|
+
inputs: {
|
210
|
+
client_id: { locked: true },
|
211
|
+
client_secret: { locked: true },
|
212
|
+
url: { locked: true },
|
213
|
+
requested_scopes: { locked: true },
|
214
|
+
code: { name: :limited_code },
|
215
|
+
state: { name: :limited_state },
|
216
|
+
patient_id: { name: :limited_patient_id },
|
217
|
+
access_token: { name: :limited_access_token },
|
218
|
+
# TODO: separate standalone/ehr discovery outputs
|
219
|
+
smart_authorization_url: { locked: true, title: 'SMART Authorization Url' },
|
220
|
+
smart_token_url: { locked: true, title: 'SMART Token Url' },
|
221
|
+
received_scopes: { name: :limited_received_scopes },
|
222
|
+
smart_credentials: { name: :limited_smart_credentials }
|
223
|
+
},
|
224
|
+
outputs: {
|
225
|
+
code: { name: :limited_code },
|
226
|
+
token_retrieval_time: { name: :limited_token_retrieval_time },
|
227
|
+
state: { name: :limited_state },
|
228
|
+
id_token: { name: :limited_id_token },
|
229
|
+
refresh_token: { name: :limited_refresh_token },
|
230
|
+
access_token: { name: :limited_access_token },
|
231
|
+
expires_in: { name: :limited_expires_in },
|
232
|
+
patient_id: { name: :limited_patient_id },
|
233
|
+
encounter_id: { name: :limited_encounter_id },
|
234
|
+
received_scopes: { name: :limited_received_scopes },
|
235
|
+
intent: { name: :limited_intent },
|
236
|
+
smart_credentials: { name: :limited_smart_credentials }
|
237
|
+
},
|
238
|
+
requests: {
|
239
|
+
redirect: { name: :limited_redirect },
|
240
|
+
token: { name: :limited_token }
|
241
|
+
},
|
242
|
+
options: {
|
243
|
+
redirect_message_proc: lambda do |auth_url|
|
244
|
+
expected_resource_string =
|
245
|
+
expected_resources
|
246
|
+
.split(',')
|
247
|
+
.map(&:strip)
|
248
|
+
.map { |resource_type| "* #{resource_type}\n" }
|
249
|
+
.join
|
250
|
+
|
251
|
+
<<~MESSAGE
|
252
|
+
### #{self.class.parent.parent.title}
|
253
|
+
|
254
|
+
[Follow this link to authorize with the SMART
|
255
|
+
server](#{auth_url}).
|
256
|
+
|
257
|
+
Tests will resume once Inferno receives a request at
|
258
|
+
`#{config.options[:redirect_uri]}` with a state of `#{state}`.
|
259
|
+
|
260
|
+
Access should only be granted to the following resources:
|
261
|
+
|
262
|
+
#{expected_resource_string}
|
263
|
+
MESSAGE
|
264
|
+
end
|
265
|
+
}
|
266
|
+
)
|
267
|
+
|
268
|
+
input :expected_resources,
|
269
|
+
title: 'Expected Resource Grant for Limited Access Launch',
|
270
|
+
description: 'The user will only grant access to the following resources during authorization.',
|
271
|
+
default: 'Patient, Condition, Observation'
|
272
|
+
|
273
|
+
test from: :g10_patient_context,
|
274
|
+
config: {
|
275
|
+
inputs: {
|
276
|
+
patient_id: { name: :limited_patient_id },
|
277
|
+
smart_credentials: { name: :limited_smart_credentials }
|
278
|
+
}
|
279
|
+
}
|
280
|
+
|
281
|
+
test from: :g10_limited_scope_grant do
|
282
|
+
config(
|
283
|
+
inputs: {
|
284
|
+
received_scopes: { name: :limited_received_scopes }
|
285
|
+
}
|
286
|
+
)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
164
290
|
group from: :g10_restricted_resource_type_access,
|
165
291
|
config: {
|
166
292
|
inputs: {
|
@@ -8,9 +8,9 @@ module ONCCertificationG10TestKit
|
|
8
8
|
* Redirect URI: `#{SMARTAppLaunch::AppRedirectTest.config.options[:redirect_uri]}`
|
9
9
|
|
10
10
|
Enter in the appropriate scope to enable patient-level access to all
|
11
|
-
relevant resources.
|
12
|
-
|
13
|
-
(launch/patient) are required.
|
11
|
+
relevant resources. If using SMART v2, v2-style scopes must be used. In
|
12
|
+
addition, support for the OpenID Connect (openid fhirUser), refresh tokens
|
13
|
+
(offline_access), and patient context (launch/patient) are required.
|
14
14
|
)
|
15
15
|
description %(
|
16
16
|
# Background
|
@@ -53,7 +53,19 @@ module ONCCertificationG10TestKit
|
|
53
53
|
},
|
54
54
|
requested_scopes: {
|
55
55
|
name: :public_requested_scopes,
|
56
|
-
title: 'Public Launch Scope'
|
56
|
+
title: 'Public Launch Scope',
|
57
|
+
default: %(
|
58
|
+
launch/patient openid fhirUser offline_access
|
59
|
+
patient/Medication.read patient/AllergyIntolerance.read
|
60
|
+
patient/CarePlan.read patient/CareTeam.read patient/Condition.read
|
61
|
+
patient/Device.read patient/DiagnosticReport.read
|
62
|
+
patient/DocumentReference.read patient/Encounter.read
|
63
|
+
patient/Goal.read patient/Immunization.read patient/Location.read
|
64
|
+
patient/MedicationRequest.read patient/Observation.read
|
65
|
+
patient/Organization.read patient/Patient.read
|
66
|
+
patient/Practitioner.read patient/Procedure.read
|
67
|
+
patient/Provenance.read patient/PractitionerRole.read
|
68
|
+
).gsub(/\s{2,}/, ' ').strip
|
57
69
|
},
|
58
70
|
url: {
|
59
71
|
title: 'Public Launch FHIR Endpoint',
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module ONCCertificationG10TestKit
|
2
|
+
class SMARTPublicStandaloneLaunchGroupSTU2 < SMARTAppLaunch::StandaloneLaunchGroupSTU2
|
3
|
+
title 'Public Client Standalone Launch with OpenID Connect'
|
4
|
+
short_title 'SMART Public Client Launch'
|
5
|
+
input_instructions %(
|
6
|
+
Register Inferno as a standalone application using the following information:
|
7
|
+
|
8
|
+
* Redirect URI: `#{SMARTAppLaunch::AppRedirectTest.config.options[:redirect_uri]}`
|
9
|
+
|
10
|
+
Enter in the appropriate scope to enable patient-level access to all
|
11
|
+
relevant resources. In addition, support for the OpenID Connect (openid
|
12
|
+
fhirUser), refresh tokens (offline_access), and patient context
|
13
|
+
(launch/patient) are required.
|
14
|
+
)
|
15
|
+
id :g10_public_standalone_launch_stu2
|
16
|
+
run_as_group
|
17
|
+
|
18
|
+
config(
|
19
|
+
inputs: {
|
20
|
+
client_id: {
|
21
|
+
name: :public_client_id,
|
22
|
+
title: 'Public Launch Client ID'
|
23
|
+
},
|
24
|
+
client_secret: {
|
25
|
+
name: :public_client_secret,
|
26
|
+
title: 'Public Launch Client Secret',
|
27
|
+
default: nil,
|
28
|
+
optional: true,
|
29
|
+
locked: true
|
30
|
+
},
|
31
|
+
requested_scopes: {
|
32
|
+
name: :public_requested_scopes,
|
33
|
+
title: 'Public Launch Scope',
|
34
|
+
default: %(
|
35
|
+
launch/patient openid fhirUser offline_access patient/Medication.rs
|
36
|
+
patient/AllergyIntolerance.rs patient/CarePlan.rs
|
37
|
+
patient/CareTeam.rs patient/Condition.rs patient/Device.rs
|
38
|
+
patient/DiagnosticReport.rs patient/DocumentReference.rs
|
39
|
+
patient/Encounter.rs patient/Goal.rs patient/Immunization.rs
|
40
|
+
patient/Location.rs patient/MedicationRequest.rs
|
41
|
+
patient/Observation.rs patient/Organization.rs patient/Patient.rs
|
42
|
+
patient/Practitioner.rs patient/Procedure.rs patient/Provenance.rs
|
43
|
+
patient/PractitionerRole.rs
|
44
|
+
).gsub(/\s{2,}/, ' ').strip
|
45
|
+
},
|
46
|
+
url: {
|
47
|
+
title: 'Public Launch FHIR Endpoint',
|
48
|
+
description: 'URL of the FHIR endpoint used by standalone applications'
|
49
|
+
},
|
50
|
+
code: {
|
51
|
+
name: :public_code
|
52
|
+
},
|
53
|
+
state: {
|
54
|
+
name: :public_state
|
55
|
+
},
|
56
|
+
smart_authorization_url: {
|
57
|
+
title: 'OAuth 2.0 Authorize Endpoint',
|
58
|
+
description: 'OAuth 2.0 Authorize Endpoint provided during the patient standalone launch'
|
59
|
+
},
|
60
|
+
smart_token_url: {
|
61
|
+
title: 'OAuth 2.0 Token Endpoint',
|
62
|
+
description: 'OAuth 2.0 Token Endpoint provided during the patient standalone launch'
|
63
|
+
},
|
64
|
+
smart_credentials: {
|
65
|
+
name: :public_smart_credentials
|
66
|
+
},
|
67
|
+
use_pkce: {
|
68
|
+
default: 'true',
|
69
|
+
locked: true
|
70
|
+
},
|
71
|
+
pkce_code_challenge_method: {
|
72
|
+
locked: true
|
73
|
+
}
|
74
|
+
},
|
75
|
+
outputs: {
|
76
|
+
code: { name: :public_code },
|
77
|
+
token_retrieval_time: { name: :public_token_retrieval_time },
|
78
|
+
state: { name: :public_state },
|
79
|
+
id_token: { name: :public_id_token },
|
80
|
+
refresh_token: { name: :public_refresh_token },
|
81
|
+
access_token: { name: :public_access_token },
|
82
|
+
expires_in: { name: :public_expires_in },
|
83
|
+
patient_id: { name: :public_patient_id },
|
84
|
+
encounter_id: { name: :public_encounter_id },
|
85
|
+
received_scopes: { name: :public_received_scopes },
|
86
|
+
intent: { name: :public_intent },
|
87
|
+
smart_credentials: { name: :public_smart_credentials }
|
88
|
+
},
|
89
|
+
requests: {
|
90
|
+
redirect: { name: :public_redirect },
|
91
|
+
token: { name: :public_token }
|
92
|
+
}
|
93
|
+
)
|
94
|
+
|
95
|
+
input_order :url,
|
96
|
+
:public_client_id,
|
97
|
+
:public_client_secret,
|
98
|
+
:public_requested_scopes,
|
99
|
+
:use_pkce,
|
100
|
+
:pkce_code_challenge_method,
|
101
|
+
:smart_authorization_url,
|
102
|
+
:smart_token_url
|
103
|
+
|
104
|
+
test from: :g10_patient_context,
|
105
|
+
config: {
|
106
|
+
inputs: {
|
107
|
+
patient_id: { name: :public_patient_id },
|
108
|
+
smart_credentials: { name: :public_smart_credentials }
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
test do
|
113
|
+
title 'OAuth token exchange response contains OpenID Connect id_token'
|
114
|
+
description %(
|
115
|
+
This test requires that an OpenID Connect id_token is provided to
|
116
|
+
demonstrate authentication capabilies for public clients.
|
117
|
+
)
|
118
|
+
id :g10_public_launch_id_token
|
119
|
+
|
120
|
+
input :id_token,
|
121
|
+
name: :public_id_token,
|
122
|
+
locked: true,
|
123
|
+
optional: true
|
124
|
+
|
125
|
+
run do
|
126
|
+
assert id_token.present?, 'Token response did not provide an id_token as required.'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|