attr_encrypted 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/attr_encrypted.rb +17 -5
- data/lib/attr_encrypted/adapters/active_record.rb +1 -1
- data/lib/attr_encrypted/version.rb +2 -2
- data/test/active_record_test.rb +8 -0
- data/test/attr_encrypted_test.rb +31 -5
- data/test/test_helper.rb +1 -1
- metadata +84 -97
data/lib/attr_encrypted.rb
CHANGED
@@ -86,8 +86,10 @@ module AttrEncrypted
|
|
86
86
|
# end
|
87
87
|
#
|
88
88
|
# @user = User.new
|
89
|
-
# @user.encrypted_email #
|
89
|
+
# @user.encrypted_email # nil
|
90
|
+
# @user.email? # false
|
90
91
|
# @user.email = 'test@example.com'
|
92
|
+
# @user.email? # true
|
91
93
|
# @user.encrypted_email # returns the encrypted version of 'test@example.com'
|
92
94
|
#
|
93
95
|
# @user.configuration = { :time_zone => 'UTC' }
|
@@ -129,7 +131,12 @@ module AttrEncrypted
|
|
129
131
|
instance_variable_set("@#{attribute}", value)
|
130
132
|
end
|
131
133
|
|
132
|
-
|
134
|
+
define_method("#{attribute}?") do
|
135
|
+
value = send(attribute)
|
136
|
+
value.respond_to?(:empty?) ? !value.empty? : !!value
|
137
|
+
end
|
138
|
+
|
139
|
+
encrypted_attributes[attribute.to_sym] = options.merge(:attribute => encrypted_attribute_name)
|
133
140
|
end
|
134
141
|
end
|
135
142
|
alias_method :attr_encryptor, :attr_encrypted
|
@@ -170,7 +177,12 @@ module AttrEncrypted
|
|
170
177
|
if options[:if] && !options[:unless] && !encrypted_value.nil? && !(encrypted_value.is_a?(String) && encrypted_value.empty?)
|
171
178
|
encrypted_value = encrypted_value.unpack(options[:encode]).first if options[:encode]
|
172
179
|
value = options[:encryptor].send(options[:decrypt_method], options.merge!(:value => encrypted_value))
|
173
|
-
|
180
|
+
if options[:marshal]
|
181
|
+
value = options[:marshaler].send(options[:load_method], value)
|
182
|
+
elsif defined?(Encoding)
|
183
|
+
encoding = Encoding.default_internal || Encoding.default_external
|
184
|
+
value = value.force_encoding(encoding.name)
|
185
|
+
end
|
174
186
|
value
|
175
187
|
else
|
176
188
|
encrypted_value
|
@@ -189,7 +201,7 @@ module AttrEncrypted
|
|
189
201
|
def encrypt(attribute, value, options = {})
|
190
202
|
options = encrypted_attributes[attribute.to_sym].merge(options)
|
191
203
|
if options[:if] && !options[:unless] && !value.nil? && !(value.is_a?(String) && value.empty?)
|
192
|
-
value = options[:marshaler].send(options[:dump_method], value)
|
204
|
+
value = options[:marshal] ? options[:marshaler].send(options[:dump_method], value) : value.to_s
|
193
205
|
encrypted_value = options[:encryptor].send(options[:encrypt_method], options.merge!(:value => value))
|
194
206
|
encrypted_value = [encrypted_value].pack(options[:encode]) if options[:encode]
|
195
207
|
encrypted_value
|
@@ -293,4 +305,4 @@ end
|
|
293
305
|
|
294
306
|
Object.extend AttrEncrypted
|
295
307
|
|
296
|
-
Dir[File.join(File.dirname(__FILE__), 'attr_encrypted', 'adapters', '*.rb')].each { |adapter| require adapter }
|
308
|
+
Dir[File.join(File.dirname(__FILE__), 'attr_encrypted', 'adapters', '*.rb')].each { |adapter| require adapter }
|
@@ -3,7 +3,7 @@ module AttrEncrypted
|
|
3
3
|
module Version
|
4
4
|
MAJOR = 1
|
5
5
|
MINOR = 2
|
6
|
-
PATCH =
|
6
|
+
PATCH = 1
|
7
7
|
|
8
8
|
# Returns a version string by joining <tt>MAJOR</tt>, <tt>MINOR</tt>, and <tt>PATCH</tt> with <tt>'.'</tt>
|
9
9
|
#
|
@@ -14,4 +14,4 @@ module AttrEncrypted
|
|
14
14
|
[MAJOR, MINOR, PATCH].join('.')
|
15
15
|
end
|
16
16
|
end
|
17
|
-
end
|
17
|
+
end
|
data/test/active_record_test.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
1
2
|
require File.expand_path('../test_helper', __FILE__)
|
2
3
|
|
3
4
|
ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => ':memory:'
|
@@ -51,6 +52,13 @@ class ActiveRecordTest < Test::Unit::TestCase
|
|
51
52
|
create_people_table
|
52
53
|
end
|
53
54
|
|
55
|
+
def test_should_decrypt_with_correct_encoding
|
56
|
+
if defined?(Encoding)
|
57
|
+
@person = Person.create :email => 'test@example.com'
|
58
|
+
assert_equal 'UTF-8', Person.find(:first).email.encoding.name
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
54
62
|
def test_should_encrypt_email
|
55
63
|
@person = Person.create :email => 'test@example.com'
|
56
64
|
assert_not_nil @person.encrypted_email
|
data/test/attr_encrypted_test.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
1
2
|
require File.expand_path('../test_helper', __FILE__)
|
2
3
|
|
3
4
|
class SillyEncryptor
|
@@ -61,6 +62,10 @@ class AttrEncryptedTest < Test::Unit::TestCase
|
|
61
62
|
assert User.attr_encrypted?('email')
|
62
63
|
end
|
63
64
|
|
65
|
+
def test_attr_encrypted_should_not_use_the_same_attribute_name_for_two_attributes_in_the_same_line
|
66
|
+
assert_not_equal User.encrypted_attributes[:email][:attribute], User.encrypted_attributes[:without_encoding][:attribute]
|
67
|
+
end
|
68
|
+
|
64
69
|
def test_attr_encrypted_should_return_false_for_salt
|
65
70
|
assert !User.attr_encrypted?('salt')
|
66
71
|
end
|
@@ -129,14 +134,20 @@ class AttrEncryptedTest < Test::Unit::TestCase
|
|
129
134
|
assert_equal User.decrypt_with_encoding(encrypted), User.decrypt_without_encoding(encrypted.unpack('m').first)
|
130
135
|
end
|
131
136
|
|
137
|
+
def test_should_decrypt_utf8_with_encoding
|
138
|
+
encrypted = User.encrypt_with_encoding("test\xC2\xA0utf-8\xC2\xA0text")
|
139
|
+
assert_equal "test\xC2\xA0utf-8\xC2\xA0text", User.decrypt_with_encoding(encrypted)
|
140
|
+
assert_equal User.decrypt_with_encoding(encrypted), User.decrypt_without_encoding(encrypted.unpack('m').first)
|
141
|
+
end
|
142
|
+
|
132
143
|
def test_should_encrypt_with_custom_encoding
|
133
|
-
assert_equal User.
|
144
|
+
assert_equal User.encrypt_with_custom_encoding('test'), [User.encrypt_without_encoding('test')].pack('m')
|
134
145
|
end
|
135
146
|
|
136
147
|
def test_should_decrypt_with_custom_encoding
|
137
|
-
encrypted = User.
|
138
|
-
assert_equal 'test', User.
|
139
|
-
assert_equal User.
|
148
|
+
encrypted = User.encrypt_with_custom_encoding('test')
|
149
|
+
assert_equal 'test', User.decrypt_with_custom_encoding(encrypted)
|
150
|
+
assert_equal User.decrypt_with_custom_encoding(encrypted), User.decrypt_without_encoding(encrypted.unpack('m').first)
|
140
151
|
end
|
141
152
|
|
142
153
|
def test_should_encrypt_with_marshaling
|
@@ -268,4 +279,19 @@ class AttrEncryptedTest < Test::Unit::TestCase
|
|
268
279
|
assert_equal "not_encrypted_stuff", @user.encrypted_with_if_changed
|
269
280
|
end
|
270
281
|
|
271
|
-
|
282
|
+
def test_should_cast_values_as_strings_before_encrypting
|
283
|
+
string_encrypted_email = User.encrypt_email('3')
|
284
|
+
assert_equal string_encrypted_email, User.encrypt_email(3)
|
285
|
+
assert_equal '3', User.decrypt_email(string_encrypted_email)
|
286
|
+
end
|
287
|
+
|
288
|
+
def test_should_create_query_accessor
|
289
|
+
@user = User.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
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,106 +1,102 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: attr_encrypted
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.2.1
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 2
|
9
|
-
- 0
|
10
|
-
version: 1.2.0
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Sean Huber
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-09-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
22
15
|
name: encryptor
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
25
17
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 17
|
30
|
-
segments:
|
31
|
-
- 1
|
32
|
-
- 1
|
33
|
-
- 1
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
34
21
|
version: 1.1.1
|
35
22
|
type: :runtime
|
36
|
-
version_requirements: *id001
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
name: activerecord
|
39
23
|
prerelease: false
|
40
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.1.1
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: activerecord
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
41
33
|
none: false
|
42
|
-
requirements:
|
43
|
-
- -
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
hash: 15
|
46
|
-
segments:
|
47
|
-
- 2
|
48
|
-
- 0
|
49
|
-
- 0
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
50
37
|
version: 2.0.0
|
51
38
|
type: :development
|
52
|
-
version_requirements: *id002
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: datamapper
|
55
39
|
prerelease: false
|
56
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.0.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: datamapper
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
57
49
|
none: false
|
58
|
-
requirements:
|
59
|
-
- -
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
|
62
|
-
segments:
|
63
|
-
- 0
|
64
|
-
version: "0"
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
65
54
|
type: :development
|
66
|
-
version_requirements: *id003
|
67
|
-
- !ruby/object:Gem::Dependency
|
68
|
-
name: mocha
|
69
55
|
prerelease: false
|
70
|
-
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: mocha
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
71
65
|
none: false
|
72
|
-
requirements:
|
73
|
-
- -
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
|
76
|
-
segments:
|
77
|
-
- 0
|
78
|
-
version: "0"
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
79
70
|
type: :development
|
80
|
-
version_requirements: *id004
|
81
|
-
- !ruby/object:Gem::Dependency
|
82
|
-
name: sequel
|
83
71
|
prerelease: false
|
84
|
-
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
73
|
none: false
|
86
|
-
requirements:
|
87
|
-
- -
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: sequel
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
93
86
|
type: :development
|
94
|
-
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
95
94
|
description: Generates attr_accessors that encrypt and decrypt attributes transparently
|
96
95
|
email: shuber@huberry.com
|
97
96
|
executables: []
|
98
|
-
|
99
97
|
extensions: []
|
100
|
-
|
101
98
|
extra_rdoc_files: []
|
102
|
-
|
103
|
-
files:
|
99
|
+
files:
|
104
100
|
- lib/attr_encrypted/adapters/active_record.rb
|
105
101
|
- lib/attr_encrypted/adapters/data_mapper.rb
|
106
102
|
- lib/attr_encrypted/adapters/sequel.rb
|
@@ -114,44 +110,35 @@ files:
|
|
114
110
|
- test/data_mapper_test.rb
|
115
111
|
- test/sequel_test.rb
|
116
112
|
- test/test_helper.rb
|
117
|
-
has_rdoc: true
|
118
113
|
homepage: http://github.com/shuber/attr_encrypted
|
119
114
|
licenses: []
|
120
|
-
|
121
115
|
post_install_message:
|
122
|
-
rdoc_options:
|
116
|
+
rdoc_options:
|
123
117
|
- --line-numbers
|
124
118
|
- --inline-source
|
125
119
|
- --main
|
126
120
|
- README.rdoc
|
127
|
-
require_paths:
|
121
|
+
require_paths:
|
128
122
|
- lib
|
129
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
124
|
none: false
|
131
|
-
requirements:
|
132
|
-
- -
|
133
|
-
- !ruby/object:Gem::Version
|
134
|
-
|
135
|
-
|
136
|
-
- 0
|
137
|
-
version: "0"
|
138
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ! '>='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
130
|
none: false
|
140
|
-
requirements:
|
141
|
-
- -
|
142
|
-
- !ruby/object:Gem::Version
|
143
|
-
|
144
|
-
segments:
|
145
|
-
- 0
|
146
|
-
version: "0"
|
131
|
+
requirements:
|
132
|
+
- - ! '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
147
135
|
requirements: []
|
148
|
-
|
149
136
|
rubyforge_project:
|
150
|
-
rubygems_version: 1.
|
137
|
+
rubygems_version: 1.8.23
|
151
138
|
signing_key:
|
152
139
|
specification_version: 3
|
153
140
|
summary: Encrypt and decrypt attributes
|
154
|
-
test_files:
|
141
|
+
test_files:
|
155
142
|
- test/active_record_test.rb
|
156
143
|
- test/attr_encrypted_test.rb
|
157
144
|
- test/data_mapper_test.rb
|