encrypted_attributes 0.1.1 → 0.1.2
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/{CHANGELOG → CHANGELOG.rdoc} +9 -11
- data/{MIT-LICENSE → LICENSE} +0 -0
- data/{README → README.rdoc} +13 -14
- data/Rakefile +46 -38
- data/lib/encrypted_attributes/sha_encryptor.rb +16 -8
- data/lib/encrypted_attributes.rb +105 -29
- data/test/app_root/script/console +8 -0
- data/test/app_root/script/rails_framework_root.rb +1 -0
- data/test/factory.rb +27 -21
- metadata +11 -8
@@ -1,29 +1,27 @@
|
|
1
|
-
|
1
|
+
== master
|
2
2
|
|
3
|
-
|
3
|
+
== 0.1.2 / 2008-07-05
|
4
|
+
|
5
|
+
* Leave salt stringification up to PluginAWeek::EncryptedString::ShaEncryptor
|
6
|
+
|
7
|
+
== 0.1.1 / 2008-06-22
|
4
8
|
|
5
9
|
* Remove log files from gems
|
6
10
|
|
7
|
-
|
11
|
+
== 0.1.0 / 2008-05-05
|
8
12
|
|
9
13
|
* Don't extend encrypted_string's encryptors, instead creating subclasses
|
10
|
-
|
11
14
|
* Don't assume anything about attribute confirmations
|
12
|
-
|
13
15
|
* Support storing the salt for SHA encryption in the same string as the original value
|
14
|
-
|
15
16
|
* Update documentation
|
16
17
|
|
17
|
-
|
18
|
+
== 0.0.2 / 2007-09-26
|
18
19
|
|
19
20
|
* Move test fixtures out of the test application root directory
|
20
|
-
|
21
21
|
* Convert dos newlines to unix newlines
|
22
22
|
|
23
|
-
|
23
|
+
== 0.0.1 / 2007-08-05
|
24
24
|
|
25
25
|
* Official public release
|
26
|
-
|
27
26
|
* Add documentation
|
28
|
-
|
29
27
|
* Refactor unit test names
|
data/{MIT-LICENSE → LICENSE}
RENAMED
File without changes
|
data/{README → README.rdoc}
RENAMED
@@ -5,21 +5,21 @@ attributes.
|
|
5
5
|
|
6
6
|
== Resources
|
7
7
|
|
8
|
-
Wiki
|
9
|
-
|
10
|
-
* http://wiki.pluginaweek.org/Encrypted_attributes
|
11
|
-
|
12
8
|
API
|
13
9
|
|
14
10
|
* http://api.pluginaweek.org/encrypted_attributes
|
15
11
|
|
12
|
+
Bugs
|
13
|
+
|
14
|
+
* http://pluginaweek.lighthouseapp.com/projects/13269-encrypted_attributes
|
15
|
+
|
16
16
|
Development
|
17
17
|
|
18
|
-
* http://
|
18
|
+
* http://github.com/pluginaweek/encrypted_attributes
|
19
19
|
|
20
20
|
Source
|
21
21
|
|
22
|
-
*
|
22
|
+
* git://github.com/pluginaweek/encrypted_attributes.git
|
23
23
|
|
24
24
|
== Description
|
25
25
|
|
@@ -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
|
32
|
+
the specific type of encryptor being used from the encrypted_strings plugin.
|
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
|
|
@@ -45,7 +45,7 @@ With the default salt:
|
|
45
45
|
encrypts :password
|
46
46
|
end
|
47
47
|
|
48
|
-
With a custom salt:
|
48
|
+
With a custom salt based on the record's values:
|
49
49
|
class User < ActiveRecord::Base
|
50
50
|
encrypts :password, :salt => :create_salt
|
51
51
|
|
@@ -55,7 +55,7 @@ With a custom salt:
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
The salt and password values are combined and stored in the
|
58
|
+
The salt and password values are combined and stored in the attribute being
|
59
59
|
encrypted. Therefore, there's no need to add a second column for storing the
|
60
60
|
salt value.
|
61
61
|
|
@@ -83,7 +83,6 @@ With custom key files:
|
|
83
83
|
encrypts :password, :mode => :asymmetric, :public_key_file => '/keys/public', :private_key_file => '/keys/private'
|
84
84
|
end
|
85
85
|
|
86
|
-
|
87
86
|
=== Targeted Encryption
|
88
87
|
|
89
88
|
If you want to store the encrypted value in a different attribute than the
|
@@ -105,13 +104,13 @@ parameters that determine whether the encryption should occur. For example,
|
|
105
104
|
=== Additional information
|
106
105
|
|
107
106
|
For more examples of actual migrations and models that encrypt attributes,
|
108
|
-
see the unit tests. Also, see encrypted_strings for more
|
109
|
-
the various options that can be passed in.
|
107
|
+
see the actual API and unit tests. Also, see encrypted_strings for more
|
108
|
+
information about the various options that can be passed in.
|
110
109
|
|
111
110
|
== Testing
|
112
111
|
|
113
112
|
Before you can run any tests, the following gem must be installed:
|
114
|
-
* plugin_test_helper[http://
|
113
|
+
* plugin_test_helper[http://github.com/pluginaweek/plugin_test_helper]
|
115
114
|
|
116
115
|
To run against a specific version of Rails:
|
117
116
|
|
@@ -120,4 +119,4 @@ To run against a specific version of Rails:
|
|
120
119
|
== Dependencies
|
121
120
|
|
122
121
|
* Rails 2.1 or later
|
123
|
-
* encrypted_strings[http://
|
122
|
+
* encrypted_strings[http://github.com/pluginaweek/encrypted_strings]
|
data/Rakefile
CHANGED
@@ -3,47 +3,55 @@ require 'rake/rdoctask'
|
|
3
3
|
require 'rake/gempackagetask'
|
4
4
|
require 'rake/contrib/sshpublisher'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
spec = Gem::Specification.new do |s|
|
7
|
+
s.name = 'encrypted_attributes'
|
8
|
+
s.version = '0.1.2'
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.summary = 'Adds support for automatically encrypting ActiveRecord attributes'
|
11
|
+
|
12
|
+
s.files = FileList['{lib,test}/**/*'].to_a - FileList['test/app_root/log/*'].to_a + %w(CHANGELOG.rdoc init.rb LICENSE Rakefile README.rdoc)
|
13
|
+
s.require_path = 'lib'
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.test_files = Dir['test/**/*_test.rb']
|
16
|
+
s.add_dependency 'encrypted_strings', '>= 0.0.5'
|
17
|
+
|
18
|
+
s.author = 'Aaron Pfeifer'
|
19
|
+
s.email = 'aaron@pluginaweek.org'
|
20
|
+
s.homepage = 'http://www.pluginaweek.org'
|
21
|
+
s.rubyforge_project = 'pluginaweek'
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Default: run all tests.'
|
12
25
|
task :default => :test
|
13
26
|
|
14
|
-
desc
|
27
|
+
desc "Test the #{spec.name} plugin."
|
15
28
|
Rake::TestTask.new(:test) do |t|
|
16
29
|
t.libs << 'lib'
|
17
|
-
t.
|
30
|
+
t.test_files = spec.test_files
|
18
31
|
t.verbose = true
|
19
32
|
end
|
20
33
|
|
21
|
-
|
34
|
+
begin
|
35
|
+
require 'rcov/rcovtask'
|
36
|
+
namespace :test do
|
37
|
+
desc "Test the #{spec.name} plugin with Rcov."
|
38
|
+
Rcov::RcovTask.new(:rcov) do |t|
|
39
|
+
t.libs << 'lib'
|
40
|
+
t.test_files = spec.test_files
|
41
|
+
t.rcov_opts << '--exclude="^(?!lib/)"'
|
42
|
+
t.verbose = true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
rescue LoadError
|
46
|
+
end
|
47
|
+
|
48
|
+
desc "Generate documentation for the #{spec.name} plugin."
|
22
49
|
Rake::RDocTask.new(:rdoc) do |rdoc|
|
23
50
|
rdoc.rdoc_dir = 'rdoc'
|
24
|
-
rdoc.title =
|
51
|
+
rdoc.title = spec.name
|
25
52
|
rdoc.template = '../rdoc_template.rb'
|
26
|
-
rdoc.options << '--line-numbers'
|
27
|
-
rdoc.rdoc_files.include('README')
|
28
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
29
|
-
end
|
30
|
-
|
31
|
-
spec = Gem::Specification.new do |s|
|
32
|
-
s.name = PKG_NAME
|
33
|
-
s.version = PKG_VERSION
|
34
|
-
s.platform = Gem::Platform::RUBY
|
35
|
-
s.summary = 'Adds support for automatically encrypting ActiveRecord attributes'
|
36
|
-
|
37
|
-
s.files = FileList['{lib,test}/**/*'].to_a - FileList['test/app_root/log/*'].to_a + %w(CHANGELOG init.rb MIT-LICENSE Rakefile README)
|
38
|
-
s.require_path = 'lib'
|
39
|
-
s.autorequire = 'encrypted_attributes'
|
40
|
-
s.has_rdoc = true
|
41
|
-
s.test_files = Dir['test/**/*_test.rb']
|
42
|
-
s.add_dependency 'encrypted_strings', '>= 0.0.1'
|
43
|
-
|
44
|
-
s.author = 'Aaron Pfeifer'
|
45
|
-
s.email = 'aaron@pluginaweek.org'
|
46
|
-
s.homepage = 'http://www.pluginaweek.org'
|
53
|
+
rdoc.options << '--line-numbers'
|
54
|
+
rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG.rdoc', 'LICENSE', 'lib/**/*.rb')
|
47
55
|
end
|
48
56
|
|
49
57
|
Rake::GemPackageTask.new(spec) do |p|
|
@@ -52,14 +60,14 @@ Rake::GemPackageTask.new(spec) do |p|
|
|
52
60
|
p.need_zip = true
|
53
61
|
end
|
54
62
|
|
55
|
-
desc 'Publish the beta gem'
|
63
|
+
desc 'Publish the beta gem.'
|
56
64
|
task :pgem => [:package] do
|
57
|
-
Rake::SshFilePublisher.new('aaron@pluginaweek.org', '/home/aaron/gems.pluginaweek.org/public/gems', 'pkg', "#{
|
65
|
+
Rake::SshFilePublisher.new('aaron@pluginaweek.org', '/home/aaron/gems.pluginaweek.org/public/gems', 'pkg', "#{spec.name}-#{spec.version}.gem").upload
|
58
66
|
end
|
59
67
|
|
60
|
-
desc 'Publish the API documentation'
|
68
|
+
desc 'Publish the API documentation.'
|
61
69
|
task :pdoc => [:rdoc] do
|
62
|
-
Rake::SshDirPublisher.new('aaron@pluginaweek.org', "/home/aaron/api.pluginaweek.org/public/#{
|
70
|
+
Rake::SshDirPublisher.new('aaron@pluginaweek.org', "/home/aaron/api.pluginaweek.org/public/#{spec.name}", 'rdoc').upload
|
63
71
|
end
|
64
72
|
|
65
73
|
desc 'Publish the API docs and gem'
|
@@ -72,10 +80,10 @@ task :release => [:gem, :package] do
|
|
72
80
|
ruby_forge = RubyForge.new.configure
|
73
81
|
ruby_forge.login
|
74
82
|
|
75
|
-
%w(
|
76
|
-
file = "pkg/#{
|
83
|
+
%w(gem tgz zip).each do |ext|
|
84
|
+
file = "pkg/#{spec.name}-#{spec.version}.#{ext}"
|
77
85
|
puts "Releasing #{File.basename(file)}..."
|
78
86
|
|
79
|
-
ruby_forge.add_release(
|
87
|
+
ruby_forge.add_release(spec.rubyforge_project, spec.name, spec.version, file)
|
80
88
|
end
|
81
89
|
end
|
@@ -1,37 +1,45 @@
|
|
1
1
|
module PluginAWeek #:nodoc:
|
2
2
|
module EncryptedAttributes
|
3
|
-
#
|
4
|
-
# salts
|
3
|
+
# Adds support for dynamically generated salts
|
5
4
|
class ShaEncryptor < PluginAWeek::EncryptedStrings::ShaEncryptor
|
6
|
-
|
5
|
+
# Encrypts a string using a Secure Hash Algorithm (SHA), specifically SHA-1.
|
6
|
+
#
|
7
|
+
# The <tt>:start</tt> configuration option can be any one of the following types:
|
8
|
+
# * +symbol+ - Calls the method on the object whose value is being encrypted
|
9
|
+
# * +proc+ - A block that will be invoked, providing it with the object whose value is being encrypted
|
10
|
+
# * +string+ - The actual salt value to use
|
11
|
+
def initialize(object, value, operation, options = {}) #:nodoc:
|
7
12
|
if operation == :write
|
8
13
|
# Figure out the actual salt value
|
9
14
|
if salt = options[:salt]
|
10
15
|
options[:salt] =
|
11
16
|
case salt
|
12
17
|
when Symbol
|
13
|
-
|
18
|
+
object.send(salt)
|
14
19
|
when Proc
|
15
|
-
salt.call(
|
20
|
+
salt.call(object)
|
16
21
|
else
|
17
22
|
salt
|
18
23
|
end
|
19
24
|
end
|
20
25
|
|
26
|
+
# Track whether or not the salt was generated dynamically
|
21
27
|
@dynamic_salt = salt != options[:salt]
|
28
|
+
|
22
29
|
super(options)
|
23
30
|
else
|
24
|
-
# The salt is
|
31
|
+
# The salt is at the end of the value if it's dynamic
|
25
32
|
salt = value[40..-1]
|
26
33
|
if @dynamic_salt = !salt.blank?
|
27
|
-
options
|
34
|
+
options[:salt] = salt
|
28
35
|
end
|
29
36
|
|
30
37
|
super(options)
|
31
38
|
end
|
32
39
|
end
|
33
40
|
|
34
|
-
# Encrypts the data, appending the salt to the end of the string
|
41
|
+
# Encrypts the data, appending the salt to the end of the string if it
|
42
|
+
# was created dynamically
|
35
43
|
def encrypt(data)
|
36
44
|
encrypted_data = Digest::SHA1.hexdigest(data + salt)
|
37
45
|
encrypted_data << salt if @dynamic_salt
|
data/lib/encrypted_attributes.rb
CHANGED
@@ -11,65 +11,141 @@ module PluginAWeek #:nodoc:
|
|
11
11
|
# Encrypts the specified attribute.
|
12
12
|
#
|
13
13
|
# Configuration options:
|
14
|
-
# * +mode+ - The mode of encryption to use. Default is sha.
|
15
|
-
# * +to+ - The attribute to write the encrypted value. Default is the same attribute being
|
14
|
+
# * +mode+ - The mode of encryption to use. Default is sha. See PluginAWeek::EncryptedStrings for other possible modes
|
15
|
+
# * +to+ - The attribute to write the encrypted value to. Default is the same attribute being encrypted.
|
16
16
|
# * +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.
|
17
17
|
# * +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.
|
18
18
|
#
|
19
|
-
# For additional configuration options
|
19
|
+
# For additional configuration options used during the actual encryption,
|
20
|
+
# see the individual encryptor class for the specified mode.
|
21
|
+
#
|
22
|
+
# == Encryption timeline
|
23
|
+
#
|
24
|
+
# Attributes are encrypted immediately before a record is validated.
|
25
|
+
# This means that you can still validate the presence of the encrypted
|
26
|
+
# attribute, but other things like password length cannot be validated
|
27
|
+
# without either (a) decrypting the value first or (b) using a different
|
28
|
+
# encryption target. For example,
|
29
|
+
#
|
30
|
+
# class User < ActiveRecord::Base
|
31
|
+
# encrypts :password, :to => :crypted_password
|
32
|
+
#
|
33
|
+
# validates_presence_of :password, :crypted_password
|
34
|
+
# validates_length_of :password, :maximum => 16
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# In the above example, the actual encrypted password will be stored in
|
38
|
+
# the +crypted_password+ attribute. This means that validations can
|
39
|
+
# still run against the model for the original password value.
|
40
|
+
#
|
41
|
+
# user = User.new(:password => 'secret')
|
42
|
+
# user.password # => "secret"
|
43
|
+
# user.crypted_password # => nil
|
44
|
+
# user.valid? # => true
|
45
|
+
# user.crypted_password # => "8152bc582f58c854f580cb101d3182813dec4afe"
|
46
|
+
#
|
47
|
+
# user = User.new(:password => 'longer_than_the_maximum_allowed')
|
48
|
+
# user.valid? # => false
|
49
|
+
# user.crypted_password # => "e80a709f25798f87d9ca8005a7f64a645964d7c2"
|
50
|
+
# user.errors[:password] # => "is too long (maximum is 16 characters)"
|
51
|
+
#
|
52
|
+
# == Encryption mode examples
|
53
|
+
#
|
54
|
+
# SHA encryption:
|
55
|
+
# class User < ActiveRecord::Base
|
56
|
+
# encrypts :password
|
57
|
+
# # encrypts :password, :salt => :create_salt
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# Symmetric encryption:
|
61
|
+
# class User < ActiveRecord::Base
|
62
|
+
# encrypts :password, :mode => :symmetric
|
63
|
+
# # encrypts :password, :mode => :symmetric, :key => 'custom'
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# Asymmetric encryption:
|
67
|
+
# class User < ActiveRecord::Base
|
68
|
+
# encrypts :password, :mode => :asymmetric
|
69
|
+
# # encrypts :password, :mode => :asymmetric, :public_key_file => '/keys/public', :private_key_file => '/keys/private'
|
70
|
+
# end
|
20
71
|
def encrypts(attr_name, options = {})
|
21
72
|
attr_name = attr_name.to_s
|
22
73
|
to_attr_name = options.delete(:to) || attr_name
|
23
74
|
|
75
|
+
# Figure out what encryptor is being configured for the attribute
|
24
76
|
mode = options.delete(:mode) || :sha
|
25
|
-
|
26
|
-
|
77
|
+
class_name = "#{mode.to_s.classify}Encryptor"
|
78
|
+
if PluginAWeek::EncryptedAttributes.const_defined?(class_name)
|
79
|
+
encryptor_class = PluginAWeek::EncryptedAttributes.const_get(class_name)
|
27
80
|
else
|
28
|
-
encryptor_class =
|
81
|
+
encryptor_class = PluginAWeek::EncryptedStrings.const_get(class_name)
|
29
82
|
end
|
30
83
|
|
31
|
-
# Set the value
|
84
|
+
# Set the encrypted value right before validation takes place
|
32
85
|
before_validation(:if => options.delete(:if), :unless => options.delete(:unless)) do |record|
|
33
|
-
|
86
|
+
record.send(:write_encrypted_attribute, attr_name, to_attr_name, encryptor_class, options)
|
87
|
+
true
|
88
|
+
end
|
89
|
+
|
90
|
+
# Define the reader when reading the encrypted attribute from the database
|
91
|
+
define_method(to_attr_name) do
|
92
|
+
read_encrypted_attribute(to_attr_name, encryptor_class, options)
|
93
|
+
end
|
94
|
+
|
95
|
+
unless included_modules.include?(PluginAWeek::EncryptedAttributes::InstanceMethods)
|
96
|
+
include PluginAWeek::EncryptedAttributes::InstanceMethods
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
module InstanceMethods #:nodoc:
|
102
|
+
private
|
103
|
+
# Encrypts the given attribute to a target location using the encryption
|
104
|
+
# options configured for that attribute
|
105
|
+
def write_encrypted_attribute(attr_name, to_attr_name, encryptor_class, options)
|
106
|
+
value = send(attr_name)
|
34
107
|
|
108
|
+
# Only encrypt values that actually have content and have not already
|
109
|
+
# been encrypted
|
35
110
|
unless value.blank? || value.encrypted?
|
36
|
-
#
|
37
|
-
encryptor =
|
38
|
-
if encryptor_class.parent == PluginAWeek::EncryptedAttributes
|
39
|
-
encryptor_class.new(record, value, :write, options.dup)
|
40
|
-
else
|
41
|
-
encryptor_class.new(options.dup)
|
42
|
-
end
|
111
|
+
# Create the encryptor configured for this attribute
|
112
|
+
encryptor = create_encryptor(encryptor_class, options, :write, value)
|
43
113
|
|
44
|
-
# Encrypt the value
|
114
|
+
# Encrypt the value
|
45
115
|
value = encryptor.encrypt(value)
|
46
116
|
value.encryptor = encryptor
|
47
117
|
|
48
|
-
|
118
|
+
# Update the value based on the target attribute
|
119
|
+
send("#{to_attr_name}=", value)
|
49
120
|
end
|
50
|
-
|
51
|
-
true
|
52
121
|
end
|
53
122
|
|
54
|
-
#
|
55
|
-
|
123
|
+
# Reads the given attribute from the database, adding contextual
|
124
|
+
# information about how it was encrypted so that equality comparisons
|
125
|
+
# can be used
|
126
|
+
def read_encrypted_attribute(to_attr_name, encryptor_class, options)
|
56
127
|
value = read_attribute(to_attr_name)
|
57
128
|
|
58
129
|
# Make sure we set the encryptor for equality comparison when reading
|
59
130
|
# from the database
|
60
131
|
unless value.blank? || value.encrypted? || attribute_changed?(to_attr_name)
|
61
|
-
#
|
62
|
-
value.encryptor =
|
63
|
-
if encryptor_class.parent == PluginAWeek::EncryptedAttributes
|
64
|
-
encryptor_class.new(self, value, :read, options.dup)
|
65
|
-
else
|
66
|
-
encryptor_class.new(options.dup)
|
67
|
-
end
|
132
|
+
# Create the encryptor configured for this attribute
|
133
|
+
value.encryptor = create_encryptor(encryptor_class, options, :read, value)
|
68
134
|
end
|
69
135
|
|
70
136
|
value
|
71
137
|
end
|
72
|
-
|
138
|
+
|
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
|
+
if klass.parent == PluginAWeek::EncryptedAttributes
|
143
|
+
# Only use the contextual information for encryptors defined in this plugin
|
144
|
+
klass.new(self, value, operator, options.dup)
|
145
|
+
else
|
146
|
+
klass.new(options.dup)
|
147
|
+
end
|
148
|
+
end
|
73
149
|
end
|
74
150
|
end
|
75
151
|
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
2
|
+
libs = " -r irb/completion"
|
3
|
+
libs << " -r test/app_root/script/rails_framework_root"
|
4
|
+
libs << " -r test/test_helper"
|
5
|
+
libs << " -r plugin_test_helper/console_with_fixtures"
|
6
|
+
libs << " -r console_app"
|
7
|
+
libs << " -r console_with_helpers"
|
8
|
+
exec "#{irb} #{libs} --simple-prompt"
|
@@ -0,0 +1 @@
|
|
1
|
+
RAILS_FRAMEWORK_ROOT = '/home/aaron/Projects/Vendor/rails'
|
data/test/factory.rb
CHANGED
@@ -1,26 +1,32 @@
|
|
1
1
|
module Factory
|
2
|
-
# Build actions for the
|
3
|
-
def self.build(
|
4
|
-
name =
|
5
|
-
define_method("#{name}_attributes", block)
|
2
|
+
# Build actions for the model
|
3
|
+
def self.build(model, &block)
|
4
|
+
name = model.to_s.underscore
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
6
|
+
define_method("#{name}_attributes", block)
|
7
|
+
define_method("valid_#{name}_attributes") {|*args| valid_attributes_for(model, *args)}
|
8
|
+
define_method("new_#{name}") {|*args| new_record(model, *args)}
|
9
|
+
define_method("create_#{name}") {|*args| create_record(model, *args)}
|
10
|
+
end
|
11
|
+
|
12
|
+
# Get valid attributes for the model
|
13
|
+
def valid_attributes_for(model, attributes = {})
|
14
|
+
name = model.to_s.underscore
|
15
|
+
send("#{name}_attributes", attributes)
|
16
|
+
attributes
|
17
|
+
end
|
18
|
+
|
19
|
+
# Build an unsaved record
|
20
|
+
def new_record(model, *args)
|
21
|
+
model.new(valid_attributes_for(model, *args))
|
22
|
+
end
|
23
|
+
|
24
|
+
# Build and save/reload a record
|
25
|
+
def create_record(model, *args)
|
26
|
+
record = new_record(model, *args)
|
27
|
+
record.save!
|
28
|
+
record.reload
|
29
|
+
record
|
24
30
|
end
|
25
31
|
|
26
32
|
build User do |attributes|
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: encrypted_attributes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Pfeifer
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-07-05 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
requirements:
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.0.
|
22
|
+
version: 0.0.5
|
23
23
|
version:
|
24
24
|
description:
|
25
25
|
email: aaron@pluginaweek.org
|
@@ -37,6 +37,9 @@ files:
|
|
37
37
|
- test/app_root/app
|
38
38
|
- test/app_root/app/models
|
39
39
|
- test/app_root/app/models/user.rb
|
40
|
+
- test/app_root/script
|
41
|
+
- test/app_root/script/rails_framework_root.rb
|
42
|
+
- test/app_root/script/console
|
40
43
|
- test/app_root/config
|
41
44
|
- test/app_root/config/environment.rb
|
42
45
|
- test/app_root/db
|
@@ -51,11 +54,11 @@ files:
|
|
51
54
|
- test/unit
|
52
55
|
- test/unit/sha_encryptor_test.rb
|
53
56
|
- test/unit/encrypted_attributes_test.rb
|
54
|
-
- CHANGELOG
|
57
|
+
- CHANGELOG.rdoc
|
55
58
|
- init.rb
|
56
|
-
-
|
59
|
+
- LICENSE
|
57
60
|
- Rakefile
|
58
|
-
- README
|
61
|
+
- README.rdoc
|
59
62
|
has_rdoc: true
|
60
63
|
homepage: http://www.pluginaweek.org
|
61
64
|
post_install_message:
|
@@ -77,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
80
|
version:
|
78
81
|
requirements: []
|
79
82
|
|
80
|
-
rubyforge_project:
|
83
|
+
rubyforge_project: pluginaweek
|
81
84
|
rubygems_version: 1.1.1
|
82
85
|
signing_key:
|
83
86
|
specification_version: 2
|