udap_security_test_kit 0.11.4 → 0.11.5
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/lib/udap_security_test_kit/client_suite.rb +2 -0
 - data/lib/udap_security_test_kit/endpoints/mock_udap_server/introspection_endpoint.rb +34 -0
 - data/lib/udap_security_test_kit/endpoints/mock_udap_server/udap_introspection_response_creation.rb +71 -0
 - data/lib/udap_security_test_kit/endpoints/mock_udap_server.rb +6 -3
 - data/lib/udap_security_test_kit/tags.rb +1 -0
 - data/lib/udap_security_test_kit/urls.rb +5 -0
 - data/lib/udap_security_test_kit/version.rb +2 -2
 - metadata +4 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 8cd9e461b7c07f1562d3cd0633dad2816f6b9a93b56a4f21d82ed608386e2035
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 636e8a27be86aaca468218ed36f8253e6ede05ef995c8cd28664636944a52b72
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 8f6b32492245d75331ca03fa96a6fcd3169894e6cb09788a2e07cd851f40fcdb776133c91488e806e663e0166042e0f361ddcd59e350664c1b2ecfce316513ef
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 4b6f85396f9dd0b4918672756471a9690f56e8b0161bd6b097baa0317728bb8491c0629792b5255dc2c25f092cfc61f0ee368ab110ca45fadf21614a8d1a3834
         
     | 
| 
         @@ -1,6 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require_relative 'endpoints/mock_udap_server/registration_endpoint'
         
     | 
| 
       2 
2 
     | 
    
         
             
            require_relative 'endpoints/mock_udap_server/authorization_endpoint'
         
     | 
| 
       3 
3 
     | 
    
         
             
            require_relative 'endpoints/mock_udap_server/token_endpoint'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative 'endpoints/mock_udap_server/introspection_endpoint'
         
     | 
| 
       4 
5 
     | 
    
         
             
            require_relative 'endpoints/echoing_fhir_responder_endpoint'
         
     | 
| 
       5 
6 
     | 
    
         
             
            require_relative 'urls'
         
     | 
| 
       6 
7 
     | 
    
         
             
            require_relative 'client_suite/registration_ac_group'
         
     | 
| 
         @@ -61,6 +62,7 @@ module UDAPSecurityTestKit 
     | 
|
| 
       61 
62 
     | 
    
         
             
                suite_endpoint :post, REGISTRATION_PATH, MockUDAPServer::RegistrationEndpoint
         
     | 
| 
       62 
63 
     | 
    
         
             
                suite_endpoint :get, AUTHORIZATION_PATH, MockUDAPServer::AuthorizationEndpoint
         
     | 
| 
       63 
64 
     | 
    
         
             
                suite_endpoint :post, AUTHORIZATION_PATH, MockUDAPServer::AuthorizationEndpoint
         
     | 
| 
      
 65 
     | 
    
         
            +
                suite_endpoint :post, INTROSPECTION_PATH, MockUDAPServer::IntrospectionEndpoint
         
     | 
| 
       64 
66 
     | 
    
         
             
                suite_endpoint :post, TOKEN_PATH, MockUDAPServer::TokenEndpoint
         
     | 
| 
       65 
67 
     | 
    
         
             
                suite_endpoint :get, FHIR_PATH, EchoingFHIRResponderEndpoint
         
     | 
| 
       66 
68 
     | 
    
         
             
                suite_endpoint :post, FHIR_PATH, EchoingFHIRResponderEndpoint
         
     | 
| 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative '../../tags'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative '../mock_udap_server'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative 'udap_introspection_response_creation'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            module UDAPSecurityTestKit
         
     | 
| 
      
 8 
     | 
    
         
            +
              module MockUDAPServer
         
     | 
| 
      
 9 
     | 
    
         
            +
                class IntrospectionEndpoint < Inferno::DSL::SuiteEndpoint
         
     | 
| 
      
 10 
     | 
    
         
            +
                  include UDAPIntrospectionResponseCreation
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  def test_run_identifier
         
     | 
| 
      
 13 
     | 
    
         
            +
                    MockUDAPServer.issued_token_to_client_id(request.params[:token])
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def make_response
         
     | 
| 
      
 17 
     | 
    
         
            +
                    response.body = make_udap_introspection_response.to_json
         
     | 
| 
      
 18 
     | 
    
         
            +
                    response.headers['Cache-Control'] = 'no-store'
         
     | 
| 
      
 19 
     | 
    
         
            +
                    response.headers['Pragma'] = 'no-cache'
         
     | 
