Skip to content

Commit e3f174d

Browse files
Bearer token auth
1 parent d4cd53a commit e3f174d

File tree

39 files changed

+1839
-325
lines changed

39 files changed

+1839
-325
lines changed

aws-cpp-sdk-core-tests/aws/config/AWSProfileConfigLoaderTest.cpp renamed to aws-cpp-sdk-core-tests/aws/config/AWSConfigFileProfileConfigLoaderTest.cpp

Lines changed: 122 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include <aws/core/config/AWSProfileConfigLoader.h>
77
#include <aws/core/utils/FileSystemUtils.h>
88
#include <aws/core/utils/memory/stl/AWSStreamFwd.h>
9-
#include <aws/testing/mocks/aws/auth/MockAWSHttpResourceClient.h>
109
#include <fstream>
1110

1211
using namespace Aws::Utils;
@@ -167,44 +166,137 @@ TEST(AWSConfigFileProfileConfigLoaderTest, TestCredentialsFileCorrupted)
167166
ASSERT_EQ(0u, loader.GetProfiles().size());
168167
}
169168

170-
static const char* const ALLOCATION_TAG = "EC2InstanceProfileConfigLoaderTest";
169+
bool WriteConfigFileWithSSO(Aws::OStream& stream, const Aws::String& profileName, const Aws::String& ssoSessionName) {
170+
const Aws::String configFileContent =
171+
R"([ default]
172+
aws_access_key_id = ACCESS_KEY_0
173+
aws_secret_access_key = SECRET_KEY_0
171174
172-
TEST(EC2InstanceProfileConfigLoaderTest, TestSuccesfullyHitsService)
175+
176+
[profile custom-profile ]
177+
aws_access_key_id = ACCESS_KEY_1
178+
aws_secret_access_key = SECRET_KEY_1
179+
[profile )" + profileName + R"(]
180+
sso_session = )" + ssoSessionName + R"(
181+
182+
[sso-session )" + ssoSessionName + R"(]
183+
sso_region = us-east-1
184+
sso_start_url = https://d-abc123.awsapps.com/start)";
185+
186+
stream << configFileContent;
187+
stream.flush();
188+
189+
return stream.good();
190+
}
191+
192+
TEST(AWSConfigFileProfileConfigLoaderTest, TestConfigWithSSOParsing)
173193
{
174-
std::shared_ptr<MockEC2MetadataClient> mockClient = Aws::MakeShared<MockEC2MetadataClient>(ALLOCATION_TAG);
175-
mockClient->SetCurrentRegionValue("us-east-1");
176-
mockClient->SetMockedCredentialsValue("{ \"AccessKeyId\": \"goodAccessKey\", \"SecretAccessKey\": \"goodSecretKey\", \"Token\": \"goodToken\" }");
194+
TempFile configFile(std::ios_base::out | std::ios_base::trunc);
177195

178-
EC2InstanceProfileConfigLoader loader(mockClient);
196+
ASSERT_TRUE(configFile.good());
197+
static const Aws::String SSO_AWS_PROFILE = "AwsSdkBearerIntegrationTest-profile"; // arbitrary
198+
Aws::String profileFileName = configFile.GetFileName().find_last_of(R"(/\)") == std::string::npos ?
199+
configFile.GetFileName() : configFile.GetFileName().substr(configFile.GetFileName().find_last_of(R"(/\)"));
200+
static const Aws::String SSO_SESSION_NAME = profileFileName + "-sso-session"; // arbitrary
201+
ASSERT_TRUE(WriteConfigFileWithSSO(configFile, SSO_AWS_PROFILE, SSO_SESSION_NAME));
202+
203+
AWSConfigFileProfileConfigLoader loader(configFile.GetFileName());
179204
ASSERT_TRUE(loader.Load());
180-
ASSERT_EQ(1u, loader.GetProfiles().size());
181205
auto profiles = loader.GetProfiles();
182-
ASSERT_NE(profiles.end(), profiles.find(Aws::Config::INSTANCE_PROFILE_KEY));
183-
auto creds = profiles[Aws::Config::INSTANCE_PROFILE_KEY].GetCredentials();
184-
ASSERT_STREQ("goodAccessKey", creds.GetAWSAccessKeyId().c_str());
185-
ASSERT_STREQ("goodSecretKey", creds.GetAWSSecretKey().c_str());
186-
ASSERT_STREQ("goodToken", creds.GetSessionToken().c_str());
187-
ASSERT_STREQ("us-east-1", profiles[Aws::Config::INSTANCE_PROFILE_KEY].GetRegion().c_str());
206+
207+
ASSERT_EQ(3u, profiles.size());
208+
ASSERT_NE(profiles.end(), profiles.find("default"));
209+
ASSERT_NE(profiles.end(), profiles.find("custom-profile"));
210+
ASSERT_NE(profiles.end(), profiles.find(SSO_AWS_PROFILE));
211+
212+
const auto ssoProfile = profiles.at(SSO_AWS_PROFILE);
213+
ASSERT_EQ(SSO_AWS_PROFILE, ssoProfile.GetName());
214+
ASSERT_TRUE(ssoProfile.GetRegion().empty());
215+
ASSERT_TRUE(ssoProfile.GetCredentials().GetAWSSecretKey().empty() &&
216+
ssoProfile.GetCredentials().GetAWSAccessKeyId().empty() &&
217+
ssoProfile.GetCredentials().GetSessionToken().empty());
218+
ASSERT_TRUE(ssoProfile.GetSourceProfile().empty());
219+
ASSERT_TRUE(ssoProfile.GetCredentialProcess().empty());
220+
221+
// Important: sso_session pointing to a sso-session section is a different entity than sso_* properties under [profile] section
222+
ASSERT_TRUE(ssoProfile.GetSsoStartUrl().empty() &&
223+
ssoProfile.GetSsoRegion().empty() &&
224+
ssoProfile.GetSsoAccountId().empty() &&
225+
ssoProfile.GetSsoRoleName().empty());
226+
227+
ASSERT_TRUE(ssoProfile.GetDefaultsMode().empty());
228+
229+
// here is [sso-session] section name that is linked by [profile] by a property "sso_session=<SSO_SESSION_NAME>" under [profile]
230+
ASSERT_EQ(SSO_SESSION_NAME, ssoProfile.GetSsoSession().GetName());
231+
ASSERT_EQ("us-east-1", ssoProfile.GetSsoSession().GetSsoRegion());
232+
ASSERT_EQ("https://d-abc123.awsapps.com/start", ssoProfile.GetSsoSession().GetSsoStartUrl());
188233
}
189234

