encrypted_attributes 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,9 @@
1
1
  == master
2
2
 
3
+ == 0.2.0 / 2008-12-4
4
+
5
+ * Update to be compatible with encrypted_strings 0.2.1
6
+
3
7
  == 0.1.3 / 2008-10-26
4
8
 
5
9
  * Change how the base module is included to prevent namespacing conflicts
data/README.rdoc CHANGED
@@ -29,7 +29,7 @@ with the encrypted_strings plugin, helps make encrypting ActiveRecord
29
29
  attributes easier by automating the process.
30
30
 
31
31
  The options that +encrypts+ takes includes all of the encryption options for
32
- the specific type of encryptor being used from the encrypted_strings plugin.
32
+ the specific type of cipher being used from the encrypted_strings library.
33
33
  Therefore, if setting the key for asymmetric encryption, this would be passed
34
34
  into the +encrypts+ method. Examples of this are show in the Usage section.
35
35
 
@@ -61,24 +61,12 @@ salt value.
61
61
 
62
62
  === Symmetric Encryption
63
63
 
64
- With the default key:
65
64
  class User < ActiveRecord::Base
66
- encrypts :password, :mode => :symmetric
67
- end
68
-
69
- With a custom key:
70
- class User < ActiveRecord::Base
71
- encrypts :password, :mode => :symmetric, :key => 'custom'
65
+ encrypts :password, :mode => :symmetric, :password => 'secret'
72
66
  end
73
67
 
74
68
  === Asymmetric Encryption
75
69
 
76
- With default key files:
77
- class User < ActiveRecord::Base
78
- encrypts :password, :mode => :asymmetric
79
- end
80
-
81
- With custom key files:
82
70
  class User < ActiveRecord::Base
83
71
  encrypts :password, :mode => :asymmetric, :public_key_file => '/keys/public', :private_key_file => '/keys/private'
84
72
  end
@@ -98,7 +86,7 @@ Like ActiveRecord validations, +encrypts+ can take <tt>:if</tt> and <tt>:unless<
98
86
  parameters that determine whether the encryption should occur. For example,
99
87
 
100
88
  class User < ActiveRecord::Base
101
- encrypts :password, :if => Proc.new {Rails.env != 'development'}
89
+ encrypts :password, :if => lambda {Rails.env != 'development'}
102
90
  end
103
91
 
104
92
  === Additional information
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ require 'rake/contrib/sshpublisher'
5
5
 
6
6
  spec = Gem::Specification.new do |s|
7
7
  s.name = 'encrypted_attributes'
8
- s.version = '0.1.3'
8
+ s.version = '0.2.0'
9
9
  s.platform = Gem::Platform::RUBY
10
10
  s.summary = 'Adds support for automatically encrypting ActiveRecord attributes'
11
11
 
@@ -13,7 +13,7 @@ spec = Gem::Specification.new do |s|
13
13
  s.require_path = 'lib'
14
14
  s.has_rdoc = true
15
15
  s.test_files = Dir['test/**/*_test.rb']
16
- s.add_dependency 'encrypted_strings', '>= 0.0.5'
16
+ s.add_dependency 'encrypted_strings', '>= 0.2.1'
17
17
 
18
18
  s.author = 'Aaron Pfeifer'
19
19
  s.email = 'aaron@pluginaweek.org'
@@ -1,10 +1,10 @@
1
1
  module PluginAWeek #:nodoc:
2
2
  module EncryptedAttributes
3
3
  # Adds support for dynamically generated salts
4
- class ShaEncryptor < PluginAWeek::EncryptedStrings::ShaEncryptor
4
+ class ShaCipher < PluginAWeek::EncryptedStrings::ShaCipher
5
5
  # Encrypts a string using a Secure Hash Algorithm (SHA), specifically SHA-1.
6
6
  #
7
- # The <tt>:start</tt> configuration option can be any one of the following types:
7
+ # The <tt>:salt</tt> configuration option can be any one of the following types:
8
8
  # * +symbol+ - Calls the method on the object whose value is being encrypted
