aws-sdk-core 3.131.0 → 3.158.1

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.
@@ -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
@@ -24,6 +24,7 @@ module Aws
24
24
  else
25
25
  code, message, data = extract_error(body, context)
26
26
  end
27
+ context[:request_id] = request_id(body)
27
28
  errors_module = context.client.class.errors_module
28
29
  error_class = errors_module.error_class(code).new(context, message, data)
29
30
  error_class
@@ -94,6 +95,12 @@ module Aws
94
95
  end
95
96
  end
96
97
 
98
+ def request_id(body)
99
+ if matches = body.match(/<RequestId>(.+?)<\/RequestId>/m)
100
+ matches[1]
101
+ end
102
+ end
103
+
97
104
  def unescape(str)
98
105
  CGI.unescapeHTML(str)
99
106
  end
data/lib/aws-sdk-core.rb CHANGED
@@ -20,6 +20,15 @@ require_relative 'aws-sdk-core/shared_credentials'
20
20
  require_relative 'aws-sdk-core/process_credentials'
21
21
  require_relative 'aws-sdk-core/sso_credentials'
22
22
 
23
+ # tokens and token providers
24
+ require_relative 'aws-sdk-core/token'
25
+ require_relative 'aws-sdk-core/token_provider'
26
+ require_relative 'aws-sdk-core/static_token_provider'
27
+ require_relative 'aws-sdk-core/refreshing_token'
28
+ require_relative 'aws-sdk-core/sso_token_provider'
29
+ require_relative 'aws-sdk-core/token_provider_chain'
30
+ require_relative 'aws-sdk-core/plugins/bearer_authorization'
31
+
23
32
  # client modules
24
33
 
25
34
  require_relative 'aws-sdk-core/client_stubs'
@@ -99,6 +108,7 @@ require_relative 'aws-sdk-sts'
99
108
 
100
109
  # aws-sdk-sso is included to support Aws::SSOCredentials
101
110
  require_relative 'aws-sdk-sso'
111
+ require_relative 'aws-sdk-ssooidc'
102
112
 
103
113
  module Aws
104
114
 
@@ -362,7 +362,8 @@ module Aws::SSO
362
362
  #
363
363
  # @option params [required, String] :access_token
364
364
  # The token issued by the `CreateToken` API call. For more information,
365
- # see [CreateToken][1] in the *AWS SSO OIDC API Reference Guide*.
365
+ # see [CreateToken][1] in the *IAM Identity Center OIDC API Reference
366
+ # Guide*.
366
367
  #
367
368
  #
368
369
  #
@@ -407,7 +408,8 @@ module Aws::SSO
407
408
  #
408
409
  # @option params [required, String] :access_token
409
410
  # The token issued by the `CreateToken` API call. For more information,
410
- # see [CreateToken][1] in the *AWS SSO OIDC API Reference Guide*.
411
+ # see [CreateToken][1] in the *IAM Identity Center OIDC API Reference
412
+ # Guide*.
411
413
  #
412
414
  #
413
415
  #
@@ -450,8 +452,8 @@ module Aws::SSO
450
452
 
451
453
  # Lists all AWS accounts assigned to the user. These AWS accounts are
452
454
  # assigned by the administrator of the account. For more information,
453
- # see [Assign User Access][1] in the *AWS SSO User Guide*. This
454
- # operation returns a paginated response.
455
+ # see [Assign User Access][1] in the *IAM Identity Center User Guide*.
456
+ # This operation returns a paginated response.
455
457
  #
456
458
  #
457
459
  #
@@ -466,7 +468,8 @@ module Aws::SSO
466
468
  #
467
469
  # @option params [required, String] :access_token
468
470
  # The token issued by the `CreateToken` API call. For more information,
469
- # see [CreateToken][1] in the *AWS SSO OIDC API Reference Guide*.
471
+ # see [CreateToken][1] in the *IAM Identity Center OIDC API Reference
472
+ # Guide*.
470
473
  #
471
474
  #
472
475
  #
@@ -504,12 +507,32 @@ module Aws::SSO
504
507
  req.send_request(options)
505
508
  end
506
509
 
