udap_security_test_kit 0.11.2 → 0.11.4

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/config/presets/UDAP_RunClientAgainstServer.json.erb +20 -0
  3. data/config/presets/UDAP_RunServerAgainstClient.json.erb +272 -0
  4. data/lib/udap_security_test_kit/client_credentials_token_exchange_test.rb +1 -1
  5. data/lib/udap_security_test_kit/client_suite/access_ac_group.rb +25 -0
  6. data/lib/udap_security_test_kit/client_suite/access_ac_interaction_test.rb +59 -0
  7. data/lib/udap_security_test_kit/client_suite/access_cc_group.rb +23 -0
  8. data/lib/udap_security_test_kit/client_suite/access_cc_interaction_test.rb +49 -0
  9. data/lib/udap_security_test_kit/client_suite/authorization_request_verification_test.rb +83 -0
  10. data/lib/udap_security_test_kit/client_suite/client_descriptions.rb +70 -0
  11. data/lib/udap_security_test_kit/client_suite/client_options.rb +20 -0
  12. data/lib/udap_security_test_kit/client_suite/oidc_jwks.json +32 -0
  13. data/lib/udap_security_test_kit/client_suite/oidc_jwks.rb +27 -0
  14. data/lib/udap_security_test_kit/client_suite/registration_ac_group.rb +18 -0
  15. data/lib/udap_security_test_kit/client_suite/registration_ac_verification_test.rb +38 -0
  16. data/lib/udap_security_test_kit/client_suite/registration_cc_group.rb +18 -0
  17. data/lib/udap_security_test_kit/client_suite/registration_cc_verification_test.rb +38 -0
  18. data/lib/udap_security_test_kit/client_suite/registration_interaction_test.rb +57 -0
  19. data/lib/udap_security_test_kit/client_suite/registration_request_verification.rb +242 -0
  20. data/lib/udap_security_test_kit/client_suite/token_request_ac_verification_test.rb +49 -0
  21. data/lib/udap_security_test_kit/client_suite/token_request_cc_verification_test.rb +49 -0
  22. data/lib/udap_security_test_kit/client_suite/token_request_verification.rb +223 -0
  23. data/lib/udap_security_test_kit/client_suite/token_use_verification_test.rb +40 -0
  24. data/lib/udap_security_test_kit/client_suite.rb +107 -0
  25. data/lib/udap_security_test_kit/docs/demo/FHIR Request.postman_collection.json +81 -0
  26. data/lib/udap_security_test_kit/docs/udap_client_suite_description.md +163 -0
  27. data/lib/udap_security_test_kit/endpoints/echoing_fhir_responder_endpoint.rb +96 -0
  28. data/lib/udap_security_test_kit/endpoints/mock_udap_server/authorization_endpoint.rb +28 -0
  29. data/lib/udap_security_test_kit/endpoints/mock_udap_server/registration_endpoint.rb +31 -0
  30. data/lib/udap_security_test_kit/endpoints/mock_udap_server/token_endpoint.rb +56 -0
  31. data/lib/udap_security_test_kit/endpoints/mock_udap_server/udap_authorization_response_creation.rb +63 -0
  32. data/lib/udap_security_test_kit/endpoints/mock_udap_server/udap_registration_response_creation.rb +28 -0
  33. data/lib/udap_security_test_kit/endpoints/mock_udap_server/udap_token_response_creation.rb +218 -0
  34. data/lib/udap_security_test_kit/endpoints/mock_udap_server.rb +382 -0
  35. data/lib/udap_security_test_kit/metadata.rb +4 -4
  36. data/lib/udap_security_test_kit/tags.rb +12 -0
  37. data/lib/udap_security_test_kit/urls.rb +52 -0
  38. data/lib/udap_security_test_kit/version.rb +2 -2
  39. data/lib/udap_security_test_kit.rb +8 -2
  40. metadata +36 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16dcc359a2f590b5427665389f1a4916be275dc2be12a388d8ed7c3a17ee5e7b
4
- data.tar.gz: 9089b5edef3d1a80f0dbf84dc5dee626e40ff04de325170d30a8f310e4b91ab7
3
+ metadata.gz: 93cc168a29a41ac4c22bdcb8a4124aa85c370d3a0ae8ac1851090555ab3a2e8b
4
+ data.tar.gz: d31eee97042a453fe3ccf6c72c1421309ff4d367eb87ff6d2f3a63a96529041d
5
5
  SHA512:
