smart_app_launch_test_kit 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 60325a0cc4d2866edb260627b289e76676d0847bd2e28523556f39170d424dac
4
- data.tar.gz: dd887ba5a645f71f16e9f2269886628ca5911d57c79e3d03699582d6ae810b7f
3
+ metadata.gz: f66c9b0314200d03d78422dc6412fe30cd0a091cd34d2a4701b9daa9a85d45f6
4
+ data.tar.gz: 7a34428293bfe281ebeebf83e8ee37597ebdfef2bf158cb8a3893598eca09876
5
5
  SHA512:
6
- metadata.gz: 16ee6a9963940d5ea882e894b5e1db23646c86a51e1f6dbe58868878c047708a581c0f353ba24d264a4c49cdc8f549f522afc40ee7bbd5127d89b0b9ac7f2e36
7
- data.tar.gz: 022f7b43c590f419638e23614a84dc0c5d106b87bbef38dd6d4b2e71650b58bf86db59bd6bb231c04280a0274e105b6486601fb41fa3749485ddfd534a15beb4
6
+ metadata.gz: d5f432c1b4b43a2c84be8613acb0b31dec557b80b1b76996773c76486db5197265a3dc1f0b9a9015eaa35c17c65d5b6b7eb506d940676e0cdae3b798b1cf8799
7
+ data.tar.gz: b63b86f90dbfc0ea88b7cc65e2075333b07a2cee7d42f88f21d209f4a51274545532706ed0278efad3cd4a0316be4ae32e948632f4ba66247d5451c68eff9559
@@ -0,0 +1,88 @@
1
+ require_relative 'backend_services_authorization_request_builder'
2
+ require_relative 'backend_services_invalid_grant_type_test'
3
+ require_relative 'backend_services_invalid_client_assertion_test'
4
+ require_relative 'backend_services_invalid_jwt_test'
5
+ require_relative 'backend_services_authorization_request_success_test'
6
+ require_relative 'backend_services_authorization_response_body_test'
7
+ require_relative 'token_exchange_stu2_test'
8
+
9
+ module SMARTAppLaunch
10
+ class BackendServicesAuthorizationGroup < Inferno::TestGroup
11
+ title 'SMART Backend Services Authorization'
12
+ short_description 'Demonstrate SMART Backend Services Authorization'
13
+
14
+ id :backend_services_authorization
15
+
16
+ input :smart_token_url,
17
+ title: 'Backend Services Token Endpoint',
18
+ description: <<~DESCRIPTION
19
+ The OAuth 2.0 Token Endpoint used by the Backend Services specification to provide bearer tokens.
20
+ DESCRIPTION
21
+
22
+ input :backend_services_client_id,
23
+ title: 'Backend Services Client ID',
24
+ description: 'Client ID provided at registration to the Inferno application.'
25
+ input :backend_services_requested_scope,
26
+ title: 'Backend Services Requested Scopes',
27
+ description: 'Backend Services Scopes provided at registration to the Inferno application; will be `system/` scopes',
28
+ default: 'system/*.read'
29
+
30
+ input :client_auth_encryption_method,
31
+ title: 'Encryption Method for Asymmetric Confidential Client Authorization',
32
+ description: <<~DESCRIPTION,
33
+ The server is required to suport either ES384 or RS384 encryption methods for JWT signature verification.
34
+ Select which method to use.
35
+ DESCRIPTION
36
+ type: 'radio',
37
+ default: 'ES384',
38
+ options: {
39
+ list_options: [
40
+ {
41
+ label: 'ES384',
42
+ value: 'ES384'
43
+ },
44
+ {
45
+ label: 'RS384',
46
+ value: 'RS384'
47
+ }
48
+ ]
49
+ }
50
+ input :backend_services_jwks_kid,
51
+ title: 'Backend Services JWKS kid',
52
+ description: <<~DESCRIPTION,
53
+ The key ID of the JWKS private key to use for signing the client assertion when fetching an auth token.
54
+ Defaults to the first JWK in the list if no kid is supplied.
55
+ DESCRIPTION
56
+ optional: true
57
+
58
+ output :bearer_token
59
+
60
+ test from: :tls_version_test do
61
+ title 'Authorization service token endpoint secured by transport layer security'
62
+ description <<~DESCRIPTION
63
+ The [SMART App Launch 2.0.0 IG specification for Backend Services](https://hl7.org/fhir/smart-app-launch/STU2/backend-services.html#request-1)
64
+ states "the client SHALL use the Transport Layer Security (TLS) Protocol Version 1.2 (RFC5246)
65
+ or a more recent version of TLS to authenticate the identity of the FHIR authorization server and to
66
+ establish an encrypted, integrity-protected link for securing all exchanges between the client and the
67
+ FHIR authorization server’s token endpoint. All exchanges described herein between the client and the
68
+ FHIR server SHALL be secured using TLS V1.2 or a more recent version of TLS."
69
+ DESCRIPTION
70
+ id :smart_backend_services_token_tls_version
71
+
72
+ config(
73
+ inputs: { url: { name: :smart_token_url } },
74
+ options: { minimum_allowed_version: OpenSSL::SSL::TLS1_2_VERSION }
75
+ )
76
+ end
77
+
78
+ test from: :smart_backend_services_invalid_grant_type
79
+
80
+ test from: :smart_backend_services_invalid_client_assertion
81
+
82
+ test from: :smart_backend_services_invalid_jwt
83
+
84
+ test from: :smart_backend_services_auth_request_success
85
+
86
+ test from: :smart_backend_services_auth_response_body
87
+ end
88
+ end
@@ -0,0 +1,74 @@
1
+ require 'json/jwt'
2
+ require_relative 'client_assertion_builder'
3
+
4
+ module SMARTAppLaunch
5
+ class BackendServicesAuthorizationRequestBuilder
6
+ def self.build(...)
7
+ new(...).authorization_request
8
+ end
9
+
10
+ attr_reader :encryption_method, :scope, :iss, :sub, :aud, :content_type, :grant_type, :client_assertion_type, :exp,
11
+ :jti, :kid
12
+
13
+ def initialize(
14
+ encryption_method:,
15
+ scope:,
16
+ iss:,
17
+ sub:,
18
+ aud:,
19
+ content_type: 'application/x-www-form-urlencoded',
20
+ grant_type: 'client_credentials',
21
+ client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
22
+ exp: 5.minutes.from_now,
23
+ jti: SecureRandom.hex(32),
24
+ kid: nil
25
+ )
26
+ @encryption_method = encryption_method
27
+ @scope = scope
28
+ @iss = iss
29
+ @sub = sub
30
+ @aud = aud
31
+ @content_type = content_type
32
+ @grant_type = grant_type
33
+ @client_assertion_type = client_assertion_type
34
+ @exp = exp
35
+ @jti = jti
36
+ @kid = kid
37
+ end
38
+
39
+ def authorization_request_headers
40
+ {
41
+ content_type:,
42
+ accept: 'application/json'
43
+ }.compact
44
+ end
45
+
46
+ def authorization_request_query_values
47
+ {
48
+ 'scope' => scope,
49
+ 'grant_type' => grant_type,
50
+ 'client_assertion_type' => client_assertion_type,
51
+ 'client_assertion' => client_assertion.to_s
52
+ }.compact
53
+ end
54
+
55
+ def client_assertion
56
+ @client_assertion ||= ClientAssertionBuilder.build(
57
+ client_auth_encryption_method: encryption_method,
58
+ iss: iss,
59
+ sub: sub,
60
+ aud: aud,
61
+ exp: exp.to_i,
62
+ jti: jti,
63
+ kid: kid
64
+ )
65
+ end
66
+
67
+ def authorization_request
68
+ uri = Addressable::URI.new
69
+ uri.query_values = authorization_request_query_values
70
+
71
+ { body: uri.query, headers: authorization_request_headers }
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,40 @@
1
+ require_relative 'backend_services_authorization_request_builder'
2
+ require_relative 'backend_services_authorization_group'
3
+
4
+ module SMARTAppLaunch
5
+ class BackendServicesAuthorizationRequestSuccessTest < Inferno::Test
6
+ id :smart_backend_services_auth_request_success
7
+ title 'Authorization request succeeds when supplied correct information'
8
+ description <<~DESCRIPTION
9
+ The [SMART App Launch 2.0.0 IG specification for Backend Services](https://hl7.org/fhir/smart-app-launch/STU2/backend-services.html#issue-access-token)
10
+ states "If the access token request is valid and authorized, the authorization server SHALL issue an access token in response."
11
+ DESCRIPTION
12
+
13
+ input :client_auth_encryption_method,
14
+ :backend_services_requested_scope,
15
+ :backend_services_client_id,
16
+ :smart_token_url,
17
+ :backend_services_jwks_kid
18
+
19
+ output :authentication_response
20
+
21
+ http_client :token_endpoint do
22
+ url :smart_token_url
23
+ end
24
+
25
+ run do
26
+ post_request_content = BackendServicesAuthorizationRequestBuilder.build(encryption_method: client_auth_encryption_method,
27
+ scope: backend_services_requested_scope,
28
+ iss: backend_services_client_id,
29
+ sub: backend_services_client_id,
30
+ aud: smart_token_url,
31
+ kid: backend_services_jwks_kid)
32
+
33
+ authentication_response = post(**{ client: :token_endpoint }.merge(post_request_content))
34
+
35
+ assert_response_status([200, 201])
36
+
37
+ output authentication_response: authentication_response.response_body
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,40 @@
1
+ require_relative 'backend_services_authorization_request_builder'
2
+
3
+ module SMARTAppLaunch
4
+ class BackendServicesAuthorizationResponseBodyTest < Inferno::Test
5
+ id :smart_backend_services_auth_response_body
6
+ title 'Authorization request response body contains required information encoded in JSON'
7
+ description <<~DESCRIPTION
8
+ The [SMART App Launch 2.0.0 IG specification for Backend Services](https://hl7.org/fhir/smart-app-launch/STU2/backend-services.html#issue-access-token)
9
+ states The access token response SHALL be a JSON object with the following properties:
10
+
11
+ | Token Property | Required? | Description |
12
+ | --- | --- | --- |
13
+ | `access_token` | required | The access token issued by the authorization server. |
14
+ | `token_type` | required | Fixed value: `bearer`. |
15
+ | `expires_in` | required | The lifetime in seconds of the access token. The recommended value is `300`, for a five-minute token lifetime. |
16
+ | `scope` | required | Scope of access authorized. Note that this can be different from the scopes requested by the app. |
17
+ DESCRIPTION
18
+
19
+ input :authentication_response
20
+ output :bearer_token
21
+
22
+ run do
23
+ skip_if authentication_response.blank?, 'No authentication response received.'
24
+
25
+ assert_valid_json(authentication_response)
26
+ response_body = JSON.parse(authentication_response)
27
+
28
+ access_token = response_body['access_token']
29
+ assert access_token.present?, 'Token response did not contain access_token as required'
30
+
31
+ output bearer_token: access_token
32
+
33
+ required_keys = ['token_type', 'expires_in', 'scope']
34
+
35
+ required_keys.each do |key|
36
+ assert response_body[key].present?, "Token response did not contain #{key} as required"
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,44 @@
1
+ require_relative 'backend_services_authorization_request_builder'
2
+
3
+ module SMARTAppLaunch
4
+ class BackendServicesInvalidClientAssertionTest < Inferno::Test
5
+ id :smart_backend_services_invalid_client_assertion
6
+ title 'Authorization request fails when supplied invalid client_assertion_type'
7
+ description <<~DESCRIPTION
8
+ The [SMART App Launch 2.0.0 IG specification for Backend Services](https://hl7.org/fhir/smart-app-launch/STU2/backend-services.html#request-1)
9
+ defines the required fields for the authorization request, made via HTTP POST to authorization
10
+ token endpoint.
11
+ This includes the `client_assertion_type` parameter, where the value must be `urn:ietf:params:oauth:client-assertion-type:jwt-bearer`.
12
+
13
+ The [OAuth 2.0 Authorization Framework Section 4.3.3](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3.3)
14
+ describes the proper response for an invalid request in the client credentials grant flow:
15
+
16
+ "If the request failed client authentication or is invalid, the authorization server returns an
17
+ error response as described in [Section 5.2](https://tools.ietf.org/html/rfc6749#section-5.2)."
18
+ DESCRIPTION
19
+
20
+ input :client_auth_encryption_method,
21
+ :backend_services_requested_scope,
22
+ :backend_services_client_id,
23
+ :smart_token_url,
24
+ :backend_services_jwks_kid
25
+
26
+ http_client :token_endpoint do
27
+ url :smart_token_url
28
+ end
29
+
30
+ run do
31
+ post_request_content = BackendServicesAuthorizationRequestBuilder.build(encryption_method: client_auth_encryption_method,
32
+ scope: backend_services_requested_scope,
33
+ iss: backend_services_client_id,
34
+ sub: backend_services_client_id,
35
+ aud: smart_token_url,
36
+ client_assertion_type: 'not_an_assertion_type',
37
+ kid: backend_services_jwks_kid)
38
+
39
+ post(**{ client: :token_endpoint }.merge(post_request_content))
40
+
41
+ assert_response_status(400)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+ require_relative 'backend_services_authorization_request_builder'
2
+
3
+ module SMARTAppLaunch
4
+ class BackendServicesInvalidGrantTypeTest < Inferno::Test
5
+ id :smart_backend_services_invalid_grant_type
6
+ title 'Authorization request fails when client supplies invalid grant_type'
7
+ description <<~DESCRIPTION
8
+ The [SMART App Launch 2.0.0 IG section on Backend Services](https://hl7.org/fhir/smart-app-launch/STU2/backend-services.html#request-1)
9
+ defines the required fields for the authorization request, made via HTTP POST to authorization
10
+ token endpoint.
11
+ This includes the `grant_type` parameter, where the value must be `client_credentials`.
12
+
13
+ The [OAuth 2.0 Authorization Framework Section 4.3.3](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3.3)
14
+ describes the proper response for an invalid request in the client credentials grant flow:
15
+
16
+ "If the request failed client authentication or is invalid, the authorization server returns an
17
+ error response as described in [Section 5.2](https://tools.ietf.org/html/rfc6749#section-5.2)."
18
+ DESCRIPTION
19
+
20
+ input :client_auth_encryption_method,
21
+ :backend_services_requested_scope,
22
+ :backend_services_client_id,
23
+ :smart_token_url,
24
+ :backend_services_jwks_kid
25
+
26
+ http_client :token_endpoint do
27
+ url :smart_token_url
28
+ end
29
+
30
+ run do
31
+ post_request_content = BackendServicesAuthorizationRequestBuilder.build(encryption_method: client_auth_encryption_method,
32
+ scope: backend_services_requested_scope,
33
+ iss: backend_services_client_id,
34
+ sub: backend_services_client_id,
35
+ aud: smart_token_url,
36
+ grant_type: 'not_a_grant_type',
37
+ kid: backend_services_jwks_kid)
38
+
39
+ post(**{ client: :token_endpoint }.merge(post_request_content))
40
+
41
+ assert_response_status(400)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,55 @@
1
+ require_relative 'backend_services_authorization_request_builder'
2
+
3
+ module SMARTAppLaunch
4
+ class BackendServicesInvalidJWTTest < Inferno::Test
5
+ id :smart_backend_services_invalid_jwt
6
+ title 'Authorization request fails when client supplies invalid JWT token'
7
+ description <<~DESCRIPTION
8
+ The [SMART App Launch 2.0.0 IG section on Backend Services](https://hl7.org/fhir/smart-app-launch/STU2/backend-services.html#request-1)
9
+ defines the required fields for the authorization request, made via HTTP POST to authorization
10
+ token endpoint.
11
+ This includes the `client_assertion` parameter, where the value must be
12
+ a valid JWT as specified in
13
+ [Asymmetric (public key) Client Authentication](https://hl7.org/fhir/smart-app-launch/STU2/client-confidential-asymmetric.html#authenticating-to-the-token-endpoint)
14
+ The JWT SHALL include the following claims, and SHALL be signed with the client’s private key.
15
+
16
+ | JWT Claim | Required? | Description |
17
+ | --- | --- | --- |
18
+ | `iss` | required | Issuer of the JWT -- the client's `client_id`, as determined during registration with the FHIR authorization server (note that this is the same as the value for the sub claim) |
19
+ | `sub` | required | The service's `client_id`, as determined during registration with the FHIR authorization server (note that this is the same as the value for the `iss` claim) |
20
+ | `aud` | required | The FHIR authorization server's "token URL" (the same URL to which this authentication JWT will be posted) |
21
+ | `exp` | required | Expiration time integer for this authentication JWT, expressed in seconds since the "Epoch" (1970-01-01T00:00:00Z UTC). This time SHALL be no more than five minutes in the future. |
22
+ | `jti` | required | A nonce string value that uniquely identifies this authentication JWT. |
23
+
24
+ The [OAuth 2.0 Authorization Framework Section 4.3.3](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3.3)
25
+ describes the proper response for an invalid request in the client credentials grant flow:
26
+
27
+ "If the request failed client authentication or is invalid, the authorization server returns an
28
+ error response as described in [Section 5.2](https://tools.ietf.org/html/rfc6749#section-5.2)."
29
+ DESCRIPTION
30
+
31
+ input :client_auth_encryption_method,
32
+ :backend_services_requested_scope,
33
+ :backend_services_client_id,
34
+ :smart_token_url,
35
+ :backend_services_jwks_kid
36
+
37
+ http_client :token_endpoint do
38
+ url :smart_token_url
39
+ end
40
+
41
+ run do
42
+ post_request_content = BackendServicesAuthorizationRequestBuilder.build(encryption_method: client_auth_encryption_method,
43
+ scope: backend_services_requested_scope,
44
+ iss: backend_services_client_id,
45
+ sub: backend_services_client_id,
46
+ aud: smart_token_url,
47
+ client_assertion_type: 'not_an_assertion_type',
48
+ kid: backend_services_jwks_kid)
49
+
50
+ post(**{ client: :token_endpoint }.merge(post_request_content))
51
+
52
+ assert_response_status(400)
53
+ end
54
+ end
55
+ end
@@ -16,7 +16,8 @@ module SMARTAppLaunch
16
16
  :grant_type,
17
17
  :iss,
18
18
  :jti,
19
- :sub
19
+ :sub,
20
+ :kid
20
21
 
21
22
  def initialize(
22
23
  client_auth_encryption_method:,
@@ -24,7 +25,8 @@ module SMARTAppLaunch
24
25
  sub:,
25
26
  aud:,
26
27
  exp: 5.minutes.from_now.to_i,
27
- jti: SecureRandom.hex(32)
28
+ jti: SecureRandom.hex(32),
29
+ kid: nil
28
30
  )
29
31
  @client_auth_encryption_method = client_auth_encryption_method
30
32
  @iss = iss
@@ -35,29 +37,35 @@ module SMARTAppLaunch
35
37
  @client_assertion_type = client_assertion_type
36
38
  @exp = exp
37
39
  @jti = jti
40
+ @kid = kid
38
41
  end
39
42
 
40
43
  def private_key
41
- @private_key ||=
42
- JWKS.jwks
43
- .find { |key| key[:key_ops]&.include?('sign') && key[:alg] == client_auth_encryption_method }
44
+ @private_key ||= JWKS.jwks
45
+ .select { |key| key[:key_ops]&.include?('sign') }
46
+ .select { |key| key[:alg] == client_auth_encryption_method }
47
+ .find { |key| !kid || key[:kid] == kid }
44
48
  end
45
49
 
46
50
  def jwt_payload
47
51
  { iss:, sub:, aud:, exp:, jti: }.compact
48
52
  end
49
53
 
50
- def kid
51
- private_key.kid
54
+ def signing_key
55
+ private_key()
56
+ if @private_key.nil?
57
+ raise Inferno::Exceptions::AssertionException, "No signing key found for inputs: encryption method = '#{client_auth_encryption_method}' and kid = '#{kid}'"
58
+ end
59
+ return @private_key.signing_key
52
60
  end
53
61
 
54
- def signing_key
55
- private_key.signing_key
62
+ def key_id
63
+ @private_key['kid']
56
64
  end
57
65
 
58
66
  def client_assertion
59
67
  @client_assertion ||=
60
- JWT.encode jwt_payload, signing_key, client_auth_encryption_method, { alg: client_auth_encryption_method, kid:, typ: 'JWT' }
68
+ JWT.encode jwt_payload, signing_key, client_auth_encryption_method, { alg: client_auth_encryption_method, kid: key_id, typ: 'JWT' }
61
69
  end
62
70
  end
63
71
  end
@@ -8,6 +8,7 @@ require_relative 'ehr_launch_group_stu2'
8
8
  require_relative 'openid_connect_group'
9
9
  require_relative 'token_introspection_group'
10
10
  require_relative 'token_refresh_group'
11
+ require_relative 'backend_services_authorization_group'
11
12
 
12
13
  module SMARTAppLaunch
13
14
  class SMARTSTU2Suite < Inferno::TestSuite
@@ -220,6 +221,23 @@ module SMARTAppLaunch
220
221
  }
221
222
  end
222
223
 
224
+ group do
225
+ title 'Backend Services'
226
+ id :smart_backend_services
227
+
228
+ input_instructions <<~INSTRUCTIONS
229
+ Please register the Inferno client with the authorization services with the
230
+ following JWK Set URL:
231
+
232
+ * `#{Inferno::Application[:base_url]}/custom/smart_stu2/.well-known/jwks.json`
233
+ INSTRUCTIONS
234
+
235
+ run_as_group
236
+
237
+ group from: :smart_discovery_stu2
238
+ group from: :backend_services_authorization
239
+ end
240
+
223
241
  group from: :smart_token_introspection
224
242
 
225
243
  end
@@ -14,21 +14,21 @@ module SMARTAppLaunch
14
14
  id :smart_token_exchange_stu2
15
15
 
16
16
  input :client_auth_encryption_method,
17
- title: 'Encryption Method (Confidential Asymmetric Client Auth Only)',
18
- type: 'radio',
19
- default: 'ES384',
20
- options: {
21
- list_options: [
22
- {
23
- label: 'ES384',
24
- value: 'ES384'
25
- },
26
- {
27
- label: 'RS384',
28
- value: 'RS384'
29
- }
30
- ]
17
+ title: 'Encryption Method (Confidential Asymmetric Client Auth Only)',
18
+ type: 'radio',
19
+ default: 'ES384',
20
+ options: {
21
+ list_options: [
22
+ {
23
+ label: 'ES384',
24
+ value: 'ES384'
25
+ },
26
+ {
27
+ label: 'RS384',
28
+ value: 'RS384'
31
29
  }
30
+ ]
31
+ }
32
32
 
33
33
  input :client_auth_type,
34
34
  title: 'Client Authentication Method',
@@ -1,3 +1,3 @@
1
1
  module SMARTAppLaunch
2
- VERSION = '0.4.0'.freeze
2
+ VERSION = '0.4.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_app_launch_test_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen MacVicar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-08 00:00:00.000000000 Z
11
+ date: 2024-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: inferno_core
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.4.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: json-jwt
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.15.3
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.15.3
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: jwt
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -134,6 +148,13 @@ files:
134
148
  - lib/smart_app_launch/app_launch_test.rb
135
149
  - lib/smart_app_launch/app_redirect_test.rb
136
150
  - lib/smart_app_launch/app_redirect_test_stu2.rb
151
+ - lib/smart_app_launch/backend_services_authorization_group.rb
152
+ - lib/smart_app_launch/backend_services_authorization_request_builder.rb
153
+ - lib/smart_app_launch/backend_services_authorization_request_success_test.rb
154
+ - lib/smart_app_launch/backend_services_authorization_response_body_test.rb
155
+ - lib/smart_app_launch/backend_services_invalid_client_assertion_test.rb
156
+ - lib/smart_app_launch/backend_services_invalid_grant_type_test.rb
157
+ - lib/smart_app_launch/backend_services_invalid_jwt_test.rb
137
158
  - lib/smart_app_launch/client_assertion_builder.rb
138
159
  - lib/smart_app_launch/code_received_test.rb
139
160
  - lib/smart_app_launch/discovery_stu1_group.rb