udap_security_test_kit 0.11.4 → 0.11.6

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/lib/udap_security_test_kit/authorization_code_received_test.rb +8 -0
  3. data/lib/udap_security_test_kit/authorization_code_redirect_test.rb +3 -0
  4. data/lib/udap_security_test_kit/authorization_code_token_exchange_test.rb +2 -0
  5. data/lib/udap_security_test_kit/authorization_endpoint_field_test.rb +5 -1
  6. data/lib/udap_security_test_kit/client_suite/access_ac_group.rb +2 -0
  7. data/lib/udap_security_test_kit/client_suite/authorization_request_verification_test.rb +5 -0
  8. data/lib/udap_security_test_kit/client_suite/registration_ac_verification_test.rb +34 -0
  9. data/lib/udap_security_test_kit/client_suite/registration_cc_verification_test.rb +30 -0
  10. data/lib/udap_security_test_kit/client_suite/token_request_ac_verification_test.rb +47 -0
  11. data/lib/udap_security_test_kit/client_suite/token_request_cc_verification_test.rb +25 -0
  12. data/lib/udap_security_test_kit/client_suite.rb +10 -0
  13. data/lib/udap_security_test_kit/discovery_group.rb +2 -0
  14. data/lib/udap_security_test_kit/dynamic_client_registration_group.rb +3 -0
  15. data/lib/udap_security_test_kit/endpoints/mock_udap_server/introspection_endpoint.rb +34 -0
  16. data/lib/udap_security_test_kit/endpoints/mock_udap_server/udap_introspection_response_creation.rb +71 -0
  17. data/lib/udap_security_test_kit/endpoints/mock_udap_server.rb +8 -5
  18. data/lib/udap_security_test_kit/grant_types_supported_field_test.rb +3 -0
  19. data/lib/udap_security_test_kit/reg_endpoint_jwt_signing_alg_values_supported_field_test.rb +6 -0
  20. data/lib/udap_security_test_kit/registration_endpoint_field_test.rb +3 -0
  21. data/lib/udap_security_test_kit/registration_failure_invalid_contents_test.rb +3 -0
  22. data/lib/udap_security_test_kit/registration_failure_invalid_jwt_signature_test.rb +2 -0
  23. data/lib/udap_security_test_kit/registration_success_contents_test.rb +3 -0
  24. data/lib/udap_security_test_kit/registration_success_test.rb +3 -0
  25. data/lib/udap_security_test_kit/requirements/generated/udap_security_client_requirements_coverage.csv +146 -0
  26. data/lib/udap_security_test_kit/requirements/generated/udap_security_requirements_coverage.csv +164 -0
  27. data/lib/udap_security_test_kit/requirements/hl7.fhir.us.udap-security_1.0.0_reqs.xlsx +0 -0
  28. data/lib/udap_security_test_kit/requirements/udap_security_test_kit_requirements.csv +308 -0
  29. data/lib/udap_security_test_kit/signed_metadata_contents_test.rb +17 -0
  30. data/lib/udap_security_test_kit/signed_metadata_field_test.rb +4 -1
  31. data/lib/udap_security_test_kit/tags.rb +1 -0
  32. data/lib/udap_security_test_kit/token_endpoint_auth_methods_supported_field_test.rb +2 -0
  33. data/lib/udap_security_test_kit/token_endpoint_auth_signing_alg_values_supported_field_test.rb +5 -0
  34. data/lib/udap_security_test_kit/token_endpoint_field_test.rb +3 -0
  35. data/lib/udap_security_test_kit/udap_auth_extensions_required_field_test.rb +3 -0
  36. data/lib/udap_security_test_kit/udap_auth_extensions_supported_field_test.rb +3 -0
  37. data/lib/udap_security_test_kit/udap_certifications_required_field_test.rb +3 -0
  38. data/lib/udap_security_test_kit/udap_certifications_supported_field_test.rb +2 -0
  39. data/lib/udap_security_test_kit/udap_profiles_supported_field_test.rb +5 -0
  40. data/lib/udap_security_test_kit/udap_versions_supported_field_test.rb +2 -0
  41. data/lib/udap_security_test_kit/urls.rb +5 -0
  42. data/lib/udap_security_test_kit/version.rb +2 -2
  43. data/lib/udap_security_test_kit/well_known_endpoint_test.rb +4 -0
  44. data/lib/udap_security_test_kit.rb +8 -0
  45. metadata +10 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 93cc168a29a41ac4c22bdcb8a4124aa85c370d3a0ae8ac1851090555ab3a2e8b