9
9
  # * +proc+ - A block that will be invoked, providing it with the object whose value is being encrypted
10
10
  # * +string+ - The actual salt value to use
@@ -41,7 +41,7 @@ module PluginAWeek #:nodoc:
41
41
  # Encrypts the data, appending the salt to the end of the string if it
42
42
  # was created dynamically
43
43
  def encrypt(data)
44
- encrypted_data = Digest::SHA1.hexdigest(data + salt)
44
+ encrypted_data = super
45
45
  encrypted_data << salt if @dynamic_salt
46
46
  encrypted_data
47
47
  end
@@ -1,5 +1,5 @@
1
1
  require 'encrypted_strings'
2
- require 'encrypted_attributes/sha_encryptor'
2
+ require 'encrypted_attributes/sha_cipher'
3
3
 
4
4
  module PluginAWeek #:nodoc:
5
5
  module EncryptedAttributes
@@ -7,13 +7,13 @@ module PluginAWeek #:nodoc:
7
7
  # Encrypts the specified attribute.
8
8
  #
9
9
  # Configuration options:
10
- # * +mode+ - The mode of encryption to use. Default is sha. See PluginAWeek::EncryptedStrings for other possible modes
10
+ # * +mode+ - The mode of encryption to use. Default is sha. See PluginAWeek::EncryptedStrings for other possible modes.
11
11
  # * +to+ - The attribute to write the encrypted value to. Default is the same attribute being encrypted.
12
12
  # * +if+ - Specifies a method, proc or string to call to determine if the encryption should occur. The method, proc or string should return or evaluate to a true or false value.
13
13
  # * +unless+ - Specifies a method, proc or string to call to determine if the encryption should not occur. The method, proc or string should return or evaluate to a true or false value.
14
14
  #
15
15
  # For additional configuration options used during the actual encryption,
16
- # see the individual encryptor class for the specified mode.
16
+ # see the individual cipher class for the specified mode.
17
17
  #
18
18
  # == Encryption timeline
19
19
  #
@@ -48,18 +48,21 @@ module PluginAWeek #:nodoc:
48
48
  # == Encryption mode examples
49
49
  #
50
50
  # SHA encryption:
51
+ #
51
52
  # class User < ActiveRecord::Base
52
53
  # encrypts :password
53
54
  # # encrypts :password, :salt => :create_salt
54
55
  # end
55
56
  #
56
57
  # Symmetric encryption:
58
+ #
57
59
  # class User < ActiveRecord::Base
58
60
  # encrypts :password, :mode => :symmetric
59
61
  # # encrypts :password, :mode => :symmetric, :key => 'custom'
60
62
  # end
61
63
  #
62
64
  # Asymmetric encryption:
65
+ #
63
66
  # class User < ActiveRecord::Base
64
67
  # encrypts :password, :mode => :asymmetric
65
68
  # # encrypts :password, :mode => :asymmetric, :public_key_file => '/keys/public', :private_key_file => '/keys/private'
@@ -68,24 +71,24 @@ module PluginAWeek #:nodoc:
68
71
  attr_name = attr_name.to_s
69
72
  to_attr_name = options.delete(:to) || attr_name
70
73
 
71
- # Figure out what encryptor is being configured for the attribute
74
+ # Figure out what cipher is being configured for the attribute
72
75
  mode = options.delete(:mode) || :sha
73
- class_name = "#{mode.to_s.classify}Encryptor"
76
+ class_name = "#{mode.to_s.classify}Cipher"
74
77
  if PluginAWeek::EncryptedAttributes.const_defined?(class_name)
75
- encryptor_class = PluginAWeek::EncryptedAttributes.const_get(class_name)
78
+ cipher_class = PluginAWeek::EncryptedAttributes.const_get(class_name)
76
79
  else
77
- encryptor_class = PluginAWeek::EncryptedStrings.const_get(class_name)
80
+ cipher_class = PluginAWeek::EncryptedStrings.const_get(class_name)
78
81
  end
