[Keyvault] CreateKey API (#1459)

* mandatory data for create

* createKey API added with partial serialize/de-serialize
This commit is contained in:
Victor Vazquez 2021-01-28 10:46:07 -08:00 committed by GitHub
parent ee156b6505
commit 3b9a465a4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 534 additions and 70 deletions

View File

@ -51,6 +51,7 @@ set(
inc/azure/core/http/policy.hpp
inc/azure/core/http/transport.hpp
inc/azure/core/internal/contract.hpp
inc/azure/core/internal/json_serializable.hpp
inc/azure/core/internal/json.hpp
inc/azure/core/internal/log.hpp
inc/azure/core/internal/strings.hpp

View File

@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Internal interface for serializable classes.
*
*/
#pragma once
#include <string>
namespace Azure { namespace Core { namespace Internal { namespace Json {
/**
* @brief Interface for json-serializable components.
*
*/
class JsonSerializable {
public:
/**
* @brief Serialize object as json string.
*
* @return The json string representation.
*/
virtual std::string Serialize() const = 0;
};
}}}} // namespace Azure::Core::Internal::Json

View File

@ -2,3 +2,6 @@
## 4.0.0-beta.1 (Unreleased)
### New Features
- KeyVaultException.

View File

@ -28,9 +28,9 @@ endif()
set(
AZURE_KEYVAULT_COMMON_HEADER
inc/azure/keyvault/common/internal/keyvault_pipeline.hpp
inc/azure/keyvault/common/keyvault_constants.hpp
inc/azure/keyvault/common/keyvault_exception.hpp
inc/azure/keyvault/common/keyvault_pipeline.hpp
inc/azure/keyvault/common/version.hpp
)

View File

@ -1,11 +1,19 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Provides a wrapper class for the Azure Core Pipeline for all Key Vault services where
* common functionality is set up.
*
*/
#pragma once
#include <azure/core/context.hpp>
#include <azure/core/http/http.hpp>
#include <azure/core/http/pipeline.hpp>
#include <azure/core/internal/json.hpp>
#include <azure/core/internal/json_serializable.hpp>
#include <azure/core/response.hpp>
#include <functional>
@ -34,6 +42,26 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Common { n
Azure::Core::Http::HttpMethod method,
std::vector<std::string> const& path) const;
/**
* @brief Create a Key Vault request with payload.
*
* @param method The HTTP method.
* @param content The HTTP payload.
* @param path The HTTP request path.
* @return A constructed request.
*/
Azure::Core::Http::Request CreateRequest(
Azure::Core::Http::HttpMethod method,
Azure::Core::Http::BodyStream* content,
std::vector<std::string> const& path) const;
/**
* @brief Start the http transfer based on the \p request.
*
* @param context The context for per-operation options or cancellation.
* @param request The HTTP request to be sent.
* @return The raw response from the network.
*/
std::unique_ptr<Azure::Core::Http::RawResponse> SendRequest(
Azure::Core::Context const& context,
Azure::Core::Http::Request& request) const;
@ -54,15 +82,14 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Common { n
}
/**
* @brief Create and send the HTTP request using. Uses the result factory function to create
* @brief Create and send the HTTP request. Uses the \p factoryFn function to create
* the response type.
*
*
* @param context The context for per-operation options or cancellation.
* @param method The method for the request.
* @param factoryFn The function to deserialize and produce T from the raw response.
* @param path A path for the request represented as a vector of strings.
* @return Azure::Core::Response<TResult>
* @return The object produced by the \p factoryFn and the raw response from the network.
*/
template <class T>
Azure::Core::Response<T> SendRequest(
@ -75,5 +102,33 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Common { n
auto response = SendRequest(context, request);
return Azure::Core::Response<T>(factoryFn(*response), std::move(response));
}
/**
* @brief Create and send the HTTP request with payload content. Uses the \p factoryFn function
* to create the response type.
*
* @param context The context for per-operation options or cancellation.
* @param method The method for the request.
* @param content The HTTP payload.
* @param factoryFn The function to deserialize and produce T from the raw response.
* @param path A path for the request represented as a vector of strings.
* @return The object produced by the \p factoryFn and the raw response from the network.
*/
template <class T>
Azure::Core::Response<T> SendRequest(
Azure::Core::Context const& context,
Azure::Core::Http::HttpMethod method,
Azure::Core::Internal::Json::JsonSerializable const& content,
std::function<T(Azure::Core::Http::RawResponse const& rawResponse)> factoryFn,
std::vector<std::string> const& path)
{
auto serialContent = content.Serialize();
auto streamContent = Azure::Core::Http::MemoryBodyStream(
reinterpret_cast<const uint8_t*>(serialContent.data()), serialContent.size());
auto request = CreateRequest(method, &streamContent, path);
auto response = SendRequest(context, request);
return Azure::Core::Response<T>(factoryFn(*response), std::move(response));
}
};
}}}}} // namespace Azure::Security::KeyVault::Common::Internal

