aws-sdk-core 3.131.1 → 3.188.0
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/CHANGELOG.md +459 -0
- data/VERSION +1 -1
- data/lib/aws-defaults/default_configuration.rb +4 -4
- data/lib/aws-sdk-core/arn.rb +13 -0
- data/lib/aws-sdk-core/binary/encode_handler.rb +12 -1
- data/lib/aws-sdk-core/credential_provider.rb +3 -0
- data/lib/aws-sdk-core/credential_provider_chain.rb +8 -5
- data/lib/aws-sdk-core/ecs_credentials.rb +177 -53
- data/lib/aws-sdk-core/endpoints/condition.rb +41 -0
- data/lib/aws-sdk-core/endpoints/endpoint.rb +17 -0
- data/lib/aws-sdk-core/endpoints/endpoint_rule.rb +75 -0
- data/lib/aws-sdk-core/endpoints/error_rule.rb +42 -0
- data/lib/aws-sdk-core/endpoints/function.rb +80 -0
- data/lib/aws-sdk-core/endpoints/matchers.rb +131 -0
- data/lib/aws-sdk-core/endpoints/reference.rb +31 -0
- data/lib/aws-sdk-core/endpoints/rule.rb +25 -0
- data/lib/aws-sdk-core/endpoints/rule_set.rb +52 -0
- data/lib/aws-sdk-core/endpoints/rules_provider.rb +37 -0
- data/lib/aws-sdk-core/endpoints/templater.rb +58 -0
- data/lib/aws-sdk-core/endpoints/tree_rule.rb +45 -0
- data/lib/aws-sdk-core/endpoints/url.rb +60 -0
- data/lib/aws-sdk-core/endpoints.rb +78 -0
- data/lib/aws-sdk-core/errors.rb +14 -1
- data/lib/aws-sdk-core/ini_parser.rb +7 -0
- data/lib/aws-sdk-core/instance_profile_credentials.rb +52 -30
- data/lib/aws-sdk-core/json/error_handler.rb +20 -1
- data/lib/aws-sdk-core/json/handler.rb +8 -1
- data/lib/aws-sdk-core/json/parser.rb +27 -2
- data/lib/aws-sdk-core/log/formatter.rb +6 -0
- data/lib/aws-sdk-core/pageable_response.rb +10 -1
- data/lib/aws-sdk-core/param_validator.rb +2 -2
- data/lib/aws-sdk-core/plugins/bearer_authorization.rb +67 -0
- data/lib/aws-sdk-core/plugins/checksum_algorithm.rb +1 -1
- data/lib/aws-sdk-core/plugins/credentials_configuration.rb +24 -0
- data/lib/aws-sdk-core/plugins/endpoint_discovery.rb +6 -2
- data/lib/aws-sdk-core/plugins/jsonvalue_converter.rb +34 -6
- data/lib/aws-sdk-core/plugins/recursion_detection.rb +14 -3
- data/lib/aws-sdk-core/plugins/regional_endpoint.rb +111 -30
- data/lib/aws-sdk-core/plugins/request_compression.rb +217 -0
- data/lib/aws-sdk-core/plugins/retries/error_inspector.rb +2 -1
- data/lib/aws-sdk-core/plugins/sign.rb +201 -0
- data/lib/aws-sdk-core/plugins/signature_v2.rb +1 -0
- data/lib/aws-sdk-core/plugins/signature_v4.rb +13 -7
- data/lib/aws-sdk-core/plugins/user_agent.rb +117 -14
- data/lib/aws-sdk-core/refreshing_credentials.rb +0 -6
- data/lib/aws-sdk-core/refreshing_token.rb +71 -0
- data/lib/aws-sdk-core/rest/handler.rb +1 -1
- data/lib/aws-sdk-core/rest/request/headers.rb +2 -6
- data/lib/aws-sdk-core/rest/request/querystring_builder.rb +43 -29
- data/lib/aws-sdk-core/shared_config.rb +106 -6
- data/lib/aws-sdk-core/sso_credentials.rb +80 -45
- data/lib/aws-sdk-core/sso_token_provider.rb +135 -0
- data/lib/aws-sdk-core/static_token_provider.rb +14 -0
- data/lib/aws-sdk-core/structure.rb +6 -4
- data/lib/aws-sdk-core/stubbing/stub_data.rb +11 -0
- data/lib/aws-sdk-core/token.rb +31 -0
- data/lib/aws-sdk-core/token_provider.rb +15 -0
- data/lib/aws-sdk-core/token_provider_chain.rb +51 -0
- data/lib/aws-sdk-core/waiters/poller.rb +3 -1
- data/lib/aws-sdk-core/xml/error_handler.rb +7 -0
- data/lib/aws-sdk-core/xml/parser/engines/oga.rb +2 -0
- data/lib/aws-sdk-core.rb +14 -0
- data/lib/aws-sdk-sso/client.rb +71 -11
- data/lib/aws-sdk-sso/endpoint_parameters.rb +66 -0
- data/lib/aws-sdk-sso/endpoint_provider.rb +57 -0
- data/lib/aws-sdk-sso/endpoints.rb +72 -0
- data/lib/aws-sdk-sso/plugins/endpoints.rb +76 -0
- data/lib/aws-sdk-sso/types.rb +8 -43
- data/lib/aws-sdk-sso.rb +5 -1
- data/lib/aws-sdk-ssooidc/client.rb +935 -0
- data/lib/aws-sdk-ssooidc/client_api.rb +271 -0
- data/lib/aws-sdk-ssooidc/customizations.rb +1 -0
- data/lib/aws-sdk-ssooidc/endpoint_parameters.rb +66 -0
- data/lib/aws-sdk-ssooidc/endpoint_provider.rb +57 -0
- data/lib/aws-sdk-ssooidc/endpoints.rb +72 -0
- data/lib/aws-sdk-ssooidc/errors.rb +321 -0
- data/lib/aws-sdk-ssooidc/plugins/endpoints.rb +76 -0
- data/lib/aws-sdk-ssooidc/resource.rb +26 -0
- data/lib/aws-sdk-ssooidc/types.rb +755 -0
- data/lib/aws-sdk-ssooidc.rb +59 -0
- data/lib/aws-sdk-sts/client.rb +298 -245
- data/lib/aws-sdk-sts/client_api.rb +12 -1
- data/lib/aws-sdk-sts/endpoint_parameters.rb +78 -0
- data/lib/aws-sdk-sts/endpoint_provider.rb +112 -0
- data/lib/aws-sdk-sts/endpoints.rb +136 -0
- data/lib/aws-sdk-sts/plugins/endpoints.rb +84 -0
- data/lib/aws-sdk-sts/presigner.rb +14 -16
- data/lib/aws-sdk-sts/types.rb +128 -197
- data/lib/aws-sdk-sts.rb +5 -1
- data/lib/seahorse/client/async_base.rb +0 -1
- data/lib/seahorse/client/configuration.rb +1 -5
- data/lib/seahorse/client/h2/connection.rb +12 -11
- data/lib/seahorse/client/net_http/patches.rb +1 -4
- data/lib/seahorse/client/plugins/h2.rb +3 -3
- data/lib/seahorse/client/plugins/request_callback.rb +40 -9
- data/lib/seahorse/client/response.rb +6 -0
- data/lib/seahorse/model/operation.rb +3 -0
- data/lib/seahorse/util.rb +4 -0
- metadata +49 -7
| @@ -0,0 +1,217 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Aws
         | 
