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