View File

@ -1,6 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Provide string constants used for all the Key Vault services.
*
*/
#pragma once
namespace Azure { namespace Security { namespace KeyVault { namespace Common { namespace Details {

View File

@ -1,6 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Defines a general exception for Key Vault service clients.
*
*/
#pragma once
#include <azure/core/http/http.hpp>

View File

@ -1,6 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief This file is used for automatic release operations.
*
*/
#pragma once
#include <string>

View File

@ -1,17 +1,33 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
#include "azure/keyvault/common/keyvault_pipeline.hpp"
#include "azure/keyvault/common/internal/keyvault_pipeline.hpp"
#include "azure/keyvault/common/keyvault_constants.hpp"
#include "azure/keyvault/common/keyvault_exception.hpp"
using namespace Azure::Security::KeyVault::Common;
namespace {
inline Azure::Core::Http::Request InitRequest(
Azure::Core::Http::HttpMethod method,
Azure::Core::Http::BodyStream* content,
Azure::Core::Http::Url const& url)
{
if (content == nullptr)
{
return Azure::Core::Http::Request(method, url);
}
return Azure::Core::Http::Request(method, url, content);
}
} // namespace
Azure::Core::Http::Request Internal::KeyVaultPipeline::CreateRequest(
Azure::Core::Http::HttpMethod method,
Azure::Core::Http::BodyStream* content,
std::vector<std::string> const& path) const
{
Azure::Core::Http::Request request(method, m_vaultUrl);
auto request = ::InitRequest(method, content, m_vaultUrl);
request.AddHeader(Details::ContentType, Details::ApplicationJson);
request.AddHeader(Details::Accept, Details::ApplicationJson);
@ -28,6 +44,13 @@ Azure::Core::Http::Request Internal::KeyVaultPipeline::CreateRequest(
return request;
}
Azure::Core::Http::Request Internal::KeyVaultPipeline::CreateRequest(
Azure::Core::Http::HttpMethod method,
std::vector<std::string> const& path) const
{
return CreateRequest(method, nullptr, path);
}
std::unique_ptr<Azure::Core::Http::RawResponse> Internal::KeyVaultPipeline::SendRequest(
Azure::Core::Context const& context,
Azure::Core::Http::Request& request) const

View File

@ -21,7 +21,10 @@ endif()
target_link_libraries(azure-security-keyvault-common-test PUBLIC azure-security-keyvault-common gtest gmock)
# gtest_add_tests will scan the test from azure-core-test and call add_test
# gtest_discover_tests will scan the test from azure-core-test and call add_test
# for each test to ctest. This enables `ctest -r` to run specific tests directly.
gtest_add_tests(TARGET azure-security-keyvault-common-test
TEST_PREFIX azure-security-keyvault-common-unittest.)
gtest_discover_tests(azure-security-keyvault-common-test
TEST_PREFIX azure-security-keyvault-common-unittest.
NO_PRETTY_TYPES
NO_PRETTY_VALUES
)

View File

@ -5,7 +5,7 @@
#include <azure/core/http/http.hpp>
#include <azure/core/http/policy.hpp>
#include <azure/keyvault/common/keyvault_pipeline.hpp>
#include <azure/keyvault/common/internal/keyvault_pipeline.hpp>
#include <memory>

View File

@ -2,3 +2,10 @@
## 4.0.0-beta.1 (Unreleased)
### New Features
- KeyVault client with the next operations:
- GetKey.
- CreateKey.
- General purpose header `key_vault.hpp`.
- KeyVault Keys types.

View File

@ -30,10 +30,13 @@ set(
AZURE_KEYVAULT_KEYS_HEADER
inc/azure/keyvault/keys/json_web_key.hpp
inc/azure/keyvault/keys/key_client.hpp
inc/azure/keyvault/keys/key_constants.hpp
inc/azure/keyvault/keys/key_create_options.hpp
inc/azure/keyvault/keys/key_client_options.hpp
inc/azure/keyvault/keys/key_operation.hpp
inc/azure/keyvault/keys/key_properties.hpp
inc/azure/keyvault/keys/key_release_policy.hpp
inc/azure/keyvault/keys/key_request_parameters.hpp
inc/azure/keyvault/keys/key_type.hpp
inc/azure/keyvault/keys/key_vault_key.hpp
inc/azure/keyvault/keys/version.hpp
@ -42,6 +45,7 @@ set(
set(
AZURE_KEYVAULT_KEYS_SOURCE
src/key_client.cpp
src/key_request_parameters.cpp
src/key_type.cpp
src/key_vault_key.cpp
)

View File

@ -1,6 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief General purpose header for Key Vault keys functionaly.
*
*/
#pragma once
#include "azure/keyvault/keys/dll_import_export.hpp"

View File

@ -1,8 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Defines the JsonWebKey.
*
*/
#pragma once
#include "azure/keyvault/keys/key_constants.hpp"
#include "azure/keyvault/keys/key_operation.hpp"
#include "azure/keyvault/keys/key_type.hpp"
@ -11,25 +17,6 @@
namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
namespace Details {
constexpr static const char* KeyIdPropertyName = "kid";
constexpr static const char* KeyTypePropertyName = "kty";
constexpr static const char* KeyOpsPropertyName = "key_ops";
constexpr static const char* CurveNamePropertyName = "crv";
constexpr static const char* NPropertyName = "n";
constexpr static const char* EPropertyName = "e";
constexpr static const char* DPPropertyName = "dp";
constexpr static const char* DQPropertyName = "dq";
constexpr static const char* QIPropertyName = "qi";
constexpr static const char* PPropertyName = "p";
constexpr static const char* QPropertyName = "q";
constexpr static const char* XPropertyName = "x";
constexpr static const char* YPropertyName = "y";
constexpr static const char* DPropertyName = "d";
constexpr static const char* KPropertyName = "k";
constexpr static const char* TPropertyName = "key_hsm";
} // namespace Details
struct JsonWebKey
{
/**

View File

@ -1,14 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Defines the Key Vault Keys client.
*
*/
#pragma once
#include <azure/core/credentials.hpp>
#include <azure/core/http/http.hpp>
#include <azure/core/response.hpp>
#include <azure/keyvault/common/keyvault_pipeline.hpp>
#include <azure/keyvault/common/internal/keyvault_pipeline.hpp>
#include "azure/keyvault/keys/key_client_options.hpp"
#include "azure/keyvault/keys/key_constants.hpp"
#include "azure/keyvault/keys/key_create_options.hpp"
#include "azure/keyvault/keys/key_request_parameters.hpp"
#include "azure/keyvault/keys/key_type.hpp"
#include "azure/keyvault/keys/key_vault_key.hpp"
#include <functional>
@ -16,11 +25,6 @@
namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
namespace Details {
constexpr static const char* KeysPath = "keys";
constexpr static const char* DeletedKeysPath = "deletedkeys";
} // namespace Details
/**
* @brief The KeyClient provides synchronous methods to manage a KeyVaultKe in the Azure Key
* Vault. The client supports creating, retrieving, updating, deleting, purging, backing up,
@ -52,11 +56,11 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
/**
* @brief Context for cancelling long running operations.
*/
Azure::Core::Context context;
Azure::Core::Context Context;
/**
* @brief Specify the key version to get.
*/
std::string version;
std::string Version;
};
/**
@ -75,12 +79,38 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
GetKeyOptions const& options = GetKeyOptions()) const
{
return m_pipeline->SendRequest<KeyVaultKey>(
options.context,
options.Context,
Azure::Core::Http::HttpMethod::Get,
[name](Azure::Core::Http::RawResponse const& rawResponse) {
return Details::KeyVaultKeyDeserialize(name, rawResponse);
},
{Details::KeysPath, name, options.version});
{Details::KeysPath, name, options.Version});
}
/**
* @brief Creates and stores a new key in Key Vault. The create key operation can be used to
* create any key type in Azure Key Vault. If the named key already exists, Azure Key Vault
* creates a new version of the key. It requires the keys/create permission.
*
* @param name The name of the key.
* @param keyType The type of key to create. See #Azure::Security::KeyVault::Keys::KeyTypeEnum.
* @param options Optional parameters for this operation. See
* #Azure::Security::KeyVault::Keys::CreateKeyOptions.
* @return The Key wrapped in the Response.
*/
Azure::Core::Response<KeyVaultKey> CreateKey(
std::string const& name,
KeyTypeEnum keyType,
CreateKeyOptions const& options = CreateKeyOptions()) const
{
return m_pipeline->SendRequest<KeyVaultKey>(
options.Context,
Azure::Core::Http::HttpMethod::Post,
Details::KeyRequestParameters(keyType, options),
[name](Azure::Core::Http::RawResponse const& rawResponse) {
return Details::KeyVaultKeyDeserialize(name, rawResponse);
},
{Details::KeysPath, name, "create"});
}
};

View File

@ -1,11 +1,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Defines the supported options to create a Key Vault Keys client.
*
*/
#pragma once
#include <azure/core/http/http.hpp>
#include <azure/core/response.hpp>
#include <azure/keyvault/common/keyvault_pipeline.hpp>
#include "azure/keyvault/keys/key_vault_key.hpp"
@ -24,7 +28,7 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
Azure::Core::Http::RetryOptions RetryOptions;
Azure::Core::Http::TransportPolicyOptions TransportPolicyOptions;
KeyClientOptions(ServiceVersion version = ServiceVersion::V7_1) : Version(version) {}
KeyClientOptions(ServiceVersion version = ServiceVersion::V7_2) : Version(version) {}
std::string GetVersionString()
{
@ -34,6 +38,8 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
return "7.0";
case ServiceVersion::V7_1:
return "7.1";
case ServiceVersion::V7_2:
return "7.2";
default:
throw std::runtime_error("Version not found");
}

View File

@ -0,0 +1,55 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Centralize the string constants used by Key Vault Keys Client.
*
*/
#pragma once
namespace Azure { namespace Security { namespace KeyVault { namespace Keys { namespace Details {
/***************** KeyVault Key *****************/
constexpr static const char KeyPropertyName[] = "key";
/***************** Key Client *****************/
constexpr static const char KeysPath[] = "keys";
constexpr static const char DeletedKeysPath[] = "deletedkeys";
/***************** Key Properties *****************/
constexpr static const char ManagedPropertyName[] = "managed";
constexpr static const char AttributesPropertyName[] = "attributes";
constexpr static const char TagsPropertyName[] = "tags";
constexpr static const char ReleasePolicyPropertyName[] = "release_policy";
/***************** Key Request Parameters *****************/
constexpr static const char KeyTypePropertyName[] = "kty";
constexpr static const char KeySizePropertyName[] = "key_size";
constexpr static const char KeyOpsPropertyName[] = "key_ops";
constexpr static const char CurveNamePropertyName[] = "crv";
constexpr static const char PublicExponentPropertyName[] = "public_exponent";
/***************** JsonWebKey *****************/
constexpr static const char KeyIdPropertyName[] = "kid";
constexpr static const char NPropertyName[] = "n";
constexpr static const char EPropertyName[] = "e";
constexpr static const char DPPropertyName[] = "dp";
constexpr static const char DQPropertyName[] = "dq";
constexpr static const char QIPropertyName[] = "qi";
constexpr static const char PPropertyName[] = "p";
constexpr static const char QPropertyName[] = "q";
constexpr static const char XPropertyName[] = "x";
constexpr static const char YPropertyName[] = "y";
constexpr static const char DPropertyName[] = "d";
constexpr static const char KPropertyName[] = "k";
constexpr static const char TPropertyName[] = "key_hsm";
/***************** KeyType *****************/
constexpr static const char EcValue[] = "EC";
constexpr static const char EcHsmValue[] = "EC-HSM";
constexpr static const char RsaValue[] = "RSA";
constexpr static const char RsaHsmValue[] = "RSA-HSM";
constexpr static const char OctValue[] = "oct";
constexpr static const char OctHsmValue[] = "oct-HSM";
}}}}} // namespace Azure::Security::KeyVault::Keys::Details

View File

@ -0,0 +1,41 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Defines the supported options to create a Key Vault Key.
*
*/
#pragma once
#include <azure/core/context.hpp>
#include <azure/core/datetime.hpp>
#include <azure/core/nullable.hpp>
#include "azure/keyvault/keys/key_operation.hpp"
#include <list>
#include <string>
#include <unordered_map>
namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
struct CreateKeyOptions
{
/**
* @brief Context for cancelling long running operations.
*/
Azure::Core::Context Context;
std::list<KeyOperation> KeyOperations;
Azure::Core::Nullable<Azure::Core::DateTime> NotBefore;
Azure::Core::Nullable<Azure::Core::DateTime> ExpiresOn;
Azure::Core::Nullable<bool> Enabled;
std::unordered_map<std::string, std::string> Tags;
};
}}}} // namespace Azure::Security::KeyVault::Keys

View File

@ -1,6 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Defines the Key Vault KeyOperation.
*
*/
#pragma once
#include <string>

View File

@ -1,6 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Defines the Key Vault Key properties.
*
*/
#pragma once
#include <azure/core/datetime.hpp>
@ -13,13 +18,6 @@
namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
namespace Details {
constexpr static const char* ManagedPropertyName = "managed";
constexpr static const char* AttributesPropertyName = "attributes";
constexpr static const char* TagsPropertyName = "tags";
constexpr static const char* ReleasePolicyPropertyName = "release_policy";
} // namespace Details
struct KeyProperties
{
std::string Name;

View File

@ -1,6 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Defines the KeyReleasePolicy.
*
*/
#pragma once
#include <string>

View File

@ -0,0 +1,37 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Internal implementation for sending the HTTP request.
*
*/
#pragma once
#include <azure/core/internal/json_serializable.hpp>
#include <azure/core/nullable.hpp>
#include "azure/keyvault/keys/key_create_options.hpp"
#include "azure/keyvault/keys/key_type.hpp"
#include <functional>
#include <memory>
#include <string>
#include <vector>
namespace Azure { namespace Security { namespace KeyVault { namespace Keys { namespace Details {
class KeyRequestParameters : public Azure::Core::Internal::Json::JsonSerializable {
private:
KeyTypeEnum m_keyType;
CreateKeyOptions const& m_options;
public:
explicit KeyRequestParameters(KeyTypeEnum keyType, CreateKeyOptions const& options)
: m_keyType(keyType), m_options(options)
{
}
std::string Serialize() const override;
};
}}}}} // namespace Azure::Security::KeyVault::Keys::Details

View File

@ -1,21 +1,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Defines the KeyTypeEnum.
*
*/
#pragma once
#include <string>
namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
namespace Details {
constexpr static const char* EcValue = "EC";
constexpr static const char* EcHsmValue = "EC-HSM";
constexpr static const char* RsaValue = "RSA";
constexpr static const char* RsaHsmValue = "RSA-HSM";
constexpr static const char* OctValue = "oct";
constexpr static const char* OctHsmValue = "oct-HSM";
} // namespace Details
enum class KeyTypeEnum
{
Ec,

View File

@ -1,9 +1,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief Defines the Key Vault Key.
*
*/
#pragma once
#include "azure/keyvault/keys/json_web_key.hpp"
#include "azure/keyvault/keys/key_constants.hpp"
#include "azure/keyvault/keys/key_operation.hpp"
#include "azure/keyvault/keys/key_properties.hpp"
@ -13,10 +19,6 @@
namespace Azure { namespace Security { namespace KeyVault { namespace Keys {
namespace Details {
constexpr static const char* KeyPropertyName = "key";
} // namespace Details
struct KeyVaultKey
{
JsonWebKey Key;

View File

@ -1,6 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @brief This file is used for automatic release operations.
*
*/
#pragma once
#include <string>

View File

@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
#include <azure/core/internal/json.hpp>
#include "azure/keyvault/keys/key_constants.hpp"
#include "azure/keyvault/keys/key_request_parameters.hpp"
#include <string>
using namespace Azure::Security::KeyVault::Keys::Details;
std::string KeyRequestParameters::Serialize() const
{
Azure::Core::Internal::Json::json payload;
/* Mandatory */
// kty
payload[Details::KeyTypePropertyName] = KeyTypeToString(m_keyType);
/* Optional */
// key_size
// public_exponent
// key_ops
for (KeyOperation op : m_options.KeyOperations)
{
payload[Details::KeyOpsPropertyName].push_back(op.ToString());
}
// attributes
// tags
for (auto tag : m_options.Tags)
{
payload[Details::TagsPropertyName][tag.first] = tag.second;
}
// crv
// release_policy
return payload.dump();
}

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: MIT
#include "azure/keyvault/keys/key_type.hpp"
#include "azure/keyvault/keys/key_constants.hpp"
#include <stdexcept>

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: MIT
#include "azure/keyvault/keys/key_vault_key.hpp"
#include "azure/keyvault/keys/key_constants.hpp"
#include <azure/core/internal/json.hpp>
@ -26,17 +27,30 @@ KeyVaultKey Details::KeyVaultKeyDeserialize(
auto body = rawResponse.GetBody();
auto jsonParser = Azure::Core::Internal::Json::json::parse(body);
// "Key"
KeyVaultKey key(name);
auto const& jsonKey = jsonParser["key"];
auto const& jsonKey = jsonParser[Details::KeyPropertyName];
{
auto keyOperationVector = jsonKey["key_ops"].get<std::vector<std::string>>();
// key_ops
auto keyOperationVector = jsonKey[Details::KeyOpsPropertyName].get<std::vector<std::string>>();
std::vector<KeyOperation> keyOperations;
ParseStringOperationsToKeyOperations(keyOperations, keyOperationVector);
key.Key.SetKeyOperations(keyOperations);
}
key.Key.Id = jsonKey[Details::KeyIdPropertyName].get<std::string>();
key.Key.KeyType
= Details::KeyTypeFromString(jsonKey[Details::KeyTypePropertyName].get<std::string>());
key.Key.Id = jsonKey["kid"].get<std::string>();
key.Key.KeyType = Details::KeyTypeFromString(jsonKey["kty"].get<std::string>());
// "Attributes"
// "Tags"
auto const& tags = jsonParser[Details::TagsPropertyName];
{
for (auto tag = tags.begin(); tag != tags.end(); ++tag)
{
key.Properties.Tags.emplace(tag.key(), tag.value().get<std::string>());
}
}
return key;
}

View File

@ -41,7 +41,10 @@ endif()
target_link_libraries(azure-security-keyvault-keys-test-live PRIVATE azure-security-keyvault-keys azure-identity gtest gmock)
# gtest_add_tests will scan the test from azure-core-test and call add_test
# gtest_discover_tests will scan the test from azure-core-test and call add_test
# for each test to ctest. This enables `ctest -r` to run specific tests directly.
gtest_add_tests(TARGET azure-security-keyvault-keys-test-live
TEST_PREFIX azure-security-keyvault-keys-livetest.)
gtest_discover_tests(azure-security-keyvault-keys-test-live
TEST_PREFIX azure-security-keyvault-keys-livetest.
NO_PRETTY_TYPES
NO_PRETTY_VALUES
)

View File

@ -13,6 +13,17 @@
#include <string>
namespace {
template <class T>
void CheckValidResponse(
Azure::Core::Response<T>& response,
Azure::Core::Http::HttpStatusCode expectedCode = Azure::Core::Http::HttpStatusCode::Ok)
{
auto rawResponse = response.ExtractRawResponse();
EXPECT_EQ(rawResponse->GetStatusCode(), expectedCode);
}
} // namespace
using namespace Azure::Security::KeyVault::Keys::Test;
TEST_F(KeyVaultClientTest, GetKey)
@ -21,9 +32,92 @@ TEST_F(KeyVaultClientTest, GetKey)
// Assuming and RS Key exists in the KeyVault Account.
std::string keyName("testKey");
auto r = keyClient.GetKey(keyName);
auto key = r.ExtractValue();
auto keyResponse = keyClient.GetKey(keyName);
CheckValidResponse(keyResponse);
auto key = keyResponse.ExtractValue();
EXPECT_EQ(key.Name(), keyName);
EXPECT_EQ(key.GetKeyType(), Azure::Security::KeyVault::Keys::KeyTypeEnum::Rsa);
}
TEST_F(KeyVaultClientTest, CreateKey)
{
Azure::Security::KeyVault::Keys::KeyClient keyClient(m_keyVaultUrl, m_credential);
std::string keyName("createKey");
{
auto keyResponse
= keyClient.CreateKey(keyName, Azure::Security::KeyVault::Keys::KeyTypeEnum::Ec);
CheckValidResponse(keyResponse);
auto keyVaultKey = keyResponse.ExtractValue();
EXPECT_EQ(keyVaultKey.Name(), keyName);
}
{
// Now get the key
auto keyResponse = keyClient.GetKey(keyName);
CheckValidResponse(keyResponse);
auto keyVaultKey = keyResponse.ExtractValue();
EXPECT_EQ(keyVaultKey.Name(), keyName);
}
}
TEST_F(KeyVaultClientTest, CreateKeyWithOptions)
{
Azure::Security::KeyVault::Keys::KeyClient keyClient(m_keyVaultUrl, m_credential);
std::string keyName("createKeyWithOptions");
Azure::Security::KeyVault::Keys::CreateKeyOptions options;
options.KeyOperations.push_back(Azure::Security::KeyVault::Keys::KeyOperation::Sign());
options.KeyOperations.push_back(Azure::Security::KeyVault::Keys::KeyOperation::Verify());
{
auto keyResponse
= keyClient.CreateKey(keyName, Azure::Security::KeyVault::Keys::KeyTypeEnum::Ec, options);
CheckValidResponse(keyResponse);
auto keyVaultKey = keyResponse.ExtractValue();
EXPECT_EQ(keyVaultKey.Name(), keyName);
EXPECT_EQ(keyVaultKey.GetKeyType(), Azure::Security::KeyVault::Keys::KeyTypeEnum::Ec);
auto& keyOperations = keyVaultKey.KeyOperations();
uint16_t expectedSize = 2;
EXPECT_EQ(keyOperations.size(), expectedSize);
auto findOperation = [keyOperations](Azure::Security::KeyVault::Keys::KeyOperation op) {
for (Azure::Security::KeyVault::Keys::KeyOperation operation : keyOperations)
{
if (operation.ToString() == op.ToString())
{
return true;
}
}
return false;
};
EXPECT_PRED1(findOperation, Azure::Security::KeyVault::Keys::KeyOperation::Sign());
EXPECT_PRED1(findOperation, Azure::Security::KeyVault::Keys::KeyOperation::Verify());
}
}
TEST_F(KeyVaultClientTest, CreateKeyWithTags)
{
Azure::Security::KeyVault::Keys::KeyClient keyClient(m_keyVaultUrl, m_credential);
std::string keyName("myKeyWithOptionsTags");
Azure::Security::KeyVault::Keys::CreateKeyOptions options;
options.Tags.emplace("one", "value=1");
options.Tags.emplace("two", "value=2");
{
auto keyResponse
= keyClient.CreateKey(keyName, Azure::Security::KeyVault::Keys::KeyTypeEnum::Rsa, options);
CheckValidResponse(keyResponse);
auto keyVaultKey = keyResponse.ExtractValue();
EXPECT_EQ(keyVaultKey.Name(), keyName);
EXPECT_EQ(keyVaultKey.GetKeyType(), Azure::Security::KeyVault::Keys::KeyTypeEnum::Rsa);
auto findTag = [keyVaultKey](std::string key, std::string value) {
// Will throw if key is not found
auto v = keyVaultKey.Properties.Tags.at(key);
return value == v;
};
}
}