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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
#include <aws/core/utils/memory/stl/AWSString.h>
#include <aws/core/utils/threading/ReaderWriterLock.h>
#include <aws/core/internal/AWSHttpResourceClient.h>
#include <aws/core/auth/CredentialRefreshResult.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/core/config/AWSProfileConfigLoader.h>
#include <aws/core/client/RetryStrategy.h>
#include <memory>

namespace Aws
{
namespace Internal { class CredentialRefreshStateImpl; }
namespace Client
{
struct ClientConfiguration;
Expand Down Expand Up @@ -58,31 +60,51 @@ namespace Aws
class AWS_CORE_API AWSCredentialsProvider
{
public:
/**
* Initializes provider. Sets last Loaded time count to 0, forcing a refresh on the
* first call to GetAWSCredentials.
*/
AWSCredentialsProvider() : m_lastLoadedMs(0)
{
}
AWSCredentialsProvider();

virtual ~AWSCredentialsProvider() = default;
virtual ~AWSCredentialsProvider();

/**
* The core of the credential provider interface. Override this method to control how credentials are retrieved.
*/
virtual AWSCredentials GetAWSCredentials() = 0;

/**
* Marks cached credentials for refresh after a service rejects them (ExpiredToken/InvalidToken).
*/
virtual void Invalidate();

protected:
/**
* The default implementation keeps up with the cache times and lets you know if it's time to refresh your internal caching
* to aid your implementation of GetAWSCredentials.
*/
virtual bool IsTimeToRefresh(long reloadFrequency);
virtual void Reload();

/**
* One attempt against the credential source, classified fresh/recoverable/non-recoverable.
* Providers on the refresh lifecycle override this; the default returns a recoverable failure.
*/
virtual Aws::Auth::RefreshResult<AWSCredentials> FetchCredentialsFromSource();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so FetchCredentialsFromSource is a protected virtual function on AWSCredentialsProvider. so a inheriting class can override it. but FetchCredentialsFromSource is not used in the GetAWSCredentials as that is the method the SDK calls to fetch credentials. so how is the override actually planned on being used?


/**
* Runs the refresh lifecycle over FetchCredentialsFromSource(): windows, backoff, serve-last-good.
* Returns the resolved credentials, or empty when a refresh fails with nothing cached to serve.
* Intended for a provider's GetAWSCredentials() to call once it adopts the lifecycle under
* AWS_NEW_CREDENTIAL_REFRESH_2026.
*/
AWSCredentials ResolveCredentialsWithLifecycle();

/**
* Clock for the refresh windows/backoff; defaults to the system clock, overridable for tests.
*/
virtual Aws::Utils::DateTime CurrentTime() const;

mutable Aws::Utils::Threading::ReaderWriterLock m_reloadLock;
private:
long long m_lastLoadedMs;
std::unique_ptr<Aws::Internal::CredentialRefreshStateImpl> m_refreshState;
};

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/

#pragma once

#include <aws/core/Core_EXPORTS.h>
#include <aws/core/utils/DateTime.h>
#include <aws/core/utils/memory/stl/AWSString.h>
#include <aws/crt/Optional.h>
#include <utility>

namespace Aws
{
namespace Auth
{
// Result of one credential-source fetch: the return type of the FetchCredentialsFromSource() override
// contract, so it is public (the refresh engine that consumes it stays internal).
template<typename CredentialsT>
class RefreshResult
{
public:
enum class Status
{
Success, // fresh credentials obtained
Recoverable, // transient failure: back off and keep serving cache
NonRecoverable // will not succeed without customer action: raise + briefly cache the error
};

RefreshResult() = default;
RefreshResult(Status status, CredentialsT credentials, Aws::Crt::Optional<Aws::Utils::DateTime> expiration,
Aws::String errorMessage)
: status(status), credentials(std::move(credentials)),
expiration(std::move(expiration)), errorMessage(std::move(errorMessage)) {}

// Named constructors. Only Fresh() carries an expiration.
static RefreshResult Fresh(CredentialsT credentials, Aws::Utils::DateTime expiration)
{
return RefreshResult(Status::Success, std::move(credentials),
Aws::Crt::Optional<Aws::Utils::DateTime>(expiration), {});
}
static RefreshResult Recoverable(Aws::String errorMessage = {})
{
return RefreshResult(Status::Recoverable, CredentialsT{}, {}, std::move(errorMessage));
}
static RefreshResult NonRecoverable(Aws::String errorMessage)
{
return RefreshResult(Status::NonRecoverable, CredentialsT{}, {}, std::move(errorMessage));
}

Status status{Status::Recoverable};
CredentialsT credentials{};
Aws::Crt::Optional<Aws::Utils::DateTime> expiration; // engaged only when status == Success
Aws::String errorMessage;
};
} // namespace Auth
} // namespace Aws
Loading
Loading