crypt_keeper 0.16.0.pre → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.travis.yml +22 -13
  4. data/Appraisals +6 -16
  5. data/README.md +43 -21
  6. data/Rakefile +7 -3
  7. data/crypt_keeper.gemspec +9 -9
  8. data/gemfiles/activerecord_4_2.gemfile +8 -0
  9. data/gemfiles/activerecord_5_1.gemfile +8 -0
  10. data/lib/crypt_keeper/helper.rb +31 -21
  11. data/lib/crypt_keeper/log_subscriber/mysql_aes.rb +11 -11
  12. data/lib/crypt_keeper/log_subscriber/postgres_pgp.rb +29 -10
  13. data/lib/crypt_keeper/model.rb +64 -17
  14. data/lib/crypt_keeper/provider/aes_new.rb +1 -1
  15. data/lib/crypt_keeper/provider/base.rb +21 -0
  16. data/lib/crypt_keeper/provider/mysql_aes_new.rb +2 -2
  17. data/lib/crypt_keeper/provider/postgres_base.rb +28 -0
  18. data/lib/crypt_keeper/provider/postgres_pgp.rb +27 -8
  19. data/lib/crypt_keeper/provider/postgres_pgp_public_key.rb +4 -20
  20. data/lib/crypt_keeper/version.rb +1 -1
  21. data/lib/crypt_keeper.rb +11 -2
  22. data/spec/crypt_keeper/log_subscriber/mysql_aes_spec.rb +50 -0
  23. data/spec/crypt_keeper/log_subscriber/postgres_pgp_spec.rb +78 -0
  24. data/spec/crypt_keeper/model_spec.rb +178 -0
  25. data/spec/crypt_keeper/provider/aes_new_spec.rb +41 -0
  26. data/spec/crypt_keeper/provider/mysql_aes_new_spec.rb +50 -0
  27. data/spec/crypt_keeper/provider/postgres_pgp_public_key_spec.rb +67 -0
  28. data/spec/crypt_keeper/provider/postgres_pgp_spec.rb +87 -0
  29. data/spec/spec_helper.rb +0 -1
  30. data/spec/support/active_record.rb +36 -26
  31. data/spec/support/encryptors.rb +9 -3
  32. data/spec/support/logging.rb +89 -0
  33. metadata +84 -92
  34. data/bin/crypt_keeper +0 -99
  35. data/gemfiles/activerecord_3_1.gemfile +0 -8
  36. data/gemfiles/activerecord_3_1.gemfile.lock +0 -109
  37. data/gemfiles/activerecord_3_2.gemfile +0 -8
  38. data/gemfiles/activerecord_3_2.gemfile.lock +0 -109
  39. data/gemfiles/activerecord_4_0.gemfile +0 -8
  40. data/gemfiles/activerecord_4_0.gemfile.lock +0 -117
  41. data/gemfiles/activerecord_4_1.gemfile +0 -8
  42. data/gemfiles/activerecord_4_1.gemfile.lock +0 -117
  43. data/lib/crypt_keeper/provider/aes.rb +0 -66
  44. data/lib/crypt_keeper/provider/mysql_aes.rb +0 -47
  45. data/spec/log_subscriber/postgres_pgp_spec.rb +0 -98
  46. data/spec/model_spec.rb +0 -95
  47. data/spec/provider/aes_new_spec.rb +0 -45
  48. data/spec/provider/aes_spec.rb +0 -67
  49. data/spec/provider/mysql_aes_new_spec.rb +0 -52
  50. data/spec/provider/mysql_aes_spec.rb +0 -35
  51. data/spec/provider/postgres_pgp_public_key_spec.rb +0 -70
  52. data/spec/provider/postgres_pgp_spec.rb +0 -68
