aws-sdk-core 3.131.3 → 3.139.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 841c00d0f15577e794600c6d510e131c28c5daceaf682ea8f037b672600d2ba1
4
- data.tar.gz: 8c1036761b99ae9d06809e8382a3abf7c018852616a26bfb907981550b960b9f
3
+ metadata.gz: 1113be75f15cd8a7409bc0a456ccc4060a7a6cc890ebb8d5221d0003049308bb
4
+ data.tar.gz: c5f900614121dad193065080cee328b5c91f0973682a382aeef52b419eba8b18
5
5
  SHA512:
6
- metadata.gz: 4fb0e66c9f849349f474881b161b81f5b07d6258998d741b12203a6814c79f029e70651c8da0aa364255e70ce89a1ed94a4e45376087e81ea4d37d391131138a
7
- data.tar.gz: 2ac018694538ba648287e3080ecd0e9bffcd350abc1f5a0a15f958a544b94d1f8d88ac245f20bd2708488b24e189137aeee40f8ae0e34b62c3be71cf197214ed
6
+ metadata.gz: 1aa1d47b5415a62e2fb0725ea1ffc7cce61cda483fdcfbf860bab7c267b98ad57000c09df6fd2d7bcc49ff244fece7eeda3da4952fcee8039913e2c730898964
7
+ data.tar.gz: 4ff12524ddf1110103e67724c10fb1313ca884b3ca26d3d4c380f15a104324a49ba83e49fd78a42cf13a06dc51f0442d55a656c17f4fef0124d8dfa4a2ab4d27
data/CHANGELOG.md CHANGED
@@ -1,10 +1,71 @@
1
1
  Unreleased Changes
2
2
  ------------------
3
3
 