| 4 | 
            +
              module Plugins
         | 
| 5 | 
            +
                # @api private
         | 
| 6 | 
            +
                class RequestCompression < Seahorse::Client::Plugin
         | 
| 7 | 
            +
                  DEFAULT_MIN_COMPRESSION_SIZE = 10_240
         | 
| 8 | 
            +
                  MIN_COMPRESSION_SIZE_LIMIT = 10_485_760
         | 
| 9 | 
            +
                  SUPPORTED_ENCODINGS = %w[gzip].freeze
         | 
| 10 | 
            +
                  CHUNK_SIZE = 1 * 1024 * 1024 # one MB
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  option(
         | 
| 13 | 
            +
                    :disable_request_compression,
         | 
| 14 | 
            +
                    default: false,
         | 
| 15 | 
            +
                    doc_type: 'Boolean',
         | 
| 16 | 
            +
                    docstring: <<-DOCS) do |cfg|
         | 
| 17 | 
            +
            When set to 'true' the request body will not be compressed
         | 
| 18 | 
            +
            for supported operations.
         | 
| 19 | 
            +
                  DOCS
         | 
| 20 | 
            +
                    resolve_disable_request_compression(cfg)
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  option(
         | 
| 24 | 
            +
                    :request_min_compression_size_bytes,
         | 
| 25 | 
            +
                    default: 10_240,
         | 
| 26 | 
            +
                    doc_type: 'Integer',
         | 
| 27 | 
            +
                    docstring: <<-DOCS) do |cfg|
         | 
| 28 | 
            +
            The minimum size in bytes that triggers compression for request
         | 
| 29 | 
            +
            bodies. The value must be non-negative integer value between 0
         | 
| 30 | 
            +
            and 10485780 bytes inclusive.
         | 
| 31 | 
            +
                  DOCS
         | 
| 32 | 
            +
                    resolve_request_min_compression_size_bytes(cfg)
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  def after_initialize(client)
         | 
| 36 | 
            +
                    validate_disable_request_compression_input(client.config)
         | 
| 37 | 
            +
                    validate_request_min_compression_size_bytes_input(client.config)
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  def validate_disable_request_compression_input(cfg)
         | 
| 41 | 
            +
                    unless [true, false].include?(cfg.disable_request_compression)
         | 
| 42 | 
            +
                      raise ArgumentError,
         | 
| 43 | 
            +
                            'Must provide either `true` or `false` for the '\
         | 
| 44 | 
            +
                            '`disable_request_compression` configuration option.'
         | 
| 45 | 
            +
                    end
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  def validate_request_min_compression_size_bytes_input(cfg)
         | 
| 49 | 
            +
                    value = Integer(cfg.request_min_compression_size_bytes)
         | 
| 50 | 
            +
                    unless value.between?(0, MIN_COMPRESSION_SIZE_LIMIT)
         | 
