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
@@ -89,19 +89,19 @@ class ReaderTest < Test::Unit::TestCase
89
89
 
90
90
  [
91
91
  # No Header
92
- {:header => false, :random_key => false, :random_iv => false},
92
+ {header: false, random_key: false, random_iv: false},
93
93
  # Default Header with random key and iv
94
94
  {},
95
95
  # Header with no compression ( default anyway )
96
- {:compress => false},
96
+ {compress: false},
97
97
  # Compress and use Random key, iv
98
- {:compress => true},
98
+ {compress: true},
99
99
  # Header but not random key or iv
100
- {:random_key => false},
100
+ {random_key: false},
101
101
  # Random iv only
102
- {:random_key => false, :random_iv => true},
102
+ {random_key: false, random_iv: true},
103
103
  # Random iv only with compression
104
- {:random_iv => true, :compress => true},
104
+ {random_iv: true, compress: true},
105
105
  ].each do |options|
106
106
 
107
107
  [:data, :empty, :blank].each do |usecase|
@@ -245,7 +245,7 @@ class ReaderTest < Test::Unit::TestCase
245
245
  setup do
246
246
  @filename = '_test'
247
247
  # Create encrypted file with old encryption key
248
- SymmetricEncryption::Writer.open(@filename, :version => 0) do |file|
248
+ SymmetricEncryption::Writer.open(@filename, version: 0) do |file|
249
249
  @data.inject(0) {|sum,str| sum + file.write(str)}
250
250
  end
251
251
  end
@@ -283,7 +283,7 @@ class ReaderTest < Test::Unit::TestCase
283
283
  setup do
284
284
  @filename = '_test'
285
285
  # Create encrypted file with old encryption key
286
- SymmetricEncryption::Writer.open(@filename, :version => 0, :header => false, :random_key => false) do |file|
286
+ SymmetricEncryption::Writer.open(@filename, version: 0, header: false, random_key: false) do |file|
287
287
  @data.inject(0) {|sum,str| sum + file.write(str)}
288
288
  end
289
289
  end
@@ -297,14 +297,14 @@ class ReaderTest < Test::Unit::TestCase
297
297
  end
298
298
 
299
299
  should "decrypt from file in a single read" do
300
- decrypted = SymmetricEncryption::Reader.open(@filename, :version => 0) {|file| file.read}
300
+ decrypted = SymmetricEncryption::Reader.open(@filename, version: 0) {|file| file.read}
301
301
  assert_equal @data_str, decrypted
302
302
  end
303
303
 
304
304
  should "decrypt from file in a single read with different version" do
305
305
  # Should fail since file was encrypted using version 0 key
306
306
  assert_raise OpenSSL::Cipher::CipherError do
307
- SymmetricEncryption::Reader.open(@filename, :version => 2) {|file| file.read}
307
+ SymmetricEncryption::Reader.open(@filename, version: 2) {|file| file.read}
308
308
  end
309
309
  end
310
310
  end
@@ -108,41 +108,41 @@ class SymmetricEncryptionTest < Test::Unit::TestCase
108
108
  assert_equal false, SymmetricEncryption.encrypted?(@social_security_number)
109
109
  end
110
110
  end
111
+ end
111
112
 
112
- context "using select_cipher" do
113
- setup do
114
- @social_security_number = "987654321"
115
- # Encrypt data without a header and encode with base64 which has a trailing '\n'
116
- @encrypted_0_ssn = SymmetricEncryption.cipher(0).encode(SymmetricEncryption.cipher(0).binary_encrypt(@social_security_number,false,false,false))
113
+ context "using select_cipher" do
114
+ setup do
115
+ @social_security_number = "987654321"
116
+ # Encrypt data without a header and encode with base64 which has a trailing '\n'
117
+ @encrypted_0_ssn = SymmetricEncryption.cipher(0).encode(SymmetricEncryption.cipher(0).binary_encrypt(@social_security_number,false,false,false))
117
118
 
