Ai
1 Star 1 Fork 0

fenghai_hhf/aws-sdk-cpp

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
STSProfileCredentialsProviderTest.cpp 24.16 KB
一键复制 编辑 原始数据 按行查看 历史
Andrew Tang 提交于 2019-11-16 04:05 +08:00 . Cached Config and Credentials
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
/*
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
#include <aws/identity-management/auth/STSProfileCredentialsProvider.h>
#include <aws/sts/model/AssumeRoleRequest.h>
#include <aws/sts/STSClient.h>
#include <aws/core/utils/Outcome.h>
#include <aws/core/utils/DateTime.h>
#include <aws/core/platform/Environment.h>
#include <aws/core/utils/memory/stl/AWSStreamFwd.h>
#include <aws/testing/platform/PlatformTesting.h>
#include <aws/core/platform/FileSystem.h>
#include <aws/external/gtest.h>
#include <fstream>
#include <cassert>
#include <thread>
using namespace Aws::Auth;
using namespace Aws::STS;
using namespace Aws::Utils;
namespace {
class MockSTSClient : public STSClient
{
public:
MockSTSClient() = default;
explicit MockSTSClient(const AWSCredentials& creds) : STSClient(creds), m_credentials(creds)
{
}
Model::AssumeRoleOutcome AssumeRole(const Model::AssumeRoleRequest& request) const override
{
m_capturedRequest = request;
return m_mockedOutcome;
}
void MockAssumeRole(const Model::AssumeRoleOutcome& outcome)
{
m_mockedOutcome = outcome;
}
const Model::AssumeRoleRequest& CapturedRequest() const
{
return m_capturedRequest;
}
const AWSCredentials& Credentials() const
{
return m_credentials;
}
private:
mutable Model::AssumeRoleRequest m_capturedRequest;
Model::AssumeRoleOutcome m_mockedOutcome;
AWSCredentials m_credentials;
};
const char CLASS_TAG[] = "STSProfileCredentialsProvider";
const char ROLE_ARN_1[] = "arn:aws:iam::123456789:role/SomeRole";
const char ROLE_ARN_2[] = "arn:aws:iam::123456789:role/AnotherRole";
const char ACCESS_KEY_ID_1[] = "accessKeyId1";
const char SECRET_ACCESS_KEY_ID_1[] = "secretAccessKeyId1";
const char SESSION_TOKEN[] = "sessionToken123";
const char ACCESS_KEY_ID_2[] = "accessKeyId2";
const char SECRET_ACCESS_KEY_ID_2[] = "secretAccessKeyId2";
const char ACCESS_KEY_ID_3[] = "accessKeyId3";
const char SECRET_ACCESS_KEY_ID_3[] = "secretAccessKeyId3";
class STSProfileCredentialsProviderTest : public ::testing::Test
{
public:
void SetUp()
{
SaveEnvironmentVariable("AWS_DEFAULT_PROFILE");
Aws::Environment::UnSetEnv("AWS_DEFAULT_PROFILE");
Aws::FileSystem::CreateDirectoryIfNotExists(ProfileConfigFileAWSCredentialsProvider::GetProfileDirectory().c_str());
Aws::StringStream ss;
ss << Aws::Auth::GetConfigProfileFilename() + "_blah" << std::this_thread::get_id();
m_configFilename = ss.str();
SaveEnvironmentVariable("AWS_CONFIG");
Aws::Environment::SetEnv("AWS_CONFIG_FILE", m_configFilename.c_str(), 1);
}
void TearDown()
{
RestoreEnvironmentVariables();
}
void SaveEnvironmentVariable(const char* variableName)
{
m_environmentVars.emplace_back(variableName, Aws::Environment::GetEnv(variableName));
}
void RestoreEnvironmentVariables()
{
for(const auto& iter : m_environmentVars)
{
if(iter.second.empty())
{
Aws::Environment::UnSetEnv(iter.first);
}
else
{
Aws::Environment::SetEnv(iter.first, iter.second.c_str(), 1);
}
}
}
Aws::String m_configFilename;
Aws::Vector<std::pair<const char*, Aws::String>> m_environmentVars;
};
TEST_F(STSProfileCredentialsProviderTest, TestCredentialsLoadAndCache)
{
Aws::OFStream configFile {m_configFilename.c_str(), Aws::OFStream::out | Aws::OFStream::trunc};
configFile << std::endl;
configFile << "[default]" << std::endl;
configFile << "source_profile = other" << std::endl;
configFile << "role_arn = " << ROLE_ARN_1 << std::endl;
configFile << std::endl;
configFile << " [other]" << std::endl;
configFile << "aws_access_key_id = " << ACCESS_KEY_ID_1 << std::endl;
configFile << "aws_secret_access_key = " << SECRET_ACCESS_KEY_ID_1 << std::endl;
configFile.close();
Aws::Config::ReloadCachedConfigFile();
constexpr auto roleSessionDuration = std::chrono::hours(1);
const DateTime expiryTime{DateTime::Now() + roleSessionDuration};
Model::Credentials stsCredentials;
stsCredentials.WithAccessKeyId(ACCESS_KEY_ID_2)
.WithSecretAccessKey(SECRET_ACCESS_KEY_ID_2)
.WithSessionToken(SESSION_TOKEN)
.WithExpiration(expiryTime);
Model::AssumeRoleResult mockResult;
mockResult.SetCredentials(stsCredentials);
Aws::UniquePtr<MockSTSClient> stsClient;
int stsCallCounter = 0;
STSProfileCredentialsProvider credsProvider("default", roleSessionDuration, [&](const AWSCredentials& creds)
{
++stsCallCounter;
stsClient = Aws::MakeUnique<MockSTSClient>(CLASS_TAG, creds);
stsClient->MockAssumeRole(mockResult);
return stsClient.get();
});
auto actualCredentials = credsProvider.GetAWSCredentials();
ASSERT_STREQ(ACCESS_KEY_ID_2, actualCredentials.GetAWSAccessKeyId().c_str());
ASSERT_STREQ(SECRET_ACCESS_KEY_ID_2, actualCredentials.GetAWSSecretKey().c_str());
ASSERT_STREQ(SESSION_TOKEN, actualCredentials.GetSessionToken().c_str());
ASSERT_EQ(expiryTime, actualCredentials.GetExpiration());
ASSERT_EQ(1, stsCallCounter);
ASSERT_STREQ(ACCESS_KEY_ID_1, stsClient->Credentials().GetAWSAccessKeyId().c_str());
ASSERT_STREQ(SECRET_ACCESS_KEY_ID_1, stsClient->Credentials().GetAWSSecretKey().c_str());
actualCredentials = credsProvider.GetAWSCredentials();
ASSERT_STREQ(ACCESS_KEY_ID_2, actualCredentials.GetAWSAccessKeyId().c_str());
ASSERT_STREQ(SECRET_ACCESS_KEY_ID_2, actualCredentials.GetAWSSecretKey().c_str());
ASSERT_STREQ(SESSION_TOKEN, actualCredentials.GetSessionToken().c_str());
ASSERT_EQ(expiryTime, actualCredentials.GetExpiration());
//we should not have called multiple times.
ASSERT_EQ(1, stsCallCounter);
}
static Aws::String WrapEchoStringWithSingleQuoteForUnixShell(Aws::String str)
{
#ifndef _WIN32
str.insert(0, 1, '\'');
str.append(1, '\'');
#endif
return str;
}
/**
* Test a initial profile with static credentials and source profile.
* Expected: use the source profile
*/
TEST_F(STSProfileCredentialsProviderTest, AssumeRoleWithStaticAndSourceProfile)
{
Aws::OFStream configFile {m_configFilename.c_str(), Aws::OFStream::out | Aws::OFStream::trunc};
configFile << std::endl;
configFile << "[default]" << std::endl;
configFile << "role_arn = " << ROLE_ARN_1 << std::endl;
configFile << "source_profile = B" << std::endl;
configFile << "aws_access_key_id = " << ACCESS_KEY_ID_1 << std::endl;
configFile << "aws_secret_access_key = " << SECRET_ACCESS_KEY_ID_1 << std::endl;
configFile << std::endl;
configFile << " [B]" << std::endl;
configFile << "aws_access_key_id = " << ACCESS_KEY_ID_2 << std::endl;
configFile << "aws_secret_access_key = " << SECRET_ACCESS_KEY_ID_2 << std::endl;
configFile.close();
Aws::Config::ReloadCachedConfigFile();
constexpr auto roleSessionDuration = std::chrono::hours(1);
const DateTime expiryTime{DateTime::Now() + roleSessionDuration};
Model::Credentials stsCredentials;
stsCredentials.WithAccessKeyId(ACCESS_KEY_ID_3)
.WithSecretAccessKey(SECRET_ACCESS_KEY_ID_3)
.WithSessionToken(SESSION_TOKEN)
.WithExpiration(expiryTime);
Model::AssumeRoleResult mockResult;
mockResult.SetCredentials(stsCredentials);
Aws::UniquePtr<MockSTSClient> stsClient;
int stsCallCounter = 0;
STSProfileCredentialsProvider credsProvider("default", roleSessionDuration, [&](const AWSCredentials& creds)
{
if (++stsCallCounter == 1)
{
EXPECT_STREQ(ACCESS_KEY_ID_2, creds.GetAWSAccessKeyId().c_str());
EXPECT_STREQ(SECRET_ACCESS_KEY_ID_2, creds.GetAWSSecretKey().c_str());
}
stsClient = Aws::MakeUnique<MockSTSClient>(CLASS_TAG, creds);
stsClient->MockAssumeRole(mockResult);
return stsClient.get();
});
const auto actualCredentials = credsProvider.GetAWSCredentials();
ASSERT_EQ(1, stsCallCounter);
ASSERT_FALSE(actualCredentials.IsExpiredOrEmpty());
ASSERT_STREQ(ACCESS_KEY_ID_3, actualCredentials.GetAWSAccessKeyId().c_str());
ASSERT_STREQ(SECRET_ACCESS_KEY_ID_3, actualCredentials.GetAWSSecretKey().c_str());
ASSERT_EQ(expiryTime, actualCredentials.GetExpiration());
}
/**
* Test that having a source profile works (happy path), with the source profile using a process to retrieve credentials.
*/
TEST_F(STSProfileCredentialsProviderTest, AssumeRoleWithProcessCredentials)
{
Aws::OFStream configFile {m_configFilename.c_str(), Aws::OFStream::out | Aws::OFStream::trunc};
configFile << std::endl;
configFile << "[default]" << std::endl;
configFile << "source_profile = other" << std::endl;
configFile << "role_arn = " << ROLE_ARN_1 << std::endl;
configFile << std::endl;
configFile << " [other]" << std::endl;
configFile << "credential_process = echo " << WrapEchoStringWithSingleQuoteForUnixShell("{\"Version\": 1, \"AccessKeyId\": \"AccessKey123\", \"SecretAccessKey\": \"SecretKey321\", \"Expiration\": \"1970-01-01T00:00:01Z\"}") << std::endl;
configFile.close();
Aws::Config::ReloadCachedConfigFile();
constexpr auto roleSessionDuration = std::chrono::hours(1);
const DateTime expiryTime{DateTime::Now() + roleSessionDuration};
Model::Credentials stsCredentials;
stsCredentials.WithAccessKeyId(ACCESS_KEY_ID_2)
.WithSecretAccessKey(SECRET_ACCESS_KEY_ID_2)
.WithSessionToken(SESSION_TOKEN)
.WithExpiration(expiryTime);
Model::AssumeRoleResult mockResult;
mockResult.SetCredentials(stsCredentials);
Aws::UniquePtr<MockSTSClient> stsClient;
int stsCallCounter = 0;
STSProfileCredentialsProvider credsProvider("default", roleSessionDuration, [&](const AWSCredentials& creds)
{
++stsCallCounter;
stsClient = Aws::MakeUnique<MockSTSClient>(CLASS_TAG, creds);
stsClient->MockAssumeRole(mockResult);
return stsClient.get();
});
auto actualCredentials = credsProvider.GetAWSCredentials();
ASSERT_STREQ(ACCESS_KEY_ID_2, actualCredentials.GetAWSAccessKeyId().c_str());
ASSERT_STREQ(SECRET_ACCESS_KEY_ID_2, actualCredentials.GetAWSSecretKey().c_str());
ASSERT_STREQ(SESSION_TOKEN, actualCredentials.GetSessionToken().c_str());
ASSERT_EQ(expiryTime, actualCredentials.GetExpiration());
ASSERT_EQ(1, stsCallCounter);
ASSERT_STREQ("AccessKey123", stsClient->Credentials().GetAWSAccessKeyId().c_str());
ASSERT_STREQ("SecretKey321", stsClient->Credentials().GetAWSSecretKey().c_str());
}
/**
* Test a profile without a Role to assume but yet it has a source profile.
*/
TEST_F(STSProfileCredentialsProviderTest, AssumeRoleWithoutRoleARN)
{
Aws::OFStream configFile {m_configFilename.c_str(), Aws::OFStream::out | Aws::OFStream::trunc};
configFile << std::endl;
configFile << "[default]" << std::endl;
configFile << "source_profile = other" << std::endl;
configFile << std::endl;
configFile << " [other]" << std::endl;
configFile << "credential_process = echo " << WrapEchoStringWithSingleQuoteForUnixShell("{\"Version\": 1, \"AccessKeyId\": \"AccessKey123\", \"SecretAccessKey\": \"SecretKey321\", \"Expiration\": \"1970-01-01T00:00:01Z\"}") << std::endl;
configFile.close();
Aws::Config::ReloadCachedConfigFile();
constexpr auto roleSessionDuration = std::chrono::hours(1);
STSProfileCredentialsProvider credsProvider("default", roleSessionDuration, [](const AWSCredentials&) {
ADD_FAILURE() << "STS Service client should not be used in this scenario.";
return nullptr;
});
auto actualCredentials = credsProvider.GetAWSCredentials();
ASSERT_TRUE(actualCredentials.IsExpiredOrEmpty());
}
/**
* Test a source profile without a Role to assume.
*/
TEST_F(STSProfileCredentialsProviderTest, AssumeRoleWithoutRoleARNInSourceProfile)
{
Aws::OFStream configFile {m_configFilename.c_str(), Aws::OFStream::out | Aws::OFStream::trunc};
configFile.open(m_configFilename.c_str());
configFile << std::endl;
configFile << "[default]" << std::endl;
configFile << "role_arn = " << ROLE_ARN_1 << std::endl;
configFile << "source_profile = second" << std::endl;
configFile << std::endl;
configFile << " [second]" << std::endl;
configFile << "source_profile = third" << std::endl;
configFile << " [third]" << std::endl;
configFile << "aws_access_key_id = " << ACCESS_KEY_ID_1 << std::endl;
configFile << "aws_secret_access_key = " << SECRET_ACCESS_KEY_ID_1 << std::endl;
configFile.close();
Aws::Config::ReloadCachedConfigFile();
constexpr auto roleSessionDuration = std::chrono::hours(1);
const DateTime expiryTime{DateTime::Now() + roleSessionDuration};
Model::Credentials stsCredentials;
stsCredentials.WithAccessKeyId(ACCESS_KEY_ID_2)
.WithSecretAccessKey(SECRET_ACCESS_KEY_ID_2)
.WithSessionToken(SESSION_TOKEN)
.WithExpiration(expiryTime);
Model::AssumeRoleResult mockResult;
mockResult.SetCredentials(stsCredentials);
Aws::UniquePtr<MockSTSClient> stsClient;
STSProfileCredentialsProvider credsProvider("default", roleSessionDuration, [&](const AWSCredentials& creds) {
stsClient = Aws::MakeUnique<MockSTSClient>(CLASS_TAG, creds);
stsClient->MockAssumeRole(mockResult);
return stsClient.get();
});
auto actualCredentials = credsProvider.GetAWSCredentials();
ASSERT_TRUE(actualCredentials.IsExpiredOrEmpty());
}
/**
* Test a profile with a Role to assume, but yet has no source profile.
*/
TEST_F(STSProfileCredentialsProviderTest, AssumeRoleWithoutSourceProfile)
{
Aws::OFStream configFile {m_configFilename.c_str(), Aws::OFStream::out | Aws::OFStream::trunc};
configFile << std::endl;
configFile << "[default]" << std::endl;
configFile << "role_arn = " << ROLE_ARN_1 << std::endl;
configFile << std::endl;
configFile.close();
Aws::Config::ReloadCachedConfigFile();
constexpr auto roleSessionDuration = std::chrono::hours(1);
STSProfileCredentialsProvider credsProvider("default", roleSessionDuration, [](const AWSCredentials&) {
ADD_FAILURE() << "STS Service client should not be used in this scenario.";
return nullptr;
});
auto actualCredentials = credsProvider.GetAWSCredentials();
ASSERT_TRUE(actualCredentials.IsExpiredOrEmpty());
}
TEST_F(STSProfileCredentialsProviderTest, AssumeRoleWithNonExistentSourceProfile)
{
Aws::OFStream configFile {m_configFilename.c_str(), Aws::OFStream::out | Aws::OFStream::trunc};
configFile << std::endl;
configFile << "[default]" << std::endl;
configFile << "source_profile = DoesNotExist" << std::endl;
configFile << "role_arn = " << ROLE_ARN_1 << std::endl;
configFile << std::endl;
configFile << " [YouCannotFindMe]" << std::endl;
configFile << "aws_access_key_id = " << ACCESS_KEY_ID_1 << std::endl;
configFile << "aws_secret_access_key = " << SECRET_ACCESS_KEY_ID_1 << std::endl;
configFile.close();
Aws::Config::ReloadCachedConfigFile();
constexpr auto roleSessionDuration = std::chrono::hours(1);
STSProfileCredentialsProvider credsProvider("default", roleSessionDuration, [](const AWSCredentials&) {
ADD_FAILURE() << "STS Service client should not be used in this scenario.";
return nullptr;
});
auto actualCredentials = credsProvider.GetAWSCredentials();
ASSERT_TRUE(actualCredentials.IsExpiredOrEmpty());
}
/**
* Test that source profiles can be chained.
* The following scenario should succeed:
* Profile A sources Profile B
* Profile B sources Profile C
*/
TEST_F(STSProfileCredentialsProviderTest, AssumeRoleRecursively)
{
Aws::OFStream configFile {m_configFilename.c_str(), Aws::OFStream::out | Aws::OFStream::trunc};
configFile << std::endl;
configFile << "[A]" << std::endl;
configFile << "source_profile = B" << std::endl;
configFile << "role_arn = " << ROLE_ARN_1 << std::endl;
configFile << std::endl;
configFile << "[B]" << std::endl;
configFile << "source_profile = C" << std::endl;
configFile << "role_arn = " << ROLE_ARN_2 << std::endl;
configFile << std::endl;
configFile << " [C]" << std::endl;
configFile << "aws_access_key_id = " << ACCESS_KEY_ID_1 << std::endl;
configFile << "aws_secret_access_key = " << SECRET_ACCESS_KEY_ID_1 << std::endl;
configFile.close();
Aws::Config::ReloadCachedConfigFile();
constexpr auto roleSessionDuration = std::chrono::hours(1);
const DateTime expiryTime{DateTime::Now() + roleSessionDuration};
Model::Credentials stsCredentials;
stsCredentials.WithAccessKeyId(ACCESS_KEY_ID_2)
.WithSecretAccessKey(SECRET_ACCESS_KEY_ID_2)
.WithSessionToken(SESSION_TOKEN)
.WithExpiration(expiryTime);
Model::AssumeRoleResult mockResult;
mockResult.SetCredentials(stsCredentials);
Aws::UniquePtr<MockSTSClient> stsClient;
int stsCallCounter = 0;
STSProfileCredentialsProvider credsProvider("A", roleSessionDuration, [&](const AWSCredentials& creds)
{
if (++stsCallCounter == 1)
{
EXPECT_STREQ(ACCESS_KEY_ID_1, creds.GetAWSAccessKeyId().c_str());
EXPECT_STREQ(SECRET_ACCESS_KEY_ID_1, creds.GetAWSSecretKey().c_str());
}
else if (stsCallCounter == 2)
{
EXPECT_STREQ(ACCESS_KEY_ID_2, creds.GetAWSAccessKeyId().c_str());
EXPECT_STREQ(SECRET_ACCESS_KEY_ID_2, creds.GetAWSSecretKey().c_str());
}
stsClient = Aws::MakeUnique<MockSTSClient>(CLASS_TAG, creds);
stsClient->MockAssumeRole(mockResult);
return stsClient.get();
});
const auto actualCredentials = credsProvider.GetAWSCredentials();
ASSERT_FALSE(actualCredentials.IsExpiredOrEmpty());
ASSERT_NE(nullptr, stsClient);
ASSERT_EQ(2, stsCallCounter);
}
/**
* Test that profile that sources itself.
*/
TEST_F(STSProfileCredentialsProviderTest, AssumeRoleSelfReferencing)
{
Aws::OFStream configFile {m_configFilename.c_str(), Aws::OFStream::out | Aws::OFStream::trunc};
configFile << std::endl;
configFile << "[A]" << std::endl;
configFile << "source_profile = A" << std::endl;
configFile << "role_arn = " << ROLE_ARN_1 << std::endl;
configFile << "aws_access_key_id = " << ACCESS_KEY_ID_1 << std::endl;
configFile << "aws_secret_access_key = " << SECRET_ACCESS_KEY_ID_1 << std::endl;
configFile << std::endl;
configFile.close();
Aws::Config::ReloadCachedConfigFile();
constexpr auto roleSessionDuration = std::chrono::hours(1);
const DateTime expiryTime{DateTime::Now() + roleSessionDuration};
Model::Credentials stsCredentials;
stsCredentials.WithAccessKeyId(ACCESS_KEY_ID_2)
.WithSecretAccessKey(SECRET_ACCESS_KEY_ID_2)
.WithSessionToken(SESSION_TOKEN)
.WithExpiration(expiryTime);
Model::AssumeRoleResult mockResult;
mockResult.SetCredentials(stsCredentials);
Aws::UniquePtr<MockSTSClient> stsClient;
int stsCallCounter = 0;
STSProfileCredentialsProvider credsProvider("A", roleSessionDuration, [&](const AWSCredentials& creds)
{
++stsCallCounter;
EXPECT_STREQ(ACCESS_KEY_ID_1, creds.GetAWSAccessKeyId().c_str());
EXPECT_STREQ(SECRET_ACCESS_KEY_ID_1, creds.GetAWSSecretKey().c_str());
stsClient = Aws::MakeUnique<MockSTSClient>(CLASS_TAG, creds);
stsClient->MockAssumeRole(mockResult);
return stsClient.get();
});
auto actualCredentials = credsProvider.GetAWSCredentials();
ASSERT_FALSE(actualCredentials.IsExpiredOrEmpty());
ASSERT_EQ(1, stsCallCounter);
ASSERT_NE(nullptr, stsClient); // if this fails, that means the sts call never happened.
}
TEST_F(STSProfileCredentialsProviderTest, AssumeRoleSelfReferencingSourceProfile)
{
Aws::OFStream configFile {m_configFilename.c_str(), Aws::OFStream::out | Aws::OFStream::trunc};
configFile << std::endl;
configFile << "[A]" << std::endl;
configFile << "source_profile = B" << std::endl;
configFile << "role_arn = " << ROLE_ARN_1 << std::endl;
configFile << "[B]" << std::endl;
configFile << "source_profile = B" << std::endl;
configFile << "role_arn = " << ROLE_ARN_2 << std::endl;
configFile << "aws_access_key_id = " << ACCESS_KEY_ID_1 << std::endl;
configFile << "aws_secret_access_key = " << SECRET_ACCESS_KEY_ID_1 << std::endl;
configFile << std::endl;
configFile.close();
Aws::Config::ReloadCachedConfigFile();
constexpr auto roleSessionDuration = std::chrono::hours(1);
const DateTime expiryTime{DateTime::Now() + roleSessionDuration};
Model::Credentials stsCredentials;
stsCredentials.WithAccessKeyId(ACCESS_KEY_ID_2)
.WithSecretAccessKey(SECRET_ACCESS_KEY_ID_2)
.WithSessionToken(SESSION_TOKEN)
.WithExpiration(expiryTime);
Model::AssumeRoleResult mockResult;
mockResult.SetCredentials(stsCredentials);
Aws::UniquePtr<MockSTSClient> stsClient;
int stsCallCounter = 0;
STSProfileCredentialsProvider credsProvider("A", roleSessionDuration, [&](const AWSCredentials& creds)
{
if (++stsCallCounter == 1)
{
EXPECT_STREQ(ACCESS_KEY_ID_1, creds.GetAWSAccessKeyId().c_str());
EXPECT_STREQ(SECRET_ACCESS_KEY_ID_1, creds.GetAWSSecretKey().c_str());
}
else if (stsCallCounter == 2)
{
EXPECT_STREQ(ACCESS_KEY_ID_2, creds.GetAWSAccessKeyId().c_str());
EXPECT_STREQ(SECRET_ACCESS_KEY_ID_2, creds.GetAWSSecretKey().c_str());
}
stsClient = Aws::MakeUnique<MockSTSClient>(CLASS_TAG, creds);
stsClient->MockAssumeRole(mockResult);
return stsClient.get();
});
auto actualCredentials = credsProvider.GetAWSCredentials();
ASSERT_FALSE(actualCredentials.IsExpiredOrEmpty());
ASSERT_EQ(2, stsCallCounter);
ASSERT_NE(nullptr, stsClient); // if this fails, then the sts call never happened.
}
/**
* Test that profiles with circular-references fail.
* The following scenario should fail and returns invalid/empty credentials
* Profile A sources Profile B.
* Profile B sources Profile C.
* Profile C sources Profile A.
*/
TEST_F(STSProfileCredentialsProviderTest, AssumeRoleRecursivelyCircularReference)
{
Aws::OFStream configFile {m_configFilename.c_str(), Aws::OFStream::out | Aws::OFStream::trunc};
configFile << std::endl;
configFile << "[A]" << std::endl;
configFile << "source_profile = B" << std::endl;
configFile << "role_arn = " << ROLE_ARN_1 << std::endl;
configFile << std::endl;
configFile << "[B]" << std::endl;
configFile << "source_profile = C" << std::endl;
configFile << "role_arn = " << ROLE_ARN_2 << std::endl;
configFile << std::endl;
configFile << "[C]" << std::endl;
configFile << "source_profile = A" << std::endl;
configFile << "role_arn = " << ROLE_ARN_2 << std::endl;
configFile << std::endl;
configFile.close();
Aws::Config::ReloadCachedConfigFile();
constexpr auto roleSessionDuration = std::chrono::hours(1);
STSProfileCredentialsProvider credsProvider("default", roleSessionDuration, [](const AWSCredentials&) {
ADD_FAILURE() << "STS Service client should not be used in this scenario.";
return nullptr;
});
auto actualCredentials = credsProvider.GetAWSCredentials();
ASSERT_TRUE(actualCredentials.IsExpiredOrEmpty());
}
} // namespace
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/fenghai_hhf/aws-sdk-cpp.git
git@gitee.com:fenghai_hhf/aws-sdk-cpp.git
fenghai_hhf
aws-sdk-cpp
aws-sdk-cpp
master

搜索帮助