From bd7227833049c0339a2caee2200f8b003f6b88a4 Mon Sep 17 00:00:00 2001 From: Juli Tera <57973151+jterapin@users.noreply.github.com> Date: Tue, 14 Nov 2023 14:35:55 -0800 Subject: [PATCH] Fix CognitoIdentityCredentials (#2944) --- gems/aws-sdk-cognitoidentity/CHANGELOG.md | 2 + .../cognito_identity_credentials.rb | 41 +++++++++---------- .../spec/cognito_identity_credentials_spec.rb | 27 +++++++++--- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/gems/aws-sdk-cognitoidentity/CHANGELOG.md b/gems/aws-sdk-cognitoidentity/CHANGELOG.md index 61230ddef79..ca24bc2e5bd 100644 --- a/gems/aws-sdk-cognitoidentity/CHANGELOG.md +++ b/gems/aws-sdk-cognitoidentity/CHANGELOG.md @@ -1,6 +1,8 @@ Unreleased Changes ------------------ +* Issue - Pass provided `logins` when a `CognitoIdentityCredentials` client is created (#2941). + 1.49.0 (2023-09-27) ------------------ diff --git a/gems/aws-sdk-cognitoidentity/lib/aws-sdk-cognitoidentity/customizations/cognito_identity_credentials.rb b/gems/aws-sdk-cognitoidentity/lib/aws-sdk-cognitoidentity/customizations/cognito_identity_credentials.rb index 31f4ee4cef3..e95f6e8a024 100644 --- a/gems/aws-sdk-cognitoidentity/lib/aws-sdk-cognitoidentity/customizations/cognito_identity_credentials.rb +++ b/gems/aws-sdk-cognitoidentity/lib/aws-sdk-cognitoidentity/customizations/cognito_identity_credentials.rb @@ -23,7 +23,7 @@ module CognitoIdentity # # ## Refreshing Credentials from Identity Service # - # The CognitoIdentityCredentials will auto-refresh the AWS credentials from + # The `CognitoIdentityCredentials` will auto-refresh the AWS credentials from # Cognito. In addition to AWS credentials expiring after a given amount of # time, the login token from the identity provider will also expire. # Once this token expires, it will not be usable to refresh AWS credentials, @@ -32,19 +32,18 @@ module CognitoIdentity # supported by most identity providers. Consult the documentation for # the identity provider for refreshing tokens. Once the refreshed token is # acquired, you should make sure to update this new token in the - # CognitoIdentityCredentials object's {logins} property. The following + # `CognitoIdentityCredentials` object's {logins} property. The following # code will update the WebIdentityToken, assuming you have retrieved # an updated token from the identity provider: # - # AWS.config.credentials.logins['graph.facebook.com'] = updatedToken; - # AWS.config.credentials.refresh! # required only if authentication state has changed + # cognito_credentials.logins['graph.facebook.com'] = updatedToken; + # cognito_credentials.refresh! # required only if authentication state has changed # - # The CognitoIdentityCredentials also provides a `before_refresh` callback + # The `CognitoIdentityCredentials` also provides a `before_refresh` callback # that can be used to help manage refreshing identity provider tokens. # `before_refresh` is called when AWS credentials are required and need # to be refreshed and it has access to the CognitoIdentityCredentials object. class CognitoIdentityCredentials - include CredentialProvider include RefreshingCredentials @@ -54,8 +53,8 @@ class CognitoIdentityCredentials # identifier in the format REGION:GUID # # @option options [String] :identity_pool_id Required unless identity_id - # is provided. A Amazon Cognito - # Identity Pool ID)in the format REGION:GUID. + # is provided. An Amazon Cognito Identity Pool ID in the + # format REGION:GUID. # # @option options [Hash] :logins A set of optional # name-value pairs that map provider names to provider tokens. @@ -69,16 +68,15 @@ class CognitoIdentityCredentials # that do not support role customization. # # @option options [Callable] before_refresh Proc called before - # credentials are refreshed from Cognito. Useful for updating logins/ - # auth tokens. `before_refresh` is called when AWS credentials are - # required and need to be refreshed. Login tokens can be refreshed using - # the following example: + # credentials are refreshed from Cognito. `before_refresh` is called + # when AWS credentials are required and need to be refreshed. + # Login tokens can be refreshed using the following example: # # before_refresh = Proc.new do |cognito_credentials| do # cognito_credentials.logins['graph.facebook.com'] = update_token # end # - # @option options [STS::CognitoIdentity] :client Optional CognitoIdentity + # @option options [CognitoIdentity::Client] :client Optional CognitoIdentity # client. If not provided, a client will be constructed. def initialize(options = {}) @identity_pool_id = options.delete(:identity_pool_id) @@ -88,9 +86,9 @@ def initialize(options = {}) @async_refresh = false client_opts = {} - options.each_pair { |k,v| client_opts[k] = v unless CLIENT_EXCLUDE_OPTIONS.include?(k) } + options.each_pair { |k, v| client_opts[k] = v unless CLIENT_EXCLUDE_OPTIONS.include?(k) } - if !@identity_pool_id && !@identity_id + unless @identity_pool_id || @identity_id raise ArgumentError, 'Must provide either identity_pool_id or identity_id' end @@ -109,19 +107,21 @@ def initialize(options = {}) # @return [String] def identity_id - @identity_id ||= @client - .get_id(identity_pool_id: @identity_pool_id) - .identity_id + @identity_id ||= @client.get_id( + identity_pool_id: @identity_pool_id, + logins: @logins + ).identity_id end private def refresh - @before_refresh.call(self) if @before_refresh + @before_refresh&.call(self) resp = @client.get_credentials_for_identity( identity_id: identity_id, - custom_role_arn: @custom_role_arn + custom_role_arn: @custom_role_arn, + logins: @logins ) @credentials = Credentials.new( @@ -134,4 +134,3 @@ def refresh end end end - diff --git a/gems/aws-sdk-cognitoidentity/spec/cognito_identity_credentials_spec.rb b/gems/aws-sdk-cognitoidentity/spec/cognito_identity_credentials_spec.rb index 7e58db04c7f..ebce9d53dff 100644 --- a/gems/aws-sdk-cognitoidentity/spec/cognito_identity_credentials_spec.rb +++ b/gems/aws-sdk-cognitoidentity/spec/cognito_identity_credentials_spec.rb @@ -29,7 +29,9 @@ module CognitoIdentity let(:identity_id) { 'identity_id' } let(:identity_pool_id) { 'pool_id' } - + let(:logins) do + { 'login_provider' => 'login_token' } + end let(:resp) { double('client-resp', credentials: cognito_creds) } describe '#initialize' do @@ -88,11 +90,13 @@ module CognitoIdentity it 'gets identity_id from the identity_pool_id' do expect(client).to receive(:get_id) - .with(identity_pool_id: identity_pool_id) + .with(identity_pool_id: identity_pool_id, logins: logins) .and_return(double("getid", identity_id: identity_id)) creds = CognitoIdentityCredentials.new( - client: client, identity_pool_id: identity_pool_id + client: client, + identity_pool_id: identity_pool_id, + logins: logins ) expect(creds.identity_id).to eq(identity_id) @@ -102,7 +106,7 @@ module CognitoIdentity describe '#refresh' do it 'extracts credentials and expiration from the response' do expect(client).to receive(:get_credentials_for_identity) - .with(identity_id: identity_id, custom_role_arn: nil) + .with(identity_id: identity_id, custom_role_arn: nil, logins: {}) .and_return(resp) creds = CognitoIdentityCredentials.new( @@ -134,8 +138,21 @@ module CognitoIdentity expect(before_refresh_called).to be(true) end - end + it 'passes logins to the credentials' do + expect(client).to receive(:get_credentials_for_identity) + .with(identity_id: identity_id, logins: logins, custom_role_arn: nil) + .and_return(resp) + + creds = CognitoIdentityCredentials.new( + client: client, + identity_id: identity_id, + logins: logins + ) + + expect(creds.logins).to eq(logins) + end + end end end end