aws-sdk-core 3.131.1 → 3.170.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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +275 -0
  3. data/VERSION +1 -1
  4. data/lib/aws-sdk-core/arn.rb +13 -0
  5. data/lib/aws-sdk-core/binary/encode_handler.rb +12 -1
  6. data/lib/aws-sdk-core/credential_provider_chain.rb +6 -4
  7. data/lib/aws-sdk-core/endpoints/condition.rb +41 -0
  8. data/lib/aws-sdk-core/endpoints/endpoint.rb +17 -0
  9. data/lib/aws-sdk-core/endpoints/endpoint_rule.rb +75 -0
  10. data/lib/aws-sdk-core/endpoints/error_rule.rb +42 -0
  11. data/lib/aws-sdk-core/endpoints/function.rb +80 -0
  12. data/lib/aws-sdk-core/endpoints/matchers.rb +127 -0
  13. data/lib/aws-sdk-core/endpoints/reference.rb +31 -0
  14. data/lib/aws-sdk-core/endpoints/rule.rb +25 -0
  15. data/lib/aws-sdk-core/endpoints/rule_set.rb +52 -0
  16. data/lib/aws-sdk-core/endpoints/rules_provider.rb +37 -0
  17. data/lib/aws-sdk-core/endpoints/templater.rb +58 -0
  18. data/lib/aws-sdk-core/endpoints/tree_rule.rb +45 -0
  19. data/lib/aws-sdk-core/endpoints/url.rb +60 -0
  20. data/lib/aws-sdk-core/endpoints.rb +74 -0
  21. data/lib/aws-sdk-core/errors.rb +13 -0
  22. data/lib/aws-sdk-core/json/error_handler.rb +10 -1
  23. data/lib/aws-sdk-core/pageable_response.rb +7 -0
  24. data/lib/aws-sdk-core/plugins/bearer_authorization.rb +67 -0
  25. data/lib/aws-sdk-core/plugins/credentials_configuration.rb +24 -0
  26. data/lib/aws-sdk-core/plugins/endpoint_discovery.rb +6 -2
  27. data/lib/aws-sdk-core/plugins/jsonvalue_converter.rb +34 -6
  28. data/lib/aws-sdk-core/plugins/recursion_detection.rb +14 -3
  29. data/lib/aws-sdk-core/plugins/regional_endpoint.rb +5 -0
  30. data/lib/aws-sdk-core/plugins/retries/error_inspector.rb +2 -1
  31. data/lib/aws-sdk-core/plugins/sign.rb +200 -0
  32. data/lib/aws-sdk-core/plugins/signature_v2.rb +1 -0
  33. data/lib/aws-sdk-core/plugins/signature_v4.rb +13 -7
  34. data/lib/aws-sdk-core/refreshing_token.rb +71 -0
  35. data/lib/aws-sdk-core/rest/handler.rb +1 -1
  36. data/lib/aws-sdk-core/rest/request/headers.rb +2 -6
  37. data/lib/aws-sdk-core/shared_config.rb +76 -5
  38. data/lib/aws-sdk-core/sso_credentials.rb +79 -44
  39. data/lib/aws-sdk-core/sso_token_provider.rb +135 -0
  40. data/lib/aws-sdk-core/static_token_provider.rb +14 -0
  41. data/lib/aws-sdk-core/structure.rb +6 -4
  42. data/lib/aws-sdk-core/token.rb +31 -0
  43. data/lib/aws-sdk-core/token_provider.rb +15 -0
  44. data/lib/aws-sdk-core/token_provider_chain.rb +51 -0
  45. data/lib/aws-sdk-core/xml/error_handler.rb +7 -0
  46. data/lib/aws-sdk-core/xml/parser/engines/oga.rb +2 -0
  47. data/lib/aws-sdk-core.rb +14 -0
  48. data/lib/aws-sdk-sso/client.rb +51 -11
  49. data/lib/aws-sdk-sso/endpoint_parameters.rb +66 -0
  50. data/lib/aws-sdk-sso/endpoint_provider.rb +51 -0
  51. data/lib/aws-sdk-sso/endpoints.rb +71 -0
  52. data/lib/aws-sdk-sso/plugins/endpoints.rb +76 -0
  53. data/lib/aws-sdk-sso/types.rb +8 -43
  54. data/lib/aws-sdk-sso.rb +5 -1
  55. data/lib/aws-sdk-ssooidc/client.rb +606 -0
  56. data/lib/aws-sdk-ssooidc/client_api.rb +216 -0
  57. data/lib/aws-sdk-ssooidc/customizations.rb +1 -0
  58. data/lib/aws-sdk-ssooidc/endpoint_parameters.rb +66 -0
  59. data/lib/aws-sdk-ssooidc/endpoint_provider.rb +51 -0
  60. data/lib/aws-sdk-ssooidc/endpoints.rb +57 -0
  61. data/lib/aws-sdk-ssooidc/errors.rb +290 -0
  62. data/lib/aws-sdk-ssooidc/plugins/endpoints.rb +74 -0
  63. data/lib/aws-sdk-ssooidc/resource.rb +26 -0
  64. data/lib/aws-sdk-ssooidc/types.rb +502 -0
  65. data/lib/aws-sdk-ssooidc.rb +59 -0
  66. data/lib/aws-sdk-sts/client.rb +153 -134
  67. data/lib/aws-sdk-sts/endpoint_parameters.rb +78 -0
  68. data/lib/aws-sdk-sts/endpoint_provider.rb +109 -0
  69. data/lib/aws-sdk-sts/endpoints.rb +135 -0
  70. data/lib/aws-sdk-sts/plugins/endpoints.rb +84 -0
  71. data/lib/aws-sdk-sts/presigner.rb +13 -15
  72. data/lib/aws-sdk-sts/types.rb +79 -186
  73. data/lib/aws-sdk-sts.rb +5 -1
  74. data/lib/seahorse/client/async_base.rb +0 -1
  75. data/lib/seahorse/client/configuration.rb +2 -2
  76. data/lib/seahorse/client/h2/connection.rb +2 -5
  77. data/lib/seahorse/client/plugins/request_callback.rb +9 -9
  78. data/lib/seahorse/util.rb +4 -0
  79. metadata +47 -6
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+
5
+ module Aws
6
+ module Endpoints
7
+ # generic matcher functions for service endpoints
8
+ # @api private
9
+ module Matchers
10
+ # Regex that extracts anything in square brackets
11
+ BRACKET_REGEX = /\[(.*?)\]/.freeze
12
+
13
+ # CORE
14
+
15
+ # isSet(value: Option<T>) bool
16
+ def self.set?(value)
17
+ !value.nil?
18
+ end
19
+
20
+ # not(value: bool) bool
21
+ def self.not(bool)
22
+ !bool
23
+ end
24
+
25
+ # getAttr(value: Object | Array, path: string) Document
26
+ def self.attr(value, path)
27
+ parts = path.split('.')
28
+
29
+ val = if (index = parts.first[BRACKET_REGEX, 1])
30
+ # remove brackets and index from part before indexing
31
+ value[parts.first.gsub(BRACKET_REGEX, '')][index.to_i]
32
+ else
33
+ value[parts.first]
34
+ end
35
+
36
+ if parts.size == 1
37
+ val
38
+ else
39
+ attr(val, parts.slice(1..-1).join('.'))
40
+ end
41
+ end
42
+
43
+ def self.substring(input, start, stop, reverse)
44
+ return nil if start >= stop || input.size < stop
45
+
46
+ return nil if input.chars.any? { |c| c.ord > 127 }
47
+
48
+ return input[start...stop] unless reverse
49
+
50
+ r_start = input.size - stop
51
+ r_stop = input.size - start
52
+ input[r_start...r_stop]
53
+ end
54
+
55
+ # stringEquals(value1: string, value2: string) bool
56
+ def self.string_equals?(value1, value2)
57
+ value1 == value2
58
+ end
59
+
60
+ # booleanEquals(value1: bool, value2: bool) bool
61
+ def self.boolean_equals?(value1, value2)
62
+ value1 == value2
63
+ end
64
+
65
+ # uriEncode(value: string) string
66
+ def self.uri_encode(value)
67
+ CGI.escape(value.encode('UTF-8')).gsub('+', '%20').gsub('%7E', '~')
68
+ end
69
+
70
+ # parseUrl(value: string) Option<URL>
71
+ def self.parse_url(value)
72
+ URL.new(value).as_json
73
+ rescue ArgumentError, URI::InvalidURIError
74
+ nil
75
+ end
76
+
77
+ # isValidHostLabel(value: string, allowSubDomains: bool) bool
78
+ def self.valid_host_label?(value, allow_sub_domains = false)
79
+ return false if value.empty?
80
+
81
+ if allow_sub_domains
82
+ labels = value.split('.')
83
+ return labels.all? { |l| valid_host_label?(l) }
84
+ end
85
+
86
+ value =~ /\A(?!-)[a-zA-Z0-9-]{1,63}(?<!-)\z/
87
+ end
88
+
89
+ # AWS
90
+
91
+ # aws.partition(value: string) Option<Partition>
92
+ def self.aws_partition(value)
93
+ partition =
94
+ Aws::Partitions.find { |p| p.region?(value) } ||
95
+ Aws::Partitions.find { |p| value.match(p.region_regex) } ||
96
+ Aws::Partitions.find { |p| p.name == 'aws' }
97
+
98
+ return nil unless partition
99
+
100
+ partition.metadata
101
+ end
102
+
103
+ # aws.parseArn(value: string) Option<ARN>
104
+ def self.aws_parse_arn(value)
105
+ arn = Aws::ARNParser.parse(value)
106
+ json = arn.as_json
107
+ # HACK: because of poor naming and also requirement of splitting
108
+ resource = json.delete('resource')
109
+ json['resourceId'] = resource.split(%r{[:\/]}, -1)
110
+ json
111
+ rescue Aws::Errors::InvalidARNError
112
+ nil
113
+ end
114
+
115
+ # aws.isVirtualHostableS3Bucket(value: string, allowSubDomains: bool) bool
116
+ def self.aws_virtual_hostable_s3_bucket?(value, allow_sub_domains = false)
117
+ !!(value.size < 64 &&
118
+ # regular naming rules
119
+ value =~ /^[a-z0-9][a-z0-9\-#{'.' if allow_sub_domains}]+[a-z0-9]$/ &&
120
+ # not IP address
121
+ value !~ /(\d+\.){3}\d+/ &&
122
+ # no dash and hyphen together
123
+ value !~ /[.-]{2}/)
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # This class is deprecated. It is used by the Runtime endpoint
6
+ # resolution approach. It has been replaced by a code generated
7
+ # approach in each service gem. It can be removed in a new
8
+ # major version. It has to exist because
9
+ # old service gems can use a new core version.
10
+ # @api private
11
+ class Reference
12
+ def initialize(ref:)
13
+ @ref = ref
14
+ end
15
+
16
+ attr_reader :ref
17
+
18
+ def resolve(parameters, assigns)
19
+ if parameters.class.singleton_class::PARAM_MAP.key?(@ref)
20
+ member_name = parameters.class.singleton_class::PARAM_MAP[@ref]
21
+ parameters[member_name]
22
+ elsif assigns.key?(@ref)
23
+ assigns[@ref]
24
+ else
25
+ raise ArgumentError,
26
+ "Reference #{@ref} is not a param or an assigned value."
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # This class is deprecated. It is used by the Runtime endpoint
6
+ # resolution approach. It has been replaced by a code generated
7
+ # approach in each service gem. It can be removed in a new
8
+ # major version. It has to exist because
9
+ # old service gems can use a new core version.
10
+ # @api private
11
+ class Rule
12
+ # Resolves a value that is a function, reference, or template string.
13
+ def resolve_value(value, parameters, assigns)
14
+ if value.is_a?(Hash) && value['fn']
15
+ Function.new(fn: value['fn'], argv: value['argv'])
16
+ .call(parameters, assigns)
17
+ elsif value.is_a?(Hash) && value['ref']
18
+ Reference.new(ref: value['ref']).resolve(parameters, assigns)
19
+ else
20
+ Templater.resolve(value, parameters, assigns)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # This class is deprecated. It is used by the Runtime endpoint
6
+ # resolution approach. It has been replaced by a code generated
7
+ # approach in each service gem. It can be removed in a new
8
+ # major version. It has to exist because
9
+ # old service gems can use a new core version.
10
+ # @api private
11
+ class RuleSet
12
+ def initialize(version:, service_id:, parameters:, rules:)
13
+ @version = version
14
+ @service_id = service_id
15
+ @parameters = parameters
16
+ @rules = RuleSet.rules_from_json(rules || [])
17
+ end
18
+
19
+ attr_reader :version
20
+ attr_reader :service_id
21
+ attr_reader :parameters
22
+ attr_reader :rules
23
+
24
+ def self.rules_from_json(rules_json)
25
+ rules_json.each.with_object([]) do |rule, rules|
26
+ if rule['type'] == 'endpoint'
27
+ rules << EndpointRule.new(
28
+ conditions: rule['conditions'],
29
+ endpoint: rule['endpoint'],
30
+ documentation: rule['documentation']
31
+ )
32
+ elsif rule['type'] == 'error'
33
+ rules << ErrorRule.new(
34
+ conditions: rule['conditions'],
35
+ error: rule['error'],
36
+ documentation: rule['documentation']
37
+ )
38
+ elsif rule['type'] == 'tree'
39
+ rules << TreeRule.new(
40
+ conditions: rule['conditions'],
41
+ rules: rule['rules'],
42
+ documentation: rule['documentation']
43
+ )
44
+ else
45
+ # should not happen
46
+ raise "Unknown endpoint rule type: #{rule}"
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,37 @@
1
+ module Aws
2
+ module Endpoints
3
+ # This class is deprecated. It is used by the Runtime endpoint
4
+ # resolution approach. It has been replaced by a code generated
5
+ # approach in each service gem. It can be removed in a new
6
+ # major version. It has to exist because
7
+ # old service gems can use a new core version.
8
+ # @api private
9
+ class RulesProvider
10
+ def initialize(rule_set)
11
+ @rule_set = rule_set
12
+ end
13
+
14
+ def resolve_endpoint(parameters)
15
+ obj = resolve_rules(parameters)
16
+ case obj
17
+ when Endpoint
18
+ obj
19
+ when ArgumentError
20
+ raise obj
21
+ else
22
+ raise ArgumentError, 'No endpoint could be resolved'
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def resolve_rules(parameters)
29
+ @rule_set.rules.each do |rule|
30
+ output = rule.match(parameters)
31
+ return output if output
32
+ end
33
+ nil
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # Does substitutions for templated endpoint strings
6
+
7
+ # This class is deprecated. It is used by the Runtime endpoint
8
+ # resolution approach. It has been replaced by a code generated
9
+ # approach in each service gem. It can be removed in a new
10
+ # major version. It has to exist because
11
+ # old service gems can use a new core version.
12
+ # @api private
13
+ module Templater
14
+ class << self
15
+ def resolve(string, parameters, assigns)
16
+ # scans for strings in curly brackets {}
17
+ string.scan(/\{.+?\}/).each do |capture|
18
+ value = capture[1..-2] # strips curly brackets
19
+ string = string.gsub(capture, replace(value, parameters, assigns))
20
+ end
21
+ string
22
+ end
23
+
24
+ private
25
+
26
+ # Replaces the captured value with values from parameters or assign
27
+ def replace(capture, parameters, assigns)
28
+ # Pound sigil is used for getAttr calls
29
+ indexes = capture.split('#')
30
+
31
+ # no sigil found, just do substitution
32
+ if indexes.size == 1
33
+ extract_value(capture, parameters, assigns)
34
+ # sigil was found, need to call getAttr
35
+ elsif indexes.size == 2
36
+ ref, property = indexes
37
+ param = extract_value(ref, parameters, assigns)
38
+ Matchers.attr(param, property)
39
+ else
40
+ raise "Invalid templatable value: #{capture}"
41
+ end
42
+ end
43
+
44
+ # Checks both parameters and assigns hash for the referenced value
45
+ def extract_value(key, parameters, assigns)
46
+ if assigns.key?(key)
47
+ assigns[key]
48
+ elsif parameters.class.singleton_class::PARAM_MAP.key?(key)
49
+ member_name = parameters.class.singleton_class::PARAM_MAP[key]
50
+ parameters[member_name]
51
+ else
52
+ raise "Templatable value not found: #{key}"
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # This class is deprecated. It is used by the Runtime endpoint
6
+ # resolution approach. It has been replaced by a code generated
7
+ # approach in each service gem. It can be removed in a new
8
+ # major version. It has to exist because
9
+ # old service gems can use a new core version.
10
+ # @api private
11
+ class TreeRule
12
+ def initialize(type: 'tree', conditions:, rules:, documentation: nil)
13
+ @type = type
14
+ @conditions = Condition.from_json(conditions)
15
+ @rules = RuleSet.rules_from_json(rules)
16
+ @documentation = documentation
17
+ end
18
+
19
+ attr_reader :type
20
+ attr_reader :conditions
21
+ attr_reader :error
22
+ attr_reader :documentation
23
+
24
+ def match(parameters, assigned = {})
25
+ assigns = assigned.dup
26
+ matched = conditions.all? do |condition|
27
+ output = condition.match?(parameters, assigns)
28
+ assigns = assigns.merge(condition.assigned) if condition.assign
29
+ output
30
+ end
31
+ resolve_rules(parameters, assigns) if matched
32
+ end
33
+
34
+ private
35
+
36
+ def resolve_rules(parameters, assigns)
37
+ @rules.each do |rule|
38
+ output = rule.match(parameters, assigns)
39
+ return output if output
40
+ end
41
+ nil
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ipaddr'
4
+
5
+ module Aws
6
+ module Endpoints
7
+
8
+ # @api private
9
+ class URL
10
+ def initialize(url)
11
+ uri = URI(url)
12
+ @scheme = uri.scheme
13
+ # only support http and https schemes
14
+ raise ArgumentError unless %w[https http].include?(@scheme)
15
+
16
+ # do not support query
17
+ raise ArgumentError if uri.query
18
+
19
+ @authority = _authority(url, uri)
20
+ @path = uri.path
21
+ @normalized_path = uri.path + (uri.path[-1] == '/' ? '' : '/')
22
+ @is_ip = _is_ip(uri.host)
23
+ end
24
+
25
+ attr_reader :scheme
26
+ attr_reader :authority
27
+ attr_reader :path
28
+ attr_reader :normalized_path
29
+ attr_reader :is_ip
30
+
31
+ def as_json(_options = {})
32
+ {
33
+ 'scheme' => scheme,
34
+ 'authority' => authority,
35
+ 'path' => path,
36
+ 'normalizedPath' => normalized_path,
37
+ 'isIp' => is_ip
38
+ }
39
+ end
40
+
41
+ private
42
+
43
+ def _authority(url, uri)
44
+ # don't include port if it's default and not parsed originally
45
+ if uri.default_port == uri.port && !url.include?(":#{uri.port}")
46
+ uri.host
47
+ else
48
+ "#{uri.host}:#{uri.port}"
49
+ end
50
+ end
51
+
52
+ def _is_ip(authority)
53
+ IPAddr.new(authority)
54
+ true
55
+ rescue IPAddr::InvalidAddressError
56
+ false
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'endpoints/rule'
4
+ require_relative 'endpoints/condition'
5
+ require_relative 'endpoints/endpoint_rule'
6
+ require_relative 'endpoints/endpoint'
7
+ require_relative 'endpoints/error_rule'
8
+ require_relative 'endpoints/function'
9
+ require_relative 'endpoints/matchers'
10
+ require_relative 'endpoints/reference'
11
+ require_relative 'endpoints/rules_provider'
12
+ require_relative 'endpoints/rule_set'
13
+ require_relative 'endpoints/templater'
14
+ require_relative 'endpoints/tree_rule'
15
+ require_relative 'endpoints/url'
16
+
17
+ module Aws
18
+ # @api private
19
+ module Endpoints
20
+ class << self
21
+ def resolve_auth_scheme(context, endpoint)
22
+ if endpoint && (auth_schemes = endpoint.properties['authSchemes'])
23
+ auth_scheme = auth_schemes.find do |scheme|
24
+ Aws::Plugins::Sign::SUPPORTED_AUTH_TYPES.include?(scheme['name'])
25
+ end
26
+ raise 'No supported auth scheme for this endpoint.' unless auth_scheme
27
+
28
+ merge_signing_defaults(auth_scheme, context.config)
29
+ else
30
+ default_auth_scheme(context)
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def default_auth_scheme(context)
37
+ case default_api_authtype(context)
38
+ when 'v4', 'v4-unsigned-body'
39
+ auth_scheme = { 'name' => 'sigv4' }
40
+ merge_signing_defaults(auth_scheme, context.config)
41
+ when 's3', 's3v4'
42
+ auth_scheme = { 'name' => 'sigv4', 'disableDoubleEncoding' => true }
43
+ merge_signing_defaults(auth_scheme, context.config)
44
+ when 'bearer'
45
+ { 'name' => 'bearer' }
46
+ when 'none', nil
47
+ { 'name' => 'none' }
48
+ end
49
+ end
50
+
51
+ def merge_signing_defaults(auth_scheme, config)
52
+ if %w[sigv4 sigv4a].include?(auth_scheme['name'])
53
+ auth_scheme['signingName'] ||= sigv4_name(config)
54
+ if auth_scheme['name'] == 'sigv4a'
55
+ auth_scheme['signingRegionSet'] ||= ['*']
56
+ else
57
+ auth_scheme['signingRegion'] ||= config.region
58
+ end
59
+ end
60
+ auth_scheme
61
+ end
62
+
63
+ def default_api_authtype(context)
64
+ context.config.api.operation(context.operation_name)['authtype'] ||
65
+ context.config.api.metadata['signatureVersion']
66
+ end
67
+
68
+ def sigv4_name(config)
69
+ config.api.metadata['signingName'] ||
70
+ config.api.metadata['endpointPrefix']
71
+ end
72
+ end
73
+ end
74
+ end
@@ -210,6 +210,19 @@ module Aws
210
210
  # Raised when SSO Credentials are invalid
211
211
  class InvalidSSOCredentials < RuntimeError; end
212
212
 
213
+ # Raised when SSO Token is invalid
214
+ class InvalidSSOToken < RuntimeError; end
215
+
216
+ # Raised when a client is unable to sign a request because
217
+ # the bearer token is not configured or available
218
+ class MissingBearerTokenError < RuntimeError
219
+ def initialize(*args)
220
+ msg = 'unable to sign request without token set'
221
+ super(msg)
222
+ end
223
+ end
224
+
225
+
213
226
  # Raised when there is a circular reference in chained
214
227
  # source_profiles
215
228
  class SourceProfileCircularReferenceError < RuntimeError; end
@@ -26,7 +26,11 @@ module Aws
26
26
  end
27
27
 
28
28
  def error_code(json, context)
29
- code = json['__type']
29
+ code = if aws_query_error?(context)
30
+ context.http_response.headers['x-amzn-query-error'].split(';')[0]
31
+ else
32
+ json['__type']
33
+ end
30
34
  code ||= json['code']
31
35
  code ||= context.http_response.headers['x-amzn-errortype']
32
36
  if code
@@ -36,6 +40,11 @@ module Aws
36
40
  end
37
41
  end
38
42
 
43
+ def aws_query_error?(context)
44
+ context.config.api.metadata['awsQueryCompatible'] &&
45
+ context.http_response.headers['x-amzn-query-error']
46
+ end
47
+
39
48
  def error_message(code, json)
40
49
  if code == 'RequestEntityTooLarge'
41
50
  'Request body must be less than 1 MB'
@@ -146,6 +146,13 @@ module Aws
146
146
  data.to_h
147
147
  end
148
148
 
149
+ def as_json(_options = {})
150
+ data.to_h(data, as_json: true)
151
+ end
152
+
153
+ def to_json(options = {})
154
+ as_json.to_json(options)
155
+ end
149
156
  end
150
157
 
151
158
  # The actual decorator module implementation. It is in a distinct module
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ # @api private
5
+ module Plugins
6
+ # @api private
7
+ class BearerAuthorization < Seahorse::Client::Plugin
8
+
9
+ option(:token_provider,
10
+ required: false,
11
+ doc_type: 'Aws::TokenProvider',
12
+ docstring: <<-DOCS
13
+ A Bearer Token Provider. This can be an instance of any one of the
14
+ following classes:
15
+
16
+ * `Aws::StaticTokenProvider` - Used for configuring static, non-refreshing
17
+ tokens.
18
+
19
+ * `Aws::SSOTokenProvider` - Used for loading tokens from AWS SSO using an
20
+ access token generated from `aws login`.
21
+
22
+ When `:token_provider` is not configured directly, the `Aws::TokenProviderChain`
23
+ will be used to search for tokens configured for your profile in shared configuration files.
24
+ DOCS
25
+ ) do |config|
26
+ if config.stub_responses
27
+ StaticTokenProvider.new('token')
28
+ else
29
+ TokenProviderChain.new(config).resolve
30
+ end
31
+ end
32
+
33
+
34
+ def add_handlers(handlers, cfg)
35
+ bearer_operations =
36
+ if cfg.api.metadata['signatureVersion'] == 'bearer'
37
+ # select operations where authtype is either not set or is bearer
38
+ cfg.api.operation_names.select do |o|
39
+ !cfg.api.operation(o)['authtype'] || cfg.api.operation(o)['authtype'] == 'bearer'
40
+ end
41
+ else # service is not bearer auth
42
+ # select only operations where authtype is explicitly bearer
43
+ cfg.api.operation_names.select do |o|
44
+ cfg.api.operation(o)['authtype'] == 'bearer'
45
+ end
46
+ end
47
+ handlers.add(Handler, step: :sign, operations: bearer_operations)
48
+ end
49
+
50
+ class Handler < Seahorse::Client::Handler
51
+ def call(context)
52
+ if context.http_request.endpoint.scheme != 'https'
53
+ raise ArgumentError, 'Unable to use bearer authorization on non https endpoint.'
54
+ end
55
+
56
+ token_provider = context.config.token_provider
57
+ if token_provider && token_provider.set?
58
+ context.http_request.headers['Authorization'] = "Bearer #{token_provider.token.token}"
59
+ else
60
+ raise Errors::MissingBearerTokenError
61
+ end
62
+ @handler.call(context)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -76,6 +76,30 @@ locations will be searched for credentials:
76
76
 
77
77
  option(:instance_profile_credentials_timeout, 1)
78
78
 
79
+ option(:token_provider,
80
+ required: false,
81
+ doc_type: 'Aws::TokenProvider',
82
+ docstring: <<-DOCS
83
+ A Bearer Token Provider. This can be an instance of any one of the
84
+ following classes:
85
+
86
+ * `Aws::StaticTokenProvider` - Used for configuring static, non-refreshing
87
+ tokens.
88
+
89
+ * `Aws::SSOTokenProvider` - Used for loading tokens from AWS SSO using an
90
+ access token generated from `aws login`.
91
+
92
+ When `:token_provider` is not configured directly, the `Aws::TokenProviderChain`
93
+ will be used to search for tokens configured for your profile in shared configuration files.
94
+ DOCS
95
+ ) do |config|
96
+ if config.stub_responses
97
+ StaticTokenProvider.new('token')
98
+ else
99
+ TokenProviderChain.new(config).resolve
100
+ end
101
+ end
102
+
79
103
  end
80
104
  end
81
105
  end