authlogic 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of authlogic might be problematic. Click here for more details.

@@ -1,4 +1,10 @@
1
- == 2.0.1
1
+ == 2.0.2
2
+
3
+ * Reset failed_login_count if consecutive_failed_logins_limit has been exceed and the failed_login_ban_for has passed.
4
+ * Update test helpers to use the new configuration scheme.
5
+ * Fixed issue when logging doesn't update last_request_at, so the next persistence try would fail.
6
+
7
+ == 2.0.1 released 2009-3-23
2
8
 
3
9
  * Validate length of password.
4
10
  * Dont save sessions with a ! during session maintenance.
@@ -19,7 +19,8 @@ module Authlogic
19
19
  klass.class_eval do
20
20
  extend Config
21
21
  include InstanceMethods
22
- validate :validate_failed_logins, :if => :protect_from_brute_force_attacks?
22
+ validate :reset_failed_login_count, :if => :reset_failed_login_count?
23
+ validate :validate_failed_logins, :if => :being_brute_force_protected?
23
24
  end
24
25
  end
25
26
 
@@ -53,24 +54,35 @@ module Authlogic
53
54
  # The methods available for an Authlogic::Session::Base object that make up the brute force protection feature.
54
55
  module InstanceMethods
55
56
  private
56
- def protect_from_brute_force_attacks?
57
+ def exceeded_failed_logins_limit?
57
58
  !attempted_record.nil? && attempted_record.respond_to?(:failed_login_count) && consecutive_failed_logins_limit > 0 &&
58
- attempted_record.failed_login_count && attempted_record.failed_login_count >= consecutive_failed_logins_limit &&
59
- (failed_login_ban_for <= 0 || (attempted_record.respond_to?(:updated_at) && attempted_record.updated_at >= failed_login_ban_for.seconds.ago))
59
+ attempted_record.failed_login_count && attempted_record.failed_login_count >= consecutive_failed_logins_limit
60
60
  end
61
61
 
62
- def consecutive_failed_logins_limit
63
- self.class.consecutive_failed_logins_limit
62
+ def being_brute_force_protected?
63
+ exceeded_failed_logins_limit? && (failed_login_ban_for <= 0 || (attempted_record.respond_to?(:updated_at) && attempted_record.updated_at >= failed_login_ban_for.seconds.ago))
64
64
  end
65
65
 
66
- def failed_login_ban_for
67
- self.class.failed_login_ban_for
66
+ def reset_failed_login_count?
67
+ exceeded_failed_logins_limit? && !being_brute_force_protected?
68
+ end
69
+
70
+ def reset_failed_login_count
71
+ attempted_record.failed_login_count = 0
68
72
  end
69
73
 
70
74
  def validate_failed_logins
71
75
  errors.clear # Clear all other error messages, as they are irrelevant at this point and can only provide additional information that is not needed
72
76
  errors.add_to_base(I18n.t('error_messages.consecutive_failed_logins_limit_exceeded', :default => "Consecutive failed logins limit exceeded, account is disabled."))
73
77
  end
78
+
79
+ def consecutive_failed_logins_limit
80
+ self.class.consecutive_failed_logins_limit
81
+ end
82
+
83
+ def failed_login_ban_for
84
+ self.class.failed_login_ban_for
85
+ end
74
86
  end
75
87
  end
76
88
  end
@@ -15,9 +15,10 @@ module Authlogic
15
15
  klass.class_eval do
16
16
  extend Config
17
17
  include InstanceMethods
18
- after_persisting :set_last_request_at
18
+ after_persisting :set_last_request_at, :if => :set_last_request_at?
19
19
  validate :increase_failed_login_count
20
20
  before_save :update_info
21
+ before_save :set_last_request_at, :if => :set_last_request_at?
21
22
  end
22
23
  end
23
24
 
@@ -59,11 +60,13 @@ module Authlogic
59
60
  record.current_login_ip = controller.request.remote_ip
60
61
  end
61
62
  end
63
+
64
+ def set_last_request_at?
65
+ record && record.class.column_names.include?("last_request_at") && (record.last_request_at.blank? || last_request_at_threshold.to_i.seconds.ago >= record.last_request_at)
66
+ end
62
67
 
63
68
  def set_last_request_at
64
- if record && record.class.column_names.include?("last_request_at") && (record.last_request_at.blank? || last_request_at_threshold.to_i.seconds.ago >= record.last_request_at)
65
- record.last_request_at = klass.default_timezone == :utc ? Time.now.utc : Time.now
66
- end
69
+ record.last_request_at = klass.default_timezone == :utc ? Time.now.utc : Time.now
67
70
  end
68
71
 
69
72
  def last_request_at_threshold
@@ -9,21 +9,21 @@ module Authlogic
9
9
  # Then you will have the methods below to use in your tests.
10
10
  module TestUnitHelpers
11
11
  private
12
- def session_class(record) # :nodoc:
13
- record.class.acts_as_authentic_config[:session_class].constantize
12
+ def session_class(record)
13
+ record.class.session_class
14
14
  end
15
15
 
16
16
  # Sets the session for a record. This way when you execute a request in your test, session values will be present.
17
17
  def set_session_for(record)
18
18
  session_class = session_class(record)
19
- @request.session[session_class.session_key] = record.send(record.class.acts_as_authentic_config[:persistence_token_field])
20
- @request.session["#{session_class.session_key}_id"] = record.id
19
+ @request.session[session_class.session_key] = record.persistence_token
20
+ @request.session["#{session_class.session_key}_#{record.class.primary_key}"] = record.id
21
21
  end