507
- # Removes the client- and server-side session that is associated with
508
- # the user.
510
+ # Removes the locally stored SSO tokens from the client-side cache and
511
+ # sends an API call to the IAM Identity Center service to invalidate the
512
+ # corresponding server-side IAM Identity Center sign in session.
513
+ #
514
+ # <note markdown="1"> If a user uses IAM Identity Center to access the AWS CLI, the user’s
515
+ # IAM Identity Center sign in session is used to obtain an IAM session,
516
+ # as specified in the corresponding IAM Identity Center permission set.
517
+ # More specifically, IAM Identity Center assumes an IAM role in the
518
+ # target account on behalf of the user, and the corresponding temporary
519
+ # AWS credentials are returned to the client.
520
+ #
521
+ # After user logout, any existing IAM role sessions that were created by
522
+ # using IAM Identity Center permission sets continue based on the
523
+ # duration configured in the permission set. For more information, see
524
+ # [User authentications][1] in the *IAM Identity Center User Guide*.
525
+ #
526
+ # </note>
527
+ #
528
+ #
529
+ #
530
+ # [1]: https://docs.aws.amazon.com/singlesignon/latest/userguide/authconcept.html
509
531
  #
510
532
  # @option params [required, String] :access_token
511
533
  # The token issued by the `CreateToken` API call. For more information,
512
- # see [CreateToken][1] in the *AWS SSO OIDC API Reference Guide*.
534
+ # see [CreateToken][1] in the *IAM Identity Center OIDC API Reference
535
+ # Guide*.
513
536
  #
514
537
  #
515
538
  #
@@ -545,7 +568,7 @@ module Aws::SSO
545
568
  params: params,
546
569
  config: config)
547
570
  context[:gem_name] = 'aws-sdk-core'
548
- context[:gem_version] = '3.131.0'
571
+ context[:gem_version] = '3.158.1'
549
572
  Seahorse::Client::Request.new(handlers, context)
550
573
  end
551
574
 
@@ -53,8 +53,8 @@ module Aws::SSO
53
53
  #
54
54
  # @!attribute [rw] access_token
55
55
  # The token issued by the `CreateToken` API call. For more
56
- # information, see [CreateToken][1] in the *AWS SSO OIDC API Reference
57
- # Guide*.
56
+ # information, see [CreateToken][1] in the *IAM Identity Center OIDC
57
+ # API Reference Guide*.
58
58
  #
59
59
  #
60
60
  #
@@ -118,8 +118,8 @@ module Aws::SSO
118
118
  #
119
119
  # @!attribute [rw] access_token
120
120
  # The token issued by the `CreateToken` API call. For more
121
- # information, see [CreateToken][1] in the *AWS SSO OIDC API Reference
122
- # Guide*.
121
+ # information, see [CreateToken][1] in the *IAM Identity Center OIDC
122
+ # API Reference Guide*.
123
123
  #
124
124
  #
125
125
  #
@@ -179,8 +179,8 @@ module Aws::SSO
179
179
  #
180
180
  # @!attribute [rw] access_token
181
181
  # The token issued by the `CreateToken` API call. For more
182
- # information, see [CreateToken][1] in the *AWS SSO OIDC API Reference
183
- # Guide*.
182
+ # information, see [CreateToken][1] in the *IAM Identity Center OIDC
183
+ # API Reference Guide*.
184
184
  #
185
185
  #
186
186
  #
@@ -224,8 +224,8 @@ module Aws::SSO
224
224
  #
225
225
  # @!attribute [rw] access_token
226
226
  # The token issued by the `CreateToken` API call. For more
227
- # information, see [CreateToken][1] in the *AWS SSO OIDC API Reference
228
- # Guide*.
227
+ # information, see [CreateToken][1] in the *IAM Identity Center OIDC
228
+ # API Reference Guide*.
229
229
  #
230
230
  #
231
231
  #
data/lib/aws-sdk-sso.rb CHANGED
@@ -50,6 +50,6 @@ require_relative 'aws-sdk-sso/customizations'
50
50
  # @!group service
51
51
  module Aws::SSO
52
52
 
53
- GEM_VERSION = '3.131.0'
53
+ GEM_VERSION = '3.158.1'
54
54
 
55
55
  end