| 51 | 
            +
                      raise ArgumentError,
         | 
| 52 | 
            +
                            'Must provide a non-negative integer value between '\
         | 
| 53 | 
            +
                              '`0` and `10485760` bytes inclusive for the '\
         | 
| 54 | 
            +
                              '`request_min_compression_size_bytes` configuration option.'
         | 
| 55 | 
            +
                    end
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  def add_handlers(handlers, _config)
         | 
| 59 | 
            +
                    # priority set to ensure compression happens BEFORE checksum
         | 
| 60 | 
            +
                    handlers.add(CompressionHandler, priority: 16, step: :build)
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  class << self
         | 
| 64 | 
            +
                    private
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                    def resolve_disable_request_compression(cfg)
         | 
| 67 | 
            +
                      value = ENV['AWS_DISABLE_REQUEST_COMPRESSION'] ||
         | 
| 68 | 
            +
                              Aws.shared_config.disable_request_compression(profile: cfg.profile) ||
         | 
| 69 | 
            +
                              'false'
         | 
| 70 | 
            +
                      Aws::Util.str_2_bool(value)
         | 
| 71 | 
            +
                    end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                    def resolve_request_min_compression_size_bytes(cfg)
         | 
| 74 | 
            +
                      value = ENV['AWS_REQUEST_MIN_COMPRESSION_SIZE_BYTES'] ||
         | 
| 75 | 
            +
                              Aws.shared_config.request_min_compression_size_bytes(profile: cfg.profile) ||
         | 
| 76 | 
            +
                              DEFAULT_MIN_COMPRESSION_SIZE.to_s
         | 
| 77 | 
            +
                      Integer(value)
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
                  end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  # @api private
         | 
| 82 | 
            +
                  class CompressionHandler < Seahorse::Client::Handler
         | 
| 83 | 
            +
                    def call(context)
         | 
| 84 | 
            +
                      if should_compress?(context)
         | 
| 85 | 
            +
                        selected_encoding = request_encoding_selection(context)
         | 
| 86 | 
            +
                        if selected_encoding
         | 
| 87 | 
            +
                          if streaming?(context.operation.input)
         | 
| 88 | 
            +
                            process_streaming_compression(selected_encoding, context)
         | 
| 89 | 
            +
                          elsif context.http_request.body.size >= context.config.request_min_compression_size_bytes
         | 
| 90 | 
            +
                            process_compression(selected_encoding, context)
         | 
| 91 | 
            +
                          end
         | 
| 92 | 
            +
                        end
         | 
| 93 | 
            +
                      end
         | 
| 94 | 
            +
                      @handler.call(context)
         | 
| 95 | 
            +
                    end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                    private
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                    def request_encoding_selection(context)
         | 
| 100 | 
            +
                      encoding_list = context.operation.request_compression['encodings']
         | 
| 101 | 
            +
                      encoding_list.find { |encoding| RequestCompression::SUPPORTED_ENCODINGS.include?(encoding) }
         | 
| 102 | 
            +
                    end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                    def update_content_encoding(encoding, context)
         | 
| 105 | 
            +
                      headers = context.http_request.headers
         | 
| 106 | 
            +
                      if headers['Content-Encoding']
         | 
| 107 | 
            +
                        headers['Content-Encoding'] += ',' + encoding
         | 
| 108 | 
            +
                      else
         | 
| 109 | 
            +
                        headers['Content-Encoding'] = encoding
         | 
| 110 | 
            +
                      end
         | 
| 111 | 
            +
                    end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                    def should_compress?(context)
         | 
| 114 | 
            +
                      context.operation.request_compression &&
         | 
| 115 | 
            +
                        !context.config.disable_request_compression
         | 
| 116 | 
            +
                    end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                    def streaming?(input)
         | 
| 119 | 
            +
                      if payload = input[:payload_member] # checking ref and shape
         | 
| 120 | 
            +
                        payload['streaming'] || payload.shape['streaming']
         | 
| 121 | 
            +
                      else
         | 
| 122 | 
            +
                        false
         | 
| 123 | 
            +
                      end
         | 
| 124 | 
            +
                    end
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                    def process_compression(encoding, context)
         | 
| 127 | 
            +
                      case encoding
         | 
| 128 | 
            +
                      when 'gzip'
         | 
| 129 | 
            +
                        gzip_compress(context)
         | 
| 130 | 
            +
                      else
         | 
| 131 | 
            +
                        raise StandardError, "We currently do not support #{encoding} encoding"
         | 
| 132 | 
            +
                      end
         | 
| 133 | 
            +
                      update_content_encoding(encoding, context)
         | 
| 134 | 
            +
                    end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                    def gzip_compress(context)
         | 
| 137 | 
            +
                      compressed = StringIO.new
         | 
| 138 | 
            +
                      compressed.binmode
         | 
| 139 | 
            +
                      gzip_writer = Zlib::GzipWriter.new(compressed)
         | 
| 140 | 
            +
                      if context.http_request.body.respond_to?(:read)
         | 
| 141 | 
            +
                        update_in_chunks(gzip_writer, context.http_request.body)
         | 
| 142 | 
            +
                      else
         | 
| 143 | 
            +
                        gzip_writer.write(context.http_request.body)
         | 
