-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Adding CRTProfileCredentialsProvider for CRT-based profile credential #3713
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
c14eda9
3dcacf1
288b730
3a600b2
0d459ee
5eb8769
444c9d8
2f38818
da5b2f0
65e5eb9
621afbf
00e8616
69959c7
233c9c0
d2bca9f
ed61b12
575f570
8a7967c
29b61af
dd2dc8e
1b0c159
01057cd
bb2223e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| #pragma once | ||
|
|
||
| #include <aws/core/Core_EXPORTS.h> | ||
| #include <aws/core/auth/AWSCredentialsProvider.h> | ||
| //#include <aws/core/auth/AWSCredentials.h> | ||
| //#include <aws/crt/auth/Credentials.h> | ||
| #include <memory> | ||
|
|
||
| namespace Aws | ||
| { | ||
| namespace Auth | ||
| { | ||
| /** | ||
| * CRT-based credentials provider that sources credentials from config files with full SEP compliance. | ||
| * Supports assume role, credential_source, role chaining, and all SEP scenarios. | ||
| */ | ||
| class AWS_CORE_API CRTProfileCredentialsProvider : public AWSCredentialsProvider | ||
| { | ||
| public: | ||
| CRTProfileCredentialsProvider(); | ||
| explicit CRTProfileCredentialsProvider(const char* profileName); | ||
| ~CRTProfileCredentialsProvider(); | ||
|
|
||
| CRTProfileCredentialsProvider(const CRTProfileCredentialsProvider&) = delete; | ||
| CRTProfileCredentialsProvider& operator=(const CRTProfileCredentialsProvider&) = delete; | ||
|
|
||
| AWSCredentials GetAWSCredentials() override; | ||
|
|
||
| protected: | ||
| void Reload() override; | ||
|
|
||
| private: | ||
| class Impl; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So when trying to do pimpl with the profile credentials provider i see it more so going like this. In the real profile credentials provider class AWS_CORE_API ProfileConfigFileAWSCredentialsProvider : public AWSCredentialsProvider
{
public:
ProfileConfigFileAWSCredentialsProvider(long refreshRateMs = REFRESH_THRESHOLD);
ProfileConfigFileAWSCredentialsProvider(const char* profile, long refreshRateMs = REFRESH_THRESHOLD);
AWSCredentials GetAWSCredentials() override;
static Aws::String GetCredentialsProfileFilename();
static Aws::String GetProfileDirectory();
protected:
void Reload() override;
private:
void RefreshIfExpired();
Aws::String m_profileToUse;
Aws::Config::AWSConfigFileProfileConfigLoader m_credentialsFileLoader;
long m_loadFrequencyMs;
};becomes class ProfileCredentialsProviderImpl;
class AWS_CORE_API ProfileConfigFileAWSCredentialsProvider : public AWSCredentialsProvider
{
public:
ProfileConfigFileAWSCredentialsProvider(long refreshRateMs = REFRESH_THRESHOLD);
ProfileConfigFileAWSCredentialsProvider(const char* profile, long refreshRateMs = REFRESH_THRESHOLD);
AWSCredentials GetAWSCredentials() override;
static Aws::String GetCredentialsProfileFilename();
static Aws::String GetProfileDirectory();
protected:
void Reload() override;
Aws::UniquePtr<ProfileCredentialsProviderImpl> m_impl;
};then in the cpp file for for That is step one to move the existing credentials provider to PIMPL. Then step two is your change, So: |
||
| std::shared_ptr<Impl> m_impl; | ||
| }; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| #include <aws/core/auth/CRTProfileCredentialsProvider.h> | ||
| #include <aws/core/Globals.h> | ||
| #include <aws/core/platform/Environment.h> | ||
| #include <condition_variable> | ||
| #include <mutex> | ||
| #include <aws/crt/auth/Credentials.h> | ||
|
|
||
| using namespace Aws::Auth; | ||
|
|
||
| class CRTProfileCredentialsProvider::Impl { | ||
| public: | ||
| std::shared_ptr<Aws::Crt::Auth::ICredentialsProvider> m_crtProvider; | ||
| }; | ||
|
|
||
| CRTProfileCredentialsProvider::CRTProfileCredentialsProvider() | ||
| : m_impl(Aws::MakeShared<Impl>("CRTProfileCredentialsProvider")){ | ||
| Aws::Crt::Auth::CredentialsProviderProfileConfig config{}; | ||
| config.Bootstrap = GetDefaultClientBootstrap(); | ||
| auto profileName = Aws::Environment::GetEnv("AWS_PROFILE"); | ||
| if(!profileName.empty()){ | ||
| config.ProfileNameOverride = Aws::Crt::ByteCursorFromCString(profileName.c_str()); | ||
| } | ||
| m_impl->m_crtProvider = Aws::Crt::Auth::CredentialsProvider::CreateCredentialsProviderProfile(config); | ||
| } | ||
|
|
||
| CRTProfileCredentialsProvider::CRTProfileCredentialsProvider(const char *profileName) | ||
| :m_impl(Aws::MakeShared<Impl>("CRTProfileCredentialsProvider")){ | ||
| Aws::Crt::Auth::CredentialsProviderProfileConfig config{}; | ||
| config.Bootstrap = GetDefaultClientBootstrap(); | ||
| if (profileName) { | ||
| config.ProfileNameOverride = Aws::Crt::ByteCursorFromCString(profileName); | ||
| } | ||
| m_impl->m_crtProvider = Aws::Crt::Auth::CredentialsProvider::CreateCredentialsProviderProfile(config); | ||
| } | ||
|
|
||
| CRTProfileCredentialsProvider::~CRTProfileCredentialsProvider() = default; | ||
|
|
||
| AWSCredentials CRTProfileCredentialsProvider::GetAWSCredentials() { | ||
| if (!m_impl || !m_impl->m_crtProvider) { | ||
| return AWSCredentials{}; | ||
| } | ||
| AWSCredentials credentials; | ||
| std::mutex mtx; | ||
| std::condition_variable cv; | ||
| bool done = false; | ||
|
|
||
| m_impl->m_crtProvider->GetCredentials([&](std::shared_ptr<Aws::Crt::Auth::Credentials> crtCreds, int errorCode) { | ||
| { | ||
| std::lock_guard<std::mutex> lock(mtx); | ||
| if (errorCode == 0 && crtCreds) { | ||
| auto accessKey = crtCreds->GetAccessKeyId(); | ||
| auto secretKey = crtCreds->GetSecretAccessKey(); | ||
| auto sessionToken = crtCreds->GetSessionToken(); | ||
|
|
||
| credentials.SetAWSAccessKeyId({reinterpret_cast<char*>(accessKey.ptr), accessKey.len}); | ||
| credentials.SetAWSSecretKey({reinterpret_cast<char*>(secretKey.ptr), secretKey.len}); | ||
| if (sessionToken.len > 0) { | ||
| credentials.SetSessionToken({reinterpret_cast<char*>(sessionToken.ptr), sessionToken.len}); | ||
| } | ||
| auto expiration = crtCreds->GetExpirationTimepointInSeconds(); | ||
| if (expiration > 0) { | ||
| credentials.SetExpiration(Aws::Utils::DateTime(static_cast<double>(expiration))); | ||
| } | ||
| } | ||
| done = true; | ||
| } | ||
| cv.notify_one(); | ||
| }); | ||
|
|
||
| std::unique_lock<std::mutex> lock(mtx); | ||
| cv.wait_for(lock,std::chrono::milliseconds(5000), [&done]() -> bool { return done;}); | ||
| return credentials; | ||
| } | ||
|
|
||
| void CRTProfileCredentialsProvider::Reload() {} | ||
|
|
||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| #include <aws/core/auth/CRTProfileCredentialsProvider.h> | ||
| #include <aws/core/platform/Environment.h> | ||
| #include <aws/core/platform/FileSystem.h> | ||
| #include <aws/core/utils/FileSystemUtils.h> | ||
| #include <aws/testing/AwsCppSdkGTestSuite.h> | ||
| #include <fstream> | ||
|
|
||
| using namespace Aws::Auth; | ||
|
|
||
| class CRTProfileCredentialsProviderTest : public Aws::Testing::AwsCppSdkGTestSuite { | ||
| protected: | ||
| void SetUp() override { | ||
| SaveEnv("AWS_CONFIG_FILE"); | ||
| SaveEnv("AWS_SHARED_CREDENTIALS_FILE"); | ||
| SaveEnv("AWS_PROFILE"); | ||
|
|
||
| Aws::FileSystem::CreateDirectoryIfNotExists(GetTestDir().c_str()); | ||
| m_configFile = GetTestDir() + "/config"; | ||
| m_credsFile = GetTestDir() + "/credentials"; | ||
|
|
||
| Aws::Environment::SetEnv("AWS_CONFIG_FILE", m_configFile.c_str(), 1); | ||
| Aws::Environment::SetEnv("AWS_SHARED_CREDENTIALS_FILE", m_credsFile.c_str(), 1); | ||
| } | ||
|
|
||
| void TearDown() override { | ||
| Aws::FileSystem::RemoveFileIfExists(m_configFile.c_str()); | ||
| Aws::FileSystem::RemoveFileIfExists(m_credsFile.c_str()); | ||
| RestoreEnv(); | ||
| } | ||
|
|
||
| void SaveEnv(const char* name) { | ||
| m_savedEnv.emplace_back(name, Aws::Environment::GetEnv(name)); | ||
| } | ||
|
|
||
| void RestoreEnv() { | ||
| for (const auto& pair : m_savedEnv) { | ||
| if (pair.second.empty()) { | ||
| Aws::Environment::UnSetEnv(pair.first); | ||
| } else { | ||
| Aws::Environment::SetEnv(pair.first, pair.second.c_str(), 1); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Aws::String GetTestDir() { | ||
| return Aws::FileSystem::GetHomeDirectory() + "/.aws_test_" + | ||
| Aws::Utils::StringUtils::to_string(std::this_thread::get_id()); | ||
| } | ||
|
|
||
| Aws::String m_configFile; | ||
| Aws::String m_credsFile; | ||
| Aws::Vector<std::pair<const char*, Aws::String>> m_savedEnv; | ||
| }; | ||
|
|
||
| TEST_F(CRTProfileCredentialsProviderTest, LoadStaticCredentials) { | ||
| std::ofstream creds(m_credsFile.c_str()); | ||
| creds << "[default]\n"; | ||
| creds << "aws_access_key_id = AKIATEST123\n"; | ||
| creds << "aws_secret_access_key = SecretKey456\n"; | ||
| creds.close(); | ||
|
|
||
| CRTProfileCredentialsProvider provider; | ||
| auto credentials = provider.GetAWSCredentials(); | ||
|
|
||
| EXPECT_STREQ("AKIATEST123", credentials.GetAWSAccessKeyId().c_str()); | ||
| EXPECT_STREQ("SecretKey456", credentials.GetAWSSecretKey().c_str()); | ||
| } | ||
|
|
||
| TEST_F(CRTProfileCredentialsProviderTest, LoadNamedProfile) { | ||
| std::ofstream creds(m_credsFile.c_str()); | ||
| creds << "[default]\n"; | ||
| creds << "aws_access_key_id = DefaultKey\n"; | ||
| creds << "aws_secret_access_key = DefaultSecret\n"; | ||
| creds << "\n"; | ||
| creds << "[test-profile]\n"; | ||
| creds << "aws_access_key_id = TestKey\n"; | ||
| creds << "aws_secret_access_key = TestSecret\n"; | ||
| creds.close(); | ||
|
|
||
| CRTProfileCredentialsProvider provider("test-profile"); | ||
| auto credentials = provider.GetAWSCredentials(); | ||
|
|
||
| EXPECT_STREQ("TestKey", credentials.GetAWSAccessKeyId().c_str()); | ||
| EXPECT_STREQ("TestSecret", credentials.GetAWSSecretKey().c_str()); | ||
| } | ||
|
|
||
| TEST_F(CRTProfileCredentialsProviderTest, LoadWithSessionToken) { | ||
| std::ofstream creds(m_credsFile.c_str()); | ||
| creds << "[default]\n"; | ||
| creds << "aws_access_key_id = AKIATEST\n"; | ||
| creds << "aws_secret_access_key = SecretKey\n"; | ||
| creds << "aws_session_token = SessionToken123\n"; | ||
| creds.close(); | ||
|
|
||
| CRTProfileCredentialsProvider provider; | ||
| auto credentials = provider.GetAWSCredentials(); | ||
|
|
||
| EXPECT_STREQ("AKIATEST", credentials.GetAWSAccessKeyId().c_str()); | ||
| EXPECT_STREQ("SecretKey", credentials.GetAWSSecretKey().c_str()); | ||
| EXPECT_STREQ("SessionToken123", credentials.GetSessionToken().c_str()); | ||
| } | ||
|
|
||
| TEST_F(CRTProfileCredentialsProviderTest, MissingProfileReturnsEmpty) { | ||
| std::ofstream creds(m_credsFile.c_str()); | ||
| creds << "[default]\n"; | ||
| creds << "aws_access_key_id = DefaultKey\n"; | ||
| creds << "aws_secret_access_key = DefaultSecret\n"; | ||
| creds.close(); | ||
|
|
||
| CRTProfileCredentialsProvider provider("nonexistent"); | ||
| auto credentials = provider.GetAWSCredentials(); | ||
|
|
||
| EXPECT_TRUE(credentials.IsEmpty()); | ||
| } | ||
|
|
||
| TEST_F(CRTProfileCredentialsProviderTest, ProcessCredentials) { | ||
| std::ofstream config(m_configFile.c_str()); | ||
| config << "[default]\n"; | ||
| config << "credential_process = echo '{\"Version\": 1, \"AccessKeyId\": \"ProcessKey\", \"SecretAccessKey\": \"ProcessSecret\"}'\n"; | ||
| config.close(); | ||
|
|
||
| CRTProfileCredentialsProvider provider; | ||
| auto credentials = provider.GetAWSCredentials(); | ||
|
|
||
| EXPECT_STREQ("ProcessKey", credentials.GetAWSAccessKeyId().c_str()); | ||
| EXPECT_STREQ("ProcessSecret", credentials.GetAWSSecretKey().c_str()); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets not name this
CRTProfileCredentialsProviderbecause its just going to be the newProfileCredentialsProvider. lets just name itProfileCredentialsProvider. also please add aAWS_DEPRECATEDto the old class so that people using it directly will get a warning to update to the new one.