symmetric-encryption 3.4.0 → 3.6.0

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 (31) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +102 -55
  3. data/Rakefile +13 -8
  4. data/lib/rails/generators/symmetric_encryption/config/config_generator.rb +1 -1
  5. data/lib/rails/generators/symmetric_encryption/heroku_config/templates/symmetric-encryption.yml +2 -2
  6. data/lib/rails/generators/symmetric_encryption/new_keys/new_keys_generator.rb +2 -2
  7. data/lib/symmetric_encryption.rb +7 -6
  8. data/lib/symmetric_encryption/cipher.rb +4 -4
  9. data/lib/symmetric_encryption/extensions/active_record/base.rb +6 -46
  10. data/lib/symmetric_encryption/extensions/mongo_mapper/plugins/encrypted_key.rb +129 -0
  11. data/lib/symmetric_encryption/{mongoid.rb → extensions/mongoid/encrypted.rb} +12 -46
  12. data/lib/symmetric_encryption/generator.rb +54 -0
  13. data/lib/symmetric_encryption/railtie.rb +3 -3
  14. data/lib/symmetric_encryption/railties/symmetric_encryption.rake +1 -1
  15. data/lib/symmetric_encryption/railties/symmetric_encryption_validator.rb +1 -1
  16. data/lib/symmetric_encryption/reader.rb +3 -3
  17. data/lib/symmetric_encryption/symmetric_encryption.rb +25 -15
  18. data/lib/symmetric_encryption/version.rb +1 -1
  19. data/lib/symmetric_encryption/writer.rb +4 -4
  20. data/test/active_record_test.rb +474 -0
  21. data/test/cipher_test.rb +15 -15
  22. data/test/config/mongo_mapper.yml +7 -0
  23. data/test/{field_encrypted_test.rb → mongo_mapper_test.rb} +68 -67
  24. data/test/mongoid_test.rb +535 -0
  25. data/test/reader_test.rb +10 -10
  26. data/test/symmetric_encryption_test.rb +27 -27
  27. data/test/test_db.sqlite3 +0 -0
  28. data/test/test_helper.rb +0 -1
  29. data/test/writer_test.rb +2 -2
  30. metadata +14 -8
  31. data/test/attr_encrypted_test.rb +0 -622
@@ -7,18 +7,18 @@ class CipherTest < Test::Unit::TestCase
7
7
 
8
8
  should "allow setting the cipher_name" do
9
9
  cipher = SymmetricEncryption::Cipher.new(
10
- :cipher_name => 'aes-128-cbc',
11
- :key => '1234567890ABCDEF1234567890ABCDEF',
12
- :iv => '1234567890ABCDEF',
13
- :encoding => :none
10
+ cipher_name: 'aes-128-cbc',
11
+ key: '1234567890ABCDEF1234567890ABCDEF',
12
+ iv: '1234567890ABCDEF',
13
+ encoding: :none
14
14
  )
15
15
  assert_equal 'aes-128-cbc', cipher.cipher_name
16
16
  end
17
17
 
18
18
  should "not require an iv" do
19
19
  cipher = SymmetricEncryption::Cipher.new(
20
- :key => '1234567890ABCDEF1234567890ABCDEF',
21
- :encoding => :none
20
+ key: '1234567890ABCDEF1234567890ABCDEF',
21
+ encoding: :none
22
22
  )
23
23
  result = "\302<\351\227oj\372\3331\310\260V\001\v'\346"
24
24
  # Note: This test fails on JRuby 1.7 RC1 since it's OpenSSL
@@ -31,10 +31,10 @@ class CipherTest < Test::Unit::TestCase
31
31
 
32
32
  should "throw an exception on bad data" do
33
33
  cipher = SymmetricEncryption::Cipher.new(
34
- :cipher_name => 'aes-128-cbc',
35
- :key => '1234567890ABCDEF1234567890ABCDEF',
36
- :iv => '1234567890ABCDEF',
37
- :encoding => :none
34
+ cipher_name: 'aes-128-cbc',
35
+ key: '1234567890ABCDEF1234567890ABCDEF',
36
+ iv: '1234567890ABCDEF',
37
+ encoding: :none
38
38
  )
39
39
  assert_raise OpenSSL::Cipher::CipherError do
40
40
  cipher.decrypt('bad data')
@@ -115,9 +115,9 @@ class CipherTest < Test::Unit::TestCase
115
115
  context 'with configuration' do
116
116
  setup do
117
117
  @cipher = SymmetricEncryption::Cipher.new(
118
- :key => '1234567890ABCDEF1234567890ABCDEF',
119
- :iv => '1234567890ABCDEF',
120
- :encoding => :none
118
+ key: '1234567890ABCDEF1234567890ABCDEF',
119
+ iv: '1234567890ABCDEF',
120
+ encoding: :none
121
121
  )
122
122
  @social_security_number = "987654321"
123
123
 
@@ -125,7 +125,7 @@ class CipherTest < Test::Unit::TestCase
125
125
  @social_security_number_encrypted.force_encoding('binary') if defined?(Encoding)
126
126
 