79
82
 
80
83
  # Set the encrypted value right before validation takes place
81
84
  before_validation(:if => options.delete(:if), :unless => options.delete(:unless)) do |record|
82
- record.send(:write_encrypted_attribute, attr_name, to_attr_name, encryptor_class, options)
85
+ record.send(:write_encrypted_attribute, attr_name, to_attr_name, cipher_class, options)
83
86
  true
84
87
  end
85
88
 
86
89
  # Define the reader when reading the encrypted attribute from the database
87
90
  define_method(to_attr_name) do
88
- read_encrypted_attribute(to_attr_name, encryptor_class, options)
91
+ read_encrypted_attribute(to_attr_name, cipher_class, options)
89
92
  end
90
93
 
91
94
  unless included_modules.include?(PluginAWeek::EncryptedAttributes::InstanceMethods)
@@ -98,18 +101,18 @@ module PluginAWeek #:nodoc:
98
101
  private
99
102
  # Encrypts the given attribute to a target location using the encryption
100
103
  # options configured for that attribute
101
- def write_encrypted_attribute(attr_name, to_attr_name, encryptor_class, options)
104
+ def write_encrypted_attribute(attr_name, to_attr_name, cipher_class, options)
102
105
  value = send(attr_name)
103
106
 
104
107
  # Only encrypt values that actually have content and have not already
105
108
  # been encrypted
106
109
  unless value.blank? || value.encrypted?
107
- # Create the encryptor configured for this attribute
108
- encryptor = create_encryptor(encryptor_class, options, :write, value)
110
+ # Create the cipher configured for this attribute
111
+ cipher = create_cipher(cipher_class, options, :write, value)
109
112
 
110
113
  # Encrypt the value
111
- value = encryptor.encrypt(value)
112
- value.encryptor = encryptor
114
+ value = cipher.encrypt(value)
115
+ value.cipher = cipher
113
116
 
114
117
  # Update the value based on the target attribute
115
118
  send("#{to_attr_name}=", value)
@@ -119,28 +122,28 @@ module PluginAWeek #:nodoc:
119
122
  # Reads the given attribute from the database, adding contextual
120
123
  # information about how it was encrypted so that equality comparisons
121
124
  # can be used
122
- def read_encrypted_attribute(to_attr_name, encryptor_class, options)
125
+ def read_encrypted_attribute(to_attr_name, cipher_class, options)
123
126
  value = read_attribute(to_attr_name)
124
127
 
125
- # Make sure we set the encryptor for equality comparison when reading
128
+ # Make sure we set the cipher for equality comparison when reading
126
129
  # from the database. This should only be done if the value is *not*
127
130
  # blank, is *not* encrypted, and hasn't changed since it was read from
128
131
  # the database. The dirty checking is important when the encypted value
129
132
  # is written to the same attribute as the unencrypted value (i.e. you
130
133
  # don't want to encrypt when a new value has been set)
131
134
  unless value.blank? || value.encrypted? || attribute_changed?(to_attr_name)
132
- # Create the encryptor configured for this attribute
133
- value.encryptor = create_encryptor(encryptor_class, options, :read, value)
135
+ # Create the cipher configured for this attribute
136
+ value.cipher = create_cipher(cipher_class, options, :read, value)
134
137
  end
135
138
 
136
139
  value
137
140
  end
138
141
 
139
- # Creates a new encryptor with the given configuration options. The
140
- # operator defines the context in which the encryptor will be used.
141
- def create_encryptor(klass, options, operator, value)
142
+ # Creates a new cipher with the given configuration options. The
143
+ # operator defines the context in which the cipher will be used.
144
+ def create_cipher(klass, options, operator, value)
142
145
  if klass.parent == PluginAWeek::EncryptedAttributes
143
- # Only use the contextual information for encryptors defined in this plugin
146
+ # Only use the contextual information for ciphers defined in this plugin
144
147
  klass.new(self, value, operator, options.dup)
