Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/mongocxx/include/mongocxx/v1/data_key_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ class data_key_options {
///
/// Return the current "keyMaterial" field.
///
MONGOCXX_ABI_EXPORT_CDECL(bsoncxx::v1::stdx::optional<key_material_type>) key_material();
MONGOCXX_ABI_EXPORT_CDECL(bsoncxx::v1::stdx::optional<key_material_type>) key_material() const;

class internal;
};

} // namespace v1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#pragma once

#include <mongocxx/v1/data_key_options-fwd.hpp>

#include <mongocxx/config/prelude.hpp>

namespace mongocxx {
Expand All @@ -29,7 +31,7 @@ class data_key;
namespace mongocxx {
namespace options {

using ::mongocxx::v_noabi::options::data_key;
using v_noabi::options::data_key;

} // namespace options
} // namespace mongocxx
Expand All @@ -40,3 +42,6 @@ using ::mongocxx::v_noabi::options::data_key;
/// @file
/// Declares @ref mongocxx::v_noabi::options::data_key.
///
/// @par Includes
/// - @ref mongocxx/v1/data_key_options-fwd.hpp
///
103 changes: 87 additions & 16 deletions src/mongocxx/include/mongocxx/v_noabi/mongocxx/options/data_key.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,22 @@

#pragma once

#include <mongocxx/options/data_key-fwd.hpp> // IWYU pragma: export

//

#include <bsoncxx/v1/document/value.hpp>

#include <mongocxx/v1/data_key_options.hpp> // IWYU pragma: export

#include <cstdint>
#include <string>
#include <utility>
#include <vector>

#include <mongocxx/client_encryption-fwd.hpp>
#include <mongocxx/options/data_key-fwd.hpp> // IWYU pragma: export
#include <mongocxx/client_encryption-fwd.hpp> // IWYU pragma: keep: backward compatibility, to be removed.

#include <bsoncxx/document/view.hpp>
#include <bsoncxx/document/view_or_value.hpp>
#include <bsoncxx/stdx/optional.hpp>

Expand All @@ -34,6 +44,35 @@ namespace options {
///
class data_key {
public:
///
/// Default initialization.
///
data_key() = default;

///
/// Construct with the @ref mongocxx::v1 equivalent.
///
/* explicit(false) */ MONGOCXX_ABI_EXPORT_CDECL() data_key(v1::data_key_options key);

///
/// Convert to the @ref mongocxx::v1 equivalent.
///
explicit operator v1::data_key_options() const {
v1::data_key_options ret;

if (_master_key) {
ret.master_key(bsoncxx::v1::document::value{bsoncxx::v_noabi::to_v1(_master_key->view())});
}

ret.key_alt_names(_key_alt_names);

if (_key_material) {
ret.key_material(*_key_material);
}

return ret;
}

///
/// Sets a KMS-specific key used to encrypt the new data key.
///
Expand Down Expand Up @@ -99,17 +138,20 @@ class data_key {
/// @see
/// - https://www.mongodb.com/docs/manual/core/security-client-side-encryption-key-management/
///
MONGOCXX_ABI_EXPORT_CDECL(data_key&)
master_key(bsoncxx::v_noabi::document::view_or_value master_key);
data_key& master_key(bsoncxx::v_noabi::document::view_or_value master_key) {
_master_key = std::move(master_key);
return *this;
}

///
/// Gets the master key.
///
/// @return
/// An optional document containing the master key.
///
MONGOCXX_ABI_EXPORT_CDECL(bsoncxx::v_noabi::stdx::optional<bsoncxx::v_noabi::document::view_or_value> const&)
master_key() const;
bsoncxx::v_noabi::stdx::optional<bsoncxx::v_noabi::document::view_or_value> const& master_key() const {
return _master_key;
}

///
/// Sets an optional list of string alternate names used to reference the key.
Expand All @@ -125,20 +167,25 @@ class data_key {
/// @see
/// - https://www.mongodb.com/docs/manual/reference/method/getClientEncryption/
///
MONGOCXX_ABI_EXPORT_CDECL(data_key&) key_alt_names(std::vector<std::string> key_alt_names);
data_key& key_alt_names(std::vector<std::string> key_alt_names) {
_key_alt_names = std::move(key_alt_names);
return *this;
}

///
/// Gets the alternate names for the data key.
///
/// @return
/// The alternate names for the data key.
///
MONGOCXX_ABI_EXPORT_CDECL(std::vector<std::string> const&) key_alt_names() const;
std::vector<std::string> const& key_alt_names() const {
return _key_alt_names;
}

///
/// Represents binary data used to represent key material.
///
using key_material_type = std::vector<uint8_t>;
using key_material_type = std::vector<std::uint8_t>;

///
/// Sets the binary data for the key material
Expand All @@ -159,7 +206,10 @@ class data_key {
/// @see
/// - https://www.mongodb.com/docs/v6.0/reference/method/KeyVault.createKey/
///
MONGOCXX_ABI_EXPORT_CDECL(data_key&) key_material(key_material_type key_material);
data_key& key_material(key_material_type key_material) {
_key_material = std::move(key_material);
return *this;
}

///
/// Gets the keyMaterial as binary data
Expand All @@ -170,14 +220,13 @@ class data_key {
/// @see
/// - https://www.mongodb.com/docs/v6.0/reference/method/KeyVault.createKey/
///
MONGOCXX_ABI_EXPORT_CDECL(bsoncxx::v_noabi::stdx::optional<key_material_type> const&)
key_material();
bsoncxx::v_noabi::stdx::optional<key_material_type> const& key_material() {
return _key_material;
}

private:
friend ::mongocxx::v_noabi::client_encryption;

void* convert() const;
class internal;

private:
bsoncxx::v_noabi::stdx::optional<bsoncxx::v_noabi::document::view_or_value> _master_key;
std::vector<std::string> _key_alt_names;
bsoncxx::v_noabi::stdx::optional<key_material_type> _key_material;
Expand All @@ -187,9 +236,31 @@ class data_key {
} // namespace v_noabi
} // namespace mongocxx

namespace mongocxx {
namespace v_noabi {

///
/// Convert to the @ref mongocxx::v_noabi equivalent of `v`.
///
inline v_noabi::options::data_key from_v1(v1::data_key_options v) {
return {std::move(v)};
}

/// Convert to the @ref mongocxx::v1 equivalent of `v`.
///
inline v1::data_key_options to_v1(v_noabi::options::data_key v) {
return v1::data_key_options{std::move(v)};
}

} // namespace v_noabi
} // namespace mongocxx

#include <mongocxx/config/postlude.hpp>

///
/// @file
/// Provides @ref mongocxx::v_noabi::options::data_key.
///
/// @par Includes
/// - @ref mongocxx/v1/data_key_options.hpp
///
154 changes: 153 additions & 1 deletion src/mongocxx/lib/mongocxx/v1/data_key_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,156 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include <mongocxx/v1/data_key_options.hpp>
#include <mongocxx/v1/data_key_options.hh>

//

#include <bsoncxx/v1/document/value.hpp>
#include <bsoncxx/v1/stdx/optional.hpp>

#include <algorithm>
#include <cstdint>
#include <iterator>
#include <memory>
#include <string>
#include <vector>

#include <mongocxx/private/mongoc.hh>
#include <mongocxx/private/scoped_bson.hh>
#include <mongocxx/private/utility.hh>

namespace mongocxx {
namespace v1 {

class data_key_options::impl {
public:
bsoncxx::v1::stdx::optional<bsoncxx::v1::document::value> _master_key;
std::vector<std::string> _key_alt_names;
bsoncxx::v1::stdx::optional<key_material_type> _key_material;

static impl const& with(data_key_options const& self) {
return *static_cast<impl const*>(self._impl);
}

static impl const* with(data_key_options const* self) {
return static_cast<impl const*>(self->_impl);
}

static impl& with(data_key_options& self) {
return *static_cast<impl*>(self._impl);
}

static impl* with(data_key_options* self) {
return static_cast<impl*>(self->_impl);
}

static impl* with(void* ptr) {
return static_cast<impl*>(ptr);
}
};

data_key_options::~data_key_options() {
delete impl::with(this);
}

data_key_options::data_key_options(data_key_options&& other) noexcept : _impl{exchange(other._impl, nullptr)} {}

data_key_options& data_key_options::operator=(data_key_options&& other) noexcept {
if (this != &other) {
delete impl::with(exchange(_impl, exchange(other._impl, nullptr)));
}

return *this;
}

data_key_options::data_key_options(data_key_options const& other) : _impl{new impl{impl::with(other)}} {}

data_key_options& data_key_options::operator=(data_key_options const& other) {
if (this != &other) {
delete impl::with(exchange(_impl, new impl{impl::with(other)}));
}

return *this;
}

data_key_options::data_key_options() : _impl{new impl{}} {}

data_key_options& data_key_options::master_key(bsoncxx::v1::document::value master_key) {
impl::with(this)->_master_key = std::move(master_key);
return *this;
}

bsoncxx::v1::stdx::optional<bsoncxx::v1::document::view> data_key_options::master_key() const {
return impl::with(this)->_master_key;
}

data_key_options& data_key_options::key_alt_names(std::vector<std::string> key_alt_names) {
impl::with(this)->_key_alt_names = std::move(key_alt_names);
return *this;
}

std::vector<std::string> data_key_options::key_alt_names() const {
return impl::with(this)->_key_alt_names;
}

data_key_options& data_key_options::key_material(key_material_type key_material) {
impl::with(this)->_key_material = std::move(key_material);
return *this;
}

bsoncxx::v1::stdx::optional<data_key_options::key_material_type> data_key_options::key_material() const {
return impl::with(this)->_key_material;
}

std::unique_ptr<mongoc_client_encryption_datakey_opts_t, data_key_options::internal::deleter_type>
data_key_options::internal::to_mongoc(data_key_options const& self) {
std::unique_ptr<mongoc_client_encryption_datakey_opts_t, data_key_options::internal::deleter_type> ret{
libmongoc::client_encryption_datakey_opts_new()};

auto const opts = ret.get();
auto& _impl = impl::with(self);

if (auto const& opt = _impl._master_key) {
libmongoc::client_encryption_datakey_opts_set_masterkey(opts, scoped_bson_view{opt->view()}.bson());
}

if (!_impl._key_alt_names.empty()) {
std::vector<char*> names;

names.reserve(_impl._key_alt_names.size());
std::transform(
_impl._key_alt_names.begin(),
_impl._key_alt_names.end(),
std::back_inserter(names),
[](std::string const& name) {
return const_cast<char*>(name.c_str()); // For copy only.
});

libmongoc::client_encryption_datakey_opts_set_keyaltnames(
opts, names.data(), static_cast<std::uint32_t>(_impl._key_alt_names.size()));
}

if (auto const& opt = _impl._key_material) {
libmongoc::client_encryption_datakey_opts_set_keymaterial(
opts, opt->data(), static_cast<std::uint32_t>(opt->size()));
}

return ret;
}

bsoncxx::v1::stdx::optional<bsoncxx::v1::document::value>& data_key_options::internal::master_key(
data_key_options& self) {
return impl::with(self)._master_key;
}

std::vector<std::string>& data_key_options::internal::key_alt_names(data_key_options& self) {
return impl::with(self)._key_alt_names;
}

bsoncxx::v1::stdx::optional<data_key_options::key_material_type>& data_key_options::internal::key_material(
data_key_options& self) {
return impl::with(self)._key_material;
}

} // namespace v1
} // namespace mongocxx
Loading