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.
- checksums.yaml +4 -4
- data/config/presets/UDAP_RunClientAgainstServer.json.erb +20 -0
- data/config/presets/UDAP_RunServerAgainstClient.json.erb +272 -0
- data/lib/udap_security_test_kit/client_credentials_token_exchange_test.rb +1 -1
- data/lib/udap_security_test_kit/client_suite/access_ac_group.rb +25 -0
- data/lib/udap_security_test_kit/client_suite/access_ac_interaction_test.rb +59 -0
- data/lib/udap_security_test_kit/client_suite/access_cc_group.rb +23 -0
- data/lib/udap_security_test_kit/client_suite/access_cc_interaction_test.rb +49 -0
- data/lib/udap_security_test_kit/client_suite/authorization_request_verification_test.rb +83 -0
- data/lib/udap_security_test_kit/client_suite/client_descriptions.rb +70 -0
- data/lib/udap_security_test_kit/client_suite/client_options.rb +20 -0
- data/lib/udap_security_test_kit/client_suite/oidc_jwks.json +32 -0
- data/lib/udap_security_test_kit/client_suite/oidc_jwks.rb +27 -0
- data/lib/udap_security_test_kit/client_suite/registration_ac_group.rb +18 -0
- data/lib/udap_security_test_kit/client_suite/registration_ac_verification_test.rb +38 -0
- data/lib/udap_security_test_kit/client_suite/registration_cc_group.rb +18 -0
- data/lib/udap_security_test_kit/client_suite/registration_cc_verification_test.rb +38 -0
- data/lib/udap_security_test_kit/client_suite/registration_interaction_test.rb +57 -0
- data/lib/udap_security_test_kit/client_suite/registration_request_verification.rb +242 -0
- data/lib/udap_security_test_kit/client_suite/token_request_ac_verification_test.rb +49 -0
- data/lib/udap_security_test_kit/client_suite/token_request_cc_verification_test.rb +49 -0
- data/lib/udap_security_test_kit/client_suite/token_request_verification.rb +223 -0
- data/lib/udap_security_test_kit/client_suite/token_use_verification_test.rb +40 -0
- data/lib/udap_security_test_kit/client_suite.rb +107 -0
- data/lib/udap_security_test_kit/docs/demo/FHIR Request.postman_collection.json +81 -0
- data/lib/udap_security_test_kit/docs/udap_client_suite_description.md +163 -0
- data/lib/udap_security_test_kit/endpoints/echoing_fhir_responder_endpoint.rb +96 -0
- data/lib/udap_security_test_kit/endpoints/mock_udap_server/authorization_endpoint.rb +28 -0
- data/lib/udap_security_test_kit/endpoints/mock_udap_server/registration_endpoint.rb +31 -0
- data/lib/udap_security_test_kit/endpoints/mock_udap_server/token_endpoint.rb +56 -0
- data/lib/udap_security_test_kit/endpoints/mock_udap_server/udap_authorization_response_creation.rb +63 -0
- data/lib/udap_security_test_kit/endpoints/mock_udap_server/udap_registration_response_creation.rb +28 -0
- data/lib/udap_security_test_kit/endpoints/mock_udap_server/udap_token_response_creation.rb +218 -0
- data/lib/udap_security_test_kit/endpoints/mock_udap_server.rb +382 -0
- data/lib/udap_security_test_kit/metadata.rb +4 -4
- data/lib/udap_security_test_kit/tags.rb +12 -0
- data/lib/udap_security_test_kit/urls.rb +52 -0
- data/lib/udap_security_test_kit/version.rb +2 -2
- data/lib/udap_security_test_kit.rb +8 -2
- metadata +36 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93cc168a29a41ac4c22bdcb8a4124aa85c370d3a0ae8ac1851090555ab3a2e8b
|
4
|
+
data.tar.gz: d31eee97042a453fe3ccf6c72c1421309ff4d367eb87ff6d2f3a63a96529041d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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-----\n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\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
|
+
}
|
@@ -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
|