symmetric-encryption 3.4.0 → 3.6.0

Sign up to get free protection for your applications and to get access to all the features.
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