sorcery 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sorcery might be problematic. Click here for more details.
- data/Gemfile +1 -2
- data/LICENSE.txt +1 -1
- data/README.rdoc +27 -11
- data/Rakefile +2 -13
- data/VERSION +1 -1
- data/lib/sorcery.rb +4 -1
- data/lib/sorcery/controller.rb +13 -7
- data/lib/sorcery/controller/submodules/activity_logging.rb +45 -0
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +8 -69
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +7 -4
- data/lib/sorcery/controller/submodules/session_timeout.rb +4 -1
- data/lib/sorcery/crypto_providers/bcrypt.rb +1 -5
- data/lib/sorcery/model/submodules/activity_logging.rb +35 -0
- data/lib/sorcery/model/submodules/brute_force_protection.rb +72 -0
- data/lib/sorcery/model/submodules/remember_me.rb +3 -1
- data/lib/sorcery/model/submodules/reset_password.rb +93 -0
- data/lib/sorcery/model/submodules/user_activation.rb +2 -0
- data/sorcery.gemspec +26 -14
- data/spec/rails3/app_root/app/controllers/application_controller.rb +2 -2
- data/spec/rails3/app_root/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +17 -0
- data/spec/rails3/app_root/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +11 -0
- data/spec/rails3/app_root/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +13 -0
- data/spec/rails3/controller_activity_logging_spec.rb +84 -0
- data/spec/rails3/controller_brute_force_protection_spec.rb +24 -41
- data/spec/rails3/controller_http_basic_auth_spec.rb +10 -0
- data/spec/rails3/controller_session_timeout_spec.rb +1 -0
- data/spec/rails3/controller_spec.rb +3 -3
- data/spec/rails3/spec_helper.rb +39 -19
- data/spec/rails3/user_activity_logging_spec.rb +36 -0
- data/spec/rails3/user_brute_force_protection_spec.rb +76 -0
- data/spec/rails3/user_reset_password_spec.rb +198 -0
- metadata +34 -22
- data/features/support/env.rb +0 -13
- data/lib/sorcery/model/submodules/password_reset.rb +0 -64
- data/spec/rails3/app_root/db/migrate/password_reset/20101224223622_add_password_reset_to_users.rb +0 -9
- data/spec/rails3/user_password_reset_spec.rb +0 -76
@@ -1,6 +1,13 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
3
|
describe ApplicationController do
|
4
|
+
before(:all) do
|
5
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/brute_force_protection")
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:all) do
|
9
|
+
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/brute_force_protection")
|
10
|
+
end
|
4
11
|
|
5
12
|
# ----------------- SESSION TIMEOUT -----------------------
|
6
13
|
describe ApplicationController, "with brute force protection features" do
|
@@ -14,59 +21,35 @@ describe ApplicationController do
|
|
14
21
|
plugin_set_controller_config_property(:user_class, User)
|
15
22
|
end
|
16
23
|
|
17
|
-
it "should
|
18
|
-
plugin_set_controller_config_property(:login_retries_amount_allowed, 32)
|
19
|
-
Sorcery::Controller::Config.login_retries_amount_allowed.should equal(32)
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should have configuration for 'login_retries_counter_reset_time'" do
|
23
|
-
plugin_set_controller_config_property(:login_retries_time_period, 32)
|
24
|
-
Sorcery::Controller::Config.login_retries_time_period.should equal(32)
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should count login retries per session" do
|
24
|
+
it "should count login retries" do
|
28
25
|
3.times {get :test_login, :username => 'gizmo', :password => 'blabla'}
|
29
|
-
|
26
|
+
User.find_by_username('gizmo').failed_logins_count.should == 3
|
30
27
|
end
|
31
28
|
|
32
|
-
it "should reset the counter
|
33
|
-
|
34
|
-
|
35
|
-
get :test_login, :username => 'gizmo', :password => '
|
36
|
-
|
37
|
-
get :test_login, :username => 'gizmo', :password => 'blabla'
|
38
|
-
session[:failed_logins].should == 1
|
29
|
+
it "should reset the counter on a good login" do
|
30
|
+
plugin_set_model_config_property(:consecutive_login_retries_amount_allowed, 5)
|
31
|
+
3.times {get :test_login, :username => 'gizmo', :password => 'blabla'}
|
32
|
+
get :test_login, :username => 'gizmo', :password => 'secret'
|
33
|
+
User.find_by_username('gizmo').failed_logins_count.should == 0
|
39
34
|
end
|
40
35
|
|
41
|
-
it "should
|
42
|
-
|
43
|
-
|
44
|
-
get :test_login, :username => 'gizmo', :password => 'blabla'
|
36
|
+
it "should lock user when number of retries reached the limit" do
|
37
|
+
User.find_by_username('gizmo').lock_expires_at.should be_nil
|
38
|
+
plugin_set_model_config_property(:consecutive_login_retries_amount_allowed, 1)
|
45
39
|
get :test_login, :username => 'gizmo', :password => 'blabla'
|
46
|
-
|
40
|
+
User.find_by_username('gizmo').lock_expires_at.should_not be_nil
|
47
41
|
end
|
48
42
|
|
49
|
-
it "should
|
50
|
-
|
51
|
-
|
52
|
-
plugin_set_controller_config_property(:login_ban_time_period, 0.2)
|
43
|
+
it "should unlock after lock time period passes" do
|
44
|
+
plugin_set_model_config_property(:consecutive_login_retries_amount_allowed, 2)
|
45
|
+
plugin_set_model_config_property(:login_lock_time_period, 0.2)
|
53
46
|
get :test_login, :username => 'gizmo', :password => 'blabla'
|
54
47
|
get :test_login, :username => 'gizmo', :password => 'blabla'
|
55
|
-
|
48
|
+
User.find_by_username('gizmo').lock_expires_at.should_not be_nil
|
56
49
|
sleep 0.3
|
57
50
|
get :test_login, :username => 'gizmo', :password => 'blabla'
|
58
|
-
|
59
|
-
end
|
60
|
-
|
61
|
-
it "banned session calls the configured banned action" do
|
62
|
-
plugin_set_controller_config_property(:login_retries_amount_allowed, 1)
|
63
|
-
plugin_set_controller_config_property(:login_retries_time_period, 50)
|
64
|
-
plugin_set_controller_config_property(:login_ban_time_period, 50)
|
65
|
-
get :test_login, :username => 'gizmo', :password => 'blabla'
|
66
|
-
get :test_login, :username => 'gizmo', :password => 'blabla'
|
67
|
-
get :test_login, :username => 'gizmo', :password => 'blabla'
|
68
|
-
session[:banned].should == true
|
69
|
-
response.body.should == " "
|
51
|
+
User.find_by_username('gizmo').lock_expires_at.should be_nil
|
70
52
|
end
|
53
|
+
|
71
54
|
end
|
72
55
|
end
|
@@ -9,6 +9,10 @@ describe ApplicationController do
|
|
9
9
|
create_new_user
|
10
10
|
end
|
11
11
|
|
12
|
+
after(:each) do
|
13
|
+
logout_user
|
14
|
+
end
|
15
|
+
|
12
16
|
it "requests basic authentication when before_filter is used" do
|
13
17
|
get :test_http_basic_auth
|
14
18
|
response.code.should == "401"
|
@@ -36,5 +40,11 @@ describe ApplicationController do
|
|
36
40
|
get :test_http_basic_auth
|
37
41
|
response.headers["WWW-Authenticate"].should == "Basic realm=\"Salad\""
|
38
42
|
end
|
43
|
+
|
44
|
+
it "should sign in the user's session on successful login" do
|
45
|
+
@request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("#{@user.username}:secret")
|
46
|
+
get :test_http_basic_auth, nil, :http_authentication_used => true
|
47
|
+
session[:user_id].should == User.find_by_username(@user.username).id
|
48
|
+
end
|
39
49
|
end
|
40
50
|
end
|
@@ -93,8 +93,8 @@ describe ApplicationController do
|
|
93
93
|
subject.logged_in_user.should == false
|
94
94
|
end
|
95
95
|
|
96
|
-
it "should respond to '
|
97
|
-
should respond_to(:
|
96
|
+
it "should respond to 'require_login'" do
|
97
|
+
should respond_to(:require_login)
|
98
98
|
end
|
99
99
|
|
100
100
|
it "should call the configured 'not_authenticated_action' when authenticate before_filter fails" do
|
@@ -104,7 +104,7 @@ describe ApplicationController do
|
|
104
104
|
response.body.should == "test_not_authenticated_action"
|
105
105
|
end
|
106
106
|
|
107
|
-
it "
|
107
|
+
it "require_login before_filter should save the url that the user originally wanted" do
|
108
108
|
get :some_action
|
109
109
|
session[:user_wanted_url].should == "http://test.host/some_action"
|
110
110
|
response.should redirect_to("http://test.host/")
|
data/spec/rails3/spec_helper.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
$: << File.join(File.dirname(__FILE__), '..', '..', 'lib' )
|
2
2
|
|
3
|
-
require 'simplecov'
|
4
|
-
SimpleCov.root File.join(File.dirname(__FILE__), "app_root" )
|
5
|
-
SimpleCov.start do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
3
|
+
# require 'simplecov'
|
4
|
+
# SimpleCov.root File.join(File.dirname(__FILE__), "app_root" )
|
5
|
+
# SimpleCov.start do
|
6
|
+
# add_filter "/config/"
|
7
|
+
#
|
8
|
+
# add_group 'Controllers', 'app/controllers'
|
9
|
+
# add_group 'Models', 'app/models'
|
10
|
+
# add_group 'Helpers', 'app/helpers'
|
11
|
+
# add_group 'Libraries', 'lib'
|
12
|
+
# add_group 'Plugins', 'vendor/plugins'
|
13
|
+
# add_group 'Migrations', 'db/migrate'
|
14
|
+
# end
|
15
15
|
|
16
16
|
# Set the default environment to sqlite3's in_memory database
|
17
17
|
ENV['RAILS_ENV'] ||= 'in_memory'
|
@@ -41,7 +41,8 @@ RSpec.configure do |config|
|
|
41
41
|
end
|
42
42
|
|
43
43
|
#----------------------------------------------------------------
|
44
|
-
#
|
44
|
+
# needed when running individual specs
|
45
|
+
require File.join(File.dirname(__FILE__), 'app_root','app','models','user')
|
45
46
|
|
46
47
|
class TestUser < ActiveRecord::Base
|
47
48
|
activate_sorcery!
|
@@ -62,15 +63,27 @@ module Sorcery
|
|
62
63
|
end
|
63
64
|
end
|
64
65
|
|
65
|
-
|
66
|
-
|
66
|
+
SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS = [:register_last_activity_time_to_db, :deny_banned_user, :validate_session]
|
67
|
+
|
68
|
+
def create_new_user(attributes_hash = nil)
|
69
|
+
user_attributes_hash = attributes_hash || {:username => 'gizmo', :email => "bla@bla.com", :password => 'secret'}
|
67
70
|
@user = User.new(user_attributes_hash)
|
68
71
|
@user.save!
|
72
|
+
@user
|
73
|
+
end
|
74
|
+
|
75
|
+
def login_user(user = nil)
|
76
|
+
user ||= @user
|
77
|
+
subject.send(:login_user,user)
|
78
|
+
subject.send(:after_login!,user,[user.username,'secret'])
|
79
|
+
end
|
80
|
+
|
81
|
+
def logout_user
|
82
|
+
subject.send(:logout)
|
69
83
|
end
|
70
84
|
|
71
|
-
def
|
72
|
-
subject.
|
73
|
-
subject.send(:after_login!,@user,['gizmo','secret'])
|
85
|
+
def clear_user_without_logout
|
86
|
+
subject.instance_variable_set(:@logged_in_user,nil)
|
74
87
|
end
|
75
88
|
|
76
89
|
# TODO: rename to sorcery_reload!(subs = [], model_opts = {}, controller_opts = {})
|
@@ -81,10 +94,15 @@ def plugin_model_configure(submodules = [], options = {})
|
|
81
94
|
::Sorcery::Controller::Config.init!
|
82
95
|
::Sorcery::Controller::Config.reset!
|
83
96
|
|
97
|
+
# remove all plugin before_filters so they won't fail other tests.
|
98
|
+
# I don't like this way, but I didn't find another.
|
99
|
+
# hopefully it won't break until Rails 4.
|
100
|
+
ApplicationController._process_action_callbacks.delete_if {|c| SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS.include?(c.filter) }
|
101
|
+
|
84
102
|
# configure
|
85
103
|
::Sorcery::Controller::Config.submodules = submodules
|
86
104
|
::Sorcery::Controller::Config.user_class = nil # the next line will reset it to User
|
87
|
-
|
105
|
+
ActionController::Base.send(:include,::Sorcery::Controller)
|
88
106
|
|
89
107
|
User.activate_sorcery! do |config|
|
90
108
|
options.each do |property,value|
|
@@ -109,6 +127,8 @@ end
|
|
109
127
|
|
110
128
|
private
|
111
129
|
|
130
|
+
# reload user class between specs
|
131
|
+
# so it will be possible to test the different submodules in isolation
|
112
132
|
def reload_user_class
|
113
133
|
Object.send(:remove_const,:User)
|
114
134
|
load 'user.rb'
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "User with activity logging submodule" do
|
4
|
+
before(:all) do
|
5
|
+
end
|
6
|
+
|
7
|
+
after(:all) do
|
8
|
+
end
|
9
|
+
|
10
|
+
# ----------------- PLUGIN CONFIGURATION -----------------------
|
11
|
+
describe User, "loaded plugin configuration" do
|
12
|
+
before(:all) do
|
13
|
+
plugin_model_configure([:activity_logging])
|
14
|
+
end
|
15
|
+
|
16
|
+
after(:each) do
|
17
|
+
User.sorcery_config.reset!
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should allow configuration option 'last_login_at_attribute_name'" do
|
21
|
+
plugin_set_model_config_property(:last_login_at_attribute_name, :login_time)
|
22
|
+
User.sorcery_config.last_login_at_attribute_name.should equal(:login_time)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should allow configuration option 'last_logout_at_attribute_name'" do
|
26
|
+
plugin_set_model_config_property(:last_logout_at_attribute_name, :logout_time)
|
27
|
+
User.sorcery_config.last_logout_at_attribute_name.should equal(:logout_time)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should allow configuration option 'last_activity_at_attribute_name'" do
|
31
|
+
plugin_set_model_config_property(:last_activity_at_attribute_name, :activity_time)
|
32
|
+
User.sorcery_config.last_activity_at_attribute_name.should equal(:activity_time)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "User with brute_force_protection submodule" do
|
4
|
+
before(:all) do
|
5
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/brute_force_protection")
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:all) do
|
9
|
+
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/brute_force_protection")
|
10
|
+
end
|
11
|
+
|
12
|
+
# ----------------- PLUGIN CONFIGURATION -----------------------
|
13
|
+
describe User, "loaded plugin configuration" do
|
14
|
+
|
15
|
+
before(:all) do
|
16
|
+
plugin_model_configure([:brute_force_protection])
|
17
|
+
create_new_user
|
18
|
+
end
|
19
|
+
|
20
|
+
after(:each) do
|
21
|
+
User.sorcery_config.reset!
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should respond to 'failed_logins_count'" do
|
25
|
+
@user.should respond_to(:failed_logins_count)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should respond to 'lock_expires_at'" do
|
29
|
+
@user.should respond_to(:failed_logins_count)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should enable configuration option 'failed_logins_count_attribute_name'" do
|
33
|
+
plugin_set_model_config_property(:failed_logins_count_attribute_name, :my_count)
|
34
|
+
User.sorcery_config.failed_logins_count_attribute_name.should equal(:my_count)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should enable configuration option 'lock_expires_at_attribute_name'" do
|
38
|
+
plugin_set_model_config_property(:lock_expires_at_attribute_name, :expires)
|
39
|
+
User.sorcery_config.lock_expires_at_attribute_name.should equal(:expires)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should enable configuration option 'consecutive_login_retries_amount_allowed'" do
|
43
|
+
plugin_set_model_config_property(:consecutive_login_retries_amount_allowed, 34)
|
44
|
+
User.sorcery_config.consecutive_login_retries_amount_allowed.should equal(34)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should enable configuration option 'login_lock_time_period'" do
|
48
|
+
plugin_set_model_config_property(:login_lock_time_period, 2.hours)
|
49
|
+
User.sorcery_config.login_lock_time_period.should == 2.hours
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# ----------------- PLUGIN ACTIVATED -----------------------
|
54
|
+
describe User, "when activated with sorcery" do
|
55
|
+
|
56
|
+
before(:all) do
|
57
|
+
plugin_model_configure([:brute_force_protection])
|
58
|
+
end
|
59
|
+
|
60
|
+
before(:each) do
|
61
|
+
User.delete_all
|
62
|
+
end
|
63
|
+
|
64
|
+
# it "should increment failed_logins_count on a failed login" do
|
65
|
+
# create_new_user
|
66
|
+
#
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
# it "should set lock expiry (effectively lock user) when failed_logins_count reaches max within max period" do
|
70
|
+
# create_new_user
|
71
|
+
# @user.lock_expires_at.should == Time.now.utc + 30
|
72
|
+
# end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "User with reset_password submodule" do
|
4
|
+
before(:all) do
|
5
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/reset_password")
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:all) do
|
9
|
+
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/reset_password")
|
10
|
+
end
|
11
|
+
|
12
|
+
# ----------------- PLUGIN CONFIGURATION -----------------------
|
13
|
+
describe User, "loaded plugin configuration" do
|
14
|
+
|
15
|
+
before(:all) do
|
16
|
+
plugin_model_configure([:reset_password], :reset_password_mailer => ::SorceryMailer)
|
17
|
+
end
|
18
|
+
|
19
|
+
after(:each) do
|
20
|
+
User.sorcery_config.reset!
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should respond to 'deliver_reset_password_instructions!'" do
|
24
|
+
create_new_user
|
25
|
+
@user.should respond_to(:deliver_reset_password_instructions!)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should respond to 'reset_password_token_valid?'" do
|
29
|
+
create_new_user
|
30
|
+
@user.should respond_to(:reset_password_token_valid?)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should respond to 'reset_password!" do
|
34
|
+
create_new_user
|
35
|
+
@user.should respond_to(:reset_password!)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should respond to 'load_from_reset_password_token'" do
|
39
|
+
create_new_user
|
40
|
+
User.should respond_to(:load_from_reset_password_token)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should allow configuration option 'reset_password_token_attribute_name'" do
|
44
|
+
plugin_set_model_config_property(:reset_password_token_attribute_name, :my_code)
|
45
|
+
User.sorcery_config.reset_password_token_attribute_name.should equal(:my_code)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should allow configuration option 'reset_password_mailer'" do
|
49
|
+
plugin_set_model_config_property(:reset_password_mailer, TestUser)
|
50
|
+
User.sorcery_config.reset_password_mailer.should equal(TestUser)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should allow configuration option 'reset_password_email_method_name'" do
|
54
|
+
plugin_set_model_config_property(:reset_password_email_method_name, :my_mailer_method)
|
55
|
+
User.sorcery_config.reset_password_email_method_name.should equal(:my_mailer_method)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should allow configuration option 'reset_password_expiration_period'" do
|
59
|
+
plugin_set_model_config_property(:reset_password_expiration_period, 16)
|
60
|
+
User.sorcery_config.reset_password_expiration_period.should equal(16)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should allow configuration option 'reset_password_email_sent_at_attribute_name'" do
|
64
|
+
plugin_set_model_config_property(:reset_password_email_sent_at_attribute_name, :blabla)
|
65
|
+
User.sorcery_config.reset_password_email_sent_at_attribute_name.should equal(:blabla)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should allow configuration option 'reset_password_time_between_emails'" do
|
69
|
+
plugin_set_model_config_property(:reset_password_time_between_emails, 16)
|
70
|
+
User.sorcery_config.reset_password_time_between_emails.should equal(16)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# ----------------- PLUGIN ACTIVATED -----------------------
|
75
|
+
describe User, "when activated with sorcery" do
|
76
|
+
|
77
|
+
before(:all) do
|
78
|
+
plugin_model_configure([:reset_password], :reset_password_mailer => ::SorceryMailer)
|
79
|
+
end
|
80
|
+
|
81
|
+
before(:each) do
|
82
|
+
User.delete_all
|
83
|
+
end
|
84
|
+
|
85
|
+
it "load_from_reset_password_token should return user when token is found" do
|
86
|
+
create_new_user
|
87
|
+
@user.deliver_reset_password_instructions!
|
88
|
+
User.load_from_reset_password_token(@user.reset_password_token).should == @user
|
89
|
+
end
|
90
|
+
|
91
|
+
it "load_from_reset_password_token should NOT return user when token is NOT found" do
|
92
|
+
create_new_user
|
93
|
+
@user.deliver_reset_password_instructions!
|
94
|
+
User.load_from_reset_password_token("a").should == nil
|
95
|
+
end
|
96
|
+
|
97
|
+
it "load_from_reset_password_token should return user when token is found and not expired" do
|
98
|
+
create_new_user
|
99
|
+
plugin_set_model_config_property(:reset_password_expiration_period, 500)
|
100
|
+
@user.deliver_reset_password_instructions!
|
101
|
+
User.load_from_reset_password_token(@user.reset_password_token).should == @user
|
102
|
+
end
|
103
|
+
|
104
|
+
it "load_from_reset_password_token should NOT return user when token is found and expired" do
|
105
|
+
create_new_user
|
106
|
+
plugin_set_model_config_property(:reset_password_expiration_period, 0.1)
|
107
|
+
@user.deliver_reset_password_instructions!
|
108
|
+
sleep 0.5
|
109
|
+
User.load_from_reset_password_token(@user.reset_password_token).should == nil
|
110
|
+
end
|
111
|
+
|
112
|
+
it "load_from_reset_password_token should return nil if token is blank" do
|
113
|
+
User.load_from_reset_password_token(nil).should == nil
|
114
|
+
User.load_from_reset_password_token("").should == nil
|
115
|
+
end
|
116
|
+
|
117
|
+
it "'deliver_reset_password_instructions!' should generate a reset_password_token" do
|
118
|
+
create_new_user
|
119
|
+
@user.reset_password_token.should be_nil
|
120
|
+
@user.deliver_reset_password_instructions!
|
121
|
+
@user.reset_password_token.should_not be_nil
|
122
|
+
end
|
123
|
+
|
124
|
+
it "the reset_password_token should be random" do
|
125
|
+
create_new_user
|
126
|
+
plugin_set_model_config_property(:reset_password_time_between_emails, 0)
|
127
|
+
@user.deliver_reset_password_instructions!
|
128
|
+
old_password_code = @user.reset_password_token
|
129
|
+
@user.deliver_reset_password_instructions!
|
130
|
+
@user.reset_password_token.should_not == old_password_code
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should send an email on reset" do
|
134
|
+
create_new_user
|
135
|
+
old_size = ActionMailer::Base.deliveries.size
|
136
|
+
@user.deliver_reset_password_instructions!
|
137
|
+
ActionMailer::Base.deliveries.size.should == old_size + 1
|
138
|
+
end
|
139
|
+
|
140
|
+
it "when reset_password! is called, should delete reset_password_token" do
|
141
|
+
create_new_user
|
142
|
+
@user.deliver_reset_password_instructions!
|
143
|
+
@user.reset_password_token.should_not be_nil
|
144
|
+
@user.reset_password!(:password => "blabulsdf")
|
145
|
+
@user.save!
|
146
|
+
@user.reset_password_token.should be_nil
|
147
|
+
end
|
148
|
+
|
149
|
+
it "code isn't valid if expiration passed" do
|
150
|
+
create_new_user
|
151
|
+
plugin_set_model_config_property(:reset_password_expiration_period, 0.1)
|
152
|
+
@user.deliver_reset_password_instructions!
|
153
|
+
sleep 0.5
|
154
|
+
@user.reset_password_token_valid?.should == false
|
155
|
+
end
|
156
|
+
|
157
|
+
it "code is valid if it's the same code and expiration period did not pass" do
|
158
|
+
create_new_user
|
159
|
+
plugin_set_model_config_property(:reset_password_expiration_period, 300)
|
160
|
+
@user.deliver_reset_password_instructions!
|
161
|
+
@user.reset_password_token_valid?.should == true
|
162
|
+
end
|
163
|
+
|
164
|
+
it "code is valid if it's the same code and expiration period is nil" do
|
165
|
+
create_new_user
|
166
|
+
plugin_set_model_config_property(:reset_password_expiration_period, nil)
|
167
|
+
@user.deliver_reset_password_instructions!
|
168
|
+
@user.reset_password_token_valid?.should == true
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should not send an email if time between emails has not passed since last email" do
|
172
|
+
create_new_user
|
173
|
+
plugin_set_model_config_property(:reset_password_time_between_emails, 10000)
|
174
|
+
old_size = ActionMailer::Base.deliveries.size
|
175
|
+
@user.deliver_reset_password_instructions!
|
176
|
+
ActionMailer::Base.deliveries.size.should == old_size + 1
|
177
|
+
@user.deliver_reset_password_instructions!
|
178
|
+
ActionMailer::Base.deliveries.size.should == old_size + 1
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should send an email if time between emails has passed since last email" do
|
182
|
+
create_new_user
|
183
|
+
plugin_set_model_config_property(:reset_password_time_between_emails, 0.5)
|
184
|
+
old_size = ActionMailer::Base.deliveries.size
|
185
|
+
@user.deliver_reset_password_instructions!
|
186
|
+
ActionMailer::Base.deliveries.size.should == old_size + 1
|
187
|
+
sleep 0.5
|
188
|
+
@user.deliver_reset_password_instructions!
|
189
|
+
ActionMailer::Base.deliveries.size.should == old_size + 2
|
190
|
+
end
|
191
|
+
|
192
|
+
it "if mailer is nil on activation, throw exception!" do
|
193
|
+
expect{plugin_model_configure([:reset_password])}.to raise_error(ArgumentError)
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|