authlogic 5.0.4 → 6.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/authlogic.rb +1 -0
- data/lib/authlogic/acts_as_authentic/base.rb +16 -1
- data/lib/authlogic/acts_as_authentic/password.rb +15 -5
- data/lib/authlogic/acts_as_authentic/session_maintenance.rb +5 -3
- data/lib/authlogic/controller_adapters/abstract_adapter.rb +21 -0
- data/lib/authlogic/controller_adapters/rails_adapter.rb +1 -1
- data/lib/authlogic/crypto_providers/md5.rb +3 -0
- data/lib/authlogic/crypto_providers/md5/v2.rb +35 -0
- data/lib/authlogic/crypto_providers/sha1.rb +3 -0
- data/lib/authlogic/crypto_providers/sha1/v2.rb +41 -0
- data/lib/authlogic/crypto_providers/sha256.rb +3 -0
- data/lib/authlogic/crypto_providers/sha256/v2.rb +58 -0
- data/lib/authlogic/crypto_providers/sha512.rb +3 -0
- data/lib/authlogic/crypto_providers/sha512/v2.rb +39 -0
- data/lib/authlogic/errors.rb +50 -0
- data/lib/authlogic/i18n/translator.rb +1 -1
- data/lib/authlogic/session/base.rb +203 -93
- data/lib/authlogic/test_case.rb +1 -0
- data/lib/authlogic/test_case/mock_api_controller.rb +52 -0
- data/lib/authlogic/test_case/mock_controller.rb +1 -1
- data/lib/authlogic/test_case/mock_cookie_jar.rb +58 -4
- data/lib/authlogic/test_case/mock_request.rb +10 -0
- data/lib/authlogic/test_case/rails_request_adapter.rb +7 -1
- data/lib/authlogic/version.rb +1 -1
- metadata +53 -33
@@ -198,7 +198,7 @@ module Authlogic
|
|
198
198
|
# 2. Enable logging out on timeouts
|
199
199
|
#
|
200
200
|
# class UserSession < Authlogic::Session::Base
|
201
|
-
# logout_on_timeout true # default
|
201
|
+
# logout_on_timeout true # default is false
|
202
202
|
# end
|
203
203
|
#
|
204
204
|
# This will require a user to log back in if they are inactive for more than
|
@@ -351,7 +351,14 @@ module Authlogic
|
|
351
351
|
- https://github.com/binarylogic/authlogic/pull/558
|
352
352
|
- https://github.com/binarylogic/authlogic/pull/577
|
353
353
|
EOS
|
354
|
-
|
354
|
+
E_DPR_FIND_BY_LOGIN_METHOD = <<~EOS.squish.freeze
|
355
|
+
find_by_login_method is deprecated in favor of record_selection_method,
|
356
|
+
to avoid confusion with ActiveRecord's "Dynamic Finders".
|
357
|
+
(https://guides.rubyonrails.org/v6.0/active_record_querying.html#dynamic-finders)
|
358
|
+
For example, rubocop-rails is confused by the deprecated method.
|
359
|
+
(https://github.com/rubocop-hq/rubocop-rails/blob/master/lib/rubocop/cop/rails/dynamic_find_by.rb)
|
360
|
+
EOS
|
361
|
+
VALID_SAME_SITE_VALUES = [nil, "Lax", "Strict", "None"].freeze
|
355
362
|
|
356
363
|
# Callbacks
|
357
364
|
# =========
|
@@ -415,10 +422,11 @@ module Authlogic
|
|
415
422
|
before_save :set_last_request_at
|
416
423
|
|
417
424
|
after_save :reset_perishable_token!
|
418
|
-
after_save :save_cookie
|
425
|
+
after_save :save_cookie, if: :cookie_enabled?
|
419
426
|
after_save :update_session
|
427
|
+
after_create :renew_session_id
|
420
428
|
|
421
|
-
after_destroy :destroy_cookie
|
429
|
+
after_destroy :destroy_cookie, if: :cookie_enabled?
|
422
430
|
after_destroy :update_session
|
423
431
|
|
424
432
|
# `validate` callbacks, in deliberate order. For example,
|
@@ -438,8 +446,7 @@ module Authlogic
|
|
438
446
|
|
439
447
|
class << self
|
440
448
|
attr_accessor(
|
441
|
-
:configured_password_methods
|
442
|
-
:configured_klass_methods
|
449
|
+
:configured_password_methods
|
443
450
|
)
|
444
451
|
end
|
445
452
|
attr_accessor(
|
@@ -472,14 +479,9 @@ module Authlogic
|
|
472
479
|
!controller.nil?
|
473
480
|
end
|
474
481
|
|
475
|
-
#
|
476
|
-
#
|
477
|
-
# I recommend keeping this enabled. The only time I feel this should be
|
478
|
-
# disabled is if you are not comfortable having your users provide their
|
479
|
-
# raw username and password. Whatever the reason, you can disable it
|
480
|
-
# here.
|
482
|
+
# Allow users to log in via HTTP basic authentication.
|
481
483
|
#
|
482
|
-
# * <tt>Default:</tt>
|
484
|
+
# * <tt>Default:</tt> false
|
483
485
|
# * <tt>Accepts:</tt> Boolean
|
484
486
|
def allow_http_basic_auth(value = nil)
|
485
487
|
rw_config(:allow_http_basic_auth, value, false)
|
@@ -669,35 +671,10 @@ module Authlogic
|
|
669
671
|
end
|
670
672
|
end
|
671
673
|
|
672
|
-
#
|
673
|
-
# validation is actually finding the user and making sure it exists.
|
674
|
-
# What method it uses the do this is up to you.
|
675
|
-
#
|
676
|
-
# Let's say you have a UserSession that is authenticating a User. By
|
677
|
-
# default UserSession will call User.find_by_login(login). You can
|
678
|
-
# change what method UserSession calls by specifying it here. Then in
|
679
|
-
# your User model you can make that method do anything you want, giving
|
680
|
-
# you complete control of how users are found by the UserSession.
|
681
|
-
#
|
682
|
-
# Let's take an example: You want to allow users to login by username or
|
683
|
-
# email. Set this to the name of the class method that does this in the
|
684
|
-
# User model. Let's call it "find_by_username_or_email"
|
685
|
-
#
|
686
|
-
# class User < ActiveRecord::Base
|
687
|
-
# def self.find_by_username_or_email(login)
|
688
|
-
# find_by_username(login) || find_by_email(login)
|
689
|
-
# end
|
690
|
-
# end
|
691
|
-
#
|
692
|
-
# Now just specify the name of this method for this configuration option
|
693
|
-
# and you are all set. You can do anything you want here. Maybe you
|
694
|
-
# allow users to have multiple logins and you want to search a has_many
|
695
|
-
# relationship, etc. The sky is the limit.
|
696
|
-
#
|
697
|
-
# * <tt>Default:</tt> "find_by_smart_case_login_field"
|
698
|
-
# * <tt>Accepts:</tt> Symbol or String
|
674
|
+
# @deprecated in favor of record_selection_method
|
699
675
|
def find_by_login_method(value = nil)
|
700
|
-
|
676
|
+
::ActiveSupport::Deprecation.warn(E_DPR_FIND_BY_LOGIN_METHOD)
|
677
|
+
record_selection_method(value)
|
701
678
|
end
|
702
679
|
alias find_by_login_method= find_by_login_method
|
703
680
|
|
@@ -782,15 +759,23 @@ module Authlogic
|
|
782
759
|
# example, the UserSession class will authenticate with the User class
|
783
760
|
# unless you specify otherwise in your configuration. See
|
784
761
|
# authenticate_with for information on how to change this value.
|
762
|
+
#
|
763
|
+
# @api public
|
785
764
|
def klass
|
786
765
|
@klass ||= klass_name ? klass_name.constantize : nil
|
787
766
|
end
|
788
767
|
|
789
|
-
# The
|
768
|
+
# The model name, guessed from the session class name, e.g. "User",
|
769
|
+
# from "UserSession".
|
770
|
+
#
|
771
|
+
# TODO: This method can return nil. We should explore this. It seems
|
772
|
+
# likely to cause a NoMethodError later, so perhaps we should raise an
|
773
|
+
# error instead.
|
774
|
+
#
|
775
|
+
# @api private
|
790
776
|
def klass_name
|
791
|
-
return @klass_name if
|
792
|
-
@klass_name = name.scan(/(.*)Session/)[0]
|
793
|
-
@klass_name = klass_name ? klass_name[0] : nil
|
777
|
+
return @klass_name if instance_variable_defined?(:@klass_name)
|
778
|
+
@klass_name = name.scan(/(.*)Session/)[0]&.first
|
794
779
|
end
|
795
780
|
|
796
781
|
# The name of the method you want Authlogic to create for storing the
|
@@ -798,8 +783,8 @@ module Authlogic
|
|
798
783
|
# Authlogic::Session, if you want it can be something completely
|
799
784
|
# different than the field in your model. So if you wanted people to
|
800
785
|
# login with a field called "login" and then find users by email this is
|
801
|
-
# completely doable. See the
|
802
|
-
# for
|
786
|
+
# completely doable. See the `record_selection_method` configuration
|
787
|
+
# option for details.
|
803
788
|
#
|
804
789
|
# * <tt>Default:</tt> klass.login_field || klass.email_field
|
805
790
|
# * <tt>Accepts:</tt> Symbol or String
|
@@ -882,6 +867,47 @@ module Authlogic
|
|
882
867
|
end
|
883
868
|
alias password_field= password_field
|
884
869
|
|
870
|
+
# Authlogic tries to validate the credentials passed to it. One part of
|
871
|
+
# validation is actually finding the user and making sure it exists.
|
872
|
+
# What method it uses the do this is up to you.
|
873
|
+
#
|
874
|
+
# ```
|
875
|
+
# # user_session.rb
|
876
|
+
# record_selection_method :find_by_email
|
877
|
+
# ```
|
878
|
+
#
|
879
|
+
# This is the recommended way to find the user by email address.
|
880
|
+
# The resulting query will be `User.find_by_email(send(login_field))`.
|
881
|
+
# (`login_field` will fall back to `email_field` if there's no `login`
|
882
|
+
# or `username` column).
|
883
|
+
#
|
884
|
+
# In your User model you can make that method do anything you want,
|
885
|
+
# giving you complete control of how users are found by the UserSession.
|
886
|
+
#
|
887
|
+
# Let's take an example: You want to allow users to login by username or
|
888
|
+
# email. Set this to the name of the class method that does this in the
|
889
|
+
# User model. Let's call it "find_by_username_or_email"
|
890
|
+
#
|
891
|
+
# ```
|
892
|
+
# class User < ActiveRecord::Base
|
893
|
+
# def self.find_by_username_or_email(login)
|
894
|
+
# find_by_username(login) || find_by_email(login)
|
895
|
+
# end
|
896
|
+
# end
|
897
|
+
# ```
|
898
|
+
#
|
899
|
+
# Now just specify the name of this method for this configuration option
|
900
|
+
# and you are all set. You can do anything you want here. Maybe you
|
901
|
+
# allow users to have multiple logins and you want to search a has_many
|
902
|
+
# relationship, etc. The sky is the limit.
|
903
|
+
#
|
904
|
+
# * <tt>Default:</tt> "find_by_smart_case_login_field"
|
905
|
+
# * <tt>Accepts:</tt> Symbol or String
|
906
|
+
def record_selection_method(value = nil)
|
907
|
+
rw_config(:record_selection_method, value, "find_by_smart_case_login_field")
|
908
|
+
end
|
909
|
+
alias record_selection_method= record_selection_method
|
910
|
+
|
885
911
|
# Whether or not to request HTTP authentication
|
886
912
|
#
|
887
913
|
# If set to true and no HTTP authentication credentials are sent with
|
@@ -951,16 +977,40 @@ module Authlogic
|
|
951
977
|
end
|
952
978
|
alias secure= secure
|
953
979
|
|
980
|
+
# Should the Rack session ID be reset after authentication, to protect
|
981
|
+
# against Session Fixation attacks?
|
982
|
+
#
|
983
|
+
# * <tt>Default:</tt> true
|
984
|
+
# * <tt>Accepts:</tt> Boolean
|
985
|
+
def session_fixation_defense(value = nil)
|
986
|
+
rw_config(:session_fixation_defense, value, true)
|
987
|
+
end
|
988
|
+
alias session_fixation_defense= session_fixation_defense
|
989
|
+
|
954
990
|
# Should the cookie be signed? If the controller adapter supports it, this is a
|
955
991
|
# measure against cookie tampering.
|
956
992
|
def sign_cookie(value = nil)
|
957
|
-
if value && !controller.cookies.respond_to?(:signed)
|
993
|
+
if value && controller && !controller.cookies.respond_to?(:signed)
|
958
994
|
raise "Signed cookies not supported with #{controller.class}!"
|
959
995
|
end
|
960
996
|
rw_config(:sign_cookie, value, false)
|
961
997
|
end
|
962
998
|
alias sign_cookie= sign_cookie
|
963
999
|
|
1000
|
+
# Should the cookie be encrypted? If the controller adapter supports it, this is a
|
1001
|
+
# measure to hide the contents of the cookie (e.g. persistence_token)
|
1002
|
+
def encrypt_cookie(value = nil)
|
1003
|
+
if value && controller && !controller.cookies.respond_to?(:encrypted)
|
1004
|
+
raise "Encrypted cookies not supported with #{controller.class}!"
|
1005
|
+
end
|
1006
|
+
if value && sign_cookie
|
1007
|
+
raise "It is recommended to use encrypt_cookie instead of sign_cookie. " \
|
1008
|
+
"You may not enable both options."
|
1009
|
+
end
|
1010
|
+
rw_config(:encrypt_cookie, value, false)
|
1011
|
+
end
|
1012
|
+
alias encrypt_cookie= encrypt_cookie
|
1013
|
+
|
964
1014
|
# Works exactly like cookie_key, but for sessions. See cookie_key for more info.
|
965
1015
|
#
|
966
1016
|
# * <tt>Default:</tt> cookie_key
|
@@ -1065,24 +1115,10 @@ module Authlogic
|
|
1065
1115
|
# Constructor
|
1066
1116
|
# ===========
|
1067
1117
|
|
1068
|
-
# rubocop:disable Metrics/AbcSize
|
1069
1118
|
def initialize(*args)
|
1070
1119
|
@id = nil
|
1071
1120
|
self.scope = self.class.scope
|
1072
|
-
|
1073
|
-
# Creating an alias method for the "record" method based on the klass
|
1074
|
-
# name, so that we can do:
|
1075
|
-
#
|
1076
|
-
# session.user
|
1077
|
-
#
|
1078
|
-
# instead of:
|
1079
|
-
#
|
1080
|
-
# session.record
|
1081
|
-
unless self.class.configured_klass_methods
|
1082
|
-
self.class.send(:alias_method, klass_name.demodulize.underscore.to_sym, :record)
|
1083
|
-
self.class.configured_klass_methods = true
|
1084
|
-
end
|
1085
|
-
|
1121
|
+
define_record_alias_method
|
1086
1122
|
raise Activation::NotActivatedError unless self.class.activated?
|
1087
1123
|
unless self.class.configured_password_methods
|
1088
1124
|
configure_password_methods
|
@@ -1091,7 +1127,6 @@ module Authlogic
|
|
1091
1127
|
instance_variable_set("@#{password_field}", nil)
|
1092
1128
|
self.credentials = args
|
1093
1129
|
end
|
1094
|
-
# rubocop:enable Metrics/AbcSize
|
1095
1130
|
|
1096
1131
|
# Public instance methods
|
1097
1132
|
# =======================
|
@@ -1480,6 +1515,23 @@ module Authlogic
|
|
1480
1515
|
sign_cookie == true || sign_cookie == "true" || sign_cookie == "1"
|
1481
1516
|
end
|
1482
1517
|
|
1518
|
+
# If the cookie should be encrypted
|
1519
|
+
def encrypt_cookie
|
1520
|
+
return @encrypt_cookie if defined?(@encrypt_cookie)
|
1521
|
+
@encrypt_cookie = self.class.encrypt_cookie
|
1522
|
+
end
|
1523
|
+
|
1524
|
+
# Accepts a boolean as to whether the cookie should be encrypted. If true
|
1525
|
+
# the cookie will be saved in an encrypted state.
|
1526
|
+
def encrypt_cookie=(value)
|
1527
|
+
@encrypt_cookie = value
|
1528
|
+
end
|
1529
|
+
|
1530
|
+
# See encrypt_cookie
|
1531
|
+
def encrypt_cookie?
|
1532
|
+
encrypt_cookie == true || encrypt_cookie == "true" || encrypt_cookie == "1"
|
1533
|
+
end
|
1534
|
+
|
1483
1535
|
# The scope of the current object
|
1484
1536
|
def scope
|
1485
1537
|
@scope ||= {}
|
@@ -1497,24 +1549,21 @@ module Authlogic
|
|
1497
1549
|
# Determines if the information you provided for authentication is valid
|
1498
1550
|
# or not. If there is a problem with the information provided errors will
|
1499
1551
|
# be added to the errors object and this method will return false.
|
1552
|
+
#
|
1553
|
+
# @api public
|
1500
1554
|
def valid?
|
1501
1555
|
errors.clear
|
1502
1556
|
self.attempted_record = nil
|
1503
|
-
|
1504
|
-
run_callbacks(:before_validation)
|
1505
|
-
run_callbacks(new_session? ? :before_validation_on_create : :before_validation_on_update)
|
1557
|
+
run_the_before_validation_callbacks
|
1506
1558
|
|
1507
1559
|
# Run the `validate` callbacks, eg. `validate_by_password`.
|
1508
1560
|
# This is when `attempted_record` is set.
|
1509
1561
|
run_callbacks(:validate)
|
1510
1562
|
|
1511
1563
|
ensure_authentication_attempted
|
1512
|
-
|
1513
1564
|
if errors.empty?
|
1514
|
-
|
1515
|
-
run_callbacks(:after_validation)
|
1565
|
+
run_the_after_validation_callbacks
|
1516
1566
|
end
|
1517
|
-
|
1518
1567
|
save_record(attempted_record)
|
1519
1568
|
errors.empty?
|
1520
1569
|
end
|
@@ -1616,14 +1665,22 @@ module Authlogic
|
|
1616
1665
|
# @api private
|
1617
1666
|
# @return ::Authlogic::CookieCredentials or if no cookie is found, nil
|
1618
1667
|
def cookie_credentials
|
1668
|
+
return unless cookie_enabled?
|
1669
|
+
|
1619
1670
|
cookie_value = cookie_jar[cookie_key]
|
1620
1671
|
unless cookie_value.nil?
|
1621
1672
|
::Authlogic::CookieCredentials.parse(cookie_value)
|
1622
1673
|
end
|
1623
1674
|
end
|
1624
1675
|
|
1676
|
+
def cookie_enabled?
|
1677
|
+
!controller.cookies.nil?
|
1678
|
+
end
|
1679
|
+
|
1625
1680
|
def cookie_jar
|
1626
|
-
if self.class.
|
1681
|
+
if self.class.encrypt_cookie
|
1682
|
+
controller.cookies.encrypted
|
1683
|
+
elsif self.class.sign_cookie
|
1627
1684
|
controller.cookies.signed
|
1628
1685
|
else
|
1629
1686
|
controller.cookies
|
@@ -1635,21 +1692,36 @@ module Authlogic
|
|
1635
1692
|
define_password_field_methods
|
1636
1693
|
end
|
1637
1694
|
|
1695
|
+
# Assign a new controller-session ID, to defend against Session Fixation.
|
1696
|
+
# https://guides.rubyonrails.org/v6.0/security.html#session-fixation
|
1697
|
+
def renew_session_id
|
1698
|
+
return unless self.class.session_fixation_defense
|
1699
|
+
controller.renew_session_id
|
1700
|
+
end
|
1701
|
+
|
1638
1702
|
def define_login_field_methods
|
1639
1703
|
return unless login_field
|
1640
1704
|
self.class.send(:attr_writer, login_field) unless respond_to?("#{login_field}=")
|
1641
1705
|
self.class.send(:attr_reader, login_field) unless respond_to?(login_field)
|
1642
1706
|
end
|
1643
1707
|
|
1708
|
+
# @api private
|
1644
1709
|
def define_password_field_methods
|
1645
1710
|
return unless password_field
|
1646
|
-
|
1647
|
-
|
1711
|
+
define_password_field_writer_method
|
1712
|
+
define_password_field_reader_methods
|
1713
|
+
end
|
1648
1714
|
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1715
|
+
# The password should not be accessible publicly. This way forms using
|
1716
|
+
# form_for don't fill the password with the attempted password. To prevent
|
1717
|
+
# this we just create this method that is private.
|
1718
|
+
#
|
1719
|
+
# @api private
|
1720
|
+
def define_password_field_reader_methods
|
1721
|
+
unless respond_to?(password_field)
|
1722
|
+
# Deliberate no-op method, see rationale above.
|
1723
|
+
self.class.send(:define_method, password_field) {}
|
1724
|
+
end
|
1653
1725
|
self.class.class_eval(
|
1654
1726
|
<<-EOS, __FILE__, __LINE__ + 1
|
1655
1727
|
private
|
@@ -1660,6 +1732,28 @@ module Authlogic
|
|
1660
1732
|
)
|
1661
1733
|
end
|
1662
1734
|
|
1735
|
+
def define_password_field_writer_method
|
1736
|
+
unless respond_to?("#{password_field}=")
|
1737
|
+
self.class.send(:attr_writer, password_field)
|
1738
|
+
end
|
1739
|
+
end
|
1740
|
+
|
1741
|
+
# Creating an alias method for the "record" method based on the klass
|
1742
|
+
# name, so that we can do:
|
1743
|
+
#
|
1744
|
+
# session.user
|
1745
|
+
#
|
1746
|
+
# instead of:
|
1747
|
+
#
|
1748
|
+
# session.record
|
1749
|
+
#
|
1750
|
+
# @api private
|
1751
|
+
def define_record_alias_method
|
1752
|
+
noun = klass_name.demodulize.underscore.to_sym
|
1753
|
+
return if respond_to?(noun)
|
1754
|
+
self.class.send(:alias_method, noun, :record)
|
1755
|
+
end
|
1756
|
+
|
1663
1757
|
def destroy_cookie
|
1664
1758
|
controller.cookies.delete cookie_key, domain: controller.cookie_domain
|
1665
1759
|
end
|
@@ -1695,8 +1789,10 @@ module Authlogic
|
|
1695
1789
|
attempted_record.failed_login_count >= consecutive_failed_logins_limit
|
1696
1790
|
end
|
1697
1791
|
|
1792
|
+
# @deprecated in favor of `self.class.record_selection_method`
|
1698
1793
|
def find_by_login_method
|
1699
|
-
|
1794
|
+
::ActiveSupport::Deprecation.warn(E_DPR_FIND_BY_LOGIN_METHOD)
|
1795
|
+
self.class.record_selection_method
|
1700
1796
|
end
|
1701
1797
|
|
1702
1798
|
def generalize_credentials_error_messages?
|
@@ -1705,13 +1801,8 @@ module Authlogic
|
|
1705
1801
|
|
1706
1802
|
# @api private
|
1707
1803
|
def generate_cookie_for_saving
|
1708
|
-
creds = ::Authlogic::CookieCredentials.new(
|
1709
|
-
record.persistence_token,
|
1710
|
-
record.send(record.class.primary_key),
|
1711
|
-
remember_me? ? remember_me_until : nil
|
1712
|
-
)
|
1713
1804
|
{
|
1714
|
-
value:
|
1805
|
+
value: generate_cookie_value.to_s,
|
1715
1806
|
expires: remember_me_until,
|
1716
1807
|
secure: secure,
|
1717
1808
|
httponly: httponly,
|
@@ -1720,6 +1811,14 @@ module Authlogic
|
|
1720
1811
|
}
|
1721
1812
|
end
|
1722
1813
|
|
1814
|
+
def generate_cookie_value
|
1815
|
+
::Authlogic::CookieCredentials.new(
|
1816
|
+
record.persistence_token,
|
1817
|
+
record.send(record.class.primary_key),
|
1818
|
+
remember_me? ? remember_me_until : nil
|
1819
|
+
)
|
1820
|
+
end
|
1821
|
+
|
1723
1822
|
# Returns a Proc to be executed by
|
1724
1823
|
# `ActionController::HttpAuthentication::Basic` when credentials are
|
1725
1824
|
# present in the HTTP request.
|
@@ -1747,7 +1846,7 @@ module Authlogic
|
|
1747
1846
|
end
|
1748
1847
|
end
|
1749
1848
|
|
1750
|
-
def
|
1849
|
+
def increment_login_count
|
1751
1850
|
if record.respond_to?(:login_count)
|
1752
1851
|
record.login_count = (record.login_count.blank? ? 1 : record.login_count + 1)
|
1753
1852
|
end
|
@@ -1898,6 +1997,18 @@ module Authlogic
|
|
1898
1997
|
attempted_record.failed_login_count = 0
|
1899
1998
|
end
|
1900
1999
|
|
2000
|
+
# @api private
|
2001
|
+
def run_the_after_validation_callbacks
|
2002
|
+
run_callbacks(new_session? ? :after_validation_on_create : :after_validation_on_update)
|
2003
|
+
run_callbacks(:after_validation)
|
2004
|
+
end
|
2005
|
+
|
2006
|
+
# @api private
|
2007
|
+
def run_the_before_validation_callbacks
|
2008
|
+
run_callbacks(:before_validation)
|
2009
|
+
run_callbacks(new_session? ? :before_validation_on_create : :before_validation_on_update)
|
2010
|
+
end
|
2011
|
+
|
1901
2012
|
# `args[0]` is the name of a model method, like
|
1902
2013
|
# `find_by_single_access_token` or `find_by_smart_case_login_field`.
|
1903
2014
|
def search_for_record(*args)
|
@@ -1935,11 +2046,7 @@ module Authlogic
|
|
1935
2046
|
end
|
1936
2047
|
|
1937
2048
|
def save_cookie
|
1938
|
-
|
1939
|
-
controller.cookies.signed[cookie_key] = generate_cookie_for_saving
|
1940
|
-
else
|
1941
|
-
controller.cookies[cookie_key] = generate_cookie_for_saving
|
1942
|
-
end
|
2049
|
+
cookie_jar[cookie_key] = generate_cookie_for_saving
|
1943
2050
|
end
|
1944
2051
|
|
1945
2052
|
# @api private
|
@@ -1969,7 +2076,7 @@ module Authlogic
|
|
1969
2076
|
end
|
1970
2077
|
|
1971
2078
|
def update_info
|
1972
|
-
|
2079
|
+
increment_login_count
|
1973
2080
|
clear_failed_login_count
|
1974
2081
|
update_login_timestamps
|
1975
2082
|
update_login_ip_addresses
|
@@ -2016,7 +2123,10 @@ module Authlogic
|
|
2016
2123
|
self.invalid_password = false
|
2017
2124
|
validate_by_password__blank_fields
|
2018
2125
|
return if errors.count > 0
|
2019
|
-
self.attempted_record = search_for_record(
|
2126
|
+
self.attempted_record = search_for_record(
|
2127
|
+
self.class.record_selection_method,
|
2128
|
+
send(login_field)
|
2129
|
+
)
|
2020
2130
|
if attempted_record.blank?
|
2021
2131
|
add_login_not_found_error
|
2022
2132
|
return
|