145
148
  else
146
149
  klass.new(options.dup)
@@ -159,12 +159,12 @@ class ShaEncryptionTest < Test::Unit::TestCase
159
159
  assert @user.password.encrypted?
160
160
  end
161
161
 
162
- def test_should_use_sha_encryptor
163
- assert_instance_of PluginAWeek::EncryptedAttributes::ShaEncryptor, @user.password.encryptor
162
+ def test_should_use_sha_cipher
163
+ assert_instance_of PluginAWeek::EncryptedAttributes::ShaCipher, @user.password.cipher
164
164
  end
165
165
 
166
166
  def test_should_use_default_salt
167
- assert_equal 'salt', @user.password.encryptor.salt
167
+ assert_equal 'salt', @user.password.cipher.salt
168
168
  end
169
169
 
170
170
  def test_should_be_able_to_check_password
@@ -192,12 +192,12 @@ class ShaWithCustomSaltEncryptionTest < Test::Unit::TestCase
192
192
  assert @user.password.encrypted?
193
193
  end
194
194
 
195
- def test_should_use_sha_encryptor
196
- assert_instance_of PluginAWeek::EncryptedAttributes::ShaEncryptor, @user.password.encryptor
195
+ def test_should_use_sha_cipher
196
+ assert_instance_of PluginAWeek::EncryptedAttributes::ShaCipher, @user.password.cipher
197
197
  end
198
198
 
199
199
  def test_should_use_custom_salt
200
- assert_equal 'admin', @user.password.encryptor.salt
200
+ assert_equal 'admin', @user.password.cipher.salt
201
201
  end
202
202
 
203
203
  def test_should_be_able_to_check_password
@@ -213,24 +213,24 @@ end
213
213
 
214
214
  class SymmetricEncryptionTest < Test::Unit::TestCase
215
215
  def setup
216
- User.encrypts :password, :mode => :symmetric, :key => 'key'
216
+ User.encrypts :password, :mode => :symmetric, :password => 'key'
217
217
  @user = create_user(:login => 'admin', :password => 'secret')
218
218
  end
219
219
 
220
220
  def test_should_encrypt_password
221
- assert_equal "+YVKcPbqSWo=\n", @user.password
221
+ assert_equal "zfKtnSa33tc=\n", @user.password
222
222
  end
223
223
 
224
224
  def test_should_be_encrypted
225
225
  assert @user.password.encrypted?
226
226
  end
227
227
 
228
- def test_should_use_sha_encryptor
229
- assert_instance_of PluginAWeek::EncryptedStrings::SymmetricEncryptor, @user.password.encryptor
228
+ def test_should_use_sha_cipher
229
+ assert_instance_of PluginAWeek::EncryptedStrings::SymmetricCipher, @user.password.cipher
230
230
  end
231
231
 
232
- def test_should_use_custom_key
233
- assert_equal 'key', @user.password.encryptor.key
232
+ def test_should_use_custom_password
233
+ assert_equal 'key', @user.password.cipher.password
234
234
  end
235
235
 
236
236
  def test_should_be_able_to_check_password
@@ -261,8 +261,8 @@ class AsymmetricEncryptionTest < Test::Unit::TestCase
261
261
  assert @user.password.encrypted?
262
262
  end
263
263
 
264
- def test_should_use_sha_encryptor
265
- assert_instance_of PluginAWeek::EncryptedStrings::AsymmetricEncryptor, @user.password.encryptor
264
+ def test_should_use_sha_cipher
265
+ assert_instance_of PluginAWeek::EncryptedStrings::AsymmetricCipher, @user.password.cipher
266
266
  end
267
267
 
268
268
  def test_should_be_able_to_check_password