22
22
 
23
23
  # Sets the cookie for a record. This way when you execute a request in your test, cookie values will be present.
24
24
  def set_cookie_for(record)
25
25
  session_class = session_class(record)
26
- @request.cookies[session_class.cookie_key] = record.send(record.class.acts_as_authentic_config[:persistence_token_field])
26
+ @request.cookies[session_class.cookie_key] = record.persistence_token
27
27
  end
28
28
 
29
29
  # Sets the HTTP_AUTHORIZATION header for basic HTTP auth. This way when you execute a request in your test that is trying to authenticate
@@ -44,7 +44,7 @@ module Authlogic # :nodoc:
44
44
 
45
45
  MAJOR = 2
46
46
  MINOR = 0
47
- TINY = 1
47
+ TINY = 2
48
48
 
49
49
  # The current version as a Version instance
50
50
  CURRENT = new(MAJOR, MINOR, TINY)
@@ -56,20 +56,43 @@ module SessionTest
56
56
 
57
57
  UserSession.consecutive_failed_logins_limit = 50
58
58
  end
59
-
60
- def test_resetting_failed_logins_count
59
+
60
+ def test_exceeded_ban_for
61
+ UserSession.consecutive_failed_logins_limit = 2
61
62
  ben = users(:ben)
62
63
 
63
64
  2.times do |i|
64
- session = UserSession.new(:login => ben.login, :password => "badpassword")
65
+ session = UserSession.new(:login => ben.login, :password => "badpassword1")
65
66
  assert !session.save
66
67
  assert session.errors.on(:password)
67
68
  assert_equal i + 1, ben.reload.failed_login_count
68
69
  end
69
-
70
+
71
+ ActiveRecord::Base.connection.execute("update users set updated_at = '#{1.day.ago.to_s(:db)}' where login = '#{ben.login}'")
70
72
  session = UserSession.new(:login => ben.login, :password => "benrocks")
71
73
  assert session.save
72
74
  assert_equal 0, ben.reload.failed_login_count
75
+
76
+ UserSession.consecutive_failed_logins_limit = 50
77
+ end
78
+
79
+ def test_exceeded_ban_and_failed_doesnt_ban_again
80
+ UserSession.consecutive_failed_logins_limit = 2
81
+ ben = users(:ben)
82
+
83
+ 2.times do |i|
84
+ session = UserSession.new(:login => ben.login, :password => "badpassword1")
85
+ assert !session.save
86
+ assert session.errors.on(:password)
87
+ assert_equal i + 1, ben.reload.failed_login_count
88
+ end
89
+
90
+ ActiveRecord::Base.connection.execute("update users set updated_at = '#{1.day.ago.to_s(:db)}' where login = '#{ben.login}'")
91
+ session = UserSession.new(:login => ben.login, :password => "badpassword1")
92
+ assert !session.save
93
+ assert_equal 1, ben.reload.failed_login_count
94
+
95
+ UserSession.consecutive_failed_logins_limit = 50
73
96
  end
74
97
  end
75
98
  end
@@ -15,6 +15,8 @@ module SessionTest
15
15
  class InstanceMethodsTest < ActiveSupport::TestCase
16
16
  def test_after_persisting_set_last_request_at
17
17
  ben = users(:ben)
18
+ assert UserSession.create(ben)
19
+
18
20
  set_cookie_for(ben)
19
21
  old_last_request_at = ben.last_request_at
20
22
  assert UserSession.find
@@ -22,7 +24,7 @@ module SessionTest
22
24
  assert ben.last_request_at != old_last_request_at
23
25
  end
24
26
 
25
- def test_valide_increase_failed_login_count
27
+ def test_valid_increase_failed_login_count
26
28
  ben = users(:ben)
27
29
  old_failed_login_count = ben.failed_login_count
28
30
  assert !UserSession.create(:login => ben.login, :password => "wrong")
@@ -45,10 +47,11 @@ module SessionTest
45
47
  old_last_login_ip = ben.last_login_ip
46
48
  old_current_login_ip = ben.current_login_ip
47
49
 
48
- assert UserSession.create(ben)
49
-
50
+ assert UserSession.create(:login => ben.login, :password => "benrocks")
51
+
52
+ ben.reload
50
53
  assert_equal old_login_count + 1, ben.login_count
51
- assert_equal old_failed_login_count - 1, ben.failed_login_count
54
+ assert_equal 0, ben.failed_login_count
52
55
  assert_equal old_current_login_at, ben.last_login_at
53
56
  assert ben.current_login_at != old_current_login_at
54
57
  assert_equal old_current_login_ip, ben.last_login_ip
@@ -38,6 +38,15 @@ module SessionTest
38
38
 
39
39
  UserSession.logout_on_timeout = false
40
40
  end
41
+
42
+ def test_successful_login
43
+ UserSession.logout_on_timeout = true
44
+ ben = users(:ben)
45
+ assert UserSession.create(:login => ben.login, :password => "benrocks")
46
+ assert session = UserSession.find
47
+ assert_equal ben, session.record
48
+ UserSession.logout_on_timeout = false
49
+ end
41
50
  end
42
51
  end
43
52
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authlogic
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Johnson of Binary Logic
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-23 00:00:00 -04:00
12
+ date: 2009-03-24 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency