minimalist_authentication 0.5
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/.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
|