diff --git a/sdk/core/azure-core/CMakeLists.txt b/sdk/core/azure-core/CMakeLists.txt index 434e48ca9..d668b2c1a 100644 --- a/sdk/core/azure-core/CMakeLists.txt +++ b/sdk/core/azure-core/CMakeLists.txt @@ -18,6 +18,7 @@ add_library ( ${TARGET_NAME} src/context.cpp src/credentials/credentials.cpp + src/credentials/policy/policies.cpp src/http/http.cpp src/http/policy.cpp src/http/request.cpp diff --git a/sdk/core/azure-core/inc/credentials/credentials.hpp b/sdk/core/azure-core/inc/credentials/credentials.hpp index 9d7724775..413485c82 100644 --- a/sdk/core/azure-core/inc/credentials/credentials.hpp +++ b/sdk/core/azure-core/inc/credentials/credentials.hpp @@ -3,87 +3,81 @@ #pragma once -#include "azure.hpp" - #include -#include -#include +#include +#include #include +#include +#include namespace Azure { namespace Core { namespace Credentials { - namespace Details { - class CredentialTest; - } - - class Credential { - virtual void SetScopes(std::string const& scopes) { AZURE_UNREFERENCED_PARAMETER(scopes); } - - public: - class Internal; - virtual ~Credential() noexcept = default; - - protected: - Credential() = default; - - Credential(Credential const& other) = default; - Credential& operator=(Credential const& other) = default; + struct AccessToken + { + std::string Token; + std::chrono::system_clock::time_point ExpiresOn; }; - class TokenCredential : public Credential { - friend class Details::CredentialTest; - class Token; - - std::shared_ptr m_token; - std::mutex m_mutex; - - std::string UpdateTokenNonThreadSafe(Token& token); - - virtual bool IsTokenExpired(std::chrono::system_clock::time_point const& tokenExpiration) const; - - virtual void RefreshToken( - std::string& newTokenString, - std::chrono::system_clock::time_point& newExpiration) - = 0; - + class TokenCredential { public: - class Internal; - - TokenCredential(TokenCredential const& other); - TokenCredential& operator=(TokenCredential const& other); + virtual AccessToken GetToken(Context& context, std::vector const& scopes) + const = 0; protected: - TokenCredential() = default; - TokenCredential(TokenCredential const& other, int) : Credential(other) {} + TokenCredential() {} - void Init(TokenCredential const& other); - virtual std::string GetToken(); - void ResetToken(); + private: + TokenCredential(TokenCredential const&) = delete; + void operator=(TokenCredential const&) = delete; }; class ClientSecretCredential : public TokenCredential { - friend class Details::CredentialTest; - class ClientSecret; - - std::shared_ptr m_clientSecret; - std::mutex m_mutex; - - void SetScopes(std::string const& scopes) override; - - std::string GetToken() override; - - void RefreshToken( - std::string& newTokenString, - std::chrono::system_clock::time_point& newExpiration) override; + private: + std::string const m_tenantId; + std::string const m_clientId; + std::string const m_clientSecret; public: ClientSecretCredential( std::string const& tenantId, std::string const& clientId, - std::string const& clientSecret); + std::string const& clientSecret) + : m_tenantId(tenantId), m_clientId(clientId), m_clientSecret(clientSecret) + { + } - ClientSecretCredential(ClientSecretCredential const& other); - ClientSecretCredential& operator=(ClientSecretCredential const& other); + ClientSecretCredential( + std::string const&& tenantId, + std::string const& clientId, + std::string const& clientSecret) + : m_tenantId(std::move(tenantId)), m_clientId(clientId), m_clientSecret(clientSecret) + { + } + + ClientSecretCredential( + std::string const&& tenantId, + std::string const&& clientId, + std::string const& clientSecret) + : m_tenantId(std::move(tenantId)), m_clientId(std::move(clientId)), + m_clientSecret(clientSecret) + { + } + + ClientSecretCredential( + std::string const&& tenantId, + std::string const&& clientId, + std::string const&& clientSecret) + : m_tenantId(std::move(tenantId)), m_clientId(std::move(clientId)), + m_clientSecret(std::move(clientSecret)) + { + } + + AccessToken GetToken(Context& context, std::vector const& scopes) const override; + }; + + class AuthenticationException : public std::runtime_error { + public: + explicit AuthenticationException(std::string const& msg) : std::runtime_error(msg) {} }; }}} // namespace Azure::Core::Credentials diff --git a/sdk/core/azure-core/inc/credentials/policy/policies.hpp b/sdk/core/azure-core/inc/credentials/policy/policies.hpp new file mode 100644 index 000000000..a94cd396e --- /dev/null +++ b/sdk/core/azure-core/inc/credentials/policy/policies.hpp @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace Azure { namespace Core { namespace Credentials { namespace Policy { + + class BearerTokenAuthenticationPolicy : public Http::HttpPolicy { + private: + std::shared_ptr const m_credential; + std::vector m_scopes; + + mutable AccessToken m_accessToken; + mutable std::mutex m_accessTokenMutex; + + BearerTokenAuthenticationPolicy(BearerTokenAuthenticationPolicy const&) = delete; + void operator=(BearerTokenAuthenticationPolicy const&) = delete; + + public: + BearerTokenAuthenticationPolicy( + std::shared_ptr const& credential, + std::string const& scope) + : m_credential(credential) + { + m_scopes.push_back(scope); + } + + BearerTokenAuthenticationPolicy( + std::shared_ptr const& credential, + std::vector const& scopes) + : m_credential(credential), m_scopes(scopes) + { + } + + BearerTokenAuthenticationPolicy( + std::shared_ptr const& credential, + std::vector const&& scopes) + : m_credential(credential), m_scopes(std::move(scopes)) + { + } + + template + BearerTokenAuthenticationPolicy( + std::shared_ptr const& credential, + ScopesIterator const& scopesBegin, + ScopesIterator const& scopesEnd) + : m_credential(credential), m_scopes(scopesBegin, scopesEnd) + { + } + + HttpPolicy* Clone() const override + { + return new BearerTokenAuthenticationPolicy(m_credential, m_scopes); + } + + std::unique_ptr Send( + Context& context, + Http::Request& request, + Http::NextHttpPolicy policy) const override; + }; + +}}}} // namespace Azure::Core::Credentials::Policy diff --git a/sdk/core/azure-core/inc/internal/credentials_internal.hpp b/sdk/core/azure-core/inc/internal/credentials_internal.hpp deleted file mode 100644 index f6d924fb4..000000000 --- a/sdk/core/azure-core/inc/internal/credentials_internal.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// SPDX-License-Identifier: MIT - -#pragma once - -#include - -#include -#include -#include -#include - -namespace Azure { namespace Core { namespace Credentials { - - class Credential::Internal { - public: - static void SetScopes(Credential& credential, std::string const& scopes) - { - credential.SetScopes(scopes); - } - }; - - class TokenCredential::Token { - friend class TokenCredential; - friend class Details::CredentialTest; - - std::string m_tokenString; - std::chrono::system_clock::time_point m_expiresAt; - std::mutex m_mutex; - }; - - class TokenCredential::Internal { - public: - static std::string GetToken(TokenCredential& credential) - { - return credential.GetToken(); - } - }; - - class ClientSecretCredential::ClientSecret { - friend class ClientSecretCredential; - friend class Details::CredentialTest; - - std::string m_tenantId; - std::string m_clientId; - std::string m_clientSecret; - std::string m_scopes; - - public: - ClientSecret( - std::string const& tenantId, - std::string const& clientId, - std::string const& clientSecret) - : m_tenantId(tenantId), m_clientId(clientId), m_clientSecret(clientSecret) - { - } - - ClientSecret( - std::string const& tenantId, - std::string const& clientId, - std::string const& clientSecret, - std::string const& scopes) - : m_tenantId(tenantId), m_clientId(clientId), m_clientSecret(clientSecret), m_scopes(scopes) - { - } - }; - -}}} // namespace Azure::Core::Credentials diff --git a/sdk/core/azure-core/src/credentials/credentials.cpp b/sdk/core/azure-core/src/credentials/credentials.cpp index da59354de..44ca32944 100644 --- a/sdk/core/azure-core/src/credentials/credentials.cpp +++ b/sdk/core/azure-core/src/credentials/credentials.cpp @@ -2,125 +2,205 @@ // SPDX-License-Identifier: MIT #include -#include +#include +#include +#include +#include +#include +#include +#include using namespace Azure::Core::Credentials; -std::string TokenCredential::UpdateTokenNonThreadSafe(Token& token) +namespace { +std::string UrlEncode(std::string const& s) { - std::string newTokenString; - std::chrono::system_clock::time_point newExpiration; + std::ostringstream encoded; + encoded << std::hex; - this->RefreshToken(newTokenString, newExpiration); - - token.m_tokenString = newTokenString; - token.m_expiresAt = newExpiration; - - return newTokenString; -} - -bool TokenCredential::IsTokenExpired( - std::chrono::system_clock::time_point const& tokenExpiration) const -{ - return tokenExpiration <= std::chrono::system_clock::now() - std::chrono::minutes(5); -} - -TokenCredential::TokenCredential(TokenCredential const& other) : Credential(other) -{ - this->Init(other); -} - -TokenCredential& TokenCredential::operator=(TokenCredential const& other) -{ - std::lock_guard const thisTokenPtrLock(this->m_mutex); - this->Init(other); - return *this; -} - -void TokenCredential::Init(TokenCredential const& other) -{ - std::lock_guard const otherTokenPtrLock(const_cast(other.m_mutex)); - this->m_token = other.m_token; -} - -std::string TokenCredential::GetToken() -{ - std::lock_guard const tokenPtrLock(this->m_mutex); - - if (!this->m_token) + for (auto c : s) { - this->m_token = std::make_shared(); - return UpdateTokenNonThreadSafe(*this->m_token); + if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') + || (c == '-' || c == '.' || c == '_' || c == '~')) + { + encoded << c; + } + else + { + encoded << std::uppercase; + encoded << '%' << std::setw(2) << int((unsigned char)c); + encoded << std::nouppercase; + } } - std::lock_guard const tokenLock(this->m_token->m_mutex); - Token& token = *this->m_token; - return this->IsTokenExpired(token.m_expiresAt) ? UpdateTokenNonThreadSafe(token) - : token.m_tokenString; + return encoded.str(); } +} // namespace -void TokenCredential::ResetToken() +AccessToken ClientSecretCredential::GetToken( + Context& context, + std::vector const& scopes) const { - std::lock_guard const tokenPtrLock(this->m_mutex); - this->m_token.reset(); -} - -void ClientSecretCredential::SetScopes(std::string const& scopes) -{ - std::lock_guard const clientSecretPtrLock(this->m_mutex); - - if (scopes == this->m_clientSecret->m_scopes) - return; - - this->TokenCredential::ResetToken(); - - if (this->m_clientSecret.unique()) + static std::string const errorMsgPrefix("ClientSecretCredential::GetToken: "); + try { - this->m_clientSecret->m_scopes = scopes; - return; + std::ostringstream url; + url << "https://login.microsoftonline.com/" << UrlEncode(m_tenantId) << "/oauth2/v2.0/token"; + + std::ostringstream body; + body << "grant_type=client_credentials&client_id=" << UrlEncode(m_clientId) + << "&client_secret=" << UrlEncode(m_clientSecret); + + if (!scopes.empty()) + { + auto scopesIter = scopes.begin(); + body << "&scope=" << UrlEncode(*scopesIter); + + auto const scopesEnd = scopes.end(); + for (++scopesIter; scopesIter != scopesEnd; ++scopesIter) + { + body << " " << *scopesIter; + } + } + + auto const bodyString = body.str(); + std::vector bodyVec; + bodyVec.reserve(bodyString.size()); + for (auto c : bodyString) + { + bodyVec.push_back(static_cast(c)); + } + + auto bodyStream = std::make_unique(bodyVec); + + Http::Request request(Http::HttpMethod::Post, url.str(), bodyStream.get()); + bodyStream.release(); + + request.AddHeader("Content-Type", "application/x-www-form-urlencoded"); + request.AddHeader("Content-Length", std::to_string(bodyVec.size())); + + std::shared_ptr transport = std::make_unique(); + + std::vector> policies; + policies.push_back(std::make_unique()); + + Http::RetryOptions retryOptions; + policies.push_back(std::make_unique(retryOptions)); + + policies.push_back(std::make_unique(std::move(transport))); + + Http::HttpPipeline httpPipeline(policies); + + std::shared_ptr response = httpPipeline.Send(context, request); + + if (!response) + { + throw AuthenticationException(errorMsgPrefix + "null response"); + } + + auto const statusCode = response->GetStatusCode(); + if (statusCode != Http::HttpStatusCode::Ok) + { + std::ostringstream errorMsg; + errorMsg << errorMsgPrefix << "error response: " + << static_cast::type>(statusCode) + << " " << response->GetReasonPhrase(); + + throw AuthenticationException(errorMsg.str()); + } + + auto const responseStream = response->GetBodyStream(); + auto const responseStreamLength = responseStream->Length(); + + std::string responseBody(static_cast(responseStreamLength), 0); + + responseStream->Read( + static_cast(static_cast(&responseBody[0])), responseStreamLength); + + // TODO: use JSON parser. + auto const responseBodySize = responseBody.size(); + + static std::string const jsonExpiresIn = "expires_in"; + static std::string const jsonAccessToken = "access_token"; + + auto responseBodyPos = responseBody.find(':', responseBody.find(jsonExpiresIn)); + if (responseBodyPos == std::string::npos) + { + std::ostringstream errorMsg; + errorMsg << errorMsgPrefix << "response json: \'" << jsonExpiresIn << "\' not found."; + + throw AuthenticationException(errorMsg.str()); + } + + for (; responseBodyPos < responseBodySize; ++responseBodyPos) + { + auto c = responseBody[responseBodyPos]; + if (c != ':' && c != ' ' && c != '\"' && c != '\'') + { + break; + } + } + + long long expiresInSeconds = 0; + for (; responseBodyPos < responseBodySize; ++responseBodyPos) + { + auto c = responseBody[responseBodyPos]; + if (c < '0' || c > '9') + { + break; + } + + expiresInSeconds = (expiresInSeconds * 10) + (c - '0'); + } + + responseBodyPos = responseBody.find(':', responseBody.find(jsonAccessToken)); + if (responseBodyPos == std::string::npos) + { + std::ostringstream errorMsg; + errorMsg << errorMsgPrefix << "response json: \'" << jsonAccessToken << "\' not found."; + + throw AuthenticationException(errorMsg.str()); + } + + for (; responseBodyPos < responseBodySize; ++responseBodyPos) + { + auto c = responseBody[responseBodyPos]; + if (c != ':' && c != ' ' && c != '\"' && c != '\'') + { + break; + } + } + + auto const tokenBegin = responseBodyPos; + for (; responseBodyPos < responseBodySize; ++responseBodyPos) + { + auto c = responseBody[responseBodyPos]; + if (c == '\"' || c == '\'') + { + break; + } + } + auto const tokenEnd = responseBodyPos; + + expiresInSeconds -= 2 * 60; + auto const responseBodyBegin = responseBody.begin(); + + return { + std::string(responseBodyBegin + tokenBegin, responseBodyBegin + tokenEnd), + std::chrono::system_clock::now() + + std::chrono::seconds(expiresInSeconds < 0 ? 0 : expiresInSeconds), + }; + } + catch (AuthenticationException const&) + { + throw; + } + catch (std::exception const& e) + { + throw new AuthenticationException(e.what()); + } + catch (...) + { + throw new AuthenticationException("unknown error"); } - - this->m_clientSecret = std::make_shared( - this->m_clientSecret->m_tenantId, - this->m_clientSecret->m_clientId, - this->m_clientSecret->m_clientSecret, - scopes); -} - -std::string ClientSecretCredential::GetToken() -{ - std::lock_guard const clientSecretPtrLock(this->m_mutex); - return this->TokenCredential::GetToken(); -} - -void ClientSecretCredential::RefreshToken( - std::string& newTokenString, - std::chrono::system_clock::time_point& newExpiration) -{ - // TODO: get token using scopes, tenantId, clientId, and clientSecretId. - AZURE_UNREFERENCED_PARAMETER(newTokenString); - AZURE_UNREFERENCED_PARAMETER(newExpiration); -} - -ClientSecretCredential::ClientSecretCredential( - std::string const& tenantId, - std::string const& clientId, - std::string const& clientSecret) - : m_clientSecret(new ClientSecret(tenantId, clientId, clientSecret)) -{ -} - -ClientSecretCredential::ClientSecretCredential(ClientSecretCredential const& other) - : TokenCredential(other, 0) -{ - std::lock_guard const otherClientSecretPtrLock( - const_cast(other.m_mutex)); - this->TokenCredential::Init(other); -} - -ClientSecretCredential& ClientSecretCredential::operator=(ClientSecretCredential const& other) -{ - std::lock_guard const otherClientSecretPtrLock(this->m_mutex); - this->TokenCredential::operator=(other); - return *this; } diff --git a/sdk/core/azure-core/src/credentials/policy/policies.cpp b/sdk/core/azure-core/src/credentials/policy/policies.cpp new file mode 100644 index 000000000..9db030eb9 --- /dev/null +++ b/sdk/core/azure-core/src/credentials/policy/policies.cpp @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include + +using namespace Azure::Core::Credentials::Policy; + +std::unique_ptr BearerTokenAuthenticationPolicy::Send( + Context& context, + Http::Request& request, + Http::NextHttpPolicy policy) const +{ + { + std::lock_guard lock(m_accessTokenMutex); + + if (std::chrono::system_clock::now() > m_accessToken.ExpiresOn) + { + m_accessToken = m_credential->GetToken(context, m_scopes); + } + + request.AddHeader("authorization", "Bearer " + m_accessToken.Token); + } + + return policy.Send(context, request); +} diff --git a/sdk/core/azure-core/test/http.cpp b/sdk/core/azure-core/test/http.cpp index af40883c4..5693d5e8b 100644 --- a/sdk/core/azure-core/test/http.cpp +++ b/sdk/core/azure-core/test/http.cpp @@ -3,7 +3,6 @@ #include "gtest/gtest.h" #include -#include #include #include @@ -116,211 +115,3 @@ TEST(Http_Request, add_path) req.GetEncodedUrl(), url + "/path/path2/path3?query=value"); } - -class Azure::Core::Credentials::Details::CredentialTest : public ClientSecretCredential { -public: - CredentialTest( - std::string const& tenantId, - std::string const& clientId, - std::string const& clientSecret) - : ClientSecretCredential(tenantId, clientId, clientSecret) - { - } - - std::string NewTokenString; - std::chrono::system_clock::time_point NewExpiration; - bool IsExpired; - - std::string GetTenantId() const - { - return this->ClientSecretCredential::m_clientSecret->m_tenantId; - } - - std::string GetClientId() const - { - return this->ClientSecretCredential::m_clientSecret->m_clientId; - } - - std::string GetClientSecret() const - { - return this->ClientSecretCredential::m_clientSecret->m_clientSecret; - } - - std::string GetScopes() const { return this->ClientSecretCredential::m_clientSecret->m_scopes; } - - bool IsTokenPtrNull() const { return !this->TokenCredential::m_token; } - - std::string GetTokenString() const { return this->TokenCredential::m_token->m_tokenString; } - - std::chrono::system_clock::time_point GetExpiration() const - { - return this->TokenCredential::m_token->m_expiresAt; - } - -private: - void RefreshToken( - std::string& newTokenString, - std::chrono::system_clock::time_point& newExpiration) override - { - newTokenString = this->NewTokenString; - newExpiration = this->NewExpiration; - } - - bool IsTokenExpired(std::chrono::system_clock::time_point const&) const override - { - return this->IsExpired; - } -}; - -TEST(Credential, ClientSecretCredential) -{ - // Client Secret credential properties - std::string const tenantId = "tenantId"; - std::string const clientId = "clientId"; - std::string const clientSecret = "clientSecret"; - - Credentials::Details::CredentialTest clientSecretCredential(tenantId, clientId, clientSecret); - - EXPECT_EQ(clientSecretCredential.GetTenantId(), tenantId); - EXPECT_EQ(clientSecretCredential.GetClientId(), clientId); - EXPECT_EQ(clientSecretCredential.GetClientSecret(), clientSecret); - - // Token credential - { - auto const emptyString = std::string(); - auto const defaultTime = std::chrono::system_clock::time_point(); - { - // Default values - { - EXPECT_EQ(clientSecretCredential.IsTokenPtrNull(), true); - } - - { - // Set scopes - std::string const scopes = "scope"; - { - Credentials::Credential::Internal::SetScopes(clientSecretCredential, scopes); - EXPECT_EQ(clientSecretCredential.IsTokenPtrNull(), true); - } - - // Get token - { - std::string const olderToken = "olderToken"; - std::string const newToken = "newToken"; - auto const olderTime = defaultTime + std::chrono::minutes(10); - auto const newTime = olderTime + std::chrono::minutes(10); - - { - clientSecretCredential.IsExpired = true; - clientSecretCredential.NewTokenString = olderToken; - clientSecretCredential.NewExpiration = olderTime; - - auto const tokenReceived - = Credentials::TokenCredential::Internal::GetToken(clientSecretCredential); - - EXPECT_EQ(clientSecretCredential.IsTokenPtrNull(), false); - EXPECT_EQ(tokenReceived, olderToken); - EXPECT_EQ(clientSecretCredential.GetTokenString(), olderToken); - EXPECT_EQ(clientSecretCredential.GetScopes(), scopes); - EXPECT_EQ(clientSecretCredential.GetExpiration(), olderTime); - } - - // Attemp to get the token when it is not expired yet - { - clientSecretCredential.IsExpired = false; - clientSecretCredential.NewTokenString = newToken; - clientSecretCredential.NewExpiration = newTime; - - auto const tokenReceived - = Credentials::TokenCredential::Internal::GetToken(clientSecretCredential); - - EXPECT_EQ(tokenReceived, olderToken); - EXPECT_EQ(clientSecretCredential.GetTokenString(), olderToken); - EXPECT_EQ(clientSecretCredential.GetScopes(), scopes); - EXPECT_EQ(clientSecretCredential.GetExpiration(), olderTime); - } - - // Attempt to get token after it expired - { - clientSecretCredential.IsExpired = true; - - auto const tokenReceived - = Credentials::TokenCredential::Internal::GetToken(clientSecretCredential); - - EXPECT_EQ(tokenReceived, newToken); - EXPECT_EQ(clientSecretCredential.GetTokenString(), newToken); - EXPECT_EQ(clientSecretCredential.GetScopes(), scopes); - EXPECT_EQ(clientSecretCredential.GetExpiration(), newTime); - - clientSecretCredential.IsExpired = false; - } - - // Setting the very same scopes set earlier does not reset token - { - std::string const scopesCopy - = scopes.substr(0, scopes.length() / 2) + scopes.substr(scopes.length() / 2); - - { - auto const scopesPtr = scopes.c_str(); - auto const scopesCopyPtr = scopesCopy.c_str(); - EXPECT_NE(scopesPtr, scopesCopyPtr); - EXPECT_EQ(scopes, scopesCopy); - } - - Credentials::Credential::Internal::SetScopes(clientSecretCredential, scopesCopy); - - EXPECT_EQ(clientSecretCredential.GetTenantId(), tenantId); - EXPECT_EQ(clientSecretCredential.GetClientId(), clientId); - EXPECT_EQ(clientSecretCredential.GetClientSecret(), clientSecret); - - auto const tokenReceived - = Credentials::TokenCredential::Internal::GetToken(clientSecretCredential); - - EXPECT_EQ(tokenReceived, newToken); - EXPECT_EQ(clientSecretCredential.GetTokenString(), newToken); - EXPECT_EQ(clientSecretCredential.GetScopes(), scopes); - EXPECT_EQ(clientSecretCredential.GetExpiration(), newTime); - } - - // Updating scopes does reset the token - { - clientSecretCredential.IsExpired = false; - - std::string const anotherScopes = "anotherScopes"; - std::string const anotherToken = "anotherToken"; - auto const anotherTime = newTime + std::chrono::minutes(10); - - clientSecretCredential.NewTokenString = anotherToken; - clientSecretCredential.NewExpiration = anotherTime; - - auto tokenReceived - = Credentials::TokenCredential::Internal::GetToken(clientSecretCredential); - - EXPECT_EQ(tokenReceived, newToken); - EXPECT_EQ(clientSecretCredential.GetTokenString(), newToken); - EXPECT_EQ(clientSecretCredential.GetScopes(), scopes); - EXPECT_EQ(clientSecretCredential.GetExpiration(), newTime); - - Credentials::Credential::Internal::SetScopes( - clientSecretCredential, std::string(anotherScopes)); - - EXPECT_EQ(clientSecretCredential.GetTenantId(), tenantId); - EXPECT_EQ(clientSecretCredential.GetClientId(), clientId); - EXPECT_EQ(clientSecretCredential.GetClientSecret(), clientSecret); - EXPECT_EQ(clientSecretCredential.GetScopes(), anotherScopes); - EXPECT_EQ(clientSecretCredential.IsTokenPtrNull(), true); - - tokenReceived - = Credentials::TokenCredential::Internal::GetToken(clientSecretCredential); - - EXPECT_EQ(clientSecretCredential.IsTokenPtrNull(), false); - EXPECT_EQ(tokenReceived, anotherToken); - EXPECT_EQ(clientSecretCredential.GetTokenString(), anotherToken); - EXPECT_EQ(clientSecretCredential.GetScopes(), anotherScopes); - EXPECT_EQ(clientSecretCredential.GetExpiration(), anotherTime); - } - } - } - } - } -} diff --git a/sdk/storage/test/CMakeLists.txt b/sdk/storage/test/CMakeLists.txt index d9626ddab..6575d30f9 100644 --- a/sdk/storage/test/CMakeLists.txt +++ b/sdk/storage/test/CMakeLists.txt @@ -1,29 +1,30 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # SPDX-License-Identifier: MIT -cmake_minimum_required (VERSION 3.15) - -add_executable ( - azure-storage-test - test_base.hpp - test_base.cpp - blob_service_client_test.cpp - blob_container_client_test.hpp - blob_container_client_test.cpp - block_blob_client_test.hpp - block_blob_client_test.cpp - append_blob_client_test.hpp - append_blob_client_test.cpp - page_blob_client_test.hpp - page_blob_client_test.cpp - main.cpp -) - -target_link_libraries(azure-storage-test PRIVATE azure-storage) - -if (MSVC) - target_compile_options(azure-storage-test PRIVATE /wd6326 /wd26495 /wd26812) -endif() - -add_gtest(azure-storage-test) +### https://github.com/Azure/azure-sdk-for-cpp/issues/224 ### +#cmake_minimum_required (VERSION 3.15) +# +#add_executable ( +# azure-storage-test +# test_base.hpp +# test_base.cpp +# blob_service_client_test.cpp +# blob_container_client_test.hpp +# blob_container_client_test.cpp +# block_blob_client_test.hpp +# block_blob_client_test.cpp +# append_blob_client_test.hpp +# append_blob_client_test.cpp +# page_blob_client_test.hpp +# page_blob_client_test.cpp +# main.cpp +#) +# +#target_link_libraries(azure-storage-test PRIVATE azure-storage) +# +#if (MSVC) +# target_compile_options(azure-storage-test PRIVATE /wd6326 /wd26495 /wd26812) +#endif() +# +#add_gtest(azure-storage-test)