| 144 | 
            +
                      end
         | 
| 145 | 
            +
                      gzip_writer.close
         | 
| 146 | 
            +
                      new_body = StringIO.new(compressed.string)
         | 
| 147 | 
            +
                      context.http_request.body = new_body
         | 
| 148 | 
            +
                    end
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                    def update_in_chunks(compressor, io)
         | 
| 151 | 
            +
                      loop do
         | 
| 152 | 
            +
                        chunk = io.read(CHUNK_SIZE)
         | 
| 153 | 
            +
                        break unless chunk
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                        compressor.write(chunk)
         | 
| 156 | 
            +
                      end
         | 
| 157 | 
            +
                    end
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                    def process_streaming_compression(encoding, context)
         | 
| 160 | 
            +
                      case encoding
         | 
| 161 | 
            +
                      when 'gzip'
         | 
| 162 | 
            +
                        context.http_request.body = GzipIO.new(context.http_request.body)
         | 
| 163 | 
            +
                      else
         | 
| 164 | 
            +
                        raise StandardError, "We currently do not support #{encoding} encoding"
         | 
| 165 | 
            +
                      end
         | 
| 166 | 
            +
                      update_content_encoding(encoding, context)
         | 
| 167 | 
            +
                    end
         | 
| 168 | 
            +
             | 
| 169 | 
            +
                    # @api private
         | 
| 170 | 
            +
                    class GzipIO
         | 
| 171 | 
            +
                      def initialize(body)
         | 
| 172 | 
            +
                        @body = body
         | 
| 173 | 
            +
                        @buffer = ChunkBuffer.new
         | 
| 174 | 
            +
                        @gzip_writer = Zlib::GzipWriter.new(@buffer)
         | 
| 175 | 
            +
                      end
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                      def read(length, buff = nil)
         | 
| 178 | 
            +
                        if @gzip_writer.closed?
         | 
| 179 | 
            +
                          # an empty string to signify an end as
         | 
| 180 | 
            +
                          # there will be nothing remaining to be read
         | 
| 181 | 
            +
                          StringIO.new('').read(length, buff)
         | 
| 182 | 
            +
                          return
         | 
| 183 | 
            +
                        end
         | 
| 184 | 
            +
             | 
| 185 | 
            +
                        chunk = @body.read(length)
         | 
| 186 | 
            +
                        if !chunk || chunk.empty?
         | 
| 187 | 
            +
                          # closing the writer will write one last chunk
         | 
| 188 | 
            +
                          # with a trailer (to be read from the @buffer)
         | 
| 189 | 
            +
                          @gzip_writer.close
         | 
| 190 | 
            +
                        else
         | 
| 191 | 
            +
                          # flush happens first to ensure that header fields
         | 
| 192 | 
            +
                          # are being sent over since write will override
         | 
| 193 | 
            +
                          @gzip_writer.flush
         | 
| 194 | 
            +
                          @gzip_writer.write(chunk)
         | 
| 195 | 
            +
                        end
         | 
| 196 | 
            +
             | 
| 197 | 
            +
                        StringIO.new(@buffer.last_chunk).read(length, buff)
         | 
| 198 | 
            +
                      end
         | 
| 199 | 
            +
                    end
         | 
| 200 | 
            +
             | 
| 201 | 
            +
                    # @api private
         | 
| 202 | 
            +
                    class ChunkBuffer
         | 
| 203 | 
            +
                      def initialize
         | 
| 204 | 
            +
                        @last_chunk = nil
         | 
| 205 | 
            +
                      end
         | 
| 206 | 
            +
             | 
| 207 | 
            +
                      attr_reader :last_chunk
         | 
| 208 | 
            +
             | 
| 209 | 
            +
                      def write(data)
         | 
| 210 | 
            +
                        @last_chunk = data
         | 
| 211 | 
            +
                      end
         | 
| 212 | 
            +
                    end
         | 
| 213 | 
            +
                  end
         | 
| 214 | 
            +
             | 
| 215 | 
            +
                end
         | 
| 216 | 
            +
              end
         | 
| 217 | 
            +
            end
         | 
| @@ -0,0 +1,201 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'aws-sigv4'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Aws
         | 
| 6 | 
            +
              module Plugins
         | 
| 7 | 
            +
                # @api private
         | 
| 8 | 
            +
                class Sign < Seahorse::Client::Plugin
         | 
| 9 | 
            +
                  # These once had defaults. But now they are used as overrides to
         | 
| 10 | 
            +
                  # new endpoint and auth resolution.
         | 
| 11 | 
            +
                  option(:sigv4_signer)
         | 
| 12 | 
            +
                  option(:sigv4_name)
         | 
| 13 | 
            +
                  option(:sigv4_region)
         | 
| 14 | 
            +
                  option(:unsigned_operations, default: [])
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  supported_auth_types = %w[sigv4 bearer none]
         | 
| 17 | 
            +
                  supported_auth_types += ['sigv4a'] if Aws::Sigv4::Signer.use_crt?
         | 
| 18 | 
            +
                  SUPPORTED_AUTH_TYPES = supported_auth_types.freeze
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  def add_handlers(handlers, cfg)
         | 