| 
      
 20 
     | 
    
         
            +
                    response.headers['Access-Control-Allow-Origin'] = '*'
         
     | 
| 
      
 21 
     | 
    
         
            +
                    response.content_type = 'application/json'
         
     | 
| 
      
 22 
     | 
    
         
            +
                    response.status = 200
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  def update_result
         
     | 
| 
      
 26 
     | 
    
         
            +
                    nil # never update for now
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  def tags
         
     | 
| 
      
 30 
     | 
    
         
            +
                    [INTROSPECTION_TAG, UDAP_TAG]
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/udap_security_test_kit/endpoints/mock_udap_server/udap_introspection_response_creation.rb
    ADDED
    
    | 
         @@ -0,0 +1,71 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative '../../tags'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative '../mock_udap_server'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module UDAPSecurityTestKit
         
     | 
| 
      
 5 
     | 
    
         
            +
              module MockUDAPServer
         
     | 
| 
      
 6 
     | 
    
         
            +
                module UDAPIntrospectionResponseCreation
         
     | 
| 
      
 7 
     | 
    
         
            +
                  def make_udap_introspection_response # rubocop:disable Metrics/CyclomaticComplexity
         
     | 
| 
      
 8 
     | 
    
         
            +
                    target_token = request.params[:token]
         
     | 
| 
      
 9 
     | 
    
         
            +
                    introspection_inactive_response_body = { active: false }
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                    return introspection_inactive_response_body if MockUDAPServer.token_expired?(target_token)
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                    token_requests = Inferno::Repositories::Requests.new.tagged_requests(test_run.test_session_id, [TOKEN_TAG])
         
     | 
| 
      
 14 
     | 
    
         
            +
                    original_response_body = nil
         
     | 
| 
      
 15 
     | 
    
         
            +
                    original_token_request = token_requests.find do |request|
         
     | 
| 
      
 16 
     | 
    
         
            +
                      next unless request.status == 200
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                      original_response_body = JSON.parse(request.response_body)
         
     | 
| 
      
 19 
     | 
    
         
            +
                      original_response_body['access_token'] == target_token
         
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
                    return introspection_inactive_response_body unless original_token_request.present?
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                    decoded_token = MockUDAPServer.decode_token(target_token)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    introspection_active_response_body = {
         
     | 
| 
      
 25 
     | 
    
         
            +
                      active: true,
         
     | 
| 
      
 26 
     | 
    
         
            +
                      client_id: decoded_token['client_id'],
         
     | 
| 
      
 27 
     | 
    
         
            +
                      exp: decoded_token['expiration']
         
     | 
| 
      
 28 
     | 
    
         
            +
                    }
         
     | 
| 
      
 29 
     | 
    
         
            +
                    original_response_body.each do |element, value|
         
     | 
| 
      
 30 
     | 
    
         
            +
                      next if ['access_token', 'refresh_token', 'token_type', 'expires_in'].include?(element)
         
     | 
| 
      
 31 
     | 
    
         
            +
                      next if introspection_active_response_body.key?(element)
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                      introspection_active_response_body[element] = value
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
                    unless introspection_active_response_body.key?('scope')
         
     | 
| 
      
 36 
     | 
    
         
            +
                      introspection_active_response_body['scope'] = requested_scope(original_token_request)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    end
         
     | 
| 
      
 38 
     | 
    
         
            +
                    if original_response_body.key?('id_token')
         
     | 
| 
      
 39 
     | 
    
         
            +
                      user_claims, _header = JWT.decode(original_response_body['id_token'], nil, false)
         
     | 
| 
      
 40 
     | 
    
         
            +
                      introspection_active_response_body['iss'] = user_claims['iss']
         
     | 
| 
      
 41 
     | 
    
         
            +
                      introspection_active_response_body['sub'] = user_claims['sub']
         
     | 
| 
      
 42 
     | 
    
         
            +
                      introspection_active_response_body['fhirUser'] = user_claims['fhirUser'] if user_claims['fhirUser'].present?
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                    introspection_active_response_body
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  def requested_scope(token_request)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    # token request
         
     | 
| 
      
 50 
     | 
    
         
            +
                    original_request_body = Rack::Utils.parse_query(token_request.request_body)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    return original_request_body['scope'] if original_request_body['scope'].present?
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                    # authorization request
         
     | 
| 
      
 54 
     | 
    
         
            +
                    authorization_request = MockUDAPServer.authorization_request_for_code(original_request_body['code'],
         
     | 
| 
      
 55 
     | 
    
         
            +
                                                                                          test_run.test_session_id)
         
     | 
