aws-sdk-core 3.165.0 → 3.201.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +462 -0
  3. data/VERSION +1 -1
  4. data/lib/aws-defaults/default_configuration.rb +4 -4
  5. data/lib/aws-sdk-core/binary/decode_handler.rb +3 -9
  6. data/lib/aws-sdk-core/binary/encode_handler.rb +1 -1
  7. data/lib/aws-sdk-core/binary/event_builder.rb +34 -37
  8. data/lib/aws-sdk-core/binary/event_stream_decoder.rb +1 -0
  9. data/lib/aws-sdk-core/binary/event_stream_encoder.rb +4 -3
  10. data/lib/aws-sdk-core/cbor/cbor_engine.rb +19 -0
  11. data/lib/aws-sdk-core/cbor/decoder.rb +310 -0
  12. data/lib/aws-sdk-core/cbor/encoder.rb +243 -0
  13. data/lib/aws-sdk-core/cbor.rb +106 -0
  14. data/lib/aws-sdk-core/client_stubs.rb +18 -14
  15. data/lib/aws-sdk-core/credential_provider.rb +4 -1
  16. data/lib/aws-sdk-core/credential_provider_chain.rb +8 -5
  17. data/lib/aws-sdk-core/ec2_metadata.rb +1 -1
  18. data/lib/aws-sdk-core/ecs_credentials.rb +178 -53
  19. data/lib/aws-sdk-core/endpoints/condition.rb +5 -0
  20. data/lib/aws-sdk-core/endpoints/endpoint_rule.rb +5 -1
  21. data/lib/aws-sdk-core/endpoints/error_rule.rb +5 -0
  22. data/lib/aws-sdk-core/endpoints/function.rb +5 -0
  23. data/lib/aws-sdk-core/endpoints/matchers.rb +18 -10
  24. data/lib/aws-sdk-core/endpoints/reference.rb +5 -0
  25. data/lib/aws-sdk-core/endpoints/rule.rb +5 -0
  26. data/lib/aws-sdk-core/endpoints/rule_set.rb +5 -0
  27. data/lib/aws-sdk-core/endpoints/rules_provider.rb +5 -0
  28. data/lib/aws-sdk-core/endpoints/templater.rb +6 -0
  29. data/lib/aws-sdk-core/endpoints/tree_rule.rb +5 -0
  30. data/lib/aws-sdk-core/endpoints/url.rb +1 -0
  31. data/lib/aws-sdk-core/endpoints.rb +69 -19
  32. data/lib/aws-sdk-core/error_handler.rb +41 -0
  33. data/lib/aws-sdk-core/errors.rb +12 -3
  34. data/lib/aws-sdk-core/event_emitter.rb +0 -16
  35. data/lib/aws-sdk-core/ini_parser.rb +7 -0
  36. data/lib/aws-sdk-core/instance_profile_credentials.rb +55 -32
  37. data/lib/aws-sdk-core/json/builder.rb +8 -1
  38. data/lib/aws-sdk-core/json/error_handler.rb +29 -14
  39. data/lib/aws-sdk-core/json/handler.rb +12 -6
  40. data/lib/aws-sdk-core/json/json_engine.rb +3 -1
  41. data/lib/aws-sdk-core/json/oj_engine.rb +7 -1
  42. data/lib/aws-sdk-core/json/parser.rb +33 -3
  43. data/lib/aws-sdk-core/json.rb +43 -14
  44. data/lib/aws-sdk-core/log/formatter.rb +6 -0
  45. data/lib/aws-sdk-core/lru_cache.rb +75 -0
  46. data/lib/aws-sdk-core/pageable_response.rb +3 -1
  47. data/lib/aws-sdk-core/param_validator.rb +9 -4
  48. data/lib/aws-sdk-core/plugins/bearer_authorization.rb +2 -0
  49. data/lib/aws-sdk-core/plugins/checksum_algorithm.rb +7 -4
  50. data/lib/aws-sdk-core/plugins/client_metrics_plugin.rb +1 -0
  51. data/lib/aws-sdk-core/plugins/client_metrics_send_plugin.rb +14 -2
  52. data/lib/aws-sdk-core/plugins/credentials_configuration.rb +2 -0
  53. data/lib/aws-sdk-core/plugins/global_configuration.rb +8 -9
  54. data/lib/aws-sdk-core/plugins/http_checksum.rb +2 -1
  55. data/lib/aws-sdk-core/plugins/invocation_id.rb +1 -11
  56. data/lib/aws-sdk-core/plugins/logging.rb +2 -0
  57. data/lib/aws-sdk-core/plugins/protocols/api_gateway.rb +3 -1
  58. data/lib/aws-sdk-core/plugins/protocols/ec2.rb +2 -24
  59. data/lib/aws-sdk-core/plugins/protocols/json_rpc.rb +6 -8
  60. data/lib/aws-sdk-core/plugins/protocols/query.rb +4 -2
  61. data/lib/aws-sdk-core/plugins/protocols/rest_json.rb +3 -15
  62. data/lib/aws-sdk-core/plugins/protocols/rest_xml.rb +3 -0
  63. data/lib/aws-sdk-core/plugins/protocols/rpc_v2.rb +17 -0
  64. data/lib/aws-sdk-core/plugins/regional_endpoint.rb +140 -35
  65. data/lib/aws-sdk-core/plugins/request_compression.rb +226 -0
  66. data/lib/aws-sdk-core/plugins/retries/error_inspector.rb +2 -1
  67. data/lib/aws-sdk-core/plugins/retry_errors.rb +12 -3
  68. data/lib/aws-sdk-core/plugins/sign.rb +43 -19
  69. data/lib/aws-sdk-core/plugins/signature_v2.rb +2 -1
  70. data/lib/aws-sdk-core/plugins/signature_v4.rb +2 -1
  71. data/lib/aws-sdk-core/plugins/stub_responses.rb +1 -0
  72. data/lib/aws-sdk-core/plugins/transfer_encoding.rb +16 -9
  73. data/lib/aws-sdk-core/plugins/user_agent.rb +152 -14
  74. data/lib/aws-sdk-core/process_credentials.rb +45 -27
  75. data/lib/aws-sdk-core/query/ec2_handler.rb +27 -0
  76. data/lib/aws-sdk-core/query/ec2_param_builder.rb +5 -7
  77. data/lib/aws-sdk-core/query/handler.rb +4 -4
  78. data/lib/aws-sdk-core/query/param_builder.rb +2 -2
  79. data/lib/aws-sdk-core/query.rb +2 -1
  80. data/lib/aws-sdk-core/refreshing_credentials.rb +12 -12
  81. data/lib/aws-sdk-core/rest/content_type_handler.rb +60 -0
  82. data/lib/aws-sdk-core/rest/handler.rb +3 -4
  83. data/lib/aws-sdk-core/rest/request/body.rb +32 -5
  84. data/lib/aws-sdk-core/rest/request/endpoint.rb +24 -4
  85. data/lib/aws-sdk-core/rest/request/headers.rb +15 -7
  86. data/lib/aws-sdk-core/rest/request/querystring_builder.rb +62 -36
  87. data/lib/aws-sdk-core/rest/response/body.rb +15 -1
  88. data/lib/aws-sdk-core/rest/response/header_list_parser.rb +79 -0
  89. data/lib/aws-sdk-core/rest/response/headers.rb +8 -3
  90. data/lib/aws-sdk-core/rest.rb +1 -0
  91. data/lib/aws-sdk-core/rpc_v2/builder.rb +62 -0
  92. data/lib/aws-sdk-core/rpc_v2/content_type_handler.rb +45 -0
  93. data/lib/aws-sdk-core/rpc_v2/error_handler.rb +84 -0
  94. data/lib/aws-sdk-core/rpc_v2/handler.rb +74 -0
  95. data/lib/aws-sdk-core/rpc_v2/parser.rb +90 -0
  96. data/lib/aws-sdk-core/rpc_v2.rb +6 -0
  97. data/lib/aws-sdk-core/shared_config.rb +77 -18
  98. data/lib/aws-sdk-core/sso_credentials.rb +80 -45
  99. data/lib/aws-sdk-core/sso_token_provider.rb +3 -2
  100. data/lib/aws-sdk-core/stubbing/protocols/rpc_v2.rb +41 -0
  101. data/lib/aws-sdk-core/stubbing/stub_data.rb +11 -0
  102. data/lib/aws-sdk-core/util.rb +39 -0
  103. data/lib/aws-sdk-core/waiters/poller.rb +4 -2
  104. data/lib/aws-sdk-core/xml/builder.rb +17 -9
  105. data/lib/aws-sdk-core/xml/error_handler.rb +32 -42
  106. data/lib/aws-sdk-core/xml/parser/frame.rb +4 -20
  107. data/lib/aws-sdk-core/xml/parser/{engines/oga.rb → oga_engine.rb} +2 -0
  108. data/lib/aws-sdk-core/xml/parser/stack.rb +2 -0
  109. data/lib/aws-sdk-core/xml/parser.rb +2 -6
  110. data/lib/aws-sdk-core.rb +8 -2
  111. data/lib/aws-sdk-sso/client.rb +103 -46
  112. data/lib/aws-sdk-sso/client_api.rb +6 -0
  113. data/lib/aws-sdk-sso/endpoint_provider.rb +41 -96
  114. data/lib/aws-sdk-sso/endpoints.rb +1 -0
  115. data/lib/aws-sdk-sso/plugins/endpoints.rb +4 -2
  116. data/lib/aws-sdk-sso/types.rb +0 -35
  117. data/lib/aws-sdk-sso.rb +1 -1
  118. data/lib/aws-sdk-ssooidc/client.rb +488 -74
  119. data/lib/aws-sdk-ssooidc/client_api.rb +82 -1
  120. data/lib/aws-sdk-ssooidc/endpoint_provider.rb +41 -95
  121. data/lib/aws-sdk-ssooidc/endpoints.rb +15 -0
  122. data/lib/aws-sdk-ssooidc/errors.rb +52 -0
  123. data/lib/aws-sdk-ssooidc/plugins/endpoints.rb +6 -2
  124. data/lib/aws-sdk-ssooidc/types.rb +372 -83
  125. data/lib/aws-sdk-ssooidc.rb +1 -1
  126. data/lib/aws-sdk-sts/client.rb +361 -288
  127. data/lib/aws-sdk-sts/client_api.rb +24 -11
  128. data/lib/aws-sdk-sts/endpoint_provider.rb +96 -213
  129. data/lib/aws-sdk-sts/endpoints.rb +1 -0
  130. data/lib/aws-sdk-sts/plugins/endpoints.rb +4 -2
  131. data/lib/aws-sdk-sts/presigner.rb +1 -1
  132. data/lib/aws-sdk-sts/types.rb +128 -197
  133. data/lib/aws-sdk-sts.rb +1 -1
  134. data/lib/seahorse/client/async_base.rb +1 -1
  135. data/lib/seahorse/client/async_response.rb +19 -0
  136. data/lib/seahorse/client/base.rb +18 -7
  137. data/lib/seahorse/client/configuration.rb +0 -4
  138. data/lib/seahorse/client/h2/connection.rb +12 -11
  139. data/lib/seahorse/client/h2/handler.rb +1 -0
  140. data/lib/seahorse/client/handler.rb +1 -1
  141. data/lib/seahorse/client/net_http/connection_pool.rb +3 -9
  142. data/lib/seahorse/client/net_http/patches.rb +1 -4
  143. data/lib/seahorse/client/plugin.rb +9 -0
  144. data/lib/seahorse/client/plugins/endpoint.rb +0 -1
  145. data/lib/seahorse/client/plugins/h2.rb +3 -3
  146. data/lib/seahorse/client/plugins/net_http.rb +48 -16
  147. data/lib/seahorse/client/plugins/request_callback.rb +31 -0
  148. data/lib/seahorse/client/response.rb +6 -0
  149. data/lib/seahorse/model/operation.rb +3 -0
  150. data/lib/seahorse/model/shapes.rb +2 -2
  151. data/sig/aws-sdk-core/client_stubs.rbs +10 -0
  152. data/sig/aws-sdk-core/errors.rbs +22 -0
  153. data/sig/aws-sdk-core/resources/collection.rbs +21 -0
  154. data/sig/aws-sdk-core/structure.rbs +4 -0
  155. data/sig/aws-sdk-core/waiters/errors.rbs +20 -0
  156. data/sig/aws-sdk-core.rbs +7 -0
  157. data/sig/seahorse/client/base.rbs +25 -0
  158. data/sig/seahorse/client/handler_builder.rbs +16 -0
  159. data/sig/seahorse/client/response.rbs +61 -0
  160. metadata +44 -17
  161. /data/lib/aws-sdk-core/xml/parser/{engines/libxml.rb → libxml_engine.rb} +0 -0
  162. /data/lib/aws-sdk-core/xml/parser/{engines/nokogiri.rb → nokogiri_engine.rb} +0 -0
  163. /data/lib/aws-sdk-core/xml/parser/{engines/ox.rb → ox_engine.rb} +0 -0
  164. /data/lib/aws-sdk-core/xml/parser/{engines/rexml.rb → rexml_engine.rb} +0 -0
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+
5
+ module Aws
6
+ module RpcV2
7
+ class Parser
8
+ include Seahorse::Model::Shapes
9
+
10
+ # @param [Seahorse::Model::ShapeRef] rules
11
+ def initialize(rules, query_compatible: false)
12
+ @rules = rules
13
+ @query_compatible = query_compatible
14
+ end
15
+
16
+ def parse(cbor, target = nil)
17
+ return {} if cbor.empty?
18
+
19
+ parse_ref(@rules, Cbor.decode(cbor), target)
20
+ end
21
+
22
+ private
23
+
24
+ def structure(ref, values, target = nil)
25
+ shape = ref.shape
26
+ target = ref.shape.struct_class.new if target.nil?
27
+ values.each do |key, value|
28
+ member_name, member_ref = shape.member_by_location_name(key)
29
+ if member_ref
30
+ target[member_name] = parse_ref(member_ref, value)
31
+ elsif shape.union && key != '__type'
32
+ target[:unknown] = { 'name' => key, 'value' => value }
33
+ end
34
+ end
35
+ # In services that were previously Query/XML, members that were
36
+ # "flattened" defaulted to empty lists. In JSON, these values are nil,
37
+ # which is backwards incompatible. To preserve backwards compatibility,
38
+ # we set a default value of [] for these members.
39
+ if @query_compatible
40
+ ref.shape.members.each do |member_name, member_target|
41
+ next unless target[member_name].nil?
42
+
43
+ if flattened_list?(member_target.shape)
44
+ target[member_name] = []
45
+ elsif flattened_map?(member_target.shape)
46
+ target[member_name] = {}
47
+ end
48
+ end
49
+ end
50
+
51
+ if shape.union
52
+ # convert to subclass
53
+ member_subclass = shape.member_subclass(target.member).new
54
+ member_subclass[target.member] = target.value
55
+ target = member_subclass
56
+ end
57
+ target
58
+ end
59
+
60
+ def list(ref, values, target = nil)
61
+ target = [] if target.nil?
62
+ values.each do |value|
63
+ target << parse_ref(ref.shape.member, value)
64
+ end
65
+ target
66
+ end
67
+
68
+ def map(ref, values, target = nil)
69
+ target = {} if target.nil?
70
+ values.each do |key, value|
71
+ target[key] = parse_ref(ref.shape.value, value) unless value.nil?
72
+ end
73
+ target
74
+ end
75
+
76
+ def parse_ref(ref, value, target = nil)
77
+ if value.nil?
78
+ nil
79
+ else
80
+ case ref.shape
81
+ when StructureShape then structure(ref, value, target)
82
+ when ListShape then list(ref, value, target)
83
+ when MapShape then map(ref, value, target)
84
+ else value
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,6 @@
1
+ require_relative 'cbor'
2
+ require_relative 'rpc_v2/handler'
3
+ require_relative 'rpc_v2/content_type_handler'
4
+ require_relative 'rpc_v2/error_handler'
5
+ require_relative 'rpc_v2/builder'
6
+ require_relative 'rpc_v2/parser'
@@ -3,9 +3,10 @@
3
3
  module Aws