118
- SymmetricEncryption.select_cipher do |encoded_str, decoded_str|
119
- # Use cipher version 0 if the encoded string ends with "\n" otherwise
120
- # use the current default cipher
121
- encoded_str.end_with?("\n") ? SymmetricEncryption.cipher(0) : SymmetricEncryption.cipher
122
- end
119
+ SymmetricEncryption.select_cipher do |encoded_str, decoded_str|
120
+ # Use cipher version 0 if the encoded string ends with "\n" otherwise
121
+ # use the current default cipher
122
+ encoded_str.end_with?("\n") ? SymmetricEncryption.cipher(0) : SymmetricEncryption.cipher
123
123
  end
124
+ end
124
125
 
125
- teardown do
126
- # Clear out select_cipher
127
- SymmetricEncryption.select_cipher
128
- end
126
+ teardown do
127
+ # Clear out select_cipher
128
+ SymmetricEncryption.select_cipher
129
+ end
129
130
 
130
- should "decrypt string without a header using an old cipher" do
131
- assert_equal @social_security_number, SymmetricEncryption.decrypt(@encrypted_0_ssn)
132
- end
131
+ should "decrypt string without a header using an old cipher" do
132
+ assert_equal @social_security_number, SymmetricEncryption.decrypt(@encrypted_0_ssn)
133
133
  end
134
+ end
134
135
 
135
- context "without select_cipher" do
136
- setup do
137
- @social_security_number = "987654321"
138
- # Encrypt data without a header and encode with base64 which has a trailing '\n'
139
- assert @encrypted_0_ssn = SymmetricEncryption.cipher(0).encode(SymmetricEncryption.cipher(0).binary_encrypt(@social_security_number,false,false,false))
140
- end
136
+ context "without select_cipher" do
137
+ setup do
138
+ @social_security_number = "987654321"
139
+ # Encrypt data without a header and encode with base64 which has a trailing '\n'
140
+ assert @encrypted_0_ssn = SymmetricEncryption.cipher(0).encode(SymmetricEncryption.cipher(0).binary_encrypt(@social_security_number,false,false,false))
141
+ end
141
142
 
142
- should "decrypt string without a header using an old cipher" do
143
- assert_raises OpenSSL::Cipher::CipherError do
144
- SymmetricEncryption.decrypt(@encrypted_0_ssn)
145
- end
143
+ should "decrypt string without a header using an old cipher" do
144
+ assert_raises OpenSSL::Cipher::CipherError do
145
+ SymmetricEncryption.decrypt(@encrypted_0_ssn)
146
146
  end
147
147
  end
148
148
  end
Binary file
@@ -7,7 +7,6 @@ require 'erb'
7
7
  require 'test/unit'
8
8
  # Since we want both the AR and Mongoid extensions loaded we need to require them first
9
9
  require 'active_record'
10
- require 'mongoid'
11
10
  require 'symmetric-encryption'
12
11
  # Should redefines Proc#bind so must include after Rails
13
12
  require 'shoulda'
@@ -27,7 +27,7 @@ class WriterTest < Test::Unit::TestCase
27
27
 
28
28
  should "encrypt to string stream" do
29
29
  stream = StringIO.new
30
- file = SymmetricEncryption::Writer.new(stream, :header => false, :random_key => false, :random_iv => false)
30
+ file = SymmetricEncryption::Writer.new(stream, header: false, random_key: false, random_iv: false)
31
31
  written_len = @data.inject(0) {|sum,str| sum + file.write(str)}
32
32
  assert_equal @data_len, file.size
33
33
  file.close
@@ -50,7 +50,7 @@ class WriterTest < Test::Unit::TestCase
50
50
 
51
51
  should "encrypt to file using .open" do
52
52
  written_len = nil
53
- SymmetricEncryption::Writer.open(@filename, :header => false, :random_key => false, :random_iv => false) do |file|
53
+ SymmetricEncryption::Writer.open(@filename, header: false, random_key: false, random_iv: false) do |file|
54
54
  written_len = @data.inject(0) {|sum,str| sum + file.write(str)}
55
55
  assert_equal @data_len, file.size
56
56
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: symmetric-encryption
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.0
4
+ version: 3.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-17 00:00:00.000000000 Z
11
+ date: 2014-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: coercible
@@ -46,7 +46,9 @@ files:
46
46
  - lib/symmetric_encryption.rb
47
47
  - lib/symmetric_encryption/cipher.rb
48
48
  - lib/symmetric_encryption/extensions/active_record/base.rb
