Skip to content

Commit

Permalink
FI-3175 Allow testers to specify new or updated client registration a…
Browse files Browse the repository at this point in the history
…ttempt (#17)

* Create client_registration_status input in test, groups

* Update registration success test to check input for expected response code

* Update registration success spec tests to check for 200 vs 201 response type

* Update input instructions and test descriptions

* Accept 200 or 201 response status for successful updated registration requests

* Update input instructions and test descriptions
  • Loading branch information
alisawallace authored Dec 20, 2024
1 parent e39d62c commit c1301a0
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 19 deletions.
4 changes: 4 additions & 0 deletions lib/udap_security_test_kit/authorization_code_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ class AuthorizationCodeGroup < Inferno::TestGroup
default: 'authorization_code',
locked: true
},
udap_client_registration_status: {
name: :udap_auth_code_flow_client_registration_status
},
udap_client_cert_pem: {
name: :udap_auth_code_flow_client_cert_pem,
title: 'Authorization Code Client Certificate(s) (PEM Format)'
Expand Down Expand Up @@ -90,6 +93,7 @@ class AuthorizationCodeGroup < Inferno::TestGroup
} do
input_order :udap_registration_endpoint,
:udap_auth_code_flow_registration_grant_type,
:udap_auth_code_flow_client_registration_status,
:udap_auth_code_flow_client_cert_pem,
:udap_auth_code_flow_client_private_key,
:udap_auth_code_flow_cert_iss,
Expand Down
4 changes: 4 additions & 0 deletions lib/udap_security_test_kit/client_credentials_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ class ClientCredentialsGroup < Inferno::TestGroup
default: 'client_credentials',
locked: true
},
udap_client_registration_status: {
name: :udap_client_credentials_flow_client_registration_status
},
udap_client_cert_pem: {
name: :udap_client_credentials_flow_client_cert_pem,
title: 'Client Credentials Client Certificate(s) (PEM Format)'
Expand Down Expand Up @@ -92,6 +95,7 @@ class ClientCredentialsGroup < Inferno::TestGroup
} do
input_order :udap_registration_endpoint,
:udap_client_credentials_flow_registration_grant_type,
:udap_client_credentials_flow_client_registration_status,
:udap_client_credentials_flow_client_cert_pem,
:udap_client_credentials_flow_client_private_key,
:udap_cert_iss_client_creds_flow,
Expand Down
34 changes: 27 additions & 7 deletions lib/udap_security_test_kit/dynamic_client_registration_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,12 @@ def self.dynamic_client_registration_input_instructions
establish a trust chain.
Cancelling a UDAP client's registration is not a required server capability and as such the Inferno client has no
way of resetting state on the authorization server after a successful registration attempt. Testers wishing to
run the Dynamic Client Registration tests more than once must do one of the following:
- Remove the Inferno test client's registration out-of-band before re-running tests, to register the original
client URI anew
- Specifiy a different client URI as the issuer input (if the client cert has more than one Subject Alternative
Name (SAN) URI entry), to register a different logical client with the original certificate
- Provide a different client certificate and its associated URI to register a new logical client
way of resetting state on the authorization server after a successful registration attempt. If a given
certificate and issuer URI identity combination has already been registered with the authorization server, testers
whose systems support registration modifications
may select the "Update Registration" option under Client Registration Status. This option will accept either a
`200 OK` or `201 Created` return status. Registration attempts for a new client may only return `201 Created`,
per the [IG](https://hl7.org/fhir/us/udap-security/STU1/registration.html#request-body).
)
end

Expand Down Expand Up @@ -57,6 +56,27 @@ def self.dynamic_client_registration_input_instructions
]
}

input :udap_client_registration_status,
title: 'Client Registration Status',
description: %(
If the client's iss and certificate combination has already been registered with the authorization server
prior to this test run, select 'Update'.
),
type: 'radio',
options: {
list_options: [
{
label: 'New Registration (201 Response Code Expected)',
value: 'new'
},
{
label: 'Update Registration (200 or 201 Response Code Expected)',
value: 'update'
}
]
},
default: 'new'