| 21 | 
            +
                    operations = cfg.api.operation_names - cfg.unsigned_operations
         | 
| 22 | 
            +
                    handlers.add(Handler, step: :sign, operations: operations)
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  # @api private
         | 
| 26 | 
            +
                  # Return a signer with the `sign(context)` method
         | 
| 27 | 
            +
                  def self.signer_for(auth_scheme, config, region_override = nil)
         | 
| 28 | 
            +
                    case auth_scheme['name']
         | 
| 29 | 
            +
                    when 'sigv4', 'sigv4a'
         | 
| 30 | 
            +
                      SignatureV4.new(auth_scheme, config, region_override)
         | 
| 31 | 
            +
                    when 'bearer'
         | 
| 32 | 
            +
                      Bearer.new
         | 
| 33 | 
            +
                    else
         | 
| 34 | 
            +
                      NullSigner.new
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  class Handler < Seahorse::Client::Handler
         | 
| 39 | 
            +
                    def call(context)
         | 
| 40 | 
            +
                      # Skip signing if using sigv2 signing from s3_signer in S3
         | 
| 41 | 
            +
                      unless v2_signing?(context.config)
         | 
| 42 | 
            +
                        signer = Sign.signer_for(
         | 
| 43 | 
            +
                          context[:auth_scheme],
         | 
| 44 | 
            +
                          context.config,
         | 
| 45 | 
            +
                          context[:sigv4_region]
         | 
| 46 | 
            +
                        )
         | 
| 47 | 
            +
                        signer.sign(context)
         | 
| 48 | 
            +
                      end
         | 
| 49 | 
            +
                      @handler.call(context)
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                    private
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                    def v2_signing?(config)
         | 
| 55 | 
            +
                      # 's3' is legacy signing, 'v4' is default
         | 
| 56 | 
            +
                      config.respond_to?(:signature_version) &&
         | 
| 57 | 
            +
                        config.signature_version == 's3'
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  # @api private
         | 
| 62 | 
            +
                  class Bearer
         | 
| 63 | 
            +
                    def initialize
         | 
| 64 | 
            +
                    end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                    def sign(context)
         | 
| 67 | 
            +
                      if context.http_request.endpoint.scheme != 'https'
         | 
| 68 | 
            +
                        raise ArgumentError,
         | 
| 69 | 
            +
                              'Unable to use bearer authorization on non https endpoint.'
         | 
| 70 | 
            +
                      end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                      token_provider = context.config.token_provider
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                      raise Errors::MissingBearerTokenError unless token_provider&.set?
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                      context.http_request.headers['Authorization'] =
         | 
| 77 | 
            +
                        "Bearer #{token_provider.token.token}"
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                    def presign_url(*args)
         | 
| 81 | 
            +
                      raise ArgumentError, 'Bearer auth does not support presigned urls'
         | 
| 82 | 
            +
                    end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                    def sign_event(*args)
         | 
| 85 | 
            +
                      raise ArgumentError, 'Bearer auth does not support event signing'
         | 
| 86 | 
            +
                    end
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                  # @api private
         | 
| 90 | 
            +
                  class SignatureV4
         | 
| 91 | 
            +
                    def initialize(auth_scheme, config, region_override = nil)
         | 
| 92 | 
            +
                      scheme_name = auth_scheme['name']
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                      unless %w[sigv4 sigv4a].include?(scheme_name)
         | 
| 95 | 
            +
                        raise ArgumentError,
         | 
| 96 | 
            +
                              "Expected sigv4 or sigv4a auth scheme, got #{scheme_name}"
         | 
| 97 | 
            +
                      end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                      region = if scheme_name == 'sigv4a'
         | 
| 100 | 
            +
                                 auth_scheme['signingRegionSet'].first
         | 
| 101 | 
            +
                               else
         | 
| 102 | 
            +
                                 auth_scheme['signingRegion']
         | 
| 103 | 
            +
                               end
         | 
| 104 | 
            +
                      begin
         | 
| 105 | 
            +
                        @signer = Aws::Sigv4::Signer.new(
         | 
| 106 | 
            +
                          service: config.sigv4_name || auth_scheme['signingName'],
         | 
| 107 | 
            +
                          region: region_override || config.sigv4_region || region,
         | 
| 108 | 
            +
                          credentials_provider: config.credentials,
         | 
| 109 | 
            +
                          signing_algorithm: scheme_name.to_sym,
         | 
| 110 | 
            +
                          uri_escape_path: !!!auth_scheme['disableDoubleEncoding'],
         | 
| 111 | 
            +
                          normalize_path: !!!auth_scheme['disableNormalizePath'],
         | 
| 112 | 
            +
                          unsigned_headers: %w[content-length user-agent x-amzn-trace-id]
         | 
| 113 | 
            +
                        )
         | 
| 114 | 
            +
                      rescue Aws::Sigv4::Errors::MissingCredentialsError
         | 
| 115 | 
            +
                        raise Aws::Errors::MissingCredentialsError
         | 
| 116 | 
            +
                      end
         | 
| 117 | 
            +
                    end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                    def sign(context)
         | 
| 120 | 
            +
                      req = context.http_request
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                      apply_authtype(context, req)
         | 