| 
      
 56 
     | 
    
         
            +
                    auth_code_request_inputs = MockUDAPServer.authorization_code_request_details(authorization_request)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    return auth_code_request_inputs['scope'] if auth_code_request_inputs&.dig('scope').present?
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                    # registration request
         
     | 
| 
      
 60 
     | 
    
         
            +
                    # not looking in registration response since the simulation currently echoes the requested scopes
         
     | 
| 
      
 61 
     | 
    
         
            +
                    registered_software_statement = MockUDAPServer.udap_registration_software_statement(test_run.test_session_id)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    if registered_software_statement.present?
         
     | 
| 
      
 63 
     | 
    
         
            +
                      registration_body, _registration_header = JWT.decode(registered_software_statement, nil, false)
         
     | 
| 
      
 64 
     | 
    
         
            +
                      return registration_body['scope'] if registration_body['scope'].present?
         
     | 
| 
      
 65 
     | 
    
         
            +
                    end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
                end
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -29,6 +29,7 @@ module UDAPSecurityTestKit 
     | 
|
| 
       29 
29 
     | 
    
         
             
                    token_endpoint: base_url + TOKEN_PATH,
         
     | 
| 
       30 
30 
     | 
    
         
             
                    token_endpoint_auth_methods_supported: ['private_key_jwt'],
         
     | 
| 
       31 
31 
     | 
    
         
             
                    token_endpoint_auth_signing_alg_values_supported: ['RS256', 'RS384', 'ES384'],
         
     | 
| 
      
 32 
     | 
    
         
            +
                    introspection_endpoint: base_url + INTROSPECTION_PATH,
         
     | 
| 
       32 
33 
     | 
    
         
             
                    signed_metadata: udap_signed_metadata_jwt(base_url)
         
     | 
| 
       33 
34 
     | 
    
         
             
                  }.to_json
         
     | 
| 
       34 
35 
     | 
    
         | 
| 
         @@ -165,8 +166,8 @@ module UDAPSecurityTestKit 
     | 
|
| 
       165 
166 
     | 
    
         
             
                    end
         
     | 
| 
       166 
167 
     | 
    
         
             
                  return unless token_to_decode.present?
         
     | 
| 
       167 
168 
     | 
    
         | 
