sorcery 0.8.5 → 0.8.6
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +60 -4
- data/CHANGELOG.md +15 -1
- data/Gemfile +9 -18
- data/Gemfile.rails4 +8 -10
- data/README.md +31 -11
- data/VERSION +1 -1
- data/gemfiles/active_record-rails41.gemfile +6 -0
- data/gemfiles/mongo_mapper-rails41.gemfile +8 -0
- data/gemfiles/mongoid-rails41.gemfile +11 -0
- data/lib/sorcery.rb +20 -28
- data/lib/sorcery/controller.rb +6 -11
- data/lib/sorcery/controller/submodules/external.rb +30 -15
- data/lib/sorcery/controller/submodules/session_timeout.rb +1 -1
- data/lib/sorcery/model.rb +102 -70
- data/lib/sorcery/model/adapters/active_record.rb +7 -2
- data/lib/sorcery/model/adapters/datamapper.rb +123 -0
- data/lib/sorcery/model/adapters/mongo_mapper.rb +8 -4
- data/lib/sorcery/model/adapters/mongoid.rb +6 -6
- data/lib/sorcery/model/submodules/activity_logging.rb +24 -0
- data/lib/sorcery/model/submodules/brute_force_protection.rb +16 -0
- data/lib/sorcery/model/submodules/remember_me.rb +19 -4
- data/lib/sorcery/model/submodules/reset_password.rb +30 -13
- data/lib/sorcery/model/submodules/user_activation.rb +53 -22
- data/lib/sorcery/{controller/submodules/external/protocols → protocols}/certs/ca-bundle.crt +0 -0
- data/lib/sorcery/protocols/oauth.rb +42 -0
- data/lib/sorcery/protocols/oauth2.rb +47 -0
- data/lib/sorcery/providers/base.rb +27 -0
- data/lib/sorcery/providers/facebook.rb +63 -0
- data/lib/sorcery/providers/github.rb +51 -0
- data/lib/sorcery/providers/google.rb +51 -0
- data/lib/sorcery/providers/linkedin.rb +66 -0
- data/lib/sorcery/providers/liveid.rb +53 -0
- data/lib/sorcery/providers/twitter.rb +59 -0
- data/lib/sorcery/providers/vk.rb +61 -0
- data/lib/sorcery/providers/xing.rb +64 -0
- data/lib/sorcery/test_helpers/internal.rb +3 -3
- data/lib/sorcery/test_helpers/internal/rails.rb +14 -3
- data/lib/sorcery/test_helpers/rails.rb +1 -10
- data/lib/sorcery/test_helpers/rails/controller.rb +17 -0
- data/lib/sorcery/test_helpers/rails/integration.rb +26 -0
- data/sorcery.gemspec +14 -18
- data/spec/active_record/controller_activity_logging_spec.rb +5 -116
- data/spec/active_record/controller_brute_force_protection_spec.rb +69 -47
- data/spec/active_record/controller_http_basic_auth_spec.rb +24 -18
- data/spec/active_record/controller_oauth2_spec.rb +112 -187
- data/spec/active_record/controller_oauth_spec.rb +41 -37
- data/spec/active_record/controller_remember_me_spec.rb +39 -38
- data/spec/active_record/controller_session_timeout_spec.rb +31 -16
- data/spec/active_record/controller_spec.rb +4 -178
- data/spec/active_record/integration_spec.rb +1 -1
- data/spec/active_record/user_activation_spec.rb +1 -1
- data/spec/active_record/user_activity_logging_spec.rb +1 -1
- data/spec/active_record/user_brute_force_protection_spec.rb +1 -1
- data/spec/active_record/user_oauth_spec.rb +1 -1
- data/spec/active_record/user_remember_me_spec.rb +1 -1
- data/spec/active_record/user_reset_password_spec.rb +1 -1
- data/spec/active_record/user_spec.rb +7 -8
- data/spec/datamapper/controller_activity_logging_spec.rb +17 -0
- data/spec/datamapper/controller_spec.rb +8 -0
- data/spec/datamapper/user_activation_spec.rb +10 -0
- data/spec/datamapper/user_activity_logging_spec.rb +9 -0
- data/spec/datamapper/user_brute_force_protection_spec.rb +9 -0
- data/spec/datamapper/user_oauth_spec.rb +9 -0
- data/spec/datamapper/user_remember_me_spec.rb +8 -0
- data/spec/datamapper/user_reset_password_spec.rb +8 -0
- data/spec/datamapper/user_spec.rb +27 -0
- data/spec/mongo_mapper/controller_spec.rb +4 -171
- data/spec/mongo_mapper/user_activation_spec.rb +1 -2
- data/spec/mongo_mapper/user_activity_logging_spec.rb +1 -1
- data/spec/mongo_mapper/user_brute_force_protection_spec.rb +1 -1
- data/spec/mongo_mapper/user_oauth_spec.rb +1 -1
- data/spec/mongo_mapper/user_remember_me_spec.rb +1 -1
- data/spec/mongo_mapper/user_reset_password_spec.rb +1 -1
- data/spec/mongo_mapper/user_spec.rb +7 -8
- data/spec/mongoid/controller_activity_logging_spec.rb +4 -99
- data/spec/mongoid/controller_spec.rb +4 -182
- data/spec/mongoid/user_activation_spec.rb +1 -2
- data/spec/mongoid/user_activity_logging_spec.rb +1 -2
- data/spec/mongoid/user_brute_force_protection_spec.rb +1 -2
- data/spec/mongoid/user_oauth_spec.rb +1 -2
- data/spec/mongoid/user_remember_me_spec.rb +1 -2
- data/spec/mongoid/user_reset_password_spec.rb +1 -2
- data/spec/mongoid/user_spec.rb +8 -9
- data/spec/orm/active_record.rb +2 -0
- data/spec/orm/datamapper.rb +34 -0
- data/spec/orm/mongo_mapper.rb +1 -0
- data/spec/orm/mongoid.rb +1 -0
- data/spec/rails_app/app/controllers/sorcery_controller.rb +64 -59
- data/spec/rails_app/app/datamapper/authentication.rb +8 -0
- data/spec/rails_app/app/datamapper/user.rb +7 -0
- data/spec/rails_app/config/routes.rb +18 -13
- data/spec/shared_examples/controller_activity_logging_shared_examples.rb +125 -0
- data/spec/shared_examples/controller_oauth2_shared_examples.rb +32 -36
- data/spec/shared_examples/controller_oauth_shared_examples.rb +19 -26
- data/spec/shared_examples/controller_shared_examples.rb +203 -0
- data/spec/shared_examples/user_activation_shared_examples.rb +107 -90
- data/spec/shared_examples/user_activity_logging_shared_examples.rb +10 -10
- data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +14 -13
- data/spec/shared_examples/user_oauth_shared_examples.rb +23 -15
- data/spec/shared_examples/user_remember_me_shared_examples.rb +32 -23
- data/spec/shared_examples/user_reset_password_shared_examples.rb +136 -115
- data/spec/shared_examples/user_shared_examples.rb +206 -146
- data/spec/sorcery_crypto_providers_spec.rb +28 -28
- data/spec/spec_helper.rb +15 -6
- metadata +83 -127
- data/lib/sorcery/controller/submodules/external/protocols/oauth1.rb +0 -46
- data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +0 -50
- data/lib/sorcery/controller/submodules/external/providers/base.rb +0 -21
- data/lib/sorcery/controller/submodules/external/providers/facebook.rb +0 -99
- data/lib/sorcery/controller/submodules/external/providers/github.rb +0 -93
- data/lib/sorcery/controller/submodules/external/providers/google.rb +0 -92
- data/lib/sorcery/controller/submodules/external/providers/linkedin.rb +0 -103
- data/lib/sorcery/controller/submodules/external/providers/liveid.rb +0 -93
- data/lib/sorcery/controller/submodules/external/providers/twitter.rb +0 -94
- data/lib/sorcery/controller/submodules/external/providers/vk.rb +0 -101
- data/lib/sorcery/controller/submodules/external/providers/xing.rb +0 -98
- data/lib/sorcery/test_helpers.rb +0 -5
@@ -30,14 +30,14 @@ module Sorcery
|
|
30
30
|
|
31
31
|
def create_new_user(attributes_hash = nil)
|
32
32
|
@user = build_new_user(attributes_hash)
|
33
|
-
@user.
|
33
|
+
@user.sorcery_save(:raise_on_failure => true)
|
34
34
|
@user
|
35
35
|
end
|
36
36
|
|
37
37
|
def create_new_external_user(provider, attributes_hash = nil)
|
38
38
|
user_attributes_hash = attributes_hash || {:username => 'gizmo'}
|
39
39
|
@user = User.new(user_attributes_hash)
|
40
|
-
@user.
|
40
|
+
@user.sorcery_save(:raise_on_failure => true)
|
41
41
|
@user.authentications.create!({:provider => provider, :uid => 123})
|
42
42
|
@user
|
43
43
|
end
|
@@ -47,7 +47,7 @@ module Sorcery
|
|
47
47
|
|
48
48
|
user_attributes_hash = attributes_hash || {:username => 'gizmo'}
|
49
49
|
@user = User.new(user_attributes_hash)
|
50
|
-
@user.
|
50
|
+
@user.sorcery_save(:raise_on_failure => true)
|
51
51
|
@user.send(authentication_association).create!({:provider => provider, :uid => 123})
|
52
52
|
@user
|
53
53
|
end
|
@@ -2,9 +2,9 @@ module Sorcery
|
|
2
2
|
module TestHelpers
|
3
3
|
module Internal
|
4
4
|
module Rails
|
5
|
-
include ::Sorcery::TestHelpers::Rails
|
5
|
+
include ::Sorcery::TestHelpers::Rails::Controller
|
6
6
|
|
7
|
-
|
7
|
+
SUBMODULES_AUTO_ADDED_CONTROLLER_FILTERS = [
|
8
8
|
:register_last_activity_time_to_db,
|
9
9
|
:deny_banned_user,
|
10
10
|
:validate_session
|
@@ -20,7 +20,13 @@ module Sorcery
|
|
20
20
|
# remove all plugin before_filters so they won't fail other tests.
|
21
21
|
# I don't like this way, but I didn't find another.
|
22
22
|
# hopefully it won't break until Rails 4.
|
23
|
-
|
23
|
+
chain = if Gem::Version.new(::Rails::VERSION::STRING) >= Gem::Version.new("4.1.0")
|
24
|
+
SorceryController._process_action_callbacks.send :chain
|
25
|
+
else
|
26
|
+
SorceryController._process_action_callbacks
|
27
|
+
end
|
28
|
+
|
29
|
+
chain.delete_if {|c| SUBMODULES_AUTO_ADDED_CONTROLLER_FILTERS.include?(c.filter) }
|
24
30
|
|
25
31
|
# configure
|
26
32
|
::Sorcery::Controller::Config.submodules = submodules
|
@@ -34,6 +40,11 @@ module Sorcery
|
|
34
40
|
end
|
35
41
|
end
|
36
42
|
User.authenticates_with_sorcery!
|
43
|
+
if defined?(DataMapper) and User.ancestors.include?(DataMapper::Resource)
|
44
|
+
DataMapper.auto_migrate!
|
45
|
+
User.finalize
|
46
|
+
Authentication.finalize
|
47
|
+
end
|
37
48
|
end
|
38
49
|
|
39
50
|
def sorcery_controller_property_set(property, value)
|
@@ -1,16 +1,7 @@
|
|
1
1
|
module Sorcery
|
2
2
|
module TestHelpers
|
3
3
|
module Rails
|
4
|
-
# logins a user and calls all callbacks
|
5
|
-
def login_user(user = nil)
|
6
|
-
user ||= @user
|
7
|
-
@controller.send(:auto_login, user)
|
8
|
-
@controller.send(:after_login!, user, [user.send(user.sorcery_config.username_attribute_names.first), 'secret'])
|
9
|
-
end
|
10
4
|
|
11
|
-
def logout_user
|
12
|
-
@controller.send(:logout)
|
13
|
-
end
|
14
5
|
end
|
15
6
|
end
|
16
|
-
end
|
7
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Sorcery
|
2
|
+
module TestHelpers
|
3
|
+
module Rails
|
4
|
+
module Controller
|
5
|
+
def login_user(user = nil, test_context = {})
|
6
|
+
user ||= @user
|
7
|
+
@controller.send(:auto_login, user)
|
8
|
+
@controller.send(:after_login!, user, [user.send(user.sorcery_config.username_attribute_names.first), 'secret'])
|
9
|
+
end
|
10
|
+
|
11
|
+
def logout_user
|
12
|
+
@controller.send(:logout)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Sorcery
|
2
|
+
module TestHelpers
|
3
|
+
module Rails
|
4
|
+
module Integration
|
5
|
+
|
6
|
+
#Accepts arguments for user to login, route to use and HTTP method
|
7
|
+
#Defaults - @user, 'sessions_url' and POST
|
8
|
+
def login_user(user = nil, route = nil, http_method = :post)
|
9
|
+
user ||= @user
|
10
|
+
route ||= sessions_url
|
11
|
+
|
12
|
+
username_attr = user.sorcery_config.username_attribute_names.first
|
13
|
+
username = user.send(username_attr)
|
14
|
+
page.driver.send(http_method, route, { :"#{username_attr}" => username, :password => 'secret' })
|
15
|
+
end
|
16
|
+
|
17
|
+
#Accepts route and HTTP method arguments
|
18
|
+
#Default - 'logout_url' and GET
|
19
|
+
def logout_user(route = nil, http_method = :get)
|
20
|
+
route ||= logout_url
|
21
|
+
page.driver.send(http_method, route)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/sorcery.gemspec
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "sorcery"
|
3
|
-
s.version = "0.8.
|
4
|
-
s.authors = ["Noam Ben Ari", "Kir Shatrov"]
|
3
|
+
s.version = "0.8.6"
|
4
|
+
s.authors = ["Noam Ben Ari", "Kir Shatrov", "Grzegorz Witek"]
|
5
5
|
s.email = "nbenari@gmail.com"
|
6
6
|
s.description = "Provides common authentication needs such as signing in/out, activating by email and resetting password."
|
7
|
-
s.summary = "Magical authentication for Rails 3 applications"
|
7
|
+
s.summary = "Magical authentication for Rails 3 & 4 applications"
|
8
8
|
s.homepage = "http://github.com/NoamB/sorcery"
|
9
9
|
|
10
10
|
s.files = `git ls-files`.split($/)
|
@@ -14,21 +14,17 @@ Gem::Specification.new do |s|
|
|
14
14
|
|
15
15
|
s.required_ruby_version = '>= 1.9.3'
|
16
16
|
|
17
|
-
s.add_dependency
|
18
|
-
s.add_dependency
|
19
|
-
s.add_dependency
|
17
|
+
s.add_dependency "oauth", "~> 0.4", ">= 0.4.4"
|
18
|
+
s.add_dependency "oauth2", ">= 0.8.0", "< 1.0.0"
|
19
|
+
s.add_dependency "bcrypt", "~> 3.1"
|
20
20
|
|
21
|
-
s.add_development_dependency
|
22
|
-
s.add_development_dependency
|
23
|
-
s.add_development_dependency
|
24
|
-
|
25
|
-
s.add_development_dependency
|
26
|
-
s.add_development_dependency
|
27
|
-
s.add_development_dependency
|
28
|
-
s.add_development_dependency
|
29
|
-
s.add_development_dependency("simplecov", ">= 0.3.8")
|
30
|
-
s.add_development_dependency("timecop", ">= 0")
|
31
|
-
s.add_development_dependency("mongo_mapper", ">= 0")
|
32
|
-
s.add_development_dependency("mongoid", "~> 2.4.4")
|
21
|
+
s.add_development_dependency "abstract", ">= 1.0.0"
|
22
|
+
s.add_development_dependency "json", ">= 1.7.7"
|
23
|
+
s.add_development_dependency "yard", "~> 0.6.0"
|
24
|
+
|
25
|
+
s.add_development_dependency "timecop"
|
26
|
+
s.add_development_dependency "simplecov", ">= 0.3.8"
|
27
|
+
s.add_development_dependency "rspec", "~> 3.0.0"
|
28
|
+
s.add_development_dependency "rspec-rails", "~> 3.0.0"
|
33
29
|
end
|
34
30
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
require 'shared_examples/controller_activity_logging_shared_examples'
|
4
|
+
|
5
|
+
describe SorceryController, :active_record => true do
|
4
6
|
before(:all) do
|
5
7
|
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activity_logging")
|
6
8
|
User.reset_column_information
|
@@ -16,125 +18,12 @@ describe SorceryController do
|
|
16
18
|
end
|
17
19
|
|
18
20
|
# ----------------- ACTIVITY LOGGING -----------------------
|
19
|
-
|
20
|
-
before(:all) do
|
21
|
-
sorcery_reload!([:activity_logging])
|
22
|
-
end
|
23
|
-
|
24
|
-
before(:each) do
|
25
|
-
create_new_user
|
26
|
-
end
|
27
|
-
|
21
|
+
context "with activity logging features" do
|
28
22
|
after(:each) do
|
29
23
|
User.delete_all
|
30
24
|
end
|
31
25
|
|
32
|
-
|
33
|
-
|
34
|
-
it "'current_users' should be empty when no users are logged in" do
|
35
|
-
subject.current_users.size.should == 0
|
36
|
-
end
|
37
|
-
|
38
|
-
it "should log login time on login" do
|
39
|
-
now = Time.now.in_time_zone
|
40
|
-
login_user
|
41
|
-
@user.last_login_at.should_not be_nil
|
42
|
-
@user.last_login_at.to_s(:db).should >= now.to_s(:db)
|
43
|
-
@user.last_login_at.to_s(:db).should <= (now+2).to_s(:db)
|
44
|
-
end
|
26
|
+
it_behaves_like "controller_activity_logging"
|
45
27
|
|
46
|
-
it "should log logout time on logout" do
|
47
|
-
login_user
|
48
|
-
now = Time.now.in_time_zone
|
49
|
-
logout_user
|
50
|
-
|
51
|
-
User.last.last_logout_at.should_not be_nil
|
52
|
-
|
53
|
-
User.last.last_logout_at.to_s(:db).should >= now.to_s(:db)
|
54
|
-
User.last.last_logout_at.to_s(:db).should <= (now+2).to_s(:db)
|
55
|
-
end
|
56
|
-
|
57
|
-
it "should log last activity time when logged in" do
|
58
|
-
sorcery_controller_property_set(:register_last_activity_time, true)
|
59
|
-
|
60
|
-
login_user
|
61
|
-
now = Time.now.in_time_zone
|
62
|
-
get :some_action
|
63
|
-
|
64
|
-
last_activity_at = User.last.last_activity_at
|
65
|
-
|
66
|
-
last_activity_at.should be_present
|
67
|
-
last_activity_at.to_s(:db).should >= now.to_s(:db)
|
68
|
-
last_activity_at.to_s(:db).should <= (now+2).to_s(:db)
|
69
|
-
end
|
70
|
-
|
71
|
-
it "should log last IP address when logged in" do
|
72
|
-
login_user
|
73
|
-
get :some_action
|
74
|
-
User.last.last_login_from_ip_address.should == "0.0.0.0"
|
75
|
-
end
|
76
|
-
|
77
|
-
it "should update nothing but activity fields" do
|
78
|
-
original_user_name = User.last.username
|
79
|
-
login_user
|
80
|
-
get :some_action_making_a_non_persisted_change_to_the_user
|
81
|
-
User.last.username.should == original_user_name
|
82
|
-
end
|
83
|
-
|
84
|
-
it "'current_users' should hold the user object when 1 user is logged in" do
|
85
|
-
login_user
|
86
|
-
get :some_action
|
87
|
-
subject.current_users.size.should == 1
|
88
|
-
subject.current_users[0].should == @user
|
89
|
-
end
|
90
|
-
|
91
|
-
it "'current_users' should show all current_users, whether they have logged out before or not." do
|
92
|
-
user1 = create_new_user({:username => 'gizmo1', :email => "bla1@bla.com", :password => 'secret1'})
|
93
|
-
login_user(user1)
|
94
|
-
get :some_action
|
95
|
-
clear_user_without_logout
|
96
|
-
user2 = create_new_user({:username => 'gizmo2', :email => "bla2@bla.com", :password => 'secret2'})
|
97
|
-
login_user(user2)
|
98
|
-
get :some_action
|
99
|
-
clear_user_without_logout
|
100
|
-
user3 = create_new_user({:username => 'gizmo3', :email => "bla3@bla.com", :password => 'secret3'})
|
101
|
-
login_user(user3)
|
102
|
-
get :some_action
|
103
|
-
subject.current_users.size.should == 3
|
104
|
-
subject.current_users[0].should == user1
|
105
|
-
subject.current_users[1].should == user2
|
106
|
-
subject.current_users[2].should == user3
|
107
|
-
end
|
108
|
-
|
109
|
-
it "should not register login time if configured so" do
|
110
|
-
sorcery_controller_property_set(:register_login_time, false)
|
111
|
-
now = Time.now.in_time_zone
|
112
|
-
login_user
|
113
|
-
@user.last_login_at.should be_nil
|
114
|
-
end
|
115
|
-
|
116
|
-
it "should not register logout time if configured so" do
|
117
|
-
sorcery_controller_property_set(:register_logout_time, false)
|
118
|
-
now = Time.now.in_time_zone
|
119
|
-
login_user
|
120
|
-
logout_user
|
121
|
-
@user.last_logout_at.should be_nil
|
122
|
-
end
|
123
|
-
|
124
|
-
it "should not register last activity time if configured so" do
|
125
|
-
sorcery_controller_property_set(:register_last_activity_time, false)
|
126
|
-
now = Time.now.in_time_zone
|
127
|
-
login_user
|
128
|
-
get :some_action
|
129
|
-
@user.last_activity_at.should be_nil
|
130
|
-
end
|
131
|
-
|
132
|
-
it "should not register last IP address if configured so" do
|
133
|
-
sorcery_controller_property_set(:register_last_ip_address, false)
|
134
|
-
ip_address = "127.0.0.1"
|
135
|
-
login_user
|
136
|
-
get :some_action
|
137
|
-
@user.last_activity_at.should be_nil
|
138
|
-
end
|
139
28
|
end
|
140
29
|
end
|
@@ -1,6 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe SorceryController do
|
3
|
+
describe SorceryController, :active_record => true do
|
4
|
+
|
5
|
+
let(:db_user) { User.find_by_email 'bla@bla.com' }
|
6
|
+
let!(:user) { create_new_user }
|
7
|
+
|
8
|
+
def request_test_login
|
9
|
+
get :test_login, :email => 'bla@bla.com', :password => 'blabla'
|
10
|
+
end
|
11
|
+
|
4
12
|
before(:all) do
|
5
13
|
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/brute_force_protection")
|
6
14
|
User.reset_column_information
|
@@ -11,81 +19,91 @@ describe SorceryController do
|
|
11
19
|
end
|
12
20
|
|
13
21
|
# ----------------- SESSION TIMEOUT -----------------------
|
14
|
-
describe
|
22
|
+
describe "brute force protection features" do
|
23
|
+
|
15
24
|
before(:all) do
|
16
25
|
sorcery_reload!([:brute_force_protection])
|
17
|
-
create_new_user
|
18
26
|
end
|
19
27
|
|
28
|
+
|
20
29
|
after(:each) do
|
21
30
|
Sorcery::Controller::Config.reset!
|
22
31
|
sorcery_controller_property_set(:user_class, User)
|
23
32
|
Timecop.return
|
24
33
|
end
|
25
34
|
|
26
|
-
it "
|
27
|
-
3.times {
|
28
|
-
|
35
|
+
it "counts login retries" do
|
36
|
+
3.times { request_test_login }
|
37
|
+
expect(db_user.failed_logins_count).to eq 3
|
29
38
|
end
|
30
39
|
|
31
|
-
it "
|
40
|
+
it "generates unlock token before mail is sent" do
|
32
41
|
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
33
42
|
sorcery_model_property_set(:login_lock_time_period, 0)
|
34
43
|
sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
|
35
|
-
3.times {
|
36
|
-
ActionMailer::Base.deliveries.last.body.to_s.match(
|
44
|
+
3.times { request_test_login }
|
45
|
+
expect(ActionMailer::Base.deliveries.last.body.to_s.match(db_user.unlock_token)).not_to be_nil
|
37
46
|
end
|
38
47
|
|
39
|
-
it "
|
48
|
+
it "unlocks after entering unlock token" do
|
40
49
|
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
41
50
|
sorcery_model_property_set(:login_lock_time_period, 0)
|
42
51
|
sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
|
43
|
-
3.times {
|
44
|
-
|
45
|
-
|
52
|
+
3.times { request_test_login }
|
53
|
+
|
54
|
+
expect(db_user.unlock_token).not_to be_nil
|
55
|
+
|
56
|
+
token = db_user.unlock_token
|
46
57
|
user = User.load_from_unlock_token(token)
|
47
|
-
|
58
|
+
|
59
|
+
expect(user).not_to be_nil
|
60
|
+
|
48
61
|
user.unlock!
|
49
|
-
User.load_from_unlock_token(
|
62
|
+
expect(User.load_from_unlock_token(db_user.unlock_token)).to be_nil
|
50
63
|
end
|
51
64
|
|
52
|
-
it "
|
65
|
+
it "resets the counter on a good login" do
|
53
66
|
# dirty hack for rails 4
|
54
|
-
@controller.
|
67
|
+
allow(@controller).to receive(:register_last_activity_time_to_db)
|
55
68
|
|
56
69
|
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 5)
|
57
|
-
3.times {
|
70
|
+
3.times { request_test_login }
|
58
71
|
get :test_login, :email => 'bla@bla.com', :password => 'secret'
|
59
|
-
|
72
|
+
|
73
|
+
expect(db_user.failed_logins_count).to eq 0
|
60
74
|
end
|
61
75
|
|
62
|
-
it "
|
63
|
-
|
76
|
+
it "locks user when number of retries reached the limit" do
|
77
|
+
expect(db_user.lock_expires_at).to be_nil
|
78
|
+
|
64
79
|
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 1)
|
65
|
-
|
66
|
-
|
80
|
+
request_test_login
|
81
|
+
|
82
|
+
expect(db_user.reload.lock_expires_at).not_to be_nil
|
67
83
|
end
|
68
84
|
|
69
|
-
it "
|
85
|
+
it "unlocks after lock time period passes" do
|
70
86
|
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
71
87
|
sorcery_model_property_set(:login_lock_time_period, 0.2)
|
72
|
-
|
73
|
-
|
74
|
-
|
88
|
+
2.times { request_test_login }
|
89
|
+
|
90
|
+
expect(db_user.reload.lock_expires_at).not_to be_nil
|
91
|
+
|
75
92
|
Timecop.travel(Time.now.in_time_zone + 0.3)
|
76
|
-
|
77
|
-
|
93
|
+
request_test_login
|
94
|
+
|
95
|
+
expect(db_user.reload.lock_expires_at).to be_nil
|
78
96
|
end
|
79
97
|
|
80
|
-
it "
|
98
|
+
it "doest not unlock if time period is 0 (permanent lock)" do
|
81
99
|
sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2)
|
82
100
|
sorcery_model_property_set(:login_lock_time_period, 0)
|
83
|
-
|
84
|
-
|
85
|
-
unlock_date = User.find_by_email('bla@bla.com').lock_expires_at
|
101
|
+
2.times { request_test_login }
|
102
|
+
unlock_date = db_user.lock_expires_at
|
86
103
|
Timecop.travel(Time.now.in_time_zone + 1)
|
87
|
-
|
88
|
-
|
104
|
+
request_test_login
|
105
|
+
|
106
|
+
expect(db_user.lock_expires_at.to_s).to eq unlock_date.to_s
|
89
107
|
end
|
90
108
|
|
91
109
|
context "unlock_token_mailer_disabled is true" do
|
@@ -97,15 +115,17 @@ describe SorceryController do
|
|
97
115
|
sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
|
98
116
|
end
|
99
117
|
|
100
|
-
it "
|
101
|
-
3.times {
|
102
|
-
|
118
|
+
it "generates unlock token after user locked" do
|
119
|
+
3.times { request_test_login }
|
120
|
+
|
121
|
+
expect(db_user.unlock_token).not_to be_nil
|
103
122
|
end
|
104
123
|
|
105
|
-
it "
|
124
|
+
it "doest *not* automatically send unlock mail" do
|
106
125
|
old_size = ActionMailer::Base.deliveries.size
|
107
|
-
3.times {
|
108
|
-
|
126
|
+
3.times { request_test_login }
|
127
|
+
|
128
|
+
expect(ActionMailer::Base.deliveries.size).to eq old_size
|
109
129
|
end
|
110
130
|
|
111
131
|
end
|
@@ -119,15 +139,17 @@ describe SorceryController do
|
|
119
139
|
sorcery_model_property_set(:unlock_token_mailer, SorceryMailer)
|
120
140
|
end
|
121
141
|
|
122
|
-
it "
|
123
|
-
3.times {
|
124
|
-
|
142
|
+
it "sets the unlock token after user locked" do
|
143
|
+
3.times { request_test_login }
|
144
|
+
|
145
|
+
expect(db_user.unlock_token).not_to be_nil
|
125
146
|
end
|
126
147
|
|
127
|
-
it "
|
148
|
+
it "automatically sends unlock mail" do
|
128
149
|
old_size = ActionMailer::Base.deliveries.size
|
129
|
-
3.times {
|
130
|
-
|
150
|
+
3.times { request_test_login }
|
151
|
+
|
152
|
+
expect(ActionMailer::Base.deliveries.size).to eq old_size + 1
|
131
153
|
end
|
132
154
|
|
133
155
|
end
|