| 123 | 
            +
                      reset_signature(req)
         | 
| 124 | 
            +
                      apply_clock_skew(context, req)
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                      # compute the signature
         | 
| 127 | 
            +
                      begin
         | 
| 128 | 
            +
                        signature = @signer.sign_request(
         | 
| 129 | 
            +
                          http_method: req.http_method,
         | 
| 130 | 
            +
                          url: req.endpoint,
         | 
| 131 | 
            +
                          headers: req.headers,
         | 
| 132 | 
            +
                          body: req.body
         | 
| 133 | 
            +
                        )
         | 
| 134 | 
            +
                      rescue Aws::Sigv4::Errors::MissingCredentialsError
         | 
| 135 | 
            +
                        # Necessary for when credentials is explicitly set to nil
         | 
| 136 | 
            +
                        raise Aws::Errors::MissingCredentialsError
         | 
| 137 | 
            +
                      end
         | 
| 138 | 
            +
                      # apply signature headers
         | 
| 139 | 
            +
                      req.headers.update(signature.headers)
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                      # add request metadata with signature components for debugging
         | 
| 142 | 
            +
                      context[:canonical_request] = signature.canonical_request
         | 
| 143 | 
            +
                      context[:string_to_sign] = signature.string_to_sign
         | 
| 144 | 
            +
                    end
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                    def presign_url(*args)
         | 
| 147 | 
            +
                      @signer.presign_url(*args)
         | 
| 148 | 
            +
                    end
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                    def sign_event(*args)
         | 
| 151 | 
            +
                      @signer.sign_event(*args)
         | 
| 152 | 
            +
                    end
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                    private
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                    def apply_authtype(context, req)
         | 
| 157 | 
            +
                      if context.operation['authtype'].eql?('v4-unsigned-body') &&
         | 
| 158 | 
            +
                         req.endpoint.scheme.eql?('https')
         | 
| 159 | 
            +
                        req.headers['X-Amz-Content-Sha256'] ||= 'UNSIGNED-PAYLOAD'
         | 
| 160 | 
            +
                      end
         | 
| 161 | 
            +
                    end
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                    def reset_signature(req)
         | 
| 164 | 
            +
                      # in case this request is being re-signed
         | 
| 165 | 
            +
                      req.headers.delete('Authorization')
         | 
| 166 | 
            +
                      req.headers.delete('X-Amz-Security-Token')
         | 
| 167 | 
            +
                      req.headers.delete('X-Amz-Date')
         | 
| 168 | 
            +
                      req.headers.delete('x-Amz-Region-Set')
         | 
| 169 | 
            +
                    end
         | 
| 170 | 
            +
             | 
| 171 | 
            +
                    def apply_clock_skew(context, req)
         | 
| 172 | 
            +
                      if context.config.respond_to?(:clock_skew) &&
         | 
| 173 | 
            +
                         context.config.clock_skew &&
         | 
| 174 | 
            +
                         context.config.correct_clock_skew
         | 
| 175 | 
            +
             | 
| 176 | 
            +
                        endpoint = context.http_request.endpoint
         | 
| 177 | 
            +
                        skew = context.config.clock_skew.clock_correction(endpoint)
         | 
| 178 | 
            +
                        if skew.abs.positive?
         | 
| 179 | 
            +
                          req.headers['X-Amz-Date'] =
         | 
| 180 | 
            +
                            (Time.now.utc + skew).strftime('%Y%m%dT%H%M%SZ')
         | 
| 181 | 
            +
                        end
         | 
| 182 | 
            +
                      end
         | 
| 183 | 
            +
                    end
         | 
| 184 | 
            +
             | 
| 185 | 
            +
                  end
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                  # @api private
         | 
| 188 | 
            +
                  class NullSigner
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                    def sign(context)
         | 
| 191 | 
            +
                    end
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                    def presign_url(*args)
         | 
| 194 | 
            +
                    end
         | 
| 195 | 
            +
             | 
| 196 | 
            +
                    def sign_event(*args)
         | 
| 197 | 
            +
                    end
         | 
| 198 | 
            +
                  end
         | 
| 199 | 
            +
                end
         | 
| 200 | 
            +
              end
         | 
| 201 | 
            +
            end
         | 
| @@ -5,8 +5,11 @@ require 'aws-sigv4' | |
| 5 5 | 
             
            module Aws
         | 
| 6 6 | 
             
              module Plugins
         | 
| 7 7 | 
             
                # @api private
         | 
| 8 | 
            +
                # Necessary to exist after endpoints 2.0
         | 
| 8 9 | 
             
                class SignatureV4 < Seahorse::Client::Plugin
         | 
| 9 10 |  | 
| 11 | 
            +
                  V4_AUTH = %w[v4 v4-unsigned-payload v4-unsigned-body]
         | 
| 12 | 
            +
             | 
| 10 13 | 
             
                  option(:sigv4_signer) do |cfg|
         | 
| 11 14 | 
             
                    SignatureV4.build_signer(cfg)
         | 
| 12 15 | 
             
                  end
         | 
| @@ -32,13 +35,16 @@ module Aws | |
| 32 35 | 
             
                  end
         | 