4
4
  # @api private
5
5
  class SharedConfig
6
- SSO_PROFILE_KEYS = %w[sso_start_url sso_region sso_account_id sso_role_name].freeze
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]
@@ -166,6 +167,26 @@ module Aws
166
167
  token
167
168
  end
168
169
 
170
+ # Source a custom configured endpoint from the shared configuration file
171
+ #
172
+ # @param [Hash] opts
173
+ # @option opts [String] :profile
174
+ # @option opts [String] :service_id
175
+ def configured_endpoint(opts = {})
176
+ # services section is only allowed in the shared config file (not credentials)
177
+ profile = opts[:profile] || @profile_name
178
+ service_id = opts[:service_id]&.gsub(" ", "_")&.downcase
179
+ if @parsed_config && (prof_config = @parsed_config[profile])
180
+ services_section_name = prof_config['services']
181
+ if (services_config = @parsed_config["services #{services_section_name}"]) &&
182
+ (service_config = services_config[service_id])
183
+ return service_config['endpoint_url'] if service_config['endpoint_url']
184
+ end
185
+ return prof_config['endpoint_url']
186
+ end
187
+ nil
188
+ end
189
+
169
190
  # Add an accessor method (similar to attr_reader) to return a configuration value
170
191
  # Uses the get_config_value below to control where
171
192
  # values are loaded from
@@ -177,6 +198,7 @@ module Aws
177
198
 
178
199
  config_reader(
179
200
  :region,
201
+ :sigv4a_signing_region_set,
180
202
  :ca_bundle,
181
203
  :credential_process,
182
204
  :endpoint_discovery_enabled,
@@ -184,6 +206,7 @@ module Aws
184
206
  :use_fips_endpoint,
185
207
  :ec2_metadata_service_endpoint,
186
208
  :ec2_metadata_service_endpoint_mode,
209
+ :ec2_metadata_v1_disabled,
187
210
  :max_attempts,
188
211
  :retry_mode,
189
212
  :adaptive_retry_wait_to_fill,
@@ -196,7 +219,12 @@ module Aws
196
219
  :s3_use_arn_region,
197
220
  :s3_us_east_1_regional_endpoint,
198
221
  :s3_disable_multiregion_access_points,
199
- :defaults_mode
222
+ :s3_disable_express_session_auth,
223
+ :defaults_mode,
224
+ :sdk_ua_app_id,
225
+ :disable_request_compression,
226
+ :request_min_compression_size_bytes,
227
+ :ignore_configured_endpoint_urls
200
228
  )
201
229
 
202
230
  private
@@ -331,14 +359,37 @@ module Aws
331
359
  def sso_credentials_from_profile(cfg, profile)
332
360
  if @parsed_config &&
333
361
  (prof_config = cfg[profile]) &&
334
- !(prof_config.keys & SSO_PROFILE_KEYS).empty?
362
+ !(prof_config.keys & SSO_CREDENTIAL_PROFILE_KEYS).empty?
363
+
364
+ if sso_session_name = prof_config['sso_session']
365
+ sso_session = sso_session(cfg, profile, sso_session_name)
366
+
367
+ sso_region = sso_session['sso_region']
368
+ sso_start_url = sso_session['sso_start_url']
369
+
370
+ # validate sso_region and sso_start_url don't conflict if set on profile and session
371
+ if prof_config['sso_region'] && prof_config['sso_region'] != sso_region
372
+ raise ArgumentError,
373
+ "sso-session #{sso_session_name}'s sso_region (#{sso_region}) " \
374
+ "does not match the profile #{profile}'s sso_region (#{prof_config['sso_region']}'"
375
+ end
376
+ if prof_config['sso_start_url'] && prof_config['sso_start_url'] != sso_start_url
377
+ raise ArgumentError,
378
+ "sso-session #{sso_session_name}'s sso_start_url (#{sso_start_url}) " \
379
+ "does not match the profile #{profile}'s sso_start_url (#{prof_config['sso_start_url']}'"
380
+ end
381
+ else
382
+ sso_region = prof_config['sso_region']
383
+ sso_start_url = prof_config['sso_start_url']
384
+ end
335
385
 
