has_secure_password 0.0.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/MIT_LICENSE +20 -0
- data/MIT_LICENSE_RAILS +20 -0
- data/README.md +30 -0
- data/Rakefile +22 -0
- data/lib/active_record/secure_password.rb +118 -0
- data/lib/version.rb +5 -0
- data/rails/init.rb +4 -0
- data/test/database.yml +4 -0
- data/test/schema.rb +7 -0
- data/test/secure_password_test.rb +160 -0
- metadata +112 -0
data/MIT_LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright 2013 Larry Halff (See also MIT_LICENCE_RAILS.)
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/MIT_LICENSE_RAILS
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2004-2013 David Heinemeier Hansson
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# has_secure_password
|
|
2
|
+
|
|
3
|
+
This is a Rails 2 plugin for "has_secure_password" as currently provided in Rails 4.
|
|
4
|
+
|
|
5
|
+
All code was copied and modified from:
|
|
6
|
+
|
|
7
|
+
https://github.com/rails/rails/blob/master/activemodel/lib/active_model/secure_password.rb
|
|
8
|
+
|
|
9
|
+
and
|
|
10
|
+
|
|
11
|
+
https://github.com/rails/rails/tree/master/activemodel/test
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
Add the following to `environment.rb` or your Gemfile:
|
|
16
|
+
|
|
17
|
+
gem "has_secure_password"
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
Use as you would the Rails has_secure_password mixin:
|
|
22
|
+
|
|
23
|
+
class User
|
|
24
|
+
has_secure_password
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
## Credits
|
|
28
|
+
|
|
29
|
+
Copyright (c) 2013 Larry Halff, released under the MIT license.
|
|
30
|
+
Most portions Copyright (c) 2004-2013 David Heinemeier Hansson, released under the MIT license.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'rake'
|
|
2
|
+
require 'rake/testtask'
|
|
3
|
+
require 'rake/rdoctask'
|
|
4
|
+
|
|
5
|
+
desc 'Default: run unit tests.'
|
|
6
|
+
task :default => :test
|
|
7
|
+
|
|
8
|
+
desc 'Test has_secure_password plugin.'
|
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
|
10
|
+
t.libs << 'lib'
|
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
|
12
|
+
t.verbose = true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
desc 'Generate documentation for has_secure_password plugin.'
|
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
18
|
+
rdoc.title = 'has_secure_password'
|
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
|
20
|
+
rdoc.rdoc_files.include('README')
|
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
22
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
module SecurePassword #:nodoc:
|
|
3
|
+
|
|
4
|
+
def self.included(base)
|
|
5
|
+
base.extend(ClassMethods)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class << self; attr_accessor :min_cost; end
|
|
9
|
+
self.min_cost = false
|
|
10
|
+
|
|
11
|
+
module ClassMethods
|
|
12
|
+
# Adds methods to set and authenticate against a BCrypt password.
|
|
13
|
+
# This mechanism requires you to have a password_digest attribute.
|
|
14
|
+
#
|
|
15
|
+
# Validations for presence of password on create, confirmation of password
|
|
16
|
+
# (using a +password_confirmation+ attribute) are automatically added. If
|
|
17
|
+
# you wish to turn off validations, pass <tt>validations: false</tt> as an
|
|
18
|
+
# argument. You can add more validations by hand if need be.
|
|
19
|
+
#
|
|
20
|
+
# If you don't need the confirmation validation, just don't set any
|
|
21
|
+
# value to the password_confirmation attribute and the the validation
|
|
22
|
+
# will not be triggered.
|
|
23
|
+
#
|
|
24
|
+
# You need to add bcrypt-ruby (~> 3.0.0) to Gemfile to use #has_secure_password:
|
|
25
|
+
#
|
|
26
|
+
# gem 'bcrypt-ruby', '~> 3.0.0'
|
|
27
|
+
#
|
|
28
|
+
# Example using Active Record (which automatically includes ActiveRecord::SecurePassword):
|
|
29
|
+
#
|
|
30
|
+
# # Schema: User(name:string, password_digest:string)
|
|
31
|
+
# class User < ActiveRecord::Base
|
|
32
|
+
# has_secure_password
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
# user = User.new(name: 'david', password: '', password_confirmation: 'nomatch')
|
|
36
|
+
# user.save # => false, password required
|
|
37
|
+
# user.password = 'mUc3m00RsqyRe'
|
|
38
|
+
# user.save # => false, confirmation doesn't match
|
|
39
|
+
# user.password_confirmation = 'mUc3m00RsqyRe'
|
|
40
|
+
# user.save # => true
|
|
41
|
+
# user.authenticate('notright') # => false
|
|
42
|
+
# user.authenticate('mUc3m00RsqyRe') # => user
|
|
43
|
+
# User.find_by(name: 'david').try(:authenticate, 'notright') # => false
|
|
44
|
+
# User.find_by(name: 'david').try(:authenticate, 'mUc3m00RsqyRe') # => user
|
|
45
|
+
def has_secure_password(options = {})
|
|
46
|
+
# Load bcrypt-ruby only when has_secure_password is used.
|
|
47
|
+
# This is to avoid ActiveRecord (and by extension the entire framework)
|
|
48
|
+
# being dependent on a binary library.
|
|
49
|
+
begin
|
|
50
|
+
gem 'bcrypt-ruby', '~> 3.0.0'
|
|
51
|
+
require 'bcrypt'
|
|
52
|
+
rescue LoadError
|
|
53
|
+
$stderr.puts "You don't have bcrypt-ruby installed in your application. Please add it to your Gemfile and run bundle install"
|
|
54
|
+
raise
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
attr_reader :password
|
|
58
|
+
|
|
59
|
+
include InstanceMethodsOnActivation
|
|
60
|
+
|
|
61
|
+
if options[:validations] == true || options[:validations].nil?
|
|
62
|
+
validates_confirmation_of :password, :if => lambda { |m| m.password.present? }
|
|
63
|
+
validates_presence_of :password, :on => :create
|
|
64
|
+
validates_presence_of :password_confirmation, :if => lambda { |m| m.password.present? }
|
|
65
|
+
|
|
66
|
+
before_create { |r| raise "Password digest missing on new record" if r.password_digest.blank? }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
if respond_to?(:attributes_protected_by_default)
|
|
70
|
+
def self.attributes_protected_by_default #:nodoc:
|
|
71
|
+
super + ['password_digest']
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
module InstanceMethodsOnActivation
|
|
78
|
+
# Returns +self+ if the password is correct, otherwise +false+.
|
|
79
|
+
#
|
|
80
|
+
# class User < ActiveRecord::Base
|
|
81
|
+
# has_secure_password validations: false
|
|
82
|
+
# end
|
|
83
|
+
#
|
|
84
|
+
# user = User.new(name: 'david', password: 'mUc3m00RsqyRe')
|
|
85
|
+
# user.save
|
|
86
|
+
# user.authenticate('notright') # => false
|
|
87
|
+
# user.authenticate('mUc3m00RsqyRe') # => user
|
|
88
|
+
def authenticate(unencrypted_password)
|
|
89
|
+
BCrypt::Password.new(password_digest) == unencrypted_password && self
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Encrypts the password into the +password_digest+ attribute, only if the
|
|
93
|
+
# new password is not blank.
|
|
94
|
+
#
|
|
95
|
+
# class User < ActiveRecord::Base
|
|
96
|
+
# has_secure_password validations: false
|
|
97
|
+
# end
|
|
98
|
+
#
|
|
99
|
+
# user = User.new
|
|
100
|
+
# user.password = nil
|
|
101
|
+
# user.password_digest # => nil
|
|
102
|
+
# user.password = 'mUc3m00RsqyRe'
|
|
103
|
+
# user.password_digest # => "$2a$10$4LEA7r4YmNHtvlAvHhsYAeZmk/xeUVtMTYqwIvYY76EW5GUqDiP4."
|
|
104
|
+
def password=(unencrypted_password)
|
|
105
|
+
unless unencrypted_password.blank?
|
|
106
|
+
@password = unencrypted_password
|
|
107
|
+
cost = ActiveRecord::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine::DEFAULT_COST
|
|
108
|
+
self.password_digest = BCrypt::Password.create(unencrypted_password, :cost => cost)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def password_confirmation=(unencrypted_password)
|
|
113
|
+
@password_confirmation = unencrypted_password
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
end
|
|
118
|
+
end
|
data/lib/version.rb
ADDED
data/rails/init.rb
ADDED
data/test/database.yml
ADDED
data/test/schema.rb
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
require 'active_record'
|
|
5
|
+
|
|
6
|
+
$:.unshift File.dirname(__FILE__) + '/../lib'
|
|
7
|
+
require File.dirname(__FILE__) + '/../rails/init'
|
|
8
|
+
|
|
9
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
|
10
|
+
ActiveRecord::Schema.verbose = false
|
|
11
|
+
|
|
12
|
+
def setup_db(position_options = {})
|
|
13
|
+
# AR caches columns options like defaults etc. Clear them!
|
|
14
|
+
ActiveRecord::Schema.define(:version => 1) do
|
|
15
|
+
create_table :mixins do |t|
|
|
16
|
+
t.column :type, :string
|
|
17
|
+
t.column :password_digest, :string
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def teardown_db
|
|
23
|
+
ActiveRecord::Base.connection.tables.each do |table|
|
|
24
|
+
ActiveRecord::Base.connection.drop_table(table)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class Mixin < ActiveRecord::Base
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class User < Mixin
|
|
32
|
+
has_secure_password
|
|
33
|
+
attr_accessor :password_digest, :password_salt
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class Visitor < Mixin
|
|
37
|
+
has_secure_password(:validations => false)
|
|
38
|
+
attr_accessor :password_digest, :password_confirmation
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class OauthedUser < Mixin
|
|
42
|
+
has_secure_password(:validations => false)
|
|
43
|
+
attr_accessor :password_digest, :password_salt
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class SecurePasswordTest < Test::Unit::TestCase
|
|
47
|
+
def setup
|
|
48
|
+
ActiveRecord::SecurePassword.min_cost = true
|
|
49
|
+
|
|
50
|
+
setup_db
|
|
51
|
+
@user = User.new
|
|
52
|
+
@visitor = Visitor.new
|
|
53
|
+
@oauthed_user = OauthedUser.new
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def teardown
|
|
57
|
+
ActiveRecord::SecurePassword.min_cost = false
|
|
58
|
+
teardown_db
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def test_blank_password
|
|
62
|
+
@user.password = @visitor.password = ''
|
|
63
|
+
assert !@user.valid?, 'user should be invalid'
|
|
64
|
+
assert @visitor.valid?, 'visitor should be valid'
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def test_nil_password
|
|
68
|
+
@user.password = @visitor.password = nil
|
|
69
|
+
assert !@user.valid?, 'user should be invalid'
|
|
70
|
+
assert @visitor.valid?, 'visitor should be valid'
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def test_blank_password_doesnt_override_previous_password
|
|
74
|
+
@user.password = 'test'
|
|
75
|
+
@user.password = ''
|
|
76
|
+
assert_equal @user.password, 'test'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def test_password_must_be_present
|
|
80
|
+
assert !@user.valid?
|
|
81
|
+
assert_equal 1, @user.errors.size
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def test_match_confirmation
|
|
85
|
+
@user.password = @visitor.password = "thiswillberight"
|
|
86
|
+
@user.password_confirmation = @visitor.password_confirmation = "wrong"
|
|
87
|
+
|
|
88
|
+
assert !@user.valid?
|
|
89
|
+
assert @visitor.valid?
|
|
90
|
+
|
|
91
|
+
@user.password_confirmation = "thiswillberight"
|
|
92
|
+
|
|
93
|
+
assert @user.valid?
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def test_authenticate
|
|
97
|
+
@user.password = "secret"
|
|
98
|
+
|
|
99
|
+
assert !@user.authenticate("wrong")
|
|
100
|
+
assert @user.authenticate("secret")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def test_user_should_not_be_created_with_blank_digest
|
|
104
|
+
@user.password = "tryapassword"
|
|
105
|
+
@user.password_confirmation = "tryapassword"
|
|
106
|
+
@user.password_digest = ""
|
|
107
|
+
assert_raise RuntimeError do
|
|
108
|
+
@user.save
|
|
109
|
+
end
|
|
110
|
+
@user.password = "supersecretpassword"
|
|
111
|
+
@user.password_confirmation = "supersecretpassword"
|
|
112
|
+
assert_nothing_raised do
|
|
113
|
+
@user.save
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def test_oauthed_user_can_be_created_with_blank_digest
|
|
118
|
+
@oauthed_user.password = "tryapassword"
|
|
119
|
+
@oauthed_user.password_confirmation = "tryapassword"
|
|
120
|
+
@oauthed_user.password_digest = ""
|
|
121
|
+
assert_nothing_raised do
|
|
122
|
+
@oauthed_user.save
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def test_password_digest_cost_defaults_to_bcrypt_default_cost_when_min_cost_is_false
|
|
127
|
+
ActiveRecord::SecurePassword.min_cost = false
|
|
128
|
+
|
|
129
|
+
@user.password = "secret"
|
|
130
|
+
assert_equal BCrypt::Engine::DEFAULT_COST, @user.password_digest.cost
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def test_Password_digest_cost_can_be_set_to_bcrypt_min_cost_to_speed_up_tests
|
|
134
|
+
ActiveRecord::SecurePassword.min_cost = true
|
|
135
|
+
|
|
136
|
+
@user.password = "secret"
|
|
137
|
+
assert_equal BCrypt::Engine::MIN_COST, @user.password_digest.cost
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def test_blank_password_confirmation_does_not_result_in_a_confirmation_error
|
|
141
|
+
@user.password = "supersecretpassword"
|
|
142
|
+
@user.password_confirmation = "supersecretpassword"
|
|
143
|
+
@user.save
|
|
144
|
+
@user_reloaded = User.find(@user.id)
|
|
145
|
+
|
|
146
|
+
assert @user_reloaded.password.nil?
|
|
147
|
+
assert @user_reloaded.password.nil?
|
|
148
|
+
assert @user_reloaded.valid?, "user should be valid"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def test will_not_save_if_confirmation_is_blank_but_password_is_not
|
|
152
|
+
@user.password = "password"
|
|
153
|
+
@user.password_confirmation = ""
|
|
154
|
+
assert !@user.valid?
|
|
155
|
+
|
|
156
|
+
@user.password_confirmation = "password"
|
|
157
|
+
assert @user.valid?
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: has_secure_password
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 29
|
|
5
|
+
prerelease:
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 0
|
|
9
|
+
- 1
|
|
10
|
+
version: 0.0.1
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- lhalff
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2013-06-14 00:00:00 Z
|
|
19
|
+
dependencies:
|
|
20
|
+
- !ruby/object:Gem::Dependency
|
|
21
|
+
name: rails
|
|
22
|
+
prerelease: false
|
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
24
|
+
none: false
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">"
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
hash: 1
|
|
29
|
+
segments:
|
|
30
|
+
- 2
|
|
31
|
+
- 1
|
|
32
|
+
version: "2.1"
|
|
33
|
+
- - <
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
hash: 7
|
|
36
|
+
segments:
|
|
37
|
+
- 3
|
|
38
|
+
- 0
|
|
39
|
+
version: "3.0"
|
|
40
|
+
type: :runtime
|
|
41
|
+
version_requirements: *id001
|
|
42
|
+
- !ruby/object:Gem::Dependency
|
|
43
|
+
name: sqlite3
|
|
44
|
+
prerelease: false
|
|
45
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
46
|
+
none: false
|
|
47
|
+
requirements:
|
|
48
|
+
- - ">="
|
|
49
|
+
- !ruby/object:Gem::Version
|
|
50
|
+
hash: 3
|
|
51
|
+
segments:
|
|
52
|
+
- 0
|
|
53
|
+
version: "0"
|
|
54
|
+
type: :development
|
|
55
|
+
version_requirements: *id002
|
|
56
|
+
description: Provides Rails 4 has_secure_password mixin for Rails 2. Requires Rails 2.1 or higher.
|
|
57
|
+
email:
|
|
58
|
+
- email@larryhalff.com
|
|
59
|
+
executables: []
|
|
60
|
+
|
|
61
|
+
extensions: []
|
|
62
|
+
|
|
63
|
+
extra_rdoc_files: []
|
|
64
|
+
|
|
65
|
+
files:
|
|
66
|
+
- rails/init.rb
|
|
67
|
+
- lib/active_record/secure_password.rb
|
|
68
|
+
- lib/version.rb
|
|
69
|
+
- MIT_LICENSE
|
|
70
|
+
- MIT_LICENSE_RAILS
|
|
71
|
+
- Rakefile
|
|
72
|
+
- README.md
|
|
73
|
+
- test/database.yml
|
|
74
|
+
- test/schema.rb
|
|
75
|
+
- test/secure_password_test.rb
|
|
76
|
+
homepage: https://github.com/lhalff/rails_secure_password
|
|
77
|
+
licenses: []
|
|
78
|
+
|
|
79
|
+
post_install_message:
|
|
80
|
+
rdoc_options: []
|
|
81
|
+
|
|
82
|
+
require_paths:
|
|
83
|
+
- lib
|
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
85
|
+
none: false
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
hash: 3
|
|
90
|
+
segments:
|
|
91
|
+
- 0
|
|
92
|
+
version: "0"
|
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
|
+
none: false
|
|
95
|
+
requirements:
|
|
96
|
+
- - ">="
|
|
97
|
+
- !ruby/object:Gem::Version
|
|
98
|
+
hash: 3
|
|
99
|
+
segments:
|
|
100
|
+
- 0
|
|
101
|
+
version: "0"
|
|
102
|
+
requirements: []
|
|
103
|
+
|
|
104
|
+
rubyforge_project:
|
|
105
|
+
rubygems_version: 1.8.25
|
|
106
|
+
signing_key:
|
|
107
|
+
specification_version: 3
|
|
108
|
+
summary: has_secure_password for Rails 2
|
|
109
|
+
test_files:
|
|
110
|
+
- test/database.yml
|
|
111
|
+
- test/schema.rb
|
|
112
|
+
- test/secure_password_test.rb
|