| 33 36 |  | 
| 34 37 | 
             
                  option(:unsigned_operations) do |cfg|
         | 
| 35 | 
            -
                    cfg.api. | 
| 36 | 
            -
                       | 
| 37 | 
            -
             | 
| 38 | 
            -
                         | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 38 | 
            +
                    if cfg.api.metadata['signatureVersion'] == 'v4'
         | 
| 39 | 
            +
                      # select operations where authtype is set and is not v4
         | 
| 40 | 
            +
                      cfg.api.operation_names.select do |o|
         | 
| 41 | 
            +
                        cfg.api.operation(o)['authtype'] && !V4_AUTH.include?(cfg.api.operation(o)['authtype'])
         | 
| 42 | 
            +
                      end
         | 
| 43 | 
            +
                    else # service is not v4 auth
         | 
| 44 | 
            +
                      # select all operations where authtype is not v4
         | 
| 45 | 
            +
                      # (includes operations with no explicit authtype)
         | 
| 46 | 
            +
                      cfg.api.operation_names.select do |o|
         | 
| 47 | 
            +
                        !V4_AUTH.include?(cfg.api.operation(o)['authtype'])
         | 
| 42 48 | 
             
                      end
         | 
| 43 49 | 
             
                    end
         | 
| 44 50 | 
             
                  end
         | 
| @@ -4,7 +4,31 @@ module Aws | |
| 4 4 | 
             
              module Plugins
         | 
| 5 5 | 
             
                # @api private
         | 
| 6 6 | 
             
                class UserAgent < Seahorse::Client::Plugin
         | 
| 7 | 
            +
                  # @api private
         | 
| 7 8 | 
             
                  option(:user_agent_suffix)
         | 
| 9 | 
            +
                  # @api private
         | 
| 10 | 
            +
                  option(:user_agent_frameworks, default: [])
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  option(
         | 
| 13 | 
            +
                    :sdk_ua_app_id,
         | 
| 14 | 
            +
                    doc_type: 'String',
         | 
| 15 | 
            +
                    docstring: <<-DOCS) do |cfg|
         | 
| 16 | 
            +
            A unique and opaque application ID that is appended to the
         | 
| 17 | 
            +
            User-Agent header as app/<sdk_ua_app_id>. It should have a
         | 
| 18 | 
            +
            maximum length of 50.
         | 
| 19 | 
            +
                    DOCS
         | 
| 20 | 
            +
                    app_id = ENV['AWS_SDK_UA_APP_ID']
         | 
| 21 | 
            +
                    app_id ||= Aws.shared_config.sdk_ua_app_id(profile: cfg.profile)
         | 
| 22 | 
            +
                    app_id
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  def self.feature(feature, &block)
         | 
| 26 | 
            +
                    Thread.current[:aws_sdk_core_user_agent_feature] ||= []
         | 
| 27 | 
            +
                    Thread.current[:aws_sdk_core_user_agent_feature] << "ft/#{feature}"
         | 
| 28 | 
            +
                    block.call
         | 
| 29 | 
            +
                  ensure
         | 
| 30 | 
            +
                    Thread.current[:aws_sdk_core_user_agent_feature].pop
         | 
| 31 | 
            +
                  end
         | 
| 8 32 |  | 
| 9 33 | 
             
                  # @api private
         | 
| 10 34 | 
             
                  class Handler < Seahorse::Client::Handler
         | 
| @@ -14,33 +38,112 @@ module Aws | |
| 14 38 | 
             
                    end
         | 
| 15 39 |  | 
| 16 40 | 
             
                    def set_user_agent(context)
         | 
| 17 | 
            -
                       | 
| 41 | 
            +
                      context.http_request.headers['User-Agent'] = UserAgent.new(context).to_s
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                    class UserAgent
         | 
| 45 | 
            +
                      def initialize(context)
         | 
| 46 | 
            +
                        @context = context
         | 
| 47 | 
            +
                      end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                      def to_s
         | 
| 50 | 
            +
                        ua = "aws-sdk-ruby3/#{CORE_GEM_VERSION}"
         | 
| 51 | 
            +
                        ua += ' ua/2.0'
         | 
| 52 | 
            +
                        ua += " #{api_metadata}" if api_metadata
         | 
| 53 | 
            +
                        ua += " #{os_metadata}"
         | 
| 54 | 
            +
                        ua += " #{language_metadata}"
         | 
| 55 | 
            +
                        ua += " #{env_metadata}" if env_metadata
         | 
| 56 | 
            +
                        ua += " #{config_metadata}" if config_metadata
         | 
| 57 | 
            +
                        ua += " #{app_id}" if app_id
         | 
| 58 | 
            +
                        ua += " #{feature_metadata}" if feature_metadata
         | 
| 59 | 
            +
                        ua += " #{framework_metadata}" if framework_metadata
         | 
| 60 | 
            +
                        if @context.config.user_agent_suffix
         | 
| 61 | 
            +
                          ua += " #{@context.config.user_agent_suffix}"
         | 
| 62 | 
            +
                        end
         | 
| 63 | 
            +
                        ua.strip
         | 
| 64 | 
            +
                      end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                      private
         | 
| 18 67 |  | 
| 19 | 
            -
                       | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
                         | 