336
386
  SSOCredentials.new(
337
- sso_start_url: prof_config['sso_start_url'],
338
- sso_region: prof_config['sso_region'],
339
387
  sso_account_id: prof_config['sso_account_id'],
340
- sso_role_name: prof_config['sso_role_name']
341
- )
388
+ sso_role_name: prof_config['sso_role_name'],
389
+ sso_session: prof_config['sso_session'],
390
+ sso_region: sso_region,
391
+ sso_start_url: sso_start_url
392
+ )
342
393
  end
343
394
  end
344
395
 
@@ -350,16 +401,7 @@ module Aws
350
401
  !(prof_config.keys & SSO_TOKEN_PROFILE_KEYS).empty?
351
402
 
352
403
  sso_session_name = prof_config['sso_session']
353
- sso_session = cfg["sso-session #{sso_session_name}"]
354
- unless sso_session
355
- raise ArgumentError,
356
- "sso-session #{sso_session_name} must be defined in the config file." /
357
- "Referenced by profile #{profile}"
358
- end
359
-
360
- unless sso_session['sso_region']
361
- raise ArgumentError, "sso-session #{sso_session_name} missing required parameter: sso_region"
362
- end
404
+ sso_session = sso_session(cfg, profile, sso_session_name)
363
405
 
364
406
  SSOTokenProvider.new(
365
407
  sso_session: sso_session_name,
@@ -417,5 +459,22 @@ module Aws
417
459
  ret ||= 'default'
418
460
  ret
419
461
  end
462
+
463
+ def sso_session(cfg, profile, sso_session_name)
464
+ # aws sso-configure may add quotes around sso session names with whitespace
465
+ sso_session = cfg["sso-session #{sso_session_name}"] || cfg["sso-session '#{sso_session_name}'"]
466
+
467
+ unless sso_session
468
+ raise ArgumentError,
469
+ "sso-session #{sso_session_name} must be defined in the config file. " \
470
+ "Referenced by profile #{profile}"
471
+ end
472
+
473
+ unless sso_session['sso_region']
474
+ raise ArgumentError, "sso-session #{sso_session_name} missing required parameter: sso_region"
475
+ end
476
+
477
+ sso_session
478
+ end
420
479
  end
421
480
  end
@@ -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. This class does NOT implement the SSO login token flow - tokens
7
- # must generated and refreshed separately by running `aws login` from the
8
- # AWS CLI with the correct profile.
9
- #
10
- # The `SSOCredentials` will auto-refresh the AWS credentials from SSO. In
11
- # addition to AWS credentials expiring after a given amount of time, the
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
- # sso_start_url: 'https://your-start-url.awsapps.com/start'
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
- SSO_REQUIRED_OPTS = [:sso_account_id, :sso_region, :sso_role_name, :sso_start_url].freeze
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] :sso_start_url The start URL is
56
- # provided by the SSO service via the console and is the URL used to
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
- missing_keys = SSO_REQUIRED_OPTS.select { |k| options[k].nil? }
70
- unless missing_keys.empty?
71
- raise ArgumentError, "Missing required keys: #{missing_keys}"
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,19 +138,27 @@ module Aws
111
138
  end
