Skip to content

RUBY-3156 Linter appeasement for #2720 #2721

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jun 1, 2023
106 changes: 59 additions & 47 deletions lib/mongo/crypt/explicit_encrypter.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# frozen_string_literal: true
# rubocop:todo all

# Copyright (C) 2020 MongoDB Inc.
#
Expand All @@ -17,12 +16,13 @@

module Mongo
module Crypt

# An ExplicitEncrypter is an object that performs explicit encryption
# operations and handles all associated options and instance variables.
#
# @api private
class ExplicitEncrypter
extend Forwardable

# Create a new ExplicitEncrypter object.
#
# @param [ Mongo::Client ] key_vault_client An instance of Mongo::Client
Expand All @@ -44,7 +44,7 @@ def initialize(key_vault_client, key_vault_namespace, kms_providers, kms_tls_opt
@encryption_io = EncryptionIO.new(
key_vault_client: key_vault_client,
metadata_client: nil,
key_vault_namespace: key_vault_namespace,
key_vault_namespace: key_vault_namespace
)
end

Expand Down Expand Up @@ -108,7 +108,7 @@ def encrypt(value, options)
Crypt::ExplicitEncryptionContext.new(
@crypt_handle,
@encryption_io,
{ 'v': value },
{ v: value },
options
).run_state_machine['v']
end
Expand Down Expand Up @@ -167,7 +167,7 @@ def encrypt_expression(expression, options)
Crypt::ExplicitEncryptionExpressionContext.new(
@crypt_handle,
@encryption_io,
{ 'v': expression },
{ v: expression },
options
).run_state_machine['v']
end
Expand All @@ -179,10 +179,10 @@ def encrypt_expression(expression, options)
#
# @return [ Object ] The decrypted value
def decrypt(value)
result = Crypt::ExplicitDecryptionContext.new(
Crypt::ExplicitDecryptionContext.new(
@crypt_handle,
@encryption_io,
{ 'v': value },
{ v: value }
).run_state_machine['v']
end

Expand All @@ -203,36 +203,28 @@ def add_key_alt_name(id, key_alt_name)
#
# @return [ Operation::Result ] The response from the database for the delete_one
# operation that deletes the key.
def delete_key(id)
@encryption_io.delete_key(id)
end
def_delegators :@encryption_io, :delete_key

# Finds a single key with the given id.
#
# @param [ BSON::Binary ] id Id of the key to get.
#
# @return [ BSON::Document | nil ] The found key document or nil
# if not found.
def get_key(id)
@encryption_io.get_key(id)
end
def_delegators :@encryption_io, :get_key

# Returns a key in the key vault collection with the given key_alt_name.
#
# @param [ String ] key_alt_name Key alt name to find a key.
#
# @return [ BSON::Document | nil ] The found key document or nil
# if not found.
def get_key_by_alt_name(key_alt_name)
@encryption_io.get_key_by_alt_name(key_alt_name)
end
def_delegators :@encryption_io, :get_key_by_alt_name

# Returns all keys in the key vault collection.
#
# @return [ Collection::View ] Keys in the key vault collection.
def get_keys
@encryption_io.get_keys
end
def_delegators :@encryption_io, :get_keys

# Removes a key_alt_name from a key in the key vault collection with the given id.
#
Expand All @@ -241,9 +233,7 @@ def get_keys
#
# @return [ BSON::Document | nil ] Document describing the identified key
# before removing the key alt name, or nil if no such key.
def remove_key_alt_name(id, key_alt_name)
@encryption_io.remove_key_alt_name(id, key_alt_name)
end
def_delegators :@encryption_io, :remove_key_alt_name

# Decrypts multiple data keys and (re-)encrypts them with a new master_key,
# or with their current master_key if a new one is not given.
Expand All @@ -259,23 +249,60 @@ def remove_key_alt_name(id, key_alt_name)
def rewrap_many_data_key(filter, opts = {})
validate_rewrap_options!(opts)

master_key_document = if opts[:provider]
options = opts.dup
provider = options.delete(:provider)
KMS::MasterKeyDocument.new(provider, options)
end
master_key_document = master_key_for_provider(opts)

rewrap_result = Crypt::RewrapManyDataKeyContext.new(
@crypt_handle,
@encryption_io,
filter,
master_key_document
).run_state_machine
if rewrap_result.nil?
return RewrapManyDataKeyResult.new(nil)
end
data_key_documents = rewrap_result.fetch('v')
updates = data_key_documents.map do |doc|

return RewrapManyDataKeyResult.new(nil) if rewrap_result.nil?

updates = updates_from_data_key_documents(rewrap_result.fetch('v'))
RewrapManyDataKeyResult.new(@encryption_io.update_data_keys(updates))
end

private

# Ensures the consistency of the options passed to #rewrap_many_data_keys.
#
# @param [ Hash ] opts the options hash to validate
#
# @raise [ ArgumentError ] if the options are not consistent or
# compatible.
def validate_rewrap_options!(opts)
return unless opts.key?(:master_key) && !opts.key?(:provider)

raise ArgumentError, 'If :master_key is specified, :provider must also be given'
end

# If a :provider is given, construct a new master key document
# with that provider.
#
# @param [ Hash ] opts the options hash
#
# @option [ String ] :provider KMS provider to encrypt keys.
#
# @return [ KMS::MasterKeyDocument | nil ] the new master key document,
# or nil if no provider was given.
def master_key_for_provider(opts)
return nil unless opts[:provider]

options = opts.dup
provider = options.delete(:provider)
KMS::MasterKeyDocument.new(provider, options)
end

# Returns the corresponding update document for each for of the given
# data key documents.
#
# @param [ Array<Hash> ] documents the data key documents
#
# @return [ Array<Hash> ] the update documents
def updates_from_data_key_documents(documents)
documents.map do |doc|
{
update_one: {
filter: { _id: doc[:_id] },
Expand All @@ -289,21 +316,6 @@ def rewrap_many_data_key(filter, opts = {})
}
}
end
RewrapManyDataKeyResult.new(
@encryption_io.update_data_keys(updates)
)
end

# Ensures the consistency of the options passed to #rewrap_many_data_keys.
#
# @param [Hash] opts the options hash to validate
#
# @raise [ ArgumentError ] if the options are not consistent or
# compatible.
def validate_rewrap_options!(opts)
if opts.key?(:master_key) && !opts.key?(:provider)
raise ArgumentError, 'If :master_key is specified, :provider must also be given'
end
end
end
end
Expand Down