-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FI-2247 backend services migration #59
Conversation
require 'json/jwt' | ||
|
||
module SMARTAppLaunch | ||
class AuthorizationRequestBuilder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would hope that this and ClientAssertionBuilder
could be combined, as backend services authorization is based on the asymmetric client credentials authorization method. If we need a specific class to handle this for backend services, the class name should reflect that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ClientAssertionBuilder
and AuthorizationRequestBuilder
address different scopes and use cases for the tests that use them. AuthorizationRequestBuilder
, used for Backend Services, is too broad for use in standalone/EHR tests, and ClientAssertionBuilder
is too narrow for Backend Services (tests would have duplicated code across them that AuthRequestBuilder
addresses).
So I opted to keep both classes but had AuthRequestBuilder
use ClientAssertionBuilder
in building the requests, so there isn't redundant behavior between the two classes. I also renamed AuthRequestBuilder
to be specific to Backend Services, since those are the only tests that use it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't this being merged into main?
The preset needs to be updated. This functionality needs unit tests.
@@ -222,5 +223,7 @@ class SMARTSTU2Suite < Inferno::TestSuite | |||
|
|||
group from: :smart_token_introspection | |||
|
|||
group from: :smart_backend_services |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should go before the token introspection tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated so backend services shows up before token introspection tests.
test from: :tls_version_test do | ||
title 'Authorization service token endpoint secured by transport layer security' | ||
description <<~DESCRIPTION | ||
[§170.315(g)(10) Test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't contain anything g10 specific. Is this a backend services requirement or just a g10 requirement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a backend services requirement too, so I left it, but updated all naming so there isn't anything g10 specific.
The OAuth 2.0 Token Endpoint used by the Backend Services specification to provide bearer tokens. | ||
DESCRIPTION | ||
input :bulk_client_id, | ||
title: 'Bulk Data Client ID', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These titles should be updated as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All titles/inputs/descriptions have been updated so they no longer refer to bulk data.
) | ||
end | ||
|
||
test do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests should all be moved into their own files and given good ids.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each test was moved into its own file and given a descriptive ID.
|
||
id :smart_backend_services | ||
|
||
input :bulk_token_endpoint, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The input ids should be updated to reflect that these are backend services inputs not bulk data inputs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All inputs were updated.
@Jammjammjamm I mentioned in the PR summary that I split the original 2247 ticket into two tickets, and updated the definition of done for this one to be that the bulk data/backend services tests properly show up in the SMART test kit and that the tests pass with the reference server. Everything else beyond this (renaming, refactoring, unit tests, etc) will be addressed in the next ticket, 2369, that is still in progress. I set up an interim working branch to hold everything until the effort is completed. Rob and I used this approach for token introspection since we kept having to break down the tasking further, and it was helpful for me get PR feedback before things were ready for Thank you for the feedback though - it'll be very helpful as I get started on the next ticket. I will work through each one and reach out if I have questions. |
I don't think this work justifies a separate non-ephemeral branch. Rather than merging this into a separate branch, this should be a draft PR targeting main, and FI-2369, to the extent that it lines up with my comments, should be incorporated into this branch. Any work on enhancements needed to expand the functionality and make it more generic that were envisioned as part of FI-2369 would make sense as a separate ticket, but not the sort of organizational changes I'm requesting here. I'd be happy to discuss this further on slack if you like. |
Note that since `smart_token_url` is an input value set from the output of another test suite the preset does not properly apply. Need to determine how we want to handle this.
This reverts commit 0525bc0.
…inate redundant behavior
This class is currently used exclusively in backend services tests, so the class name now reflects that.
@Jammjammjamm I have addressed all of your PR feedback at this point except unit tests, so the PR is still a draft but is ready for re-review. I'll get started on unit tests while waiting for feedback. |
@@ -41,7 +41,7 @@ | |||
"value": null | |||
}, | |||
{ | |||
"name": "client_auth_encryption_method", | |||
"name": "asymm_conf_client_encryption_method", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should change this input name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name has been reverted back to client_auth_encryption_method
id :smart_backend_services_auth_request_success | ||
title 'Authorization request succeeds when supplied correct information' | ||
description <<~DESCRIPTION | ||
[The SMART Backend Services IG STU 2.0.0](https://hl7.org/fhir/smart-app-launch/STU2/backend-services.html#issue-access-token) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no SMART Backend Services IG. There's only the SMART App Launch IG.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the link titles to be "SMART App Launch 2.0.0 specification for Backend Services" instead.
@@ -220,6 +221,23 @@ class SMARTSTU2Suite < Inferno::TestSuite | |||
} | |||
end | |||
|
|||
group do | |||
title 'Backend Services' | |||
id :smart_full_backend_services |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is awkward. I think the subgroup should be something like "Backend Services Authorization" to avoid this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed main suite group to smart_backend_services
and the subgroup to smart_backend_services_authorization
@@ -1,5 +1,6 @@ | |||
require_relative 'client_assertion_builder' | |||
require_relative 'token_exchange_test' | |||
require_relative 'backend_services_group' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this test require the backend services group?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't, it was accidentally leftover from when I was testing some inputs and has been removed now.
Inferno::TestRunner.new(test_session:, test_run:).run(runnable) | ||
end | ||
|
||
describe '[Invalid grant_type] test' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason for these specs to be here rather than in a spec for the specific tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I copied and pasted the specs from the ones already present in the (g)(10) test kit, found in a single file here, and just made some minor naming updates for them to pass. If they need to be refactored and separated out to separate files I can do so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, they should each have their own file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spec tests have been refactored so each backend services test/class has its own spec file.
|
||
expect { | ||
build_and_decode_jwt(encryption_method, kid) | ||
}.to raise_error(RuntimeError) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Raising generic errors is something we try very hard to avoid in tests. What are the circumstances where this error could appear?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I included the underlying exception, found here, to support the new functionality of making the kid
of the JWKS a user input (from this PR). I found that when I entered a valid kid
but accidentally specified the wrong algorithm I got a somewhat cryptic error "undefined method signing_key
for nil:NilClass" in client_assertion_builder.rb
. What was happening was that the signing_key
method of that class was returning a null object as a result of there being no match for the specified kid
and algorithm
input when searching the key set. I catch an exception in this case to communicate that to the user.
Maybe this doesn't warrant the custom error message? Or if it does, there's a better way to structure the exception? I'm not very familiar with this in Ruby.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this error would be the result of bad inputs? If so, it should be an Inferno::Exceptions::AssertionException
. If this would be caused by private_key
being nil
, the intention would be clearer by having a guard against it being nil
that raises this exception rather than rescuing NoMethodError
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Yes, this is a result of bad inputs. I've updated this to check for a nil private_key
and to raise Inferno::Exceptions::AssertionException
instead.
end | ||
|
||
def client_assertion | ||
@client_assertion ||= ClientAssertionBuilder.build( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
require_relative 'client_assertion_builder' | ||
|
||
module SMARTAppLaunch | ||
class BackendServicesAuthorizationRequestBuilder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of these file names should be the lower snake case version of the class name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated all the file names (though some of them are pretty long now, hopefully that's okay).
@Jammjammjamm I addressed all of your comments and am ready for re-review. The following items in particular could use your input:
Thanks! |
@Jammjammjamm I addressed the remaining comments and am ready for re-review:
Confirmed that all spec tests are passing and tests in the browser pass with reference server preset. Thanks! |
Summary
Migrating the Bulk Data Authorization tests into the SMART App Launch test kit. Bulk Data test files were copied from the ONC (g)(10) Certification Test Kits, including this PR from an external contributor, and now live under a Backend Services group for STU2.
Updates From First Round of Feedback
ClientAssertionBuilder
andAuthenticationRequestBuilder
AuthenticationRequestBuilder
toBackendServicesAuthorizationRequestBuilder
and had it useClientAssertionBuilder
backend_services_client_id
Testing Guidance