49
- - lib/symmetric_encryption/mongoid.rb
49
+ - lib/symmetric_encryption/extensions/mongo_mapper/plugins/encrypted_key.rb
50
+ - lib/symmetric_encryption/extensions/mongoid/encrypted.rb
51
+ - lib/symmetric_encryption/generator.rb
50
52
  - lib/symmetric_encryption/railtie.rb
51
53
  - lib/symmetric_encryption/railties/symmetric_encryption.rake
52
54
  - lib/symmetric_encryption/railties/symmetric_encryption_validator.rb
@@ -54,10 +56,11 @@ files:
54
56
  - lib/symmetric_encryption/symmetric_encryption.rb
55
57
  - lib/symmetric_encryption/version.rb
56
58
  - lib/symmetric_encryption/writer.rb
57
- - test/attr_encrypted_test.rb
59
+ - test/active_record_test.rb
58
60
  - test/cipher_test.rb
59
61
  - test/config/database.yml
60
62
  - test/config/empty.csv
63
+ - test/config/mongo_mapper.yml
61
64
  - test/config/mongoid_v2.yml
62
65
  - test/config/mongoid_v3.yml
63
66
  - test/config/symmetric-encryption.yml
@@ -65,7 +68,8 @@ files:
65
68
  - test/config/test_new.key
66
69
  - test/config/test_secondary_1.iv
67
70
  - test/config/test_secondary_1.key
68
- - test/field_encrypted_test.rb
71
+ - test/mongo_mapper_test.rb
72
+ - test/mongoid_test.rb
69
73
  - test/reader_test.rb
70
74
  - test/symmetric_encryption_test.rb
71
75
  - test/test_db.sqlite3
@@ -91,15 +95,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
95
  version: '0'
92
96
  requirements: []
93
97
  rubyforge_project:
94
- rubygems_version: 2.2.0
98
+ rubygems_version: 2.2.2
95
99
  signing_key:
96
100
  specification_version: 4
97
101
  summary: Symmetric Encryption for Ruby, and Ruby on Rails
98
102
  test_files:
99
- - test/attr_encrypted_test.rb
103
+ - test/active_record_test.rb
100
104
  - test/cipher_test.rb
101
105
  - test/config/database.yml
102
106
  - test/config/empty.csv
107
+ - test/config/mongo_mapper.yml
103
108
  - test/config/mongoid_v2.yml
104
109
  - test/config/mongoid_v3.yml
105
110
  - test/config/symmetric-encryption.yml
@@ -107,7 +112,8 @@ test_files:
107
112
  - test/config/test_new.key
108
113
  - test/config/test_secondary_1.iv
109
114
  - test/config/test_secondary_1.key
110
- - test/field_encrypted_test.rb
115
+ - test/mongo_mapper_test.rb
116
+ - test/mongoid_test.rb
111
117
  - test/reader_test.rb
112
118
  - test/symmetric_encryption_test.rb
113
119
  - test/test_db.sqlite3
