authlogic 4.5.0 → 6.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/authlogic/acts_as_authentic/base.rb +19 -19
- 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 +67 -256
- 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 +12 -8
- 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 +28 -4
- data/lib/authlogic/controller_adapters/rack_adapter.rb +2 -0
- data/lib/authlogic/controller_adapters/rails_adapter.rb +7 -30
- data/lib/authlogic/controller_adapters/sinatra_adapter.rb +6 -0
- data/lib/authlogic/cookie_credentials.rb +63 -0
- data/lib/authlogic/crypto_providers/bcrypt.rb +3 -3
- data/lib/authlogic/crypto_providers/md5/v2.rb +35 -0
- data/lib/authlogic/crypto_providers/md5.rb +6 -6
- data/lib/authlogic/crypto_providers/scrypt.rb +2 -0
- data/lib/authlogic/crypto_providers/sha1/v2.rb +41 -0
- data/lib/authlogic/crypto_providers/sha1.rb +7 -6
- data/lib/authlogic/crypto_providers/sha256/v2.rb +58 -0
- data/lib/authlogic/crypto_providers/sha256.rb +5 -0
- data/lib/authlogic/crypto_providers/sha512/v2.rb +39 -0
- data/lib/authlogic/crypto_providers/sha512.rb +9 -5
- data/lib/authlogic/crypto_providers.rb +5 -20
- data/lib/authlogic/errors.rb +50 -0
- data/lib/authlogic/i18n/translator.rb +4 -1
- data/lib/authlogic/i18n.rb +3 -1
- data/lib/authlogic/random.rb +2 -0
- data/lib/authlogic/session/base.rb +2197 -39
- data/lib/authlogic/session/magic_column/assigns_last_request_at.rb +46 -0
- data/lib/authlogic/test_case/mock_api_controller.rb +52 -0
- data/lib/authlogic/test_case/mock_controller.rb +3 -1
- data/lib/authlogic/test_case/mock_cookie_jar.rb +32 -6
- data/lib/authlogic/test_case/mock_logger.rb +2 -0
- data/lib/authlogic/test_case/mock_request.rb +12 -0
- data/lib/authlogic/test_case/rails_request_adapter.rb +9 -1
- data/lib/authlogic/test_case.rb +5 -0
- data/lib/authlogic/version.rb +2 -1
- data/lib/authlogic.rb +5 -28
- metadata +175 -200
- 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 -348
- data/CONTRIBUTING.md +0 -91
- data/Gemfile +0 -6
- data/LICENSE +0 -20
- data/README.md +0 -448
- 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 -329
- 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 -244
- 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,103 +0,0 @@
|
|
1
|
-
module Authlogic
|
2
|
-
module Session
|
3
|
-
# Provides methods to create and destroy objects. Basically controls their
|
4
|
-
# "existence".
|
5
|
-
module Existence
|
6
|
-
class SessionInvalidError < ::StandardError # :nodoc:
|
7
|
-
def initialize(session)
|
8
|
-
message = I18n.t(
|
9
|
-
"error_messages.session_invalid",
|
10
|
-
default: "Your session is invalid and has the following errors:"
|
11
|
-
)
|
12
|
-
message += " #{session.errors.full_messages.to_sentence}"
|
13
|
-
super message
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.included(klass)
|
18
|
-
klass.class_eval do
|
19
|
-
extend ClassMethods
|
20
|
-
include InstanceMethods
|
21
|
-
attr_accessor :new_session, :record
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
module ClassMethods
|
26
|
-
# A convenience method. The same as:
|
27
|
-
#
|
28
|
-
# session = UserSession.new(*args)
|
29
|
-
# session.save
|
30
|
-
#
|
31
|
-
# Instead you can do:
|
32
|
-
#
|
33
|
-
# UserSession.create(*args)
|
34
|
-
def create(*args, &block)
|
35
|
-
session = new(*args)
|
36
|
-
session.save(&block)
|
37
|
-
session
|
38
|
-
end
|
39
|
-
|
40
|
-
# Same as create but calls create!, which raises an exception when validation fails.
|
41
|
-
def create!(*args)
|
42
|
-
session = new(*args)
|
43
|
-
session.save!
|
44
|
-
session
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
module InstanceMethods
|
49
|
-
# Clears all errors and the associated record, you should call this
|
50
|
-
# terminate a session, thus requiring the user to authenticate again if
|
51
|
-
# it is needed.
|
52
|
-
def destroy
|
53
|
-
before_destroy
|
54
|
-
save_record
|
55
|
-
errors.clear
|
56
|
-
@record = nil
|
57
|
-
after_destroy
|
58
|
-
true
|
59
|
-
end
|
60
|
-
|
61
|
-
# Returns true if the session is new, meaning no action has been taken
|
62
|
-
# on it and a successful save has not taken place.
|
63
|
-
def new_session?
|
64
|
-
new_session != false
|
65
|
-
end
|
66
|
-
|
67
|
-
# After you have specified all of the details for your session you can
|
68
|
-
# try to save it. This will run validation checks and find the
|
69
|
-
# associated record, if all validation passes. If validation does not
|
70
|
-
# pass, the save will fail and the errors will be stored in the errors
|
71
|
-
# object.
|
72
|
-
def save
|
73
|
-
result = nil
|
74
|
-
if valid?
|
75
|
-
self.record = attempted_record
|
76
|
-
|
77
|
-
before_save
|
78
|
-
new_session? ? before_create : before_update
|
79
|
-
new_session? ? after_create : after_update
|
80
|
-
after_save
|
81
|
-
|
82
|
-
save_record
|
83
|
-
self.new_session = false
|
84
|
-
result = true
|
85
|
-
else
|
86
|
-
result = false
|
87
|
-
end
|
88
|
-
|
89
|
-
yield result if block_given?
|
90
|
-
result
|
91
|
-
end
|
92
|
-
|
93
|
-
# Same as save but raises an exception of validation errors when
|
94
|
-
# validation fails
|
95
|
-
def save!
|
96
|
-
result = save
|
97
|
-
raise SessionInvalidError.new(self) unless result
|
98
|
-
result
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
@@ -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
|
@@ -1,82 +0,0 @@
|
|
1
|
-
module Authlogic
|
2
|
-
module Session
|
3
|
-
# Authlogic tries to check the state of the record before creating the session. If
|
4
|
-
# your record responds to the following methods and any of them return false,
|
5
|
-
# validation will fail:
|
6
|
-
#
|
7
|
-
# Method name Description
|
8
|
-
# active? Is the record marked as active?
|
9
|
-
# approved? Has the record been approved?
|
10
|
-
# confirmed? Has the record been confirmed?
|
11
|
-
#
|
12
|
-
# Authlogic does nothing to define these methods for you, its up to you to define what
|
13
|
-
# they mean. If your object responds to these methods Authlogic will use them,
|
14
|
-
# otherwise they are ignored.
|
15
|
-
#
|
16
|
-
# What's neat about this is that these are checked upon any type of login. When
|
17
|
-
# logging in explicitly, by cookie, session, or basic http auth. So if you mark a user
|
18
|
-
# inactive in the middle of their session they wont be logged back in next time they
|
19
|
-
# refresh the page. Giving you complete control.
|
20
|
-
#
|
21
|
-
# Need Authlogic to check your own "state"? No problem, check out the hooks section
|
22
|
-
# below. Add in a before_validation to do your own checking. The sky is the limit.
|
23
|
-
module MagicStates
|
24
|
-
def self.included(klass)
|
25
|
-
klass.class_eval do
|
26
|
-
extend Config
|
27
|
-
include InstanceMethods
|
28
|
-
validate :validate_magic_states, unless: :disable_magic_states?
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Configuration for the magic states feature.
|
33
|
-
module Config
|
34
|
-
# Set this to true if you want to disable the checking of active?, approved?, and
|
35
|
-
# confirmed? on your record. This is more or less of a convenience feature, since
|
36
|
-
# 99% of the time if those methods exist and return false you will not want the
|
37
|
-
# user logging in. You could easily accomplish this same thing with a
|
38
|
-
# before_validation method or other callbacks.
|
39
|
-
#
|
40
|
-
# * <tt>Default:</tt> false
|
41
|
-
# * <tt>Accepts:</tt> Boolean
|
42
|
-
def disable_magic_states(value = nil)
|
43
|
-
rw_config(:disable_magic_states, value, false)
|
44
|
-
end
|
45
|
-
alias_method :disable_magic_states=, :disable_magic_states
|
46
|
-
end
|
47
|
-
|
48
|
-
# The methods available for an Authlogic::Session::Base object that make up the
|
49
|
-
# magic states feature.
|
50
|
-
module InstanceMethods
|
51
|
-
private
|
52
|
-
|
53
|
-
def disable_magic_states?
|
54
|
-
self.class.disable_magic_states == true
|
55
|
-
end
|
56
|
-
|
57
|
-
# @api private
|
58
|
-
def required_magic_states_for(record)
|
59
|
-
%i[active approved confirmed].select { |state|
|
60
|
-
record.respond_to?("#{state}?")
|
61
|
-
}
|
62
|
-
end
|
63
|
-
|
64
|
-
def validate_magic_states
|
65
|
-
return true if attempted_record.nil?
|
66
|
-
required_magic_states_for(attempted_record).each do |required_status|
|
67
|
-
next if attempted_record.send("#{required_status}?")
|
68
|
-
errors.add(
|
69
|
-
:base,
|
70
|
-
I18n.t(
|
71
|
-
"error_messages.not_#{required_status}",
|
72
|
-
default: "Your account is not #{required_status}"
|
73
|
-
)
|
74
|
-
)
|
75
|
-
return false
|
76
|
-
end
|
77
|
-
true
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|