Add credential classes (#42)
This commit is contained in:
parent
a6bb11ed01
commit
9631e5978a
@ -9,6 +9,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
add_library (
|
||||
azure-core
|
||||
src/credentials/credentials
|
||||
src/http/http
|
||||
src/http/request
|
||||
)
|
||||
|
||||
104
sdk/core/azure-core/inc/credentials/credentials.hpp
Normal file
104
sdk/core/azure-core/inc/credentials/credentials.hpp
Normal file
@ -0,0 +1,104 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
namespace azure
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
namespace credentials
|
||||
{
|
||||
|
||||
class Credential
|
||||
{
|
||||
virtual void SetScopes(std::string const& scopes) { (void)scopes; }
|
||||
|
||||
public:
|
||||
class Internal;
|
||||
virtual ~Credential() noexcept = default;
|
||||
|
||||
protected:
|
||||
Credential() = default;
|
||||
|
||||
Credential(Credential const& other) = default;
|
||||
Credential& operator=(Credential const& other) = default;
|
||||
};
|
||||
|
||||
class TokenCredential : public Credential
|
||||
{
|
||||
struct Token
|
||||
{
|
||||
public:
|
||||
std::string Scopes;
|
||||
std::string TokenString;
|
||||
std::chrono::system_clock::time_point ExpiresAt;
|
||||
};
|
||||
|
||||
Token m_token;
|
||||
mutable std::mutex m_tokenMutex;
|
||||
|
||||
void SetScopes(std::string const& scopes) override;
|
||||
|
||||
Token GetToken() const;
|
||||
|
||||
void SetToken(
|
||||
std::string const& tokenString,
|
||||
std::chrono::system_clock::time_point const& expiresAt);
|
||||
|
||||
void SetToken(Token const& token);
|
||||
|
||||
public:
|
||||
class Internal;
|
||||
|
||||
protected:
|
||||
TokenCredential() = default;
|
||||
|
||||
TokenCredential(TokenCredential const& other) : Credential(other), m_token(other.GetToken()) {}
|
||||
|
||||
TokenCredential& operator=(TokenCredential const& other)
|
||||
{
|
||||
this->SetToken(other.GetToken());
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class ClientSecretCredential : public TokenCredential
|
||||
{
|
||||
std::string m_tenantId;
|
||||
std::string m_clientId;
|
||||
std::string m_clientSecret;
|
||||
|
||||
public:
|
||||
class Internal;
|
||||
|
||||
ClientSecretCredential(
|
||||
std::string const& tenantId,
|
||||
std::string const& clientId,
|
||||
std::string const& clientSecret)
|
||||
: m_tenantId(tenantId), m_clientId(clientId), m_clientSecret(clientSecret)
|
||||
{
|
||||
}
|
||||
|
||||
ClientSecretCredential(ClientSecretCredential const& other)
|
||||
: TokenCredential(other), m_tenantId(other.m_tenantId), m_clientId(other.m_clientId),
|
||||
m_clientSecret(other.m_clientSecret)
|
||||
{
|
||||
}
|
||||
|
||||
ClientSecretCredential& operator=(ClientSecretCredential const& other)
|
||||
{
|
||||
this->m_tenantId = other.m_tenantId;
|
||||
this->m_clientId = other.m_clientId;
|
||||
this->m_clientSecret = other.m_clientSecret;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace credentials
|
||||
} // namespace core
|
||||
} // namespace azure
|
||||
62
sdk/core/azure-core/inc/internal/credentials_internal.hpp
Normal file
62
sdk/core/azure-core/inc/internal/credentials_internal.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <credentials/credentials.hpp>
|
||||
|
||||
namespace azure
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
namespace credentials
|
||||
{
|
||||
|
||||
class Credential::Internal
|
||||
{
|
||||
public:
|
||||
static void SetScopes(Credential& credential, std::string const& scopes)
|
||||
{
|
||||
credential.SetScopes(scopes);
|
||||
}
|
||||
};
|
||||
|
||||
class TokenCredential::Internal
|
||||
{
|
||||
public:
|
||||
static Token GetToken(TokenCredential const& credential)
|
||||
{
|
||||
return credential.GetToken();
|
||||
}
|
||||
|
||||
static void SetToken(
|
||||
TokenCredential& credential,
|
||||
std::string const& token,
|
||||
std::chrono::system_clock::time_point const& expiration)
|
||||
{
|
||||
credential.SetToken(token, expiration);
|
||||
}
|
||||
};
|
||||
|
||||
class ClientSecretCredential::Internal
|
||||
{
|
||||
public:
|
||||
static std::string const& GetTenantId(ClientSecretCredential const& credential)
|
||||
{
|
||||
return credential.m_tenantId;
|
||||
}
|
||||
|
||||
static std::string const& GetClientId(ClientSecretCredential const& credential)
|
||||
{
|
||||
return credential.m_clientId;
|
||||
}
|
||||
|
||||
static std::string const& GetClientSecret(ClientSecretCredential const& credential)
|
||||
{
|
||||
return credential.m_clientSecret;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace credentials
|
||||
} // namespace core
|
||||
} // namespace azure
|
||||
34
sdk/core/azure-core/src/credentials/credentials.cpp
Normal file
34
sdk/core/azure-core/src/credentials/credentials.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <credentials/credentials.hpp>
|
||||
|
||||
using namespace azure::core::credentials;
|
||||
|
||||
void TokenCredential::SetScopes(std::string const& scopes)
|
||||
{
|
||||
std::lock_guard<std::mutex> const lock(this->m_tokenMutex);
|
||||
if (this->m_token.Scopes != scopes)
|
||||
{
|
||||
this->m_token = { scopes, {}, {} };
|
||||
}
|
||||
}
|
||||
|
||||
TokenCredential::Token TokenCredential::GetToken() const
|
||||
{
|
||||
std::lock_guard<std::mutex> const lock(this->m_tokenMutex);
|
||||
return this->m_token;
|
||||
}
|
||||
|
||||
void TokenCredential::SetToken(
|
||||
std::string const& tokenString,
|
||||
std::chrono::system_clock::time_point const& expiresAt)
|
||||
{
|
||||
this->SetToken({ this->m_token.Scopes, tokenString, expiresAt });
|
||||
}
|
||||
|
||||
void TokenCredential::SetToken(Token const& token)
|
||||
{
|
||||
std::lock_guard<std::mutex> const lock(this->m_tokenMutex);
|
||||
this->m_token = token;
|
||||
}
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
#include <http/http.hpp>
|
||||
#include <http/request.hpp>
|
||||
#include <internal/credentials_internal.hpp>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
@ -148,4 +149,101 @@ TEST(Http_Request, add_path)
|
||||
[](std::string a, std::string b) { return a == b; },
|
||||
req.getEncodedUrl(),
|
||||
url + "/path/path2/path3?query=value");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Credential, ClientSecretCredential)
|
||||
{
|
||||
// Client Secret credential properties
|
||||
credentials::ClientSecretCredential clientSecretCredential(
|
||||
"tenantId", "clientId", "clientSecret");
|
||||
|
||||
EXPECT_EQ(
|
||||
credentials::ClientSecretCredential::Internal::GetTenantId(clientSecretCredential),
|
||||
"tenantId");
|
||||
|
||||
EXPECT_EQ(
|
||||
credentials::ClientSecretCredential::Internal::GetClientId(clientSecretCredential),
|
||||
"clientId");
|
||||
|
||||
EXPECT_EQ(
|
||||
credentials::ClientSecretCredential::Internal::GetClientSecret(clientSecretCredential),
|
||||
"clientSecret");
|
||||
|
||||
// Token credential
|
||||
{
|
||||
auto const emptyString = std::string();
|
||||
auto const defaultTime = std::chrono::system_clock::time_point();
|
||||
{
|
||||
// Default values
|
||||
{
|
||||
auto const initialToken
|
||||
= credentials::TokenCredential::Internal::GetToken(clientSecretCredential);
|
||||
|
||||
EXPECT_EQ(initialToken.TokenString, emptyString);
|
||||
EXPECT_EQ(initialToken.Scopes, emptyString);
|
||||
EXPECT_EQ(initialToken.ExpiresAt, defaultTime);
|
||||
}
|
||||
|
||||
{
|
||||
// Set scopes
|
||||
std::string const scopes = "scope";
|
||||
{
|
||||
credentials::Credential::Internal::SetScopes(clientSecretCredential, scopes);
|
||||
|
||||
auto const scopedToken
|
||||
= credentials::TokenCredential::Internal::GetToken(clientSecretCredential);
|
||||
|
||||
EXPECT_EQ(scopedToken.TokenString, emptyString);
|
||||
EXPECT_EQ(scopedToken.Scopes, scopes);
|
||||
EXPECT_EQ(scopedToken.ExpiresAt, defaultTime);
|
||||
}
|
||||
|
||||
// Set token
|
||||
{
|
||||
std::string const token = "token";
|
||||
auto const recentTime = std::chrono::system_clock::now();
|
||||
|
||||
{
|
||||
credentials::TokenCredential::Internal::SetToken(
|
||||
clientSecretCredential, token, recentTime);
|
||||
|
||||
auto const refreshedToken
|
||||
= credentials::TokenCredential::Internal::GetToken(clientSecretCredential);
|
||||
|
||||
EXPECT_EQ(refreshedToken.TokenString, token);
|
||||
EXPECT_EQ(refreshedToken.Scopes, scopes);
|
||||
EXPECT_EQ(refreshedToken.ExpiresAt, recentTime);
|
||||
}
|
||||
|
||||
// Setting the very same scopes set earlier does not reset token
|
||||
{
|
||||
credentials::Credential::Internal::SetScopes(
|
||||
clientSecretCredential, std::string(scopes));
|
||||
|
||||
auto const rescopedToken
|
||||
= credentials::TokenCredential::Internal::GetToken(clientSecretCredential);
|
||||
|
||||
EXPECT_EQ(rescopedToken.TokenString, token);
|
||||
EXPECT_EQ(rescopedToken.Scopes, scopes);
|
||||
EXPECT_EQ(rescopedToken.ExpiresAt, recentTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Updating scopes does reset the token
|
||||
{
|
||||
std::string const another_scopes = "another_scopes";
|
||||
|
||||
credentials::Credential::Internal::SetScopes(
|
||||
clientSecretCredential, std::string(another_scopes));
|
||||
|
||||
auto const resetToken
|
||||
= credentials::TokenCredential::Internal::GetToken(clientSecretCredential);
|
||||
|
||||
EXPECT_EQ(resetToken.TokenString, emptyString);
|
||||
EXPECT_EQ(resetToken.Scopes, another_scopes);
|
||||
EXPECT_EQ(resetToken.ExpiresAt, defaultTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user