127
127
  @sample_data = [
128
- { :text => '555052345', :encrypted => ''}
128
+ { text: '555052345', encrypted: ''}
129
129
  ]
130
130
  end
131
131
 
@@ -149,7 +149,7 @@ class CipherTest < Test::Unit::TestCase
149
149
  assert_equal random_cipher.send(:iv), header.iv, "IVs differ"
150
150
 
151
151
  string = "Hello World"
152
- cipher = SymmetricEncryption::Cipher.new(:key => header.key, :iv => header.iv, :cipher_name => header.cipher_name)
152
+ cipher = SymmetricEncryption::Cipher.new(key: header.key, iv: header.iv, cipher_name: header.cipher_name)
153
153
  # Test Encryption
154
154
  assert_equal random_cipher.encrypt(string, false, false), cipher.encrypt(string, false, false), "Encrypted values differ"
155
155
  end
@@ -0,0 +1,7 @@
1
+ test:
2
+ uri: mongodb://localhost:27017/symmetric_encryption_test
3
+ options:
4
+ :w: 1
5
+ :pool_size: 5
6
+ :pool_timeout: 5
7
+ :connect_timeout: 5
@@ -1,43 +1,44 @@
1
- require File.dirname(__FILE__) + '/test_helper'
2
-
3
- Mongoid.logger = SemanticLogger[Mongoid]
4
- filename = defined?(Mongoid::VERSION) ? "test/config/mongoid_v3.yml" : "test/config/mongoid_v2.yml"
5
- Mongoid.load!(filename)
6
-
7
- class MongoidUser
8
- include Mongoid::Document
9
-
10
- field :name, :type => String
11
- field :encrypted_bank_account_number, :type => String, :encrypted => true
12
- field :encrypted_social_security_number, :type => String, :encrypted => true
13
- field :encrypted_string, :type => String, :encrypted => {:random_iv => true}
14
- field :encrypted_long_string, :type => String, :encrypted => {:random_iv => true, :compress => true}
15
-
16
- field :encrypted_integer_value, :type => String, :encrypted => {:type => :integer}
17
- field :aiv, :type => String, :encrypted => {:type => :integer, decrypt_as: :aliased_integer_value}
18
- field :encrypted_float_value, :type => String, :encrypted => {:type => :float}
19
- field :encrypted_decimal_value, :type => String, :encrypted => {:type => :decimal}
20
- field :encrypted_datetime_value, :type => String, :encrypted => {:type => :datetime}
21
- field :encrypted_time_value, :type => String, :encrypted => {:type => :time}
22
- field :encrypted_date_value, :type => String, :encrypted => {:type => :date}
23
- field :encrypted_true_value, :type => String, :encrypted => {:type => :boolean}
24
- field :encrypted_false_value, :type => String, :encrypted => {:type => :boolean}
25
- field :encrypted_data_yaml, :type => String, :encrypted => {:random_iv => true, :compress => true, :type => :yaml}
26
- field :encrypted_data_json, :type => String, :encrypted => {:random_iv => true, :compress => true, :type => :json}
27
-
28
- # TODO Validates should work
29
- #validates :encrypted_bank_account_number, :symmetric_encrypted => true
30
- #validates :encrypted_social_security_number, :symmetric_encrypted => true
1
+ $LOAD_PATH.unshift File.dirname(__FILE__)
2
+ require 'mongo_mapper'
3
+ require 'test_helper'
4
+ require 'symmetric_encryption/extensions/mongo_mapper/plugins/encrypted_key'
5
+
6
+ # Initialize MongoMapper
7
+ config_file = File.join('test', 'config', 'mongo_mapper.yml')
8
+ config = YAML.load(ERB.new(File.read(config_file)).result)
9
+ MongoMapper.setup(config, 'test', logger: SemanticLogger['Mongo'])
10
+
11
+ class MongoMapperUser
12
+ include MongoMapper::Document
13
+
14
+ key :name, String
15
+ encrypted_key :bank_account_number, String
16
+ encrypted_key :social_security_number, String
17
+ encrypted_key :string, String, encrypted: { random_iv: true }
18
+ encrypted_key :long_string, String, encrypted: { random_iv: true, compress: true }
19
+
20
+ # Valid Types: String, Integer, Float, BigDecimal, DateTime, Time, Date, Hash
21
+ encrypted_key :integer_value, Integer
22
+ encrypted_key :aliased_integer_value, Integer, encrypted: { encrypt_as: :aiv }
23
+ encrypted_key :float_value, Float
24
+ encrypted_key :decimal_value, BigDecimal
25
+ encrypted_key :datetime_value, DateTime
26
+ encrypted_key :time_value, Time
27
+ encrypted_key :date_value, Date
28
+ encrypted_key :true_value, Boolean
29
+ encrypted_key :false_value, Boolean
30
+ encrypted_key :data_json, Hash, encrypted: {random_iv: true, compress: true}
31
+ encrypted_key :data_yaml, Hash, encrypted: {random_iv: true, compress: true, type: :yaml}
32
+
33
+ validates :encrypted_bank_account_number, symmetric_encryption: true
34
+ validates :encrypted_social_security_number, symmetric_encryption: true
31
35
  end
