File: explicit_queryable_encryption_spec.rb

package info (click to toggle)
ruby-mongo 2.23.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 15,020 kB
  • sloc: ruby: 110,810; makefile: 5
file content (150 lines) | stat: -rw-r--r-- 4,858 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# frozen_string_literal: true

require 'spec_helper'

# No need to rewrite existing specs to make the examples shorter, until/unless
# we revisit these specs and need to make substantial changes.
# rubocop:disable RSpec/ExampleLength
describe 'Explicit Queryable Encryption' do
  require_libmongocrypt
  min_server_version '7.0.0-rc0'
  require_topology :replica_set, :sharded, :load_balanced

  include_context 'define shared FLE helpers'

  let(:key1_id) do
    key1_document['_id']
  end

  let(:encrypted_coll) do
    'explicit_encryption'
  end

  let(:value) do
    'encrypted indexed value'
  end

  let(:unindexed_value) do
    'encrypted unindexed value'
  end

  let(:key_vault_client) do
    ClientRegistry.instance.new_local_client(SpecConfig.instance.addresses)
  end

  let(:client_encryption_opts) do
    {
      kms_providers: local_kms_providers,
      kms_tls_options: kms_tls_options,
      key_vault_namespace: key_vault_namespace
    }
  end

  let(:client_encryption) do
    Mongo::ClientEncryption.new(
      key_vault_client,
      client_encryption_opts
    )
  end

  let(:encrypted_client) do
    ClientRegistry.instance.new_local_client(
      SpecConfig.instance.addresses,
      auto_encryption_options: {
        key_vault_namespace: "#{key_vault_db}.#{key_vault_coll}",
        kms_providers: local_kms_providers,
        bypass_query_analysis: true
      },
      database: SpecConfig.instance.test_db
    )
  end

  before do
    authorized_client[encrypted_coll].drop(encrypted_fields: encrypted_fields)
    authorized_client[encrypted_coll].create(encrypted_fields: encrypted_fields)
    authorized_client.use(key_vault_db)[key_vault_coll].drop
    authorized_client.use(key_vault_db)[key_vault_coll, write_concern: { w: :majority }].insert_one(key1_document)
  end

  after do
    authorized_client[encrypted_coll].drop(encrypted_fields: encrypted_fields)
    authorized_client.use(key_vault_db)[key_vault_coll].drop
  end

  it 'can insert encrypted indexed and find' do
    insert_payload = client_encryption.encrypt(
      value, key_id: key1_id, algorithm: 'Indexed', contention_factor: 0
    )
    encrypted_client[encrypted_coll].insert_one(
      'encryptedIndexed' => insert_payload
    )
    find_payload = client_encryption.encrypt(
      value, key_id: key1_id, algorithm: 'Indexed', query_type: 'equality', contention_factor: 0
    )
    find_results = encrypted_client[encrypted_coll]
                   .find('encryptedIndexed' => find_payload)
                   .to_a
    expect(find_results.size).to eq(1)
    expect(find_results.first['encryptedIndexed']).to eq(value)
  end

  it 'can insert encrypted indexed and find with non-zero contention' do
    10.times do
      insert_payload = client_encryption.encrypt(
        value, key_id: key1_id, algorithm: 'Indexed', contention_factor: 10
      )
      encrypted_client[encrypted_coll].insert_one(
        'encryptedIndexed' => insert_payload
      )
    end
    find_payload = client_encryption.encrypt(
      value, key_id: key1_id, algorithm: 'Indexed', query_type: 'equality', contention_factor: 0
    )
    find_results = encrypted_client[encrypted_coll]
                   .find('encryptedIndexed' => find_payload)
                   .to_a
    expect(find_results.size).to be < 10
    find_results.each do |doc|
      expect(doc['encryptedIndexed']).to eq(value)
    end
    find_payload2 = client_encryption.encrypt(
      value, key_id: key1_id, algorithm: 'Indexed', query_type: 'equality', contention_factor: 10
    )
    find_results2 = encrypted_client[encrypted_coll]
                    .find('encryptedIndexed' => find_payload2)
                    .to_a
    expect(find_results2.size).to eq(10)
    find_results2.each do |doc|
      expect(doc['encryptedIndexed']).to eq(value)
    end
  end

  it 'can insert encrypted unindexed' do
    insert_payload = client_encryption.encrypt(
      unindexed_value, key_id: key1_id, algorithm: 'Unindexed'
    )
    encrypted_client[encrypted_coll].insert_one(
      '_id' => 1, 'encryptedUnindexed' => insert_payload
    )
    find_results = encrypted_client[encrypted_coll].find('_id' => 1).to_a
    expect(find_results.size).to eq(1)
    expect(find_results.first['encryptedUnindexed']).to eq(unindexed_value)
  end

  it 'can roundtrip encrypted indexed' do
    payload = client_encryption.encrypt(
      value, key_id: key1_id, algorithm: 'Indexed', contention_factor: 0
    )
    decrypted_value = client_encryption.decrypt(payload)
    expect(decrypted_value).to eq(value)
  end

  it 'can roundtrip encrypted unindexed' do
    payload = client_encryption.encrypt(
      unindexed_value, key_id: key1_id, algorithm: 'Unindexed'
    )
    decrypted_value = client_encryption.decrypt(payload)
    expect(decrypted_value).to eq(unindexed_value)
  end
end
# rubocop:enable RSpec/ExampleLength