112
139
 
113
140
  def refresh
114
- cached_token = read_cached_token
115
- c = @client.get_role_credentials(
116
- account_id: @sso_account_id,
117
- role_name: @sso_role_name,
118
- access_token: cached_token['accessToken']
119
- ).role_credentials
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,
123
158
  c.secret_access_key,
124
159
  c.session_token
125
160
  )
126
- @expiration = c.expiration
161
+ @expiration = Time.at(c.expiration / 1000.0)
127
162
  end
128
163
 
129
164
  def sso_cache_file
@@ -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 [SSO::Client]
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['client_secret'],
70
+ client_secret: token_json['clientSecret'],
70
71
  refresh_token: token_json['refreshToken']
71
72
  )
72
73
  token_json['accessToken'] = resp.access_token
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Stubbing
5
+ module Protocols
6
+ class RpcV2
7
+
8
+ def stub_data(api, operation, data)
9
+ resp = Seahorse::Client::Http::Response.new
10
+ resp.status_code = 200
11
+ resp.headers['Content-Type'] = content_type(api)
12
+ resp.headers['x-amzn-RequestId'] = 'stubbed-request-id'
13
+ resp.body = build_body(operation, data)
14
+ resp
15
+ end
16
+
17
+ def stub_error(error_code)
18
+ http_resp = Seahorse::Client::Http::Response.new
19
+ http_resp.status_code = 400
20
+ http_resp.body = <<-JSON.strip
21
+ {
22
+ "code": #{error_code.inspect},
23
+ "message": "stubbed-response-error-message"
24
+ }
25
+ JSON
26
+ http_resp
27
+ end
28
+
29
+ private
30
+
31
+ def content_type(api)
32
+ 'application/cbor'
33
+ end
34
+
35
+ def build_body(operation, data)
36
+ Aws::RpcV2::Builder.new(operation.output).serialize(data)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -13,12 +13,23 @@ module Aws
13
13
  def stub(data = {})