4
- data.tar.gz: d31eee97042a453fe3ccf6c72c1421309ff4d367eb87ff6d2f3a63a96529041d
3
+ metadata.gz: ba9b8ab76dbc1af4171a44facc2bad0501b87d408914b1112211b4a6dd407972
4
+ data.tar.gz: ab96e3353c18cb382f24051c0d97869d7bd211ec21827f1389c1703f7f1827a2
5
5
  SHA512:
6
- metadata.gz: 69293481ba6a4edeca09cf992cd7b7ff97ff380636a43e1d40cb6dd2610711bb1feac263cdf887fbb7e74e8c72ed15329335b8d3b4fdd3a4d3ed1f3f73341eef
7
- data.tar.gz: 90878299bfb40e53ad43ff65144d008f3793a1654c8f61ff3dd24a4a8cb6f3dcef11c092cac49ccdadb7dec165ed20134213cc56a566b8e78792e0b83c6ca872
6
+ metadata.gz: 8901c4441f4dbc98ba53a1babdcb1bbdef421c52457627266e5faaa6602f88df692b58b1d7f788d079374bd8419a46564cf4e0a2edcf7bb67a3e9ee15a7459bb
7
+ data.tar.gz: 1de972b29f3c1c0ef84273d707420c379f16a9d30b9340f78b0fae573a452ad50cab6e6b5db7a3cf5497e965f7fe8aed424a0f20770c472895ed80dd9658b727
@@ -9,12 +9,20 @@ module UDAPSecurityTestKit
9
9
  output :udap_authorization_code
10
10
  uses_request :redirect
11
11
 
12
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@133',
13
+ 'hl7.fhir.us.udap-security_1.0.0@134',
14
+ 'hl7.fhir.us.udap-security_1.0.0@138',
15
+ 'hl7.fhir.us.udap-security_1.0.0@190'
16
+
12
17
  run do
13
18
  code = request.query_parameters['code']
14
19
  output udap_authorization_code: code
15
20
 
16
21
  assert code.present?, 'No `code` parameter received'
17
22
 
23
+ state = request.query_parameters['state']
24
+ assert state.present?, '`state` parameter is required since it was present in client request'
25
+
18
26
  error = request.query_parameters['error']
19
27
 
20
28
  pass_if error.blank?
@@ -52,6 +52,9 @@ module UDAPSecurityTestKit
52
52
 
53
53
  receives_request :redirect
54
54
 
55
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@133',
56
+ 'hl7.fhir.us.udap-security_1.0.0@190'
57
+
55
58
  config options: {
56
59
  redirect_uri: UDAPSecurityTestKit::UDAP_REDIRECT_URI
57
60
  }
@@ -62,6 +62,8 @@ module UDAPSecurityTestKit
62
62
 
63
63
  makes_request :token_exchange
64
64
 
65
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@148'
66
+
65
67
  run do