190-
TEST(EC2InstanceProfileConfigLoaderTest, TestFailsToHitService)
235+
TEST(AWSConfigFileProfileConfigLoaderTest, TestProfileDumping)
191236
{
192-
std::shared_ptr<MockEC2MetadataClient> mockClient = Aws::MakeShared<MockEC2MetadataClient>(ALLOCATION_TAG);
193-
mockClient->SetCurrentRegionValue("");
194-
mockClient->SetMockedCredentialsValue("");
237+
TempFile configFile(std::ios_base::out | std::ios_base::trunc);
195238

196-
EC2InstanceProfileConfigLoader loader(mockClient);
197-
ASSERT_FALSE(loader.Load());
198-
ASSERT_EQ(0u, loader.GetProfiles().size());
199-
}
239+
ASSERT_TRUE(configFile.good());
240+
static const Aws::String SSO_AWS_PROFILE = "AwsSdkBearerIntegrationTest-profile"; // arbitrary
241+
Aws::String profileFileName = configFile.GetFileName().find_last_of(R"(/\)") == std::string::npos ?
242+
configFile.GetFileName() : configFile.GetFileName().substr(configFile.GetFileName().find_last_of(R"(/\)"));
243+
static const Aws::String SSO_SESSION_NAME = profileFileName + "-sso-session"; // arbitrary
244+
ASSERT_TRUE(WriteConfigFileWithSSO(configFile, SSO_AWS_PROFILE, SSO_SESSION_NAME));
245+
246+
class TEST_HELPER_AWSConfigFileProfileConfigLoader : public AWSConfigFileProfileConfigLoader
247+
{
248+
public:
249+
TEST_HELPER_AWSConfigFileProfileConfigLoader(const Aws::String& fileName)
250+
: AWSConfigFileProfileConfigLoader(fileName, /*useProfilePrefix*/true)
251+
{}
252+
253+
bool Public_PersistInternal(const Aws::Map<Aws::String, Aws::Config::Profile>& profiles)
254+
{
255+
return this->PersistInternal(profiles);
256+
}
257+
};
258+
259+
// Parse static test profile config
260+
AWSConfigFileProfileConfigLoader loader(configFile.GetFileName());
261+
ASSERT_TRUE(loader.Load());
262+
auto initiallyReadProfiles = loader.GetProfiles();
200263

