authlogic 4.4.2 → 5.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/lib/authlogic.rb +4 -28
- data/lib/authlogic/acts_as_authentic/base.rb +3 -18
- data/lib/authlogic/acts_as_authentic/email.rb +3 -170
- data/lib/authlogic/acts_as_authentic/logged_in_status.rb +3 -1
- data/lib/authlogic/acts_as_authentic/login.rb +7 -174
- data/lib/authlogic/acts_as_authentic/magic_columns.rb +7 -4
- data/lib/authlogic/acts_as_authentic/password.rb +54 -253
- data/lib/authlogic/acts_as_authentic/perishable_token.rb +8 -5
- data/lib/authlogic/acts_as_authentic/persistence_token.rb +10 -4
- data/lib/authlogic/acts_as_authentic/queries/case_sensitivity.rb +53 -0
- data/lib/authlogic/acts_as_authentic/queries/find_with_case.rb +36 -20
- data/lib/authlogic/acts_as_authentic/session_maintenance.rb +8 -6
- data/lib/authlogic/acts_as_authentic/single_access_token.rb +10 -8
- data/lib/authlogic/config.rb +9 -1
- data/lib/authlogic/controller_adapters/abstract_adapter.rb +7 -4
- data/lib/authlogic/controller_adapters/rack_adapter.rb +2 -0
- data/lib/authlogic/controller_adapters/rails_adapter.rb +19 -19
- data/lib/authlogic/controller_adapters/sinatra_adapter.rb +6 -0
- data/lib/authlogic/cookie_credentials.rb +63 -0
- data/lib/authlogic/crypto_providers.rb +5 -20
- data/lib/authlogic/crypto_providers/bcrypt.rb +3 -3
- data/lib/authlogic/crypto_providers/md5.rb +3 -6
- data/lib/authlogic/crypto_providers/scrypt.rb +2 -0
- data/lib/authlogic/crypto_providers/sha1.rb +4 -6
- data/lib/authlogic/crypto_providers/sha256.rb +2 -0
- data/lib/authlogic/crypto_providers/sha512.rb +6 -5
- data/lib/authlogic/i18n.rb +3 -1
- data/lib/authlogic/i18n/translator.rb +3 -0
- data/lib/authlogic/random.rb +2 -0
- data/lib/authlogic/session/base.rb +2087 -39
- data/lib/authlogic/session/magic_column/assigns_last_request_at.rb +46 -0
- data/lib/authlogic/test_case.rb +4 -0
- data/lib/authlogic/test_case/mock_controller.rb +2 -0
- data/lib/authlogic/test_case/mock_cookie_jar.rb +7 -0
- data/lib/authlogic/test_case/mock_logger.rb +2 -0
- data/lib/authlogic/test_case/mock_request.rb +2 -0
- data/lib/authlogic/test_case/rails_request_adapter.rb +2 -0
- data/lib/authlogic/version.rb +2 -1
- metadata +136 -182
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -28
- data/.github/ISSUE_TEMPLATE/feature_proposal.md +0 -32
- data/.github/triage.md +0 -86
- data/.gitignore +0 -15
- data/.rubocop.yml +0 -133
- data/.rubocop_todo.yml +0 -74
- data/.travis.yml +0 -24
- data/CHANGELOG.md +0 -326
- data/CONTRIBUTING.md +0 -91
- data/Gemfile +0 -6
- data/LICENSE +0 -20
- data/README.md +0 -439
- data/Rakefile +0 -21
- data/UPGRADING.md +0 -22
- data/authlogic.gemspec +0 -40
- data/doc/use_normal_rails_validation.md +0 -82
- data/gemfiles/Gemfile.rails-4.2.x +0 -6
- data/gemfiles/Gemfile.rails-5.1.x +0 -6
- data/gemfiles/Gemfile.rails-5.2.x +0 -6
- data/lib/authlogic/acts_as_authentic/restful_authentication.rb +0 -106
- data/lib/authlogic/acts_as_authentic/validations_scope.rb +0 -35
- data/lib/authlogic/authenticates_many/association.rb +0 -50
- data/lib/authlogic/authenticates_many/base.rb +0 -81
- data/lib/authlogic/crypto_providers/aes256.rb +0 -71
- data/lib/authlogic/crypto_providers/wordpress.rb +0 -72
- data/lib/authlogic/regex.rb +0 -79
- data/lib/authlogic/session/activation.rb +0 -73
- data/lib/authlogic/session/active_record_trickery.rb +0 -65
- data/lib/authlogic/session/brute_force_protection.rb +0 -127
- data/lib/authlogic/session/callbacks.rb +0 -153
- data/lib/authlogic/session/cookies.rb +0 -296
- data/lib/authlogic/session/existence.rb +0 -103
- data/lib/authlogic/session/foundation.rb +0 -105
- data/lib/authlogic/session/http_auth.rb +0 -107
- data/lib/authlogic/session/id.rb +0 -53
- data/lib/authlogic/session/klass.rb +0 -73
- data/lib/authlogic/session/magic_columns.rb +0 -119
- data/lib/authlogic/session/magic_states.rb +0 -82
- data/lib/authlogic/session/params.rb +0 -130
- data/lib/authlogic/session/password.rb +0 -318
- data/lib/authlogic/session/perishable_token.rb +0 -24
- data/lib/authlogic/session/persistence.rb +0 -77
- data/lib/authlogic/session/priority_record.rb +0 -38
- data/lib/authlogic/session/scopes.rb +0 -138
- data/lib/authlogic/session/session.rb +0 -77
- data/lib/authlogic/session/timeout.rb +0 -103
- data/lib/authlogic/session/unauthorized_record.rb +0 -56
- data/lib/authlogic/session/validation.rb +0 -93
- data/test/acts_as_authentic_test/base_test.rb +0 -27
- data/test/acts_as_authentic_test/email_test.rb +0 -241
- data/test/acts_as_authentic_test/logged_in_status_test.rb +0 -64
- data/test/acts_as_authentic_test/login_test.rb +0 -153
- data/test/acts_as_authentic_test/magic_columns_test.rb +0 -29
- data/test/acts_as_authentic_test/password_test.rb +0 -263
- data/test/acts_as_authentic_test/perishable_token_test.rb +0 -98
- data/test/acts_as_authentic_test/persistence_token_test.rb +0 -62
- data/test/acts_as_authentic_test/restful_authentication_test.rb +0 -48
- data/test/acts_as_authentic_test/session_maintenance_test.rb +0 -150
- data/test/acts_as_authentic_test/single_access_test.rb +0 -46
- data/test/adapter_test.rb +0 -23
- data/test/authenticates_many_test.rb +0 -33
- data/test/config_test.rb +0 -38
- data/test/crypto_provider_test/aes256_test.rb +0 -16
- data/test/crypto_provider_test/bcrypt_test.rb +0 -16
- data/test/crypto_provider_test/scrypt_test.rb +0 -16
- data/test/crypto_provider_test/sha1_test.rb +0 -25
- data/test/crypto_provider_test/sha256_test.rb +0 -16
- data/test/crypto_provider_test/sha512_test.rb +0 -16
- data/test/crypto_provider_test/wordpress_test.rb +0 -26
- data/test/fixtures/companies.yml +0 -5
- data/test/fixtures/employees.yml +0 -17
- data/test/fixtures/projects.yml +0 -3
- data/test/fixtures/users.yml +0 -41
- data/test/i18n/lol.yml +0 -4
- data/test/i18n_test.rb +0 -35
- data/test/libs/affiliate.rb +0 -9
- data/test/libs/company.rb +0 -8
- data/test/libs/employee.rb +0 -9
- data/test/libs/employee_session.rb +0 -4
- data/test/libs/ldaper.rb +0 -5
- data/test/libs/project.rb +0 -5
- data/test/libs/user.rb +0 -9
- data/test/libs/user_session.rb +0 -27
- data/test/random_test.rb +0 -15
- data/test/session_test/activation_test.rb +0 -45
- data/test/session_test/active_record_trickery_test.rb +0 -78
- data/test/session_test/brute_force_protection_test.rb +0 -110
- data/test/session_test/callbacks_test.rb +0 -42
- data/test/session_test/cookies_test.rb +0 -226
- data/test/session_test/credentials_test.rb +0 -0
- data/test/session_test/existence_test.rb +0 -88
- data/test/session_test/foundation_test.rb +0 -24
- data/test/session_test/http_auth_test.rb +0 -60
- data/test/session_test/id_test.rb +0 -19
- data/test/session_test/klass_test.rb +0 -42
- data/test/session_test/magic_columns_test.rb +0 -62
- data/test/session_test/magic_states_test.rb +0 -60
- data/test/session_test/params_test.rb +0 -61
- data/test/session_test/password_test.rb +0 -107
- data/test/session_test/perishability_test.rb +0 -17
- data/test/session_test/persistence_test.rb +0 -35
- data/test/session_test/scopes_test.rb +0 -68
- data/test/session_test/session_test.rb +0 -80
- data/test/session_test/timeout_test.rb +0 -84
- data/test/session_test/unauthorized_record_test.rb +0 -15
- data/test/session_test/validation_test.rb +0 -25
- data/test/test_helper.rb +0 -272
@@ -1,105 +0,0 @@
|
|
1
|
-
module Authlogic
|
2
|
-
module Session
|
3
|
-
# Sort of like an interface, it sets the foundation for the class, such as the
|
4
|
-
# required methods. This also allows other modules to overwrite methods and call super
|
5
|
-
# on them. It's also a place to put "utility" methods used throughout Authlogic.
|
6
|
-
module Foundation
|
7
|
-
def self.included(klass)
|
8
|
-
klass.class_eval do
|
9
|
-
extend Authlogic::Config
|
10
|
-
include InstanceMethods
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
module InstanceMethods
|
15
|
-
E_AC_PARAMETERS = <<~EOS.freeze
|
16
|
-
Passing an ActionController::Parameters to Authlogic is not allowed.
|
17
|
-
|
18
|
-
In Authlogic 3, especially during the transition of rails to Strong
|
19
|
-
Parameters, it was common for Authlogic users to forget to `permit`
|
20
|
-
their params. They would pass their params into Authlogic, we'd call
|
21
|
-
`to_h`, and they'd be surprised when authentication failed.
|
22
|
-
|
23
|
-
In 2018, people are still making this mistake. We'd like to help them
|
24
|
-
and make authlogic a little simpler at the same time, so in Authlogic
|
25
|
-
3.7.0, we deprecated the use of ActionController::Parameters. Instead,
|
26
|
-
pass a plain Hash. Please replace:
|
27
|
-
|
28
|
-
UserSession.new(user_session_params)
|
29
|
-
UserSession.create(user_session_params)
|
30
|
-
|
31
|
-
with
|
32
|
-
|
33
|
-
UserSession.new(user_session_params.to_h)
|
34
|
-
UserSession.create(user_session_params.to_h)
|
35
|
-
|
36
|
-
And don't forget to `permit`!
|
37
|
-
|
38
|
-
We discussed this issue thoroughly between late 2016 and early
|
39
|
-
2018. Notable discussions include:
|
40
|
-
|
41
|
-
- https://github.com/binarylogic/authlogic/issues/512
|
42
|
-
- https://github.com/binarylogic/authlogic/pull/558
|
43
|
-
- https://github.com/binarylogic/authlogic/pull/577
|
44
|
-
EOS
|
45
|
-
|
46
|
-
def initialize(*args)
|
47
|
-
self.credentials = args
|
48
|
-
end
|
49
|
-
|
50
|
-
# The credentials you passed to create your session. See credentials= for more
|
51
|
-
# info.
|
52
|
-
def credentials
|
53
|
-
[]
|
54
|
-
end
|
55
|
-
|
56
|
-
# Set your credentials before you save your session. There are many
|
57
|
-
# method signatures.
|
58
|
-
#
|
59
|
-
# ```
|
60
|
-
# # A hash of credentials is most common
|
61
|
-
# session.credentials = { login: "foo", password: "bar", remember_me: true }
|
62
|
-
#
|
63
|
-
# # You must pass an actual Hash, `ActionController::Parameters` is
|
64
|
-
# # specifically not allowed.
|
65
|
-
#
|
66
|
-
# # You can pass an array of objects:
|
67
|
-
# session.credentials = [my_user_object, true]
|
68
|
-
#
|
69
|
-
# # If you need to set an id (see `Authlogic::Session::Id`) pass it
|
70
|
-
# # last. It needs be the last item in the array you pass, since the id
|
71
|
-
# # is something that you control yourself, it should never be set from
|
72
|
-
# # a hash or a form. Examples:
|
73
|
-
# session.credentials = [
|
74
|
-
# {:login => "foo", :password => "bar", :remember_me => true},
|
75
|
-
# :my_id
|
76
|
-
# ]
|
77
|
-
# session.credentials = [my_user_object, true, :my_id]
|
78
|
-
#
|
79
|
-
# # Finally, there's priority_record
|
80
|
-
# [{ priority_record: my_object }, :my_id]
|
81
|
-
# ```
|
82
|
-
def credentials=(values)
|
83
|
-
normalized = Array.wrap(values)
|
84
|
-
if normalized.first.class.name == "ActionController::Parameters"
|
85
|
-
raise TypeError.new(E_AC_PARAMETERS)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def inspect
|
90
|
-
format(
|
91
|
-
"#<%s: %s>",
|
92
|
-
self.class.name,
|
93
|
-
credentials.blank? ? "no credentials provided" : credentials.inspect
|
94
|
-
)
|
95
|
-
end
|
96
|
-
|
97
|
-
private
|
98
|
-
|
99
|
-
def build_key(last_part)
|
100
|
-
last_part
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
@@ -1,107 +0,0 @@
|
|
1
|
-
module Authlogic
|
2
|
-
module Session
|
3
|
-
# Handles all authentication that deals with basic HTTP auth. Which is
|
4
|
-
# authentication built into the HTTP protocol:
|
5
|
-
#
|
6
|
-
# http://username:password@whatever.com
|
7
|
-
#
|
8
|
-
# Also, if you are not comfortable letting users pass their raw username and
|
9
|
-
# password you can always use the single access token. See
|
10
|
-
# Authlogic::Session::Params for more info.
|
11
|
-
module HttpAuth
|
12
|
-
def self.included(klass)
|
13
|
-
klass.class_eval do
|
14
|
-
extend Config
|
15
|
-
include InstanceMethods
|
16
|
-
persist :persist_by_http_auth, if: :persist_by_http_auth?
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# Configuration for the HTTP basic auth feature of Authlogic.
|
21
|
-
module Config
|
22
|
-
# Do you want to allow your users to log in via HTTP basic auth?
|
23
|
-
#
|
24
|
-
# I recommend keeping this enabled. The only time I feel this should be
|
25
|
-
# disabled is if you are not comfortable having your users provide their
|
26
|
-
# raw username and password. Whatever the reason, you can disable it
|
27
|
-
# here.
|
28
|
-
#
|
29
|
-
# * <tt>Default:</tt> true
|
30
|
-
# * <tt>Accepts:</tt> Boolean
|
31
|
-
def allow_http_basic_auth(value = nil)
|
32
|
-
rw_config(:allow_http_basic_auth, value, false)
|
33
|
-
end
|
34
|
-
alias_method :allow_http_basic_auth=, :allow_http_basic_auth
|
35
|
-
|
36
|
-
# Whether or not to request HTTP authentication
|
37
|
-
#
|
38
|
-
# If set to true and no HTTP authentication credentials are sent with
|
39
|
-
# the request, the Rails controller method
|
40
|
-
# authenticate_or_request_with_http_basic will be used and a '401
|
41
|
-
# Authorization Required' header will be sent with the response. In
|
42
|
-
# most cases, this will cause the classic HTTP authentication popup to
|
43
|
-
# appear in the users browser.
|
44
|
-
#
|
45
|
-
# If set to false, the Rails controller method
|
46
|
-
# authenticate_with_http_basic is used and no 401 header is sent.
|
47
|
-
#
|
48
|
-
# Note: This parameter has no effect unless allow_http_basic_auth is
|
49
|
-
# true
|
50
|
-
#
|
51
|
-
# * <tt>Default:</tt> false
|
52
|
-
# * <tt>Accepts:</tt> Boolean
|
53
|
-
def request_http_basic_auth(value = nil)
|
54
|
-
rw_config(:request_http_basic_auth, value, false)
|
55
|
-
end
|
56
|
-
alias_method :request_http_basic_auth=, :request_http_basic_auth
|
57
|
-
|
58
|
-
# HTTP authentication realm
|
59
|
-
#
|
60
|
-
# Sets the HTTP authentication realm.
|
61
|
-
#
|
62
|
-
# Note: This option has no effect unless request_http_basic_auth is true
|
63
|
-
#
|
64
|
-
# * <tt>Default:</tt> 'Application'
|
65
|
-
# * <tt>Accepts:</tt> String
|
66
|
-
def http_basic_auth_realm(value = nil)
|
67
|
-
rw_config(:http_basic_auth_realm, value, "Application")
|
68
|
-
end
|
69
|
-
alias_method :http_basic_auth_realm=, :http_basic_auth_realm
|
70
|
-
end
|
71
|
-
|
72
|
-
# Instance methods for the HTTP basic auth feature of authlogic.
|
73
|
-
module InstanceMethods
|
74
|
-
private
|
75
|
-
|
76
|
-
def persist_by_http_auth?
|
77
|
-
allow_http_basic_auth? && login_field && password_field
|
78
|
-
end
|
79
|
-
|
80
|
-
def persist_by_http_auth
|
81
|
-
login_proc = proc do |login, password|
|
82
|
-
if !login.blank? && !password.blank?
|
83
|
-
send("#{login_field}=", login)
|
84
|
-
send("#{password_field}=", password)
|
85
|
-
valid?
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
if self.class.request_http_basic_auth
|
90
|
-
controller.authenticate_or_request_with_http_basic(
|
91
|
-
self.class.http_basic_auth_realm,
|
92
|
-
&login_proc
|
93
|
-
)
|
94
|
-
else
|
95
|
-
controller.authenticate_with_http_basic(&login_proc)
|
96
|
-
end
|
97
|
-
|
98
|
-
false
|
99
|
-
end
|
100
|
-
|
101
|
-
def allow_http_basic_auth?
|
102
|
-
self.class.allow_http_basic_auth == true
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
data/lib/authlogic/session/id.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
module Authlogic
|
2
|
-
module Session
|
3
|
-
# Allows you to separate sessions with an id, ultimately letting you create
|
4
|
-
# multiple sessions for the same user.
|
5
|
-
module Id
|
6
|
-
def initialize(*args)
|
7
|
-
@id = nil
|
8
|
-
super
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.included(klass)
|
12
|
-
klass.class_eval do
|
13
|
-
attr_writer :id
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
# Setting the id if it is passed in the credentials.
|
18
|
-
def credentials=(value)
|
19
|
-
super
|
20
|
-
values = value.is_a?(Array) ? value : [value]
|
21
|
-
self.id = values.last if values.last.is_a?(Symbol)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Allows you to set a unique identifier for your session, so that you can
|
25
|
-
# have more than 1 session at a time. A good example when this might be
|
26
|
-
# needed is when you want to have a normal user session and a "secure"
|
27
|
-
# user session. The secure user session would be created only when they
|
28
|
-
# want to modify their billing information, or other sensitive
|
29
|
-
# information. Similar to me.com. This requires 2 user sessions. Just use
|
30
|
-
# an id for the "secure" session and you should be good.
|
31
|
-
#
|
32
|
-
# You can set the id during initialization (see initialize for more
|
33
|
-
# information), or as an attribute:
|
34
|
-
#
|
35
|
-
# session.id = :my_id
|
36
|
-
#
|
37
|
-
# Just be sure and set your id before you save your session.
|
38
|
-
#
|
39
|
-
# Lastly, to retrieve your session with the id check out the find class
|
40
|
-
# method.
|
41
|
-
def id
|
42
|
-
@id
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
# Used for things like cookie_key, session_key, etc.
|
48
|
-
def build_key(last_part)
|
49
|
-
[id, super].compact.join("_")
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
module Authlogic
|
2
|
-
module Session
|
3
|
-
# Handles authenticating via a traditional username and password.
|
4
|
-
module Klass
|
5
|
-
def self.included(klass)
|
6
|
-
klass.class_eval do
|
7
|
-
extend Config
|
8
|
-
include InstanceMethods
|
9
|
-
|
10
|
-
class << self
|
11
|
-
attr_accessor :configured_klass_methods
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
module Config
|
17
|
-
# Lets you change which model to use for authentication.
|
18
|
-
#
|
19
|
-
# * <tt>Default:</tt> inferred from the class name. UserSession would
|
20
|
-
# automatically try User
|
21
|
-
# * <tt>Accepts:</tt> an ActiveRecord class
|
22
|
-
def authenticate_with(klass)
|
23
|
-
@klass_name = klass.name
|
24
|
-
@klass = klass
|
25
|
-
end
|
26
|
-
alias_method :authenticate_with=, :authenticate_with
|
27
|
-
|
28
|
-
# The name of the class that this session is authenticating with. For
|
29
|
-
# example, the UserSession class will authenticate with the User class
|
30
|
-
# unless you specify otherwise in your configuration. See
|
31
|
-
# authenticate_with for information on how to change this value.
|
32
|
-
def klass
|
33
|
-
@klass ||= klass_name ? klass_name.constantize : nil
|
34
|
-
end
|
35
|
-
|
36
|
-
# The string of the model name class guessed from the actual session class name.
|
37
|
-
def klass_name
|
38
|
-
return @klass_name if defined?(@klass_name)
|
39
|
-
@klass_name = name.scan(/(.*)Session/)[0]
|
40
|
-
@klass_name = klass_name ? klass_name[0] : nil
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
module InstanceMethods
|
45
|
-
# Creating an alias method for the "record" method based on the klass
|
46
|
-
# name, so that we can do:
|
47
|
-
#
|
48
|
-
# session.user
|
49
|
-
#
|
50
|
-
# instead of:
|
51
|
-
#
|
52
|
-
# session.record
|
53
|
-
def initialize(*args)
|
54
|
-
unless self.class.configured_klass_methods
|
55
|
-
self.class.send(:alias_method, klass_name.demodulize.underscore.to_sym, :record)
|
56
|
-
self.class.configured_klass_methods = true
|
57
|
-
end
|
58
|
-
super
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
def klass
|
64
|
-
self.class.klass
|
65
|
-
end
|
66
|
-
|
67
|
-
def klass_name
|
68
|
-
self.class.klass_name
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,119 +0,0 @@
|
|
1
|
-
module Authlogic
|
2
|
-
module Session
|
3
|
-
# Just like ActiveRecord has "magic" columns, such as: created_at and updated_at.
|
4
|
-
# Authlogic has its own "magic" columns too:
|
5
|
-
#
|
6
|
-
# * login_count - Increased every time an explicit login is made. This will *NOT*
|
7
|
-
# increase if logging in by a session, cookie, or basic http auth
|
8
|
-
# * failed_login_count - This increases for each consecutive failed login. See
|
9
|
-
# Authlogic::Session::BruteForceProtection and the consecutive_failed_logins_limit
|
10
|
-
# config option for more details.
|
11
|
-
# * last_request_at - Updates every time the user logs in, either by explicitly
|
12
|
-
# logging in, or logging in by cookie, session, or http auth
|
13
|
-
# * current_login_at - Updates with the current time when an explicit login is made.
|
14
|
-
# * last_login_at - Updates with the value of current_login_at before it is reset.
|
15
|
-
# * current_login_ip - Updates with the request ip when an explicit login is made.
|
16
|
-
# * last_login_ip - Updates with the value of current_login_ip before it is reset.
|
17
|
-
module MagicColumns
|
18
|
-
def self.included(klass)
|
19
|
-
klass.class_eval do
|
20
|
-
extend Config
|
21
|
-
include InstanceMethods
|
22
|
-
after_persisting :set_last_request_at, if: :set_last_request_at?
|
23
|
-
validate :increase_failed_login_count
|
24
|
-
before_save :update_info
|
25
|
-
before_save :set_last_request_at, if: :set_last_request_at?
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# Configuration for the magic columns feature.
|
30
|
-
module Config
|
31
|
-
# Every time a session is found the last_request_at field for that record is
|
32
|
-
# updated with the current time, if that field exists. If you want to limit how
|
33
|
-
# frequent that field is updated specify the threshold here. For example, if your
|
34
|
-
# user is making a request every 5 seconds, and you feel this is too frequent, and
|
35
|
-
# feel a minute is a good threshold. Set this to 1.minute. Once a minute has
|
36
|
-
# passed in between requests the field will be updated.
|
37
|
-
#
|
38
|
-
# * <tt>Default:</tt> 0
|
39
|
-
# * <tt>Accepts:</tt> integer representing time in seconds
|
40
|
-
def last_request_at_threshold(value = nil)
|
41
|
-
rw_config(:last_request_at_threshold, value, 0)
|
42
|
-
end
|
43
|
-
alias_method :last_request_at_threshold=, :last_request_at_threshold
|
44
|
-
end
|
45
|
-
|
46
|
-
# The methods available for an Authlogic::Session::Base object that make
|
47
|
-
# up the magic columns feature.
|
48
|
-
module InstanceMethods
|
49
|
-
private
|
50
|
-
|
51
|
-
def clear_failed_login_count
|
52
|
-
if record.respond_to?(:failed_login_count)
|
53
|
-
record.failed_login_count = 0
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def increase_failed_login_count
|
58
|
-
if invalid_password? && attempted_record.respond_to?(:failed_login_count)
|
59
|
-
attempted_record.failed_login_count ||= 0
|
60
|
-
attempted_record.failed_login_count += 1
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def increment_login_cout
|
65
|
-
if record.respond_to?(:login_count)
|
66
|
-
record.login_count = (record.login_count.blank? ? 1 : record.login_count + 1)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def update_info
|
71
|
-
increment_login_cout
|
72
|
-
clear_failed_login_count
|
73
|
-
update_login_timestamps
|
74
|
-
update_login_ip_addresses
|
75
|
-
end
|
76
|
-
|
77
|
-
def update_login_ip_addresses
|
78
|
-
if record.respond_to?(:current_login_ip)
|
79
|
-
record.last_login_ip = record.current_login_ip if record.respond_to?(:last_login_ip)
|
80
|
-
record.current_login_ip = controller.request.ip
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def update_login_timestamps
|
85
|
-
if record.respond_to?(:current_login_at)
|
86
|
-
record.last_login_at = record.current_login_at if record.respond_to?(:last_login_at)
|
87
|
-
record.current_login_at = klass.default_timezone == :utc ? Time.now.utc : Time.now
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
# This method lets authlogic know whether it should allow the
|
92
|
-
# last_request_at field to be updated with the current time.
|
93
|
-
#
|
94
|
-
# See also `last_request_update_allowed?` in
|
95
|
-
# `Authlogic::ControllerAdapters::AbstractAdapter`
|
96
|
-
#
|
97
|
-
# @api private
|
98
|
-
def set_last_request_at?
|
99
|
-
if !record || !klass.column_names.include?("last_request_at")
|
100
|
-
return false
|
101
|
-
end
|
102
|
-
unless controller.last_request_update_allowed?
|
103
|
-
return false
|
104
|
-
end
|
105
|
-
record.last_request_at.blank? ||
|
106
|
-
last_request_at_threshold.to_i.seconds.ago >= record.last_request_at
|
107
|
-
end
|
108
|
-
|
109
|
-
def set_last_request_at
|
110
|
-
record.last_request_at = klass.default_timezone == :utc ? Time.now.utc : Time.now
|
111
|
-
end
|
112
|
-
|
113
|
-
def last_request_at_threshold
|
114
|
-
self.class.last_request_at_threshold
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|