66
68
  client_assertion_payload = UDAPClientAssertionPayloadBuilder.build(
67
69
  udap_client_id,
@@ -13,6 +13,10 @@ module UDAPSecurityTestKit
13
13
  input :udap_well_known_metadata_json
14
14
  output :udap_authorization_endpoint
15
15
 
16
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@9',
17
+ 'hl7.fhir.us.udap-security_1.0.0@38',
18
+ 'hl7.fhir.us.udap-security_1.0.0@39'
19
+
16
20
  run do
17
21
  assert_valid_json(udap_well_known_metadata_json)
18
22
  config = JSON.parse(udap_well_known_metadata_json)
@@ -29,7 +33,7 @@ module UDAPSecurityTestKit
29
33
  '`authorization_endpoint` field is only required if `authorization_code` is a supported grant type'
30
34
 
31
35
  assert config.key?('authorization_endpoint'),
32
- '`authorization_endpoint` field is required if `authorization_endpoint` is a supported grant type'
36
+ '`authorization_endpoint` field is required if `authorization_code` is a supported grant type'
33
37
 
34
38
  endpoint = config['authorization_endpoint']
35
39
 
@@ -17,6 +17,8 @@ module UDAPSecurityTestKit
17
17
 
18
18
  run_as_group
19
19
 
20
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@126'
21
+
20
22
  test from: :udap_client_access_ac_interaction
21
23
  test from: :udap_client_authorization_request_verification
22
24
  test from: :udap_client_token_request_ac_verification
@@ -24,6 +24,11 @@ module UDAPSecurityTestKit
24
24
  locked: 'true',
25
25
  description: INPUT_UDAP_REGISTRATION_JWT_DESCRIPTION_LOCKED
26
26
 
27
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@67',
28
+ 'hl7.fhir.us.udap-security_1.0.0@127',
29
+ 'hl7.fhir.us.udap-security_1.0.0@128',
30
+ 'hl7.fhir.us.udap-security_1.0.0@129'
31
+
27
32
  def client_suite_id
28
33
  return config.options[:endpoint_suite_id] if config.options[:endpoint_suite_id].present?
29
34
 
@@ -17,6 +17,40 @@ module UDAPSecurityTestKit
17
17
  input :udap_client_uri
18
18
  output :udap_registration_jwt
19
19
 
20
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@1',
21
+ 'hl7.fhir.us.udap-security_1.0.0@2',
22
+ 'hl7.fhir.us.udap-security_1.0.0@3',
23
+ 'hl7.fhir.us.udap-security_1.0.0@7',
24
+ 'hl7.fhir.us.udap-security_1.0.0@8',
25
+ 'hl7.fhir.us.udap-security_1.0.0@66',
26
+ 'hl7.fhir.us.udap-security_1.0.0@71',
27
+ 'hl7.fhir.us.udap-security_1.0.0@72',
28
+ 'hl7.fhir.us.udap-security_1.0.0@73',
29
+ 'hl7.fhir.us.udap-security_1.0.0@74',
30
+ 'hl7.fhir.us.udap-security_1.0.0@75',
31
+ 'hl7.fhir.us.udap-security_1.0.0@76',
32
+ 'hl7.fhir.us.udap-security_1.0.0@77',
33
+ 'hl7.fhir.us.udap-security_1.0.0@78',
34
+ 'hl7.fhir.us.udap-security_1.0.0@79',
35
+ 'hl7.fhir.us.udap-security_1.0.0@80',
36
+ 'hl7.fhir.us.udap-security_1.0.0@81',
37
+ 'hl7.fhir.us.udap-security_1.0.0@83',
38
+ 'hl7.fhir.us.udap-security_1.0.0@84',
39
+ 'hl7.fhir.us.udap-security_1.0.0@86',
40
+ 'hl7.fhir.us.udap-security_1.0.0@87',
41
+ 'hl7.fhir.us.udap-security_1.0.0@88',
42
+ 'hl7.fhir.us.udap-security_1.0.0@90',
43
+ 'hl7.fhir.us.udap-security_1.0.0@91',
44
+ 'hl7.fhir.us.udap-security_1.0.0@92',
45
+ 'hl7.fhir.us.udap-security_1.0.0@93',
46
+ 'hl7.fhir.us.udap-security_1.0.0@94',
47
+ 'hl7.fhir.us.udap-security_1.0.0@96',
48
+ 'hl7.fhir.us.udap-security_1.0.0@97',
49
+ 'hl7.fhir.us.udap-security_1.0.0@101',
50
+ 'hl7.fhir.us.udap-security_1.0.0@102',
51
+ 'hl7.fhir.us.udap-security_1.0.0@103',
52
+ 'hl7.fhir.us.udap-security_1.0.0@104'
53
+
20
54
  def client_suite_id
21
55
  return config.options[:endpoint_suite_id] if config.options[:endpoint_suite_id].present?
22
56
 
@@ -23,6 +23,36 @@ module UDAPSecurityTestKit
23
23
  UDAPSecurityTestKit::UDAPSecurityClientTestSuite.id
24
24
  end
25
25
 
26
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@1',
27
+ 'hl7.fhir.us.udap-security_1.0.0@2',
28
+ 'hl7.fhir.us.udap-security_1.0.0@3',
29
+ 'hl7.fhir.us.udap-security_1.0.0@7',
30
+ 'hl7.fhir.us.udap-security_1.0.0@8',
31
+ 'hl7.fhir.us.udap-security_1.0.0@66',
32
+ 'hl7.fhir.us.udap-security_1.0.0@71',
33
+ 'hl7.fhir.us.udap-security_1.0.0@72',
34
+ 'hl7.fhir.us.udap-security_1.0.0@73',
35
+ 'hl7.fhir.us.udap-security_1.0.0@74',
36
+ 'hl7.fhir.us.udap-security_1.0.0@75',
37
+ 'hl7.fhir.us.udap-security_1.0.0@76',
38
+ 'hl7.fhir.us.udap-security_1.0.0@77',
39
+ 'hl7.fhir.us.udap-security_1.0.0@78',
40
+ 'hl7.fhir.us.udap-security_1.0.0@79',
41
+ 'hl7.fhir.us.udap-security_1.0.0@80',
42
+ 'hl7.fhir.us.udap-security_1.0.0@81',
43
+ 'hl7.fhir.us.udap-security_1.0.0@83',
44
+ 'hl7.fhir.us.udap-security_1.0.0@85',
45
+ 'hl7.fhir.us.udap-security_1.0.0@86',
46
+ 'hl7.fhir.us.udap-security_1.0.0@87',
47
+ 'hl7.fhir.us.udap-security_1.0.0@92',
48
+ 'hl7.fhir.us.udap-security_1.0.0@95',
49
+ 'hl7.fhir.us.udap-security_1.0.0@96',
50
+ 'hl7.fhir.us.udap-security_1.0.0@97',
51
+ 'hl7.fhir.us.udap-security_1.0.0@101',
52
+ 'hl7.fhir.us.udap-security_1.0.0@102',
53
+ 'hl7.fhir.us.udap-security_1.0.0@103',
54
+ 'hl7.fhir.us.udap-security_1.0.0@104'
55
+
26
56
  run do
27
57
  client_registration_requests = load_registration_requests_for_client_uri(udap_client_uri)
28
58
  skip_if client_registration_requests.empty?,
@@ -28,6 +28,53 @@ module UDAPSecurityTestKit
28
28
  description: INPUT_UDAP_REGISTRATION_JWT_DESCRIPTION_LOCKED
29
29
  output :udap_tokens
30
30
 
31
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@1',
32
+ 'hl7.fhir.us.udap-security_1.0.0@2',
33
+ 'hl7.fhir.us.udap-security_1.0.0@3',
34
+ 'hl7.fhir.us.udap-security_1.0.0@7',
35
+ 'hl7.fhir.us.udap-security_1.0.0@8',
36
+ 'hl7.fhir.us.udap-security_1.0.0@67',
37
+ 'hl7.fhir.us.udap-security_1.0.0@69',
38
+ 'hl7.fhir.us.udap-security_1.0.0@140',
39
+ 'hl7.fhir.us.udap-security_1.0.0@141',
40
+ 'hl7.fhir.us.udap-security_1.0.0@142',
41
+ 'hl7.fhir.us.udap-security_1.0.0@143',
42
+ 'hl7.fhir.us.udap-security_1.0.0@145',
43
+ 'hl7.fhir.us.udap-security_1.0.0@151',
44
+ 'hl7.fhir.us.udap-security_1.0.0@152',
45
+ 'hl7.fhir.us.udap-security_1.0.0@153',
46
+ 'hl7.fhir.us.udap-security_1.0.0@154',
47
+ 'hl7.fhir.us.udap-security_1.0.0@155',
48
+ 'hl7.fhir.us.udap-security_1.0.0@156',
49
+ 'hl7.fhir.us.udap-security_1.0.0@157',
50
+ 'hl7.fhir.us.udap-security_1.0.0@158',
51
+ 'hl7.fhir.us.udap-security_1.0.0@160',
52
+ 'hl7.fhir.us.udap-security_1.0.0@161',
53
+ 'hl7.fhir.us.udap-security_1.0.0@163',
54
+ 'hl7.fhir.us.udap-security_1.0.0@165',
55
+ 'hl7.fhir.us.udap-security_1.0.0@166',
56
+ 'hl7.fhir.us.udap-security_1.0.0@167',
57
+ 'hl7.fhir.us.udap-security_1.0.0@168',
58
+ 'hl7.fhir.us.udap-security_1.0.0@169',
59
+ 'hl7.fhir.us.udap-security_1.0.0@170',
60
+ 'hl7.fhir.us.udap-security_1.0.0@171',
61
+ 'hl7.fhir.us.udap-security_1.0.0@175',
62
+ 'hl7.fhir.us.udap-security_1.0.0@177',
63
+ 'hl7.fhir.us.udap-security_1.0.0@178',
64
+ 'hl7.fhir.us.udap-security_1.0.0@179',
65
+ 'hl7.fhir.us.udap-security_1.0.0@180',
66
+ 'hl7.fhir.us.udap-security_1.0.0@185',
67
+ 'hl7.fhir.us.udap-security_1.0.0@192',
68
+ 'hl7.fhir.us.udap-security_1.0.0@193',
69
+ 'hl7.fhir.us.udap-security_1.0.0@194',
70
+ 'hl7.fhir.us.udap-security_1.0.0@195',
71
+ 'hl7.fhir.us.udap-security_1.0.0@196',
72
+ 'hl7.fhir.us.udap-security_1.0.0@197',
73
+ 'hl7.fhir.us.udap-security_1.0.0@222',
74
+ 'hl7.fhir.us.udap-security_1.0.0@232',
75
+ 'hl7.fhir.us.udap-security_1.0.0@233',
76
+ 'hl7.fhir.us.udap-security_1.0.0@234'
77
+
31
78
  def client_suite_id
32
79
  return config.options[:endpoint_suite_id] if config.options[:endpoint_suite_id].present?
33
80
 
@@ -28,6 +28,31 @@ module UDAPSecurityTestKit
28
28
  description: INPUT_UDAP_REGISTRATION_JWT_DESCRIPTION_LOCKED
29
29
  output :udap_tokens
30
30
 
31
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@1',
32
+ 'hl7.fhir.us.udap-security_1.0.0@2',
33
+ 'hl7.fhir.us.udap-security_1.0.0@3',
34
+ 'hl7.fhir.us.udap-security_1.0.0@7',
35
+ 'hl7.fhir.us.udap-security_1.0.0@8',
36
+ 'hl7.fhir.us.udap-security_1.0.0@67',
37
+ 'hl7.fhir.us.udap-security_1.0.0@69',
38
+ 'hl7.fhir.us.udap-security_1.0.0@186',
39
+ 'hl7.fhir.us.udap-security_1.0.0@192',
40
+ 'hl7.fhir.us.udap-security_1.0.0@193',
41
+ 'hl7.fhir.us.udap-security_1.0.0@194',
42
+ 'hl7.fhir.us.udap-security_1.0.0@195',
43
+ 'hl7.fhir.us.udap-security_1.0.0@196',
44
+ 'hl7.fhir.us.udap-security_1.0.0@197',
45
+ 'hl7.fhir.us.udap-security_1.0.0@198',
46
+ 'hl7.fhir.us.udap-security_1.0.0@202',
47
+ 'hl7.fhir.us.udap-security_1.0.0@212',
48
+ 'hl7.fhir.us.udap-security_1.0.0@214',
49
+ 'hl7.fhir.us.udap-security_1.0.0@215',
50
+ 'hl7.fhir.us.udap-security_1.0.0@223',
51
+ 'hl7.fhir.us.udap-security_1.0.0@225',
52
+ 'hl7.fhir.us.udap-security_1.0.0@226',
53
+ 'hl7.fhir.us.udap-security_1.0.0@227',
54
+ 'hl7.fhir.us.udap-security_1.0.0@228'
55
+
31
56
  def client_suite_id
32
57
  return config.options[:endpoint_suite_id] if config.options[:endpoint_suite_id].present?
33
58
 
@@ -1,6 +1,7 @@
1
1
  require_relative 'endpoints/mock_udap_server/registration_endpoint'
2
2
  require_relative 'endpoints/mock_udap_server/authorization_endpoint'
3
3
  require_relative 'endpoints/mock_udap_server/token_endpoint'
4
+ require_relative 'endpoints/mock_udap_server/introspection_endpoint'
4
5
  require_relative 'endpoints/echoing_fhir_responder_endpoint'
5
6
  require_relative 'urls'
6
7
  require_relative 'client_suite/registration_ac_group'
@@ -14,6 +15,14 @@ module UDAPSecurityTestKit
14
15
  title 'UDAP Security Client'
15
16
  description File.read(File.join(__dir__, 'docs', 'udap_client_suite_description.md'))
16
17
 
18
+ requirement_sets(
19
+ {
20
+ identifier: 'hl7.fhir.us.udap-security_1.0.0',
21
+ title: 'Security for Scalable Registration, Authentication, and Authorization (UDAP)',
22
+ actor: 'Client'
23
+ }
24
+ )
25
+
17
26
  links [
18
27
  {
19
28
  type: 'source_code',
@@ -61,6 +70,7 @@ module UDAPSecurityTestKit
61
70
  suite_endpoint :post, REGISTRATION_PATH, MockUDAPServer::RegistrationEndpoint
62
71
  suite_endpoint :get, AUTHORIZATION_PATH, MockUDAPServer::AuthorizationEndpoint
63
72
  suite_endpoint :post, AUTHORIZATION_PATH, MockUDAPServer::AuthorizationEndpoint
73
+ suite_endpoint :post, INTROSPECTION_PATH, MockUDAPServer::IntrospectionEndpoint
64
74
  suite_endpoint :post, TOKEN_PATH, MockUDAPServer::TokenEndpoint
65
75
  suite_endpoint :get, FHIR_PATH, EchoingFHIRResponderEndpoint
66
76
  suite_endpoint :post, FHIR_PATH, EchoingFHIRResponderEndpoint
@@ -61,6 +61,8 @@ module UDAPSecurityTestKit
61
61
  output :udap_registration_endpoint
62
62
  output :udap_registration_grant_type
63
63
 
64
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@15'
65
+
64
66
  test from: :udap_well_known_endpoint
65
67
  test from: :udap_versions_supported_field
66
68
  test from: :udap_grant_types_supported_field
@@ -141,6 +141,9 @@ module UDAPSecurityTestKit
141
141
  type: 'textarea',
142
142
  optional: true
143
143
 
144
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@68',
145
+ 'hl7.fhir.us.udap-security_1.0.0@105'
146
+
144
147
  test from: :udap_registration_failure_invalid_contents
145
148
  test from: :udap_registration_failure_invalid_jwt_signature
146
149
  test from: :udap_registration_success
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../tags'
4
+ require_relative '../mock_udap_server'
5
+ require_relative 'udap_introspection_response_creation'
6
+
7
+ module UDAPSecurityTestKit
8
+ module MockUDAPServer
9
+ class IntrospectionEndpoint < Inferno::DSL::SuiteEndpoint
10
+ include UDAPIntrospectionResponseCreation
11
+
12
+ def test_run_identifier
13
+ MockUDAPServer.issued_token_to_client_id(request.params[:token])
14
+ end
15
+
16
+ def make_response
17
+ response.body = make_udap_introspection_response.to_json
18
+ response.headers['Cache-Control'] = 'no-store'
19
+ response.headers['Pragma'] = 'no-cache'
20
+ response.headers['Access-Control-Allow-Origin'] = '*'
21
+ response.content_type = 'application/json'
22
+ response.status = 200
23
+ end
24
+
25
+ def update_result
26
+ nil # never update for now
27
+ end
28
+
29
+ def tags
30
+ [INTROSPECTION_TAG, UDAP_TAG]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,71 @@
1
+ require_relative '../../tags'
2
+ require_relative '../mock_udap_server'
3
+
4
+ module UDAPSecurityTestKit
5
+ module MockUDAPServer
6
+ module UDAPIntrospectionResponseCreation
7
+ def make_udap_introspection_response # rubocop:disable Metrics/CyclomaticComplexity
8
+ target_token = request.params[:token]
9
+ introspection_inactive_response_body = { active: false }
10
+
11
+ return introspection_inactive_response_body if MockUDAPServer.token_expired?(target_token)
12
+
13
+ token_requests = Inferno::Repositories::Requests.new.tagged_requests(test_run.test_session_id, [TOKEN_TAG])
14
+ original_response_body = nil
15
+ original_token_request = token_requests.find do |request|
16
+ next unless request.status == 200
17
+
18
+ original_response_body = JSON.parse(request.response_body)
19
+ original_response_body['access_token'] == target_token
20
+ end
21
+ return introspection_inactive_response_body unless original_token_request.present?
22
+
23
+ decoded_token = MockUDAPServer.decode_token(target_token)
24
+ introspection_active_response_body = {
25
+ active: true,
26
+ client_id: decoded_token['client_id'],
27
+ exp: decoded_token['expiration']
28
+ }
29
+ original_response_body.each do |element, value|
30
+ next if ['access_token', 'refresh_token', 'token_type', 'expires_in'].include?(element)
31
+ next if introspection_active_response_body.key?(element)
32
+
33
+ introspection_active_response_body[element] = value
34
+ end
35
+ unless introspection_active_response_body.key?('scope')
36
+ introspection_active_response_body['scope'] = requested_scope(original_token_request)
37
+ end
38
+ if original_response_body.key?('id_token')
39
+ user_claims, _header = JWT.decode(original_response_body['id_token'], nil, false)
40
+ introspection_active_response_body['iss'] = user_claims['iss']
41
+ introspection_active_response_body['sub'] = user_claims['sub']
42
+ introspection_active_response_body['fhirUser'] = user_claims['fhirUser'] if user_claims['fhirUser'].present?
43
+ end
44
+
45
+ introspection_active_response_body
46
+ end
47
+
48
+ def requested_scope(token_request)
49
+ # token request
50
+ original_request_body = Rack::Utils.parse_query(token_request.request_body)
51
+ return original_request_body['scope'] if original_request_body['scope'].present?
52
+
53
+ # authorization request
54
+ authorization_request = MockUDAPServer.authorization_request_for_code(original_request_body['code'],
55
+ test_run.test_session_id)
56
+ auth_code_request_inputs = MockUDAPServer.authorization_code_request_details(authorization_request)
57
+ return auth_code_request_inputs['scope'] if auth_code_request_inputs&.dig('scope').present?
58
+
59
+ # registration request
60
+ # not looking in registration response since the simulation currently echoes the requested scopes
61
+ registered_software_statement = MockUDAPServer.udap_registration_software_statement(test_run.test_session_id)
62
+ if registered_software_statement.present?
63
+ registration_body, _registration_header = JWT.decode(registered_software_statement, nil, false)
64
+ return registration_body['scope'] if registration_body['scope'].present?
65
+ end
66
+
67
+ nil
68
+ end
69
+ end
70
+ end
71
+ end
@@ -29,6 +29,7 @@ module UDAPSecurityTestKit
29
29
  token_endpoint: base_url + TOKEN_PATH,
30
30
  token_endpoint_auth_methods_supported: ['private_key_jwt'],
31
31
  token_endpoint_auth_signing_alg_values_supported: ['RS256', 'RS384', 'ES384'],
32
+ introspection_endpoint: base_url + INTROSPECTION_PATH,
32
33
  signed_metadata: udap_signed_metadata_jwt(base_url)
33
34
  }.to_json
34
35
 
@@ -158,15 +159,15 @@ module UDAPSecurityTestKit
158
159
 
159
160
  def decode_token(token)
160
161
  token_to_decode =
161
- if issued_token_is_refresh_token(token)
162
+ if issued_token_is_refresh_token?(token)
162
163
  refresh_token_to_authorization_code(token)
163
164
  else
164
165
  token
165
166
  end
166
167
  return unless token_to_decode.present?
167
168
 
168
- JSON.parse(Base64.urlsafe_decode64(token))
169
- rescue JSON::ParserError
169
+ JSON.parse(Base64.urlsafe_decode64(token_to_decode))
170
+ rescue StandardError
170
171
  nil
171
172
  end
172
173
 
@@ -174,7 +175,7 @@ module UDAPSecurityTestKit
174
175
  decode_token(token)&.dig('client_id')
175
176
  end
176
177
 
177
- def issued_token_is_refresh_token(token)
178
+ def issued_token_is_refresh_token?(token)
178
179
  token.end_with?('_rt')
179
180
  end
180
181
 
@@ -206,7 +207,7 @@ module UDAPSecurityTestKit
206
207
  response.format = :json
207
208
  response.body = FHIR::OperationOutcome.new(
208
209
  issue: FHIR::OperationOutcome::Issue.new(severity: 'fatal', code: 'expired',
209
- details: FHIR::CodeableConcept.new(text: "#{type}has expired"))
210
+ details: FHIR::CodeableConcept.new(text: "#{type} has expired"))
210
211
  ).to_json
211
212
  end
212
213
 
@@ -372,6 +373,8 @@ module UDAPSecurityTestKit
372
373
  end
373
374
 
374
375
  def authorization_code_request_details(inferno_request)
376
+ return unless inferno_request.present?
377
+
375
378
  if inferno_request.verb.downcase == 'get'
376
379
  Rack::Utils.parse_query(URI(inferno_request.url)&.query)
377
380
  elsif inferno_request.verb.downcase == 'post'
@@ -13,6 +13,9 @@ module UDAPSecurityTestKit
13
13
  input :required_flow_type
14
14
  output :udap_registration_grant_type
15
15
 
16
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@36',
17
+ 'hl7.fhir.us.udap-security_1.0.0@37'
18
+
16
19
  run do
17
20
  assert_valid_json(udap_well_known_metadata_json)
18
21
  config = JSON.parse(udap_well_known_metadata_json)
@@ -16,6 +16,9 @@ module UDAPSecurityTestKit
16
16
 
17
17
  input :udap_well_known_metadata_json
18
18
 
19
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@4',
20
+ 'hl7.fhir.us.udap-security_1.0.0@45'
21
+
19
22
  run do
20
23
  assert_valid_json(udap_well_known_metadata_json)
21
24
  config = JSON.parse(udap_well_known_metadata_json)
@@ -24,6 +27,9 @@ module UDAPSecurityTestKit
24
27
  '`registration_endpoint_jwt_signing_alg_values_supported` field is recommended but not required'
25
28
 
26
29
  CommonAssertions.assert_array_of_strings(config, 'registration_endpoint_jwt_signing_alg_values_supported')
30
+
31
+ assert config['registration_endpoint_jwt_signing_alg_values_supported'].include?('RS256'),
32
+ 'All UDAP implementations must support RS256 signature algorithm'
27
33
  end
28
34
  end
29
35
  end
@@ -12,6 +12,9 @@ module UDAPSecurityTestKit
12
12
  input :udap_well_known_metadata_json
13
13
  output :udap_registration_endpoint
14
14
 
15
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@11',
16
+ 'hl7.fhir.us.udap-security_1.0.0@43'
17
+
15
18
  run do
16
19
  assert_valid_json(udap_well_known_metadata_json)
17
20
  config = JSON.parse(udap_well_known_metadata_json)
@@ -35,6 +35,9 @@ module UDAPSecurityTestKit
35
35
  input :udap_registration_certifications,
36
36
  optional: true
37
37
 
38
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@106',
39
+ 'hl7.fhir.us.udap-security_1.0.0@114'
40
+
38
41
  run do
39
42
  software_statement_payload = SoftwareStatementBuilder.build_payload(
40
43
  'invalid_iss',
@@ -36,6 +36,8 @@ module UDAPSecurityTestKit
36
36
  input :udap_registration_certifications,
37
37
  optional: true
38
38
 
39
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@114'
40
+
39
41
  run do
40
42
  software_statement_payload = SoftwareStatementBuilder.build_payload(
41
43
  udap_cert_iss,
@@ -43,6 +43,9 @@ module UDAPSecurityTestKit
43
43
 
44
44
  output :udap_client_id
45
45
 
46
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@111',
47
+ 'hl7.fhir.us.udap-security_1.0.0@113'
48
+
46
49
  run do
47
50
  assert_valid_json(udap_registration_response)
48
51
  registration_response = JSON.parse(udap_registration_response)
@@ -39,6 +39,9 @@ module UDAPSecurityTestKit
39
39
  output :udap_software_statement_json
40
40
  output :udap_registration_response
41
41
 
42
+ verifies_requirements 'hl7.fhir.us.udap-security_1.0.0@110',
43
+ 'hl7.fhir.us.udap-security_1.0.0@119'
44
+
42
45
  run do
43
46
  software_statement_payload = SoftwareStatementBuilder.build_payload(
44
47
  udap_cert_iss,