201-
TEST(EC2InstanceProfileConfigLoaderTest, TestBadJsonInResponse)
202-
{
203-
std::shared_ptr<MockEC2MetadataClient> mockClient = Aws::MakeShared<MockEC2MetadataClient>(ALLOCATION_TAG);
204-
mockClient->SetCurrentRegionValue("us-east-1");
205-
mockClient->SetMockedCredentialsValue("{ \"AccessKeyId\": \"goodAccessKey\",");
264+
// Dump parsed test profile config
265+
TempFile dumpedConfigFile(std::ios_base::out | std::ios_base::trunc);
266+
ASSERT_TRUE(dumpedConfigFile.good());
267+
TEST_HELPER_AWSConfigFileProfileConfigLoader dumper(dumpedConfigFile.GetFileName());
268+
dumper.Public_PersistInternal(initiallyReadProfiles);
206269

207-
EC2InstanceProfileConfigLoader loader(mockClient);
208-
ASSERT_FALSE(loader.Load());
209-
ASSERT_EQ(0u, loader.GetProfiles().size());
270+
// Parse dumped test profile config
271+
AWSConfigFileProfileConfigLoader loaderOfDumped(dumpedConfigFile.GetFileName());
272+
ASSERT_TRUE(loaderOfDumped.Load());
273+
auto profiles = loaderOfDumped.GetProfiles();
274+
275+
// Repeat validation from a previous test
276+
ASSERT_EQ(3u, profiles.size());
277+
ASSERT_NE(profiles.end(), profiles.find("default"));
278+
ASSERT_NE(profiles.end(), profiles.find("custom-profile"));
279+
ASSERT_NE(profiles.end(), profiles.find(SSO_AWS_PROFILE));
280+
281+
const auto ssoProfile = profiles.at(SSO_AWS_PROFILE);
282+
ASSERT_EQ(SSO_AWS_PROFILE, ssoProfile.GetName());
283+
ASSERT_TRUE(ssoProfile.GetRegion().empty());
284+
ASSERT_TRUE(ssoProfile.GetCredentials().GetAWSSecretKey().empty() &&
285+
ssoProfile.GetCredentials().GetAWSAccessKeyId().empty() &&
286+
ssoProfile.GetCredentials().GetSessionToken().empty());
287+
ASSERT_TRUE(ssoProfile.GetSourceProfile().empty());
288+
ASSERT_TRUE(ssoProfile.GetCredentialProcess().empty());
289+
290+
// Important: sso_session pointing to a sso-session section is a different entity than sso_* properties under [profile] section
291+
ASSERT_TRUE(ssoProfile.GetSsoStartUrl().empty() &&
292+
ssoProfile.GetSsoRegion().empty() &&
293+
ssoProfile.GetSsoAccountId().empty() &&
294+
ssoProfile.GetSsoRoleName().empty());
295+
296+
ASSERT_TRUE(ssoProfile.GetDefaultsMode().empty());
297+
298+
// here is [sso-session] section name that is linked by [profile] by a property "sso_session=<SSO_SESSION_NAME>" under [profile]
299+
ASSERT_EQ(SSO_SESSION_NAME, ssoProfile.GetSsoSession().GetName());
300+
ASSERT_EQ("us-east-1", ssoProfile.GetSsoSession().GetSsoRegion());
301+
ASSERT_EQ("https://d-abc123.awsapps.com/start", ssoProfile.GetSsoSession().GetSsoStartUrl());
210302
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
#include <gtest/gtest.h>
6+
#include <aws/core/config/AWSProfileConfigLoader.h>
7+
#include <aws/testing/mocks/aws/auth/MockAWSHttpResourceClient.h>
8+
#include <fstream>
9+
10+
using namespace Aws::Utils;
11+
using namespace Aws::Config;
12+
13+
static const char* const ALLOCATION_TAG = "EC2InstanceProfileConfigLoaderTest";
14+
15+
TEST(EC2InstanceProfileConfigLoaderTest, TestSuccesfullyHitsService)
16+
{
17+
std::shared_ptr<MockEC2MetadataClient> mockClient = Aws::MakeShared<MockEC2MetadataClient>(ALLOCATION_TAG);
18+
mockClient->SetCurrentRegionValue("us-east-1");
19+
mockClient->SetMockedCredentialsValue("{ \"AccessKeyId\": \"goodAccessKey\", \"SecretAccessKey\": \"goodSecretKey\", \"Token\": \"goodToken\" }");
20+
21+
EC2InstanceProfileConfigLoader loader(mockClient);
22+
ASSERT_TRUE(loader.Load());
23+
ASSERT_EQ(1u, loader.GetProfiles().size());
24+
auto profiles = loader.GetProfiles();
25+
ASSERT_NE(profiles.end(), profiles.find(Aws::Config::INSTANCE_PROFILE_KEY));
26+
auto creds = profiles[Aws::Config::INSTANCE_PROFILE_KEY].GetCredentials();
27+
ASSERT_STREQ("goodAccessKey", creds.GetAWSAccessKeyId().c_str());
28+
ASSERT_STREQ("goodSecretKey", creds.GetAWSSecretKey().c_str());
29+
ASSERT_STREQ("goodToken", creds.GetSessionToken().c_str());
30+
ASSERT_STREQ("us-east-1", profiles[Aws::Config::INSTANCE_PROFILE_KEY].GetRegion().c_str());
31+
}
32+
33+
TEST(EC2InstanceProfileConfigLoaderTest, TestFailsToHitService)
34+
{
35+
std::shared_ptr<MockEC2MetadataClient> mockClient = Aws::MakeShared<MockEC2MetadataClient>(ALLOCATION_TAG);
36+
mockClient->SetCurrentRegionValue("");
37+
mockClient->SetMockedCredentialsValue("");
38+
39+
EC2InstanceProfileConfigLoader loader(mockClient);
40+
ASSERT_FALSE(loader.Load());
41+
ASSERT_EQ(0u, loader.GetProfiles().size());
42+
}
43+
44+
TEST(EC2InstanceProfileConfigLoaderTest, TestBadJsonInResponse)
45+
{
46+
std::shared_ptr<MockEC2MetadataClient> mockClient = Aws::MakeShared<MockEC2MetadataClient>(ALLOCATION_TAG);
47+
mockClient->SetCurrentRegionValue("us-east-1");
48+
mockClient->SetMockedCredentialsValue("{ \"AccessKeyId\": \"goodAccessKey\",");
49+
50+
EC2InstanceProfileConfigLoader loader(mockClient);
51+
ASSERT_FALSE(loader.Load());
52+
ASSERT_EQ(0u, loader.GetProfiles().size());
53+
}

aws-cpp-sdk-core/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ file(GLOB AWS_HEADERS "include/aws/core/*.h")
4545
file(GLOB AWS_AUTH_HEADERS "include/aws/core/auth/*.h")
4646
file(GLOB AWS_AUTH_SIGNER_HEADERS "include/aws/core/auth/signer/*.h")
4747
file(GLOB AWS_AUTH_SIGNER_PROVIDER_HEADERS "include/aws/core/auth/signer-provider/*.h")
48+
file(GLOB AWS_AUTH_BEARER_TOKEN_PROVIDER_HEADERS "include/aws/core/auth/bearer-token-provider*.h")
4849
file(GLOB AWS_CLIENT_HEADERS "include/aws/core/client/*.h")
4950
file(GLOB AWS_INTERNAL_HEADERS "include/aws/core/internal/*.h")
5051
file(GLOB NET_HEADERS "include/aws/core/net/*.h")
@@ -75,6 +76,7 @@ file(GLOB CJSON_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source/external/cjson/*.cpp"
7576
file(GLOB AWS_AUTH_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source/auth/*.cpp")
7677
file(GLOB AWS_AUTH_SIGNER_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source/auth/signer/*.cpp")
7778
file(GLOB AWS_AUTH_SIGNER_PROVIDER_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source/auth/signer-provider/*.cpp")
79+
file(GLOB AWS_AUTH_BEARER_TOKEN_PROVIDER_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source/auth/bearer-token-provider/*.cpp")
7880
file(GLOB AWS_CLIENT_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source/client/*.cpp")
7981
file(GLOB AWS_INTERNAL_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source/internal/*.cpp")
8082
file(GLOB AWS_MODEL_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source/aws/model/*.cpp")
@@ -219,6 +221,7 @@ file(GLOB AWS_NATIVE_SDK_COMMON_SRC
219221
${AWS_AUTH_SOURCE}
220222
${AWS_AUTH_SIGNER_SOURCE}
221223
${AWS_AUTH_SIGNER_PROVIDER_SOURCE}
224+
${AWS_AUTH_BEARER_TOKEN_PROVIDER_SOURCE}
222225
${AWS_CLIENT_SOURCE}
223226
${HTTP_STANDARD_SOURCE}
224227
${HTTP_CLIENT_SOURCE}
@@ -241,6 +244,7 @@ file(GLOB AWS_NATIVE_SDK_COMMON_HEADERS
241244
${AWS_AUTH_HEADERS}
242245
${AWS_AUTH_SIGNER_HEADERS}
243246
${AWS_AUTH_SIGNER_PROVIDER_HEADERS}
247+
${AWS_AUTH_BEARER_TOKEN_PROVIDER_HEADERS}
244248
${AWS_CLIENT_HEADERS}
245249
${AWS_INTERNAL_HEADERS}
246250
${NET_HEADERS}
@@ -355,6 +359,7 @@ if(MSVC)
355359
source_group("Header Files\\aws\\core\\auth" FILES ${AWS_AUTH_HEADERS})
356360
source_group("Header Files\\aws\\core\\auth\\signer" FILES ${AWS_AUTH_SIGNER_HEADERS})
357361
source_group("Header Files\\aws\\core\\auth\\signer-provider" FILES ${AWS_AUTH_SIGNER_PROVIDER_HEADERS})
362+
source_group("Header Files\\aws\\core\\auth\\bearer-token-provider" FILES ${AWS_AUTH_BEARER_TOKEN_PROVIDER_HEADERS})
358363
source_group("Header Files\\aws\\core\\client" FILES ${AWS_CLIENT_HEADERS})
359364
source_group("Header Files\\aws\\core\\internal" FILES ${AWS_INTERNAL_HEADERS})
360365
source_group("Header Files\\aws\\core\\net" FILES ${NET_HEADERS})
@@ -402,6 +407,7 @@ if(MSVC)
402407
source_group("Source Files\\auth" FILES ${AWS_AUTH_SOURCE})
403408
source_group("Source Files\\auth\\signer" FILES ${AWS_AUTH_SIGNER_SOURCE})
404409
source_group("Source Files\\auth\\signer-provider" FILES ${AWS_AUTH_SIGNER_PROVIDER_SOURCE})
410+
source_group("Source Files\\auth\\bearer-token-provider" FILES ${AWS_AUTH_BEARER_TOKEN_PROVIDER_SOURCE})
405411
source_group("Source Files\\client" FILES ${AWS_CLIENT_SOURCE})
406412
source_group("Source Files\\internal" FILES ${AWS_INTERNAL_SOURCE})
407413
source_group("Source Files\\net\\windows" FILES ${NET_SOURCE})
@@ -571,6 +577,7 @@ install (FILES ${AWS_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/aws/core)
571577
install (FILES ${AWS_AUTH_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/aws/core/auth)
572578
install (FILES ${AWS_AUTH_SIGNER_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/aws/core/auth/signer)
573579
install (FILES ${AWS_AUTH_SIGNER_PROVIDER_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/aws/core/auth/signer-provider)
580+
install (FILES ${AWS_AUTH_BEARER_TOKEN_PROVIDER_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/aws/core/auth/bearer-token-provider)
574581
install (FILES ${AWS_CLIENT_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/aws/core/client)
575582
install (FILES ${AWS_INTERNAL_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/aws/core/internal)
576583
install (FILES ${NET_HEADERS} DESTINATION ${INCLUDE_DIRECTORY}/aws/core/net)

aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSignerProvider.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88

99
#include <aws/core/auth/signer-provider/AWSAuthSignerProviderBase.h>
1010
#include <aws/core/auth/signer-provider/DefaultAuthSignerProvider.h>
11+
#include <aws/core/auth/signer-provider/BearerTokenAuthSignerProvider.h>
1112

1213
// This is a header that represents old legacy all-in-one header to maintain backward compatibility

0 commit comments

Comments
 (0)