@@ -1,98 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module CryptKeeper::LogSubscriber
4
- describe PostgresPgp do
5
- use_postgres
6
-
7
- context "Symmetric encryption" do
8
- # Fire the ActiveSupport.on_load
9
- before do
10
- CryptKeeper::Provider::PostgresPgp.new key: 'secret'
11
- end
12
-
13
- subject { ::ActiveRecord::LogSubscriber.new }
14
-
15
- let(:input_query) do
16
- "SELECT pgp_sym_encrypt('encrypt_value', 'encrypt_key'), pgp_sym_decrypt('decrypt_value', 'decrypt_key') FROM DUAL;"
17
- end
18
-
19
- let(:output_query) do
20
- "SELECT encrypt([FILTERED]) FROM DUAL;"
21
- end
22
-
23
- let(:input_search_query) do
24
- "SELECT \"sensitive_data\".* FROM \"sensitive_data\" WHERE ((pgp_sym_decrypt('f'), 'tool') = 'blah')) AND secret = 'testing'"
25
- end
26
-
27
- let(:output_search_query) do
28
- "SELECT \"sensitive_data\".* FROM \"sensitive_data\" WHERE decrypt([FILTERED]) AND secret = 'testing'"
29
- end
30
-
31
- it "filters pgp functions" do
32
- subject.should_receive(:sql_without_postgres_pgp) do |event|
33
- event.payload[:sql].should == output_query
34
- end
35
-
36
- subject.sql(ActiveSupport::Notifications::Event.new(:sql, 1, 1, 1, { sql: input_query }))
37
- end
38
-
39
- it "filters pgp functions in lowercase" do
40
- subject.should_receive(:sql_without_postgres_pgp) do |event|
41
- event.payload[:sql].should == output_query.downcase.gsub(/filtered/, 'FILTERED')
42
- end
43
-
44
- subject.sql(ActiveSupport::Notifications::Event.new(:sql, 1, 1, 1, { sql: input_query.downcase }))
45
- end
46
-
47
- it "filters pgp functions when searching" do
48
- subject.should_receive(:sql_without_postgres_pgp) do |event|
49
- event.payload[:sql].should == output_search_query
50
- end
51
-
52
- subject.sql(ActiveSupport::Notifications::Event.new(:sql, 1, 1, 1, { sql: input_search_query }))
53
- end
54
- end
55
-
56
- context "Public key encryption" do
57
- let(:public_key) do
58
- IO.read(File.join(SPEC_ROOT, 'fixtures', 'public.asc'))
59
- end
60
-
61
- let(:private_key) do
62
- IO.read(File.join(SPEC_ROOT, 'fixtures', 'private.asc'))
63
- end
64
-
65
- # Fire the ActiveSupport.on_load
66
- before do
67
- CryptKeeper::Provider::PostgresPgpPublicKey.new key: 'secret', public_key: public_key, private_key: private_key
68
- end
69
-
70
- subject { ::ActiveRecord::LogSubscriber.new }
71
-
72
- let(:input_query) do
73
- "SELECT pgp_pub_encrypt('test', dearmor('#{public_key}
74
- '))"
75
- end
76
-
77
- let(:output_query) do
78
- "SELECT encrypt([FILTERED])"
79
- end
80
-
81
- it "filters pgp functions" do
82
- subject.should_receive(:sql_without_postgres_pgp) do |event|
83
- event.payload[:sql].should == output_query
84
- end
85
-
86
- subject.sql(ActiveSupport::Notifications::Event.new(:sql, 1, 1, 1, { sql: input_query }))
87
- end
88
-
89
- it "filters pgp functions in lowercase" do
90
- subject.should_receive(:sql_without_postgres_pgp) do |event|
91
- event.payload[:sql].should == output_query.downcase.gsub(/filtered/, 'FILTERED')
92
- end
93
-
94
- subject.sql(ActiveSupport::Notifications::Event.new(:sql, 1, 1, 1, { sql: input_query.downcase }))
95
- end
96
- end
97
- end
98
- end
data/spec/model_spec.rb DELETED
@@ -1,95 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module CryptKeeper
4
- describe Model do
5
- use_sqlite
6
-
7
- before do
8
- SensitiveData.instance_variable_set('@encryptor_klass', nil)
9
- end
10
-
11
- subject { SensitiveData }
12
-
13
- describe "#crypt_keeper" do
14
- context "Fields" do
15
- it "enables encryption for the given fields" do
16
- subject.crypt_keeper :storage, :secret, encryptor: :fake_encryptor
17
- subject.crypt_keeper_fields.should == [:storage, :secret]
18
- end
19
-
20
- it "raises an exception for missing field" do
21
- msg = "Column :none does not exist"
22
- subject.crypt_keeper :none, encryptor: :fake_encryptor
23
- expect { subject.new.save }.to raise_error(ArgumentError, msg)
24
- end
25
-
26
- it "raises an exception for non text fields" do
27
- msg = "Column :name must be of type 'text' to be used for encryption"
28
- subject.crypt_keeper :name, encryptor: :fake_encryptor
29
- expect { subject.new.save }.to raise_error(ArgumentError, msg)
30
- end
31
- end
32
-
33
- context "Options" do
34
- it "accepts the class name as a string" do
35
- subject.crypt_keeper :storage, :secret, key1: 1, key2: 2, encryptor: "FakeEncryptor"
36
- subject.send(:encryptor_klass).should == CryptKeeper::Provider::FakeEncryptor
37
- end
38
-
39
- it "raises an error on missing encryptor" do
40
- expect { subject.crypt_keeper :storage, :secret }.
41
- to raise_error(RuntimeError, /You must specify a valid encryptor/)
42
- end
43
- end
44
- end
45
-
46
- context "Encryption and Decryption" do
47
- let(:plain_text) { 'plain_text' }
48
- let(:cipher_text) { 'tooltxet_nialp' }
49
-
50
- before do
51
- SensitiveData.crypt_keeper :storage, passphrase: 'tool', encryptor: :encryptor
52
- end
53
-
54
- it "encrypts the data" do
55
- CryptKeeper::Provider::Encryptor.any_instance.should_receive(:encrypt).with('testing')
56
- SensitiveData.create!(storage: 'testing')
57
- end
58
-
59
- it "decrypts the data" do
60
- record = SensitiveData.create!(storage: 'testing')
61
- CryptKeeper::Provider::Encryptor.any_instance.should_receive(:decrypt).at_least(1).times.with('toolgnitset')
62
- SensitiveData.find(record).storage
63
- end
64
-
65
- it "returns the plaintext on decrypt" do
66
- record = SensitiveData.create!(storage: 'testing')
67
- SensitiveData.find(record).storage.should == 'testing'
68
- end
69
-
70
- it "does not encrypt or decrypt nil" do
71
- data = SensitiveData.create!(storage: nil)
72
- data.storage.should be_nil
73
- end
74
-
75
- it "does not encrypt or decrypt empty strings" do
76
- data = SensitiveData.create!(storage: "")
77
- data.storage.should be_empty
78
- end
79
- end
80
-
81
- context "Search" do
82
- before do
83
- SensitiveData.crypt_keeper :storage, passphrase: 'tool', encryptor: :search_encryptor
84
- end
85
-
86
- it "searches if supported" do
87
- expect { SensitiveData.search_by_plaintext(:storage, 'test1') }.to_not raise_error
88
- end
89
-
90
- it "complains about bad columns" do
91
- expect { SensitiveData.search_by_plaintext(:what, 'test1') }.to raise_error(/what is not a crypt_keeper field/)
92
- end
93
- end
94
- end
95
- end
@@ -1,45 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module CryptKeeper
4
- module Provider
5
- describe AesNew do
6
- subject { AesNew.new(key: 'cake', salt: 'salt') }
7
-
8
- describe "#initialize" do
9
- let(:digested_key) do
10
- ::Armor.digest('cake', 'salt')
11
- end
12
-
13
- its(:key) { should == digested_key }
14
- specify { expect { AesNew.new }.to raise_error(ArgumentError, "Missing :key") }
15
- end
16
-
17
- describe "#encrypt" do
18
- let(:encrypted) do
19
- subject.encrypt 'string'
20
- end
21
-
22
- specify { encrypted.should_not == 'string' }
23
- specify { encrypted.should_not be_blank }
24
- end
25
-
26
- describe "#decrypt" do
27
- let(:decrypted) do
28
- subject.decrypt "V02ebRU2wLk25AizasROVg==$kE+IpRaUNdBfYqR+WjMqvA=="
29
- end
30
-
31
- specify { decrypted.should == 'string' }
32
- end
33
-
34
- describe "#search" do
35
- let(:records) do
36
- [{ name: 'Bob' }, { name: 'Tim' }]
37
- end
38
-
39
- it "finds the matching record" do
40
- expect(subject.search(records, :name, 'Bob')).to eql([records.first])
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,67 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module CryptKeeper
4
- module Provider
5
- describe Aes do
6
- subject { Aes.new(key: 'cake') }
7
-
8
- describe "#initialize" do
9
- let(:hexed_key) do
10
- Digest::SHA256.digest('cake')
11
- end
12
-
13
- its(:key) { should == hexed_key }
14
- specify { expect { Aes.new }.to raise_error(ArgumentError, "Missing :key") }
15
- end
16
-
17
- describe "#encrypt" do
18
- let(:encrypted) do
19
- subject.encrypt 'string'
20
- end
21
-
22
- specify { encrypted.should_not == 'string' }
23
- specify { encrypted.should_not be_blank }
24
-
25
- context "an empty string" do
26
- let(:encrypted) do
27
- subject.encrypt ''
28
- end
29
-
30
- specify { encrypted.should == '' }
31
- end
32
-
33
- context "a nil" do
34
- let(:encrypted) do
35
- subject.encrypt nil
36
- end
37
-
38
- specify { encrypted.should be_nil }
39
- end
40
- end
41
-
42
- describe "#decrypt" do
43
- let(:decrypted) do
44
- subject.decrypt "MC41MDk5MjI2NjgxMDI1MDI2OmNyeXB0X2tlZXBlcjpPI/8dCqWXDMVj7Jqs\nuwf/\n"
45
- end
46
-
47
- specify { decrypted.should == 'string' }
48
-
49
- context "an empty string" do
50
- let(:decrypted) do
51
- subject.decrypt ''
52
- end
53
-
54
- specify { decrypted.should == '' }
55
- end
56
-
57
- context "a nil" do
58
- let(:decrypted) do
59
- subject.decrypt nil
60
- end
61
-
62
- specify { decrypted.should be_nil }
63
- end
64
- end
65
- end
66
- end
67
- end
@@ -1,52 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module CryptKeeper
4
- module Provider
5
- describe MysqlAesNew do
6
- use_mysql
7
-
8
- let(:plain_text) { 'test' }
9
-
10
- # MySQL stores AES encrypted strings in binary which you can't paste
11
- # into a spec :). This is a Base64 encoded string of 'test' AES encrypted
12
- # by AES_ENCRYPT()
13
- let(:cipher_text) do
14
- "fBN8i7bx/DGAA4NJ4EWi0A=="
15
- end
16
-
17
- subject { MysqlAesNew.new key: ENCRYPTION_PASSWORD, salt: 'salt' }
18
-
19
- its(:key) { should == "825e8c5e8ca394818b307b22b8cb7d3df2735e9c1e5838b476e7719135a4f499f2133022c1a0e8597c9ac1507b0f0c44328a40049f9704fab3598c5dec120724" }
20
-
21
- describe "#initialize" do
22
- specify { expect { MysqlAesNew.new }.to raise_error(ArgumentError, "Missing :key") }
23
- specify { expect { MysqlAesNew.new(key: 'blah') }.to raise_error(ArgumentError, "Missing :salt") }
24
- end
25
-
26
- describe "#encrypt" do
27
- specify { subject.encrypt(plain_text).should_not == plain_text }
28
- specify { subject.encrypt(plain_text).should_not be_blank }
29
- end
30
-
31
- describe "#decrypt" do
32
- specify { subject.decrypt(cipher_text).should == plain_text }
33
- end
34
-
35
- describe "#search" do
36
- it "finds the matching record" do
37
- SensitiveDataMysql.create!(storage: 'blah2')
38
- match = SensitiveDataMysql.create!(storage: 'blah')
39
- SensitiveDataMysql.search_by_plaintext(:storage, 'blah').first.should == match
40
- end
41
-
42
- it "keeps the scope" do
43
- SensitiveDataMysql.create!(storage: 'blah')
44
- SensitiveDataMysql.create!(storage: 'blah')
45
-
46
- scope = SensitiveDataMysql.limit(1)
47
- expect(scope.search_by_plaintext(:storage, 'blah').count).to eql(1)
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,35 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module CryptKeeper
4
- module Provider
5
- describe MysqlAes do
6
- use_mysql
7
-
8
- let(:plain_text) { 'test' }
9
-
10
- # MySQL stores AES encrypted strings in binary which you can't paste
11
- # into a spec :). This is a Base64 encoded string of 'test' AES encrypted
12
- # by AES_ENCRYPT()
13
- let(:cipher_text) do
14
- "nbKOoWn8kvAw9k/C2Mex6Q==\n"
15
- end
16
-
17
- subject { MysqlAes.new key: 'candy' }
18
-
19
- its(:key) { should == 'candy' }
20
-
21
- describe "#initialize" do
22
- specify { expect { MysqlAes.new }.to raise_error(ArgumentError, "Missing :key") }
23
- end
24
-
25
- describe "#encrypt" do
26
- specify { subject.encrypt(plain_text).should_not == plain_text }
27
- specify { subject.encrypt(plain_text).should_not be_blank }
28
- end
29
-
30
- describe "#decrypt" do
31
- specify { subject.decrypt(cipher_text).should == plain_text }
32
- end
33
- end
34
- end
35
- end
@@ -1,70 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module CryptKeeper
4
- module Provider
5
- describe PostgresPgpPublicKey do
6
- use_postgres
7
-
8
- let(:cipher_text) { '\xc1c04c036c401ad086beb9e3010800987d6c4ccd974322190caa75a3a01aba37bc1970182c4c1d3faec98edf186780520f0586101f286e0626096a1eca91a229ed4d4058a6913a8d13cdf49f29ea44e2b96d10347f9b1b860bb3c959f000a3b1b415a95d2cd07af8c74aa6df8cd10ab06b6a6f7db69cdf3185466d68c5b66b95b813acdfb3ddfb021cac92e0967d67e90df73332f27970c1d2b9a56ac74f602d4107b163ed73ef89fca560d9a0a0d2bc7a74005f29fa27babfbaf950ac07b1c809049db4ab126be4824cf76416c278571f7064f638edf830a1ae5ee1ab544d35fce0f974f21b9dcbbea3986077d27b0de34144dc23f369f471090b57e067a056901e680493ddf2a6b29e4af3462387d235010259556079d07daa249b6703e2bc79345da556cfb46f228cad40a8a5b569ac46f08865f9176acf89129a3e0ceb2a7b1991012f65' }
9
-
10
- let(:integer_cipher_text) { '\xc1c04c036c401ad086beb9e30107ff59e674ba05958eb053c2427b44355e0f333f1726e18a0b851130130510c648f580b13b3f6a223eb26e397008596867c5a511a4f5bfbf2ecc852d8929814480d63166e525fa2b259b6a8d4474b5b1373b4e1a4fe70a491d25442e1c0046fd3d69466ad30153c8d8d920e9b4260d4e4e421ef3ead162b3aba5d85408c4ef9f9d342b5655c7568d1bdc61c27ddb419133bf091f22f42e7bc91ec6d279b7b25b87ea65119568b85ae81079dd0a6a7258b58fb219c6cc4580f33cb46de97770a1eb0880bdf87426fd0529576a1e791e521d9b3c426e393e63d83321f319b00f9dc4027ea5a81dd57c0f5ba868fb86d73179c34f2287c437266e8becc072b45a929562d2320194be54464e03854635d0f7d7fb10813adbc6efe51efa9095a9bacc2a03fb5c41d1c1896384e4f36b100c0f00e81d4cff7d' }
11
-
12
- let(:integer_plain_text) { 1 }
13
- let(:plain_text) { 'test' }
14
-
15
- let(:public_key) do
16
- IO.read(File.join(SPEC_ROOT, 'fixtures', 'public.asc'))
17
- end
18
-
19
- let(:private_key) do
20
- IO.read(File.join(SPEC_ROOT, 'fixtures', 'private.asc'))
21
- end
22
-
23
- subject { PostgresPgpPublicKey.new key: ENCRYPTION_PASSWORD, public_key: public_key, private_key: private_key }
24
-
25
-
26
- its(:key) { should == ENCRYPTION_PASSWORD }
27
-
28
- describe "#initialize" do
29
- specify { expect { PostgresPgpPublicKey.new }.to raise_error(ArgumentError, "Missing :key") }
30
- end
31
-
32
- describe "#encrypt" do
33
- context "Strings" do
34
- specify { subject.encrypt(plain_text).should_not == plain_text }
35
- specify { subject.encrypt(plain_text).should_not be_empty }
36
-
37
- it "does not double encrypt" do
38
- pgp = PostgresPgpPublicKey.new key: ENCRYPTION_PASSWORD, public_key: public_key
39
- pgp.encrypt(cipher_text).should == cipher_text
40
- end
41
- end
42
-
43
- context "Integers" do
44
- specify { subject.encrypt(integer_plain_text).should_not == integer_plain_text }
45
- specify { subject.encrypt(integer_plain_text).should_not be_empty }
46
- end
47
- end
48
-
49
- describe "#decrypt" do
50
- specify { subject.decrypt(cipher_text).should == plain_text }
51
- specify { subject.decrypt(integer_cipher_text).should == integer_plain_text.to_s }
52
-
53
- it "does not decrypt w/o private key" do
54
- pgp = PostgresPgpPublicKey.new key: ENCRYPTION_PASSWORD, public_key: public_key
55
- pgp.decrypt(cipher_text).should eql(cipher_text)
56
- end
57
- end
58
-
59
- describe "#encrypted?" do
60
- it "returns true for encrypted strings" do
61
- subject.encrypted?(cipher_text).should be_true
62
- end
63
-
64
- it "returns false for non-encrypted strings" do
65
- subject.encrypted?(plain_text).should be_false
66
- end
67
- end
68
- end
69
- end
70
- end
@@ -1,68 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module CryptKeeper
4
- module Provider
5
- describe PostgresPgp do
6
- use_postgres
7
-
8
- let(:cipher_text) { '\xc30d04070302f1a092093988b26873d235017203ce086a53fce1925dc39b4e972e534f192d10b94af3dcf8589abc1f828456f5d3e20b225d56006ffd1e312e3b8a492a6010e9' }
9
- let(:plain_text) { 'test' }
10
-
11
- let(:integer_cipher_text) { '\xc30d04070302c8d266353bcf2fc07dd23201153f9d9c32fbb3c36b9b0db137bf8b6c609172210d89ded63f11dff23d1ddbf5111c0266549dde26175c4425e06bb4bd6f' }
12
-
13
- let(:integer_plain_text) { 1 }
14
-
15
- subject { PostgresPgp.new key: ENCRYPTION_PASSWORD }
16
-
17
- its(:key) { should == ENCRYPTION_PASSWORD }
18
-
19
- describe "#initialize" do
20
- specify { expect { PostgresPgp.new }.to raise_error(ArgumentError, "Missing :key") }
21
- end
22
-
23
- describe "#encrypt" do
24
- context "Strings" do
25
- specify { subject.encrypt(plain_text).should_not == plain_text }
26
- specify { subject.encrypt(plain_text).should_not be_empty }
27
- end
28
-
29
- context "Integers" do
30
- specify { subject.encrypt(integer_plain_text).should_not == integer_plain_text }
31
- specify { subject.encrypt(integer_plain_text).should_not be_empty }
32
- end
33
- end
34
-
35
- describe "#decrypt" do
36
- specify { subject.decrypt(cipher_text).should == plain_text }
37
- specify { subject.decrypt(integer_cipher_text).should == integer_plain_text.to_s }
38
- end
39
-
40
- describe "#search" do
41
- it "finds the matching record" do
42
- SensitiveDataPg.create!(storage: 'blah2')
43
- match = SensitiveDataPg.create!(storage: 'blah')
44
- SensitiveDataPg.search_by_plaintext(:storage, 'blah').first.should == match
45
- end
46
- end
47
-
48
- describe "Custom pgcrypto options" do
49
- let(:pgcrypto_options) { 'compress-level=0' }
50
-
51
- subject { PostgresPgp.new key: 'candy', pgcrypto_options: pgcrypto_options }
52
-
53
- it "reads and writes" do
54
- queries = logged_queries do
55
- encrypted = subject.encrypt(plain_text)
56
- subject.decrypt(encrypted).should == plain_text
57
- end
58
-
59
- queries.should_not be_empty
60
-
61
- queries.select { |query| query.include?("pgp_sym_encrypt") }.each do |q|
62
- q.should include(pgcrypto_options)
63
- end
64
- end
65
- end
66
- end
67
- end
68
- end