14
14
  stub = EmptyStub.new(@rules).stub
15
15
  remove_paging_tokens(stub)
16
+ remove_checksums(stub)
16
17
  apply_data(data, stub)
17
18
  stub
18
19
  end
19
20
 
20
21
  private
21
22
 
23
+ def remove_checksums(stub)
24
+ if @rules && @rules.shape.is_a?(Seahorse::Model::Shapes::StructureShape)
25
+ @rules.shape.members.each do |key, member|
26
+ if member.location == 'header' && member.location_name.start_with?('x-amz-checksum-')
27
+ stub[key] = nil
28
+ end
29
+ end
30
+ end
31
+ end
32
+
22
33
  def remove_paging_tokens(stub)
23
34
  if @pager
24
35
  @pager.instance_variable_get("@tokens").keys.each do |path|
@@ -67,6 +67,45 @@ module Aws
67
67
  end
68
68
  end
69
69
 
70
+ # @param [Number] input
71
+ # @return [Number, String] The serialized number
72
+ def serialize_number(input)
73
+ if input == ::Float::INFINITY then 'Infinity'
74
+ elsif input == -::Float::INFINITY then '-Infinity'
75
+ elsif input&.nan? then 'NaN'
76
+ else
77
+ input
78
+ end
79
+ end
80
+
81
+ # @param [String] str
82
+ # @return [Number] The input as a number
83
+ def deserialize_number(str)
84
+ case str
85
+ when 'Infinity' then ::Float::INFINITY
86
+ when '-Infinity' then -::Float::INFINITY
87
+ when 'NaN' then ::Float::NAN
88
+ when nil then nil
89
+ else str.to_f
90
+ end
91
+ end
92
+
93
+ # @param [String] value
94
+ # @return [Time]
95
+ def deserialize_time(value)
96
+ case value
97
+ when nil then nil
98
+ when /^[\d.]+$/ then Time.at(value.to_f).utc
99
+ else
100
+ begin
101
+ fractional_time = Time.parse(value).to_f
102
+ Time.at(fractional_time).utc
103
+ rescue ArgumentError
104
+ raise "unhandled timestamp format `#{value}'"
105
+ end
106
+ end
107
+ end
108
+
70
109
  end