@@ -0,0 +1,56 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class ShaCipherOnWriteTest < Test::Unit::TestCase
4
+ def setup
5
+ @user = create_user(:login => 'admin')
6
+ end
7
+
8
+ def test_should_allow_symbolic_salt
9
+ cipher = PluginAWeek::EncryptedAttributes::ShaCipher.new(@user, 'password', :write, :salt => :login)
10
+ assert_equal 'admin', cipher.salt
11
+ end
12
+
13
+ def test_should_allow_stringified_salt
14
+ cipher = PluginAWeek::EncryptedAttributes::ShaCipher.new(@user, 'password', :write, :salt => 'custom_salt')
15
+ assert_equal 'custom_salt', cipher.salt
16
+ end
17
+
18
+ def test_should_allow_block_salt
19
+ dynamic_salt = lambda {|user| user.login}
20
+ cipher = PluginAWeek::EncryptedAttributes::ShaCipher.new(@user, 'password', :write, :salt => dynamic_salt)
21
+ assert_equal 'admin', cipher.salt
22
+ end
23
+
24
+ def test_should_allow_dynamic_nil_salt
25
+ dynamic_salt = lambda {|user| nil}
26
+ cipher = PluginAWeek::EncryptedAttributes::ShaCipher.new(@user, 'password', :write, :salt => dynamic_salt)
27
+ assert_equal '', cipher.salt
28
+ end
29
+
30
+ def test_should_append_salt_to_encrypted_value_if_dynamic
31
+ cipher = PluginAWeek::EncryptedAttributes::ShaCipher.new(@user, 'password', :write, :salt => :login)
32
+ assert_equal 'a55d037f385cad22efe7862e07b805938d150154admin', cipher.encrypt('secret')
33
+ end
34
+
35
+ def test_should_not_append_salt_to_encrypted_value_if_static
36
+ cipher = PluginAWeek::EncryptedAttributes::ShaCipher.new(@user, 'password', :write, :salt => 'custom_salt')
37
+ assert_equal 'dc0fc7c07bba982a8d8f18fe138dbea912df5e0e', cipher.encrypt('secret')
38
+ end
39
+ end
40
+
41
+ class ShaCipherOnReadTest < Test::Unit::TestCase
42
+ def setup
43
+ @user = create_user(:login => 'admin')
44
+ @cipher = PluginAWeek::EncryptedAttributes::ShaCipher.new(@user, 'dc0fc7c07bba982a8d8f18fe138dbea912df5e0ecustom_salt', :read)
45
+ end
46
+
47
+ def test_should_should_use_remaining_characters_after_password_for_salt
48
+ assert_equal 'custom_salt', @cipher.salt
49
+ end
50
+
51
+ def test_should_be_able_to_perform_equality_on_encrypted_strings
52
+ password = 'dc0fc7c07bba982a8d8f18fe138dbea912df5e0ecustom_salt'
53
+ password.cipher = @cipher
54
+ assert_equal 'secret', password
55
+ end
56
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: encrypted_attributes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Pfeifer
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-10-26 00:00:00 -04:00
12
+ date: 2008-12-04 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 0.0.5
23
+ version: 0.2.1
24
24
  version:
25
25
  description:
26
26
  email: aaron@pluginaweek.org
@@ -31,26 +31,26 @@ extensions: []
31
31
  extra_rdoc_files: []
32
32
 
33
33
  files:
34
- - lib/encrypted_attributes
35
- - lib/encrypted_attributes/sha_encryptor.rb
36
34
  - lib/encrypted_attributes.rb
35
+ - lib/encrypted_attributes
36
+ - lib/encrypted_attributes/sha_cipher.rb
37
+ - test/factory.rb
38
+ - test/test_helper.rb
39
+ - test/unit
40
+ - test/unit/sha_cipher_test.rb
41
+ - test/unit/encrypted_attributes_test.rb
42
+ - test/keys
43
+ - test/keys/private
44
+ - test/keys/public
37
45
  - test/app_root
38
- - test/app_root/app
39
- - test/app_root/app/models
40
- - test/app_root/app/models/user.rb
41
- - test/app_root/config
42
- - test/app_root/config/environment.rb
43
46
  - test/app_root/db
44
47
  - test/app_root/db/migrate
