Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions gems/aws-sdk-cognitoidentity/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Unreleased Changes
------------------

* Issue - Pass provided `logins` when a `CognitoIdentityCredentials` client is created (#2941).

1.49.0 (2023-09-27)
------------------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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

Expand All @@ -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<String,String>] :logins A set of optional
# name-value pairs that map provider names to provider tokens.
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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(
Expand All @@ -134,4 +134,3 @@ def refresh
end
end
end

Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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(
Expand Down Expand Up @@ -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