aws-sdk-core 3.165.0 → 3.174.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 +105 -0
- data/VERSION +1 -1
- data/lib/aws-sdk-core/credential_provider_chain.rb +8 -5
- data/lib/aws-sdk-core/ecs_credentials.rb +111 -53
- data/lib/aws-sdk-core/endpoints/condition.rb +5 -0
- data/lib/aws-sdk-core/endpoints/endpoint_rule.rb +5 -1
- data/lib/aws-sdk-core/endpoints/error_rule.rb +5 -0
- data/lib/aws-sdk-core/endpoints/function.rb +5 -0
- data/lib/aws-sdk-core/endpoints/reference.rb +5 -0
- data/lib/aws-sdk-core/endpoints/rule.rb +5 -0
- data/lib/aws-sdk-core/endpoints/rule_set.rb +5 -0
- data/lib/aws-sdk-core/endpoints/rules_provider.rb +5 -0
- data/lib/aws-sdk-core/endpoints/templater.rb +6 -0
- data/lib/aws-sdk-core/endpoints/tree_rule.rb +5 -0
- data/lib/aws-sdk-core/endpoints/url.rb +1 -0
- data/lib/aws-sdk-core/json/error_handler.rb +15 -5
- data/lib/aws-sdk-core/log/formatter.rb +6 -0
- data/lib/aws-sdk-core/pageable_response.rb +3 -1
- data/lib/aws-sdk-core/plugins/checksum_algorithm.rb +1 -1
- data/lib/aws-sdk-core/plugins/retries/error_inspector.rb +2 -1
- data/lib/aws-sdk-core/plugins/sign.rb +17 -7
- data/lib/aws-sdk-core/plugins/user_agent.rb +117 -14
- data/lib/aws-sdk-core/shared_config.rb +38 -9
- data/lib/aws-sdk-core/sso_credentials.rb +79 -44
- data/lib/aws-sdk-core/sso_token_provider.rb +3 -2
- data/lib/aws-sdk-core/waiters/poller.rb +3 -1
- data/lib/aws-sdk-core/xml/parser/engines/oga.rb +2 -0
- data/lib/aws-sdk-core.rb +1 -0
- data/lib/aws-sdk-sso/client.rb +6 -1
- data/lib/aws-sdk-sso/endpoint_provider.rb +35 -96
- data/lib/aws-sdk-sso/types.rb +0 -35
- data/lib/aws-sdk-sso.rb +1 -1
- data/lib/aws-sdk-ssooidc/client.rb +6 -1
- data/lib/aws-sdk-ssooidc/endpoint_provider.rb +35 -95
- data/lib/aws-sdk-ssooidc/types.rb +0 -32
- data/lib/aws-sdk-ssooidc.rb +1 -1
- data/lib/aws-sdk-sts/client.rb +244 -241
- data/lib/aws-sdk-sts/endpoint_provider.rb +96 -213
- data/lib/aws-sdk-sts/types.rb +87 -195
- data/lib/aws-sdk-sts.rb +1 -1
- data/lib/seahorse/client/h2/connection.rb +12 -11
- metadata +4 -4
| @@ -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
         | 
| @@ -3,9 +3,10 @@ | |
| 3 3 | 
             
            module Aws
         | 
| 4 4 | 
             
              # @api private
         | 
| 5 5 | 
             
              class SharedConfig
         | 
| 6 | 
            -
                 | 
| 6 | 
            +
                SSO_CREDENTIAL_PROFILE_KEYS = %w[sso_account_id sso_role_name].freeze
         | 
| 7 | 
            +
                SSO_PROFILE_KEYS = %w[sso_session sso_start_url sso_region sso_account_id sso_role_name].freeze
         | 
| 7 8 | 
             
                SSO_TOKEN_PROFILE_KEYS = %w[sso_session].freeze
         | 
| 8 | 
            -
                SSO_SESSION_KEYS = %w[sso_region]
         | 
| 9 | 
            +
                SSO_SESSION_KEYS = %w[sso_region sso_start_url].freeze
         | 
| 9 10 |  | 
| 10 11 |  | 
| 11 12 | 
             
                # @return [String]
         | 
| @@ -196,7 +197,8 @@ module Aws | |
| 196 197 | 
             
                  :s3_use_arn_region,
         | 
| 197 198 | 
             
                  :s3_us_east_1_regional_endpoint,
         | 
| 198 199 | 
             
                  :s3_disable_multiregion_access_points,
         | 
| 199 | 
            -
                  :defaults_mode
         | 
| 200 | 
            +
                  :defaults_mode,
         | 
| 201 | 
            +
                  :sdk_ua_app_id
         | 
| 200 202 | 
             
                )
         | 
| 201 203 |  | 
| 202 204 | 
             
                private
         | 
| @@ -331,14 +333,41 @@ module Aws | |
| 331 333 | 
             
                def sso_credentials_from_profile(cfg, profile)
         | 
| 332 334 | 
             
                  if @parsed_config &&
         | 
| 333 335 | 
             
                     (prof_config = cfg[profile]) &&
         | 