71
110
  end
72
111
  end
@@ -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
- req.send_request
65
+ Aws::Plugins::UserAgent.metric('WAITER') do
66
+ req.send_request
67
+ end
66
68
  end
67
69
 
68
70
  def acceptor_matches?(acceptor, response)
@@ -95,7 +97,7 @@ module Aws
95
97
 
96
98
  def matches_error?(acceptor, response)
97
99
  Aws::Errors::ServiceError === response.error &&
98
- response.error.code == acceptor['expected'].gsub('.', '')
100
+ response.error.code == acceptor['expected'].delete('.')
99
101
  end
100
102
 
101
103
  def path(acceptor)
@@ -10,6 +10,8 @@ module Aws
10
10
 
11
11
  def initialize(rules, options = {})
12
12
  @rules = rules
13
+ @location_name =
14
+ options[:location_name].nil? ? @rules.location_name : options[:location_name]
13
15
  @xml = options[:target] || []
14
16
  indent = options[:indent] || ''
15
17
  pad = options[:pad] || ''
@@ -17,7 +19,7 @@ module Aws
17
19
  end
18
20
 
19
21
  def to_xml(params)
20
- structure(@rules.location_name, @rules, params)
22
+ structure(@location_name, @rules, params)
21
23
  @xml.join
22
24
  end
23
25
  alias serialize to_xml
@@ -50,7 +52,7 @@ module Aws
50
52
  def list(name, ref, values)
51
53
  if ref[:flattened] || ref.shape.flattened
52
54
  values.each do |value|
53
- member(ref.shape.member.location_name || name, ref.shape.member, value)
55
+ member(name, ref.shape.member, value)
54
56
  end
55
57
  else
56
58
  node(name, ref) do
@@ -65,7 +67,7 @@ module Aws
65
67
  def map(name, ref, hash)
66
68
  key_ref = ref.shape.key
67
69
  value_ref = ref.shape.value
68
- if ref.shape.flattened
70
+ if ref[:flattened] || ref.shape.flattened
69
71
  hash.each do |key, value|
70
72
  node(name, ref) do
71
73
  member(key_ref.location_name || 'key', key_ref, key)
@@ -75,7 +77,8 @@ module Aws
75
77
  else
76
78
  node(name, ref) do
77
79
  hash.each do |key, value|
78
- node('entry', ref) do
80
+ # Pass in a new ShapeRef to create an entry node
81
+ node('entry', ShapeRef.new) do
79
82
  member(key_ref.location_name || 'key', key_ref, key)
80
83
  member(value_ref.location_name || 'value', value_ref, value)
81
84
  end
@@ -129,11 +132,16 @@ module Aws
129
132
  end
130
133
 
131
134
  def shape_attrs(ref)
132
- if xmlns = ref['xmlNamespace']
133
- if prefix = xmlns['prefix']
134
- { 'xmlns:' + prefix => xmlns['uri'] }
135
- else
136
- { 'xmlns' => xmlns['uri'] }
135
+ if (xmlns = ref['xmlNamespace'])
136
+ case xmlns
137
+ when String
138
+ { 'xmlns' => xmlns }
139
+ when Hash
140
+ if (prefix = xmlns['prefix'])
141
+ { "xmlns:#{prefix}" => xmlns['uri'] }
142
+ else
143
+ { 'xmlns' => xmlns['uri'] }
144
+ end
137
145
  end
138
146
  else
139
147
  {}