attr_encrypted 1.2.1 → 1.3.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.
- data/README.rdoc +2 -2
- data/Rakefile +15 -4
- data/lib/attr_encrypted.rb +45 -1
- data/lib/attr_encrypted/adapters/active_record.rb +9 -0
- data/lib/attr_encrypted/version.rb +2 -2
- data/test/active_record_test.rb +48 -52
- data/test/attr_encrypted_test.rb +33 -38
- data/test/compatibility_test.rb +126 -0
- data/test/data_mapper_test.rb +10 -5
- data/test/legacy_active_record_test.rb +116 -0
- data/test/legacy_attr_encrypted_test.rb +297 -0
- data/test/legacy_compatibility_test.rb +104 -0
- data/test/legacy_data_mapper_test.rb +52 -0
- data/test/legacy_sequel_test.rb +48 -0
- data/test/sequel_test.rb +12 -9
- data/test/test_helper.rb +26 -1
- metadata +109 -6
@@ -0,0 +1,126 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../test_helper', __FILE__)
|
3
|
+
|
4
|
+
# Test to ensure that existing representations in database do not break on
|
5
|
+
# migrating to new versions of this gem. This ensures that future versions of
|
6
|
+
# this gem will retain backwards compatibility with data generated by earlier
|
7
|
+
# versions.
|
8
|
+
class CompatibilityTest < Test::Unit::TestCase
|
9
|
+
class NonmarshallingPet < ActiveRecord::Base
|
10
|
+
PET_NICKNAME_SALT = Digest::SHA256.hexdigest('my-really-really-secret-pet-nickname-salt')
|
11
|
+
PET_NICKNAME_KEY = 'my-really-really-secret-pet-nickname-key'
|
12
|
+
PET_BIRTHDATE_SALT = Digest::SHA256.hexdigest('my-really-really-secret-pet-birthdate-salt')
|
13
|
+
PET_BIRTHDATE_KEY = 'my-really-really-secret-pet-birthdate-key'
|
14
|
+
|
15
|
+
self.attr_encrypted_options[:mode] = :per_attribute_iv_and_salt
|
16
|
+
|
17
|
+
attr_encrypted :nickname,
|
18
|
+
:key => proc { Encryptor.encrypt(:value => PET_NICKNAME_SALT, :key => PET_NICKNAME_KEY) }
|
19
|
+
attr_encrypted :birthdate,
|
20
|
+
:key => proc { Encryptor.encrypt(:value => PET_BIRTHDATE_SALT, :key => PET_BIRTHDATE_KEY) }
|
21
|
+
end
|
22
|
+
|
23
|
+
class MarshallingPet < ActiveRecord::Base
|
24
|
+
PET_NICKNAME_SALT = Digest::SHA256.hexdigest('my-really-really-secret-pet-nickname-salt')
|
25
|
+
PET_NICKNAME_KEY = 'my-really-really-secret-pet-nickname-key'
|
26
|
+
PET_BIRTHDATE_SALT = Digest::SHA256.hexdigest('my-really-really-secret-pet-birthdate-salt')
|
27
|
+
PET_BIRTHDATE_KEY = 'my-really-really-secret-pet-birthdate-key'
|
28
|
+
|
29
|
+
self.attr_encrypted_options[:mode] = :per_attribute_iv_and_salt
|
30
|
+
|
31
|
+
attr_encrypted :nickname,
|
32
|
+
:key => proc { Encryptor.encrypt(:value => PET_NICKNAME_SALT, :key => PET_NICKNAME_KEY) },
|
33
|
+
:marshal => true
|
34
|
+
attr_encrypted :birthdate,
|
35
|
+
:key => proc { Encryptor.encrypt(:value => PET_BIRTHDATE_SALT, :key => PET_BIRTHDATE_KEY) },
|
36
|
+
:marshal => true
|
37
|
+
end
|
38
|
+
|
39
|
+
def setup
|
40
|
+
ActiveRecord::Base.connection.tables.each { |table| ActiveRecord::Base.connection.drop_table(table) }
|
41
|
+
create_tables
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_nonmarshalling_backwards_compatibility
|
45
|
+
pet = NonmarshallingPet.create!(
|
46
|
+
:name => 'Fido',
|
47
|
+
:encrypted_nickname => 'E4lJTxFG/EfkfPg5MpnriQ==',
|
48
|
+
:encrypted_nickname_iv => 'z4Q8deE4h7f6S8NNZcbPNg==',
|
49
|
+
:encrypted_nickname_salt => 'adcd833001a873db',
|
50
|
+
:encrypted_birthdate => '6uKEAiFVdJw+N5El+U6Gow==',
|
51
|
+
:encrypted_birthdate_iv => 'zxtc1XPssL4s2HwA69nORQ==',
|
52
|
+
:encrypted_birthdate_salt => '4f879270045eaad7'
|
53
|
+
)
|
54
|
+
|
55
|
+
assert_equal 'Fido', pet.name
|
56
|
+
assert_equal 'Fido the Dog', pet.nickname
|
57
|
+
assert_equal '2011-07-09', pet.birthdate
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_marshalling_backwards_compatibility
|
61
|
+
# Marshalling formats changed significantly from Ruby 1.8.7 to 1.9.3.
|
62
|
+
# Also, Date class did not correctly support marshalling pre-1.9.3, so here
|
63
|
+
# we just marshal it as a string in the Ruby 1.8.7 case.
|
64
|
+
if RUBY_VERSION < '1.9.3'
|
65
|
+
pet = MarshallingPet.create!(
|
66
|
+
:name => 'Fido',
|
67
|
+
:encrypted_nickname => 'NhpLBIp3aKRzNZrUgUfVuceYi4x+8lE3wUsVCSI9BcU=',
|
68
|
+
:encrypted_nickname_iv => 'wpQqrj3KN16fN6PsAerUTA==',
|
69
|
+
:encrypted_nickname_salt => '8f1a62d274ca8a3a',
|
70
|
+
:encrypted_birthdate => '4nbCEzcj6CjLd3B9liKm9Q==',
|
71
|
+
:encrypted_birthdate_iv => 'Vt10PQZMrbamh/gmjSLdkQ==',
|
72
|
+
:encrypted_birthdate_salt => 'cfb245a3df76404f'
|
73
|
+
)
|
74
|
+
else
|
75
|
+
pet = MarshallingPet.create!(
|
76
|
+
:name => 'Fido',
|
77
|
+
:encrypted_nickname => 'EsQScJYkPw80vVGvKWkE37Px99HHpXPFjoEPTNa4rbs=',
|
78
|
+
:encrypted_nickname_iv => 'fNq1OZcGvty4KfcvGTcFSw==',
|
79
|
+
:encrypted_nickname_salt => '733b459b7d34c217',
|
80
|
+
:encrypted_birthdate => '+VUlKQGfNWkOgCwI4hv+3qlGIwh9h6cJ/ranJlaxvU+xxQdL3H3cOzTcI2rkYkdR',
|
81
|
+
:encrypted_birthdate_iv => 'Ka+zF/SwEYZKwVa24lvFfA==',
|
82
|
+
:encrypted_birthdate_salt => 'd5e892d5bbd81566'
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
86
|
+
assert_equal 'Fido', pet.name
|
87
|
+
assert_equal 'Mummy\'s little helper', pet.nickname
|
88
|
+
|
89
|
+
# See earlier comment.
|
90
|
+
if RUBY_VERSION < '1.9.3'
|
91
|
+
assert_equal '2011-07-09', pet.birthdate
|
92
|
+
else
|
93
|
+
assert_equal Date.new(2011, 7, 9), pet.birthdate
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def create_tables
|
100
|
+
silence_stream(STDOUT) do
|
101
|
+
ActiveRecord::Schema.define(:version => 1) do
|
102
|
+
create_table :nonmarshalling_pets do |t|
|
103
|
+
t.string :name
|
104
|
+
t.string :encrypted_nickname
|
105
|
+
t.string :encrypted_nickname_iv
|
106
|
+
t.string :encrypted_nickname_salt
|
107
|
+
t.string :encrypted_birthdate
|
108
|
+
t.string :encrypted_birthdate_iv
|
109
|
+
t.string :encrypted_birthdate_salt
|
110
|
+
end
|
111
|
+
create_table :marshalling_pets do |t|
|
112
|
+
t.string :name
|
113
|
+
t.string :encrypted_nickname
|
114
|
+
t.string :encrypted_nickname_iv
|
115
|
+
t.string :encrypted_nickname_salt
|
116
|
+
t.string :encrypted_birthdate
|
117
|
+
t.string :encrypted_birthdate_iv
|
118
|
+
t.string :encrypted_birthdate_salt
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => ':memory:'
|
126
|
+
|
data/test/data_mapper_test.rb
CHANGED
@@ -7,15 +7,20 @@ class Client
|
|
7
7
|
|
8
8
|
property :id, Serial
|
9
9
|
property :encrypted_email, String
|
10
|
+
property :encrypted_email_iv, String
|
11
|
+
property :encrypted_email_salt, String
|
12
|
+
|
10
13
|
property :encrypted_credentials, Text
|
11
|
-
property :
|
14
|
+
property :encrypted_credentials_iv, Text
|
15
|
+
property :encrypted_credentials_salt, Text
|
16
|
+
|
17
|
+
self.attr_encrypted_options[:mode] = :per_attribute_iv_and_salt
|
12
18
|
|
13
|
-
attr_encrypted :email, :key =>
|
14
|
-
attr_encrypted :credentials, :key =>
|
19
|
+
attr_encrypted :email, :key => SECRET_KEY
|
20
|
+
attr_encrypted :credentials, :key => SECRET_KEY, :marshal => true
|
15
21
|
|
16
22
|
def initialize(attrs = {})
|
17
23
|
super attrs
|
18
|
-
self.salt ||= Digest::SHA1.hexdigest((Time.now.to_i * rand(5)).to_s)
|
19
24
|
self.credentials ||= { :username => 'example', :password => 'test' }
|
20
25
|
end
|
21
26
|
end
|
@@ -49,4 +54,4 @@ class DataMapperTest < Test::Unit::TestCase
|
|
49
54
|
assert Client.attr_encrypted_options[:encode]
|
50
55
|
end
|
51
56
|
|
52
|
-
end
|
57
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../test_helper', __FILE__)
|
3
|
+
|
4
|
+
ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => ':memory:'
|
5
|
+
|
6
|
+
def create_people_table
|
7
|
+
silence_stream(STDOUT) do
|
8
|
+
ActiveRecord::Schema.define(:version => 1) do
|
9
|
+
create_table :legacy_people do |t|
|
10
|
+
t.string :encrypted_email
|
11
|
+
t.string :password
|
12
|
+
t.string :encrypted_credentials
|
13
|
+
t.string :salt
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# The table needs to exist before defining the class
|
20
|
+
create_people_table
|
21
|
+
|
22
|
+
ActiveRecord::MissingAttributeError = ActiveModel::MissingAttributeError unless defined?(ActiveRecord::MissingAttributeError)
|
23
|
+
|
24
|
+
class LegacyPerson < ActiveRecord::Base
|
25
|
+
attr_encrypted :email, :key => 'a secret key'
|
26
|
+
attr_encrypted :credentials, :key => Proc.new { |user| Encryptor.encrypt(:value => user.salt, :key => 'some private key') }, :marshal => true
|
27
|
+
|
28
|
+
ActiveSupport::Deprecation.silenced = true
|
29
|
+
def after_initialize; end
|
30
|
+
ActiveSupport::Deprecation.silenced = false
|
31
|
+
|
32
|
+
after_initialize :initialize_salt_and_credentials
|
33
|
+
|
34
|
+
protected
|
35
|
+
|
36
|
+
def initialize_salt_and_credentials
|
37
|
+
self.salt ||= Digest::SHA256.hexdigest((Time.now.to_i * rand(5)).to_s)
|
38
|
+
self.credentials ||= { :username => 'example', :password => 'test' }
|
39
|
+
rescue ActiveRecord::MissingAttributeError
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class LegacyPersonWithValidation < LegacyPerson
|
44
|
+
validates_presence_of :email
|
45
|
+
validates_uniqueness_of :encrypted_email
|
46
|
+
end
|
47
|
+
|
48
|
+
class LegacyActiveRecordTest < Test::Unit::TestCase
|
49
|
+
|
50
|
+
def setup
|
51
|
+
ActiveRecord::Base.connection.tables.each { |table| ActiveRecord::Base.connection.drop_table(table) }
|
52
|
+
create_people_table
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_should_decrypt_with_correct_encoding
|
56
|
+
if defined?(Encoding)
|
57
|
+
@person = LegacyPerson.create :email => 'test@example.com'
|
58
|
+
assert_equal 'UTF-8', LegacyPerson.find(:first).email.encoding.name
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_should_encrypt_email
|
63
|
+
@person = LegacyPerson.create :email => 'test@example.com'
|
64
|
+
assert_not_nil @person.encrypted_email
|
65
|
+
assert_not_equal @person.email, @person.encrypted_email
|
66
|
+
assert_equal @person.email, LegacyPerson.find(:first).email
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_should_marshal_and_encrypt_credentials
|
70
|
+
@person = LegacyPerson.create
|
71
|
+
assert_not_nil @person.encrypted_credentials
|
72
|
+
assert_not_equal @person.credentials, @person.encrypted_credentials
|
73
|
+
assert_equal @person.credentials, LegacyPerson.find(:first).credentials
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_should_find_by_email
|
77
|
+
@person = LegacyPerson.create(:email => 'test@example.com')
|
78
|
+
assert_equal @person, LegacyPerson.find_by_email('test@example.com')
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_should_find_by_email_and_password
|
82
|
+
LegacyPerson.create(:email => 'test@example.com', :password => 'invalid')
|
83
|
+
@person = LegacyPerson.create(:email => 'test@example.com', :password => 'test')
|
84
|
+
assert_equal @person, LegacyPerson.find_by_email_and_password('test@example.com', 'test')
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_should_scope_by_email
|
88
|
+
@person = LegacyPerson.create(:email => 'test@example.com')
|
89
|
+
assert_equal @person, LegacyPerson.scoped_by_email('test@example.com').find(:first) rescue NoMethodError
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_should_scope_by_email_and_password
|
93
|
+
LegacyPerson.create(:email => 'test@example.com', :password => 'invalid')
|
94
|
+
@person = LegacyPerson.create(:email => 'test@example.com', :password => 'test')
|
95
|
+
assert_equal @person, LegacyPerson.scoped_by_email_and_password('test@example.com', 'test').find(:first) rescue NoMethodError
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_should_encode_by_default
|
99
|
+
assert LegacyPerson.attr_encrypted_options[:encode]
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_should_validate_presence_of_email
|
103
|
+
@person = LegacyPersonWithValidation.new
|
104
|
+
assert !@person.valid?
|
105
|
+
assert !@person.errors[:email].empty? || @person.errors.on(:email)
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_should_validate_uniqueness_of_email
|
109
|
+
@person = LegacyPersonWithValidation.new :email => 'test@example.com'
|
110
|
+
assert @person.save
|
111
|
+
@person2 = LegacyPersonWithValidation.new :email => @person.email
|
112
|
+
assert !@person2.valid?
|
113
|
+
assert !@person2.errors[:encrypted_email].empty? || @person2.errors.on(:encrypted_email)
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
@@ -0,0 +1,297 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../test_helper', __FILE__)
|
3
|
+
|
4
|
+
class LegacySillyEncryptor
|
5
|
+
def self.silly_encrypt(options)
|
6
|
+
(options[:value] + options[:some_arg]).reverse
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.silly_decrypt(options)
|
10
|
+
options[:value].reverse.gsub(/#{options[:some_arg]}$/, '')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class LegacyUser
|
15
|
+
self.attr_encrypted_options[:key] = Proc.new { |user| user.class.to_s } # default key
|
16
|
+
|
17
|
+
attr_encrypted :email, :without_encoding, :key => 'secret key'
|
18
|
+
attr_encrypted :password, :prefix => 'crypted_', :suffix => '_test'
|
19
|
+
attr_encrypted :ssn, :key => :salt, :attribute => 'ssn_encrypted'
|
20
|
+
attr_encrypted :credit_card, :encryptor => LegacySillyEncryptor, :encrypt_method => :silly_encrypt, :decrypt_method => :silly_decrypt, :some_arg => 'test'
|
21
|
+
attr_encrypted :with_encoding, :key => 'secret key', :encode => true
|
22
|
+
attr_encrypted :with_custom_encoding, :key => 'secret key', :encode => 'm'
|
23
|
+
attr_encrypted :with_marshaling, :key => 'secret key', :marshal => true
|
24
|
+
attr_encrypted :with_true_if, :key => 'secret key', :if => true
|
25
|
+
attr_encrypted :with_false_if, :key => 'secret key', :if => false
|
26
|
+
attr_encrypted :with_true_unless, :key => 'secret key', :unless => true
|
27
|
+
attr_encrypted :with_false_unless, :key => 'secret key', :unless => false
|
28
|
+
attr_encrypted :with_if_changed, :key => 'secret key', :if => :should_encrypt
|
29
|
+
|
30
|
+
attr_encryptor :aliased, :key => 'secret_key'
|
31
|
+
|
32
|
+
attr_accessor :salt
|
33
|
+
attr_accessor :should_encrypt
|
34
|
+
|
35
|
+
def initialize
|
36
|
+
self.salt = Time.now.to_i.to_s
|
37
|
+
self.should_encrypt = true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class LegacyAdmin < LegacyUser
|
42
|
+
attr_encrypted :testing
|
43
|
+
end
|
44
|
+
|
45
|
+
class LegacySomeOtherClass
|
46
|
+
def self.call(object)
|
47
|
+
object.class
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class LegacyAttrEncryptedTest < Test::Unit::TestCase
|
52
|
+
|
53
|
+
def test_should_store_email_in_encrypted_attributes
|
54
|
+
assert LegacyUser.encrypted_attributes.include?(:email)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_should_not_store_salt_in_encrypted_attributes
|
58
|
+
assert !LegacyUser.encrypted_attributes.include?(:salt)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_attr_encrypted_should_return_true_for_email
|
62
|
+
assert LegacyUser.attr_encrypted?('email')
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_attr_encrypted_should_not_use_the_same_attribute_name_for_two_attributes_in_the_same_line
|
66
|
+
assert_not_equal LegacyUser.encrypted_attributes[:email][:attribute], LegacyUser.encrypted_attributes[:without_encoding][:attribute]
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_attr_encrypted_should_return_false_for_salt
|
70
|
+
assert !LegacyUser.attr_encrypted?('salt')
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_should_generate_an_encrypted_attribute
|
74
|
+
assert LegacyUser.new.respond_to?(:encrypted_email)
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_should_generate_an_encrypted_attribute_with_a_prefix_and_suffix
|
78
|
+
assert LegacyUser.new.respond_to?(:crypted_password_test)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_should_generate_an_encrypted_attribute_with_the_attribute_option
|
82
|
+
assert LegacyUser.new.respond_to?(:ssn_encrypted)
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_should_not_encrypt_nil_value
|
86
|
+
assert_nil LegacyUser.encrypt_email(nil)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_should_not_encrypt_empty_string
|
90
|
+
assert_equal '', LegacyUser.encrypt_email('')
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_should_encrypt_email
|
94
|
+
assert_not_nil LegacyUser.encrypt_email('test@example.com')
|
95
|
+
assert_not_equal 'test@example.com', LegacyUser.encrypt_email('test@example.com')
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_should_encrypt_email_when_modifying_the_attr_writer
|
99
|
+
@user = LegacyUser.new
|
100
|
+
assert_nil @user.encrypted_email
|
101
|
+
@user.email = 'test@example.com'
|
102
|
+
assert_not_nil @user.encrypted_email
|
103
|
+
assert_equal LegacyUser.encrypt_email('test@example.com'), @user.encrypted_email
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_should_not_decrypt_nil_value
|
107
|
+
assert_nil LegacyUser.decrypt_email(nil)
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_should_not_decrypt_empty_string
|
111
|
+
assert_equal '', LegacyUser.decrypt_email('')
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_should_decrypt_email
|
115
|
+
encrypted_email = LegacyUser.encrypt_email('test@example.com')
|
116
|
+
assert_not_equal 'test@test.com', encrypted_email
|
117
|
+
assert_equal 'test@example.com', LegacyUser.decrypt_email(encrypted_email)
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_should_decrypt_email_when_reading
|
121
|
+
@user = LegacyUser.new
|
122
|
+
assert_nil @user.email
|
123
|
+
@user.encrypted_email = LegacyUser.encrypt_email('test@example.com')
|
124
|
+
assert_equal 'test@example.com', @user.email
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_should_encrypt_with_encoding
|
128
|
+
assert_equal LegacyUser.encrypt_with_encoding('test'), [LegacyUser.encrypt_without_encoding('test')].pack('m')
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_should_decrypt_with_encoding
|
132
|
+
encrypted = LegacyUser.encrypt_with_encoding('test')
|
133
|
+
assert_equal 'test', LegacyUser.decrypt_with_encoding(encrypted)
|
134
|
+
assert_equal LegacyUser.decrypt_with_encoding(encrypted), LegacyUser.decrypt_without_encoding(encrypted.unpack('m').first)
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_should_decrypt_utf8_with_encoding
|
138
|
+
encrypted = LegacyUser.encrypt_with_encoding("test\xC2\xA0utf-8\xC2\xA0text")
|
139
|
+
assert_equal "test\xC2\xA0utf-8\xC2\xA0text", LegacyUser.decrypt_with_encoding(encrypted)
|
140
|
+
assert_equal LegacyUser.decrypt_with_encoding(encrypted), LegacyUser.decrypt_without_encoding(encrypted.unpack('m').first)
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_should_encrypt_with_custom_encoding
|
144
|
+
assert_equal LegacyUser.encrypt_with_custom_encoding('test'), [LegacyUser.encrypt_without_encoding('test')].pack('m')
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_should_decrypt_with_custom_encoding
|
148
|
+
encrypted = LegacyUser.encrypt_with_custom_encoding('test')
|
149
|
+
assert_equal 'test', LegacyUser.decrypt_with_custom_encoding(encrypted)
|
150
|
+
assert_equal LegacyUser.decrypt_with_custom_encoding(encrypted), LegacyUser.decrypt_without_encoding(encrypted.unpack('m').first)
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_should_encrypt_with_marshaling
|
154
|
+
@user = LegacyUser.new
|
155
|
+
@user.with_marshaling = [1, 2, 3]
|
156
|
+
assert_not_nil @user.encrypted_with_marshaling
|
157
|
+
assert_equal LegacyUser.encrypt_with_marshaling([1, 2, 3]), @user.encrypted_with_marshaling
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_should_decrypt_with_marshaling
|
161
|
+
encrypted = LegacyUser.encrypt_with_marshaling([1, 2, 3])
|
162
|
+
@user = LegacyUser.new
|
163
|
+
assert_nil @user.with_marshaling
|
164
|
+
@user.encrypted_with_marshaling = encrypted
|
165
|
+
assert_equal [1, 2, 3], @user.with_marshaling
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_should_use_custom_encryptor_and_crypt_method_names_and_arguments
|
169
|
+
assert_equal LegacySillyEncryptor.silly_encrypt(:value => 'testing', :some_arg => 'test'), LegacyUser.encrypt_credit_card('testing')
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_should_evaluate_a_key_passed_as_a_symbol
|
173
|
+
@user = LegacyUser.new
|
174
|
+
assert_nil @user.ssn_encrypted
|
175
|
+
@user.ssn = 'testing'
|
176
|
+
assert_not_nil @user.ssn_encrypted
|
177
|
+
assert_equal Encryptor.encrypt(:value => 'testing', :key => @user.salt), @user.ssn_encrypted
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_should_evaluate_a_key_passed_as_a_proc
|
181
|
+
@user = LegacyUser.new
|
182
|
+
assert_nil @user.crypted_password_test
|
183
|
+
@user.password = 'testing'
|
184
|
+
assert_not_nil @user.crypted_password_test
|
185
|
+
assert_equal Encryptor.encrypt(:value => 'testing', :key => 'LegacyUser'), @user.crypted_password_test
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_should_use_options_found_in_the_attr_encrypted_options_attribute
|
189
|
+
@user = LegacyUser.new
|
190
|
+
assert_nil @user.crypted_password_test
|
191
|
+
@user.password = 'testing'
|
192
|
+
assert_not_nil @user.crypted_password_test
|
193
|
+
assert_equal Encryptor.encrypt(:value => 'testing', :key => 'LegacyUser'), @user.crypted_password_test
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_should_inherit_encrypted_attributes
|
197
|
+
assert_equal [LegacyUser.encrypted_attributes.keys, :testing].flatten.collect { |key| key.to_s }.sort, LegacyAdmin.encrypted_attributes.keys.collect { |key| key.to_s }.sort
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_should_inherit_attr_encrypted_options
|
201
|
+
assert !LegacyUser.attr_encrypted_options.empty?
|
202
|
+
assert_equal LegacyUser.attr_encrypted_options, LegacyAdmin.attr_encrypted_options
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_should_not_inherit_unrelated_attributes
|
206
|
+
assert LegacySomeOtherClass.attr_encrypted_options.empty?
|
207
|
+
assert LegacySomeOtherClass.encrypted_attributes.empty?
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_should_evaluate_a_symbol_option
|
211
|
+
assert_equal Object, Object.new.send(:evaluate_attr_encrypted_option, :class)
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_should_evaluate_a_proc_option
|
215
|
+
assert_equal Object, Object.new.send(:evaluate_attr_encrypted_option, proc { |object| object.class })
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_should_evaluate_a_lambda_option
|
219
|
+
assert_equal Object, Object.new.send(:evaluate_attr_encrypted_option, lambda { |object| object.class })
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_should_evaluate_a_method_option
|
223
|
+
assert_equal Object, Object.new.send(:evaluate_attr_encrypted_option, LegacySomeOtherClass.method(:call))
|
224
|
+
end
|
225
|
+
|
226
|
+
def test_should_return_a_string_option
|
227
|
+
assert_equal 'Object', Object.new.send(:evaluate_attr_encrypted_option, 'Object')
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_should_encrypt_with_true_if
|
231
|
+
@user = LegacyUser.new
|
232
|
+
assert_nil @user.encrypted_with_true_if
|
233
|
+
@user.with_true_if = 'testing'
|
234
|
+
assert_not_nil @user.encrypted_with_true_if
|
235
|
+
assert_equal Encryptor.encrypt(:value => 'testing', :key => 'secret key'), @user.encrypted_with_true_if
|
236
|
+
end
|
237
|
+
|
238
|
+
def test_should_not_encrypt_with_false_if
|
239
|
+
@user = LegacyUser.new
|
240
|
+
assert_nil @user.encrypted_with_false_if
|
241
|
+
@user.with_false_if = 'testing'
|
242
|
+
assert_not_nil @user.encrypted_with_false_if
|
243
|
+
assert_equal 'testing', @user.encrypted_with_false_if
|
244
|
+
end
|
245
|
+
|
246
|
+
def test_should_encrypt_with_false_unless
|
247
|
+
@user = LegacyUser.new
|
248
|
+
assert_nil @user.encrypted_with_false_unless
|
249
|
+
@user.with_false_unless = 'testing'
|
250
|
+
assert_not_nil @user.encrypted_with_false_unless
|
251
|
+
assert_equal Encryptor.encrypt(:value => 'testing', :key => 'secret key'), @user.encrypted_with_false_unless
|
252
|
+
end
|
253
|
+
|
254
|
+
def test_should_not_encrypt_with_true_unless
|
255
|
+
@user = LegacyUser.new
|
256
|
+
assert_nil @user.encrypted_with_true_unless
|
257
|
+
@user.with_true_unless = 'testing'
|
258
|
+
assert_not_nil @user.encrypted_with_true_unless
|
259
|
+
assert_equal 'testing', @user.encrypted_with_true_unless
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_should_work_with_aliased_attr_encryptor
|
263
|
+
assert LegacyUser.encrypted_attributes.include?(:aliased)
|
264
|
+
end
|
265
|
+
|
266
|
+
def test_should_always_reset_options
|
267
|
+
@user = LegacyUser.new
|
268
|
+
@user.with_if_changed = "encrypt_stuff"
|
269
|
+
@user.stubs(:instance_variable_get).returns(nil)
|
270
|
+
@user.stubs(:instance_variable_set).raises("BadStuff")
|
271
|
+
assert_raise RuntimeError do
|
272
|
+
@user.with_if_changed
|
273
|
+
end
|
274
|
+
|
275
|
+
@user = LegacyUser.new
|
276
|
+
@user.should_encrypt = false
|
277
|
+
@user.with_if_changed = "not_encrypted_stuff"
|
278
|
+
assert_equal "not_encrypted_stuff", @user.with_if_changed
|
279
|
+
assert_equal "not_encrypted_stuff", @user.encrypted_with_if_changed
|
280
|
+
end
|
281
|
+
|
282
|
+
def test_should_cast_values_as_strings_before_encrypting
|
283
|
+
string_encrypted_email = LegacyUser.encrypt_email('3')
|
284
|
+
assert_equal string_encrypted_email, LegacyUser.encrypt_email(3)
|
285
|
+
assert_equal '3', LegacyUser.decrypt_email(string_encrypted_email)
|
286
|
+
end
|
287
|
+
|
288
|
+
def test_should_create_query_accessor
|
289
|
+
@user = LegacyUser.new
|
290
|
+
assert !@user.email?
|
291
|
+
@user.email = ''
|
292
|
+
assert !@user.email?
|
293
|
+
@user.email = 'test@example.com'
|
294
|
+
assert @user.email?
|
295
|
+
end
|
296
|
+
|
297
|
+
end
|