input :udap_client_cert_pem,
title: 'X.509 Client Certificate(s) (PEM Format)',
description: %(
Expand Down
16 changes: 15 additions & 1 deletion lib/udap_security_test_kit/registration_success_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,22 @@ class RegistrationSuccessTest < Inferno::Test
The [UDAP IG Section 3.2.3](https://hl7.org/fhir/us/udap-security/STU1/registration.html#request-body) states:
> If a new registration is successful, the Authorization Server SHALL return a registration response with a 201
> Created HTTP response code as per Section 5.1 of UDAP Dynamic Client Registration
If the tester indicated this registration attempt represents a modification of an existing registration entry,
the [UDAP IG Section 3.4](https://hl7.org/fhir/us/udap-security/STU1/registration.html#modifying-and-cancelling-registrations)
states:
> If the Authorization Server returns the same client_id in the registration response for a modification request,
> it SHOULD also return a 200 OK HTTP response code.
In this case, the test will require either a 201 or 200 response code to pass.
)

input :udap_client_cert_pem
input :udap_client_private_key_pem
input :udap_cert_iss

input :udap_registration_endpoint
input :udap_client_registration_status
input :udap_jwt_signing_alg
input :udap_registration_requested_scope
input :udap_registration_grant_type
Expand Down Expand Up @@ -60,7 +69,12 @@ class RegistrationSuccessTest < Inferno::Test

post(udap_registration_endpoint, body: reg_body, headers: reg_headers)

assert_response_status(201)
if udap_client_registration_status == 'new'
assert_response_status(201)
elsif udap_client_registration_status == 'update'
assert_response_status([200, 201])
end

assert_valid_json(response[:body])
output udap_registration_response: response[:body]
end
Expand Down
58 changes: 47 additions & 11 deletions spec/udap_security_test_kit/registration_success_test_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
let(:udap_registration_requested_scope) { 'system/*' }
let(:udap_registration_grant_type) { 'client_credentials' }
let(:udap_registration_certifications) { '' }
let(:udap_client_registration_status) { 'new' }
let(:input) do
{
udap_client_cert_pem:,
Expand All @@ -30,7 +31,8 @@
udap_jwt_signing_alg:,
udap_registration_requested_scope:,
udap_registration_grant_type:,
udap_registration_certifications:
udap_registration_certifications:,
udap_client_registration_status:
}
end

Expand All @@ -48,21 +50,55 @@ def run(runnable, inputs = {})
Inferno::TestRunner.new(test_session:, test_run:).run(runnable)
end

it 'fails if response status is not 201' do
stub_request(:post, udap_registration_endpoint)
.to_return(status: 400, body: {}.to_json)
context 'when new client is being registered' do
it 'fails if response status is not 201' do
stub_request(:post, udap_registration_endpoint)
.to_return(status: 200, body: {}.to_json)

result = run(runnable, input)
result = run(runnable, input)

expect(result.result).to eq('fail')
expect(result.result).to eq('fail')
end

it 'passes when response status is 201' do
stub_request(:post, udap_registration_endpoint)
.to_return(status: 201, body: {}.to_json)

result = run(runnable, input)

expect(result.result).to eq('pass')
end
end

it 'passes when response status is 201' do
stub_request(:post, udap_registration_endpoint)
.to_return(status: 201, body: {}.to_json)
context 'when existing client is updating its registration data' do
it 'fails if response status is not 200 or 201' do
stub_request(:post, udap_registration_endpoint)
.to_return(status: 401, body: {}.to_json)

input[:udap_client_registration_status] = 'update'
result = run(runnable, input)

expect(result.result).to eq('fail')
end

it 'passes when response status is 200' do
stub_request(:post, udap_registration_endpoint)
.to_return(status: 200, body: {}.to_json)

result = run(runnable, input)
input[:udap_client_registration_status] = 'update'
result = run(runnable, input)

expect(result.result).to eq('pass')
end

expect(result.result).to eq('pass')
it 'passes when response status is 201' do
stub_request(:post, udap_registration_endpoint)
.to_return(status: 201, body: {}.to_json)

input[:udap_client_registration_status] = 'update'
result = run(runnable, input)

expect(result.result).to eq('pass')
end
end
end

0 comments on commit c1301a0

Please sign in to comment.