6
- metadata.gz: 201455391e33a8f2e278fa15150fd8882c8dd27562cf7425f965431ad61c8a17d5470da3ae699515b2acd1e1d5c9b736e5c51e45bfad8446a35dafdb490787ce
7
- data.tar.gz: 1abdcaa5303cb9328ce8916aa0bedf766d5c590460246a421619931c60b1b4e9ed7a069946af7c688d3f4d79cc22590946f05bbddae4690d303c8f4b0acba606
6
+ metadata.gz: 69293481ba6a4edeca09cf992cd7b7ff97ff380636a43e1d40cb6dd2610711bb1feac263cdf887fbb7e74e8c72ed15329335b8d3b4fdd3a4d3ed1f3f73341eef
7
+ data.tar.gz: 90878299bfb40e53ad43ff65144d008f3793a1654c8f61ff3dd24a4a8cb6f3dcef11c092cac49ccdadb7dec165ed20134213cc56a566b8e78792e0b83c6ca872
@@ -0,0 +1,20 @@
1
+ {
2
+ "title": "Demo: Run Against the UDAP Security Server Suite",
3
+ "id": "udap_run_client_against_server",
4
+ "test_suite_id": "udap_security_client",
5
+ "inputs": [
6
+ {
7
+ "name": "udap_client_uri",
8
+ "description": "The UDAP Client URI that will be used to register with Inferno's simulated UDAP server.",
9
+ "optional": true,
10
+ "title": "UDAP Client URI",
11
+ "type": "text",
12
+ "value": "<%= Inferno::Application['base_url'] %>/custom/udap_security/fhir"
13
+ },
14
+ {
15
+ "name": "echoed_fhir_response",
16
+ "type": "text",
17
+ "value": "{\n \"resourceType\": \"Patient\",\n \"id\": \"example\",\n \"name\": [\n {\n \"family\": \"Chalmers\",\n \"given\": [\n \"Peter\",\n \"James\"\n ]\n }\n ],\n \"gender\": \"male\",\n \"birthDate\": \"1974-12-25\",\n \"address\": [\n {\n \"line\": [\n \"534 Erewhon St\"\n ],\n \"city\": \"Ann Arbor\",\n \"state\": \"MI\",\n \"postalCode\": \"48108\"\n }\n ]\n}"
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,272 @@
1
+ {
2
+ "title": "Demo: Run Against the UDAP Security Client Suite",
3
+ "id": "udap_run_server_against_client",
4
+ "test_suite_id": "udap_security",
5
+ "inputs": [
6
+ {
7
+ "name": "udap_fhir_base_url",
8
+ "description": "Base FHIR URL of FHIR Server. Discovery request will be sent to {baseURL}/.well-known/udap",
9
+ "title": "FHIR Server Base URL",
10
+ "type": "text",
11
+ "value": "<%= Inferno::Application['base_url'] %>/custom/udap_security_client/fhir"
12
+ },
13
+ {
14
+ "name": "udap_community_parameter",
15
+ "description": "If included, the designated community value will be appended as a query to the well-known endpoint to indicate the client's trust of certificates from this trust community.",
16
+ "optional": true,
17
+ "title": "UDAP Community Parameter",
18
+ "type": "text",
19
+ "value": ""
20
+ },
21
+ {
22
+ "name": "flow_type_auth_code",
23
+ "default": [
24
+ "authorization_code"
25
+ ],
26
+ "description": "Which grant type(s) must be supported per the returned Discovery metadata",
27
+ "locked": true,
28
+ "options": {
29
+ "list_options": [
30
+ {
31
+ "label": "Authorization Code",
32
+ "value": "authorization_code"
33
+ },
34
+ {
35
+ "label": "Client Credentials",
36
+ "value": "client_credentials"
37
+ }
38
+ ]
39
+ },
40
+ "title": "Required OAuth2.0 Flow Type for Authorization Code Workflow",
41
+ "type": "checkbox",
42
+ "value": "[\"authorization_code\"]"
43
+ },
44
+ {
45
+ "name": "udap_server_trust_anchor_certs",
46
+ "description": "A list of one or more trust anchor root CA X.509 certificates, separated by a newline. Inferno will use these to establish trust with the authorization server's certificates provided in the discovery response signed_metadata JWT.",
47
+ "optional": true,
48
+ "title": "Auth Server Trust Anchor X509 Certificate(s) (PEM Format)",
49
+ "type": "textarea",
50
+ "value": "-----BEGIN CERTIFICATE-----\nMIIGDzCCA/egAwIBAgIUHwBisiqxYRNYzDtSvNRPOu09emswDQYJKoZIhvcNAQEL\nBQAwgYYxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNQTEQMA4GA1UEBwwHQmVkZm9y\nZDEQMA4GA1UECgwHSW5mZXJubzEdMBsGA1UEAwwUSW5mZXJuby1VREFQLVJvb3Qt\nQ0ExJzAlBgkqhkiG9w0BCQEWGGluZmVybm9AZ3JvdXBzLm1pdHJlLm9yZzAeFw0y\nNDA4MTIyMzU4MDlaFw0zNDA4MTAyMzU4MDlaMIGGMQswCQYDVQQGEwJVUzELMAkG\nA1UECAwCTUExEDAOBgNVBAcMB0JlZGZvcmQxEDAOBgNVBAoMB0luZmVybm8xHTAb\nBgNVBAMMFEluZmVybm8tVURBUC1Sb290LUNBMScwJQYJKoZIhvcNAQkBFhhpbmZl\ncm5vQGdyb3Vwcy5taXRyZS5vcmcwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK\nAoICAQC3Hz72FU3I4PFztBPpeDX7augTiw5KKMzEQWoOtsyx8de0lXLDaY13SugL\nwCduDei5WYaHat3/eAWnsvGb2VQjQOpfUTvdwnmvUSTAZH+EB+IPy/Jk2AbXtgGv\n8GcLsmjpZNiePvCrcOT28j9tTAdO8gKaIOg0XpYq/Kdyyecr1jMINKgUMOyoi//R\nQjzvx6dRq/YBegb2bEOe+YBUdo7EzAXZUAk48RelAq5b1vaqyhJeuOcxXxVCLjTi\nKN+Tje6FnmQkD/J7P05XlRFvoNxzp5X+92bcrZ+LcOjNy4wTxiT3f76e6DCMHRcM\n3QmhfU3cerv1pvb78peb0bKglzwdmquw+H6+UQrvmaCqCNWnVjmUzB1bgRxAc5YV\np18kHzNnUAoXHMU6+ZVHqvrbtNEBHYI5NUrgOCVBpFCRf53qRtfQjSIfJrKEoKvC\nvidDeW0YWy5FILZ50g+Auo/JvPLVUzm+qENN+y/at3LZx27VEoyZpi18DqbWWYNa\n+QnGow/rEf/fHRUrsTBhgttQ7/VhTr8M6KcsHLpqm7Ec6zPy6MvrFLowXsXWZGNq\nzhEb6YGHi9WzNDcsAILybRm4jDS07/1f1CJ6BJuQrPFDsVo4o0PhCsAWH5MqcL2V\nlKt/kfJxva83JoshB9zFNmtCdfuw/Mkl8i+OO5WR/vqIZNam9wIDAQABo3MwcTAd\nBgNVHQ4EFgQUNOqoPKju4u9y9JAuAfnSAcFbNKAwHwYDVR0jBBgwFoAUNOqoPKju\n4u9y9JAuAfnSAcFbNKAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAYYwEQYD\nVR0gBAowCDAGBgRVHSAAMA0GCSqGSIb3DQEBCwUAA4ICAQCbLfJy6q2r26iyKZ3x\nMNUorDfsiTWH8TspYBm6v3h4yn9U+9qbyBwsjCu0U2ns5VqHzw25jInW5FQbwZZV\nAiUYKNpn6gIWZKpWOaDYaMWB4Jv9BMLLsENkP6PM6XxAheBVj2WNrlXaOaBql7XQ\npkZ9TpX56Vim86Jk999o4idi4CWyaoZHXtwOGyKkOPp0xghg9VAX2y2xLYdBzgSs\nJW9P8+WIeIIbz3mpSlq0Aqh9LjneKW9wfinYEO/IxsMpOqAV54VtWJ9tMZtR8e83\ntNihJuWJvhA2rWXffh1/uPv7uA3Yge/a5vf+VfJn5MoSPn4X8ZRaJMmUFnyyvyzD\nK4fxAV2dCBjOsQtEU4pIWKwS8BopLdOcoM8Wyth+0KpxpCDTPBY0idxqU/Dg0wBe\n8YQ/mAN+cVZy2U0BoXEKlW49+czQ1wKAv4rzDJFTZUTudG+r4LmNFDPXnoiMwhni\nXkgFz1NO4YucWXBestvBSDgQ2BPFF2TkcGZl7bLk+WiGAhA/SxtLvHjIKqXwGYHG\nm8C45sJ7h0h0zdmd3/ImHWRd6D99k5eFyX5O2qNoa6v6w5rRqE7gZCe/0yZVpdth\nhhXWl1vLHPiRE5N+vRgOW1i66Ly2I7WwX965erNDxEgNCvgsP84FjbMs/2Xnb3Be\ntsGvVZ6GCrAl5XejmwQBzyZQQw==\n-----END CERTIFICATE-----\n"
51
+ },
52
+ {
53
+ "name": "udap_auth_code_flow_registration_grant_type",
54
+ "default": "authorization_code",
55
+ "description": "The OAuth2.0 grant type for which this client will register itself. A given client may register as either option, but not both.",
56
+ "locked": true,
57
+ "options": {
58
+ "list_options": [
59
+ {
60
+ "label": "Authorization Code",
61
+ "value": "authorization_code"
62
+ },
63
+ {
64
+ "label": "Client Credentials",
65
+ "value": "client_credentials"
66
+ }
67
+ ]
68
+ },
69
+ "title": "Client Registration Grant Type",
70
+ "type": "radio",
71
+ "value": "authorization_code"
72
+ },
73
+ {
74
+ "name": "udap_auth_code_flow_client_registration_status",
75
+ "default": "new",
76
+ "description": "If the client's iss and certificate combination has already been registered with the authorization server prior to this test run, select 'Update'.",
77
+ "options": {
78
+ "list_options": [
79
+ {
80
+ "label": "New Registration (201 Response Code Expected)",
81
+ "value": "new"
82
+ },
83
+ {
84
+ "label": "Update Registration (200 or 201 Response Code Expected)",
85
+ "value": "update"
86
+ }
87
+ ]
88
+ },
89
+ "title": "Client Registration Status",
90
+ "type": "radio",
91
+ "value": "new"
92
+ },
93
+ {
94
+ "name": "udap_auth_code_flow_client_cert_pem",
95
+ "description": "A list of one or more X.509 certificates in PEM format separated by a newline. The first (leaf) certificate MUST represent the client entity Inferno will register as, and the trust chain that will be built from the provided certificate(s) must resolve to a CA trusted by the authorization server under test.",
96
+ "title": "Authorization Code Client Certificate(s) (PEM Format)",
97
+ "type": "textarea",
98
+ "value": "-----BEGIN CERTIFICATE-----\nMIIFcjCCA1qgAwIBAgIUbdCfB3IJ9bdOPGQVtxJHhMxUWv0wDQYJKoZIhvcNAQEL\nBQAwgYYxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNQTEQMA4GA1UEBwwHQmVkZm9y\nZDEQMA4GA1UECgwHSW5mZXJubzEdMBsGA1UEAwwUSW5mZXJuby1VREFQLVJvb3Qt\nQ0ExJzAlBgkqhkiG9w0BCQEWGGluZmVybm9AZ3JvdXBzLm1pdHJlLm9yZzAeFw0y\nNDA4MTIyMzU4MTBaFw0zNDA4MTAyMzU4MTBaMGExCzAJBgNVBAYTAlVTMQswCQYD\nVQQIDAJNQTEQMA4GA1UEBwwHQmVkZm9yZDEQMA4GA1UECgwHSW5mZXJubzEhMB8G\nA1UEAwwYVURBUCBFeGFtcGxlIFRlc3QgQ2xpZW50MIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEAnfqzJCyeFNRhlcsrUPiO2LQtudObDHUKj4Q7fkYPUf9X\necTMckfPKd8UJ7x8Vb5o1zmR3hsMoo1A7IkwBkmK2BXvxq243cCGO1q4w/jdL/EG\nDiIZjTr7qvkawyeh9cAaApOrBlD4gnOxB05GjingDZgiT7GqBwrpEB2XJ4tw4idS\nB3W9Rv0ynbgqPKgGw9hnEef+uNAvFIvSbfdz1n4xHNP0GuMuAX+edFCyxYFmDe74\n8pl3TH9dxkoM945r5tHmuJS9n1pXkTB9L5RVbqH77dIyOBobehHHpT4D3zjdSFmh\nfta5NnDi5/iqRcFz7FVO79jJIoAqN+mWBlVH0yyfYQIDAQABo4H7MIH4MC8GA1Ud\nEQQoMCaGJGh0dHBzOi8vaW5mZXJuby5jb20vdWRhcF9zZWN1cml0eS9hYzAxBgNV\nHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBDA6\nBgNVHR8EMzAxMC+gLaArhilodHRwczovL2luZmVybm8uY29tL21vY2tfY3JsX2Vu\nZHBvaW50LmNybDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQU6Eo2\nHE37gpSaW9zBGf0t7XfYnfIwHwYDVR0jBBgwFoAUNOqoPKju4u9y9JAuAfnSAcFb\nNKAwDQYJKoZIhvcNAQELBQADggIBACh2uQ1Krkw6F3Gq0HG3ohCm2j1ynmLSJwGE\nHvPlkiBcs8RBPxZzJOZJBMxGmjTPga2Kt6zsBlmjLg++C7C5/8JruwrMtrBuTtHx\nKky0Qw+YJm81IgATeDIU/qkJB8LcnHgkQbu3nyoyeKocx9XSW8nlEm4FkyREXxfC\nrSVCoc70GGg2vSnSkRikNjxwKGnHvmEDUOW2bBbbzvTGKlTKSIF50NiNPM3Fi7vF\nbOfi1aZh6m8IKVaI2KUXVFHco1qB3QDK5BUEimko+EyaWSZPvP83PE2+TIdapRrw\nHxQQJEr774GUNH1/hdW0qlP4u3CMMMAjS2H4dOsRYOOmgC6iEewFEBQqTRLkEfgP\npMxYhGAVAmrglLLr4t+ZF9KOmifvB6f18qF352Bj1D0TMB+oLy67kFw3s2ah21la\n3Xm6hQt+M5mZ/EYZIOUPxMHtqVt5DSJdMENHO2cjcRARyeD/BGYnJqnf6yA1LL2V\nTK+jhC/C/Dcv0hHQnVWlUGlwoFMOOzfsr2K3mXYezAuHASP8LIAyjodPpd6cLQu2\nSZTVVobSebaNmZ2UeX8Bc9bcobM2bbVb2c3UeezEJWOpt5cSOeEScEiwkaktxD5p\nix1K3KkIg2yDP176ILlVqBBA0X2FqTSSvFbTa5us3XIwkDfARJBpLnA7OfmsO61+\nIj5io7+X\n-----END CERTIFICATE-----"
99
+ },
100
+ {
101
+ "name": "udap_auth_code_flow_client_private_key",
102
+ "description": "The private key corresponding to the client certificate used for registration, in PEM format. Used to sign registration and/or authentication JWTs.",
103
+ "title": "Authorization Code Client Private Key (PEM Format)",
104
+ "type": "textarea",
105
+ "value": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCd+rMkLJ4U1GGV\nyytQ+I7YtC2505sMdQqPhDt+Rg9R/1d5xMxyR88p3xQnvHxVvmjXOZHeGwyijUDs\niTAGSYrYFe/GrbjdwIY7WrjD+N0v8QYOIhmNOvuq+RrDJ6H1wBoCk6sGUPiCc7EH\nTkaOKeANmCJPsaoHCukQHZcni3DiJ1IHdb1G/TKduCo8qAbD2GcR5/640C8Ui9Jt\n93PWfjEc0/Qa4y4Bf550ULLFgWYN7vjymXdMf13GSgz3jmvm0ea4lL2fWleRMH0v\nlFVuofvt0jI4Ght6EcelPgPfON1IWaF+1rk2cOLn+KpFwXPsVU7v2MkigCo36ZYG\nVUfTLJ9hAgMBAAECggEAApTpPosYHkEGQztpvs4BD5uKL8I8g2yaOpQvoLWmZHGm\nzU+hA7EWuplxq+CRq5kL/5BqSNXqU/G5AOSRC1lCUpuxKm8GWWFfEDNAV7uGadUn\ngy2de0heeoHNpSjNpcV451fgcJ78IK2hU/w8fPBEQBSfYuwFWk4cVu4U3UmTE68I\nO7PpCdTjk70IOsLT8uBagAOw92Fj0mGU7agCdWfJ+LjPRUtg+PhVvODatL3taG+l\nFAParsomiRqKGINyn8vALXNISuBYHVDUzv93P10gG5rA2sJ7953/+++Hr9DoLpmL\nSH/q/LebFzPJ2u6KzLc6bam1YX0w/MSNTJVIxA5V/QKBgQDU+iFXdShLwvEXGVtb\nFdZuRk3XsN+yfkFyM9SZrmaLF2VBALkC5pd+rYkXSaTA/cbs623VOYpoJhVmjL8d\nVvTlN/G+8TzfdsmOlAXiOSiUn3VKM/Othu5l9k0AgylU8aXBWTUv5FzmV8gMn+/s\n9oOucAVFa60LdkR2d609y/tKnwKBgQC95Gviall3E/+7drT05KxPPGDKRUjhCLBe\nBNj2+ttSt4+v+E5v3K+LSd11VfGkvLkDvkhjiJlVamf+XgLne3TLrEThAKq8ySUr\nXKBRi+nfmisUHSrMGljHw500Rx+MR/LEpfEERMosLQWTrOTz5VG2RueVHbWbD622\nWitr8tnV/wKBgGDYUNr9GlLBFXJEhIc5ueUxMOp4sm/u+4Gb0fwEEvsCq3dQhdCs\n3IytCp69TR65B4DqWWpRHP/Y+XhFXg5QYVHuC46hEeYnlOWxp69EAJD8pZAVaaQp\nrDRPOJqYCe5nZ9Ew6H+bnybbGcur2qTtP9nNdIgpu2lv4RfhubRVEjLPAoGAXqzb\nSSii8GbNMwcNU6gLbPn6e/6tRl1RqZ6bGhCadxREFIUlfko2T6kFPDIcZ3kceYxO\nhSme4WJK9RykMAtygPWj5daySauz13m4CNBMS4qO/dlI9DgSmY6i+2SWixd4J6lg\nkDNH5VyREj66bAuigNG7NrJ4UBYyEt/EFG8hQrsCgYEAyLwk7f2Wgu9ykdwSrrQE\nTBK0iOVUcwPhxj1UbFyDxPdO0EspyKtIFD5w/sbBtQbJGSUFd7ZPoCsYkT2yAsDp\n3cI/ubRxA+/GaqUo84QxvJ4Uqdu8YS8C0FCEnhXGjA60Y5HFzufJF5EqfzwNctCr\nG0cRyX/4Ut4BNUcir/CRVL0=\n-----END PRIVATE KEY-----"
106
+ },
107
+ {
108
+ "name": "udap_auth_code_flow_cert_iss",
109
+ "description": "MUST correspond to a unique URI entry in the Subject Alternative Name (SAN) extension of the client certificate used for registration.",
110
+ "title": "Authorization Code JWT Issuer (iss) Claim",
111
+ "type": "text",
112
+ "value": "<%= Inferno::Application['base_url'] %>/custom/udap_security/fhir"
113
+ },
114
+ {
115
+ "name": "udap_auth_code_flow_registration_scope",
116
+ "description": "String containing a space delimited list of scopes requested by the client application for use in subsequent requests. The Authorization Server MAY consider this list when deciding the scopes that it will allow the application to subsequently request. Apps requesting the \"authorization_code\" grant type SHOULD request user or patient scopes.",
117
+ "title": "Authorization Code Registration Requested Scope(s)",
118
+ "type": "text",
119
+ "value": "patient/*.read"
120
+ },
121
+ {
122
+ "name": "udap_jwt_signing_alg",
123
+ "default": "RS256",
124
+ "description": "Algorithm used to sign UDAP JSON Web Tokens (JWTs). UDAP Implementations SHALL support RS256.",
125
+ "locked": true,
126
+ "options": {
127
+ "list_options": [
128
+ {
129
+ "label": "RS256",
130
+ "value": "RS256"
131
+ }
132
+ ]
133
+ },
134
+ "title": "JWT Signing Algorithm",
135
+ "type": "radio",
136
+ "value": "RS256"
137
+ },
138
+ {
139
+ "name": "udap_auth_code_flow_registration_certifications",
140
+ "description": "Additional UDAP certifications to include in registration request, if required by the authorization server. Include a space separated list of strings representing a Base64-encoded, signed JWT.",
141
+ "optional": true,
142
+ "title": "Authorization Code UDAP Registration Certifications",
143
+ "type": "textarea",
144
+ "value": ""
145
+ },
146
+ {
147
+ "name": "udap_authorization_code_request_scopes",
148
+ "description": "A list of space-separated scopes to include in the authorization request. If included, these may be equal to or a subset of the scopes requested during registration. If empty, scope will be omitted as a parameter to the authorization endpoint.",
149
+ "optional": true,
150
+ "title": "Scope Parameter for Authorization Request",
151
+ "type": "text",
152
+ "value": ""
153
+ },
154
+ {
155
+ "name": "udap_authorization_code_request_aud",
156
+ "description": "If selected, the Base FHIR URL will be used as the 'aud' parameter in the request to the authorization endpoint.",
157
+ "optional": true,
158
+ "options": {
159
+ "list_options": [
160
+ {
161
+ "label": "Include 'aud' parameter",
162
+ "value": "include_aud"
163
+ }
164
+ ]
165
+ },
166
+ "title": "Audience ('aud') Parameter for Authorization Request",
167
+ "type": "checkbox",
168
+ "value": "[]"
169
+ },
170
+ {
171
+ "name": "flow_type_client_creds",
172
+ "default": [
173
+ "client_credentials"
174
+ ],
175
+ "description": "Which grant type(s) must be supported per the returned Discovery metadata",
176
+ "locked": true,
177
+ "optional": "false",
178
+ "options": {
179
+ "list_options": [
180
+ {
181
+ "label": "Authorization Code",
182
+ "value": "authorization_code"
183
+ },
184
+ {
185
+ "label": "Client Credentials",
186
+ "value": "client_credentials"
187
+ }
188
+ ]
189
+ },
190
+ "title": "Required OAuth2.0 Flow Type for Client Credentials Workflow",
191
+ "type": "checkbox",
192
+ "value": "[\"client_credentials\"]"
193
+ },
194
+ {
195
+ "name": "udap_client_credentials_flow_registration_grant_type",
196
+ "default": "client_credentials",
197
+ "description": "The OAuth2.0 grant type for which this client will register itself. A given client may register as either option, but not both.",
198
+ "locked": true,
199
+ "options": {
200
+ "list_options": [
201
+ {
202
+ "label": "Authorization Code",
203
+ "value": "authorization_code"
204
+ },
205
+ {
206
+ "label": "Client Credentials",
207
+ "value": "client_credentials"
208
+ }
209
+ ]
210
+ },
211
+ "title": "Client Registration Grant Type",
212
+ "type": "radio",
213
+ "value": "client_credentials"
214
+ },
215
+ {
216
+ "name": "udap_client_credentials_flow_client_registration_status",
217
+ "default": "new",
218
+ "description": "If the client's iss and certificate combination has already been registered with the authorization server prior to this test run, select 'Update'.",
219
+ "options": {
220
+ "list_options": [
221
+ {
222
+ "label": "New Registration (201 Response Code Expected)",
223
+ "value": "new"
224
+ },
225
+ {
226
+ "label": "Update Registration (200 or 201 Response Code Expected)",
227
+ "value": "update"
228
+ }
229
+ ]
230
+ },
231
+ "title": "Client Registration Status",
232
+ "type": "radio",
233
+ "value": "new"
234
+ },
235
+ {
236
+ "name": "udap_client_credentials_flow_client_cert_pem",
237
+ "description": "A list of one or more X.509 certificates in PEM format separated by a newline. The first (leaf) certificate MUST represent the client entity Inferno will register as, and the trust chain that will be built from the provided certificate(s) must resolve to a CA trusted by the authorization server under test.",
238
+ "title": "Client Credentials Client Certificate(s) (PEM Format)",
239
+ "type": "textarea",
240
+ "value": "-----BEGIN CERTIFICATE-----\nMIIFcjCCA1qgAwIBAgIUbdCfB3IJ9bdOPGQVtxJHhMxUWv0wDQYJKoZIhvcNAQEL\nBQAwgYYxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNQTEQMA4GA1UEBwwHQmVkZm9y\nZDEQMA4GA1UECgwHSW5mZXJubzEdMBsGA1UEAwwUSW5mZXJuby1VREFQLVJvb3Qt\nQ0ExJzAlBgkqhkiG9w0BCQEWGGluZmVybm9AZ3JvdXBzLm1pdHJlLm9yZzAeFw0y\nNDA4MTIyMzU4MTBaFw0zNDA4MTAyMzU4MTBaMGExCzAJBgNVBAYTAlVTMQswCQYD\nVQQIDAJNQTEQMA4GA1UEBwwHQmVkZm9yZDEQMA4GA1UECgwHSW5mZXJubzEhMB8G\nA1UEAwwYVURBUCBFeGFtcGxlIFRlc3QgQ2xpZW50MIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEAnfqzJCyeFNRhlcsrUPiO2LQtudObDHUKj4Q7fkYPUf9X\necTMckfPKd8UJ7x8Vb5o1zmR3hsMoo1A7IkwBkmK2BXvxq243cCGO1q4w/jdL/EG\nDiIZjTr7qvkawyeh9cAaApOrBlD4gnOxB05GjingDZgiT7GqBwrpEB2XJ4tw4idS\nB3W9Rv0ynbgqPKgGw9hnEef+uNAvFIvSbfdz1n4xHNP0GuMuAX+edFCyxYFmDe74\n8pl3TH9dxkoM945r5tHmuJS9n1pXkTB9L5RVbqH77dIyOBobehHHpT4D3zjdSFmh\nfta5NnDi5/iqRcFz7FVO79jJIoAqN+mWBlVH0yyfYQIDAQABo4H7MIH4MC8GA1Ud\nEQQoMCaGJGh0dHBzOi8vaW5mZXJuby5jb20vdWRhcF9zZWN1cml0eS9hYzAxBgNV\nHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBDA6\nBgNVHR8EMzAxMC+gLaArhilodHRwczovL2luZmVybm8uY29tL21vY2tfY3JsX2Vu\nZHBvaW50LmNybDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQU6Eo2\nHE37gpSaW9zBGf0t7XfYnfIwHwYDVR0jBBgwFoAUNOqoPKju4u9y9JAuAfnSAcFb\nNKAwDQYJKoZIhvcNAQELBQADggIBACh2uQ1Krkw6F3Gq0HG3ohCm2j1ynmLSJwGE\nHvPlkiBcs8RBPxZzJOZJBMxGmjTPga2Kt6zsBlmjLg++C7C5/8JruwrMtrBuTtHx\nKky0Qw+YJm81IgATeDIU/qkJB8LcnHgkQbu3nyoyeKocx9XSW8nlEm4FkyREXxfC\nrSVCoc70GGg2vSnSkRikNjxwKGnHvmEDUOW2bBbbzvTGKlTKSIF50NiNPM3Fi7vF\nbOfi1aZh6m8IKVaI2KUXVFHco1qB3QDK5BUEimko+EyaWSZPvP83PE2+TIdapRrw\nHxQQJEr774GUNH1/hdW0qlP4u3CMMMAjS2H4dOsRYOOmgC6iEewFEBQqTRLkEfgP\npMxYhGAVAmrglLLr4t+ZF9KOmifvB6f18qF352Bj1D0TMB+oLy67kFw3s2ah21la\n3Xm6hQt+M5mZ/EYZIOUPxMHtqVt5DSJdMENHO2cjcRARyeD/BGYnJqnf6yA1LL2V\nTK+jhC/C/Dcv0hHQnVWlUGlwoFMOOzfsr2K3mXYezAuHASP8LIAyjodPpd6cLQu2\nSZTVVobSebaNmZ2UeX8Bc9bcobM2bbVb2c3UeezEJWOpt5cSOeEScEiwkaktxD5p\nix1K3KkIg2yDP176ILlVqBBA0X2FqTSSvFbTa5us3XIwkDfARJBpLnA7OfmsO61+\nIj5io7+X\n-----END CERTIFICATE-----"
241
+ },
242
+ {
243
+ "name": "udap_client_credentials_flow_client_private_key",
244
+ "description": "The private key corresponding to the client certificate used for registration, in PEM format. Used to sign registration and/or authentication JWTs.",
245
+ "title": "Client Credentials Client Private Key (PEM Format)",
246
+ "type": "textarea",
247
+ "value": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCd+rMkLJ4U1GGV\nyytQ+I7YtC2505sMdQqPhDt+Rg9R/1d5xMxyR88p3xQnvHxVvmjXOZHeGwyijUDs\niTAGSYrYFe/GrbjdwIY7WrjD+N0v8QYOIhmNOvuq+RrDJ6H1wBoCk6sGUPiCc7EH\nTkaOKeANmCJPsaoHCukQHZcni3DiJ1IHdb1G/TKduCo8qAbD2GcR5/640C8Ui9Jt\n93PWfjEc0/Qa4y4Bf550ULLFgWYN7vjymXdMf13GSgz3jmvm0ea4lL2fWleRMH0v\nlFVuofvt0jI4Ght6EcelPgPfON1IWaF+1rk2cOLn+KpFwXPsVU7v2MkigCo36ZYG\nVUfTLJ9hAgMBAAECggEAApTpPosYHkEGQztpvs4BD5uKL8I8g2yaOpQvoLWmZHGm\nzU+hA7EWuplxq+CRq5kL/5BqSNXqU/G5AOSRC1lCUpuxKm8GWWFfEDNAV7uGadUn\ngy2de0heeoHNpSjNpcV451fgcJ78IK2hU/w8fPBEQBSfYuwFWk4cVu4U3UmTE68I\nO7PpCdTjk70IOsLT8uBagAOw92Fj0mGU7agCdWfJ+LjPRUtg+PhVvODatL3taG+l\nFAParsomiRqKGINyn8vALXNISuBYHVDUzv93P10gG5rA2sJ7953/+++Hr9DoLpmL\nSH/q/LebFzPJ2u6KzLc6bam1YX0w/MSNTJVIxA5V/QKBgQDU+iFXdShLwvEXGVtb\nFdZuRk3XsN+yfkFyM9SZrmaLF2VBALkC5pd+rYkXSaTA/cbs623VOYpoJhVmjL8d\nVvTlN/G+8TzfdsmOlAXiOSiUn3VKM/Othu5l9k0AgylU8aXBWTUv5FzmV8gMn+/s\n9oOucAVFa60LdkR2d609y/tKnwKBgQC95Gviall3E/+7drT05KxPPGDKRUjhCLBe\nBNj2+ttSt4+v+E5v3K+LSd11VfGkvLkDvkhjiJlVamf+XgLne3TLrEThAKq8ySUr\nXKBRi+nfmisUHSrMGljHw500Rx+MR/LEpfEERMosLQWTrOTz5VG2RueVHbWbD622\nWitr8tnV/wKBgGDYUNr9GlLBFXJEhIc5ueUxMOp4sm/u+4Gb0fwEEvsCq3dQhdCs\n3IytCp69TR65B4DqWWpRHP/Y+XhFXg5QYVHuC46hEeYnlOWxp69EAJD8pZAVaaQp\nrDRPOJqYCe5nZ9Ew6H+bnybbGcur2qTtP9nNdIgpu2lv4RfhubRVEjLPAoGAXqzb\nSSii8GbNMwcNU6gLbPn6e/6tRl1RqZ6bGhCadxREFIUlfko2T6kFPDIcZ3kceYxO\nhSme4WJK9RykMAtygPWj5daySauz13m4CNBMS4qO/dlI9DgSmY6i+2SWixd4J6lg\nkDNH5VyREj66bAuigNG7NrJ4UBYyEt/EFG8hQrsCgYEAyLwk7f2Wgu9ykdwSrrQE\nTBK0iOVUcwPhxj1UbFyDxPdO0EspyKtIFD5w/sbBtQbJGSUFd7ZPoCsYkT2yAsDp\n3cI/ubRxA+/GaqUo84QxvJ4Uqdu8YS8C0FCEnhXGjA60Y5HFzufJF5EqfzwNctCr\nG0cRyX/4Ut4BNUcir/CRVL0=\n-----END PRIVATE KEY-----"
248
+ },
249
+ {
250
+ "name": "udap_cert_iss_client_creds_flow",
251
+ "description": "MUST correspond to a unique URI entry in the Subject Alternative Name (SAN) extension of the client certificate used for registration.",
252
+ "title": "Client Credentials JWT Issuer (iss) Claim",
253
+ "type": "text",
254
+ "value": "<%= Inferno::Application['base_url'] %>/custom/udap_security/fhir"
255
+ },
256
+ {
257
+ "name": "udap_client_credentials_flow_registration_scope",
258
+ "description": "String containing a space delimited list of scopes requested by the client application for use in subsequent requests. The Authorization Server MAY consider this list when deciding the scopes that it will allow the application to subsequently request. Apps requesting the \"client_credentials\" grant type SHOULD request system scopes.",
259
+ "title": "Client Credentials Registration Requested Scope(s)",
260
+ "type": "text",
261
+ "value": "system/*.read"
262
+ },
263
+ {
264
+ "name": "udap_client_creds_flow_registration_certifications",
265
+ "description": "Additional UDAP certifications to include in registration request, if required by the authorization server. Include a space separated list of strings representing a Base64-encoded, signed JWT.",
266
+ "optional": true,
267
+ "title": "Client Credentials UDAP Registration Certifications",
268
+ "type": "textarea",
269
+ "value": ""
270
+ }
271
+ ]
272
+ }
@@ -94,7 +94,7 @@ module UDAPSecurityTestKit
94
94
  client_assertion_payload = UDAPClientAssertionPayloadBuilder.build(
95
95
  udap_client_id,
96
96
  udap_token_endpoint,
97
- extensions.to_json
97
+ extensions
98
98
  )
99
99
 
100
100
  x5c_certs = UDAPJWTBuilder.split_user_input_cert_string(
@@ -0,0 +1,25 @@
1
+ require_relative 'access_ac_interaction_test'
2
+ require_relative 'authorization_request_verification_test'
3
+ require_relative 'token_request_ac_verification_test'
4
+ require_relative 'token_use_verification_test'
5
+
6
+ module UDAPSecurityTestKit
7
+ class UDAPClientAccessAuthorizationCode < Inferno::TestGroup
8
+ id :udap_client_access_ac
9
+ title 'Client Access'
10
+ description %(
11
+ During these tests, the client system will access Inferno's simulated
12
+ FHIR server by requesting an access token using UDAP's authorization_code flow
13
+ and making a FHIR request presenting the access token. Inferno will then verify
14
+ that any requests made as a part of obtaining the token were conformant and that
15
+ a token returned from a token request was used on an access request.
16
+ )
17
+
18
+ run_as_group
19
+
20
+ test from: :udap_client_access_ac_interaction
21
+ test from: :udap_client_authorization_request_verification
22
+ test from: :udap_client_token_request_ac_verification
23
+ test from: :udap_client_token_use_verification
24
+ end
25
+ end
@@ -0,0 +1,59 @@
1
+ require_relative '../urls'
2
+ require_relative '../endpoints/mock_udap_server'
3
+ require_relative 'client_descriptions'
4
+
5
+ module UDAPSecurityTestKit
6
+ class UDAPClientAccessAuthorizationCodeInteraction < Inferno::Test
7
+ include URLs
8
+ include ClientWaitDialogDescriptions
9
+
10
+ id :udap_client_access_ac_interaction
11
+ title 'Perform UDAP-secured Access'
12
+ description %(
13
+ During this test, Inferno will wait for the client to access data
14
+ using a UDAP token obtained during an earlier test.
15
+ )
16
+ input :client_id,
17
+ title: 'Client Id',
18
+ type: 'text',
19
+ locked: true,
20
+ description: INPUT_CLIENT_ID_DESCRIPTION_LOCKED
21
+ input :launch_context,
22
+ title: 'Launch Context',
23
+ type: 'textarea',
24
+ optional: true,
25
+ description: INPUT_LAUNCH_CONTEXT_DESCRIPTION
26
+ input :fhir_user_relative_reference,
27
+ title: 'FHIR User Relative Reference',
28
+ type: 'text',
29
+ optional: true,
30
+ description: INPUT_FHIR_USER_RELATIVE_REFERENCE
31
+ input :fhir_read_resources_bundle,
32
+ title: 'Available Resources',
33
+ type: 'textarea',
34
+ optional: true,
35
+ description: INPUT_FHIR_READ_RESOURCES_BUNDLE_DESCRIPTION
36
+ input :echoed_fhir_response,
37
+ title: 'Default FHIR Response',
38
+ type: 'textarea',
39
+ optional: true,
40
+ description: INPUT_ECHOED_FHIR_RESPONSE_DESCRIPTION
41
+
42
+ def client_suite_id
43
+ return config.options[:endpoint_suite_id] if config.options[:endpoint_suite_id].present?
44
+
45
+ UDAPSecurityTestKit::UDAPSecurityClientTestSuite.id
46
+ end
47
+
48
+ run do
49
+ message =
50
+ wait_dialog_authorization_code_access_prefix(client_id, client_fhir_base_url) +
51
+ wait_dialog_access_response_and_continue_suffix(client_id, client_resume_pass_url)
52
+
53
+ wait(
54
+ identifier: client_id,
55
+ message:
56
+ )
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'access_cc_interaction_test'
2
+ require_relative 'token_request_cc_verification_test'
3
+ require_relative 'token_use_verification_test'
4
+
5
+ module UDAPSecurityTestKit
6
+ class UDAPClientAccessClientCredentials < Inferno::TestGroup
7
+ id :udap_client_access_cc
8
+ title 'Client Access'
9
+ description %(
10
+ During these tests, the client system will access Inferno's simulated
11
+ FHIR server by requesting an access token using UDAP's client_credentials flow
12
+ and making a FHIR request presenting the access token. Inferno will then verify
13
+ that any requests made as a part of obtaining the token were conformant and that
14
+ a token returned from a token request was used on an access request.
15
+ )
16
+
17
+ run_as_group
18
+
19
+ test from: :udap_client_access_cc_interaction
20
+ test from: :udap_client_token_request_cc_verification
21
+ test from: :udap_client_token_use_verification
22
+ end
23
+ end
@@ -0,0 +1,49 @@
1
+ require_relative '../urls'
2
+ require_relative '../endpoints/mock_udap_server'
3
+ require_relative 'client_descriptions'
4
+
5
+ module UDAPSecurityTestKit
6
+ class UDAPClientAccessClientCredentialsInteraction < Inferno::Test
7
+ include URLs
8
+ include ClientWaitDialogDescriptions
9
+
10
+ id :udap_client_access_cc_interaction
11
+ title 'Perform UDAP-secured Access'
12
+ description %(
13
+ During this test, Inferno will wait for the client to access data
14
+ using a UDAP token obtained during an earlier test.
15
+ )
16
+ input :client_id,
17
+ title: 'Client Id',
18
+ type: 'text',
19
+ locked: true,
20
+ description: INPUT_CLIENT_ID_DESCRIPTION_LOCKED
21
+ input :fhir_read_resources_bundle,
22
+ title: 'Available Resources',
23
+ type: 'textarea',
24
+ optional: true,
25
+ description: INPUT_FHIR_READ_RESOURCES_BUNDLE_DESCRIPTION
26
+ input :echoed_fhir_response,
27
+ title: 'Default FHIR Response',
28
+ type: 'textarea',
29
+ optional: true,
30
+ description: INPUT_ECHOED_FHIR_RESPONSE_DESCRIPTION
31
+
32
+ def client_suite_id
33
+ return config.options[:endpoint_suite_id] if config.options[:endpoint_suite_id].present?
34
+
35
+ UDAPSecurityTestKit::UDAPSecurityClientTestSuite.id
36
+ end
37
+
38
+ run do
39
+ message =
40
+ wait_dialog_client_credentials_access_prefix(client_id, client_fhir_base_url) +
41
+ wait_dialog_access_response_and_continue_suffix(client_id, client_resume_pass_url)
42
+
43
+ wait(
44
+ identifier: client_id,
45
+ message:
46
+ )
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,83 @@
1
+ require_relative '../tags'
2
+ require_relative '../urls'
3
+ require_relative '../endpoints/mock_udap_server'
4
+ require_relative 'client_descriptions'
5
+
6
+ module UDAPSecurityTestKit
7
+ class UDAPClientAppLaunchAuthorizationRequestVerification < Inferno::Test
8
+ include URLs
9
+
10
+ id :udap_client_authorization_request_verification
11
+ title 'Verify UDAP Authorization Requests'
12
+ description %(
13
+ Check that UDAP authorization requests made are conformant.
14
+ )
15
+
16
+ input :client_id,
17
+ title: 'Client Id',
18
+ type: 'text',
19
+ locked: true,
20
+ description: INPUT_CLIENT_ID_DESCRIPTION_LOCKED
21
+ input :udap_registration_jwt,
22
+ title: 'Registered UDAP Software Statement',
23
+ type: 'textarea',
24
+ locked: 'true',
25
+ description: INPUT_UDAP_REGISTRATION_JWT_DESCRIPTION_LOCKED
26
+
27
+ def client_suite_id
28
+ return config.options[:endpoint_suite_id] if config.options[:endpoint_suite_id].present?
29
+
30
+ UDAPSecurityTestKit::UDAPSecurityClientTestSuite.id
31
+ end
32
+
33
+ run do
34
+ load_tagged_requests(AUTHORIZATION_TAG, UDAP_TAG)
35
+ skip_if requests.blank?, 'No UDAP authorization requests made.'
36
+
37
+ requests.each_with_index do |authorization_request, index|
38
+ auth_code_request_params = MockUDAPServer.authorization_code_request_details(authorization_request)
39
+ check_request_params(auth_code_request_params, index + 1)
40
+ end
41
+
42
+ assert messages.none? { |msg|
43
+ msg[:type] == 'error'
44
+ }, 'Invalid authorization requests detected. See messages for details.'
45
+ end
46
+
47
+ def check_request_params(params, request_num) # rubocop:disable Metrics/CyclomaticComplexity
48
+ if params['response_type'] != 'code'
49
+ add_message('error',
50
+ "Authorization request #{request_num} had an incorrect `response_type`: expected 'code', " \
51
+ "but got '#{params['response_type']}'")
52
+ end
53
+ if params['client_id'] != client_id
54
+ add_message('error',
55
+ "Authorization request #{request_num} had an incorrect `client_id`: expected #{client_id}, " \
56
+ "but got '#{params['client_id']}'")
57
+ end
58
+ registration_body, _registration_header = JWT.decode(udap_registration_jwt, nil, false)
59
+ if params['redirect_uri'].present?
60
+ # must be a registered redirect_uri
61
+ unless registration_body['redirect_uris']&.include?(params['redirect_uri'])
62
+ add_message('error',
63
+ "Authorization request #{request_num} had an invalid `redirect_uri`: expected one of " \
64
+ "'#{registration_body['redirect_uris']&.join(', ')}', but got '#{params['redirect_uri']}'")
65
+ end
66
+ else
67
+ # can only be one registered redirect_uri
68
+ unless registration_body['redirect_uris']&.length == 1
69
+ add_message('error',
70
+ "Authorization request #{request_num} had an invalid `redirect_uri`: expected one of " \
71
+ "'#{registration_body['redirect_uris']&.join(', ')}', but got none")
72
+ end
73
+ end
74
+
75
+ if params['state'].blank?
76
+ add_message('warning',
77
+ "Authorization request #{request_num} is missing the recommended `state` element")
78
+ end
79
+
80
+ nil
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rack/utils'
4
+
5
+ module UDAPSecurityTestKit
6
+ RE_RUN_REGISTRATION_SUFFIX =
7
+ 'Create a new session and re-run the Client Registration group if you need to change this value.'
8
+ INPUT_CLIENT_ID_DESCRIPTION_LOCKED =
9
+ "The registered Client Id for use in obtaining access tokens. #{RE_RUN_REGISTRATION_SUFFIX}".freeze
10
+ INPUT_UDAP_REGISTRATION_JWT_DESCRIPTION_LOCKED =
11
+ "The software statement JWT provided during UDAP client registration. #{RE_RUN_REGISTRATION_SUFFIX}".freeze
12
+
13
+ INPUT_LAUNCH_CONTEXT_DESCRIPTION =
14
+ 'Launch context details to be included in access token responses, specified as a JSON array. If provided, ' \
15
+ 'the contents will be merged into Inferno\'s token responses.'
16
+ INPUT_FHIR_USER_RELATIVE_REFERENCE =
17
+ 'A FHIR relative reference (<resource type>/<id>) for the FHIR user record to return when the openid ' \
18
+ 'and fhirUser scopes are requested. Include this resource in the **Available Resources** input so ' \
19
+ 'that it can be accessed via FHIR read.'
20
+ INPUT_FHIR_READ_RESOURCES_BUNDLE_DESCRIPTION =
21
+ 'Resources to make available in Inferno\'s simulated FHIR server provided as a FHIR bundle. Each entry ' \
22
+ 'must contain a resource with the id element populated. Each instance present will be available for ' \
23
+ 'retrieval from Inferno at the endpoint: <fhir-base>/<resource type>/<instance id>. These will only ' \
24
+ 'be available through the read interaction.'
25
+ INPUT_ECHOED_FHIR_RESPONSE_DESCRIPTION =
26
+ 'JSON representation of a default FHIR resource for Inferno to echo when a request is made to the ' \
27
+ 'simulated FHIR server. Reads targetting resources in the **Available Resources** input will return ' \
28
+ 'that resource instead of this. Otherwise, the content here will be echoed back exactly and no check ' \
29
+ 'will be made that it is appropriate for the request made. If nothing is provided, an OperationOutcome ' \
30
+ 'indicating nothing to echo will be returned.'
31
+
32
+ module ClientWaitDialogDescriptions
33
+ def wait_dialog_client_credentials_access_prefix(client_id, fhir_base_url)
34
+ <<~PREFIX
35
+ **Access**
36
+
37
+ Use the registered client id (#{client_id}) to obtain an access
38
+ token using the [UDAP B2B client credentials flow](https://hl7.org/fhir/us/udap-security/STU1/b2b.html)
39
+ and use that token to access a FHIR endpoint under the simulated server's base URL
40
+
41
+ `#{fhir_base_url}`
42
+ PREFIX
43
+ end
44
+
45
+ def wait_dialog_authorization_code_access_prefix(client_id, fhir_base_url)
46
+ <<~PREFIX
47
+ **Access**
48
+
49
+ Use the registered client id (#{client_id}) to obtain an access
50
+ token using the UDAP [consumer-facing](https://hl7.org/fhir/us/udap-security/STU1/consumer.html)
51
+ or [B2B authorization code flow](https://hl7.org/fhir/us/udap-security/STU1/b2b.html)
52
+ and use that token to access a FHIR endpoint under the simulated server's base URL
53
+
54
+ `#{fhir_base_url}`
55
+ PREFIX
56
+ end
57
+
58
+ def wait_dialog_access_response_and_continue_suffix(client_id, resume_pass_url)
59
+ <<~SUFFIX
60
+ Inferno will respond to requests with either:
61
+ - A resource from the Bundle in the **Available Resources** input if the request is a read matching
62
+ a resource type and id found in the Bundle.
63
+ - Otherwise, the contents of the **Default FHIR Response** if provided.
64
+ - Otherwise, an OperationOutcome indicating nothing to echo.
65
+
66
+ [Click here](#{resume_pass_url}?token=#{client_id}) once you performed the data access.
67
+ SUFFIX
68
+ end
69
+ end
70
+ end