Skip to content

Commit e5a4559

Browse files
committed
Add after_login_lock callback
This patch added a callback that execute only when user locked. This callback useful for run something actions(e.g. send notifications to admin) when user locked.
1 parent 6ba63a4 commit e5a4559

File tree

5 files changed

+24
-1
lines changed

5 files changed

+24
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Changelog
22
## HEAD
33

4+
* Add `after_login_lock` callback [#236](https://github.com/Sorcery/sorcery/pull/236)
5+
46
## 0.15.0
57

68
* Fix brute force vuln due to callbacks no being ran [#235](https://github.com/Sorcery/sorcery/pull/235)

lib/sorcery/controller.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ def after_remember_me!(user)
162162
Config.after_remember_me.each { |c| send(c, user) }
163163
end
164164

165+
def after_login_lock!(credentials)
166+
Config.after_login_lock.each { |c| send(c, credentials) }
167+
end
168+
165169
def user_class
166170
@user_class ||= Config.user_class.to_s.constantize
167171
rescue NameError

lib/sorcery/controller/config.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class << self
1919
attr_accessor :before_logout
2020
attr_accessor :after_logout
2121
attr_accessor :after_remember_me
22+
attr_accessor :after_login_lock
2223

2324
def init!
2425
@defaults = {
@@ -31,6 +32,7 @@ def init!
3132
:@before_logout => Set.new,
3233
:@after_logout => Set.new,
3334
:@after_remember_me => Set.new,
35+
:@after_login_lock => Set.new,
3436
:@save_return_to_url => true,
3537
:@cookie_domain => nil
3638
}

lib/sorcery/controller/submodules/brute_force_protection.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ module InstanceMethods
2222
# Runs as a hook after a failed login.
2323
def update_failed_logins_count!(credentials)
2424
user = user_class.sorcery_adapter.find_by_credentials(credentials)
25-
user.register_failed_login! if user
25+
if user && !user.login_locked?
26+
user.register_failed_login!
27+
after_login_lock!(credentials) if user.login_locked?
28+
end
2629
end
2730

2831
# Resets the failed logins counter.

spec/controllers/controller_brute_force_protection_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def request_test_login
2222
it 'counts login retries' do
2323
allow(User).to receive(:authenticate) { |&block| block.call(nil, :other) }
2424
allow(User.sorcery_adapter).to receive(:find_by_credentials).with(['[email protected]', 'blabla']).and_return(user)
25+
allow(user).to receive(:login_locked?).and_return(false)
2526

2627
expect(user).to receive(:register_failed_login!).exactly(3).times
2728

@@ -37,5 +38,16 @@ def request_test_login
3738

3839
get :test_login, params: { email: '[email protected]', password: 'secret' }
3940
end
41+
42+
it 'calls after_login_lock when user locked' do
43+
allow(User).to receive(:authenticate) { |&block| block.call(nil, :other) }
44+
allow(User.sorcery_adapter).to receive(:find_by_credentials).with(['[email protected]', 'blabla']).and_return(user)
45+
allow(user).to receive(:register_failed_login!)
46+
allow(user).to receive(:login_locked?).and_return(false, true)
47+
48+
expect(@controller).to receive(:after_login_lock!).exactly(1).times
49+
50+
request_test_login
51+
end
4052
end
4153
end

0 commit comments

Comments
 (0)