encrypted_attributes 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,29 +1,27 @@
1
- *SVN*
1
+ == master
2
2
 
3
- *0.1.1* (June 22nd, 2008)
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
- *0.1.0* (May 5th, 2008)
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
- *0.0.2* (September 26th, 2007)
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
- *0.0.1* (August 5th, 2007)
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
File without changes
@@ -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://dev.pluginaweek.org/browser/trunk/encrypted_attributes
18
+ * http://github.com/pluginaweek/encrypted_attributes
19
19
 
20
20
  Source
21
21
 
22
- * http://svn.pluginaweek.org/trunk/encrypted_attributes
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 in the encrypted_strings plugin.
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 attributed being
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 information about
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://wiki.pluginaweek.org/Plugin_test_helper]
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://wiki.pluginaweek.org/Encrypted_strings]
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
- PKG_NAME = 'encrypted_attributes'
7
- PKG_VERSION = '0.1.1'
8
- PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
9
- RUBY_FORGE_PROJECT = 'pluginaweek'
10
-
11
- desc 'Default: run unit tests.'
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 'Test the encrypted_attributes plugin.'
27
+ desc "Test the #{spec.name} plugin."
15
28
  Rake::TestTask.new(:test) do |t|
16
29
  t.libs << 'lib'
17
- t.pattern = 'test/**/*_test.rb'
30
+ t.test_files = spec.test_files
18
31
  t.verbose = true
19
32
  end
20
33
 
21
- desc 'Generate documentation for the encrypted_attributes plugin.'
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 = 'EncryptedAttributes'
51
+ rdoc.title = spec.name
25
52
  rdoc.template = '../rdoc_template.rb'
26
- rdoc.options << '--line-numbers' << '--inline-source'
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', "#{PKG_FILE_NAME}.gem").upload
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/#{PKG_NAME}", 'rdoc').upload
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( gem tgz zip ).each do |ext|
76
- file = "pkg/#{PKG_FILE_NAME}.#{ext}"
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(RUBY_FORGE_PROJECT, PKG_NAME, PKG_VERSION, file)
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
- # Supports encryption for ActiveRecord models by adding dynamically generated
4
- # salts
3
+ # Adds support for dynamically generated salts
5
4
  class ShaEncryptor < PluginAWeek::EncryptedStrings::ShaEncryptor
6
- def initialize(record, value, operation, options = {}) #:nodoc:
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
- record.send(salt).to_s
18
+ object.send(salt)
14
19
  when Proc
15
- salt.call(record).to_s
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 in the value if it's dynamic
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.merge!(:salt => salt)
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
@@ -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 encryupted.
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, see the individual encryptor class.
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
- if mode == :sha
26
- encryptor_class = "PluginAWeek::EncryptedAttributes::#{mode.to_s.classify}Encryptor".constantize
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 = "PluginAWeek::EncryptedStrings::#{mode.to_s.classify}Encryptor".constantize
81
+ encryptor_class = PluginAWeek::EncryptedStrings.const_get(class_name)
29
82
  end
30
83
 
31
- # Set the value immediately before validation takes place
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
- value = record.send(attr_name)
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
- # Add contextual information for this plugin's encryptors
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 and then track the encryptor used
114
+ # Encrypt the value
45
115
  value = encryptor.encrypt(value)
46
116
  value.encryptor = encryptor
47
117
 
48
- record.send("#{to_attr_name}=", value)
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
- # Define the reader when reading the crypted attribute from the db
55
- define_method(to_attr_name) do
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
- # Add contextual information for this plugin's encryptors
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
- end
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 class
3
- def self.build(klass, &block)
4
- name = klass.to_s.underscore
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
- module_eval <<-end_eval
8
- def valid_#{name}_attributes(attributes = {})
9
- #{name}_attributes(attributes)
10
- attributes
11
- end
12
-
13
- def new_#{name}(attributes = {})
14
- #{klass}.new(valid_#{name}_attributes(attributes))
15
- end
16
-
17
- def create_#{name}(*args)
18
- record = new_#{name}(*args)
19
- record.save!
20
- record.reload
21
- record
22
- end
23
- end_eval
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.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Pfeifer
8
- autorequire: encrypted_attributes
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-06-22 00:00:00 -04:00
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.1
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
- - MIT-LICENSE
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