udap_security_test_kit 0.11.3 → 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_RunServerAgainstClient.json.erb +4 -4
- 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/{client_registration_interaction_test.rb → registration_interaction_test.rb} +11 -4
- data/lib/udap_security_test_kit/client_suite/{client_registration_verification_test.rb → registration_request_verification.rb} +38 -40
- 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/{client_token_request_verification_test.rb → token_request_verification.rb} +91 -46
- data/lib/udap_security_test_kit/client_suite/{client_token_use_verification_test.rb → token_use_verification_test.rb} +0 -3
- data/lib/udap_security_test_kit/client_suite.rb +46 -17
- data/lib/udap_security_test_kit/docs/udap_client_suite_description.md +74 -31
- 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 +112 -31
- data/lib/udap_security_test_kit/metadata.rb +1 -1
- data/lib/udap_security_test_kit/tags.rb +4 -0
- data/lib/udap_security_test_kit/urls.rb +15 -8
- data/lib/udap_security_test_kit/version.rb +2 -2
- metadata +28 -12
- data/lib/udap_security_test_kit/client_suite/client_access_group.rb +0 -22
- data/lib/udap_security_test_kit/client_suite/client_access_interaction_test.rb +0 -53
- data/lib/udap_security_test_kit/client_suite/client_registration_group.rb +0 -26
- data/lib/udap_security_test_kit/endpoints/echoing_fhir_responder.rb +0 -52
- data/lib/udap_security_test_kit/endpoints/mock_udap_server/registration.rb +0 -57
- data/lib/udap_security_test_kit/endpoints/mock_udap_server/token.rb +0 -27
@@ -9,8 +9,11 @@ client systems to the STU 1.0.0 version of the HL7® FHIR®
|
|
9
9
|
The UDAP Security Client Test Suite verifies that systems correctly implement
|
10
10
|
the [UDAP Security IG](https://hl7.org/fhir/us/udap-security/STU1/)
|
11
11
|
for authorizating and/or authenticating with a server in order to gain
|
12
|
-
access to HL7® FHIR® APIs.
|
13
|
-
|
12
|
+
access to HL7® FHIR® APIs. The suite contains options for testing clients that follow the
|
13
|
+
- Authorization Code flow for [consumer facing](https://hl7.org/fhir/us/udap-security/STU1/consumer.html)
|
14
|
+
or [Business-to-Business](https://hl7.org/fhir/us/udap-security/STU1/b2b.html) access.
|
15
|
+
- Client Credentials flow for [Business-to-Business](https://hl7.org/fhir/us/udap-security/STU1/b2b.html)
|
16
|
+
access.
|
14
17
|
|
15
18
|
These tests are a **DRAFT** intended to allow implementers to perform
|
16
19
|
preliminary checks of their systems against UDAP Security IG
|
@@ -20,8 +23,8 @@ requirements and may change the test verification logic.
|
|
20
23
|
|
21
24
|
## Test Methodology
|
22
25
|
|
23
|
-
For these tests Inferno simulates a UDAP server that supports the
|
24
|
-
client credentials
|
26
|
+
For these tests Inferno simulates a UDAP server that supports both the authorization code
|
27
|
+
and the client credentials flows. In both cases, testers will
|
25
28
|
1. Provide to Inferno the client URI with which they will register their system.
|
26
29
|
2. Make a dynamic registration request to Inferno using the provided client URI
|
27
30
|
and including the X.509 certificate used to sign the registeration and subsequent
|
@@ -59,24 +62,26 @@ steps use [Postman](https://www.postman.com/) to generate the access request usi
|
|
59
62
|
[this collection](https://github.com/inferno-framework/udap-security-test-kit/blob/main/lib/udap_security_test_kit/docs/demo/FHIR%20Request.postman_collection.json).
|
60
63
|
Install the app and import the collection before following these steps.
|
61
64
|
|
62
|
-
1. Start an instance of the UDAP Security Client test suite
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
65
|
+
1. Start an instance of the UDAP Security Client test suite and choose either option: *Authorization Code*,
|
66
|
+
or *Client Credentials* flow. Remember your choice for use later.
|
67
|
+
1. From the drop down in the upper left, select preset "Demo: Run Against the UDAP Security Server Suite".
|
68
|
+
1. Click the "RUN ALL TESTS" button in the upper right and click "SUBMIT"
|
69
|
+
1. In a new tab, start an instance of the UDAP Security Server Test Suite
|
70
|
+
1. From the drop down in the upper left, select preset "Demo: Run Against the UDAP Security Client Suite"
|
71
|
+
1. Select the test group corresponding to your choice in step 1: **1** for *Authorization Code* and **2**
|
72
|
+
for *Client Credentials*. Click the "RUN ALL TESTS" button in the upper right, and click "SUBMIT".
|
73
|
+
1. If testing the *Authorization Code* flow, click the link to authorize with the server.
|
74
|
+
1. In the Client suite tab, click the link in the wait dialog to continue the tests.
|
75
|
+
1. In the Server suite tab, find the access token to use for the data access request by opening
|
76
|
+
test **1.3.03** or **2.3.01** OAuth token exchange request succeeds when supplied correct information,
|
77
|
+
click on the "REQUESTS" tab, clicking on the "DETAILS" button, and expanding the "Response Body".
|
73
78
|
Copy the "access_token" value, which will be a ~100 character string of letters and numbers (e.g., eyJjbGllbnRfaWQiOiJzbWFydF9jbGllbnRfdGVzdF9kZW1vIiwiZXhwaXJhdGlvbiI6MTc0MzUxNDk4Mywibm9uY2UiOiJlZDI5MWIwNmZhMTE4OTc4In0)
|
74
|
-
|
79
|
+
1. Open Postman and open the "FHIR Request" Collection. Click the "Variables" tab and add the
|
75
80
|
copied access token as the current value of the `bearer_token` variable. Also update the
|
76
81
|
`base_url` value for where the test is running (see details on the "Overview" tab).
|
77
82
|
Save the collection.
|
78
|
-
|
79
|
-
|
83
|
+
1. Select the "Patient Read" request and click "Send". A FHIR Patient resource should be returned.
|
84
|
+
1. Return to the client tests and click the link to continue and complete the tests.
|
80
85
|
|
81
86
|
The client tests should pass. On the server side some of the registration tests will fail. This is
|
82
87
|
expected as the Server tests make several intentionally invalid token requests. Inferno's simulated UDAP
|
@@ -86,20 +91,58 @@ registration requests is itself not conformant there are corresponding failures
|
|
86
91
|
|
87
92
|
### Additional Inputs
|
88
93
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
94
|
+
#### Inputs Controlling Token Responses
|
95
|
+
|
96
|
+
The UDAP simulation incorporates some aspects of SMART App launch including its approach to
|
97
|
+
[context data](https://hl7.org/fhir/smart-app-launch/STU2.2/scopes-and-launch-context.html)
|
98
|
+
in token responses during the authorization code flow.
|
99
|
+
Inferno's SMART simulation does not include the details needed to populate
|
100
|
+
these details into the token response when requested by apps using scopes.
|
101
|
+
If the tested app needs and will request these details, the tester must provide them for Inferno
|
102
|
+
to respond with using the following inputs:
|
103
|
+
- **Launch Context** (available for all *SMART App Launch* clients): Testers can provide a JSON
|
104
|
+
array for Inferno to use as the base for building a token response on. This can include
|
105
|
+
keys like `"patient"` when the `launch/patient` scope will be requested. Note that when keys that Inferno
|
106
|
+
also populates (e.g. `access_token` or `id_token`) are included, the Inferno value will be returned.
|
107
|
+
- **FHIR User Relative Reference** (available for all *SMART App Launch* clients): Testers
|
108
|
+
can provide a FHIR relative reference (`<resource type>/<id>`) for the FHIR user record
|
109
|
+
to return with the `id_token` when the `openid` and `fhirUser` scopes are requested. If populated,
|
110
|
+
include the corresponding resource in the **Available Resources** input (See the "Inputs
|
111
|
+
Controlling FHIR Responses" section) so that it can be accessed via FHIR read.
|
112
|
+
|
113
|
+
#### Inputs Controlling FHIR Responses
|
114
|
+
The focus of this test kit is on the auth protocol, so the simulated FHIR server implemented
|
115
|
+
in this test suite is very simple. It will respond to any FHIR request with either:
|
116
|
+
- A resource from a tester-provided Bundle in the **Available Resources** input
|
117
|
+
if the request is a read matching a resource type and id found in the Bundle.
|
118
|
+
- Otherwise, the contents of the **Default FHIR Response** input, if provided.
|
119
|
+
- Otherwise, an OperationOutcome indicating no response was available.
|
120
|
+
|
121
|
+
The two inputs that control these response include:
|
122
|
+
- **Available Resources**: A FHIR Bundle of resources to make available via the
|
123
|
+
simulated FHIR sever. Each entry must contain a resource with the id element
|
124
|
+
populated. Each instance present will be available for retrieval from Inferno
|
125
|
+
at the endpoint: `<fhir-base>/<resource type>/<instance id>`. These will only
|
126
|
+
be available through the read interaction.
|
127
|
+
- **FHIR Response to Echo**: A static FHIR JSON body for Inferno to return for all FHIR requests
|
128
|
+
not covered by reads of instances in the **Available Resources** input. In this case,
|
129
|
+
the simulation is a simple echo and Inferno does not check that the response is
|
130
|
+
appropriate for the request made.
|
95
131
|
|
96
132
|
## Current Limitations
|
97
133
|
|
98
134
|
This test kit is still in draft form and does not test all of the requirements and features
|
99
|
-
described in the UDAP Security IG for clients.
|
100
|
-
is tested at this time.
|
135
|
+
described in the UDAP Security IG for clients.
|
101
136
|
|
102
|
-
The following sections list
|
137
|
+
The following sections list known gaps and limitations.
|
138
|
+
|
139
|
+
### SMART Scope Checking and Fulfilment
|
140
|
+
|
141
|
+
These tests do not verify any details about scopes, including that the
|
142
|
+
- Requested scopes are conformant, such as that they have a valid format and are consistent
|
143
|
+
between authorization and refresh token requests.
|
144
|
+
- Provided **Launch Context** input fullfils the requested data context scopes.
|
145
|
+
- Access performed is allowed by the requested scope.
|
103
146
|
|
104
147
|
### UDAP Server Simulation Limitations
|
105
148
|
|
@@ -114,7 +157,7 @@ systems from passing in the [github repository's issues page](https://github.com
|
|
114
157
|
### FHIR Server Simulation Limitations
|
115
158
|
|
116
159
|
The FHIR server simulation used to support clients in demonstrating their ability to access
|
117
|
-
FHIR APIs using access tokens obtained using the
|
118
|
-
able to provide a single static response that will be echoed for any
|
119
|
-
Inferno will never implement a fully general FHIR server simulation,
|
120
|
-
in the future based on community feedback.
|
160
|
+
FHIR APIs using access tokens obtained using the SMART flows is very limited. Testers are currently
|
161
|
+
able to provide a list of resources to be read and a single static response that will be echoed for any
|
162
|
+
other FHIR request made. While Inferno will never implement a fully general FHIR server simulation,
|
163
|
+
additional options, such as may be added in the future based on community feedback.
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../urls'
|
4
|
+
require_relative '../tags'
|
5
|
+
require_relative 'mock_udap_server'
|
6
|
+
|
7
|
+
module UDAPSecurityTestKit
|
8
|
+
class EchoingFHIRResponderEndpoint < Inferno::DSL::SuiteEndpoint
|
9
|
+
def test_run_identifier
|
10
|
+
MockUDAPServer.issued_token_to_client_id(request.headers['authorization']&.delete_prefix('Bearer '))
|
11
|
+
end
|
12
|
+
|
13
|
+
def make_response
|
14
|
+
return if response.status == 401 # set in update_result (expired token handling there)
|
15
|
+
|
16
|
+
response.content_type = 'application/fhir+json'
|
17
|
+
response.headers['Access-Control-Allow-Origin'] = '*'
|
18
|
+
response.status = 200
|
19
|
+
|
20
|
+
# look for read of provided resources
|
21
|
+
read_response = tester_provided_read_response_body
|
22
|
+
if read_response.present?
|
23
|
+
response.body = read_response.to_json
|
24
|
+
return
|
25
|
+
end
|
26
|
+
|
27
|
+
# If the tester provided a response, echo it
|
28
|
+
# otherwise, operation outcome
|
29
|
+
echo_response = JSON.parse(result.input_json)
|
30
|
+
.find { |input| input['name'].include?('echoed_fhir_response') }
|
31
|
+
&.dig('value')
|
32
|
+
if echo_response.present?
|
33
|
+
response.body = echo_response
|
34
|
+
return
|
35
|
+
end
|
36
|
+
|
37
|
+
response.status = 400
|
38
|
+
response.body = FHIR::OperationOutcome.new(
|
39
|
+
issue: FHIR::OperationOutcome::Issue.new(
|
40
|
+
severity: 'fatal', code: 'required',
|
41
|
+
details: FHIR::CodeableConcept.new(text: 'No response provided to echo.')
|
42
|
+
)
|
43
|
+
).to_json
|
44
|
+
end
|
45
|
+
|
46
|
+
def update_result
|
47
|
+
if MockUDAPServer.request_has_expired_token?(request)
|
48
|
+
MockUDAPServer.update_response_for_expired_token(response, 'Bearer token')
|
49
|
+
return
|
50
|
+
end
|
51
|
+
|
52
|
+
nil # never update for now
|
53
|
+
end
|
54
|
+
|
55
|
+
def tags
|
56
|
+
[ACCESS_TAG]
|
57
|
+
end
|
58
|
+
|
59
|
+
def tester_provided_read_response_body
|
60
|
+
resource_type = request.params[:one]
|
61
|
+
id = request.params[:two]
|
62
|
+
|
63
|
+
return unless resource_type.present? && id.present?
|
64
|
+
|
65
|
+
resource_type_class =
|
66
|
+
begin
|
67
|
+
FHIR.const_get(resource_type)
|
68
|
+
rescue NameError
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
return unless resource_type_class.present?
|
72
|
+
|
73
|
+
resource_bundle = ehr_input_bundle
|
74
|
+
return unless resource_bundle.present?
|
75
|
+
|
76
|
+
find_resource_in_bundle(resource_bundle, resource_type_class, id)
|
77
|
+
end
|
78
|
+
|
79
|
+
def ehr_input_bundle
|
80
|
+
ehr_bundle_input =
|
81
|
+
JSON.parse(result.input_json).find { |input| input['name'] == 'fhir_read_resources_bundle' }&.dig('value')
|
82
|
+
ehr_bundle = FHIR.from_contents(ehr_bundle_input) if ehr_bundle_input.present?
|
83
|
+
return ehr_bundle if ehr_bundle.is_a?(FHIR::Bundle)
|
84
|
+
|
85
|
+
nil
|
86
|
+
rescue StandardError
|
87
|
+
nil
|
88
|
+
end
|
89
|
+
|
90
|
+
def find_resource_in_bundle(bundle, resource_type_class, id)
|
91
|
+
bundle.entry&.find do |entry|
|
92
|
+
entry.resource.is_a?(resource_type_class) && entry.resource.id == id
|
93
|
+
end&.resource
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../tags'
|
4
|
+
require_relative 'udap_authorization_response_creation'
|
5
|
+
|
6
|
+
module UDAPSecurityTestKit
|
7
|
+
module MockUDAPServer
|
8
|
+
class AuthorizationEndpoint < Inferno::DSL::SuiteEndpoint
|
9
|
+
include UDAPAuthorizationResponseCreation
|
10
|
+
|
11
|
+
def test_run_identifier
|
12
|
+
request.params[:client_id]
|
13
|
+
end
|
14
|
+
|
15
|
+
def make_response
|
16
|
+
make_udap_authorization_response
|
17
|
+
end
|
18
|
+
|
19
|
+
def update_result
|
20
|
+
nil # never update for now
|
21
|
+
end
|
22
|
+
|
23
|
+
def tags
|
24
|
+
[AUTHORIZATION_TAG, AUTHORIZATION_CODE_TAG, UDAP_TAG]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../tags'
|
4
|
+
require_relative '../mock_udap_server'
|
5
|
+
require_relative 'udap_registration_response_creation'
|
6
|
+
|
7
|
+
module UDAPSecurityTestKit
|
8
|
+
module MockUDAPServer
|
9
|
+
class RegistrationEndpoint < Inferno::DSL::SuiteEndpoint
|
10
|
+
include UDAPRegistrationResponseCreation
|
11
|
+
|
12
|
+
def test_run_identifier
|
13
|
+
MockUDAPServer.client_uri_to_client_id(
|
14
|
+
MockUDAPServer.udap_client_uri_from_registration_payload(MockUDAPServer.parsed_io_body(request))
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
def make_response
|
19
|
+
make_udap_registration_response
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_result
|
23
|
+
nil # never update for now
|
24
|
+
end
|
25
|
+
|
26
|
+
def tags
|
27
|
+
[REGISTRATION_TAG, UDAP_TAG]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../tags'
|
4
|
+
require_relative '../../urls'
|
5
|
+
require_relative '../mock_udap_server'
|
6
|
+
require_relative 'udap_token_response_creation'
|
7
|
+
|
8
|
+
module UDAPSecurityTestKit
|
9
|
+
module MockUDAPServer
|
10
|
+
class TokenEndpoint < Inferno::DSL::SuiteEndpoint
|
11
|
+
include UDAPTokenResponseCreation
|
12
|
+
include URLs
|
13
|
+
|
14
|
+
def test_run_identifier
|
15
|
+
case request.params[:grant_type]
|
16
|
+
when CLIENT_CREDENTIALS_TAG
|
17
|
+
MockUDAPServer.client_id_from_client_assertion(request.params[:client_assertion])
|
18
|
+
when AUTHORIZATION_CODE_TAG
|
19
|
+
MockUDAPServer.issued_token_to_client_id(request.params[:code])
|
20
|
+
when REFRESH_TOKEN_TAG
|
21
|
+
MockUDAPServer.issued_token_to_client_id(
|
22
|
+
MockUDAPServer.refresh_token_to_authorization_code(request.params[:refresh_token])
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def make_response
|
28
|
+
case request.params[:grant_type]
|
29
|
+
when CLIENT_CREDENTIALS_TAG
|
30
|
+
make_udap_client_credential_token_response
|
31
|
+
when AUTHORIZATION_CODE_TAG
|
32
|
+
make_udap_authorization_code_token_response
|
33
|
+
when REFRESH_TOKEN_TAG
|
34
|
+
make_udap_refresh_token_response
|
35
|
+
else
|
36
|
+
MockUDAPServer.update_response_for_error(
|
37
|
+
response,
|
38
|
+
"unsupported grant_type: #{request.params[:grant_type]}"
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def update_result
|
44
|
+
nil # never update for now
|
45
|
+
end
|
46
|
+
|
47
|
+
def tags
|
48
|
+
tags = [TOKEN_TAG, UDAP_TAG]
|
49
|
+
if [CLIENT_CREDENTIALS_TAG, AUTHORIZATION_CODE_TAG, REFRESH_TOKEN_TAG].include?(request.params[:grant_type])
|
50
|
+
tags << request.params[:grant_type]
|
51
|
+
end
|
52
|
+
tags
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/udap_security_test_kit/endpoints/mock_udap_server/udap_authorization_response_creation.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'jwt'
|
2
|
+
require_relative '../mock_udap_server'
|
3
|
+
|
4
|
+
module UDAPSecurityTestKit
|
5
|
+
module MockUDAPServer
|
6
|
+
module UDAPAuthorizationResponseCreation
|
7
|
+
def make_udap_authorization_response
|
8
|
+
redirect_uri = request.params[:redirect_uri]
|
9
|
+
registered_redirect_uri_list = udap_registered_redirect_uris
|
10
|
+
|
11
|
+
if redirect_uri.blank?
|
12
|
+
# need one from the registered list
|
13
|
+
if registered_redirect_uri_list.blank?
|
14
|
+
response.status = 400
|
15
|
+
response.body = {
|
16
|
+
error: 'Bad request',
|
17
|
+
message: 'Missing required redirect_uri parameter with no default provided in the registration.'
|
18
|
+
}.to_json
|
19
|
+
response.content_type = 'application/json'
|
20
|
+
return
|
21
|
+
elsif registered_redirect_uri_list.length > 1
|
22
|
+
response.status = 400
|
23
|
+
response.body = {
|
24
|
+
error: 'Bad request',
|
25
|
+
message: 'Missing required redirect_uri parameter with multiple options provided in the registration.'
|
26
|
+
}.to_json
|
27
|
+
response.content_type = 'application/json'
|
28
|
+
return
|
29
|
+
else
|
30
|
+
redirect_uri = registered_redirect_uri_list.first
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
client_id = request.params[:client_id]
|
35
|
+
state = request.params[:state]
|
36
|
+
|
37
|
+
exp_min = 10
|
38
|
+
token = MockUDAPServer.client_id_to_token(client_id, exp_min)
|
39
|
+
code_query_string = "code=#{ERB::Util.url_encode(token)}"
|
40
|
+
query_string =
|
41
|
+
if state.present?
|
42
|
+
"#{code_query_string}&state=#{ERB::Util.url_encode(state)}"
|
43
|
+
else
|
44
|
+
code_query_string
|
45
|
+
end
|
46
|
+
response.headers['Location'] = "#{redirect_uri}#{redirect_uri.include?('?') ? '&' : '?'}#{query_string}"
|
47
|
+
response.status = 302
|
48
|
+
end
|
49
|
+
|
50
|
+
def udap_registered_redirect_uris
|
51
|
+
registered_software_statement = MockUDAPServer.udap_registration_software_statement(test_run.test_session_id)
|
52
|
+
return unless registered_software_statement.present?
|
53
|
+
|
54
|
+
registration_jwt_body, _registration_jwt_header = JWT.decode(registered_software_statement, nil, false)
|
55
|
+
return [] unless registration_jwt_body['redirect'].present?
|
56
|
+
return registration_jwt_body['redirect'] if registration_jwt_body['redirect'].is_a?(Array)
|
57
|
+
|
58
|
+
# invalid registration, but we'll succeed here and fail during registration verification
|
59
|
+
[registration_jwt_body['redirect']]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/udap_security_test_kit/endpoints/mock_udap_server/udap_registration_response_creation.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative '../mock_udap_server'
|
2
|
+
|
3
|
+
module UDAPSecurityTestKit
|
4
|
+
module MockUDAPServer
|
5
|
+
module UDAPRegistrationResponseCreation
|
6
|
+
def make_udap_registration_response
|
7
|
+
parsed_body = MockUDAPServer.parsed_io_body(request)
|
8
|
+
client_id = MockUDAPServer.client_uri_to_client_id(
|
9
|
+
MockUDAPServer.udap_client_uri_from_registration_payload(parsed_body)
|
10
|
+
)
|
11
|
+
ss_jwt = MockUDAPServer.udap_software_statement_jwt(parsed_body)
|
12
|
+
|
13
|
+
response_body = {
|
14
|
+
client_id:,
|
15
|
+
software_statement: ss_jwt
|
16
|
+
}
|
17
|
+
response_body.merge!(MockUDAPServer.jwt_claims(ss_jwt).except(['iss', 'sub', 'exp', 'iat', 'jti']))
|
18
|
+
|
19
|
+
response.body = response_body.to_json
|
20
|
+
response.headers['Cache-Control'] = 'no-store'
|
21
|
+
response.headers['Pragma'] = 'no-cache'
|
22
|
+
response.headers['Access-Control-Allow-Origin'] = '*'
|
23
|
+
response.content_type = 'application/json'
|
24
|
+
response.status = 201
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|