45
48
  - test/app_root/db/migrate/001_create_users.rb
46
- - test/keys
47
- - test/keys/private
48
- - test/keys/public
49
- - test/test_helper.rb
50
- - test/factory.rb
51
- - test/unit
52
- - test/unit/sha_encryptor_test.rb
53
- - test/unit/encrypted_attributes_test.rb
49
+ - test/app_root/config
50
+ - test/app_root/config/environment.rb
51
+ - test/app_root/app
52
+ - test/app_root/app/models
53
+ - test/app_root/app/models/user.rb
54
54
  - CHANGELOG.rdoc
55
55
  - init.rb
56
56
  - LICENSE
@@ -83,5 +83,5 @@ signing_key:
83
83
  specification_version: 2
84
84
  summary: Adds support for automatically encrypting ActiveRecord attributes
85
85
  test_files:
86
- - test/unit/sha_encryptor_test.rb
86
+ - test/unit/sha_cipher_test.rb
87
87
  - test/unit/encrypted_attributes_test.rb
@@ -1,56 +0,0 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
-
3
- class ShaEncryptorOnWriteTest < Test::Unit::TestCase
4
- def setup
5
- @user = create_user(:login => 'admin')
6
- end
7
-
8
- def test_should_allow_symbolic_salt
9
- encryptor = PluginAWeek::EncryptedAttributes::ShaEncryptor.new(@user, 'password', :write, :salt => :login)
10
- assert_equal 'admin', encryptor.salt
11
- end
12
-
13
- def test_should_allow_stringified_salt
14
- encryptor = PluginAWeek::EncryptedAttributes::ShaEncryptor.new(@user, 'password', :write, :salt => 'custom_salt')
15
- assert_equal 'custom_salt', encryptor.salt
16
- end
17
-
18
- def test_should_allow_block_salt
19
- dynamic_salt = lambda {|user| user.login}
20
- encryptor = PluginAWeek::EncryptedAttributes::ShaEncryptor.new(@user, 'password', :write, :salt => dynamic_salt)
21
- assert_equal 'admin', encryptor.salt
22
- end
23
-
24
- def test_should_allow_dynamic_nil_salt
25
- dynamic_salt = lambda {|user| nil}
26
- encryptor = PluginAWeek::EncryptedAttributes::ShaEncryptor.new(@user, 'password', :write, :salt => dynamic_salt)
27
- assert_equal '', encryptor.salt
28
- end
29
-
30
- def test_should_append_salt_to_encrypted_value_if_dynamic
31
- encryptor = PluginAWeek::EncryptedAttributes::ShaEncryptor.new(@user, 'password', :write, :salt => :login)
32
- assert_equal 'a55d037f385cad22efe7862e07b805938d150154admin', encryptor.encrypt('secret')
33
- end
34
-
35
- def test_should_not_append_salt_to_encrypted_value_if_static
36
- encryptor = PluginAWeek::EncryptedAttributes::ShaEncryptor.new(@user, 'password', :write, :salt => 'custom_salt')
37
- assert_equal 'dc0fc7c07bba982a8d8f18fe138dbea912df5e0e', encryptor.encrypt('secret')
38
- end
39
- end
40
-
41
- class ShaEncryptorOnReadTest < Test::Unit::TestCase
42
- def setup
43
- @user = create_user(:login => 'admin')
44
- @encryptor = PluginAWeek::EncryptedAttributes::ShaEncryptor.new(@user, 'dc0fc7c07bba982a8d8f18fe138dbea912df5e0ecustom_salt', :read)
45
- end
46
-
47
- def test_should_should_use_remaining_characters_after_password_for_salt
48
- assert_equal 'custom_salt', @encryptor.salt
49
- end
50
-
51
- def test_should_be_able_to_perform_equality_on_encrypted_strings
52
- password = 'dc0fc7c07bba982a8d8f18fe138dbea912df5e0ecustom_salt'
53
- password.encryptor = @encryptor
54
- assert_equal 'secret', password
55
- end
56
- end