@@ -1,622 +0,0 @@
1
- require File.dirname(__FILE__) + '/test_helper'
2
-
3
- ActiveRecord::Base.logger = SemanticLogger[ActiveRecord]
4
- ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read('test/config/database.yml')).result)
5
- ActiveRecord::Base.establish_connection('test')
6
-
7
- ActiveRecord::Schema.define :version => 0 do
8
- create_table :users, :force => true do |t|
9
- t.string :encrypted_bank_account_number
10
- t.string :encrypted_social_security_number
11
- t.string :encrypted_string
12
- t.text :encrypted_long_string
13
- t.text :encrypted_data_yaml
14
- t.text :encrypted_data_json
15
- t.string :name
16
-
17
- t.string :encrypted_integer_value
18
- t.string :encrypted_float_value
19
- t.string :encrypted_decimal_value
20
- t.string :encrypted_datetime_value
21
- t.string :encrypted_time_value
22
- t.string :encrypted_date_value
23
- t.string :encrypted_true_value
24
- t.string :encrypted_false_value
25
- end
26
- end
27
-
28
- class User < ActiveRecord::Base
29
- attr_encrypted :bank_account_number
30
- attr_encrypted :social_security_number
31
- attr_encrypted :string, :random_iv => true
32
- attr_encrypted :long_string, :random_iv => true, :compress => true
33
- attr_encrypted :data_yaml, :random_iv => true, :compress => true, :type => :yaml
34
- attr_encrypted :data_json, :random_iv => true, :compress => true, :type => :json
35
-
36
- attr_encrypted :integer_value, :type => :integer
37
- attr_encrypted :float_value, :type => :float
38
- attr_encrypted :decimal_value, :type => :decimal
39
- attr_encrypted :datetime_value, :type => :datetime
40
- attr_encrypted :time_value, :type => :time
41
- attr_encrypted :date_value, :type => :date
42
- attr_encrypted :true_value, :type => :boolean
43
- attr_encrypted :false_value, :type => :boolean
44
-
45
- validates :encrypted_bank_account_number, :symmetric_encryption => true
46
- validates :encrypted_social_security_number, :symmetric_encryption => true
47
- end
48
-
49
- # Load Symmetric Encryption keys
50
- SymmetricEncryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
51
-
52
- # Initialize the database connection
53
- config_file = File.join(File.dirname(__FILE__), 'config', 'database.yml')
54
- raise "database config not found. Create a config file at: test/config/database.yml" unless File.exists? config_file
55
-
56
- cfg = YAML.load(ERB.new(File.new(config_file).read).result)['test']
57
- raise("Environment 'test' not defined in test/config/database.yml") unless cfg
58
-
59
- User.establish_connection(cfg)
60
-
61
- #
62
- # Unit Test for attr_encrypted and validation aspects of SymmetricEncryption
63
- #
64
- class AttrEncryptedTest < Test::Unit::TestCase
65
- context 'the SymmetricEncryption Library' do
66
-
67
- setup do
68
- @bank_account_number = "1234567890"
69
- @bank_account_number_encrypted = "QEVuQwIAL94ArJeFlJrZp6SYsvoOGA=="
70
-
71
- @social_security_number = "987654321"
72
- @social_security_number_encrypted = "QEVuQwIAS+8X1NRrqdfEIQyFHVPuVA=="
73
-
74
- @string = "A string containing some data to be encrypted with a random initialization vector"
75
- @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"
76
-
77
- @name = 'Joe Bloggs'
78
-
79
- @integer_value = 12
80
- @float_value = 88.12345
81
- @decimal_value = BigDecimal.new("22.51")
82
- @datetime_value = DateTime.new(2001, 11, 26, 20, 55, 54, "-5")
83
- @time_value = Time.new(2013, 01, 01, 22, 30, 00, "-04:00")
84
- @date_value = Date.new(1927, 04, 02)
85
- @h = { :a => 'A', :b => 'B' }
86
-
87
- @user = User.new(
88
- # Encrypted Attribute
89
- :bank_account_number => @bank_account_number,
90
- # Encrypted Attribute
91
- :social_security_number => @social_security_number,
92
- :name => @name,
93
- # data type specific fields
94
- :integer_value => @integer_value,
95
- :float_value => @float_value,
96
- :decimal_value => @decimal_value,
97
- :datetime_value => @datetime_value,
98
- :time_value => @time_value,
99
- :date_value => @date_value,
100
- :true_value => true,
101
- :false_value => false,
102
- :data_yaml => @h.dup,
103
- :data_json => @h.dup
104
- )
105
- end
106
-
107
- should "have encrypted methods" do
108
- assert_equal true, @user.respond_to?(:encrypted_bank_account_number)
109
- assert_equal true, @user.respond_to?(:bank_account_number)
110
- assert_equal true, @user.respond_to?(:encrypted_social_security_number)
111
- assert_equal true, @user.respond_to?(:social_security_number)
112
- assert_equal true, @user.respond_to?(:data_yaml)
113
- assert_equal true, @user.respond_to?(:data_json)
114
- assert_equal false, @user.respond_to?(:encrypted_name)
115
- end
116
-
117
- should "have unencrypted values" do
118
- assert_equal @bank_account_number, @user.bank_account_number
119
- assert_equal @social_security_number, @user.social_security_number
120
- end
121
-
122
- should "have encrypted values" do
123
- assert_equal @bank_account_number_encrypted, @user.encrypted_bank_account_number
124
- assert_equal @social_security_number_encrypted, @user.encrypted_social_security_number
125
- end
126
-
127
- should "support same iv" do
128
- @user.social_security_number = @social_security_number
129
- assert first_value = @user.social_security_number
130
- # Assign the same value
131
- @user.social_security_number = @social_security_number
132
- assert_equal first_value, @user.social_security_number
133
- end
134
-
135
- should "support a random iv" do
136
- @user.string = @string
137
- assert first_value = @user.encrypted_string
138
- # Assign the same value
139
- @user.string = @string.dup
140
- assert_equal true, first_value != @user.encrypted_string
141
- end
142
-
143
- should "support a random iv and compress" do
144
- @user.string = @long_string
145
- @user.long_string = @long_string
146
-
147
- assert_equal true, (@user.encrypted_long_string.length.to_f / @user.encrypted_string.length) < 0.8
148
- end
149
-
150
- should "encrypt" do
151
- user = User.new
152
- user.bank_account_number = @bank_account_number
153
- assert_equal @bank_account_number, user.bank_account_number
154
- assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
155
- end
156
-
157
- should "allow lookups using unencrypted or encrypted column name" do
158
- @user.save!
159
-
160
- inq = User.find_by_bank_account_number(@bank_account_number)
161
- assert_equal @bank_account_number, inq.bank_account_number
162
- assert_equal @bank_account_number_encrypted, inq.encrypted_bank_account_number
163
-
164
- @user.delete
165
- end
166
-
167
- should "all paths should lead to the same result" do
168
- assert_equal @bank_account_number_encrypted, (@user.encrypted_social_security_number = @bank_account_number_encrypted)
169
- assert_equal @bank_account_number, @user.social_security_number
170
- assert_equal @bank_account_number_encrypted, @user.encrypted_social_security_number
171
- end
172
-
173
- should "all paths should lead to the same result 2" do
174
- assert_equal @bank_account_number, (@user.social_security_number = @bank_account_number)
175
- assert_equal @bank_account_number_encrypted, @user.encrypted_social_security_number
176
- assert_equal @bank_account_number, @user.social_security_number
177
- end
178
-
179
- should "all paths should lead to the same result, check uninitialized" do
180
- user = User.new
181
- assert_equal nil, user.social_security_number
182
- assert_equal @bank_account_number, (user.social_security_number = @bank_account_number)
183
- assert_equal @bank_account_number, user.social_security_number
184
- assert_equal @bank_account_number_encrypted, user.encrypted_social_security_number
185
-
186
- assert_equal nil, (user.social_security_number = nil)
187
- assert_equal nil, user.social_security_number
188
- assert_equal nil, user.encrypted_social_security_number
189
- end
190
-
191
- should "allow unencrypted values to be passed to the constructor" do
192
- user = User.new(:bank_account_number => @bank_account_number, :social_security_number => @social_security_number)
193
- assert_equal @bank_account_number, user.bank_account_number
194
- assert_equal @social_security_number, user.social_security_number
195
- assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
196
- assert_equal @social_security_number_encrypted, user.encrypted_social_security_number
197
- end
198
-
199
- should "return encrypted attributes for the class" do
200
- expect = {:social_security_number=>:encrypted_social_security_number, :bank_account_number=>:encrypted_bank_account_number}
201
- result = User.encrypted_attributes
202
- expect.each_pair {|k,v| assert_equal expect[k], result[k]}
203
- end
204
-
205
- should "return encrypted keys for the class" do
206
- expect = [:social_security_number, :bank_account_number]
207
- result = User.encrypted_keys
208
- expect.each {|val| assert_equal true, result.include?(val)}
209
-
210
- # Also check encrypted_attribute?
211
- expect.each {|val| assert_equal true, User.encrypted_attribute?(val)}
212
- end
213
-
214
- should "return encrypted columns for the class" do
215
- expect = [:encrypted_social_security_number, :encrypted_bank_account_number]
216
- result = User.encrypted_columns
217
- expect.each {|val| assert_equal true, result.include?(val)}
218
-
219
- # Also check encrypted_column?
220
- expect.each {|val| assert_equal true, User.encrypted_column?(val)}
221
- end
222
-
223
- should "validate encrypted data" do
224
- assert_equal true, @user.valid?
225
- @user.encrypted_bank_account_number = '123'
226
- assert_equal false, @user.valid?
227
- assert_equal ["must be a value encrypted using SymmetricEncryption.encrypt"], @user.errors[:encrypted_bank_account_number]
228
- @user.encrypted_bank_account_number = SymmetricEncryption.encrypt('123')
229
- assert_equal true, @user.valid?
230
- @user.bank_account_number = '123'
231
- assert_equal true, @user.valid?
232
- end
233
-
234
-
235
-
236
- context "with saved user" do
237
- setup do
238
- @user.save!
239
- end
240
-
241
- teardown do
242
- @user.destroy
243
- end
244
-
245
- should "return correct data type before save" do
246
- u = User.new(:integer_value => "5")
247
- assert_equal 5, u.integer_value
248
- assert u.integer_value.kind_of?(Integer)
249
- end
250
-
251
- should "handle gsub! for non-encrypted_field" do
252
- @user.name.gsub!('a', 'v')
253
- new_name = @name.gsub('a', 'v')
254
- assert_equal new_name, @user.name
255
- @user.reload
256
- assert_equal new_name, @user.name
257
- end
258
-
259
- should "prevent gsub! on non-encrypted value of encrypted_field" do
260
- # can't modify frozen String
261
- assert_raises RuntimeError do
262
- @user.bank_account_number.gsub!('5', '4')
263
- end
264
- end
265
-
266
- should "revert changes on reload" do
267
- new_bank_account_number = '444444444'
268
- @user.bank_account_number = new_bank_account_number
269
- assert_equal new_bank_account_number, @user.bank_account_number
270
-
271
- # Reload User model from the database
272
- @user.reload
273
- assert_equal @bank_account_number_encrypted, @user.encrypted_bank_account_number
274
- assert_equal @bank_account_number, @user.bank_account_number
275
- end
276
-
277
- should "revert changes to encrypted field on reload" do
278
- new_bank_account_number = '111111111'
279
- new_encrypted_bank_account_number = SymmetricEncryption.encrypt(new_bank_account_number)
280
- @user.encrypted_bank_account_number = new_encrypted_bank_account_number
281
- assert_equal new_encrypted_bank_account_number, @user.encrypted_bank_account_number
282
- assert_equal new_bank_account_number, @user.bank_account_number
283
-
284
- # Reload User model from the database
285
- @user.reload
286
- assert_equal @bank_account_number_encrypted, @user.encrypted_bank_account_number
287
- assert_equal @bank_account_number, @user.bank_account_number
288
- end
289
-
290
- context "data types" do
291
- setup do
292
- @user_clone = User.find(@user.id)
293
- end
294
-
295
- context "integer values" do
296
- should "return correct data type" do
297
- assert_equal @integer_value, @user_clone.integer_value
298
- assert @user.clone.integer_value.kind_of?(Integer)
299
- end
300
-
301
- should "coerce data type before save" do
302
- u = User.new(:integer_value => "5")
303
- assert_equal 5, u.integer_value
304
- assert u.integer_value.kind_of?(Integer)
305
- end
306
-
307
- should "permit replacing value with nil" do
308
- @user_clone.integer_value = nil
309
- @user_clone.save!
310
-
311
- @user.reload
312
- assert_nil @user.integer_value
313
- assert_nil @user.encrypted_integer_value
314
- end
315
-
316
- should "permit replacing value" do
317
- new_integer_value = 98
318
- @user_clone.integer_value = new_integer_value
319
- @user_clone.save!
320
-
321
- @user.reload
322
- assert_equal new_integer_value, @user.integer_value
323
- end
324
- end
325
-
326
- context "float values" do
327
- should "return correct data type" do
328
- assert_equal @float_value, @user_clone.float_value
329
- assert @user.clone.float_value.kind_of?(Float)
330
- end
331
-
332
- should "coerce data type before save" do
333
- u = User.new(:float_value => "5.6")
334
- assert_equal 5.6, u.float_value
335
- assert u.float_value.kind_of?(Float)
336
- end
337
-
338
- should "permit replacing value with nil" do
339
- @user_clone.float_value = nil
340
- @user_clone.save!
341
-
342
- @user.reload
343
- assert_nil @user.float_value
344
- assert_nil @user.encrypted_float_value
345
- end
346
-
347
- should "permit replacing value" do
348
- new_float_value = 45.4321
349
- @user_clone.float_value = new_float_value
350
- @user_clone.save!
351
-
352
- @user.reload
353
- assert_equal new_float_value, @user.float_value
354
- end
355
- end
356
-
357
- context "decimal values" do
358
- should "return correct data type" do
359
- assert_equal @decimal_value, @user_clone.decimal_value
360
- assert @user.clone.decimal_value.kind_of?(BigDecimal)
361
- end
362
-
363
- should "coerce data type before save" do
364
- u = User.new(:decimal_value => "99.95")
365
- assert_equal BigDecimal.new("99.95"), u.decimal_value
366
- assert u.decimal_value.kind_of?(BigDecimal)
367
- end
368
-
369
- should "permit replacing value with nil" do
370
- @user_clone.decimal_value = nil
371
- @user_clone.save!
372
-
373
- @user.reload
374
- assert_nil @user.decimal_value
375
- assert_nil @user.encrypted_decimal_value
376
- end
377
-
378
- should "permit replacing value" do
379
- new_decimal_value = BigDecimal.new("99.95")
380
- @user_clone.decimal_value = new_decimal_value
381
- @user_clone.save!
382
-
383
- @user.reload
384
- assert_equal new_decimal_value, @user.decimal_value
385
- end
386
- end
387
-
388
- context "datetime values" do
389
- should "return correct data type" do
390
- assert_equal @datetime_value, @user_clone.datetime_value
391
- assert @user.clone.datetime_value.kind_of?(DateTime)
392
- end
393
-
394
- should "coerce data type before save" do
395
- now = Time.now
396
- u = User.new(:datetime_value => now)
397
- assert_equal now, u.datetime_value
398
- assert u.datetime_value.kind_of?(DateTime)
399
- end
400
-
401
- should "permit replacing value with nil" do
402
- @user_clone.datetime_value = nil
403
- @user_clone.save!
404
-
405
- @user.reload
406
- assert_nil @user.datetime_value
407
- assert_nil @user.encrypted_datetime_value
408
- end
409
-
410
- should "permit replacing value" do
411
- new_datetime_value = DateTime.new(1998, 10, 21, 8, 33, 28, "+5")
412
- @user_clone.datetime_value = new_datetime_value
413
- @user_clone.save!
414
-
415
- @user.reload
416
- assert_equal new_datetime_value, @user.datetime_value
417
- end
418
- end
419
-
420
- context "time values" do
421
- should "return correct data type" do
422
- assert_equal @time_value, @user_clone.time_value
423
- assert @user.clone.time_value.kind_of?(Time)
424
- end
425
-
426
- should "coerce data type before save" do
427
- now = Time.now
428
- u = User.new(:time_value => now)
429
- assert_equal now, u.time_value
430
- assert u.time_value.kind_of?(Time)
431
- end
432
-
433
- should "permit replacing value with nil" do
434
- @user_clone.time_value = nil
435
- @user_clone.save!
436
-
437
- @user.reload
438
- assert_nil @user.time_value
439
- assert_nil @user.encrypted_time_value
440
- end
441
-
442
- should "permit replacing value" do
443
- new_time_value = Time.new(1998, 10, 21, 8, 33, 28, "+04:00")
444
- @user_clone.time_value = new_time_value
445
- @user_clone.save!
446
-
447
- @user.reload
448
- assert_equal new_time_value, @user.time_value
449
- end
450
- end
451
-
452
- context "date values" do
453
- should "return correct data type" do
454
- assert_equal @date_value, @user_clone.date_value
455
- assert @user.clone.date_value.kind_of?(Date)
456
- end
457
-
458
- should "coerce data type before save" do
459
- now = Time.now
460
- u = User.new(:date_value => now)
461
- assert_equal now.to_date, u.date_value
462
- assert u.date_value.kind_of?(Date)
463
- end
464
-
465
- should "permit replacing value with nil" do
466
- @user_clone.date_value = nil
467
- @user_clone.save!
468
-
469
- @user.reload
470
- assert_nil @user.date_value
471
- assert_nil @user.encrypted_date_value
472
- end
473
-
474
- should "permit replacing value" do
475
- new_date_value = Date.new(1998, 10, 21)
476
- @user_clone.date_value = new_date_value
477
- @user_clone.save!
478
-
479
- @user.reload
480
- assert_equal new_date_value, @user.date_value
481
- end
482
- end
483
-
484
- context "true values" do
485
- should "return correct data type" do
486
- assert_equal true, @user_clone.true_value
487
- assert @user.clone.true_value.kind_of?(TrueClass)
488
- end
489
-
490
- should "coerce data type before save" do
491
- u = User.new(:true_value => "1")
492
- assert_equal true, u.true_value
493
- assert u.true_value.kind_of?(TrueClass)
494
- end
495
-
496
- should "permit replacing value with nil" do
497
- @user_clone.true_value = nil
498
- @user_clone.save!
499
-
500
- @user.reload
501
- assert_nil @user.true_value
502
- assert_nil @user.encrypted_true_value
503
- end
504
-
505
- should "permit replacing value" do
506
- new_value = false
507
- @user_clone.true_value = new_value
508
- @user_clone.save!
509
-
510
- @user.reload
511
- assert_equal new_value, @user.true_value
512
- end
513
- end
514
-
515
- context "false values" do
516
- should "return correct data type" do
517
- assert_equal false, @user_clone.false_value
518
- assert @user.clone.false_value.kind_of?(FalseClass)
519
- end
520
-
521
- should "coerce data type before save" do
522
- u = User.new(:false_value => "0")
523
- assert_equal false, u.false_value
524
- assert u.false_value.kind_of?(FalseClass)
525
- end
526
-
527
- should "permit replacing value with nil" do
528
- @user_clone.false_value = nil
529
- @user_clone.save!
530
-
531
- @user.reload
532
- assert_nil @user.false_value
533
- assert_nil @user.encrypted_false_value
534
- end
535
-
536
- should "permit replacing value" do
537
- new_value = true
538
- @user_clone.false_value = new_value
539
- @user_clone.save!
540
-
541
- @user.reload
542
- assert_equal new_value, @user.false_value
543
- end
544
- end
545
-
546
- context "JSON Serialization" do
547
- setup do
548
- # JSON Does not support symbols, so they will come back as strings
549
- # Convert symbols to string in the test
550
- @h.keys.each do |k|
551
- @h[k.to_s] = @h[k]
552
- @h.delete(k)
553
- end
554
- end
555
-
556
- should "return correct data type" do
557
- assert_equal @h, @user_clone.data_json
558
- assert @user.clone.data_json.kind_of?(Hash)
559
- end
560
-
561
- should "not coerce data type (leaves as hash) before save" do
562
- u = User.new(:data_json => @h)
563
- assert_equal @h, u.data_json
564
- assert u.data_json.kind_of?(Hash)
565
- end
566
-
567
- should "permit replacing value with nil" do
568
- @user_clone.data_json = nil
569
- @user_clone.save!
570
-
571
- @user.reload
572
- assert_nil @user.data_json
573
- assert_nil @user.encrypted_data_json
574
- end
575
-
576
- should "permit replacing value" do
577
- new_value = @h.clone
578
- new_value['c'] = 'C'
579
- @user_clone.data_json = new_value
580
- @user_clone.save!
581
-
582
- @user.reload
583
- assert_equal new_value, @user.data_json
584
- end
585
- end
586
-
587
- context "YAML Serialization" do
588
- should "return correct data type" do
589
- assert_equal @h, @user_clone.data_yaml
590
- assert @user.clone.data_yaml.kind_of?(Hash)
591
- end
592
-
593
- should "not coerce data type (leaves as hash) before save" do
594
- u = User.new(:data_yaml => @h)
595
- assert_equal @h, u.data_yaml
596
- assert u.data_yaml.kind_of?(Hash)
597
- end
598
-
599
- should "permit replacing value with nil" do
600
- @user_clone.data_yaml = nil
601
- @user_clone.save!
602
-
603
- @user.reload
604
- assert_nil @user.data_yaml
605
- assert_nil @user.encrypted_data_yaml
606
- end
607
-
608
- should "permit replacing value" do
609
- new_value = @h.clone
610
- new_value[:c] = 'C'
611
- @user_clone.data_yaml = new_value
612
- @user_clone.save!
613
-
614
- @user.reload
615
- assert_equal new_value, @user.data_yaml
616
- end
617
- end
618
-
619
- end
620
- end
621
- end
622
- end