winton-authentication 1.0.0
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 +74 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +82 -0
- data/Rakefile +22 -0
- data/init.rb +7 -0
- data/lib/huberry/authentication/controller_methods.rb +61 -0
- data/lib/huberry/authentication/model_methods.rb +84 -0
- data/test/_controller_test.rb +114 -0
- data/test/_model_test.rb +99 -0
- data/test/helpers/table_test_helper.rb +25 -0
- data/test/helpers/user_test_helper.rb +11 -0
- data/test/init.rb +45 -0
- metadata +63 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
2008-06-23 - Sean Huber (shuber@huberry.com)
|
2
|
+
* Renamed authentication_message/redirect_path to unauthenticated_message/redirect_path
|
3
|
+
* logged_in? now accepts a block that will yield when true
|
4
|
+
|
5
|
+
2008-06-09 - Sean Huber (shuber@huberry.com)
|
6
|
+
* unauthenticated method stores request_uri in session[:return_to]
|
7
|
+
|
8
|
+
2008-06-09 - Sean Huber (shuber@huberry.com)
|
9
|
+
* Removed accidently left over hard coded logic from password_required?
|
10
|
+
|
11
|
+
2008-06-09 - Sean Huber (shuber@huberry.com)
|
12
|
+
* Reloading a model sets password_changed? to false
|
13
|
+
|
14
|
+
2008-06-05 - Sean Huber (shuber@huberry.com)
|
15
|
+
* Changed email addresses in CHANGELOG
|
16
|
+
|
17
|
+
2008-06-05 - Sean Huber (shuber@huberry.com)
|
18
|
+
* Added find_current_user functional tests
|
19
|
+
|
20
|
+
2008-06-05 - Sean Huber (shuber@huberry.com)
|
21
|
+
* Renamed test files
|
22
|
+
* find_current_user always returns current_user
|
23
|
+
|
24
|
+
2008-06-05 - Sean Huber (shuber@huberry.com)
|
25
|
+
* Renamed login_required to authentication_required
|
26
|
+
|
27
|
+
2008-06-05 - Sean Huber (shuber@huberry.com)
|
28
|
+
* Renamed @searched_for_current_user to @queried_for_current_user
|
29
|
+
|
30
|
+
2008-06-05 - Sean Huber (shuber@huberry.com)
|
31
|
+
* Added extra uses_authentication field options
|
32
|
+
* Updated README
|
33
|
+
|
34
|
+
2008-06-05 - Sean Huber (shuber@huberry.com)
|
35
|
+
* current_user returns nil unless logged_in?
|
36
|
+
* Updated README
|
37
|
+
|
38
|
+
2008-06-05 - Sean Huber (shuber@huberry.com)
|
39
|
+
* Updated README
|
40
|
+
|
41
|
+
2008-06-05 - Sean Huber (shuber@huberry.com)
|
42
|
+
* Updated README
|
43
|
+
|
44
|
+
2008-06-04 - Sean Huber (shuber@huberry.com)
|
45
|
+
* Updated README
|
46
|
+
|
47
|
+
2008-06-04 - Sean Huber (shuber@huberry.com)
|
48
|
+
* Updated README
|
49
|
+
|
50
|
+
2008-06-04 - Sean Huber (shuber@huberry.com)
|
51
|
+
* Controller no longer has to call uses_authentication - logic included automatically
|
52
|
+
* Updated README
|
53
|
+
|
54
|
+
2008-06-04 - Sean Huber (shuber@huberry.com)
|
55
|
+
* Updated README
|
56
|
+
|
57
|
+
2008-06-04 - Sean Huber (shuber@huberry.com)
|
58
|
+
* Updated README
|
59
|
+
|
60
|
+
2008-06-04 - Sean Huber (shuber@huberry.com)
|
61
|
+
* Updated README
|
62
|
+
|
63
|
+
2008-06-04 - Sean Huber (shuber@huberry.com)
|
64
|
+
* Added functional tests
|
65
|
+
|
66
|
+
2008-06-04 - Sean Huber (shuber@huberry.com)
|
67
|
+
* Fixed functional test exception
|
68
|
+
|
69
|
+
2008-06-04 - Sean Huber (shuber@huberry.com)
|
70
|
+
* Controller and model must call uses_authentication
|
71
|
+
|
72
|
+
2008-06-04 - Sean Huber (shuber@huberry.com)
|
73
|
+
* Initial import from access_control_list repository
|
74
|
+
* Login field is configurable
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Sean Huber (shuber@huberry.com)
|
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.markdown
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
Huberry::Authentication
|
2
|
+
=======================
|
3
|
+
|
4
|
+
A rails plugin that handles authentication
|
5
|
+
|
6
|
+
|
7
|
+
Installation
|
8
|
+
------------
|
9
|
+
|
10
|
+
script/plugin install git://github.com/shuber/authentication.git
|
11
|
+
|
12
|
+
|
13
|
+
Example
|
14
|
+
-------
|
15
|
+
|
16
|
+
class User < ActiveRecord::Base
|
17
|
+
# Accepts an optional hash of options
|
18
|
+
# :login_field - The field to use for logins (e.g. username or email) (defaults to :email)
|
19
|
+
# :password_field - (defaults to :password)
|
20
|
+
# :hashed_password_field - (defaults to :hashed_password)
|
21
|
+
# :salt_field - (defaults to :salt)
|
22
|
+
uses_authentication :login_field => :username
|
23
|
+
end
|
24
|
+
|
25
|
+
class ApplicationController < ActionController::Base
|
26
|
+
# Set optional authentication options here
|
27
|
+
# self.authentication_model = The model that uses authentication (defaults to 'User')
|
28
|
+
# self.unauthenticated_message = The error flash message to set when unauthenticated (defaults to 'Login to continue')
|
29
|
+
# self.unauthenticated_redirect_path = The path to redirect to when unauthenticated (can be a symbol of a method) (defaults to '/')
|
30
|
+
end
|
31
|
+
|
32
|
+
class UsersController < ApplicationController
|
33
|
+
before_filter :login_required, :only => [:index]
|
34
|
+
|
35
|
+
def index
|
36
|
+
render :text => 'test'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
Controller Methods
|
42
|
+
------------------
|
43
|
+
|
44
|
+
# Returns the current user or nil if a user is not logged in
|
45
|
+
current_user
|
46
|
+
|
47
|
+
# Checks if the current user is authenticated (optionaly accepts a block that is yielded when true)
|
48
|
+
logged_in?
|
49
|
+
|
50
|
+
# Login a user
|
51
|
+
login(user)
|
52
|
+
|
53
|
+
# A before filter to require authentication - redirects to the controller class's authentication_redirect_path if unauthenticated
|
54
|
+
login_required
|
55
|
+
|
56
|
+
# Logout the current user
|
57
|
+
logout
|
58
|
+
|
59
|
+
|
60
|
+
Model Methods
|
61
|
+
-------------
|
62
|
+
|
63
|
+
# Class method that authenticates a user based on a login and password - returns a user instance or false
|
64
|
+
User.authenticate(login, password)
|
65
|
+
|
66
|
+
# Checks if the password passed to it matches the current user instance's password
|
67
|
+
authenticated?(password)
|
68
|
+
|
69
|
+
# Checks if the current user instance's password has just been changed
|
70
|
+
password_changed?
|
71
|
+
|
72
|
+
# Resets the password - will generate a new random password if one is not specified
|
73
|
+
reset_password(new_password = nil)
|
74
|
+
|
75
|
+
# Resets the password and saves - will generate a new random password if one is not specified
|
76
|
+
reset_password!(new_password = nil)
|
77
|
+
|
78
|
+
|
79
|
+
Contact
|
80
|
+
-------
|
81
|
+
|
82
|
+
Problems, comments, and suggestions all welcome: [shuber@huberry.com](mailto:shuber@huberry.com)
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run the authentication tests'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the authentication 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 the authentication plugin.'
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'Authentication'
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
+
rdoc.rdoc_files.include('README')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
require 'huberry/authentication/controller_methods'
|
2
|
+
require 'huberry/authentication/model_methods'
|
3
|
+
|
4
|
+
ActionController::Base.extend Huberry::Authentication::ControllerMethods
|
5
|
+
ActiveRecord::Base.extend Huberry::Authentication::ModelMethods
|
6
|
+
|
7
|
+
$:.unshift File.dirname(__FILE__) + '/lib'
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Huberry
|
2
|
+
module Authentication
|
3
|
+
module ControllerMethods
|
4
|
+
def self.extended(base)
|
5
|
+
base.class_eval do
|
6
|
+
include InstanceMethods
|
7
|
+
|
8
|
+
cattr_accessor :authentication_model, :unauthenticated_message, :unauthenticated_redirect_path
|
9
|
+
self.authentication_model = 'User'
|
10
|
+
self.unauthenticated_message = 'Login to continue'
|
11
|
+
self.unauthenticated_redirect_path = '/'
|
12
|
+
|
13
|
+
attr_accessor :current_user
|
14
|
+
helper_method :current_user, :logged_in?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module InstanceMethods
|
19
|
+
protected
|
20
|
+
|
21
|
+
def authentication_required
|
22
|
+
unauthenticated unless logged_in?
|
23
|
+
end
|
24
|
+
|
25
|
+
def find_current_user(force_query = false)
|
26
|
+
if @queried_for_current_user.nil? || force_query
|
27
|
+
@queried_for_current_user = true
|
28
|
+
self.current_user = self.class.authentication_model.to_s.constantize.find(session[:user_id]) rescue nil
|
29
|
+
end
|
30
|
+
self.current_user
|
31
|
+
end
|
32
|
+
|
33
|
+
def logged_in?
|
34
|
+
find_current_user if self.current_user.nil?
|
35
|
+
if self.current_user.nil?
|
36
|
+
block_given? ? nil : false
|
37
|
+
else
|
38
|
+
block_given? ? yield : true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def login(user)
|
43
|
+
self.current_user = user
|
44
|
+
session[:user_id] = user.id
|
45
|
+
end
|
46
|
+
|
47
|
+
def logout
|
48
|
+
self.current_user = nil
|
49
|
+
session[:user_id] = nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def unauthenticated
|
53
|
+
session[:return_to] = request.request_uri
|
54
|
+
flash[:error] = self.class.unauthenticated_message.to_s
|
55
|
+
redirect_to respond_to?(self.class.unauthenticated_redirect_path) ? send(self.class.unauthenticated_redirect_path) : self.class.unauthenticated_redirect_path.to_s
|
56
|
+
false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'digest/sha2'
|
2
|
+
|
3
|
+
module Huberry
|
4
|
+
module Authentication
|
5
|
+
module ModelMethods
|
6
|
+
def uses_authentication(options = {})
|
7
|
+
extend ClassMethods
|
8
|
+
include InstanceMethods
|
9
|
+
|
10
|
+
cattr_accessor :hashed_password_field, :login_field, :password_field, :salt_field
|
11
|
+
self.hashed_password_field = options[:hashed_password_field] || :hashed_password
|
12
|
+
self.login_field = options[:login_field] || :email
|
13
|
+
self.password_field = options[:password_field] || :password
|
14
|
+
self.salt_field = options[:salt_field] || :salt
|
15
|
+
|
16
|
+
attr_accessor self.password_field, "#{self.password_field}_confirmation".to_sym
|
17
|
+
|
18
|
+
validates_presence_of self.login_field
|
19
|
+
validates_presence_of self.password_field, :if => :password_required?
|
20
|
+
validates_confirmation_of self.password_field, :if => :password_required?
|
21
|
+
|
22
|
+
before_save :hash_password
|
23
|
+
|
24
|
+
alias_method_chain :reload, :authentication
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module ClassMethods
|
29
|
+
def authenticate(login, password)
|
30
|
+
user = send("find_by_#{self.login_field}", login)
|
31
|
+
user && user.authenticated?(password) ? user : false
|
32
|
+
end
|
33
|
+
|
34
|
+
def digest(str)
|
35
|
+
Digest::SHA256.hexdigest(str.to_s)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
module InstanceMethods
|
40
|
+
def authenticated?(password)
|
41
|
+
send(self.class.hashed_password_field) == self.class.digest(password.to_s + send(self.class.salt_field).to_s)
|
42
|
+
end
|
43
|
+
|
44
|
+
def password_changed?
|
45
|
+
!!@password_changed
|
46
|
+
end
|
47
|
+
|
48
|
+
def reload_with_authentication(*args)
|
49
|
+
reload_without_authentication(*args)
|
50
|
+
@password_changed = false
|
51
|
+
end
|
52
|
+
|
53
|
+
def reset_password(new_password = nil)
|
54
|
+
new_password = generate_salt[0..7] if new_password.blank?
|
55
|
+
send("#{self.class.salt_field}=", nil)
|
56
|
+
send("#{self.class.password_field}=", new_password)
|
57
|
+
send("#{self.class.password_field}_confirmation=", new_password)
|
58
|
+
@password_changed = true
|
59
|
+
end
|
60
|
+
|
61
|
+
def reset_password!(new_password = nil)
|
62
|
+
reset_password(new_password)
|
63
|
+
save
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
|
68
|
+
def generate_salt
|
69
|
+
self.class.digest("--#{Time.now}--#{rand}--")
|
70
|
+
end
|
71
|
+
|
72
|
+
def hash_password
|
73
|
+
if password_changed? || password_required?
|
74
|
+
send("#{self.class.salt_field}=", generate_salt) if send("#{self.class.salt_field}").blank?
|
75
|
+
send("#{self.class.hashed_password_field}=", self.class.digest(send(self.class.password_field).to_s + send(self.class.salt_field).to_s))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def password_required?
|
80
|
+
send(self.class.hashed_password_field).blank? || !send(self.class.password_field).blank?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/init'
|
2
|
+
|
3
|
+
class TestController < ActionController::Base
|
4
|
+
before_filter :authentication_required, :only => :login_required
|
5
|
+
|
6
|
+
def login_required
|
7
|
+
render :text => 'test'
|
8
|
+
end
|
9
|
+
|
10
|
+
def login_not_required
|
11
|
+
render :text => 'test'
|
12
|
+
end
|
13
|
+
|
14
|
+
def rescue_action(e)
|
15
|
+
raise e
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
ActionController::Routing::Routes.append do |map|
|
20
|
+
map.connect 'login_required', :controller => 'test', :action => 'login_required'
|
21
|
+
map.connect 'login_not_required', :controller => 'test', :action => 'login_not_required'
|
22
|
+
end
|
23
|
+
|
24
|
+
class ControllerTest < Test::Unit::TestCase
|
25
|
+
|
26
|
+
def setup
|
27
|
+
create_users_table
|
28
|
+
@user = create_user
|
29
|
+
|
30
|
+
@controller = TestController.new
|
31
|
+
@request = ActionController::TestRequest.new
|
32
|
+
@response = ActionController::TestResponse.new
|
33
|
+
|
34
|
+
@controller.instance_variable_set('@_session', @request.session)
|
35
|
+
end
|
36
|
+
|
37
|
+
def teardown
|
38
|
+
drop_all_tables
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_logged_in?
|
42
|
+
assert !@controller.send(:logged_in?)
|
43
|
+
|
44
|
+
@controller.send :login, @user
|
45
|
+
assert @controller.send(:logged_in?)
|
46
|
+
|
47
|
+
@controller.send :logout
|
48
|
+
assert !@controller.send(:logged_in?)
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_logged_in_yields_block_on_true
|
52
|
+
assert_equal nil, @controller.send(:logged_in?) { 'some_value' }
|
53
|
+
|
54
|
+
@controller.send :login, @user
|
55
|
+
assert_equal 'some_value', @controller.send(:logged_in?) { 'some_value' }
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_current_user
|
59
|
+
assert_nil @controller.send(:current_user)
|
60
|
+
|
61
|
+
@controller.send :login, @user
|
62
|
+
assert_equal @user, @controller.send(:current_user)
|
63
|
+
|
64
|
+
@controller.send :logout
|
65
|
+
assert_nil @controller.send(:current_user)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_should_require_login
|
69
|
+
get :login_required
|
70
|
+
assert_response :redirect
|
71
|
+
assert flash.has_key?(:error)
|
72
|
+
assert_equal @controller.unauthenticated_message, flash[:error]
|
73
|
+
assert_redirected_to '/'
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_should_not_require_login
|
77
|
+
get :login_not_required
|
78
|
+
assert_response :success
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_should_login_and_get_authentication_required
|
82
|
+
@controller.send :login, @user
|
83
|
+
get :login_required
|
84
|
+
assert_response :success
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_find_current_user_with_valid_user
|
88
|
+
@request.session[:user_id] = @user.id
|
89
|
+
assert_equal @user, @controller.send(:find_current_user)
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_find_current_user_with_nil_user
|
93
|
+
assert_nil @controller.send(:find_current_user)
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_find_current_user_with_invalid_user
|
97
|
+
@request.session[:user_id] = 2
|
98
|
+
assert_nil @controller.send(:find_current_user)
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_find_current_user_force_query
|
102
|
+
assert_nil @controller.send(:find_current_user)
|
103
|
+
|
104
|
+
@request.session[:user_id] = @user.id
|
105
|
+
assert_nil @controller.send(:find_current_user)
|
106
|
+
assert_equal @user, @controller.send(:find_current_user, true)
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_unauthenticated_sets_return_to_session_variable
|
110
|
+
get :login_required
|
111
|
+
assert_equal @controller.session[:return_to], '/login_required'
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
data/test/_model_test.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/init'
|
2
|
+
|
3
|
+
class ModelTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
create_users_table
|
7
|
+
end
|
8
|
+
|
9
|
+
def teardown
|
10
|
+
drop_all_tables
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_should_create_user
|
14
|
+
assert_difference 'User.count' do
|
15
|
+
create_user
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_should_not_create_without_email
|
20
|
+
assert_no_difference 'User.count' do
|
21
|
+
@user = create_user :email => ''
|
22
|
+
end
|
23
|
+
assert @user.errors.on(:email)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_should_not_create_without_password
|
27
|
+
assert_no_difference 'User.count' do
|
28
|
+
@user = create_user :password => ''
|
29
|
+
end
|
30
|
+
assert @user.errors.on(:password)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_should_not_create_without_password_confirmation
|
34
|
+
assert_no_difference 'User.count' do
|
35
|
+
@user = create_user :password_confirmation => ''
|
36
|
+
end
|
37
|
+
assert @user.errors.on(:password)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_should_generate_salt_on_create
|
41
|
+
@user = create_user
|
42
|
+
assert !@user.salt.blank?
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_should_hash_password_on_create
|
46
|
+
@user = create_user
|
47
|
+
assert !@user.hashed_password.blank?
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_should_destroy
|
51
|
+
@user = create_user
|
52
|
+
assert_difference 'User.count', -1 do
|
53
|
+
@user.destroy
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_should_authenticate
|
58
|
+
@user = create_user
|
59
|
+
assert_equal @user, User.authenticate(@user.email, @user.password)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_should_not_authenticate_with_invalid_email
|
63
|
+
@user = create_user
|
64
|
+
assert !User.authenticate('invalid', @user.password)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_should_not_authenticate_with_invalid_password
|
68
|
+
@user = create_user
|
69
|
+
assert !User.authenticate(@user.email, 'invalid')
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_should_reset_password
|
73
|
+
@user = create_user
|
74
|
+
assert !@user.password_changed?
|
75
|
+
old_password = @user.password
|
76
|
+
|
77
|
+
@user.reset_password('new_password')
|
78
|
+
assert_not_equal 'new_password', old_password
|
79
|
+
assert_equal 'new_password', @user.password
|
80
|
+
assert @user.password_changed?
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_should_reset_password!
|
84
|
+
@user = create_user
|
85
|
+
assert @user.reset_password!('new_password')
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_reload_should_set_password_changed_to_false
|
89
|
+
@user = create_user
|
90
|
+
assert !@user.password_changed?
|
91
|
+
|
92
|
+
@user.reset_password!('new_password')
|
93
|
+
assert @user.password_changed?
|
94
|
+
|
95
|
+
@user.reload
|
96
|
+
assert !@user.password_changed?
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module TableTestHelper
|
2
|
+
|
3
|
+
def create_users_table
|
4
|
+
silence_stream(STDOUT) do
|
5
|
+
ActiveRecord::Schema.define(:version => 1) do
|
6
|
+
create_table :users do |t|
|
7
|
+
t.string :email
|
8
|
+
t.string :hashed_password
|
9
|
+
t.string :salt
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def drop_all_tables
|
16
|
+
ActiveRecord::Base.connection.tables.each do |table|
|
17
|
+
drop_table(table)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def drop_table(table)
|
22
|
+
ActiveRecord::Base.connection.drop_table(table)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/test/init.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
$:.reject! { |path| path.include? 'TextMate' }
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
# Require and include test helpers
|
5
|
+
#
|
6
|
+
Dir[File.join(File.dirname(__FILE__), 'helpers', '*_test_helper.rb')].each do |helper|
|
7
|
+
require helper
|
8
|
+
/(.*?)_test_helper\.rb/.match File.basename(helper)
|
9
|
+
class_name = $1.split('_').collect{ |name| name.downcase.capitalize }.join('') + 'TestHelper'
|
10
|
+
Test::Unit::TestCase.send :include, Object.const_get(class_name) if Object.const_defined?(class_name)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Load ActiveRecord
|
14
|
+
#
|
15
|
+
require 'rubygems'
|
16
|
+
gem 'activerecord'
|
17
|
+
require 'active_record'
|
18
|
+
ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :dbfile => ':memory:'
|
19
|
+
|
20
|
+
# Load ActionPack
|
21
|
+
#
|
22
|
+
gem 'actionpack'
|
23
|
+
require 'action_pack'
|
24
|
+
require 'action_controller'
|
25
|
+
require 'action_controller/routing'
|
26
|
+
require 'action_controller/assertions'
|
27
|
+
require 'action_controller/test_process'
|
28
|
+
|
29
|
+
# Routing
|
30
|
+
#
|
31
|
+
class ActionController::Routing::RouteSet
|
32
|
+
def append
|
33
|
+
yield Mapper.new(self)
|
34
|
+
install_helpers
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Require the main init.rb for the plugin
|
39
|
+
#
|
40
|
+
require File.join(File.dirname(File.dirname(__FILE__)), 'init')
|
41
|
+
|
42
|
+
# Basic user class
|
43
|
+
class User < ActiveRecord::Base
|
44
|
+
uses_authentication
|
45
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: winton-authentication
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sean Huber
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-08-16 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A rails plugin that handles authentication
|
17
|
+
email: shuber@huberry.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- CHANGELOG
|
26
|
+
- init.rb
|
27
|
+
- lib/huberry/authentication/controller_methods.rb
|
28
|
+
- lib/huberry/authentication/model_methods.rb
|
29
|
+
- MIT-LICENSE
|
30
|
+
- Rakefile
|
31
|
+
- README.markdown
|
32
|
+
has_rdoc: false
|
33
|
+
homepage: http://github.com/shuber/authentication
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
requirements: []
|
52
|
+
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 1.2.0
|
55
|
+
signing_key:
|
56
|
+
specification_version: 2
|
57
|
+
summary: A rails plugin that handles authentication
|
58
|
+
test_files:
|
59
|
+
- test/_controller_test.rb
|
60
|
+
- test/_model_test.rb
|
61
|
+
- test/helpers/table_test_helper.rb
|
62
|
+
- test/helpers/user_test_helper.rb
|
63
|
+
- test/init.rb
|