32
36
 
33
- # Load Symmetric Encryption keys
34
- SymmetricEncryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
35
-
36
37
  #
37
- # Unit Tests for field encrypted and validation aspects of SymmetricEncryption
38
+ # Unit Tests for MongoMapper
38
39
  #
39
- class FieldEncryptedTest < Test::Unit::TestCase
40
- context 'the SymmetricEncryption Library' do
40
+ class MongoMapperTest < Test::Unit::TestCase
41
+ context 'MongoMapperUser' do
41
42
  setup do
42
43
  @bank_account_number = "1234567890"
43
44
  @bank_account_number_encrypted = "QEVuQwIAL94ArJeFlJrZp6SYsvoOGA=="
@@ -63,24 +64,24 @@ class FieldEncryptedTest < Test::Unit::TestCase
63
64
  @datetime_value = DateTime.new(2001, 11, 26, 20, 55, 54, "-5")
64
65
  @time_value = Time.new(2013, 01, 01, 22, 30, 00, "-04:00")
65
66
  @date_value = Date.new(1927, 04, 02)
66
- @h = { :a => 'A', :b => 'B' }
67
+ @h = { a: 'A', b: 'B' }
67
68
 
68
- @user = MongoidUser.new(
69
- :encrypted_bank_account_number => @bank_account_number_encrypted,
70
- :encrypted_social_security_number => @social_security_number_encrypted,
71
- :name => "Joe Bloggs",
69
+ @user = MongoMapperUser.new(
70
+ encrypted_bank_account_number: @bank_account_number_encrypted,
71
+ encrypted_social_security_number: @social_security_number_encrypted,
72
+ name: "Joe Bloggs",
72
73
  # data type specific fields
73
- :integer_value => @integer_value,
74
- :aliased_integer_value => @integer_value,
75
- :float_value => @float_value,
76
- :decimal_value => @decimal_value,
77
- :datetime_value => @datetime_value,
78
- :time_value => @time_value,
79
- :date_value => @date_value,
80
- :true_value => true,
81
- :false_value => false,
82
- :data_yaml => @h.dup,
83
- :data_json => @h.dup
74
+ integer_value: @integer_value,
75
+ aliased_integer_value: @integer_value,
76
+ float_value: @float_value,
77
+ decimal_value: @decimal_value,
78
+ datetime_value: @datetime_value,
79
+ time_value: @time_value,
80
+ date_value: @date_value,
81
+ true_value: true,
82
+ false_value: false,
83
+ data_yaml: @h.dup,
84
+ data_json: @h.dup
84
85
  )
85
86
  end
86
87
 
@@ -151,7 +152,7 @@ class FieldEncryptedTest < Test::Unit::TestCase
151
152
  end
152
153
 
153
154
  should "encrypt" do
154
- user = MongoidUser.new
155
+ user = MongoMapperUser.new
155
156
  user.bank_account_number = @bank_account_number
156
157
  assert_equal @bank_account_number, user.bank_account_number
157
158
  assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
@@ -168,7 +169,7 @@ class FieldEncryptedTest < Test::Unit::TestCase
168
169
  end
169
170
 
170
171
  should "all paths should lead to the same result, check uninitialized" do
171
- user = MongoidUser.new
172
+ user = MongoMapperUser.new
172
173
  assert_equal nil, user.social_security_number
173
174
  assert_equal @bank_account_number, (user.social_security_number = @bank_account_number)
174
175
  assert_equal @bank_account_number, user.social_security_number
@@ -180,7 +181,7 @@ class FieldEncryptedTest < Test::Unit::TestCase
180
181
  end
181
182
 
182
183
  should "allow unencrypted values to be passed to the constructor" do
183
- user = MongoidUser.new(:bank_account_number => @bank_account_number, :social_security_number => @social_security_number)
184
+ user = MongoMapperUser.new(bank_account_number: @bank_account_number, social_security_number: @social_security_number)
184
185
  assert_equal @bank_account_number, user.bank_account_number
185
186
  assert_equal @social_security_number, user.social_security_number
186
187
  assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
@@ -188,7 +189,7 @@ class FieldEncryptedTest < Test::Unit::TestCase
188
189
  end
189
190
 
190
191
  should "allow both encrypted and unencrypted values to be passed to the constructor" do
191
- user = MongoidUser.new(:encrypted_bank_account_number => @bank_account_number_encrypted, :social_security_number => @social_security_number)
192
+ user = MongoMapperUser.new(encrypted_bank_account_number: @bank_account_number_encrypted, social_security_number: @social_security_number)
192
193
  assert_equal @bank_account_number, user.bank_account_number
193
194
  assert_equal @social_security_number, user.social_security_number
194
195
  assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
@@ -198,7 +199,7 @@ class FieldEncryptedTest < Test::Unit::TestCase
198
199
  context "data types" do
199
200
  setup do
200
201
  @user.save!
201
- @user_clone = MongoidUser.find(@user.id)
202
+ @user_clone = MongoMapperUser.find(@user.id)
202
203
  end
203
204
 
204
205
  context "aliased fields" do
@@ -215,7 +216,7 @@ class FieldEncryptedTest < Test::Unit::TestCase
215
216
  end
216
217
 
217
218
  should "coerce data type before save" do
218
- u = MongoidUser.new(:integer_value => "5")
219
+ u = MongoMapperUser.new(integer_value: "5")
219
220
  assert_equal 5, u.integer_value
220
221
  assert u.integer_value.kind_of?(Integer)
221
222
  end
@@ -246,7 +247,7 @@ class FieldEncryptedTest < Test::Unit::TestCase
246
247
  end
247
248
 
248
249
  should "coerce data type before save" do
249
- u = MongoidUser.new(:float_value => "5.6")
250
+ u = MongoMapperUser.new(float_value: "5.6")
250
251
  assert_equal 5.6, u.float_value
251
252
  assert u.float_value.kind_of?(Float)
252
253
  end
@@ -277,7 +278,7 @@ class FieldEncryptedTest < Test::Unit::TestCase
277
278
  end
278
279
 
279
280
  should "coerce data type before save" do
280
- u = MongoidUser.new(:decimal_value => "99.95")
281
+ u = MongoMapperUser.new(decimal_value: "99.95")
281
282
  assert_equal BigDecimal.new("99.95"), u.decimal_value
282
283
  assert u.decimal_value.kind_of?(BigDecimal)
283
284
  end
@@ -309,7 +310,7 @@ class FieldEncryptedTest < Test::Unit::TestCase
309
310
 
310
311
  should "coerce data type before save" do
311
312
  now = Time.now
312
- u = MongoidUser.new(:datetime_value => now)
313
+ u = MongoMapperUser.new(datetime_value: now)
313
314
  assert_equal now, u.datetime_value
314
315
  assert u.datetime_value.kind_of?(DateTime)
315
316
  end
@@ -341,7 +342,7 @@ class FieldEncryptedTest < Test::Unit::TestCase
341
342
 
342
343
  should "coerce data type before save" do
343
344
  now = Time.now
344
- u = MongoidUser.new(:time_value => now)
345
+ u = MongoMapperUser.new(time_value: now)
345
346
  assert_equal now, u.time_value
346
347
  assert u.time_value.kind_of?(Time)
347
348
  end
@@ -373,7 +374,7 @@ class FieldEncryptedTest < Test::Unit::TestCase
373
374
 
374
375
  should "coerce data type before save" do
375
376
  now = Time.now
376
- u = MongoidUser.new(:date_value => now)
377
+ u = MongoMapperUser.new(date_value: now)
377
378
  assert_equal now.to_date, u.date_value
378
379
  assert u.date_value.kind_of?(Date)
379
380
  end
@@ -404,7 +405,7 @@ class FieldEncryptedTest < Test::Unit::TestCase
404
405
  end
405
406
 
406
407
  should "coerce data type before save" do
407
- u = MongoidUser.new(:true_value => "1")
408
+ u = MongoMapperUser.new(true_value: "1")
408
409
  assert_equal true, u.true_value
409
410
  assert u.true_value.kind_of?(TrueClass)
410
411
  end
@@ -435,7 +436,7 @@ class FieldEncryptedTest < Test::Unit::TestCase
435
436
  end
436
437
 
437
438
  should "coerce data type before save" do
438
- u = MongoidUser.new(:false_value => "0")
439
+ u = MongoMapperUser.new(false_value: "0")
439
440
  assert_equal false, u.false_value
440
441
  assert u.false_value.kind_of?(FalseClass)
441
442
  end
@@ -475,7 +476,7 @@ class FieldEncryptedTest < Test::Unit::TestCase
475
476
  end
476
477
 
477
478
  should "not coerce data type (leaves as hash) before save" do
478
- u = MongoidUser.new(:data_json => @h)
479
+ u = MongoMapperUser.new(data_json: @h)
479
480
  assert_equal @h, u.data_json
480
481
  assert u.data_json.kind_of?(Hash)
481
482
  end
@@ -507,7 +508,7 @@ class FieldEncryptedTest < Test::Unit::TestCase
507
508
  end
508
509
 
509
510
  should "not coerce data type (leaves as hash) before save" do
510
- u = MongoidUser.new(:data_yaml => @h)
511
+ u = MongoMapperUser.new(data_yaml: @h)
511
512
  assert_equal @h, u.data_yaml
512
513
  assert u.data_yaml.kind_of?(Hash)
513
514
  end
@@ -0,0 +1,535 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ if defined?(Mongoid)
3
+ Mongoid.logger = SemanticLogger[Mongoid]
4
+ filename = defined?(Mongoid::VERSION) ? "test/config/mongoid_v3.yml" : "test/config/mongoid_v2.yml"
5
+ Mongoid.load!(filename)
6
+
7
+ class MongoidUser
8
+ include Mongoid::Document
9
+
10
+ field :name, type: String
11
+ field :encrypted_bank_account_number, type: String, encrypted: true
12
+ field :encrypted_social_security_number, type: String, encrypted: true
13
+ field :encrypted_string, type: String, encrypted: {random_iv: true}
14
+ field :encrypted_long_string, type: String, encrypted: {random_iv: true, compress: true}
15
+
16
+ field :encrypted_integer_value, type: String, encrypted: {type: :integer}
17
+ field :aiv, type: String, encrypted: {type: :integer, encrypt_as: :aliased_integer_value}
18
+ field :encrypted_float_value, type: String, encrypted: {type: :float}
19
+ field :encrypted_decimal_value, type: String, encrypted: {type: :decimal}
20
+ field :encrypted_datetime_value, type: String, encrypted: {type: :datetime}
21
+ field :encrypted_time_value, type: String, encrypted: {type: :time}
22
+ field :encrypted_date_value, type: String, encrypted: {type: :date}
23
+ field :encrypted_true_value, type: String, encrypted: {type: :boolean}
24
+ field :encrypted_false_value, type: String, encrypted: {type: :boolean}
25
+ field :encrypted_data_yaml, type: String, encrypted: {random_iv: true, compress: true, type: :yaml}
26
+ field :encrypted_data_json, type: String, encrypted: {random_iv: true, compress: true, type: :json}
27
+
28
+ validates :encrypted_bank_account_number, symmetric_encryption: true
29
+ validates :encrypted_social_security_number, symmetric_encryption: true
30
+ end
31
+
32
+ #
33
+ # Unit Tests for field encrypted and validation aspects of SymmetricEncryption
34
+ #
35
+ class MongoidTest < Test::Unit::TestCase
36
+ context 'Mongoid' do
37
+ setup do
38
+ @bank_account_number = "1234567890"
39
+ @bank_account_number_encrypted = "QEVuQwIAL94ArJeFlJrZp6SYsvoOGA=="
40
+
41
+ @social_security_number = "987654321"
42
+ @social_security_number_encrypted = "QEVuQwIAS+8X1NRrqdfEIQyFHVPuVA=="
43
+
44
+ @integer = 32768
45
+ @integer_encrypted = "FA3smFQEKqB/ITv+A0xACg=="
46
+
47
+ @float = 0.9867
48
+ @float_encrypted = "z7Pwt2JDp74d+u0IXFAdrQ=="
49
+
50
+ @date = Date.parse('20120320')
51
+ @date_encrypted = "WTkSPHo5ApSSHBJMxxWt2A=="
52
+
53
+ @string = "A string containing some data to be encrypted with a random initialization vector"
54
+ @long_string = "A string containing some data to be encrypted with a random initialization vector and compressed since it takes up so much space in plain text form"
55
+
56
+ @integer_value = 12
57
+ @float_value = 88.12345
58
+ @decimal_value = BigDecimal.new("22.51")
59
+ @datetime_value = DateTime.new(2001, 11, 26, 20, 55, 54, "-5")
60
+ @time_value = Time.new(2013, 01, 01, 22, 30, 00, "-04:00")
61
+ @date_value = Date.new(1927, 04, 02)
62
+ @h = { a: 'A', b: 'B' }
63
+
64
+ @user = MongoidUser.new(
65
+ encrypted_bank_account_number: @bank_account_number_encrypted,
66
+ encrypted_social_security_number: @social_security_number_encrypted,
67
+ name: "Joe Bloggs",
68
+ # data type specific fields
69
+ integer_value: @integer_value,
70
+ aliased_integer_value: @integer_value,
71
+ float_value: @float_value,
72
+ decimal_value: @decimal_value,
73
+ datetime_value: @datetime_value,
74
+ time_value: @time_value,
75
+ date_value: @date_value,
76
+ true_value: true,
77
+ false_value: false,
78
+ data_yaml: @h.dup,
79
+ data_json: @h.dup
80
+ )
81
+ end
82
+
83
+ should "have encrypted methods" do
84
+ assert_equal true, @user.respond_to?(:encrypted_bank_account_number)
85
+ assert_equal true, @user.respond_to?(:encrypted_social_security_number)
86
+ assert_equal true, @user.respond_to?(:encrypted_string)
87
+ assert_equal true, @user.respond_to?(:encrypted_long_string)
88
+ assert_equal false, @user.respond_to?(:encrypted_name)
89
+
90
+ assert_equal true, @user.respond_to?(:encrypted_bank_account_number=)
91
+ assert_equal true, @user.respond_to?(:encrypted_social_security_number=)
92
+ assert_equal true, @user.respond_to?(:encrypted_string=)
93
+ assert_equal true, @user.respond_to?(:encrypted_long_string=)
94
+ assert_equal false, @user.respond_to?(:encrypted_name=)
95
+ end
96
+
97
+ should "have unencrypted methods" do
98
+ assert_equal true, @user.respond_to?(:bank_account_number)
99
+ assert_equal true, @user.respond_to?(:social_security_number)
100
+ assert_equal true, @user.respond_to?(:string)
101
+ assert_equal true, @user.respond_to?(:long_string)
102
+ assert_equal true, @user.respond_to?(:name)
103
+
104
+ assert_equal true, @user.respond_to?(:bank_account_number=)
105
+ assert_equal true, @user.respond_to?(:social_security_number=)
106
+ assert_equal true, @user.respond_to?(:string=)
107
+ assert_equal true, @user.respond_to?(:long_string=)
108
+ assert_equal true, @user.respond_to?(:name=)
109
+ end
110
+
111
+ should "support aliased fields" do
112
+ assert_equal true, @user.respond_to?(:aliased_integer_value=)
113
+ assert_equal true, @user.respond_to?(:aliased_integer_value)
114
+ end
115
+
116
+ should "have unencrypted values" do
117
+ assert_equal @bank_account_number, @user.bank_account_number
118
+ assert_equal @social_security_number, @user.social_security_number
119
+ end
120
+
121
+ should "have encrypted values" do
122
+ assert_equal @bank_account_number_encrypted, @user.encrypted_bank_account_number
123
+ assert_equal @social_security_number_encrypted, @user.encrypted_social_security_number
124
+ end
125
+
126
+ should "support same iv" do
127
+ @user.social_security_number = @social_security_number
128
+ assert first_value = @user.social_security_number
129
+ # Assign the same value
130
+ @user.social_security_number = @social_security_number
131
+ assert_equal first_value, @user.social_security_number
132
+ end
133
+
134
+ should "support a random iv" do
135
+ @user.string = @string
136
+ assert first_value = @user.encrypted_string
137
+ # Assign the same value
138
+ @user.string = @string.dup
139
+ assert_equal true, first_value != @user.encrypted_string
140
+ end
141
+
142
+ should "support a random iv and compress" do
143
+ @user.string = @long_string
144
+ @user.long_string = @long_string
145
+
146
+ assert_equal true, (@user.encrypted_long_string.length.to_f / @user.encrypted_string.length) < 0.8
147
+ end
148
+
149
+ should "encrypt" do
150
+ user = MongoidUser.new
151
+ user.bank_account_number = @bank_account_number
152
+ assert_equal @bank_account_number, user.bank_account_number
153
+ assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
154
+ end
155
+
156
+ should "all paths should lead to the same result" do
157
+ assert_equal @bank_account_number_encrypted, (@user.encrypted_social_security_number = @bank_account_number_encrypted)
158
+ assert_equal @bank_account_number, @user.social_security_number
159
+ end
160
+
161
+ should "all paths should lead to the same result 2" do
162
+ assert_equal @bank_account_number, (@user.social_security_number = @bank_account_number)
163
+ assert_equal @bank_account_number_encrypted, @user.encrypted_social_security_number
164
+ end
165
+
166
+ should "all paths should lead to the same result, check uninitialized" do
167
+ user = MongoidUser.new
168
+ assert_equal nil, user.social_security_number
169
+ assert_equal @bank_account_number, (user.social_security_number = @bank_account_number)
170
+ assert_equal @bank_account_number, user.social_security_number
171
+ assert_equal @bank_account_number_encrypted, user.encrypted_social_security_number
172
+
173
+ assert_equal nil, (user.social_security_number = nil)
174
+ assert_equal nil, user.social_security_number
175
+ assert_equal nil, user.encrypted_social_security_number
176
+ end
177
+
178
+ should "allow unencrypted values to be passed to the constructor" do
179
+ user = MongoidUser.new(bank_account_number: @bank_account_number, social_security_number: @social_security_number)
180
+ assert_equal @bank_account_number, user.bank_account_number
181
+ assert_equal @social_security_number, user.social_security_number
182
+ assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
183
+ assert_equal @social_security_number_encrypted, user.encrypted_social_security_number
184
+ end
185
+
186
+ should "allow both encrypted and unencrypted values to be passed to the constructor" do
187
+ user = MongoidUser.new(encrypted_bank_account_number: @bank_account_number_encrypted, social_security_number: @social_security_number)
188
+ assert_equal @bank_account_number, user.bank_account_number
189
+ assert_equal @social_security_number, user.social_security_number
190
+ assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
191
+ assert_equal @social_security_number_encrypted, user.encrypted_social_security_number
192
+ end
193
+
194
+ context "data types" do
195
+ setup do
196
+ @user.save!
197
+ @user_clone = MongoidUser.find(@user.id)
198
+ end
199
+
200
+ context "aliased fields" do
201
+ should "return correct data type" do
202
+ @user_clone.aliased_integer_value = "5"
203
+ assert_equal 5, @user_clone.aliased_integer_value
204
+ end
205
+ end
206
+
207
+ context "integer values" do
208
+ should "return correct data type" do
209
+ assert_equal @integer_value, @user_clone.integer_value
210
+ assert @user.clone.integer_value.kind_of?(Integer)
211
+ end
212
+
213
+ should "coerce data type before save" do
214
+ u = MongoidUser.new(integer_value: "5")
215
+ assert_equal 5, u.integer_value
216
+ assert u.integer_value.kind_of?(Integer)
217
+ end
218
+
219
+ should "permit replacing value with nil" do
220
+ @user_clone.integer_value = nil
221
+ @user_clone.save!
222
+
223
+ @user.reload
224
+ assert_nil @user.integer_value
225
+ assert_nil @user.encrypted_integer_value
226
+ end
227
+
228
+ should "permit replacing value" do
229
+ new_integer_value = 98
230
+ @user_clone.integer_value = new_integer_value
231
+ @user_clone.save!
232
+
233
+ @user.reload
234
+ assert_equal new_integer_value, @user.integer_value
235
+ end
236
+ end
237
+
238
+ context "float values" do
239
+ should "return correct data type" do
240
+ assert_equal @float_value, @user_clone.float_value
241
+ assert @user.clone.float_value.kind_of?(Float)
242
+ end
243
+
244
+ should "coerce data type before save" do
245
+ u = MongoidUser.new(float_value: "5.6")
246
+ assert_equal 5.6, u.float_value
247
+ assert u.float_value.kind_of?(Float)
248
+ end
249
+
250
+ should "permit replacing value with nil" do
251
+ @user_clone.float_value = nil
252
+ @user_clone.save!
253
+
254
+ @user.reload
255
+ assert_nil @user.float_value
256
+ assert_nil @user.encrypted_float_value
257
+ end
258
+
259
+ should "permit replacing value" do
260
+ new_float_value = 45.4321
261
+ @user_clone.float_value = new_float_value
262
+ @user_clone.save!
263
+
264
+ @user.reload
265
+ assert_equal new_float_value, @user.float_value
266
+ end
267
+ end
268
+
269
+ context "decimal values" do
270
+ should "return correct data type" do
271
+ assert_equal @decimal_value, @user_clone.decimal_value
272
+ assert @user.clone.decimal_value.kind_of?(BigDecimal)
273
+ end
274
+
275
+ should "coerce data type before save" do
276
+ u = MongoidUser.new(decimal_value: "99.95")
277
+ assert_equal BigDecimal.new("99.95"), u.decimal_value
278
+ assert u.decimal_value.kind_of?(BigDecimal)
279
+ end
280
+
281
+ should "permit replacing value with nil" do
282
+ @user_clone.decimal_value = nil
283
+ @user_clone.save!
284
+
285
+ @user.reload
286
+ assert_nil @user.decimal_value
287
+ assert_nil @user.encrypted_decimal_value
288
+ end
289
+
290
+ should "permit replacing value" do
291
+ new_decimal_value = BigDecimal.new("99.95")
292
+ @user_clone.decimal_value = new_decimal_value
293
+ @user_clone.save!
294
+
295
+ @user.reload
296
+ assert_equal new_decimal_value, @user.decimal_value
297
+ end
298
+ end
299
+
300
+ context "datetime values" do
301
+ should "return correct data type" do
302
+ assert_equal @datetime_value, @user_clone.datetime_value
303
+ assert @user.clone.datetime_value.kind_of?(DateTime)
304
+ end
305
+
306
+ should "coerce data type before save" do
307
+ now = Time.now
308
+ u = MongoidUser.new(datetime_value: now)
309
+ assert_equal now, u.datetime_value
310
+ assert u.datetime_value.kind_of?(DateTime)
311
+ end
312
+
313
+ should "permit replacing value with nil" do
314
+ @user_clone.datetime_value = nil
315
+ @user_clone.save!
316
+
317
+ @user.reload
318
+ assert_nil @user.datetime_value
319
+ assert_nil @user.encrypted_datetime_value
320
+ end
321
+
322
+ should "permit replacing value" do
323
+ new_datetime_value = DateTime.new(1998, 10, 21, 8, 33, 28, "+5")
324
+ @user_clone.datetime_value = new_datetime_value
325
+ @user_clone.save!
326
+
327
+ @user.reload
328
+ assert_equal new_datetime_value, @user.datetime_value
329
+ end
330
+ end
331
+
332
+ context "time values" do
333
+ should "return correct data type" do
334
+ assert_equal @time_value, @user_clone.time_value
335
+ assert @user.clone.time_value.kind_of?(Time)
336
+ end
337
+
338
+ should "coerce data type before save" do
339
+ now = Time.now
340
+ u = MongoidUser.new(time_value: now)
341
+ assert_equal now, u.time_value
342
+ assert u.time_value.kind_of?(Time)
343
+ end
344
+
345
+ should "permit replacing value with nil" do
346
+ @user_clone.time_value = nil
347
+ @user_clone.save!
348
+
349
+ @user.reload
350
+ assert_nil @user.time_value
351
+ assert_nil @user.encrypted_time_value
352
+ end
353
+
354
+ should "permit replacing value" do
355
+ new_time_value = Time.new(1998, 10, 21, 8, 33, 28, "+04:00")
356
+ @user_clone.time_value = new_time_value
357
+ @user_clone.save!
358
+
359
+ @user.reload
360
+ assert_equal new_time_value, @user.time_value
361
+ end
362
+ end
363
+
364
+ context "date values" do
365
+ should "return correct data type" do
366
+ assert_equal @date_value, @user_clone.date_value
367
+ assert @user.clone.date_value.kind_of?(Date)
368
+ end
369
+
370
+ should "coerce data type before save" do
371
+ now = Time.now
372
+ u = MongoidUser.new(date_value: now)
373
+ assert_equal now.to_date, u.date_value
374
+ assert u.date_value.kind_of?(Date)
375
+ end
376
+
377
+ should "permit replacing value with nil" do
378
+ @user_clone.date_value = nil
379
+ @user_clone.save!
380
+
381
+ @user.reload
382
+ assert_nil @user.date_value
383
+ assert_nil @user.encrypted_date_value
384
+ end
385
+
386
+ should "permit replacing value" do
387
+ new_date_value = Date.new(1998, 10, 21)
388
+ @user_clone.date_value = new_date_value
389
+ @user_clone.save!
390
+
391
+ @user.reload
392
+ assert_equal new_date_value, @user.date_value
393
+ end
394
+ end
395
+
396
+ context "true values" do
397
+ should "return correct data type" do
398
+ assert_equal true, @user_clone.true_value
399
+ assert @user.clone.true_value.kind_of?(TrueClass)
400
+ end
401
+
402
+ should "coerce data type before save" do
403
+ u = MongoidUser.new(true_value: "1")
404
+ assert_equal true, u.true_value
405
+ assert u.true_value.kind_of?(TrueClass)
406
+ end
407
+
408
+ should "permit replacing value with nil" do
409
+ @user_clone.true_value = nil
410
+ @user_clone.save!
411
+
412
+ @user.reload
413
+ assert_nil @user.true_value
414
+ assert_nil @user.encrypted_true_value
415
+ end
416
+
417
+ should "permit replacing value" do
418
+ new_value = false
419
+ @user_clone.true_value = new_value
420
+ @user_clone.save!
421
+
422
+ @user.reload
423
+ assert_equal new_value, @user.true_value
424
+ end
425
+ end
426
+
427
+ context "false values" do
428
+ should "return correct data type" do
429
+ assert_equal false, @user_clone.false_value
430
+ assert @user.clone.false_value.kind_of?(FalseClass)
431
+ end
432
+
433
+ should "coerce data type before save" do
434
+ u = MongoidUser.new(false_value: "0")
435
+ assert_equal false, u.false_value
436
+ assert u.false_value.kind_of?(FalseClass)
437
+ end
438
+
439
+ should "permit replacing value with nil" do
440
+ @user_clone.false_value = nil
441
+ @user_clone.save!
442
+
443
+ @user.reload
444
+ assert_nil @user.false_value
445
+ assert_nil @user.encrypted_false_value
446
+ end
447
+
448
+ should "permit replacing value" do
449
+ new_value = true
450
+ @user_clone.false_value = new_value
451
+ @user_clone.save!
452
+
453
+ @user.reload
454
+ assert_equal new_value, @user.false_value
455
+ end
456
+ end
457
+
458
+ context "JSON Serialization" do
459
+ setup do
460
+ # JSON Does not support symbols, so they will come back as strings
461
+ # Convert symbols to string in the test
462
+ @h.keys.each do |k|
463
+ @h[k.to_s] = @h[k]
464
+ @h.delete(k)
465
+ end
466
+ end
467
+
468
+ should "return correct data type" do
469
+ assert_equal @h, @user_clone.data_json
470
+ assert @user.clone.data_json.kind_of?(Hash)
471
+ end
472
+
473
+ should "not coerce data type (leaves as hash) before save" do
474
+ u = MongoidUser.new(data_json: @h)
475
+ assert_equal @h, u.data_json
476
+ assert u.data_json.kind_of?(Hash)
477
+ end
478
+
479
+ should "permit replacing value with nil" do
480
+ @user_clone.data_json = nil
481
+ @user_clone.save!
482
+
483
+ @user.reload
484
+ assert_nil @user.data_json
485
+ assert_nil @user.encrypted_data_json
486
+ end
487
+
488
+ should "permit replacing value" do
489
+ new_value = @h.clone
490
+ new_value['c'] = 'C'
491
+ @user_clone.data_json = new_value
492
+ @user_clone.save!
493
+
494
+ @user.reload
495
+ assert_equal new_value, @user.data_json
496
+ end
497
+ end
498
+
499
+ context "YAML Serialization" do
500
+ should "return correct data type" do
501
+ assert_equal @h, @user_clone.data_yaml
502
+ assert @user.clone.data_yaml.kind_of?(Hash)
503
+ end
504
+
505
+ should "not coerce data type (leaves as hash) before save" do
506
+ u = MongoidUser.new(data_yaml: @h)
507
+ assert_equal @h, u.data_yaml
508
+ assert u.data_yaml.kind_of?(Hash)
509
+ end
510
+
511
+ should "permit replacing value with nil" do
512
+ @user_clone.data_yaml = nil
513
+ @user_clone.save!
514
+
515
+ @user.reload
516
+ assert_nil @user.data_yaml
517
+ assert_nil @user.encrypted_data_yaml
518
+ end
519
+
520
+ should "permit replacing value" do
521
+ new_value = @h.clone
522
+ new_value[:c] = 'C'
523
+ @user_clone.data_yaml = new_value
524
+ @user_clone.save!
525
+
526
+ @user.reload
527
+ assert_equal new_value, @user.data_yaml
528
+ end
529
+ end
530
+
531
+ end
532
+
533
+ end
534
+ end
535
+ end