| 68 | 
            +
                      # Used to be gem_name/gem_version
         | 
| 69 | 
            +
                      def api_metadata
         | 
| 70 | 
            +
                        service_id = @context.config.api.metadata['serviceId']
         | 
| 71 | 
            +
                        return unless service_id
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                        service_id = service_id.gsub(' ', '_').downcase
         | 
| 74 | 
            +
                        gem_version = @context[:gem_version]
         | 
| 75 | 
            +
                        "api/#{service_id}##{gem_version}"
         | 
| 76 | 
            +
                      end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                      # Used to be RUBY_PLATFORM
         | 
| 79 | 
            +
                      def os_metadata
         | 
| 80 | 
            +
                        os =
         | 
| 81 | 
            +
                          case RbConfig::CONFIG['host_os']
         | 
| 82 | 
            +
                          when /mac|darwin/
         | 
| 83 | 
            +
                            'macos'
         | 
| 84 | 
            +
                          when /linux|cygwin/
         | 
| 85 | 
            +
                            'linux'
         | 
| 86 | 
            +
                          when /mingw|mswin/
         | 
| 87 | 
            +
                            'windows'
         | 
| 88 | 
            +
                          else
         | 
| 89 | 
            +
                            'other'
         | 
| 90 | 
            +
                          end
         | 
| 91 | 
            +
                        metadata = "os/#{os}"
         | 
| 92 | 
            +
                        local_version = Gem::Platform.local.version
         | 
| 93 | 
            +
                        metadata += "##{local_version}" if local_version
         | 
| 94 | 
            +
                        metadata += " md/#{RbConfig::CONFIG['host_cpu']}"
         | 
| 95 | 
            +
                        metadata
         | 
| 23 96 | 
             
                      end
         | 
| 24 97 |  | 
| 25 | 
            -
                       | 
| 98 | 
            +
                      # Used to be RUBY_ENGINE/RUBY_VERSION
         | 
| 99 | 
            +
                      def language_metadata
         | 
| 100 | 
            +
                        "lang/#{RUBY_ENGINE}##{RUBY_ENGINE_VERSION} md/#{RUBY_VERSION}"
         | 
| 101 | 
            +
                      end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                      def env_metadata
         | 
| 104 | 
            +
                        return unless (execution_env = ENV['AWS_EXECUTION_ENV'])
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                        "exec-env/#{execution_env}"
         | 
| 107 | 
            +
                      end
         | 
| 26 108 |  | 
| 27 | 
            -
                       | 
| 28 | 
            -
                         | 
| 109 | 
            +
                      def config_metadata
         | 
| 110 | 
            +
                        "cfg/retry-mode##{@context.config.retry_mode}"
         | 
| 29 111 | 
             
                      end
         | 
| 30 112 |  | 
| 31 | 
            -
                       | 
| 32 | 
            -
                         | 
| 113 | 
            +
                      def app_id
         | 
| 114 | 
            +
                        return unless (app_id = @context.config.sdk_ua_app_id)
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                        # Sanitize and only allow these characters
         | 
| 117 | 
            +
                        app_id = app_id.gsub(/[^!#$%&'*+\-.^_`|~0-9A-Za-z]/, '-')
         | 
| 118 | 
            +
                        "app/#{app_id}"
         | 
| 33 119 | 
             
                      end
         | 
| 34 120 |  | 
| 35 | 
            -
                       | 
| 36 | 
            -
                         | 
| 121 | 
            +
                      def feature_metadata
         | 
| 122 | 
            +
                        return unless Thread.current[:aws_sdk_core_user_agent_feature]
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                        Thread.current[:aws_sdk_core_user_agent_feature].join(' ')
         | 
| 37 125 | 
             
                      end
         | 
| 38 126 |  | 
| 39 | 
            -
                       | 
| 127 | 
            +
                      def framework_metadata
         | 
| 128 | 
            +
                        if (frameworks_cfg = @context.config.user_agent_frameworks).empty?
         | 
| 129 | 
            +
                          return
         | 
| 130 | 
            +
                        end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                        # Frameworks may be aws-record, aws-sdk-rails, etc.
         | 
| 133 | 
            +
                        regex = /gems\/(?<name>#{frameworks_cfg.join('|')})-(?<version>\d+\.\d+\.\d+)/.freeze
         | 
| 134 | 
            +
                        frameworks = {}
         | 
| 135 | 
            +
                        Kernel.caller.each do |line|
         | 
| 136 | 
            +
                          match = line.match(regex)
         | 
| 137 | 
            +
                          next unless match
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                          frameworks[match[:name]] = match[:version]
         | 
| 140 | 
            +
                        end
         | 
| 141 | 
            +
                        frameworks.map { |n, v| "lib/#{n}##{v}" }.join(' ')
         | 
| 142 | 
            +
                      end
         | 
| 40 143 | 
             
                    end
         | 
| 41 144 | 
             
                  end
         | 
| 42 145 |  | 
| 43 | 
            -
                  handler(Handler)
         | 
| 146 | 
            +
                  handler(Handler, priority: 1)
         | 
| 44 147 | 
             
                end
         | 
| 45 148 | 
             
              end
         | 
| 46 149 | 
             
            end
         |