| 
       168 
     | 
    
         
            -
                  JSON.parse(Base64.urlsafe_decode64( 
     | 
| 
       169 
     | 
    
         
            -
                rescue  
     | 
| 
      
 169 
     | 
    
         
            +
                  JSON.parse(Base64.urlsafe_decode64(token_to_decode))
         
     | 
| 
      
 170 
     | 
    
         
            +
                rescue StandardError
         
     | 
| 
       170 
171 
     | 
    
         
             
                  nil
         
     | 
| 
       171 
172 
     | 
    
         
             
                end
         
     | 
| 
       172 
173 
     | 
    
         | 
| 
         @@ -206,7 +207,7 @@ module UDAPSecurityTestKit 
     | 
|
| 
       206 
207 
     | 
    
         
             
                  response.format = :json
         
     | 
| 
       207 
208 
     | 
    
         
             
                  response.body = FHIR::OperationOutcome.new(
         
     | 
| 
       208 
209 
     | 
    
         
             
                    issue: FHIR::OperationOutcome::Issue.new(severity: 'fatal', code: 'expired',
         
     | 
| 
       209 
     | 
    
         
            -
                                                             details: FHIR::CodeableConcept.new(text: "#{type}has expired"))
         
     | 
| 
      
 210 
     | 
    
         
            +
                                                             details: FHIR::CodeableConcept.new(text: "#{type} has expired"))
         
     | 
| 
       210 
211 
     | 
    
         
             
                  ).to_json
         
     | 
| 
       211 
212 
     | 
    
         
             
                end
         
     | 
| 
       212 
213 
     | 
    
         | 
| 
         @@ -372,6 +373,8 @@ module UDAPSecurityTestKit 
     | 
|
| 
       372 
373 
     | 
    
         
             
                end
         
     | 
| 
       373 
374 
     | 
    
         | 
| 
       374 
375 
     | 
    
         
             
                def authorization_code_request_details(inferno_request)
         
     | 
| 
      
 376 
     | 
    
         
            +
                  return unless inferno_request.present?
         
     | 
| 
      
 377 
     | 
    
         
            +
             
     | 
| 
       375 
378 
     | 
    
         
             
                  if inferno_request.verb.downcase == 'get'
         
     | 
| 
       376 
379 
     | 
    
         
             
                    Rack::Utils.parse_query(URI(inferno_request.url)&.query)
         
     | 
| 
       377 
380 
     | 
    
         
             
                  elsif inferno_request.verb.downcase == 'post'
         
     | 
| 
         @@ -8,6 +8,7 @@ module UDAPSecurityTestKit 
     | 
|
| 
       8 
8 
     | 
    
         
             
              AUTH_SERVER_PATH = '/auth'
         
     | 
| 
       9 
9 
     | 
    
         
             
              REGISTRATION_PATH = "#{AUTH_SERVER_PATH}/register".freeze
         
     | 
| 
       10 
10 
     | 
    
         
             
              AUTHORIZATION_PATH = "#{AUTH_SERVER_PATH}/authorization".freeze
         
     | 
| 
      
 11 
     | 
    
         
            +
              INTROSPECTION_PATH = "#{AUTH_SERVER_PATH}/introspect".freeze
         
     | 
| 
       11 
12 
     | 
    
         
             
              TOKEN_PATH = "#{AUTH_SERVER_PATH}/token".freeze
         
     | 
| 
       12 
13 
     | 
    
         
             
              RESUME_PASS_PATH = '/resume_pass'
         
     | 
| 
       13 
14 
     | 
    
         
             
              RESUME_FAIL_PATH = '/resume_fail'
         
     | 
| 
         @@ -41,6 +42,10 @@ module UDAPSecurityTestKit 
     | 
|
| 
       41 
42 
     | 
    
         
             
                  @client_authorization_url ||= client_base_url + AUTHORIZATION_PATH
         
     | 
| 
       42 
43 
     | 
    
         
             
                end
         
     | 
| 
       43 
44 
     | 
    
         | 
| 
      
 45 
     | 
    
         
            +
                def client_introspection_url
         
     | 
| 
      
 46 
     | 
    
         
            +
                  @client_introspection_url ||= client_base_url + INTROSPECTION_PATH
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
       44 
49 
     | 
    
         
             
                def client_token_url
         
     | 
| 
       45 
50 
     | 
    
         
             
                  @client_token_url ||= client_base_url + TOKEN_PATH
         
     | 
| 
       46 
51 
     | 
    
         
             
                end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: udap_security_test_kit
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.11. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.11.5
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Stephen MacVicar
         
     | 
| 
         @@ -9,7 +9,7 @@ authors: 
     | 
|
| 
       9 
9 
     | 
    
         
             
            autorequire:
         
     | 
| 
       10 
10 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       11 
11 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       12 
     | 
    
         
            -
            date: 2025-05- 
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2025-05-14 00:00:00.000000000 Z
         
     | 
| 
       13 
13 
     | 
    
         
             
            dependencies:
         
     | 
| 
       14 
14 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       15 
15 
     | 
    
         
             
              name: inferno_core
         
     | 
| 
         @@ -93,9 +93,11 @@ files: 
     | 
|
| 
       93 
93 
     | 
    
         
             
            - lib/udap_security_test_kit/endpoints/echoing_fhir_responder_endpoint.rb
         
     | 
| 
       94 
94 
     | 
    
         
             
            - lib/udap_security_test_kit/endpoints/mock_udap_server.rb
         
     | 
| 
       95 
95 
     | 
    
         
             
            - lib/udap_security_test_kit/endpoints/mock_udap_server/authorization_endpoint.rb
         
     | 
| 
      
 96 
     | 
    
         
            +
            - lib/udap_security_test_kit/endpoints/mock_udap_server/introspection_endpoint.rb
         
     | 
| 
       96 
97 
     | 
    
         
             
            - lib/udap_security_test_kit/endpoints/mock_udap_server/registration_endpoint.rb
         
     | 
| 
       97 
98 
     | 
    
         
             
            - lib/udap_security_test_kit/endpoints/mock_udap_server/token_endpoint.rb
         
     | 
| 
       98 
99 
     | 
    
         
             
            - lib/udap_security_test_kit/endpoints/mock_udap_server/udap_authorization_response_creation.rb
         
     | 
| 
      
 100 
     | 
    
         
            +
            - lib/udap_security_test_kit/endpoints/mock_udap_server/udap_introspection_response_creation.rb
         
     | 
| 
       99 
101 
     | 
    
         
             
            - lib/udap_security_test_kit/endpoints/mock_udap_server/udap_registration_response_creation.rb
         
     | 
| 
       100 
102 
     | 
    
         
             
            - lib/udap_security_test_kit/endpoints/mock_udap_server/udap_token_response_creation.rb
         
     | 
| 
       101 
103 
     | 
    
         
             
            - lib/udap_security_test_kit/grant_types_supported_field_test.rb
         
     |