| 334 | 
            -
                     !(prof_config.keys &  | 
| 336 | 
            +
                     !(prof_config.keys & SSO_CREDENTIAL_PROFILE_KEYS).empty?
         | 
| 337 | 
            +
             | 
| 338 | 
            +
                    if sso_session_name = prof_config['sso_session']
         | 
| 339 | 
            +
                      sso_session = cfg["sso-session #{sso_session_name}"]
         | 
| 340 | 
            +
                      unless sso_session
         | 
| 341 | 
            +
                        raise ArgumentError,
         | 
| 342 | 
            +
                              "sso-session #{sso_session_name} must be defined in the config file. " \
         | 
| 343 | 
            +
                                "Referenced by profile #{profile}"
         | 
| 344 | 
            +
                      end
         | 
| 345 | 
            +
                      sso_region = sso_session['sso_region']
         | 
| 346 | 
            +
                      sso_start_url = sso_session['sso_start_url']
         | 
| 347 | 
            +
             | 
| 348 | 
            +
                      # validate sso_region and sso_start_url don't conflict if set on profile and session
         | 
| 349 | 
            +
                      if prof_config['sso_region'] &&  prof_config['sso_region'] != sso_region
         | 
| 350 | 
            +
                        raise ArgumentError,
         | 
| 351 | 
            +
                              "sso-session #{sso_session_name}'s sso_region (#{sso_region}) " \
         | 
| 352 | 
            +
                                "does not match the profile #{profile}'s sso_region (#{prof_config['sso_region']}'"
         | 
| 353 | 
            +
                      end
         | 
| 354 | 
            +
                      if prof_config['sso_start_url'] &&  prof_config['sso_start_url'] != sso_start_url
         | 
| 355 | 
            +
                        raise ArgumentError,
         | 
| 356 | 
            +
                              "sso-session #{sso_session_name}'s sso_start_url (#{sso_start_url}) " \
         | 
| 357 | 
            +
                                "does not match the profile #{profile}'s sso_start_url (#{prof_config['sso_start_url']}'"
         | 
| 358 | 
            +
                      end
         | 
| 359 | 
            +
                    else
         | 
| 360 | 
            +
                      sso_region = prof_config['sso_region']
         | 
| 361 | 
            +
                      sso_start_url = prof_config['sso_start_url']
         | 
| 362 | 
            +
                    end
         | 
| 335 363 |  | 
| 336 364 | 
             
                    SSOCredentials.new(
         | 
| 337 | 
            -
                      sso_start_url: prof_config['sso_start_url'],
         | 
| 338 | 
            -
                      sso_region: prof_config['sso_region'],
         | 
| 339 365 | 
             
                      sso_account_id: prof_config['sso_account_id'],
         | 
| 340 | 
            -
                      sso_role_name: prof_config['sso_role_name']
         | 
| 341 | 
            -
             | 
| 366 | 
            +
                      sso_role_name: prof_config['sso_role_name'],
         | 
| 367 | 
            +
                      sso_session: prof_config['sso_session'],
         | 
| 368 | 
            +
                      sso_region: sso_region,
         | 
| 369 | 
            +
                      sso_start_url: prof_config['sso_start_url']
         | 
| 370 | 
            +
                      )
         | 
| 342 371 | 
             
                  end
         | 
| 343 372 | 
             
                end
         | 
| 344 373 |  | 
| @@ -353,7 +382,7 @@ module Aws | |
| 353 382 | 
             
                    sso_session = cfg["sso-session #{sso_session_name}"]
         | 
| 354 383 | 
             
                    unless sso_session
         | 
| 355 384 | 
             
                      raise ArgumentError,
         | 
| 356 | 
            -
                            "sso-session #{sso_session_name} must be defined in the config file."  | 
| 385 | 
            +
                            "sso-session #{sso_session_name} must be defined in the config file." \
         | 
| 357 386 | 
             
                              "Referenced by profile #{profile}"
         | 
| 358 387 | 
             
                    end
         | 
| 359 388 |  | 
| @@ -3,24 +3,19 @@ | |
| 3 3 | 
             
            module Aws
         | 
| 4 4 | 
             
              # An auto-refreshing credential provider that assumes a role via
         | 
| 5 5 | 
             
              # {Aws::SSO::Client#get_role_credentials} using a cached access
         | 
| 6 | 
            -
              # token.  | 
| 7 | 
            -
              #  | 
| 8 | 
            -
              #  | 
| 9 | 
            -
              #
         | 
| 10 | 
            -
              #  | 
| 11 | 
            -
              #  | 
| 12 | 
            -
              # access token generated and cached from `aws login` will also expire.
         | 
| 13 | 
            -
              # Once this token expires, it will not be usable to refresh AWS credentials,
         | 
| 14 | 
            -
              # and another token will be needed. The SDK does not manage refreshing of
         | 
| 15 | 
            -
              # the token value, but this can be done by running `aws login` with the
         | 
| 16 | 
            -
              # correct profile.
         | 
| 6 | 
            +
              # token. When `sso_session` is specified, token refresh logic from
         | 
| 7 | 
            +
              # {Aws::SSOTokenProvider} will be used to refresh the token if possible.
         | 
| 8 | 
            +
              # This class does NOT implement the SSO login token flow - tokens
         | 
| 9 | 
            +
              # must generated separately by running `aws login` from the
         | 
| 10 | 
            +
              # AWS CLI with the correct profile. The `SSOCredentials` will
         | 
| 11 | 
            +
              # auto-refresh the AWS credentials from SSO.
         | 
| 17 12 | 
             
              #
         | 
| 18 13 | 
             
              #     # You must first run aws sso login --profile your-sso-profile
         | 
| 19 14 | 
             
              #     sso_credentials = Aws::SSOCredentials.new(
         | 
| 20 15 | 
             
              #       sso_account_id: '123456789',
         | 
| 21 16 | 
             
              #       sso_role_name: "role_name",
         | 
| 22 17 | 
             
              #       sso_region: "us-east-1",
         | 
| 23 | 
            -
              #        | 
| 18 | 
            +
              #       sso_session: 'my_sso_session'
         | 
| 24 19 | 
             
              #     )
         | 
| 25 20 | 
             
              #     ec2 = Aws::EC2::Client.new(credentials: sso_credentials)
         | 
| 26 21 | 
             
              #
         | 
| @@ -35,7 +30,8 @@ module Aws | |
| 35 30 | 
             
                include RefreshingCredentials
         | 
| 36 31 |  | 
| 37 32 | 
             
                # @api private
         | 
| 38 | 
            -
                 | 
| 33 | 
            +
                LEGACY_REQUIRED_OPTS =         [:sso_start_url, :sso_account_id, :sso_region, :sso_role_name].freeze
         | 
| 34 | 
            +
                TOKEN_PROVIDER_REQUIRED_OPTS = [:sso_session, :sso_account_id, :sso_region, :sso_role_name].freeze
         | 
| 39 35 |  | 
| 40 36 | 
             
                # @api private
         | 
| 41 37 | 
             
                SSO_LOGIN_GUIDANCE = 'The SSO session associated with this profile has '\
         | 
| @@ -45,17 +41,23 @@ module Aws | |
| 45 41 | 
             
                # @option options [required, String] :sso_account_id The AWS account ID
         | 
| 46 42 | 
             
                #   that temporary AWS credentials will be resolved for
         | 
| 47 43 | 
             
                #
         | 
| 48 | 
            -
                # @option options [required, String] :sso_region The AWS region where the
         | 
| 49 | 
            -
                #   SSO directory for the given sso_start_url is hosted.
         | 
| 50 | 
            -
                #
         | 
| 51 44 | 
             
                # @option options [required, String] :sso_role_name The corresponding
         | 
| 52 45 | 
             
                #   IAM role in the AWS account that temporary AWS credentials
         | 
| 53 46 | 
             
                #   will be resolved for.
         | 
| 54 47 | 
             
                #
         | 
| 55 | 
            -
                # @option options [required, String] : | 
| 56 | 
            -
                #    | 
| 48 | 
            +
                # @option options [required, String] :sso_region The AWS region where the
         | 
| 49 | 
            +
                #   SSO directory for the given sso_start_url is hosted.
         | 
| 50 | 
            +
                #
         | 
| 51 | 
            +
                # @option options [String] :sso_session The SSO Token used for fetching
         | 
| 52 | 
            +
                #   the token. If provided, refresh logic from the {Aws::SSOTokenProvider}
         | 
| 53 | 
            +
                #   will be used.
         | 
| 54 | 
            +
                #
         | 
| 55 | 
            +
                # @option options [String] :sso_start_url (legacy profiles) If provided,
         | 
| 56 | 
            +
                #   legacy token fetch behavior will be used, which does not support
         | 
| 57 | 
            +
                #   token refreshing.  The start URL is provided by the SSO
         | 
| 58 | 
            +
                #   service via the console and is the URL used to
         | 
| 57 59 | 
             
                #   login to the SSO directory. This is also sometimes referred to as
         | 
| 58 | 
            -
                #   the "User Portal URL"
         | 
| 60 | 
            +
                #   the "User Portal URL".
         | 
| 59 61 | 
             
                #
         | 
| 60 62 | 
             
                # @option options [SSO::Client] :client Optional `SSO::Client`.  If not
         | 
| 61 63 | 
             
                #   provided, a client will be constructed.
         | 
| @@ -65,27 +67,52 @@ module Aws | |
| 65 67 | 
             
                #   with an instance of this object when
         | 
| 66 68 | 
             
                #   AWS credentials are required and need to be refreshed.
         | 
| 67 69 | 
             
                def initialize(options = {})
         | 
| 68 | 
            -
             | 
| 69 | 
            -
                   | 
| 70 | 
            -
             | 
| 71 | 
            -
                     | 
| 70 | 
            +
                  options = options.select {|k, v| !v.nil? }
         | 
| 71 | 
            +
                  if (options[:sso_session])
         | 
| 72 | 
            +
                    missing_keys = TOKEN_PROVIDER_REQUIRED_OPTS.select { |k| options[k].nil? }
         | 
| 73 | 
            +
                    unless missing_keys.empty?
         | 
| 74 | 
            +
                      raise ArgumentError, "Missing required keys: #{missing_keys}"
         | 
| 75 | 
            +
                    end
         | 
| 76 | 
            +
                    @legacy = false
         | 
| 77 | 
            +
                    @sso_role_name = options.delete(:sso_role_name)
         | 
| 78 | 
            +
                    @sso_account_id = options.delete(:sso_account_id)
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                    # if client has been passed, don't pass through to SSOTokenProvider
         | 
| 81 | 
            +
                    @client = options.delete(:client)
         | 
| 82 | 
            +
                    options.delete(:sso_start_url)
         | 
| 83 | 
            +
                    @token_provider = Aws::SSOTokenProvider.new(options.dup)
         | 
| 84 | 
            +
                    @sso_session = options.delete(:sso_session)
         | 
| 85 | 
            +
                    @sso_region = options.delete(:sso_region)
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                    unless @client
         | 
| 88 | 
            +
                      client_opts = {}
         | 
| 89 | 
            +
                      options.each_pair { |k,v| client_opts[k] = v unless CLIENT_EXCLUDE_OPTIONS.include?(k) }
         | 
| 90 | 
            +
                      client_opts[:region] = @sso_region
         | 
| 91 | 
            +
                      client_opts[:credentials] = nil
         | 
| 92 | 
            +
                      @client = Aws::SSO::Client.new(client_opts)
         | 
| 93 | 
            +
                    end
         | 
| 94 | 
            +
                  else # legacy behavior
         | 
| 95 | 
            +
                    missing_keys = LEGACY_REQUIRED_OPTS.select { |k| options[k].nil? }
         | 
| 96 | 
            +
                    unless missing_keys.empty?
         | 
| 97 | 
            +
                      raise ArgumentError, "Missing required keys: #{missing_keys}"
         | 
| 98 | 
            +
                    end
         | 
| 99 | 
            +
                    @legacy = true
         | 
| 100 | 
            +
                    @sso_start_url = options.delete(:sso_start_url)
         | 
| 101 | 
            +
                    @sso_region = options.delete(:sso_region)
         | 
| 102 | 
            +
                    @sso_role_name = options.delete(:sso_role_name)
         | 
| 103 | 
            +
                    @sso_account_id = options.delete(:sso_account_id)
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                    # validate we can read the token file
         | 
| 106 | 
            +
                    read_cached_token
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                    client_opts = {}
         | 
| 109 | 
            +
                    options.each_pair { |k,v| client_opts[k] = v unless CLIENT_EXCLUDE_OPTIONS.include?(k) }
         | 
| 110 | 
            +
                    client_opts[:region] = @sso_region
         | 
| 111 | 
            +
                    client_opts[:credentials] = nil
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                    @client = options[:client] || Aws::SSO::Client.new(client_opts)
         | 
| 72 114 | 
             
                  end
         | 
| 73 115 |  | 
| 74 | 
            -
                  @sso_start_url = options.delete(:sso_start_url)
         | 
| 75 | 
            -
                  @sso_region = options.delete(:sso_region)
         | 
| 76 | 
            -
                  @sso_role_name = options.delete(:sso_role_name)
         | 
| 77 | 
            -
                  @sso_account_id = options.delete(:sso_account_id)
         | 
| 78 | 
            -
             | 
| 79 | 
            -
                  # validate we can read the token file
         | 
| 80 | 
            -
                  read_cached_token
         | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
                  client_opts = {}
         | 
| 84 | 
            -
                  options.each_pair { |k,v| client_opts[k] = v unless CLIENT_EXCLUDE_OPTIONS.include?(k) }
         | 
| 85 | 
            -
                  client_opts[:region] = @sso_region
         | 
| 86 | 
            -
                  client_opts[:credentials] = nil
         | 
| 87 | 
            -
             | 
| 88 | 
            -
                  @client = options[:client] || Aws::SSO::Client.new(client_opts)
         | 
| 89 116 | 
             
                  @async_refresh = true
         | 
| 90 117 | 
             
                  super
         | 
| 91 118 | 
             
                end
         | 
| @@ -111,12 +138,20 @@ module Aws | |
| 111 138 | 
             
                end
         | 
| 112 139 |  | 
| 113 140 | 
             
                def refresh
         | 
| 114 | 
            -
                   | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 141 | 
            +
                  c = if @legacy
         | 
| 142 | 
            +
                        cached_token = read_cached_token
         | 
| 143 | 
            +
                        @client.get_role_credentials(
         | 
| 144 | 
            +
                          account_id: @sso_account_id,
         | 
| 145 | 
            +
                          role_name: @sso_role_name,
         | 
| 146 | 
            +
                          access_token: cached_token['accessToken']
         | 
| 147 | 
            +
                        ).role_credentials
         | 
| 148 | 
            +
                      else
         | 
| 149 | 
            +
                        @client.get_role_credentials(
         | 
| 150 | 
            +
                          account_id: @sso_account_id,
         | 
| 151 | 
            +
                          role_name: @sso_role_name,
         | 
| 152 | 
            +
                          access_token: @token_provider.token.token
         | 
| 153 | 
            +
                        ).role_credentials
         | 
| 154 | 
            +
                      end
         | 
| 120 155 |  | 
| 121 156 | 
             
                  @credentials = Credentials.new(
         | 
| 122 157 | 
             
                    c.access_key_id,
         | 
| @@ -39,12 +39,13 @@ module Aws | |
| 39 39 |  | 
| 40 40 | 
             
                  options[:region] = @sso_region
         | 
| 41 41 | 
             
                  options[:credentials] = nil
         | 
| 42 | 
            +
                  options[:token_provider] = nil
         | 
| 42 43 | 
             
                  @client = options[:client] || Aws::SSOOIDC::Client.new(options)
         | 
| 43 44 |  | 
| 44 45 | 
             
                  super
         | 
| 45 46 | 
             
                end
         | 
| 46 47 |  | 
| 47 | 
            -
                # @return [ | 
| 48 | 
            +
                # @return [SSOOIDC::Client]
         | 
| 48 49 | 
             
                attr_reader :client
         | 
| 49 50 |  | 
| 50 51 | 
             
                private
         | 
| @@ -66,7 +67,7 @@ module Aws | |
| 66 67 | 
             
                      resp = @client.create_token(
         | 
| 67 68 | 
             
                        grant_type: 'refresh_token',
         | 
| 68 69 | 
             
                        client_id: token_json['clientId'],
         | 
| 69 | 
            -
                        client_secret: token_json[' | 
| 70 | 
            +
                        client_secret: token_json['clientSecret'],
         | 
| 70 71 | 
             
                        refresh_token: token_json['refreshToken']
         | 
| 71 72 | 
             
                      )
         | 
| 72 73 | 
             
                      token_json['accessToken'] = resp.access_token
         | 
| @@ -62,7 +62,9 @@ module Aws | |
| 62 62 | 
             
                  def send_request(options)
         | 
| 63 63 | 
             
                    req = options[:client].build_request(@operation_name, options[:params])
         | 
| 64 64 | 
             
                    req.handlers.remove(RAISE_HANDLER)
         | 
| 65 | 
            -
                     | 
| 65 | 
            +
                    Aws::Plugins::UserAgent.feature('waiter') do
         | 
| 66 | 
            +
                      req.send_request
         | 
| 67 | 
            +
                    end
         | 
| 66 68 | 
             
                  end
         | 
| 67 69 |  | 
| 68 70 | 
             
                  def acceptor_matches?(acceptor, response)
         | 
    
        data/lib/aws-sdk-core.rb
    CHANGED
    
    
    
        data/lib/aws-sdk-sso/client.rb
    CHANGED
    
    | @@ -275,6 +275,11 @@ module Aws::SSO | |
| 275 275 | 
             
                #       in the future.
         | 
| 276 276 | 
             
                #
         | 
| 277 277 | 
             
                #
         | 
| 278 | 
            +
                #   @option options [String] :sdk_ua_app_id
         | 
| 279 | 
            +
                #     A unique and opaque application ID that is appended to the
         | 
| 280 | 
            +
                #     User-Agent header as app/<sdk_ua_app_id>. It should have a
         | 
| 281 | 
            +
                #     maximum length of 50.
         | 
| 282 | 
            +
                #
         | 
| 278 283 | 
             
                #   @option options [String] :secret_access_key
         | 
| 279 284 | 
             
                #
         | 
| 280 285 | 
             
                #   @option options [String] :session_token
         | 
| @@ -585,7 +590,7 @@ module Aws::SSO | |
| 585 590 | 
             
                    params: params,
         | 
| 586 591 | 
             
                    config: config)
         | 
| 587 592 | 
             
                  context[:gem_name] = 'aws-sdk-core'
         | 
| 588 | 
            -
                  context[:gem_version] = '3. | 
| 593 | 
            +
                  context[:gem_version] = '3.174.0'
         | 
| 589 594 | 
             
                  Seahorse::Client::Request.new(handlers, context)
         | 
| 590 595 | 
             
                end
         | 
| 591 596 |  | 
| @@ -9,104 +9,43 @@ | |
| 9 9 |  | 
| 10 10 | 
             
            module Aws::SSO
         | 
| 11 11 | 
             
              class EndpointProvider
         | 
| 12 | 
            -
                def  | 
| 13 | 
            -
                   | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
                       | 
| 20 | 
            -
             | 
| 12 | 
            +
                def resolve_endpoint(parameters)
         | 
| 13 | 
            +
                  region = parameters.region
         | 
| 14 | 
            +
                  use_dual_stack = parameters.use_dual_stack
         | 
| 15 | 
            +
                  use_fips = parameters.use_fips
         | 
| 16 | 
            +
                  endpoint = parameters.endpoint
         | 
| 17 | 
            +
                  if (partition_result = Aws::Endpoints::Matchers.aws_partition(region))
         | 
| 18 | 
            +
                    if Aws::Endpoints::Matchers.set?(endpoint) && (url = Aws::Endpoints::Matchers.parse_url(endpoint))
         | 
| 19 | 
            +
                      if Aws::Endpoints::Matchers.boolean_equals?(use_fips, true)
         | 
| 20 | 
            +
                        raise ArgumentError, "Invalid Configuration: FIPS and custom endpoint are not supported"
         | 
| 21 | 
            +
                      end
         | 
| 22 | 
            +
                      if Aws::Endpoints::Matchers.boolean_equals?(use_dual_stack, true)
         | 
| 23 | 
            +
                        raise ArgumentError, "Invalid Configuration: Dualstack and custom endpoint are not supported"
         | 
| 24 | 
            +
                      end
         | 
| 25 | 
            +
                      return Aws::Endpoints::Endpoint.new(url: endpoint, headers: {}, properties: {})
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                    if Aws::Endpoints::Matchers.boolean_equals?(use_fips, true) && Aws::Endpoints::Matchers.boolean_equals?(use_dual_stack, true)
         | 
| 28 | 
            +
                      if Aws::Endpoints::Matchers.boolean_equals?(true, Aws::Endpoints::Matchers.attr(partition_result, "supportsFIPS")) && Aws::Endpoints::Matchers.boolean_equals?(true, Aws::Endpoints::Matchers.attr(partition_result, "supportsDualStack"))
         | 
| 29 | 
            +
                        return Aws::Endpoints::Endpoint.new(url: "https://portal.sso-fips.#{region}.#{partition_result['dualStackDnsSuffix']}", headers: {}, properties: {})
         | 
| 30 | 
            +
                      end
         | 
| 31 | 
            +
                      raise ArgumentError, "FIPS and DualStack are enabled, but this partition does not support one or both"
         | 
| 32 | 
            +
                    end
         | 
| 33 | 
            +
                    if Aws::Endpoints::Matchers.boolean_equals?(use_fips, true)
         | 
| 34 | 
            +
                      if Aws::Endpoints::Matchers.boolean_equals?(true, Aws::Endpoints::Matchers.attr(partition_result, "supportsFIPS"))
         | 
| 35 | 
            +
                        return Aws::Endpoints::Endpoint.new(url: "https://portal.sso-fips.#{region}.#{partition_result['dnsSuffix']}", headers: {}, properties: {})
         | 
| 36 | 
            +
                      end
         | 
| 37 | 
            +
                      raise ArgumentError, "FIPS is enabled but this partition does not support FIPS"
         | 
| 38 | 
            +
                    end
         | 
| 39 | 
            +
                    if Aws::Endpoints::Matchers.boolean_equals?(use_dual_stack, true)
         | 
| 40 | 
            +
                      if Aws::Endpoints::Matchers.boolean_equals?(true, Aws::Endpoints::Matchers.attr(partition_result, "supportsDualStack"))
         | 
| 41 | 
            +
                        return Aws::Endpoints::Endpoint.new(url: "https://portal.sso.#{region}.#{partition_result['dualStackDnsSuffix']}", headers: {}, properties: {})
         | 
| 42 | 
            +
                      end
         | 
| 43 | 
            +
                      raise ArgumentError, "DualStack is enabled but this partition does not support DualStack"
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                    return Aws::Endpoints::Endpoint.new(url: "https://portal.sso.#{region}.#{partition_result['dnsSuffix']}", headers: {}, properties: {})
         | 
| 21 46 | 
             
                  end
         | 
| 22 | 
            -
                   | 
| 23 | 
            -
                end
         | 
| 47 | 
            +
                  raise ArgumentError, 'No endpoint could be resolved'
         | 
| 24 48 |  | 
| 25 | 
            -
                def resolve_endpoint(parameters)
         | 
| 26 | 
            -
                  @provider.resolve_endpoint(parameters)
         | 
| 27 49 | 
             
                end
         | 
| 28 | 
            -
             | 
| 29 | 
            -
                # @api private
         | 
| 30 | 
            -
                RULES = <<-JSON
         | 
| 31 | 
            -
            eyJ2ZXJzaW9uIjoiMS4wIiwicGFyYW1ldGVycyI6eyJSZWdpb24iOnsiYnVp
         | 
| 32 | 
            -
            bHRJbiI6IkFXUzo6UmVnaW9uIiwicmVxdWlyZWQiOmZhbHNlLCJkb2N1bWVu
         | 
| 33 | 
            -
            dGF0aW9uIjoiVGhlIEFXUyByZWdpb24gdXNlZCB0byBkaXNwYXRjaCB0aGUg
         | 
| 34 | 
            -
            cmVxdWVzdC4iLCJ0eXBlIjoiU3RyaW5nIn0sIlVzZUR1YWxTdGFjayI6eyJi
         | 
| 35 | 
            -
            dWlsdEluIjoiQVdTOjpVc2VEdWFsU3RhY2siLCJyZXF1aXJlZCI6dHJ1ZSwi
         | 
| 36 | 
            -
            ZGVmYXVsdCI6ZmFsc2UsImRvY3VtZW50YXRpb24iOiJXaGVuIHRydWUsIHVz
         | 
| 37 | 
            -
            ZSB0aGUgZHVhbC1zdGFjayBlbmRwb2ludC4gSWYgdGhlIGNvbmZpZ3VyZWQg
         | 
| 38 | 
            -
            ZW5kcG9pbnQgZG9lcyBub3Qgc3VwcG9ydCBkdWFsLXN0YWNrLCBkaXNwYXRj
         | 
| 39 | 
            -
            aGluZyB0aGUgcmVxdWVzdCBNQVkgcmV0dXJuIGFuIGVycm9yLiIsInR5cGUi
         | 
| 40 | 
            -
            OiJCb29sZWFuIn0sIlVzZUZJUFMiOnsiYnVpbHRJbiI6IkFXUzo6VXNlRklQ
         | 
| 41 | 
            -
            UyIsInJlcXVpcmVkIjp0cnVlLCJkZWZhdWx0IjpmYWxzZSwiZG9jdW1lbnRh
         | 
| 42 | 
            -
            dGlvbiI6IldoZW4gdHJ1ZSwgc2VuZCB0aGlzIHJlcXVlc3QgdG8gdGhlIEZJ
         | 
| 43 | 
            -
            UFMtY29tcGxpYW50IHJlZ2lvbmFsIGVuZHBvaW50LiBJZiB0aGUgY29uZmln
         | 
| 44 | 
            -
            dXJlZCBlbmRwb2ludCBkb2VzIG5vdCBoYXZlIGEgRklQUyBjb21wbGlhbnQg
         | 
| 45 | 
            -
            ZW5kcG9pbnQsIGRpc3BhdGNoaW5nIHRoZSByZXF1ZXN0IHdpbGwgcmV0dXJu
         | 
| 46 | 
            -
            IGFuIGVycm9yLiIsInR5cGUiOiJCb29sZWFuIn0sIkVuZHBvaW50Ijp7ImJ1
         | 
| 47 | 
            -
            aWx0SW4iOiJTREs6OkVuZHBvaW50IiwicmVxdWlyZWQiOmZhbHNlLCJkb2N1
         | 
| 48 | 
            -
            bWVudGF0aW9uIjoiT3ZlcnJpZGUgdGhlIGVuZHBvaW50IHVzZWQgdG8gc2Vu
         | 
| 49 | 
            -
            ZCB0aGlzIHJlcXVlc3QiLCJ0eXBlIjoiU3RyaW5nIn19LCJydWxlcyI6W3si
         | 
| 50 | 
            -
            Y29uZGl0aW9ucyI6W3siZm4iOiJhd3MucGFydGl0aW9uIiwiYXJndiI6W3si
         | 
| 51 | 
            -
            cmVmIjoiUmVnaW9uIn1dLCJhc3NpZ24iOiJQYXJ0aXRpb25SZXN1bHQifV0s
         | 
| 52 | 
            -
            InR5cGUiOiJ0cmVlIiwicnVsZXMiOlt7ImNvbmRpdGlvbnMiOlt7ImZuIjoi
         | 
| 53 | 
            -
            aXNTZXQiLCJhcmd2IjpbeyJyZWYiOiJFbmRwb2ludCJ9XX0seyJmbiI6InBh
         | 
| 54 | 
            -
            cnNlVVJMIiwiYXJndiI6W3sicmVmIjoiRW5kcG9pbnQifV0sImFzc2lnbiI6
         | 
| 55 | 
            -
            InVybCJ9XSwidHlwZSI6InRyZWUiLCJydWxlcyI6W3siY29uZGl0aW9ucyI6
         | 
| 56 | 
            -
            W3siZm4iOiJib29sZWFuRXF1YWxzIiwiYXJndiI6W3sicmVmIjoiVXNlRklQ
         | 
| 57 | 
            -
            UyJ9LHRydWVdfV0sImVycm9yIjoiSW52YWxpZCBDb25maWd1cmF0aW9uOiBG
         | 
| 58 | 
            -
            SVBTIGFuZCBjdXN0b20gZW5kcG9pbnQgYXJlIG5vdCBzdXBwb3J0ZWQiLCJ0
         | 
| 59 | 
            -
            eXBlIjoiZXJyb3IifSx7ImNvbmRpdGlvbnMiOltdLCJ0eXBlIjoidHJlZSIs
         | 
| 60 | 
            -
            InJ1bGVzIjpbeyJjb25kaXRpb25zIjpbeyJmbiI6ImJvb2xlYW5FcXVhbHMi
         | 
| 61 | 
            -
            LCJhcmd2IjpbeyJyZWYiOiJVc2VEdWFsU3RhY2sifSx0cnVlXX1dLCJlcnJv
         | 
| 62 | 
            -
            ciI6IkludmFsaWQgQ29uZmlndXJhdGlvbjogRHVhbHN0YWNrIGFuZCBjdXN0
         | 
| 63 | 
            -
            b20gZW5kcG9pbnQgYXJlIG5vdCBzdXBwb3J0ZWQiLCJ0eXBlIjoiZXJyb3Ii
         | 
| 64 | 
            -
            fSx7ImNvbmRpdGlvbnMiOltdLCJlbmRwb2ludCI6eyJ1cmwiOnsicmVmIjoi
         | 
| 65 | 
            -
            RW5kcG9pbnQifSwicHJvcGVydGllcyI6e30sImhlYWRlcnMiOnt9fSwidHlw
         | 
| 66 | 
            -
            ZSI6ImVuZHBvaW50In1dfV19LHsiY29uZGl0aW9ucyI6W3siZm4iOiJib29s
         | 
| 67 | 
            -
            ZWFuRXF1YWxzIiwiYXJndiI6W3sicmVmIjoiVXNlRklQUyJ9LHRydWVdfSx7
         | 
| 68 | 
            -
            ImZuIjoiYm9vbGVhbkVxdWFscyIsImFyZ3YiOlt7InJlZiI6IlVzZUR1YWxT
         | 
| 69 | 
            -
            dGFjayJ9LHRydWVdfV0sInR5cGUiOiJ0cmVlIiwicnVsZXMiOlt7ImNvbmRp
         | 
| 70 | 
            -
            dGlvbnMiOlt7ImZuIjoiYm9vbGVhbkVxdWFscyIsImFyZ3YiOlt0cnVlLHsi
         | 
| 71 | 
            -
            Zm4iOiJnZXRBdHRyIiwiYXJndiI6W3sicmVmIjoiUGFydGl0aW9uUmVzdWx0
         | 
| 72 | 
            -
            In0sInN1cHBvcnRzRklQUyJdfV19LHsiZm4iOiJib29sZWFuRXF1YWxzIiwi
         | 
| 73 | 
            -
            YXJndiI6W3RydWUseyJmbiI6ImdldEF0dHIiLCJhcmd2IjpbeyJyZWYiOiJQ
         | 
| 74 | 
            -
            YXJ0aXRpb25SZXN1bHQifSwic3VwcG9ydHNEdWFsU3RhY2siXX1dfV0sInR5
         | 
| 75 | 
            -
            cGUiOiJ0cmVlIiwicnVsZXMiOlt7ImNvbmRpdGlvbnMiOltdLCJlbmRwb2lu
         | 
| 76 | 
            -
            dCI6eyJ1cmwiOiJodHRwczovL3BvcnRhbC5zc28tZmlwcy57UmVnaW9ufS57
         | 
| 77 | 
            -
            UGFydGl0aW9uUmVzdWx0I2R1YWxTdGFja0Ruc1N1ZmZpeH0iLCJwcm9wZXJ0
         | 
| 78 | 
            -
            aWVzIjp7fSwiaGVhZGVycyI6e319LCJ0eXBlIjoiZW5kcG9pbnQifV19LHsi
         | 
| 79 | 
            -
            Y29uZGl0aW9ucyI6W10sImVycm9yIjoiRklQUyBhbmQgRHVhbFN0YWNrIGFy
         | 
| 80 | 
            -
            ZSBlbmFibGVkLCBidXQgdGhpcyBwYXJ0aXRpb24gZG9lcyBub3Qgc3VwcG9y
         | 
| 81 | 
            -
            dCBvbmUgb3IgYm90aCIsInR5cGUiOiJlcnJvciJ9XX0seyJjb25kaXRpb25z
         | 
| 82 | 
            -
            IjpbeyJmbiI6ImJvb2xlYW5FcXVhbHMiLCJhcmd2IjpbeyJyZWYiOiJVc2VG
         | 
| 83 | 
            -
            SVBTIn0sdHJ1ZV19XSwidHlwZSI6InRyZWUiLCJydWxlcyI6W3siY29uZGl0
         | 
| 84 | 
            -
            aW9ucyI6W3siZm4iOiJib29sZWFuRXF1YWxzIiwiYXJndiI6W3RydWUseyJm
         | 
| 85 | 
            -
            biI6ImdldEF0dHIiLCJhcmd2IjpbeyJyZWYiOiJQYXJ0aXRpb25SZXN1bHQi
         | 
| 86 | 
            -
            fSwic3VwcG9ydHNGSVBTIl19XX1dLCJ0eXBlIjoidHJlZSIsInJ1bGVzIjpb
         | 
| 87 | 
            -
            eyJjb25kaXRpb25zIjpbXSwidHlwZSI6InRyZWUiLCJydWxlcyI6W3siY29u
         | 
| 88 | 
            -
            ZGl0aW9ucyI6W10sImVuZHBvaW50Ijp7InVybCI6Imh0dHBzOi8vcG9ydGFs
         | 
| 89 | 
            -
            LnNzby1maXBzLntSZWdpb259LntQYXJ0aXRpb25SZXN1bHQjZG5zU3VmZml4
         | 
| 90 | 
            -
            fSIsInByb3BlcnRpZXMiOnt9LCJoZWFkZXJzIjp7fX0sInR5cGUiOiJlbmRw
         | 
| 91 | 
            -
            b2ludCJ9XX1dfSx7ImNvbmRpdGlvbnMiOltdLCJlcnJvciI6IkZJUFMgaXMg
         | 
| 92 | 
            -
            ZW5hYmxlZCBidXQgdGhpcyBwYXJ0aXRpb24gZG9lcyBub3Qgc3VwcG9ydCBG
         | 
| 93 | 
            -
            SVBTIiwidHlwZSI6ImVycm9yIn1dfSx7ImNvbmRpdGlvbnMiOlt7ImZuIjoi
         | 
| 94 | 
            -
            Ym9vbGVhbkVxdWFscyIsImFyZ3YiOlt7InJlZiI6IlVzZUR1YWxTdGFjayJ9
         | 
| 95 | 
            -
            LHRydWVdfV0sInR5cGUiOiJ0cmVlIiwicnVsZXMiOlt7ImNvbmRpdGlvbnMi
         | 
| 96 | 
            -
            Olt7ImZuIjoiYm9vbGVhbkVxdWFscyIsImFyZ3YiOlt0cnVlLHsiZm4iOiJn
         | 
| 97 | 
            -
            ZXRBdHRyIiwiYXJndiI6W3sicmVmIjoiUGFydGl0aW9uUmVzdWx0In0sInN1
         | 
| 98 | 
            -
            cHBvcnRzRHVhbFN0YWNrIl19XX1dLCJ0eXBlIjoidHJlZSIsInJ1bGVzIjpb
         | 
| 99 | 
            -
            eyJjb25kaXRpb25zIjpbXSwiZW5kcG9pbnQiOnsidXJsIjoiaHR0cHM6Ly9w
         | 
| 100 | 
            -
            b3J0YWwuc3NvLntSZWdpb259LntQYXJ0aXRpb25SZXN1bHQjZHVhbFN0YWNr
         | 
| 101 | 
            -
            RG5zU3VmZml4fSIsInByb3BlcnRpZXMiOnt9LCJoZWFkZXJzIjp7fX0sInR5
         | 
| 102 | 
            -
            cGUiOiJlbmRwb2ludCJ9XX0seyJjb25kaXRpb25zIjpbXSwiZXJyb3IiOiJE
         | 
| 103 | 
            -
            dWFsU3RhY2sgaXMgZW5hYmxlZCBidXQgdGhpcyBwYXJ0aXRpb24gZG9lcyBu
         | 
| 104 | 
            -
            b3Qgc3VwcG9ydCBEdWFsU3RhY2siLCJ0eXBlIjoiZXJyb3IifV19LHsiY29u
         | 
| 105 | 
            -
            ZGl0aW9ucyI6W10sImVuZHBvaW50Ijp7InVybCI6Imh0dHBzOi8vcG9ydGFs
         | 
| 106 | 
            -
            LnNzby57UmVnaW9ufS57UGFydGl0aW9uUmVzdWx0I2Ruc1N1ZmZpeH0iLCJw
         | 
| 107 | 
            -
            cm9wZXJ0aWVzIjp7fSwiaGVhZGVycyI6e319LCJ0eXBlIjoiZW5kcG9pbnQi
         | 
| 108 | 
            -
            fV19XX0=
         | 
| 109 | 
            -
             | 
| 110 | 
            -
                JSON
         | 
| 111 50 | 
             
              end
         | 
| 112 51 | 
             
            end
         |