diff --git a/sdk/core/azure-core/CMakeLists.txt b/sdk/core/azure-core/CMakeLists.txt index f23c34e67..153cd1a51 100644 --- a/sdk/core/azure-core/CMakeLists.txt +++ b/sdk/core/azure-core/CMakeLists.txt @@ -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 diff --git a/sdk/core/azure-core/inc/azure/core/internal/json_serializable.hpp b/sdk/core/azure-core/inc/azure/core/internal/json_serializable.hpp new file mode 100644 index 000000000..bdb90440c --- /dev/null +++ b/sdk/core/azure-core/inc/azure/core/internal/json_serializable.hpp @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +/** + * @brief Internal interface for serializable classes. + * + */ + +#pragma once + +#include + +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 diff --git a/sdk/keyvault/azure-security-keyvault-common/CHANGELOG.md b/sdk/keyvault/azure-security-keyvault-common/CHANGELOG.md index 2fcc5787f..74c5d6d05 100644 --- a/sdk/keyvault/azure-security-keyvault-common/CHANGELOG.md +++ b/sdk/keyvault/azure-security-keyvault-common/CHANGELOG.md @@ -2,3 +2,6 @@ ## 4.0.0-beta.1 (Unreleased) +### New Features + +- KeyVaultException. diff --git a/sdk/keyvault/azure-security-keyvault-common/CMakeLists.txt b/sdk/keyvault/azure-security-keyvault-common/CMakeLists.txt index 1d88baf2f..5310cd8e7 100644 --- a/sdk/keyvault/azure-security-keyvault-common/CMakeLists.txt +++ b/sdk/keyvault/azure-security-keyvault-common/CMakeLists.txt @@ -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 ) diff --git a/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_pipeline.hpp b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/internal/keyvault_pipeline.hpp similarity index 51% rename from sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_pipeline.hpp rename to sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/internal/keyvault_pipeline.hpp index 6a140d9c8..5e1ce476c 100644 --- a/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_pipeline.hpp +++ b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/internal/keyvault_pipeline.hpp @@ -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 #include #include +#include +#include #include #include @@ -34,6 +42,26 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Common { n Azure::Core::Http::HttpMethod method, std::vector 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 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 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 + * @return The object produced by the \p factoryFn and the raw response from the network. */ template Azure::Core::Response SendRequest( @@ -75,5 +102,33 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Common { n auto response = SendRequest(context, request); return Azure::Core::Response(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 + Azure::Core::Response SendRequest( + Azure::Core::Context const& context, + Azure::Core::Http::HttpMethod method, + Azure::Core::Internal::Json::JsonSerializable const& content, + std::function factoryFn, + std::vector const& path) + { + auto serialContent = content.Serialize(); + auto streamContent = Azure::Core::Http::MemoryBodyStream( + reinterpret_cast(serialContent.data()), serialContent.size()); + + auto request = CreateRequest(method, &streamContent, path); + auto response = SendRequest(context, request); + return Azure::Core::Response(factoryFn(*response), std::move(response)); + } }; }}}}} // namespace Azure::Security::KeyVault::Common::Internal diff --git a/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_constants.hpp b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_constants.hpp index 718fca54b..9390ebd6f 100644 --- a/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_constants.hpp +++ b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_constants.hpp @@ -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 { diff --git a/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_exception.hpp b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_exception.hpp index a72c8dcf0..35b08803e 100644 --- a/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_exception.hpp +++ b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/keyvault_exception.hpp @@ -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 diff --git a/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/version.hpp b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/version.hpp index 58a760c77..add6a827f 100644 --- a/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/version.hpp +++ b/sdk/keyvault/azure-security-keyvault-common/inc/azure/keyvault/common/version.hpp @@ -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 diff --git a/sdk/keyvault/azure-security-keyvault-common/src/keyvault_pipeline.cpp b/sdk/keyvault/azure-security-keyvault-common/src/keyvault_pipeline.cpp index 5b22b1bc9..fc26dad77 100644 --- a/sdk/keyvault/azure-security-keyvault-common/src/keyvault_pipeline.cpp +++ b/sdk/keyvault/azure-security-keyvault-common/src/keyvault_pipeline.cpp @@ -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 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 const& path) const +{ + return CreateRequest(method, nullptr, path); +} + std::unique_ptr Internal::KeyVaultPipeline::SendRequest( Azure::Core::Context const& context, Azure::Core::Http::Request& request) const diff --git a/sdk/keyvault/azure-security-keyvault-common/test/CMakeLists.txt b/sdk/keyvault/azure-security-keyvault-common/test/CMakeLists.txt index 4869a2fc7..a24c30161 100644 --- a/sdk/keyvault/azure-security-keyvault-common/test/CMakeLists.txt +++ b/sdk/keyvault/azure-security-keyvault-common/test/CMakeLists.txt @@ -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 +) diff --git a/sdk/keyvault/azure-security-keyvault-common/test/pipeline_test.cpp b/sdk/keyvault/azure-security-keyvault-common/test/pipeline_test.cpp index 6c06515b3..a425c822c 100644 --- a/sdk/keyvault/azure-security-keyvault-common/test/pipeline_test.cpp +++ b/sdk/keyvault/azure-security-keyvault-common/test/pipeline_test.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include diff --git a/sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md b/sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md index 2fcc5787f..1242815a5 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md +++ b/sdk/keyvault/azure-security-keyvault-keys/CHANGELOG.md @@ -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. diff --git a/sdk/keyvault/azure-security-keyvault-keys/CMakeLists.txt b/sdk/keyvault/azure-security-keyvault-keys/CMakeLists.txt index 5fe7632b4..5580ee7ab 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/CMakeLists.txt +++ b/sdk/keyvault/azure-security-keyvault-keys/CMakeLists.txt @@ -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 ) diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/key_vault.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/key_vault.hpp index 0186be601..38550ad34 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/key_vault.hpp +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/key_vault.hpp @@ -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" diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/json_web_key.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/json_web_key.hpp index e7f1cccf5..dc693b8f4 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/json_web_key.hpp +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/json_web_key.hpp @@ -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 { /** diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client.hpp index 97dbcc11d..65a673df5 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client.hpp +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client.hpp @@ -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 #include #include -#include +#include #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 @@ -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( - 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 CreateKey( + std::string const& name, + KeyTypeEnum keyType, + CreateKeyOptions const& options = CreateKeyOptions()) const + { + return m_pipeline->SendRequest( + 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"}); } }; diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client_options.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client_options.hpp index 54bbc53b7..4bf18fa54 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client_options.hpp +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_client_options.hpp @@ -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 #include -#include #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"); } diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_constants.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_constants.hpp new file mode 100644 index 000000000..e741668a7 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_constants.hpp @@ -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 diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_create_options.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_create_options.hpp new file mode 100644 index 000000000..b726b6a2a --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_create_options.hpp @@ -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 +#include +#include + +#include "azure/keyvault/keys/key_operation.hpp" + +#include +#include +#include + +namespace Azure { namespace Security { namespace KeyVault { namespace Keys { + + struct CreateKeyOptions + { + /** + * @brief Context for cancelling long running operations. + */ + Azure::Core::Context Context; + + std::list KeyOperations; + + Azure::Core::Nullable NotBefore; + + Azure::Core::Nullable ExpiresOn; + + Azure::Core::Nullable Enabled; + + std::unordered_map Tags; + }; + +}}}} // namespace Azure::Security::KeyVault::Keys diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_operation.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_operation.hpp index 0a20e46a6..2b1e0a6bf 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_operation.hpp +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_operation.hpp @@ -1,6 +1,11 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // SPDX-License-Identifier: MIT +/** + * @brief Defines the Key Vault KeyOperation. + * + */ + #pragma once #include diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_properties.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_properties.hpp index 4c68d6f1e..637c70f4c 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_properties.hpp +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_properties.hpp @@ -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 @@ -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; diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_release_policy.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_release_policy.hpp index b6644a1d7..74698888c 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_release_policy.hpp +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_release_policy.hpp @@ -1,6 +1,11 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // SPDX-License-Identifier: MIT +/** + * @brief Defines the KeyReleasePolicy. + * + */ + #pragma once #include diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_request_parameters.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_request_parameters.hpp new file mode 100644 index 000000000..1567019dc --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_request_parameters.hpp @@ -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 +#include + +#include "azure/keyvault/keys/key_create_options.hpp" +#include "azure/keyvault/keys/key_type.hpp" + +#include +#include +#include +#include + +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 diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_type.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_type.hpp index 33f7e6982..ef96dbd1a 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_type.hpp +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_type.hpp @@ -1,21 +1,17 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // SPDX-License-Identifier: MIT +/** + * @brief Defines the KeyTypeEnum. + * + */ + #pragma once #include 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, diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_vault_key.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_vault_key.hpp index 8ccf01878..ec1e5bbcd 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_vault_key.hpp +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/key_vault_key.hpp @@ -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; diff --git a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/version.hpp b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/version.hpp index effa471d4..34556fcb2 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/version.hpp +++ b/sdk/keyvault/azure-security-keyvault-keys/inc/azure/keyvault/keys/version.hpp @@ -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 diff --git a/sdk/keyvault/azure-security-keyvault-keys/src/key_request_parameters.cpp b/sdk/keyvault/azure-security-keyvault-keys/src/key_request_parameters.cpp new file mode 100644 index 000000000..5a131d53e --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-keys/src/key_request_parameters.cpp @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include + +#include "azure/keyvault/keys/key_constants.hpp" +#include "azure/keyvault/keys/key_request_parameters.hpp" + +#include + +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(); +} diff --git a/sdk/keyvault/azure-security-keyvault-keys/src/key_type.cpp b/sdk/keyvault/azure-security-keyvault-keys/src/key_type.cpp index 8af3924f9..217cc2f3b 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/src/key_type.cpp +++ b/sdk/keyvault/azure-security-keyvault-keys/src/key_type.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MIT #include "azure/keyvault/keys/key_type.hpp" +#include "azure/keyvault/keys/key_constants.hpp" #include diff --git a/sdk/keyvault/azure-security-keyvault-keys/src/key_vault_key.cpp b/sdk/keyvault/azure-security-keyvault-keys/src/key_vault_key.cpp index 6bf714968..95e414fc0 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/src/key_vault_key.cpp +++ b/sdk/keyvault/azure-security-keyvault-keys/src/key_vault_key.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MIT #include "azure/keyvault/keys/key_vault_key.hpp" +#include "azure/keyvault/keys/key_constants.hpp" #include @@ -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>(); + // key_ops + auto keyOperationVector = jsonKey[Details::KeyOpsPropertyName].get>(); std::vector keyOperations; ParseStringOperationsToKeyOperations(keyOperations, keyOperationVector); key.Key.SetKeyOperations(keyOperations); } + key.Key.Id = jsonKey[Details::KeyIdPropertyName].get(); + key.Key.KeyType + = Details::KeyTypeFromString(jsonKey[Details::KeyTypePropertyName].get()); - key.Key.Id = jsonKey["kid"].get(); - key.Key.KeyType = Details::KeyTypeFromString(jsonKey["kty"].get()); + // "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()); + } + } return key; } diff --git a/sdk/keyvault/azure-security-keyvault-keys/test/CMakeLists.txt b/sdk/keyvault/azure-security-keyvault-keys/test/CMakeLists.txt index 83af55f4e..75a62ce87 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/test/CMakeLists.txt +++ b/sdk/keyvault/azure-security-keyvault-keys/test/CMakeLists.txt @@ -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 +) diff --git a/sdk/keyvault/azure-security-keyvault-keys/test/key_client_test_live.cpp b/sdk/keyvault/azure-security-keyvault-keys/test/key_client_test_live.cpp index 310185035..653f8cff8 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/test/key_client_test_live.cpp +++ b/sdk/keyvault/azure-security-keyvault-keys/test/key_client_test_live.cpp @@ -13,6 +13,17 @@ #include +namespace { +template +void CheckValidResponse( + Azure::Core::Response& 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; + }; + } +}