minimalist_authentication 0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/MIT-LICENSE +20 -0
- data/README +45 -0
- data/Rakefile +35 -0
- data/init.rb +2 -0
- data/lib/app/views/sessions/_form.html.erb +12 -0
- data/lib/app/views/sessions/new.html.erb +1 -0
- data/lib/minimalist/authentication.rb +124 -0
- data/lib/minimalist/authorization.rb +49 -0
- data/lib/minimalist/sessions.rb +59 -0
- data/lib/minimalist/test_helper.rb +12 -0
- data/lib/minimalist/version.rb +3 -0
- data/lib/minimalist_authentication.rb +4 -0
- data/lib/tasks/minimalist_authentication_tasks.rake +4 -0
- data/minimalist_authentication.gemspec +15 -0
- data/test/.gitignore +1 -0
- data/test/authentication_test.rb +99 -0
- data/test/authorization_test.rb +77 -0
- data/test/factories.rb +8 -0
- data/test/rails_root/Gemfile +33 -0
- data/test/rails_root/Gemfile.lock +79 -0
- data/test/rails_root/README +256 -0
- data/test/rails_root/Rakefile +7 -0
- data/test/rails_root/app/controllers/application_controller.rb +5 -0
- data/test/rails_root/app/controllers/sessions_controller.rb +3 -0
- data/test/rails_root/app/helpers/application_helper.rb +2 -0
- data/test/rails_root/app/models/user.rb +3 -0
- data/test/rails_root/app/views/layouts/application.html.erb +14 -0
- data/test/rails_root/config.ru +4 -0
- data/test/rails_root/config/application.rb +42 -0
- data/test/rails_root/config/boot.rb +13 -0
- data/test/rails_root/config/database.yml +22 -0
- data/test/rails_root/config/environment.rb +5 -0
- data/test/rails_root/config/environments/development.rb +26 -0
- data/test/rails_root/config/environments/production.rb +49 -0
- data/test/rails_root/config/environments/test.rb +35 -0
- data/test/rails_root/config/initializers/backtrace_silencers.rb +7 -0
- data/test/rails_root/config/initializers/inflections.rb +10 -0
- data/test/rails_root/config/initializers/mime_types.rb +5 -0
- data/test/rails_root/config/initializers/secret_token.rb +7 -0
- data/test/rails_root/config/initializers/session_store.rb +8 -0
- data/test/rails_root/config/locales/en.yml +5 -0
- data/test/rails_root/config/routes.rb +5 -0
- data/test/rails_root/db/.gitignore +2 -0
- data/test/rails_root/db/schema.rb +21 -0
- data/test/rails_root/db/seeds.rb +7 -0
- data/test/rails_root/doc/README_FOR_APP +2 -0
- data/test/rails_root/lib/tasks/.gitkeep +0 -0
- data/test/rails_root/log/.gitignore +1 -0
- data/test/rails_root/log/.gitkeep +0 -0
- data/test/rails_root/script/rails +6 -0
- data/test/rails_root/test/performance/browsing_test.rb +9 -0
- data/test/rails_root/test/test_helper.rb +13 -0
- data/test/sessions_test.rb +30 -0
- data/test/test_helper.rb +11 -0
- metadata +161 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 'WWIDEA, INC'
|
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
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
MinimalistAuthentication
|
2
|
+
========================
|
3
|
+
|
4
|
+
A Rails authentication plugin that takes a minimalist approach. It is designed to be simple to understand, use, and modify for your application.
|
5
|
+
|
6
|
+
This plugin was largely inspired by the restful-authentication plugin (http://github.com/technoweenie/restful-authentication/tree/master). I selected the essential methods for password based authentication, reorganized them, trimmed them down when possible, added a couple of features, and resisted the urge to start adding more.
|
7
|
+
|
8
|
+
|
9
|
+
Installation
|
10
|
+
============
|
11
|
+
script/plugin install git://github.com/aaron/minimalist_authentication.git
|
12
|
+
|
13
|
+
ruby script/generate scaffold user active:boolean email:string crypted_password:string salt:string using_digest_version:integer last_logged_in_at:datetime
|
14
|
+
|
15
|
+
|
16
|
+
Example
|
17
|
+
=======
|
18
|
+
|
19
|
+
app/models/user.rb
|
20
|
+
class User < ActiveRecord::Base
|
21
|
+
include Minimalist::Authentication
|
22
|
+
end
|
23
|
+
|
24
|
+
app/controllers/application.rb
|
25
|
+
class ApplicationController < ActionController::Base
|
26
|
+
include Minimalist::Authorization
|
27
|
+
|
28
|
+
# Lock down everything by default
|
29
|
+
# use skip_before_filter to open up sepecific actions
|
30
|
+
prepend_before_filter :authorization_required
|
31
|
+
end
|
32
|
+
|
33
|
+
app/controllers/sessions_controller.rb
|
34
|
+
class SessionsController < ApplicationController
|
35
|
+
include Minimalist::Sessions
|
36
|
+
skip_before_filter :authorization_required, :only => [:new, :create]
|
37
|
+
end
|
38
|
+
|
39
|
+
test/test_helper.rb
|
40
|
+
class Test::Unit::TestCase
|
41
|
+
include Minimalist::TestHelper
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
Copyright (c) 2009 Aaron Baldwin, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,35 @@
|
|
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 the minimalist_authentication plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.libs << 'test'
|
12
|
+
t.pattern = 'test/**/*_test.rb'
|
13
|
+
t.verbose = true
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Generate documentation for the minimalist_authentication plugin.'
|
17
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
18
|
+
rdoc.rdoc_dir = 'rdoc'
|
19
|
+
rdoc.title = 'MinimalistAuthentication'
|
20
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
21
|
+
rdoc.rdoc_files.include('README')
|
22
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'Measures test coverage using rcov'
|
26
|
+
task :rcov do
|
27
|
+
rm_f "coverage"
|
28
|
+
rcov = "rcov --rails --text-summary -Ilib --exclude /gems/,/app/,/Library/"
|
29
|
+
system("#{rcov} --html #{Dir.glob('test/**/*_test.rb').join(' ')}")
|
30
|
+
if PLATFORM['darwin'] #Mac
|
31
|
+
system("open coverage/index.html")
|
32
|
+
elsif PLATFORM[/linux/] #Ubuntu, etc.
|
33
|
+
system("/etc/alternatives/x-www-browser coverage/index.html")
|
34
|
+
end
|
35
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
<%= form_tag session_path do %>
|
2
|
+
<div>
|
3
|
+
<%= label_tag 'email' %>
|
4
|
+
<%= text_field_tag 'email', @email %>
|
5
|
+
</div>
|
6
|
+
<div>
|
7
|
+
<%= label_tag 'password' %>
|
8
|
+
<%= password_field_tag 'password', nil %>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<p><%= submit_tag 'Log in', :class =>'submit' %></p>
|
12
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => 'form' %>
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
module Minimalist
|
4
|
+
module Authentication
|
5
|
+
GUEST_USER_EMAIL = 'guest'
|
6
|
+
PREFERRED_DIGEST_VERSION = 2
|
7
|
+
|
8
|
+
def self.included( base )
|
9
|
+
base.extend(ClassMethods)
|
10
|
+
base.class_eval do
|
11
|
+
include InstanceMethods
|
12
|
+
|
13
|
+
attr_accessor :password
|
14
|
+
before_save :encrypt_password
|
15
|
+
|
16
|
+
validates_presence_of :email, :if => :validate_email_presence?
|
17
|
+
validates_uniqueness_of :email, :if => :validate_email_uniqueness?
|
18
|
+
validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :if => :validate_email_format?
|
19
|
+
validates_presence_of :password, :if => :password_required?
|
20
|
+
validates_confirmation_of :password, :if => :password_required?
|
21
|
+
validates_length_of :password, :within => 6..40, :if => :password_required?
|
22
|
+
|
23
|
+
scope :active, :conditions => {:active => true}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
def authenticate(email, password)
|
29
|
+
return if email.blank? || password.blank?
|
30
|
+
user = active.first(:conditions => {:email => email})
|
31
|
+
return unless user && user.authenticated?(password)
|
32
|
+
return user
|
33
|
+
end
|
34
|
+
|
35
|
+
def secure_digest(string, salt, version = 1)
|
36
|
+
case version
|
37
|
+
when 0 then Digest::MD5.hexdigest(string.to_s)
|
38
|
+
when 1 then Digest::SHA1.hexdigest("#{string}--#{salt}")
|
39
|
+
when 2 then Digest::SHA2.hexdigest("#{string}#{salt}", 512)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def make_token
|
44
|
+
secure_digest(Time.now, (1..10).map{ rand.to_s.gsub(/0\./,'') }.join, PREFERRED_DIGEST_VERSION)
|
45
|
+
end
|
46
|
+
|
47
|
+
def guest
|
48
|
+
new.tap do |user|
|
49
|
+
user.email = GUEST_USER_EMAIL
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
module InstanceMethods
|
55
|
+
|
56
|
+
def active?
|
57
|
+
active
|
58
|
+
end
|
59
|
+
|
60
|
+
def authenticated?(password)
|
61
|
+
if crypted_password == encrypt(password)
|
62
|
+
if self.respond_to?(:using_digest_version) and using_digest_version != PREFERRED_DIGEST_VERSION
|
63
|
+
new_salt = self.class.make_token
|
64
|
+
self.update_attribute(:crypted_password,self.class.secure_digest(password, new_salt, PREFERRED_DIGEST_VERSION))
|
65
|
+
self.update_attribute(:salt, new_salt)
|
66
|
+
self.update_attribute(:using_digest_version, PREFERRED_DIGEST_VERSION)
|
67
|
+
end
|
68
|
+
return true
|
69
|
+
else
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def logged_in
|
75
|
+
self.class.update_all("last_logged_in_at='#{Time.now.to_s(:db)}'", "id=#{self.id}") # use update_all to avoid updated_on trigger
|
76
|
+
end
|
77
|
+
|
78
|
+
def is_guest?
|
79
|
+
email == GUEST_USER_EMAIL
|
80
|
+
end
|
81
|
+
|
82
|
+
#######
|
83
|
+
private
|
84
|
+
#######
|
85
|
+
|
86
|
+
def password_required?
|
87
|
+
active? && (crypted_password.blank? || !password.blank?)
|
88
|
+
end
|
89
|
+
|
90
|
+
def encrypt(password)
|
91
|
+
self.class.secure_digest(password, salt, digest_version)
|
92
|
+
end
|
93
|
+
|
94
|
+
def encrypt_password
|
95
|
+
return if password.blank?
|
96
|
+
self.salt = self.class.make_token if new_record?
|
97
|
+
self.crypted_password = self.class.secure_digest(password, salt, (self.respond_to?(:using_digest_version) ? PREFERRED_DIGEST_VERSION : 1))
|
98
|
+
self.using_digest_version = PREFERRED_DIGEST_VERSION if self.respond_to?(:using_digest_version)
|
99
|
+
end
|
100
|
+
|
101
|
+
def digest_version
|
102
|
+
self.respond_to?(:using_digest_version) ? (using_digest_version || 1) : 1
|
103
|
+
end
|
104
|
+
|
105
|
+
# email validation
|
106
|
+
def validate_email?
|
107
|
+
# allows applications to turn off email validation
|
108
|
+
true
|
109
|
+
end
|
110
|
+
|
111
|
+
def validate_email_presence?
|
112
|
+
validate_email? && active?
|
113
|
+
end
|
114
|
+
|
115
|
+
def validate_email_format?
|
116
|
+
validate_email? && active?
|
117
|
+
end
|
118
|
+
|
119
|
+
def validate_email_uniqueness?
|
120
|
+
validate_email? && active?
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Minimalist
|
2
|
+
module Authorization
|
3
|
+
def self.included( base )
|
4
|
+
base.class_eval do
|
5
|
+
include InstanceMethods
|
6
|
+
helper_method :current_user, :logged_in?, :authorized?
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module InstanceMethods
|
11
|
+
#######
|
12
|
+
private
|
13
|
+
#######
|
14
|
+
|
15
|
+
def current_user
|
16
|
+
@current_user ||= (get_user_from_session || User.guest)
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_user_from_session
|
20
|
+
User.find_by_id(session[:user_id]) if session[:user_id]
|
21
|
+
end
|
22
|
+
|
23
|
+
def authorization_required
|
24
|
+
authorized? || access_denied
|
25
|
+
end
|
26
|
+
|
27
|
+
def authorized?(action = action_name, resource = controller_name)
|
28
|
+
logged_in?
|
29
|
+
end
|
30
|
+
|
31
|
+
def logged_in?
|
32
|
+
!current_user.is_guest?
|
33
|
+
end
|
34
|
+
|
35
|
+
def access_denied
|
36
|
+
store_location if request.method == :get && !logged_in?
|
37
|
+
redirect_to new_session_path
|
38
|
+
end
|
39
|
+
|
40
|
+
def store_location
|
41
|
+
session[:return_to] = request.request_uri
|
42
|
+
end
|
43
|
+
|
44
|
+
def redirect_back_or_default(default)
|
45
|
+
redirect_to(session.delete(:return_to) || default)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Minimalist
|
2
|
+
module Sessions
|
3
|
+
def self.included( base )
|
4
|
+
base.class_eval do
|
5
|
+
include InstanceMethods
|
6
|
+
append_view_path File.join(File.dirname(__FILE__), '..', '/app/views')
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module InstanceMethods
|
11
|
+
def show
|
12
|
+
redirect_to new_session_path
|
13
|
+
end
|
14
|
+
|
15
|
+
def new
|
16
|
+
end
|
17
|
+
|
18
|
+
def create
|
19
|
+
if user = User.authenticate(params[:email], params[:password])
|
20
|
+
user.logged_in
|
21
|
+
session[:user_id] = user.id
|
22
|
+
after_authentication(user)
|
23
|
+
redirect_back_or_default(login_redirect_to(user))
|
24
|
+
return
|
25
|
+
else
|
26
|
+
after_authentication_failure(user)
|
27
|
+
flash.now[:error] = "Couldn't log you in as '#{params[:email]}'"
|
28
|
+
render :action => 'new'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def destroy
|
33
|
+
session[:user_id] = nil
|
34
|
+
flash[:notice] = "You have been logged out."
|
35
|
+
redirect_to logout_redirect_to
|
36
|
+
end
|
37
|
+
|
38
|
+
#######
|
39
|
+
private
|
40
|
+
#######
|
41
|
+
|
42
|
+
def login_redirect_to(user)
|
43
|
+
'/'
|
44
|
+
end
|
45
|
+
|
46
|
+
def logout_redirect_to
|
47
|
+
'/'
|
48
|
+
end
|
49
|
+
|
50
|
+
def after_authentication(user)
|
51
|
+
# overide in application
|
52
|
+
end
|
53
|
+
|
54
|
+
def after_authentication_failure(user)
|
55
|
+
# overide in application
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Minimalist
|
2
|
+
module TestHelper
|
3
|
+
# Sets the current user in the session from the user fixtures.
|
4
|
+
def login_as(user)
|
5
|
+
@request.session[:user_id] = user ? users(user).id : nil
|
6
|
+
end
|
7
|
+
|
8
|
+
def current_user
|
9
|
+
@current_user ||= User.find(@request.session[:user_id])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.expand_path('../lib/minimalist/version', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "minimalist_authentication"
|
5
|
+
s.version = MinimalistAuthentication::VERSION
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.authors = ['Aaron Baldwin', 'Jonathan S. Garvin', 'WWIDEA, Inc']
|
8
|
+
s.email = ["developers@wwidea.org"]
|
9
|
+
s.homepage = "https://github.com/wwidea/minimalist_authentication"
|
10
|
+
s.summary = %q{A Rails authentication plugin that takes a minimalist approach.}
|
11
|
+
s.description = %q{A Rails authentication plugin that takes a minimalist approach. It is designed to be simple to understand, use, and modify for your application.}
|
12
|
+
s.files = `git ls-files`.split("\n")
|
13
|
+
s.test_files = `git ls-files -- test/*`.split("\n")
|
14
|
+
s.require_paths = ["lib"]
|
15
|
+
end
|
data/test/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
debug.log
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class AuthenticationTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
test "should not be able to set crypted_password through mass assignment" do
|
6
|
+
user = Factory(:user)
|
7
|
+
old_crypted_password = user.crypted_password
|
8
|
+
user.update_attributes(:crypted_password => 'should not work')
|
9
|
+
assert_equal(old_crypted_password, user.crypted_password)
|
10
|
+
end
|
11
|
+
|
12
|
+
test "should return active user" do
|
13
|
+
user = Factory(:user)
|
14
|
+
assert_equal([user], User.active)
|
15
|
+
end
|
16
|
+
|
17
|
+
test "should authenticate user" do
|
18
|
+
user = Factory(:user)
|
19
|
+
assert_equal(user, User.authenticate(user.email, 'password'))
|
20
|
+
end
|
21
|
+
|
22
|
+
test "should fail to authenticate when email is blank" do
|
23
|
+
user = Factory(:user)
|
24
|
+
assert_nil(User.authenticate('', 'password'))
|
25
|
+
end
|
26
|
+
|
27
|
+
test "should fail to authenticate when password is blank" do
|
28
|
+
user = Factory(:user)
|
29
|
+
assert_nil(User.authenticate(user.email, ''))
|
30
|
+
end
|
31
|
+
|
32
|
+
test "should fail to authenticate when user is not active" do
|
33
|
+
user = Factory(:user, :active => false)
|
34
|
+
assert_nil(User.authenticate(user.email, 'password'))
|
35
|
+
end
|
36
|
+
|
37
|
+
test "should fail to authenticate for incorrect password" do
|
38
|
+
user = Factory(:user)
|
39
|
+
assert_nil(User.authenticate(user.email, 'incorrect_password'))
|
40
|
+
end
|
41
|
+
|
42
|
+
test "should create salt and encrypted_password for new user" do
|
43
|
+
user = User.new(:email => 'test@testing.com', :password => 'testing')
|
44
|
+
assert(user.save)
|
45
|
+
assert_not_nil(user.salt)
|
46
|
+
assert_not_nil(user.crypted_password)
|
47
|
+
assert(user.authenticated?('testing'))
|
48
|
+
end
|
49
|
+
|
50
|
+
test "should update last_logged_in_at without updating updated_at timestamp" do
|
51
|
+
user = Factory(:user, :updated_at => 1.day.ago)
|
52
|
+
updated_at = user.updated_at
|
53
|
+
user.logged_in
|
54
|
+
assert(user.updated_at == updated_at)
|
55
|
+
end
|
56
|
+
|
57
|
+
test "guest should be guest" do
|
58
|
+
assert(User.guest.is_guest?)
|
59
|
+
end
|
60
|
+
|
61
|
+
test "should allow inactive user to pass validation without an email or password" do
|
62
|
+
assert(User.new.valid?)
|
63
|
+
end
|
64
|
+
|
65
|
+
test "should fail validation for active user without email" do
|
66
|
+
user = User.new(:active => true)
|
67
|
+
assert_equal(false, user.valid?)
|
68
|
+
assert(user.errors[:email])
|
69
|
+
end
|
70
|
+
|
71
|
+
test "should fail validation for active user without password" do
|
72
|
+
user = User.new(:active => true)
|
73
|
+
assert_equal(false, user.valid?)
|
74
|
+
assert(user.errors[:password])
|
75
|
+
end
|
76
|
+
|
77
|
+
test "should use latest digest version for new users" do
|
78
|
+
assert_equal(User::PREFERRED_DIGEST_VERSION,Factory(:user).using_digest_version)
|
79
|
+
end
|
80
|
+
|
81
|
+
test "should migrate legacy users to new digest version" do
|
82
|
+
#Setup a user using the old digest version.
|
83
|
+
#This wouldn't be necessary with fixtures.
|
84
|
+
legacy_user = User.create(:active => true, :email => 'legacy@user.com', :password => '123456', :password_confirmation => '123456')
|
85
|
+
legacy_user.password = nil
|
86
|
+
legacy_user.salt = 'my_salt'
|
87
|
+
legacy_user.crypted_password = User.secure_digest('my_password', 'my_salt', 1)
|
88
|
+
legacy_user.using_digest_version = nil
|
89
|
+
assert(legacy_user.save)
|
90
|
+
assert_equal(nil, legacy_user.reload.using_digest_version)
|
91
|
+
assert_equal('86f156baf9e4868e6dcf910b65775efdeaa347d8',legacy_user.crypted_password)
|
92
|
+
|
93
|
+
# Ok, now we can finally do the test.
|
94
|
+
legacy_crypted_password = legacy_user.crypted_password
|
95
|
+
assert(legacy_user.authenticated?('my_password'))
|
96
|
+
assert_equal(2,legacy_user.reload.using_digest_version)
|
97
|
+
assert_not_equal(legacy_crypted_password,legacy_user.crypted_password)
|
98
|
+
end
|
99
|
+
end
|