* Add GetCredentialName()

* Update

* Undo accidental change

* Clang-format

* Call GetCredentialName() instead of using constant; Return in-place constructed name; Explicit tests for GetCredentialName()

* PR feedback

* constructor parameter + non-virtual GetCredentialName()

* Update sdk/core/azure-core/CMakeLists.txt

* Update sdk/identity/azure-identity/test/ut/client_secret_credential_test.cpp

* Update sdk/identity/azure-identity/test/ut/client_certificate_credential_test.cpp

* GCC and Clang warnings

* Promote ThrowIfNotSafeCmdLineInput() to private member; avoid copies when calling GetCredentialName()

* Spelling

* Fix deprecated usage

* Fix iteration

* Clang-format

---------

Co-authored-by: Anton Kolesnyk <antkmsft@users.noreply.github.com>
This commit is contained in:
Anton Kolesnyk 2023-03-14 16:46:10 -07:00 коммит произвёл GitHub
Родитель f0a26fd4ad
Коммит ef24dfda2e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
24 изменённых файлов: 292 добавлений и 109 удалений

Просмотреть файл

@ -31,6 +31,8 @@ namespace Azure { namespace Core { namespace Test {
class TestNonExpiringCredential final : public Core::Credentials::TokenCredential { class TestNonExpiringCredential final : public Core::Credentials::TokenCredential {
public: public:
TestNonExpiringCredential() : TokenCredential("TestNonExpiringCredential") {}
Core::Credentials::AccessToken GetToken( Core::Credentials::AccessToken GetToken(
Core::Credentials::TokenRequestContext const& tokenRequestContext, Core::Credentials::TokenRequestContext const& tokenRequestContext,
Core::Context const& context) const override Core::Context const& context) const override

Просмотреть файл

@ -6,6 +6,7 @@
- Added the ability to ignore invalid certificate common name for TLS connections in WinHTTP transport. - Added the ability to ignore invalid certificate common name for TLS connections in WinHTTP transport.
- Added `DisableTlsCertificateValidation` in `TransportOptions`. - Added `DisableTlsCertificateValidation` in `TransportOptions`.
- Added `TokenCredential::GetCredentialName()` to be utilized in diagnostic messages. If you have any custom implementations of `TokenCredential`, it is recommended to pass the name of your credential to `TokenCredential` constructor. The old parameterless constructor is deprecated.
### Breaking Changes ### Breaking Changes

Просмотреть файл

@ -60,6 +60,9 @@ namespace Azure { namespace Core { namespace Credentials {
* @brief A base type of credential that uses Azure::Core::AccessToken to authenticate requests. * @brief A base type of credential that uses Azure::Core::AccessToken to authenticate requests.
*/ */
class TokenCredential { class TokenCredential {
private:
std::string m_credentialName;
public: public:
/** /**
* @brief Gets an authentication token. * @brief Gets an authentication token.
@ -75,6 +78,12 @@ namespace Azure { namespace Core { namespace Credentials {
TokenRequestContext const& tokenRequestContext, TokenRequestContext const& tokenRequestContext,
Context const& context) const = 0; Context const& context) const = 0;
/**
* @brief Gets the name of the credential.
*
*/
std::string const& GetCredentialName() const { return m_credentialName; }
/** /**
* @brief Destructs `%TokenCredential`. * @brief Destructs `%TokenCredential`.
* *
@ -82,11 +91,25 @@ namespace Azure { namespace Core { namespace Credentials {
virtual ~TokenCredential() = default; virtual ~TokenCredential() = default;
protected: protected:
/**
* @brief Constructs an instance of `%TokenCredential`.
*
* @param credentialName Name of the credential for diagnostic messages.
*/
TokenCredential(std::string const& credentialName)
: m_credentialName(credentialName.empty() ? "Custom Credential" : credentialName)
{
}
/** /**
* @brief Constructs a default instance of `%TokenCredential`. * @brief Constructs a default instance of `%TokenCredential`.
* *
* @deprecated Use the constructor with parameter.
*/ */
TokenCredential() {} [[deprecated("Use the constructor with parameter.")]] TokenCredential()
: TokenCredential(std::string{})
{
}
private: private:
/** /**

Просмотреть файл

@ -16,7 +16,7 @@ private:
public: public:
explicit TestTokenCredential( explicit TestTokenCredential(
std::shared_ptr<Azure::Core::Credentials::AccessToken const> accessToken) std::shared_ptr<Azure::Core::Credentials::AccessToken const> accessToken)
: m_accessToken(accessToken) : TokenCredential("TestTokenCredential"), m_accessToken(accessToken)
{ {
} }

Просмотреть файл

@ -10,6 +10,8 @@
### Other Changes ### Other Changes
- Improved diagnostics to utilize `Azure::Core::Credentials::TokenCredential::GetCredentialName()`.
## 1.5.0-beta.1 (2023-03-07) ## 1.5.0-beta.1 (2023-03-07)
### Features Added ### Features Added

Просмотреть файл

@ -58,6 +58,8 @@ namespace Azure { namespace Identity {
DateTime::duration cliProcessTimeout, DateTime::duration cliProcessTimeout,
Core::Credentials::TokenCredentialOptions const& options); Core::Credentials::TokenCredentialOptions const& options);
void ThrowIfNotSafeCmdLineInput(std::string const& input, std::string const& description) const;
public: public:
/** /**
* @brief Constructs an Azure CLI Credential. * @brief Constructs an Azure CLI Credential.

Просмотреть файл

@ -62,13 +62,9 @@ namespace Azure { namespace Identity {
Core::Context const& context) const override; Core::Context const& context) const override;
private: private:
explicit ChainedTokenCredential( explicit ChainedTokenCredential(Sources sources, std::string const& enclosingCredential);
Sources sources,
std::string const& enclosingCredential,
std::vector<std::string> sourcesFriendlyNames);
Sources m_sources; Sources m_sources;
std::vector<std::string> m_sourcesFriendlyNames;
std::string m_logPrefix; std::string m_logPrefix;
}; };

Просмотреть файл

@ -51,9 +51,12 @@ using Azure::Identity::_detail::TokenCache;
using Azure::Identity::_detail::TokenCredentialImpl; using Azure::Identity::_detail::TokenCredentialImpl;
namespace { namespace {
std::string const MsgPrefix = "Identity: AzureCliCredential"; constexpr auto IdentityPrefix = "Identity: ";
}
void ThrowIfNotSafeCmdLineInput(std::string const& input, std::string const& description) void AzureCliCredential::ThrowIfNotSafeCmdLineInput(
std::string const& input,
std::string const& description) const
{ {
for (auto const c : input) for (auto const c : input)
{ {
@ -71,20 +74,21 @@ void ThrowIfNotSafeCmdLineInput(std::string const& input, std::string const& des
if (!std::isalnum(c, std::locale::classic())) if (!std::isalnum(c, std::locale::classic()))
{ {
throw AuthenticationException( throw AuthenticationException(
MsgPrefix + ": Unsafe command line input found in " + description + ": " + input); IdentityPrefix + GetCredentialName() + ": Unsafe command line input found in "
+ description + ": " + input);
} }
} }
} }
} }
} // namespace
AzureCliCredential::AzureCliCredential( AzureCliCredential::AzureCliCredential(
std::string tenantId, std::string tenantId,
DateTime::duration cliProcessTimeout, DateTime::duration cliProcessTimeout,
Core::Credentials::TokenCredentialOptions const& options) Core::Credentials::TokenCredentialOptions const& options)
: m_tenantId(std::move(tenantId)), m_cliProcessTimeout(std::move(cliProcessTimeout)) : TokenCredential("AzureCliCredential"), m_tenantId(std::move(tenantId)),
m_cliProcessTimeout(std::move(cliProcessTimeout))
{ {
static_cast<void>(options); static_cast<void>(options);
ThrowIfNotSafeCmdLineInput(m_tenantId, "TenantID"); ThrowIfNotSafeCmdLineInput(m_tenantId, "TenantID");
auto const logLevel = Logger::Level::Informational; auto const logLevel = Logger::Level::Informational;
@ -92,7 +96,7 @@ AzureCliCredential::AzureCliCredential(
{ {
Log::Write( Log::Write(
logLevel, logLevel,
MsgPrefix IdentityPrefix + GetCredentialName()
+ " created.\n" + " created.\n"
"Successful creation does not guarantee further successful token retrieval."); "Successful creation does not guarantee further successful token retrieval.");
} }
@ -161,7 +165,8 @@ AccessToken AzureCliCredential::GetToken(
} }
catch (std::exception const& e) catch (std::exception const& e)
{ {
auto const errorMsg = MsgPrefix + " didn't get the token: \"" + e.what() + '\"'; auto const errorMsg
= IdentityPrefix + GetCredentialName() + " didn't get the token: \"" + e.what() + '\"';
auto const logLevel = Logger::Level::Warning; auto const logLevel = Logger::Level::Warning;
if (Log::ShouldWrite(logLevel)) if (Log::ShouldWrite(logLevel))

Просмотреть файл

@ -4,7 +4,6 @@
#include "azure/identity/chained_token_credential.hpp" #include "azure/identity/chained_token_credential.hpp"
#include "azure/core/internal/diagnostics/log.hpp" #include "azure/core/internal/diagnostics/log.hpp"
#include <azure/core/azure_assert.hpp>
#include <utility> #include <utility>
@ -15,63 +14,53 @@ using Azure::Core::Diagnostics::Logger;
using Azure::Core::Diagnostics::_internal::Log; using Azure::Core::Diagnostics::_internal::Log;
namespace { namespace {
std::string const IdentityPrefix = "Identity: "; constexpr auto IdentityPrefix = "Identity: ";
} } // namespace
ChainedTokenCredential::ChainedTokenCredential(ChainedTokenCredential::Sources sources) ChainedTokenCredential::ChainedTokenCredential(ChainedTokenCredential::Sources sources)
: ChainedTokenCredential(sources, {}, {}) : ChainedTokenCredential(sources, {})
{ {
} }
ChainedTokenCredential::ChainedTokenCredential( ChainedTokenCredential::ChainedTokenCredential(
ChainedTokenCredential::Sources sources, ChainedTokenCredential::Sources sources,
std::string const& enclosingCredential, std::string const& enclosingCredential)
std::vector<std::string> sourcesFriendlyNames) : TokenCredential("ChainedTokenCredential"), m_sources(std::move(sources))
: m_sources(std::move(sources)), m_sourcesFriendlyNames(std::move(sourcesFriendlyNames))
{ {
// LCOV_EXCL_START m_logPrefix = IdentityPrefix
AZURE_ASSERT(m_sourcesFriendlyNames.empty() || m_sourcesFriendlyNames.size() == m_sources.size()); + (enclosingCredential.empty() ? GetCredentialName()
// LCOV_EXCL_STOP : (enclosingCredential + " -> " + GetCredentialName()))
+ ": ";
auto const logLevel = m_sources.empty() ? Logger::Level::Warning : Logger::Level::Informational; auto const logLevel = m_sources.empty() ? Logger::Level::Warning : Logger::Level::Informational;
if (Log::ShouldWrite(logLevel)) if (Log::ShouldWrite(logLevel))
{ {
std::string credentialsList; std::string credSourceDetails = " with EMPTY chain of credentials.";
if (!m_sourcesFriendlyNames.empty()) if (!m_sources.empty())
{ {
auto const sourceDescriptionsSize = m_sourcesFriendlyNames.size(); credSourceDetails = " with the following credentials: ";
for (size_t i = 0; i < (sourceDescriptionsSize - 1); ++i)
auto const sourcesSize = m_sources.size();
for (size_t i = 0; i < sourcesSize; ++i)
{ {
credentialsList += m_sourcesFriendlyNames[i] + ", "; if (i != 0)
{
credSourceDetails += ", ";
}
credSourceDetails += m_sources[i]->GetCredentialName();
} }
credentialsList += m_sourcesFriendlyNames.back(); credSourceDetails += '.';
} }
Log::Write( Log::Write(
logLevel, logLevel,
IdentityPrefix IdentityPrefix
+ (enclosingCredential.empty() + (enclosingCredential.empty()
? "ChainedTokenCredential: Created" ? (GetCredentialName() + ": Created")
: (enclosingCredential + ": Created ChainedTokenCredential")) : (enclosingCredential + ": Created " + GetCredentialName()))
+ " with " + credSourceDetails);
+ (m_sourcesFriendlyNames.empty()
? (std::to_string(m_sources.size()) + " credentials.")
: (std::string("the following credentials: ") + credentialsList + '.')));
}
m_logPrefix = IdentityPrefix
+ (enclosingCredential.empty() ? "ChainedTokenCredential"
: (enclosingCredential + " -> ChainedTokenCredential"))
+ ": ";
if (m_sourcesFriendlyNames.empty())
{
auto const sourcesSize = m_sources.size();
for (size_t i = 1; i <= sourcesSize; ++i)
{
m_sourcesFriendlyNames.push_back(std::string("credential #") + std::to_string(i));
}
} }
} }
@ -106,7 +95,8 @@ AccessToken ChainedTokenCredential::GetToken(
{ {
Log::Write( Log::Write(
logLevel, logLevel,
m_logPrefix + "Successfully got token from " + m_sourcesFriendlyNames[i] + '.'); m_logPrefix + "Successfully got token from " + m_sources[i]->GetCredentialName()
+ '.');
} }
} }
@ -120,7 +110,7 @@ AccessToken ChainedTokenCredential::GetToken(
{ {
Log::Write( Log::Write(
logLevel, logLevel,
m_logPrefix + "Failed to get token from " + m_sourcesFriendlyNames[i] + ": " m_logPrefix + "Failed to get token from " + m_sources[i]->GetCredentialName() + ": "
+ e.what()); + e.what());
} }
} }
@ -139,5 +129,5 @@ AccessToken ChainedTokenCredential::GetToken(
} }
} }
throw AuthenticationException("Failed to get token from ChainedTokenCredential."); throw AuthenticationException("Failed to get token from " + GetCredentialName() + '.');
} }

Просмотреть файл

@ -80,7 +80,8 @@ ClientCertificateCredential::ClientCertificateCredential(
std::string const& clientCertificatePath, std::string const& clientCertificatePath,
std::string const& authorityHost, std::string const& authorityHost,
TokenCredentialOptions const& options) TokenCredentialOptions const& options)
: m_clientCredentialCore(tenantId, authorityHost), : TokenCredential("ClientCertificateCredential"),
m_clientCredentialCore(tenantId, authorityHost),
m_tokenCredentialImpl(std::make_unique<TokenCredentialImpl>(options)), m_tokenCredentialImpl(std::make_unique<TokenCredentialImpl>(options)),
m_requestBody( m_requestBody(
std::string( std::string(

Просмотреть файл

@ -21,7 +21,7 @@ ClientSecretCredential::ClientSecretCredential(
std::string const& clientSecret, std::string const& clientSecret,
std::string const& authorityHost, std::string const& authorityHost,
TokenCredentialOptions const& options) TokenCredentialOptions const& options)
: m_clientCredentialCore(tenantId, authorityHost), : TokenCredential("ClientSecretCredential"), m_clientCredentialCore(tenantId, authorityHost),
m_tokenCredentialImpl(std::make_unique<TokenCredentialImpl>(options)), m_tokenCredentialImpl(std::make_unique<TokenCredentialImpl>(options)),
m_requestBody( m_requestBody(
std::string("grant_type=client_credentials&client_id=") + Url::Encode(clientId) std::string("grant_type=client_credentials&client_id=") + Url::Encode(clientId)

Просмотреть файл

@ -17,10 +17,11 @@ using Azure::Core::Diagnostics::Logger;
using Azure::Core::Diagnostics::_internal::Log; using Azure::Core::Diagnostics::_internal::Log;
namespace { namespace {
std::string const IdentityPrefix = "Identity: "; constexpr auto IdentityPrefix = "Identity: ";
} } // namespace
DefaultAzureCredential::DefaultAzureCredential(TokenCredentialOptions const& options) DefaultAzureCredential::DefaultAzureCredential(TokenCredentialOptions const& options)
: TokenCredential("DefaultAzureCredential")
{ {
// Initializing m_credential below and not in the member initializer list to have a specific order // Initializing m_credential below and not in the member initializer list to have a specific order
// of log messages. // of log messages.
@ -29,13 +30,16 @@ DefaultAzureCredential::DefaultAzureCredential(TokenCredentialOptions const& opt
{ {
Log::Write( Log::Write(
logLevel, logLevel,
IdentityPrefix std::string(IdentityPrefix) + "Creating " + GetCredentialName()
+ "Creating DefaultAzureCredential which combines mutiple parameterless credentials " + " which combines mutiple parameterless credentials "
"into a single one (by using ChainedTokenCredential)." "into a single one (by using ChainedTokenCredential).\n"
"\nDefaultAzureCredential is only recommended for the early stages of development, " + GetCredentialName()
+ " is only recommended for the early stages of development, "
"and not for usage in production environment." "and not for usage in production environment."
"\nOnce the developer focuses on the Credentials and Authentication aspects of their " "\nOnce the developer focuses on the Credentials and Authentication aspects "
"application, DefaultAzureCredential needs to be replaced with the credential that " "of their application, "
+ GetCredentialName()
+ " needs to be replaced with the credential that "
"is the better fit for the application."); "is the better fit for the application.");
} }
@ -47,9 +51,7 @@ DefaultAzureCredential::DefaultAzureCredential(TokenCredentialOptions const& opt
// Using the ChainedTokenCredential's private constructor for more detailed log messages. // Using the ChainedTokenCredential's private constructor for more detailed log messages.
m_credentials.reset(new ChainedTokenCredential( m_credentials.reset(new ChainedTokenCredential(
ChainedTokenCredential::Sources{envCred, azCliCred, managedIdentityCred}, ChainedTokenCredential::Sources{envCred, azCliCred, managedIdentityCred},
"DefaultAzureCredential", // extra args for the ChainedTokenCredential's private constructor. GetCredentialName())); // extra arg for the ChainedTokenCredential's private constructor.
std::vector<std::string>{
"EnvironmentCredential", "AzureCliCredential", "ManagedIdentityCredential"}));
} }
DefaultAzureCredential::~DefaultAzureCredential() = default; DefaultAzureCredential::~DefaultAzureCredential() = default;
@ -64,9 +66,10 @@ AccessToken DefaultAzureCredential::GetToken(
} }
catch (AuthenticationException const&) catch (AuthenticationException const&)
{ {
throw AuthenticationException("Failed to get token from DefaultAzureCredential." throw AuthenticationException(
"\nSee Azure::Core::Diagnostics::Logger for details " "Failed to get token from " + GetCredentialName()
"(https://github.com/Azure/azure-sdk-for-cpp/tree/main/sdk/" + ".\nSee Azure::Core::Diagnostics::Logger for details "
"identity/azure-identity#troubleshooting)."); "(https://github.com/Azure/azure-sdk-for-cpp/tree/main/sdk/"
"identity/azure-identity#troubleshooting).");
} }
} }

Просмотреть файл

@ -30,15 +30,19 @@ constexpr auto AzureClientSecretEnvVarName = "AZURE_CLIENT_SECRET";
constexpr auto AzureAuthorityHostEnvVarName = "AZURE_AUTHORITY_HOST"; constexpr auto AzureAuthorityHostEnvVarName = "AZURE_AUTHORITY_HOST";
constexpr auto AzureClientCertificatePathEnvVarName = "AZURE_CLIENT_CERTIFICATE_PATH"; constexpr auto AzureClientCertificatePathEnvVarName = "AZURE_CLIENT_CERTIFICATE_PATH";
std::string const LogMsgPrefix = "Identity: EnvironmentCredential"; constexpr auto IdentityPrefix = "Identity: ";
void PrintCredentialCreationLogMessage( void PrintCredentialCreationLogMessage(
std::string const& logMsgPrefix,
std::vector<std::pair<char const*, char const*>> const& envVarsToParams, std::vector<std::pair<char const*, char const*>> const& envVarsToParams,
char const* credThatGetsCreated); char const* credThatGetsCreated);
} // namespace } // namespace
EnvironmentCredential::EnvironmentCredential(TokenCredentialOptions options) EnvironmentCredential::EnvironmentCredential(TokenCredentialOptions options)
: TokenCredential("EnvironmentCredential")
{ {
auto const logMsgPrefix = IdentityPrefix + GetCredentialName();
auto tenantId = Environment::GetVariable(AzureTenantIdEnvVarName); auto tenantId = Environment::GetVariable(AzureTenantIdEnvVarName);
auto clientId = Environment::GetVariable(AzureClientIdEnvVarName); auto clientId = Environment::GetVariable(AzureClientIdEnvVarName);
@ -54,6 +58,7 @@ EnvironmentCredential::EnvironmentCredential(TokenCredentialOptions options)
if (!authority.empty()) if (!authority.empty())
{ {
PrintCredentialCreationLogMessage( PrintCredentialCreationLogMessage(
logMsgPrefix,
{ {
{AzureTenantIdEnvVarName, "tenantId"}, {AzureTenantIdEnvVarName, "tenantId"},
{AzureClientIdEnvVarName, "clientId"}, {AzureClientIdEnvVarName, "clientId"},
@ -72,6 +77,7 @@ EnvironmentCredential::EnvironmentCredential(TokenCredentialOptions options)
else else
{ {
PrintCredentialCreationLogMessage( PrintCredentialCreationLogMessage(
logMsgPrefix,
{ {
{AzureTenantIdEnvVarName, "tenantId"}, {AzureTenantIdEnvVarName, "tenantId"},
{AzureClientIdEnvVarName, "clientId"}, {AzureClientIdEnvVarName, "clientId"},
@ -88,6 +94,7 @@ EnvironmentCredential::EnvironmentCredential(TokenCredentialOptions options)
if (!authority.empty()) if (!authority.empty())
{ {
PrintCredentialCreationLogMessage( PrintCredentialCreationLogMessage(
logMsgPrefix,
{ {
{AzureTenantIdEnvVarName, "tenantId"}, {AzureTenantIdEnvVarName, "tenantId"},
{AzureClientIdEnvVarName, "clientId"}, {AzureClientIdEnvVarName, "clientId"},
@ -106,6 +113,7 @@ EnvironmentCredential::EnvironmentCredential(TokenCredentialOptions options)
else else
{ {
PrintCredentialCreationLogMessage( PrintCredentialCreationLogMessage(
logMsgPrefix,
{ {
{AzureTenantIdEnvVarName, "tenantId"}, {AzureTenantIdEnvVarName, "tenantId"},
{AzureClientIdEnvVarName, "clientId"}, {AzureClientIdEnvVarName, "clientId"},
@ -124,7 +132,7 @@ EnvironmentCredential::EnvironmentCredential(TokenCredentialOptions options)
auto const logLevel = Logger::Level::Warning; auto const logLevel = Logger::Level::Warning;
if (Log::ShouldWrite(logLevel)) if (Log::ShouldWrite(logLevel))
{ {
auto const basicMessage = LogMsgPrefix + " was not initialized with underlying credential"; auto const basicMessage = logMsgPrefix + " was not initialized with underlying credential";
if (!Log::ShouldWrite(Logger::Level::Verbose)) if (!Log::ShouldWrite(Logger::Level::Verbose))
{ {
@ -163,7 +171,8 @@ AccessToken EnvironmentCredential::GetToken(
{ {
if (!m_credentialImpl) if (!m_credentialImpl)
{ {
auto const AuthUnavailable = LogMsgPrefix + " authentication unavailable. "; auto const AuthUnavailable
= IdentityPrefix + GetCredentialName() + " authentication unavailable. ";
{ {
auto const logLevel = Logger::Level::Warning; auto const logLevel = Logger::Level::Warning;
@ -171,7 +180,7 @@ AccessToken EnvironmentCredential::GetToken(
{ {
Log::Write( Log::Write(
logLevel, logLevel,
AuthUnavailable + "See earlier EnvironmentCredential log messages for details."); AuthUnavailable + "See earlier " + GetCredentialName() + " log messages for details.");
} }
} }
@ -184,6 +193,7 @@ AccessToken EnvironmentCredential::GetToken(
namespace { namespace {
void PrintCredentialCreationLogMessage( void PrintCredentialCreationLogMessage(
std::string const& logMsgPrefix,
std::vector<std::pair<char const*, char const*>> const& envVarsToParams, std::vector<std::pair<char const*, char const*>> const& envVarsToParams,
char const* credThatGetsCreated) char const* credThatGetsCreated)
{ {
@ -193,7 +203,7 @@ void PrintCredentialCreationLogMessage(
{ {
Log::Write( Log::Write(
Logger::Level::Informational, Logger::Level::Informational,
LogMsgPrefix + " gets created with " + credThatGetsCreated + '.'); logMsgPrefix + " gets created with " + credThatGetsCreated + '.');
} }
return; return;
@ -224,7 +234,7 @@ void PrintCredentialCreationLogMessage(
Log::Write( Log::Write(
Logger::Level::Verbose, Logger::Level::Verbose,
LogMsgPrefix + ": " + envVars + " environment variables are set, so " + credThatGetsCreated logMsgPrefix + ": " + envVars + " environment variables are set, so " + credThatGetsCreated
+ " with corresponding " + credParams + " gets created."); + " with corresponding " + credParams + " gets created.");
} }
} // namespace } // namespace

Просмотреть файл

@ -8,13 +8,16 @@ using namespace Azure::Identity;
namespace { namespace {
std::unique_ptr<_detail::ManagedIdentitySource> CreateManagedIdentitySource( std::unique_ptr<_detail::ManagedIdentitySource> CreateManagedIdentitySource(
std::string const& credentialName,
std::string const& clientId, std::string const& clientId,
Azure::Core::Credentials::TokenCredentialOptions const& options) Azure::Core::Credentials::TokenCredentialOptions const& options)
{ {
using namespace Azure::Core::Credentials; using namespace Azure::Core::Credentials;
using namespace Azure::Identity::_detail; using namespace Azure::Identity::_detail;
static std::unique_ptr<ManagedIdentitySource> (*managedIdentitySourceCreate[])( static std::unique_ptr<ManagedIdentitySource> (*managedIdentitySourceCreate[])(
std::string const& clientId, TokenCredentialOptions const& options) std::string const& credName,
std::string const& clientId,
TokenCredentialOptions const& options)
= {AppServiceV2019ManagedIdentitySource::Create, = {AppServiceV2019ManagedIdentitySource::Create,
AppServiceV2017ManagedIdentitySource::Create, AppServiceV2017ManagedIdentitySource::Create,
CloudShellManagedIdentitySource::Create, CloudShellManagedIdentitySource::Create,
@ -25,7 +28,7 @@ std::unique_ptr<_detail::ManagedIdentitySource> CreateManagedIdentitySource(
// For that reason, it is not possible to cover that execution branch in tests. // For that reason, it is not possible to cover that execution branch in tests.
for (auto create : managedIdentitySourceCreate) // LCOV_EXCL_LINE for (auto create : managedIdentitySourceCreate) // LCOV_EXCL_LINE
{ {
if (auto source = create(clientId, options)) if (auto source = create(credentialName, clientId, options))
{ {
return source; return source;
} }
@ -33,7 +36,7 @@ std::unique_ptr<_detail::ManagedIdentitySource> CreateManagedIdentitySource(
// LCOV_EXCL_START // LCOV_EXCL_START
throw AuthenticationException( throw AuthenticationException(
"ManagedIdentityCredential authentication unavailable. No Managed Identity endpoint found."); credentialName + " authentication unavailable. No Managed Identity endpoint found.");
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
} }
} // namespace } // namespace
@ -43,8 +46,9 @@ ManagedIdentityCredential::~ManagedIdentityCredential() = default;
ManagedIdentityCredential::ManagedIdentityCredential( ManagedIdentityCredential::ManagedIdentityCredential(
std::string const& clientId, std::string const& clientId,
Azure::Core::Credentials::TokenCredentialOptions const& options) Azure::Core::Credentials::TokenCredentialOptions const& options)
: m_managedIdentitySource(CreateManagedIdentitySource(clientId, options)) : TokenCredential("ManagedIdentityCredential")
{ {
m_managedIdentitySource = CreateManagedIdentitySource(GetCredentialName(), clientId, options);
} }
ManagedIdentityCredential::ManagedIdentityCredential( ManagedIdentityCredential::ManagedIdentityCredential(

Просмотреть файл

@ -19,28 +19,28 @@ using Azure::Core::Diagnostics::Logger;
using Azure::Core::Diagnostics::_internal::Log; using Azure::Core::Diagnostics::_internal::Log;
namespace { namespace {
std::string const IdentityPrefix = "Identity: "; constexpr auto IdentityPrefix = "Identity: ";
constexpr auto CredPrefix = "ManagedIdentityCredential";
std::string WithSourceMessage(std::string const& credSource) std::string WithSourceMessage(std::string const& credSource)
{ {
return " with " + credSource + " source"; return " with " + credSource + " source";
} }
void PrintEnvNotSetUpMessage(std::string const& credSource) void PrintEnvNotSetUpMessage(std::string const& credName, std::string const& credSource)
{ {
auto const logLevel = Logger::Level::Verbose; auto const logLevel = Logger::Level::Verbose;
if (Log::ShouldWrite(logLevel)) if (Log::ShouldWrite(logLevel))
{ {
Log::Write( Log::Write(
logLevel, logLevel,
IdentityPrefix + CredPrefix + ": Environment is not set up for the credential to be created" IdentityPrefix + credName + ": Environment is not set up for the credential to be created"
+ WithSourceMessage(credSource) + '.'); + WithSourceMessage(credSource) + '.');
} }
} }
} // namespace } // namespace
Azure::Core::Url ManagedIdentitySource::ParseEndpointUrl( Azure::Core::Url ManagedIdentitySource::ParseEndpointUrl(
std::string const& credName,
std::string const& url, std::string const& url,
char const* envVarName, char const* envVarName,
std::string const& credSource) std::string const& credSource)
@ -57,7 +57,7 @@ Azure::Core::Url ManagedIdentitySource::ParseEndpointUrl(
{ {
Log::Write( Log::Write(
logLevel, logLevel,
IdentityPrefix + CredPrefix + " will be created" + WithSourceMessage(credSource) + '.'); IdentityPrefix + credName + " will be created" + WithSourceMessage(credSource) + '.');
} }
return endpointUrl; return endpointUrl;
@ -69,7 +69,7 @@ Azure::Core::Url ManagedIdentitySource::ParseEndpointUrl(
{ {
} }
auto const errorMessage = CredPrefix + WithSourceMessage(credSource) auto const errorMessage = credName + WithSourceMessage(credSource)
+ ": Failed to create: The environment variable \'" + envVarName + ": Failed to create: The environment variable \'" + envVarName
+ "\' contains an invalid URL."; + "\' contains an invalid URL.";
@ -84,6 +84,7 @@ Azure::Core::Url ManagedIdentitySource::ParseEndpointUrl(
template <typename T> template <typename T>
std::unique_ptr<ManagedIdentitySource> AppServiceManagedIdentitySource::Create( std::unique_ptr<ManagedIdentitySource> AppServiceManagedIdentitySource::Create(
std::string const& credName,
std::string const& clientId, std::string const& clientId,
Azure::Core::Credentials::TokenCredentialOptions const& options, Azure::Core::Credentials::TokenCredentialOptions const& options,
char const* endpointVarName, char const* endpointVarName,
@ -98,10 +99,13 @@ std::unique_ptr<ManagedIdentitySource> AppServiceManagedIdentitySource::Create(
if (!msiEndpoint.empty() && !msiSecret.empty()) if (!msiEndpoint.empty() && !msiSecret.empty())
{ {
return std::unique_ptr<ManagedIdentitySource>(new T( return std::unique_ptr<ManagedIdentitySource>(new T(
clientId, options, ParseEndpointUrl(msiEndpoint, endpointVarName, credSource), msiSecret)); clientId,
options,
ParseEndpointUrl(credName, msiEndpoint, endpointVarName, credSource),
msiSecret));
} }
PrintEnvNotSetUpMessage(credSource); PrintEnvNotSetUpMessage(credName, credSource);
return nullptr; return nullptr;
} }
@ -163,22 +167,25 @@ Azure::Core::Credentials::AccessToken AppServiceManagedIdentitySource::GetToken(
} }
std::unique_ptr<ManagedIdentitySource> AppServiceV2017ManagedIdentitySource::Create( std::unique_ptr<ManagedIdentitySource> AppServiceV2017ManagedIdentitySource::Create(
std::string const& credName,
std::string const& clientId, std::string const& clientId,
Core::Credentials::TokenCredentialOptions const& options) Core::Credentials::TokenCredentialOptions const& options)
{ {
return AppServiceManagedIdentitySource::Create<AppServiceV2017ManagedIdentitySource>( return AppServiceManagedIdentitySource::Create<AppServiceV2017ManagedIdentitySource>(
clientId, options, "MSI_ENDPOINT", "MSI_SECRET", "2017"); credName, clientId, options, "MSI_ENDPOINT", "MSI_SECRET", "2017");
} }
std::unique_ptr<ManagedIdentitySource> AppServiceV2019ManagedIdentitySource::Create( std::unique_ptr<ManagedIdentitySource> AppServiceV2019ManagedIdentitySource::Create(
std::string const& credName,
std::string const& clientId, std::string const& clientId,
Core::Credentials::TokenCredentialOptions const& options) Core::Credentials::TokenCredentialOptions const& options)
{ {
return AppServiceManagedIdentitySource::Create<AppServiceV2019ManagedIdentitySource>( return AppServiceManagedIdentitySource::Create<AppServiceV2019ManagedIdentitySource>(
clientId, options, "IDENTITY_ENDPOINT", "IDENTITY_HEADER", "2019"); credName, clientId, options, "IDENTITY_ENDPOINT", "IDENTITY_HEADER", "2019");
} }
std::unique_ptr<ManagedIdentitySource> CloudShellManagedIdentitySource::Create( std::unique_ptr<ManagedIdentitySource> CloudShellManagedIdentitySource::Create(
std::string const& credName,
std::string const& clientId, std::string const& clientId,
Azure::Core::Credentials::TokenCredentialOptions const& options) Azure::Core::Credentials::TokenCredentialOptions const& options)
{ {
@ -190,10 +197,10 @@ std::unique_ptr<ManagedIdentitySource> CloudShellManagedIdentitySource::Create(
if (!msiEndpoint.empty()) if (!msiEndpoint.empty())
{ {
return std::unique_ptr<ManagedIdentitySource>(new CloudShellManagedIdentitySource( return std::unique_ptr<ManagedIdentitySource>(new CloudShellManagedIdentitySource(
clientId, options, ParseEndpointUrl(msiEndpoint, EndpointVarName, CredSource))); clientId, options, ParseEndpointUrl(credName, msiEndpoint, EndpointVarName, CredSource)));
} }
PrintEnvNotSetUpMessage(CredSource); PrintEnvNotSetUpMessage(credName, CredSource);
return nullptr; return nullptr;
} }
@ -252,6 +259,7 @@ Azure::Core::Credentials::AccessToken CloudShellManagedIdentitySource::GetToken(
} }
std::unique_ptr<ManagedIdentitySource> AzureArcManagedIdentitySource::Create( std::unique_ptr<ManagedIdentitySource> AzureArcManagedIdentitySource::Create(
std::string const& credName,
std::string const& clientId, std::string const& clientId,
Azure::Core::Credentials::TokenCredentialOptions const& options) Azure::Core::Credentials::TokenCredentialOptions const& options)
{ {
@ -264,7 +272,7 @@ std::unique_ptr<ManagedIdentitySource> AzureArcManagedIdentitySource::Create(
if (identityEndpoint.empty() || Environment::GetVariable("IMDS_ENDPOINT").empty()) if (identityEndpoint.empty() || Environment::GetVariable("IMDS_ENDPOINT").empty())
{ {
PrintEnvNotSetUpMessage(credSource); PrintEnvNotSetUpMessage(credName, credSource);
return nullptr; return nullptr;
} }
@ -277,7 +285,7 @@ std::unique_ptr<ManagedIdentitySource> AzureArcManagedIdentitySource::Create(
} }
return std::unique_ptr<ManagedIdentitySource>(new AzureArcManagedIdentitySource( return std::unique_ptr<ManagedIdentitySource>(new AzureArcManagedIdentitySource(
options, ParseEndpointUrl(identityEndpoint, EndpointVarName, credSource))); options, ParseEndpointUrl(credName, identityEndpoint, EndpointVarName, credSource)));
} }
AzureArcManagedIdentitySource::AzureArcManagedIdentitySource( AzureArcManagedIdentitySource::AzureArcManagedIdentitySource(
@ -373,6 +381,7 @@ Azure::Core::Credentials::AccessToken AzureArcManagedIdentitySource::GetToken(
} }
std::unique_ptr<ManagedIdentitySource> ImdsManagedIdentitySource::Create( std::unique_ptr<ManagedIdentitySource> ImdsManagedIdentitySource::Create(
std::string const& credName,
std::string const& clientId, std::string const& clientId,
Azure::Core::Credentials::TokenCredentialOptions const& options) Azure::Core::Credentials::TokenCredentialOptions const& options)
{ {
@ -381,7 +390,7 @@ std::unique_ptr<ManagedIdentitySource> ImdsManagedIdentitySource::Create(
{ {
Log::Write( Log::Write(
logLevel, logLevel,
IdentityPrefix + CredPrefix + " will be created" IdentityPrefix + credName + " will be created"
+ WithSourceMessage("Azure Instance Metadata Service") + WithSourceMessage("Azure Instance Metadata Service")
+ ".\nSuccessful creation does not guarantee further successful token retrieval."); + ".\nSuccessful creation does not guarantee further successful token retrieval.");
} }

Просмотреть файл

@ -30,6 +30,7 @@ namespace Azure { namespace Identity { namespace _detail {
_detail::TokenCache m_tokenCache; _detail::TokenCache m_tokenCache;
static Core::Url ParseEndpointUrl( static Core::Url ParseEndpointUrl(
std::string const& credName,
std::string const& url, std::string const& url,
char const* envVarName, char const* envVarName,
std::string const& credSource); std::string const& credSource);
@ -63,6 +64,7 @@ namespace Azure { namespace Identity { namespace _detail {
template <typename T> template <typename T>
static std::unique_ptr<ManagedIdentitySource> Create( static std::unique_ptr<ManagedIdentitySource> Create(
std::string const& credName,
std::string const& clientId, std::string const& clientId,
Core::Credentials::TokenCredentialOptions const& options, Core::Credentials::TokenCredentialOptions const& options,
char const* endpointVarName, char const* endpointVarName,
@ -97,6 +99,7 @@ namespace Azure { namespace Identity { namespace _detail {
public: public:
static std::unique_ptr<ManagedIdentitySource> Create( static std::unique_ptr<ManagedIdentitySource> Create(
std::string const& credName,
std::string const& clientId, std::string const& clientId,
Core::Credentials::TokenCredentialOptions const& options); Core::Credentials::TokenCredentialOptions const& options);
}; };
@ -123,6 +126,7 @@ namespace Azure { namespace Identity { namespace _detail {
public: public:
static std::unique_ptr<ManagedIdentitySource> Create( static std::unique_ptr<ManagedIdentitySource> Create(
std::string const& credName,
std::string const& clientId, std::string const& clientId,
Core::Credentials::TokenCredentialOptions const& options); Core::Credentials::TokenCredentialOptions const& options);
}; };
@ -139,6 +143,7 @@ namespace Azure { namespace Identity { namespace _detail {
public: public:
static std::unique_ptr<ManagedIdentitySource> Create( static std::unique_ptr<ManagedIdentitySource> Create(
std::string const& credName,
std::string const& clientId, std::string const& clientId,
Core::Credentials::TokenCredentialOptions const& options); Core::Credentials::TokenCredentialOptions const& options);
@ -157,6 +162,7 @@ namespace Azure { namespace Identity { namespace _detail {
public: public:
static std::unique_ptr<ManagedIdentitySource> Create( static std::unique_ptr<ManagedIdentitySource> Create(
std::string const& credName,
std::string const& clientId, std::string const& clientId,
Core::Credentials::TokenCredentialOptions const& options); Core::Credentials::TokenCredentialOptions const& options);
@ -175,6 +181,7 @@ namespace Azure { namespace Identity { namespace _detail {
public: public:
static std::unique_ptr<ManagedIdentitySource> Create( static std::unique_ptr<ManagedIdentitySource> Create(
std::string const& credName,
std::string const& clientId, std::string const& clientId,
Core::Credentials::TokenCredentialOptions const& options); Core::Credentials::TokenCredentialOptions const& options);

Просмотреть файл

@ -158,6 +158,12 @@ TEST(AzureCliCredential, Error)
Logger::SetListener(nullptr); Logger::SetListener(nullptr);
} }
TEST(AzureCliCredential, GetCredentialName)
{
AzureCliTestCredential const cred(EmptyOutputCommand);
EXPECT_EQ(cred.GetCredentialName(), "AzureCliCredential");
}
TEST(AzureCliCredential, EmptyOutput) TEST(AzureCliCredential, EmptyOutput)
{ {
AzureCliTestCredential const azCliCred(EmptyOutputCommand); AzureCliTestCredential const azCliCred(EmptyOutputCommand);

Просмотреть файл

@ -25,7 +25,7 @@ private:
std::string m_token; std::string m_token;
public: public:
TestCredential(std::string token = "") : m_token(token) {} TestCredential(std::string token = "") : TokenCredential("TestCredential"), m_token(token) {}
mutable bool WasInvoked = false; mutable bool WasInvoked = false;
@ -45,6 +45,12 @@ public:
}; };
} // namespace } // namespace
TEST(ChainedTokenCredential, GetCredentialName)
{
ChainedTokenCredential const cred(ChainedTokenCredential::Sources{});
EXPECT_EQ(cred.GetCredentialName(), "ChainedTokenCredential");
}
TEST(ChainedTokenCredential, Success) TEST(ChainedTokenCredential, Success)
{ {
auto c1 = std::make_shared<TestCredential>("Token1"); auto c1 = std::make_shared<TestCredential>("Token1");
@ -110,7 +116,9 @@ TEST(ChainedTokenCredential, Logging)
ChainedTokenCredential cred({}); ChainedTokenCredential cred({});
EXPECT_EQ(log.size(), LogMsgVec::size_type(1)); EXPECT_EQ(log.size(), LogMsgVec::size_type(1));
EXPECT_EQ(log[0].first, Logger::Level::Warning); EXPECT_EQ(log[0].first, Logger::Level::Warning);
EXPECT_EQ(log[0].second, "Identity: ChainedTokenCredential: Created with 0 credentials."); EXPECT_EQ(
log[0].second,
"Identity: ChainedTokenCredential: Created with EMPTY chain of credentials.");
log.clear(); log.clear();
EXPECT_THROW(static_cast<void>(cred.GetToken({}, {})), AuthenticationException); EXPECT_THROW(static_cast<void>(cred.GetToken({}, {})), AuthenticationException);
@ -128,7 +136,10 @@ TEST(ChainedTokenCredential, Logging)
ChainedTokenCredential cred({c}); ChainedTokenCredential cred({c});
EXPECT_EQ(log.size(), LogMsgVec::size_type(1)); EXPECT_EQ(log.size(), LogMsgVec::size_type(1));
EXPECT_EQ(log[0].first, Logger::Level::Informational); EXPECT_EQ(log[0].first, Logger::Level::Informational);
EXPECT_EQ(log[0].second, "Identity: ChainedTokenCredential: Created with 1 credentials."); EXPECT_EQ(
log[0].second,
"Identity: ChainedTokenCredential: Created with the following credentials: "
"TestCredential.");
log.clear(); log.clear();
EXPECT_FALSE(c->WasInvoked); EXPECT_FALSE(c->WasInvoked);
@ -141,7 +152,7 @@ TEST(ChainedTokenCredential, Logging)
EXPECT_EQ(log[0].first, Logger::Level::Verbose); EXPECT_EQ(log[0].first, Logger::Level::Verbose);
EXPECT_EQ( EXPECT_EQ(
log[0].second, log[0].second,
"Identity: ChainedTokenCredential: Failed to get token from credential #1: " "Identity: ChainedTokenCredential: Failed to get token from TestCredential: "
"Test Error"); "Test Error");
EXPECT_EQ(log[1].first, Logger::Level::Warning); EXPECT_EQ(log[1].first, Logger::Level::Warning);
@ -158,7 +169,10 @@ TEST(ChainedTokenCredential, Logging)
ChainedTokenCredential cred({c1, c2}); ChainedTokenCredential cred({c1, c2});
EXPECT_EQ(log.size(), LogMsgVec::size_type(1)); EXPECT_EQ(log.size(), LogMsgVec::size_type(1));
EXPECT_EQ(log[0].first, Logger::Level::Informational); EXPECT_EQ(log[0].first, Logger::Level::Informational);
EXPECT_EQ(log[0].second, "Identity: ChainedTokenCredential: Created with 2 credentials."); EXPECT_EQ(
log[0].second,
"Identity: ChainedTokenCredential: Created with the following credentials: "
"TestCredential, TestCredential.");
log.clear(); log.clear();
EXPECT_FALSE(c1->WasInvoked); EXPECT_FALSE(c1->WasInvoked);
@ -175,13 +189,13 @@ TEST(ChainedTokenCredential, Logging)
EXPECT_EQ(log[0].first, Logger::Level::Verbose); EXPECT_EQ(log[0].first, Logger::Level::Verbose);
EXPECT_EQ( EXPECT_EQ(
log[0].second, log[0].second,
"Identity: ChainedTokenCredential: Failed to get token from credential #1: " "Identity: ChainedTokenCredential: Failed to get token from TestCredential: "
"Test Error"); "Test Error");
EXPECT_EQ(log[1].first, Logger::Level::Informational); EXPECT_EQ(log[1].first, Logger::Level::Informational);
EXPECT_EQ( EXPECT_EQ(
log[1].second, log[1].second,
"Identity: ChainedTokenCredential: Successfully got token from credential #2."); "Identity: ChainedTokenCredential: Successfully got token from TestCredential.");
} }
Logger::SetListener(nullptr); Logger::SetListener(nullptr);

Просмотреть файл

@ -30,9 +30,20 @@ std::vector<std::string> SplitString(const std::string& s, char separator);
std::string ToString(std::vector<uint8_t> const& vec); std::string ToString(std::vector<uint8_t> const& vec);
} // namespace } // namespace
TEST(ClientCertificateCredential, GetCredentialName)
{
TempCertFile const tempCertFile;
ClientCertificateCredential const cred(
"01234567-89ab-cdef-fedc-ba8976543210",
"fedcba98-7654-3210-0123-456789abcdef",
TempCertFile::Path);
EXPECT_EQ(cred.GetCredentialName(), "ClientCertificateCredential");
}
TEST(ClientCertificateCredential, Regular) TEST(ClientCertificateCredential, Regular)
{ {
TempCertFile tempCertFile; TempCertFile const tempCertFile;
auto const actual = CredentialTestHelper::SimulateTokenRequest( auto const actual = CredentialTestHelper::SimulateTokenRequest(
[](auto transport) { [](auto transport) {
@ -167,7 +178,7 @@ TEST(ClientCertificateCredential, Regular)
TEST(ClientCertificateCredential, AzureStack) TEST(ClientCertificateCredential, AzureStack)
{ {
TempCertFile tempCertFile; TempCertFile const tempCertFile;
auto const actual = CredentialTestHelper::SimulateTokenRequest( auto const actual = CredentialTestHelper::SimulateTokenRequest(
[](auto transport) { [](auto transport) {
@ -294,7 +305,7 @@ TEST(ClientCertificateCredential, AzureStack)
TEST(ClientCertificateCredential, Authority) TEST(ClientCertificateCredential, Authority)
{ {
TempCertFile tempCertFile; TempCertFile const tempCertFile;
auto const actual = CredentialTestHelper::SimulateTokenRequest( auto const actual = CredentialTestHelper::SimulateTokenRequest(
[](auto transport) { [](auto transport) {

Просмотреть файл

@ -12,6 +12,16 @@ using Azure::Identity::ClientSecretCredential;
using Azure::Identity::ClientSecretCredentialOptions; using Azure::Identity::ClientSecretCredentialOptions;
using Azure::Identity::Test::_detail::CredentialTestHelper; using Azure::Identity::Test::_detail::CredentialTestHelper;
TEST(ClientSecretCredential, GetCredentialName)
{
ClientSecretCredential const cred(
"01234567-89ab-cdef-fedc-ba8976543210",
"fedcba98-7654-3210-0123-456789abcdef",
"CLIENTSECRET");
EXPECT_EQ(cred.GetCredentialName(), "ClientSecretCredential");
}
TEST(ClientSecretCredential, Regular) TEST(ClientSecretCredential, Regular)
{ {
auto const actual = CredentialTestHelper::SimulateTokenRequest( auto const actual = CredentialTestHelper::SimulateTokenRequest(

Просмотреть файл

@ -17,6 +17,28 @@ using Azure::Identity::Test::_detail::CredentialTestHelper;
namespace { namespace {
} // namespace } // namespace
TEST(DefaultAzureCredential, GetCredentialName)
{
CredentialTestHelper::EnvironmentOverride const env({
{"AZURE_TENANT_ID", "01234567-89ab-cdef-fedc-ba8976543210"},
{"AZURE_CLIENT_ID", "fedcba98-7654-3210-0123-456789abcdef"},
{"AZURE_CLIENT_SECRET", "CLIENTSECRET"},
{"AZURE_AUTHORITY_HOST", ""},
{"AZURE_USERNAME", ""},
{"AZURE_PASSWORD", ""},
{"AZURE_CLIENT_CERTIFICATE_PATH", ""},
{"MSI_ENDPOINT", ""},
{"MSI_SECRET", ""},
{"IDENTITY_ENDPOINT", "https://visualstudio.com/"},
{"IMDS_ENDPOINT", ""},
{"IDENTITY_HEADER", "CLIENTSECRET"},
{"IDENTITY_SERVER_THUMBPRINT", ""},
});
DefaultAzureCredential const cred;
EXPECT_EQ(cred.GetCredentialName(), "DefaultAzureCredential");
}
TEST(DefaultAzureCredential, LogMessages) TEST(DefaultAzureCredential, LogMessages)
{ {
using LogMsgVec = std::vector<std::pair<Logger::Level, std::string>>; using LogMsgVec = std::vector<std::pair<Logger::Level, std::string>>;

Просмотреть файл

@ -13,6 +13,22 @@ using Azure::Core::Http::HttpMethod;
using Azure::Identity::EnvironmentCredential; using Azure::Identity::EnvironmentCredential;
using Azure::Identity::Test::_detail::CredentialTestHelper; using Azure::Identity::Test::_detail::CredentialTestHelper;
TEST(EnvironmentCredential, GetCredentialName)
{
CredentialTestHelper::EnvironmentOverride const env({
{"AZURE_TENANT_ID", "01234567-89ab-cdef-fedc-ba8976543210"},
{"AZURE_CLIENT_ID", "fedcba98-7654-3210-0123-456789abcdef"},
{"AZURE_CLIENT_SECRET", "CLIENTSECRET"},
{"AZURE_AUTHORITY_HOST", ""},
{"AZURE_USERNAME", ""},
{"AZURE_PASSWORD", ""},
{"AZURE_CLIENT_CERTIFICATE_PATH", ""},
});
EnvironmentCredential const cred;
EXPECT_EQ(cred.GetCredentialName(), "EnvironmentCredential");
}
TEST(EnvironmentCredential, RegularClientSecretCredential) TEST(EnvironmentCredential, RegularClientSecretCredential)
{ {
using Azure::Core::Diagnostics::Logger; using Azure::Core::Diagnostics::Logger;

Просмотреть файл

@ -16,6 +16,21 @@ using Azure::Core::Http::HttpStatusCode;
using Azure::Identity::ManagedIdentityCredential; using Azure::Identity::ManagedIdentityCredential;
using Azure::Identity::Test::_detail::CredentialTestHelper; using Azure::Identity::Test::_detail::CredentialTestHelper;
TEST(ManagedIdentityCredential, GetCredentialName)
{
CredentialTestHelper::EnvironmentOverride const env({
{"MSI_ENDPOINT", ""},
{"MSI_SECRET", ""},
{"IDENTITY_ENDPOINT", "https://visualstudio.com/"},
{"IMDS_ENDPOINT", ""},
{"IDENTITY_HEADER", "CLIENTSECRET"},
{"IDENTITY_SERVER_THUMBPRINT", ""},
});
ManagedIdentityCredential const cred;
EXPECT_EQ(cred.GetCredentialName(), "ManagedIdentityCredential");
}
TEST(ManagedIdentityCredential, AppServiceV2019) TEST(ManagedIdentityCredential, AppServiceV2019)
{ {
using Azure::Core::Diagnostics::Logger; using Azure::Core::Diagnostics::Logger;

Просмотреть файл

@ -34,15 +34,16 @@ public:
HttpMethod httpMethod, HttpMethod httpMethod,
Url url, Url url,
TokenCredentialOptions const& options) TokenCredentialOptions const& options)
: m_httpMethod(std::move(httpMethod)), m_url(std::move(url)), : TokenCredential("TokenCredentialImplTester"), m_httpMethod(std::move(httpMethod)),
m_tokenCredentialImpl(new TokenCredentialImpl(options)) m_url(std::move(url)), m_tokenCredentialImpl(new TokenCredentialImpl(options))
{ {
} }
explicit TokenCredentialImplTester( explicit TokenCredentialImplTester(
std::function<void()> throwingFunction, std::function<void()> throwingFunction,
TokenCredentialOptions const& options) TokenCredentialOptions const& options)
: m_throwingFunction(std::move(throwingFunction)), : TokenCredential("TokenCredentialImplTester"),
m_throwingFunction(std::move(throwingFunction)),
m_tokenCredentialImpl(new TokenCredentialImpl(options)) m_tokenCredentialImpl(new TokenCredentialImpl(options))
{ {
} }
@ -63,8 +64,41 @@ public:
}); });
} }
}; };
// Disable deprecation warning
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4996)
#elif defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
// This credential is needed to test the default behavior when the customer has custom credential
// they implemented while using earlier versions of the SDK which didn't have a constructor with
// credentialName.
class CustomTokenCredential : public TokenCredential {
public:
AccessToken GetToken(TokenRequestContext const&, Context const&) const override { return {}; }
};
#if defined(_MSC_VER)
#pragma warning(pop)
#elif defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif // _MSC_VER
} // namespace } // namespace
TEST(CustomTokenCredential, GetCredentialName)
{
CustomTokenCredential cred;
EXPECT_EQ(cred.GetCredentialName(), "Custom Credential");
}
TEST(TokenCredentialImpl, Normal) TEST(TokenCredentialImpl, Normal)
{ {
auto const actual = CredentialTestHelper::SimulateTokenRequest( auto const actual = CredentialTestHelper::SimulateTokenRequest(