4
+ 3.139.0 (2022-09-01)
5
+ ------------------
6
+
7
+ * Feature - Updated Aws::SSO::Client with the latest API changes.
8
+
9
+ 3.138.0 (2022-08-31)
10
+ ------------------
11
+
12
+ * Feature - Updated Aws::SSO::Client with the latest API changes.
13
+
14
+ 3.137.0 (2022-08-30)
15
+ ------------------
16
+
17
+ * Feature - Updated Aws::SSO::Client with the latest API changes.
18
+
19
+ * Issue - Fix errors in recursion detection when `_X_AMZN_TRACE_ID` is unset (#2748).
20
+
21
+ 3.136.0 (2022-08-25)
22
+ ------------------
23
+
24
+ * Feature - Updated Aws::SSO::Client with the latest API changes.
25
+
26
+ 3.135.0 (2022-08-24)
27
+ ------------------
28
+
29
+ * Feature - Updated Aws::SSO::Client with the latest API changes.
30
+
31
+ 3.134.0 (2022-08-23)
32
+ ------------------
33
+
34
+ * Feature - Updated Aws::SSO::Client with the latest API changes.
35
+
36
+ * Feature - Add support for Bearer Token Authentication and TokenProviders.
37
+ * Issue - Validate that `_X_AMZN_TRACE_ID` ENV value contains only valid, non-control characters.
38
+
39
+ 3.133.0 (2022-08-22)
40
+ ------------------
41
+
42
+ * Feature - Moved functionality from `aws-sdk-ssoidc` into core.
43
+
44
+ 3.132.0 (2022-08-08)
45
+ ------------------
46
+
47
+ * Feature - Updated Aws::SSO::Client with the latest API changes.
48
+
49
+ 3.131.6 (2022-08-03)
50
+ ------------------
51
+
52
+ * Issue - Fix typo in `RecursionDetection`, change amz to amzn in header and env name.
53
+
54
+ 3.131.5 (2022-07-28)
55
+ ------------------
56
+
57
+ * Issue - Fix `to_json` usage in nested hashes by defining `as_json` (#2733).
58
+
59
+ 3.131.4 (2022-07-27)
60
+ ------------------
61
+
62
+ * Issue - Fix `to_json` usage on pageable responses when using Rails (#2733).
63
+ * Issue - Use `expand_path` on credential/config paths in SharedConfig (#2735).
64
+
4
65
  3.131.3 (2022-07-18)
5
66
  ------------------
6
67
 
7
- * Issue - Add support for serializing shapes on the body with `jsonvalue` members.
68
+ * Issue - Add support for serializing shapes on the body with `jsonvalue` members.
8
69
 
9
70
  3.131.2 (2022-06-20)
10
71
  ------------------
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.131.3
1
+ 3.139.0
@@ -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
@@ -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
@@ -9,14 +9,25 @@ module Aws
9
9
  class Handler < Seahorse::Client::Handler
10
10
  def call(context)
11
11
 
12
- unless context.http_request.headers.key?('x-amz-trace-id')
12
+ unless context.http_request.headers.key?('x-amzn-trace-id')
13
13
  if ENV['AWS_LAMBDA_FUNCTION_NAME'] &&
14
- (trace_id = ENV['_X_AMZ_TRACE_ID'])
15
- context.http_request.headers['x-amz-trace-id'] = trace_id
14
+ (trace_id = validate_header(ENV['_X_AMZN_TRACE_ID']))
15
+ context.http_request.headers['x-amzn-trace-id'] = trace_id
16
16
  end
17
17
  end
18
18
  @handler.call(context)
19
19
  end
20
+
21
+ private
22
+ def validate_header(header_value)
23
+ return unless header_value
24
+
25
+ if (header_value.chars & (0..31).map(&:chr)).any?
26
+ raise ArgumentError, 'Invalid _X_AMZN_TRACE_ID value: '\
27
+ 'contains ASCII control characters'
28
+ end
29
+ header_value
30
+ end
20
31
  end
21
32
 
22
33
  # should be at the end of build so that
@@ -7,6 +7,8 @@ module Aws
7
7
  # @api private
8
8
  class SignatureV4 < Seahorse::Client::Plugin
9
9
 
10
+ V4_AUTH = %w[v4 v4-unsigned-payload v4-unsigned-body]
11
+
10
12
  option(:sigv4_signer) do |cfg|
11
13
  SignatureV4.build_signer(cfg)
12
14
  end
@@ -32,13 +34,16 @@ module Aws
32
34
  end
33
35
 
34
36
  option(:unsigned_operations) do |cfg|
35
- cfg.api.operation_names.inject([]) do |unsigned, operation_name|
36
- if cfg.api.operation(operation_name)['authtype'] == 'none' ||
37
- cfg.api.operation(operation_name)['authtype'] == 'custom'
38
- # Unsign requests that has custom apigateway authorizer as well
39
- unsigned << operation_name
40
- else
41
- unsigned
37
+ if cfg.api.metadata['signatureVersion'] == 'v4'
38
+ # select operations where authtype is set and is not v4
39
+ cfg.api.operation_names.select do |o|
40
+ cfg.api.operation(o)['authtype'] && !V4_AUTH.include?(cfg.api.operation(o)['authtype'])
41
+ end
42
+ else # service is not v4 auth
43
+ # select all operations where authtype is not v4
44
+ # (includes operations with no explicit authtype)
45
+ cfg.api.operation_names.select do |o|
46
+ !V4_AUTH.include?(cfg.api.operation(o)['authtype'])
42
47
  end
43
48
  end
44
49
  end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thread'
4
+
5
+ module Aws
6
+
7
+ # Module/mixin used by token provider classes that can be refreshed. This
8
+ # provides basic refresh logic in a thread-safe manner. Classes mixing in
9
+ # this module are expected to implement a #refresh method that populates
10
+ # the following instance variable:
11
+ #
12
+ # * `@token` [Token] - {Aws::Token} object with the `expiration` and `token`
13
+ # fields set.
14
+ #
15
+ # @api private
16
+ module RefreshingToken
17
+
18
+ def initialize(options = {})
19
+ @mutex = Mutex.new
20
+ @before_refresh = options.delete(:before_refresh) if Hash === options
21
+
22
+ @before_refresh.call(self) if @before_refresh
23
+ refresh
24
+ end
25
+
26
+ # @return [Token]
27
+ def token
28
+ refresh_if_near_expiration
29
+ @token
30
+ end
31
+
32
+ # @return [Time,nil]
33
+ def expiration
34
+ refresh_if_near_expiration
35
+ @expiration
36
+ end
37
+
38
+ # Refresh token.
39
+ # @return [void]
40
+ def refresh!
41
+ @mutex.synchronize do
42
+ @before_refresh.call(self) if @before_refresh
43
+ refresh
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ # Refreshes token if it is within
50
+ # 5 minutes of expiration.
51
+ def refresh_if_near_expiration
52
+ if near_expiration?
53
+ @mutex.synchronize do
54
+ if near_expiration?
55
+ @before_refresh.call(self) if @before_refresh
56
+ refresh
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ def near_expiration?
63
+ if @token && @token.expiration
64
+ # are we within 5 minutes of expiration?
65
+ (Time.now.to_i + 5 * 60) > @token.expiration.to_i
66
+ else
67
+ true
68
+ end
69
+ end
70
+ end
71
+ end
@@ -4,6 +4,9 @@ module Aws
4
4
  # @api private
5
5
  class SharedConfig
6
6
  SSO_PROFILE_KEYS = %w[sso_start_url sso_region sso_account_id sso_role_name].freeze
7
+ SSO_TOKEN_PROFILE_KEYS = %w[sso_session].freeze
8
+ SSO_SESSION_KEYS = %w[sso_region]
9
+
7
10
 
8
11
  # @return [String]
9
12
  attr_reader :credentials_path
@@ -51,10 +54,12 @@ module Aws
51
54
  @config_enabled = options[:config_enabled]
52
55
  @credentials_path = options[:credentials_path] ||
53
56
  determine_credentials_path
57
+ @credentials_path = File.expand_path(@credentials_path) if @credentials_path
54
58
  @parsed_credentials = {}
55
59
  load_credentials_file if loadable?(@credentials_path)
56
60
  if @config_enabled
57
61
  @config_path = options[:config_path] || determine_config_path
62
+ @config_path = File.expand_path(@config_path) if @config_path
58
63
  load_config_file if loadable?(@config_path)
59
64
  end
60
65
  end
@@ -149,6 +154,18 @@ module Aws
149
154
  credentials
150
155
  end
151
156
 
157
+ # Attempts to load from shared config or shared credentials file.
158
+ # Will always attempt first to load from the shared credentials
159
+ # file, if present.
160
+ def sso_token_from_config(opts = {})
161
+ p = opts[:profile] || @profile_name
162
+ token = sso_token_from_profile(@parsed_credentials, p)
163
+ if @parsed_config
164
+ token ||= sso_token_from_profile(@parsed_config, p)
165
+ end
166
+ token
167
+ end
168
+
152
169
  # Add an accessor method (similar to attr_reader) to return a configuration value
153
170
  # Uses the get_config_value below to control where
154
171
  # values are loaded from
@@ -325,6 +342,32 @@ module Aws
325
342
  end
326
343
  end
327
344
 
345
+ # If the required sso_ profile values are present, attempt to construct
346
+ # SSOTokenProvider
347
+ def sso_token_from_profile(cfg, profile)
348
+ if @parsed_config &&
349
+ (prof_config = cfg[profile]) &&
350
+ !(prof_config.keys & SSO_TOKEN_PROFILE_KEYS).empty?
351
+
352
+ 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
363
+
364
+ SSOTokenProvider.new(
365
+ sso_session: sso_session_name,
366
+ sso_region: sso_session['sso_region']
367
+ )
368
+ end
369
+ end
370
+
328
371
  def credentials_from_profile(prof_config)
329
372
  creds = Credentials.new(
330
373
  prof_config['aws_access_key_id'],
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ class SSOTokenProvider
5
+
6
+ include TokenProvider
7
+ include RefreshingToken
8
+
9
+ # @api private
10
+ SSO_REQUIRED_OPTS = [:sso_region, :sso_session].freeze
11
+
12
+ # @api private
13
+ SSO_LOGIN_GUIDANCE = 'The SSO session associated with this profile has '\
14
+ 'expired or is otherwise invalid. To refresh this SSO session run '\
15
+ 'aws sso login with the corresponding profile.'.freeze
16
+
17
+ # @option options [required, String] :sso_region The AWS region where the
18
+ # SSO directory for the given sso_start_url is hosted.
19
+ #
20
+ # @option options [required, String] :sso_session The SSO Session used to
21
+ # for fetching this token.
22
+ #
23
+ # @option options [SSOOIDC::Client] :client Optional `SSOOIDC::Client`. If not
24
+ # provided, a client will be constructed.
25
+ #
26
+ # @option options [Callable] before_refresh Proc called before
27
+ # credentials are refreshed. `before_refresh` is called
28
+ # with an instance of this object when
29
+ # AWS credentials are required and need to be refreshed.
30
+ def initialize(options = {})
31
+
32
+ missing_keys = SSO_REQUIRED_OPTS.select { |k| options[k].nil? }
33
+ unless missing_keys.empty?
34
+ raise ArgumentError, "Missing required keys: #{missing_keys}"
35
+ end
36
+
37
+ @sso_session = options.delete(:sso_session)
38
+ @sso_region = options.delete(:sso_region)
39
+
40
+ options[:region] = @sso_region
41
+ options[:credentials] = nil
42
+ @client = options[:client] || Aws::SSOOIDC::Client.new(options)
43
+
44
+ super
45
+ end
46
+
47
+ # @return [SSO::Client]
48
+ attr_reader :client
49
+
50
+ private
51
+
52
+ def refresh
53
+ # token is valid and not in refresh window - do not refresh it.
54
+ return if @token && @token.expiration && !near_expiration?
55
+
56
+ # token may not exist or is out of the expiration window
57
+ # attempt to refresh from disk first (another process/application may have refreshed already)
58
+ token_json = read_cached_token
59
+ @token = Token.new(token_json['accessToken'], token_json['expiresAt'])
60
+ return if @token && @token.expiration && !near_expiration?
61
+
62
+ # The token is expired and needs to be refreshed
63
+ if can_refresh_token?(token_json)
64
+ begin
65
+ current_time = Time.now
66
+ resp = @client.create_token(
67
+ grant_type: 'refresh_token',
68
+ client_id: token_json['clientId'],
69
+ client_secret: token_json['client_secret'],
70
+ refresh_token: token_json['refreshToken']
71
+ )
72
+ token_json['accessToken'] = resp.access_token
73
+ token_json['expiresAt'] = current_time + resp.expires_in
74
+ @token = Token.new(token_json['accessToken'], token_json['expiresAt'])
75
+
76
+ if resp.refresh_token
77
+ token_json['refreshToken'] = resp.refresh_token
78
+ else
79
+ token_json.delete('refreshToken')
80
+ end
81
+
82
+ update_token_cache(token_json)
83
+ rescue
84
+ # refresh has failed, continue attempting to use the token if its not hard expired
85
+ end
86
+ end
87
+
88
+ if !@token.expiration || @token.expiration < Time.now
89
+ # Token is hard expired, raise an exception
90
+ raise Errors::InvalidSSOToken, 'Token is invalid and failed to refresh.'
91
+ end
92
+ end
93
+
94
+ def read_cached_token
95
+ cached_token = Json.load(File.read(sso_cache_file))
96
+ # validation
97
+ unless cached_token['accessToken'] && cached_token['expiresAt']
98
+ raise ArgumentError, 'Missing required field(s)'
99
+ end
100
+ cached_token['expiresAt'] = Time.parse(cached_token['expiresAt'])
101
+ cached_token
102
+ rescue Errno::ENOENT, Aws::Json::ParseError, ArgumentError
103
+ raise Errors::InvalidSSOToken, SSO_LOGIN_GUIDANCE
104
+ end
105
+
106
+ def update_token_cache(token_json)
107
+ cached_token = token_json.dup
108
+ cached_token['expiresAt'] = cached_token['expiresAt'].iso8601
109
+ File.write(sso_cache_file, Json.dump(cached_token))
110
+ end
111
+
112
+ def sso_cache_file
113
+ sso_session_sha1 = OpenSSL::Digest::SHA1.hexdigest(@sso_session.encode('utf-8'))
114
+ File.join(Dir.home, '.aws', 'sso', 'cache', "#{sso_session_sha1}.json")
115
+ rescue ArgumentError
116
+ # Dir.home raises ArgumentError when ENV['home'] is not set
117
+ raise ArgumentError, "Unable to load sso_cache_file: ENV['HOME'] is not set."
118
+ end
119
+
120
+ # return true if all required fields are present
121
+ # return false if registrationExpiresAt exists and is later than now
122
+ def can_refresh_token?(token_json)
123
+ if token_json['clientId'] &&
124
+ token_json['clientSecret'] &&
125
+ token_json['refreshToken']
126
+
127
+ return !token_json['registrationExpiresAt'] ||
128
+ Time.parse(token_json['registrationExpiresAt']) > Time.now
129
+ else
130
+ false
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ class StaticTokenProvider
5
+
6
+ include TokenProvider
7
+
8
+ # @param [String] token
9
+ # @param [Time] expiration
10
+ def initialize(token, expiration=nil)
11
+ @token = Token.new(token, expiration)
12
+ end
13
+ end
14
+ end
@@ -28,18 +28,20 @@ module Aws
28
28
  # in stdlib Struct.
29
29
  #
30
30
  # @return [Hash]
31
- def to_h(obj = self)
31
+ def to_h(obj = self, options = {})
32
32
  case obj
33
33
  when Struct
34
34
  obj.each_pair.with_object({}) do |(member, value), hash|
35
- hash[member] = to_hash(value) unless value.nil?
35
+ member = member.to_s if options[:as_json]
36
+ hash[member] = to_hash(value, options) unless value.nil?
36
37
  end
37
38
  when Hash
38
39
  obj.each.with_object({}) do |(key, value), hash|
39
- hash[key] = to_hash(value)
40
+ key = key.to_s if options[:as_json]
41
+ hash[key] = to_hash(value, options)
40
42
  end
41
43
  when Array
42
- obj.collect { |value| to_hash(value) }
44
+ obj.collect { |value| to_hash(value, options) }
43
45
  else
44
46
  obj
45
47
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ class Token
5
+
6
+ # @param [String] token
7
+ # @param [Time] expiration
8
+ def initialize(token, expiration=nil)
9
+ @token = token
10
+ @expiration = expiration
11
+ end
12
+
13
+ # @return [String, nil]
14
+ attr_reader :token
15
+
16
+ # @return [Time, nil]
17
+ attr_reader :expiration
18
+
19
+ # @return [Boolean] Returns `true` if token is set
20
+ def set?
21
+ !token.nil? && !token.empty?
22
+ end
23
+
24
+ # Removing the token from the default inspect string.
25
+ # @api private
26
+ def inspect
27
+ "#<#{self.class.name} token=[FILTERED]> expiration=#{expiration}>"
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module TokenProvider
5
+
6
+ # @return [Token]
7
+ attr_reader :token
8
+
9
+ # @return [Boolean]
10
+ def set?
11
+ !!token && token.set?
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ # @api private
5
+ class TokenProviderChain
6
+ def initialize(config = nil)
7
+ @config = config
8
+ end
9
+
10
+ # @return [TokenProvider, nil]
11
+ def resolve
12
+ providers.each do |method_name, options|
13
+ provider = send(method_name, options.merge(config: @config))
14
+ return provider if provider && provider.set?
15
+ end
16
+ nil
17
+ end
18
+
19
+ private
20
+
21
+ def providers
22
+ [
23
+ [:static_profile_sso_token, {}],
24
+ [:sso_token, {}]
25
+ ]
26
+ end
27
+
28
+ def static_profile_sso_token(options)
29
+ if Aws.shared_config.config_enabled? && options[:config] && options[:config].profile
30
+ Aws.shared_config.sso_token_from_config(
31
+ profile: options[:config].profile
32
+ )
33
+ end
34
+ end
35
+
36
+
37
+ def sso_token(options)
38
+ profile_name = determine_profile_name(options)
39
+ if Aws.shared_config.config_enabled?
40
+ Aws.shared_config.sso_token_from_config(profile: profile_name)
41
+ end
42
+ rescue Errors::NoSuchProfileError
43
+ nil
44
+ end
45
+
46
+ def determine_profile_name(options)
47
+ (options[:config] && options[:config].profile) || ENV['AWS_PROFILE'] || ENV['AWS_DEFAULT_PROFILE'] || 'default'
48
+ end
49
+
50
+ end
51
+ end