authlogic 3.5.0 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.github/ISSUE_TEMPLATE.md +13 -0
- data/.rubocop_todo.yml +1 -37
- data/.travis.yml +15 -6
- data/CHANGELOG.md +2 -130
- data/CONTRIBUTING.md +13 -2
- data/README.md +2 -3
- data/authlogic.gemspec +4 -5
- data/lib/authlogic/acts_as_authentic/base.rb +4 -2
- data/lib/authlogic/acts_as_authentic/email.rb +8 -3
- data/lib/authlogic/acts_as_authentic/logged_in_status.rb +21 -3
- data/lib/authlogic/acts_as_authentic/login.rb +44 -25
- data/lib/authlogic/acts_as_authentic/password.rb +28 -12
- data/lib/authlogic/acts_as_authentic/perishable_token.rb +21 -12
- data/lib/authlogic/acts_as_authentic/restful_authentication.rb +16 -9
- data/lib/authlogic/acts_as_authentic/session_maintenance.rb +5 -3
- data/lib/authlogic/authenticates_many/association.rb +11 -4
- data/lib/authlogic/authenticates_many/base.rb +5 -4
- data/lib/authlogic/controller_adapters/rack_adapter.rb +6 -2
- data/lib/authlogic/controller_adapters/rails_adapter.rb +11 -8
- data/lib/authlogic/crypto_providers/aes256.rb +21 -2
- data/lib/authlogic/crypto_providers/bcrypt.rb +4 -1
- data/lib/authlogic/crypto_providers/sha512.rb +15 -10
- data/lib/authlogic/regex.rb +7 -6
- data/lib/authlogic/session/activation.rb +19 -10
- data/lib/authlogic/session/cookies.rb +3 -1
- data/lib/authlogic/session/id.rb +13 -7
- data/lib/authlogic/session/magic_columns.rb +19 -10
- data/lib/authlogic/session/magic_states.rb +7 -1
- data/lib/authlogic/session/password.rb +82 -35
- data/lib/authlogic/session/perishable_token.rb +7 -3
- data/lib/authlogic/session/validation.rb +13 -11
- data/lib/authlogic/test_case.rb +52 -32
- data/lib/authlogic.rb +6 -0
- data/test/acts_as_authentic_test/email_test.rb +33 -27
- data/test/acts_as_authentic_test/logged_in_status_test.rb +2 -2
- data/test/acts_as_authentic_test/login_test.rb +50 -37
- data/test/acts_as_authentic_test/magic_columns_test.rb +8 -8
- data/test/acts_as_authentic_test/password_test.rb +14 -14
- data/test/acts_as_authentic_test/perishable_token_test.rb +5 -5
- data/test/acts_as_authentic_test/persistence_token_test.rb +4 -4
- data/test/acts_as_authentic_test/restful_authentication_test.rb +6 -6
- data/test/acts_as_authentic_test/session_maintenance_test.rb +15 -10
- data/test/acts_as_authentic_test/single_access_test.rb +6 -6
- data/test/authenticates_many_test.rb +21 -6
- data/test/gemfiles/Gemfile.rails-5.1.x +6 -0
- data/test/gemfiles/Gemfile.rails-5.2.x +6 -0
- data/test/libs/company.rb +1 -1
- data/test/session_test/activation_test.rb +1 -1
- data/test/session_test/active_record_trickery_test.rb +3 -3
- data/test/session_test/brute_force_protection_test.rb +19 -14
- data/test/session_test/cookies_test.rb +21 -12
- data/test/session_test/existence_test.rb +15 -10
- data/test/session_test/http_auth_test.rb +2 -2
- data/test/session_test/magic_columns_test.rb +7 -4
- data/test/session_test/magic_states_test.rb +7 -9
- data/test/session_test/params_test.rb +6 -6
- data/test/session_test/password_test.rb +2 -2
- data/test/session_test/perishability_test.rb +1 -1
- data/test/session_test/persistence_test.rb +2 -2
- data/test/session_test/timeout_test.rb +7 -5
- data/test/session_test/validation_test.rb +1 -1
- data/test/test_helper.rb +37 -6
- metadata +57 -36
- checksums.yaml +0 -7
@@ -1,9 +1,13 @@
|
|
1
1
|
module Authlogic
|
2
2
|
module ActsAsAuthentic
|
3
|
-
# This provides a handy token that is "perishable". Meaning the token is
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
3
|
+
# This provides a handy token that is "perishable". Meaning the token is
|
4
|
+
# only good for a certain amount of time. This is perfect for resetting
|
5
|
+
# password, confirming accounts, etc. Typically during these actions you
|
6
|
+
# send them this token in via their email. Once they use the token and do
|
7
|
+
# what they need to do, that token should expire. Don't worry about
|
8
|
+
# maintaining this, changing it, or expiring it yourself. Authlogic does all
|
9
|
+
# of this for you. See the sub modules for all of the tools Authlogic
|
10
|
+
# provides to you.
|
7
11
|
module PerishableToken
|
8
12
|
def self.included(klass)
|
9
13
|
klass.class_eval do
|
@@ -14,8 +18,9 @@ module Authlogic
|
|
14
18
|
|
15
19
|
# Change how the perishable token works.
|
16
20
|
module Config
|
17
|
-
# When using the find_using_perishable_token method the token can
|
18
|
-
#
|
21
|
+
# When using the find_using_perishable_token method the token can
|
22
|
+
# expire. If the token is expired, no record will be returned. Use this
|
23
|
+
# option to specify how long the token is valid for.
|
19
24
|
#
|
20
25
|
# * <tt>Default:</tt> 10.minutes
|
21
26
|
# * <tt>Accepts:</tt> Fixnum
|
@@ -24,9 +29,10 @@ module Authlogic
|
|
24
29
|
end
|
25
30
|
alias_method :perishable_token_valid_for=, :perishable_token_valid_for
|
26
31
|
|
27
|
-
# Authlogic tries to expire and change the perishable token as much as
|
28
|
-
# it's purpose. This is for security
|
29
|
-
#
|
32
|
+
# Authlogic tries to expire and change the perishable token as much as
|
33
|
+
# possible, without compromising it's purpose. This is for security
|
34
|
+
# reasons. If you want to manage it yourself, you can stop Authlogic
|
35
|
+
# from getting your in way by setting this to true.
|
30
36
|
#
|
31
37
|
# * <tt>Default:</tt> false
|
32
38
|
# * <tt>Accepts:</tt> Boolean
|
@@ -52,12 +58,14 @@ module Authlogic
|
|
52
58
|
|
53
59
|
# Class level methods for the perishable token
|
54
60
|
module ClassMethods
|
55
|
-
# Use this method to find a record with a perishable token. This
|
61
|
+
# Use this method to find a record with a perishable token. This
|
62
|
+
# method does 2 things for you:
|
56
63
|
#
|
57
64
|
# 1. It ignores blank tokens
|
58
65
|
# 2. It enforces the perishable_token_valid_for configuration option.
|
59
66
|
#
|
60
|
-
# If you want to use a different timeout value, just pass it as the
|
67
|
+
# If you want to use a different timeout value, just pass it as the
|
68
|
+
# second parameter:
|
61
69
|
#
|
62
70
|
# User.find_using_perishable_token(token, 1.hour)
|
63
71
|
def find_using_perishable_token(token, age = self.perishable_token_valid_for)
|
@@ -94,7 +102,8 @@ module Authlogic
|
|
94
102
|
save_without_session_maintenance(:validate => false)
|
95
103
|
end
|
96
104
|
|
97
|
-
# A convenience method based on the
|
105
|
+
# A convenience method based on the
|
106
|
+
# disable_perishable_token_maintenance configuration option.
|
98
107
|
def disable_perishable_token_maintenance?
|
99
108
|
self.class.disable_perishable_token_maintenance == true
|
100
109
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Authlogic
|
2
2
|
module ActsAsAuthentic
|
3
|
-
# This module is responsible for transitioning existing applications from
|
3
|
+
# This module is responsible for transitioning existing applications from
|
4
|
+
# the restful_authentication plugin.
|
4
5
|
module RestfulAuthentication
|
5
6
|
def self.included(klass)
|
6
7
|
klass.class_eval do
|
@@ -10,10 +11,13 @@ module Authlogic
|
|
10
11
|
end
|
11
12
|
|
12
13
|
module Config
|
13
|
-
# Switching an existing app to Authlogic from restful_authentication? No
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
14
|
+
# Switching an existing app to Authlogic from restful_authentication? No
|
15
|
+
# problem, just set this true and your users won't know anything
|
16
|
+
# changed. From your database perspective nothing will change at all.
|
17
|
+
# Authlogic will continue to encrypt passwords just like
|
18
|
+
# restful_authentication, so your app won't skip a beat. Although, might
|
19
|
+
# consider transitioning your users to a newer and stronger algorithm.
|
20
|
+
# Checkout the transition_from_restful_authentication option.
|
17
21
|
#
|
18
22
|
# * <tt>Default:</tt> false
|
19
23
|
# * <tt>Accepts:</tt> Boolean
|
@@ -24,10 +28,13 @@ module Authlogic
|
|
24
28
|
end
|
25
29
|
alias_method :act_like_restful_authentication=, :act_like_restful_authentication
|
26
30
|
|
27
|
-
# This works just like act_like_restful_authentication except that it
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
+
# This works just like act_like_restful_authentication except that it
|
32
|
+
# will start transitioning your users to the algorithm you specify with
|
33
|
+
# the crypto provider option. The next time they log in it will resave
|
34
|
+
# their password with the new algorithm and any new record will use the
|
35
|
+
# new algorithm as well. Make sure to update your users table if you are
|
36
|
+
# using the default migration since it will set crypted_password and
|
37
|
+
# salt columns to a maximum width of 40 characters which is not enough.
|
31
38
|
def transition_from_restful_authentication(value = nil)
|
32
39
|
r = rw_config(:transition_from_restful_authentication, value, false)
|
33
40
|
set_restful_authentication_config if value
|
@@ -102,7 +102,8 @@ module Authlogic
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def get_session_information
|
105
|
-
# Need to determine if we are completely logged out, or logged in as
|
105
|
+
# Need to determine if we are completely logged out, or logged in as
|
106
|
+
# another user.
|
106
107
|
@_sessions = []
|
107
108
|
|
108
109
|
session_ids.each do |session_id|
|
@@ -120,8 +121,9 @@ module Authlogic
|
|
120
121
|
end
|
121
122
|
|
122
123
|
def create_session
|
123
|
-
# We only want to automatically login into the first session, since
|
124
|
-
#
|
124
|
+
# We only want to automatically login into the first session, since
|
125
|
+
# this is the main session. The other sessions are sessions that
|
126
|
+
# need to be created after logging into the main session.
|
125
127
|
session_id = session_ids.first
|
126
128
|
session_class.create(*[self, self, session_id].compact)
|
127
129
|
|
@@ -1,14 +1,17 @@
|
|
1
1
|
module Authlogic
|
2
2
|
module AuthenticatesMany
|
3
|
-
# An object of this class is used as a proxy for the authenticates_many
|
4
|
-
#
|
3
|
+
# An object of this class is used as a proxy for the authenticates_many
|
4
|
+
# relationship. It basically allows you to "save" scope details and call
|
5
|
+
# them on an object, which allows you to do the following:
|
5
6
|
#
|
6
7
|
# @account.user_sessions.new
|
7
8
|
# @account.user_sessions.find
|
8
9
|
# # ... etc
|
9
10
|
#
|
10
|
-
# You can call all of the class level methods off of an object with a saved
|
11
|
-
#
|
11
|
+
# You can call all of the class level methods off of an object with a saved
|
12
|
+
# scope, so that calling the above methods scopes the user sessions down to
|
13
|
+
# that specific account. To implement this via ActiveRecord do something
|
14
|
+
# like:
|
12
15
|
#
|
13
16
|
# class User < ActiveRecord::Base
|
14
17
|
# authenticates_many :user_sessions
|
@@ -16,6 +19,10 @@ module Authlogic
|
|
16
19
|
class Association
|
17
20
|
attr_accessor :klass, :find_options, :id
|
18
21
|
|
22
|
+
# - id: Usually `nil`, but if the `scope_cookies` option is used, then
|
23
|
+
# `id` is a string like "company_123". It may seem strange to refer
|
24
|
+
# to such a string as an "id", but the naming is intentional, and
|
25
|
+
# is derived from `Authlogic::Session::Id`.
|
19
26
|
def initialize(klass, find_options, id)
|
20
27
|
self.klass = klass
|
21
28
|
self.find_options = find_options
|
@@ -43,17 +43,18 @@ module Authlogic
|
|
43
43
|
# * <tt>scope_cookies:</tt> default: false
|
44
44
|
# By the nature of cookies they scope themselves if you are using subdomains to
|
45
45
|
# access accounts. If you aren't using subdomains you need to have separate
|
46
|
-
# cookies for each account, assuming a user is logging into
|
46
|
+
# cookies for each account, assuming a user is logging into more than one account.
|
47
47
|
# Authlogic can take care of this for you by prefixing the name of the cookie and
|
48
|
-
#
|
49
|
-
#
|
48
|
+
# session with the model id. Because it affects both cookies names and session keys,
|
49
|
+
# the name `scope_cookies` is misleading. Perhaps simply `scope` or `scoped`
|
50
|
+
# would have been better.
|
50
51
|
def authenticates_many(name, options = {})
|
51
52
|
options[:session_class] ||= name.to_s.classify.constantize
|
52
53
|
options[:relationship_name] ||= options[:session_class].klass_name.underscore.pluralize
|
53
54
|
class_eval <<-"end_eval", __FILE__, __LINE__
|
54
55
|
def #{name}
|
55
56
|
find_options = #{options[:find_options].inspect} || #{options[:relationship_name]}.where(nil)
|
56
|
-
@#{name} ||= Authlogic::AuthenticatesMany::Association.new(#{options[:session_class]}, find_options, #{options[:scope_cookies] ? "self.class.model_name.underscore + '_' + self.send(self.class.primary_key).to_s" : "nil"})
|
57
|
+
@#{name} ||= Authlogic::AuthenticatesMany::Association.new(#{options[:session_class]}, find_options, #{options[:scope_cookies] ? "self.class.model_name.name.underscore + '_' + self.send(self.class.primary_key).to_s" : "nil"})
|
57
58
|
end
|
58
59
|
end_eval
|
59
60
|
end
|
@@ -2,8 +2,10 @@ require 'action_controller'
|
|
2
2
|
|
3
3
|
module Authlogic
|
4
4
|
module ControllerAdapters
|
5
|
-
# Adapts authlogic to work with rails. The point is to close the gap between
|
6
|
-
#
|
5
|
+
# Adapts authlogic to work with rails. The point is to close the gap between
|
6
|
+
# what authlogic expects and what the rails controller object provides.
|
7
|
+
# Similar to how ActiveRecord has an adapter for MySQL, PostgreSQL, SQLite,
|
8
|
+
# etc.
|
7
9
|
class RailsAdapter < AbstractAdapter
|
8
10
|
class AuthlogicLoadedTooLateError < StandardError; end
|
9
11
|
|
@@ -31,12 +33,13 @@ module Authlogic
|
|
31
33
|
if defined?(::ApplicationController)
|
32
34
|
raise AuthlogicLoadedTooLateError.new(
|
33
35
|
<<-EOS.strip_heredoc
|
34
|
-
Authlogic is trying to add a callback to ActionController::Base
|
35
|
-
ApplicationController has already been loaded, so the
|
36
|
-
be copied into your application. Generally this
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
Authlogic is trying to add a callback to ActionController::Base
|
37
|
+
but ApplicationController has already been loaded, so the
|
38
|
+
callback won't be copied into your application. Generally this
|
39
|
+
is due to another gem or plugin requiring your
|
40
|
+
ApplicationController prematurely, such as the
|
41
|
+
resource_controller plugin. Please require Authlogic first,
|
42
|
+
before these other gems / plugins.
|
40
43
|
EOS
|
41
44
|
)
|
42
45
|
end
|
@@ -38,8 +38,27 @@ module Authlogic
|
|
38
38
|
private
|
39
39
|
|
40
40
|
def aes
|
41
|
-
|
42
|
-
|
41
|
+
if @key.blank?
|
42
|
+
raise ArgumentError.new(
|
43
|
+
"You must provide a key like #{name}.key = my_key before using the #{name}"
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
@aes ||= openssl_cipher_class.new("AES-256-ECB")
|
48
|
+
end
|
49
|
+
|
50
|
+
# `::OpenSSL::Cipher::Cipher` has been deprecated since at least 2014,
|
51
|
+
# in favor of `::OpenSSL::Cipher`, but a deprecation warning was not
|
52
|
+
# printed until 2016
|
53
|
+
# (https://github.com/ruby/openssl/commit/5c20a4c014) when openssl
|
54
|
+
# became a gem. Its first release as a gem was 2.0.0, in ruby 2.4.
|
55
|
+
# (See https://github.com/ruby/ruby/blob/v2_4_0/NEWS)
|
56
|
+
def openssl_cipher_class
|
57
|
+
if ::Gem::Version.new(::OpenSSL::VERSION) < ::Gem::Version.new("2.0.0")
|
58
|
+
::OpenSSL::Cipher::Cipher
|
59
|
+
else
|
60
|
+
::OpenSSL::Cipher
|
61
|
+
end
|
43
62
|
end
|
44
63
|
end
|
45
64
|
end
|
@@ -56,7 +56,10 @@ module Authlogic
|
|
56
56
|
|
57
57
|
def cost=(val)
|
58
58
|
if val < ::BCrypt::Engine::MIN_COST
|
59
|
-
raise ArgumentError.new(
|
59
|
+
raise ArgumentError.new(
|
60
|
+
"Authlogic's bcrypt cost cannot be set below the engine's " \
|
61
|
+
"min cost (#{::BCrypt::Engine::MIN_COST})"
|
62
|
+
)
|
60
63
|
end
|
61
64
|
@cost = val
|
62
65
|
end
|
@@ -1,22 +1,25 @@
|
|
1
1
|
require "digest/sha2"
|
2
2
|
|
3
3
|
module Authlogic
|
4
|
-
# The acts_as_authentic method has a crypto_provider option. This allows you
|
5
|
-
#
|
4
|
+
# The acts_as_authentic method has a crypto_provider option. This allows you
|
5
|
+
# to use any type of encryption you like. Just create a class with a class
|
6
|
+
# level encrypt and matches? method. See example below.
|
6
7
|
#
|
7
8
|
# === Example
|
8
9
|
#
|
9
10
|
# class MyAwesomeEncryptionMethod
|
10
11
|
# def self.encrypt(*tokens)
|
11
|
-
# #
|
12
|
-
# # just do what you need to do with them and return a
|
13
|
-
# #
|
12
|
+
# # The tokens passed will be an array of objects, what type of object
|
13
|
+
# # is irrelevant, just do what you need to do with them and return a
|
14
|
+
# # single encrypted string. For example, you will most likely join all
|
15
|
+
# # of the objects into a single string and then encrypt that string.
|
14
16
|
# end
|
15
17
|
#
|
16
18
|
# def self.matches?(crypted, *tokens)
|
17
|
-
# #
|
18
|
-
# #
|
19
|
-
# # encrypt the tokens and make sure it matches the
|
19
|
+
# # Return true if the crypted string matches the tokens. Depending on
|
20
|
+
# # your algorithm you might decrypt the string then compare it to the
|
21
|
+
# # token, or you might encrypt the tokens and make sure it matches the
|
22
|
+
# # crypted string, its up to you.
|
20
23
|
# end
|
21
24
|
# end
|
22
25
|
module CryptoProviders
|
@@ -27,7 +30,8 @@ module Authlogic
|
|
27
30
|
class << self
|
28
31
|
attr_accessor :join_token
|
29
32
|
|
30
|
-
# The number of times to loop through the encryption. This is twenty
|
33
|
+
# The number of times to loop through the encryption. This is twenty
|
34
|
+
# because that is what restful_authentication defaults to.
|
31
35
|
def stretches
|
32
36
|
@stretches ||= 20
|
33
37
|
end
|
@@ -40,7 +44,8 @@ module Authlogic
|
|
40
44
|
digest
|
41
45
|
end
|
42
46
|
|
43
|
-
# Does the crypted password match the tokens? Uses the same tokens that
|
47
|
+
# Does the crypted password match the tokens? Uses the same tokens that
|
48
|
+
# were used to encrypt.
|
44
49
|
def matches?(crypted, *tokens)
|
45
50
|
encrypt(*tokens) == crypted
|
46
51
|
end
|
data/lib/authlogic/regex.rb
CHANGED
@@ -5,15 +5,16 @@ module Authlogic
|
|
5
5
|
#
|
6
6
|
# validates_format_of :my_email_field, :with => Authlogic::Regex.email
|
7
7
|
module Regex
|
8
|
-
# A general email regular expression. It allows top level domains (TLD) to be from 2 -
|
9
|
-
# The decisions behind this regular expression were made by analyzing
|
10
|
-
# maintained by IANA and by reading this website:
|
11
|
-
# which is an excellent resource for
|
8
|
+
# A general email regular expression. It allows top level domains (TLD) to be from 2 -
|
9
|
+
# 24 in length. The decisions behind this regular expression were made by analyzing
|
10
|
+
# the list of top-level domains maintained by IANA and by reading this website:
|
11
|
+
# http://www.regular-expressions.info/email.html, which is an excellent resource for
|
12
|
+
# regular expressions.
|
12
13
|
def self.email
|
13
14
|
@email_regex ||= begin
|
14
15
|
email_name_regex = '[A-Z0-9_\.&%\+\-\']+'
|
15
16
|
domain_head_regex = '(?:[A-Z0-9\-]+\.)+'
|
16
|
-
domain_tld_regex = '(?:[A-Z]{2,
|
17
|
+
domain_tld_regex = '(?:[A-Z]{2,25})'
|
17
18
|
/\A#{email_name_regex}@#{domain_head_regex}#{domain_tld_regex}\z/i
|
18
19
|
end
|
19
20
|
end
|
@@ -33,7 +34,7 @@ module Authlogic
|
|
33
34
|
@email_nonascii_regex ||= begin
|
34
35
|
email_name_regex = '[^[:cntrl:][@\[\]\^ \!\"#$\(\)*,/:;<=>\?`{|}~\\\]]+'
|
35
36
|
domain_head_regex = '(?:[^[:cntrl:][@\[\]\^ \!\"#$&\(\)*,/:;<=>\?`{|}~\\\_\.%\+\']]+\.)+'
|
36
|
-
domain_tld_regex = '(?:[^[:cntrl:][@\[\]\^ \!\"#$&\(\)*,/:;<=>\?`{|}~\\\_\.%\+\-\'0-9]]{2,
|
37
|
+
domain_tld_regex = '(?:[^[:cntrl:][@\[\]\^ \!\"#$&\(\)*,/:;<=>\?`{|}~\\\_\.%\+\-\'0-9]]{2,25})'
|
37
38
|
/\A#{email_name_regex}@#{domain_head_regex}#{domain_tld_regex}\z/
|
38
39
|
end
|
39
40
|
end
|
@@ -2,9 +2,11 @@ require 'request_store'
|
|
2
2
|
|
3
3
|
module Authlogic
|
4
4
|
module Session
|
5
|
-
# Activating Authlogic requires that you pass it an
|
6
|
-
#
|
7
|
-
#
|
5
|
+
# Activating Authlogic requires that you pass it an
|
6
|
+
# Authlogic::ControllerAdapters::AbstractAdapter object, or a class that
|
7
|
+
# extends it. This is sort of like a database connection for an ORM library,
|
8
|
+
# Authlogic can't do anything until it is "connected" to a controller. If
|
9
|
+
# you are using a supported framework, Authlogic takes care of this for you.
|
8
10
|
module Activation
|
9
11
|
class NotActivatedError < ::StandardError # :nodoc:
|
10
12
|
def initialize(session)
|
@@ -20,17 +22,24 @@ module Authlogic
|
|
20
22
|
end
|
21
23
|
|
22
24
|
module ClassMethods
|
23
|
-
# Returns true if a controller has been set and can be used properly.
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
25
|
+
# Returns true if a controller has been set and can be used properly.
|
26
|
+
# This MUST be set before anything can be done. Similar to how
|
27
|
+
# ActiveRecord won't allow you to do anything without establishing a DB
|
28
|
+
# connection. In your framework environment this is done for you, but if
|
29
|
+
# you are using Authlogic outside of your framework, you need to assign
|
30
|
+
# a controller object to Authlogic via
|
31
|
+
# Authlogic::Session::Base.controller = obj. See the controller= method
|
32
|
+
# for more information.
|
27
33
|
def activated?
|
28
34
|
!controller.nil?
|
29
35
|
end
|
30
36
|
|
31
|
-
# This accepts a controller object wrapped with the Authlogic controller
|
32
|
-
#
|
33
|
-
#
|
37
|
+
# This accepts a controller object wrapped with the Authlogic controller
|
38
|
+
# adapter. The controller adapters close the gap between the different
|
39
|
+
# controllers in each framework. That being said, Authlogic is expecting
|
40
|
+
# your object's class to extend
|
41
|
+
# Authlogic::ControllerAdapters::AbstractAdapter. See
|
42
|
+
# Authlogic::ControllerAdapters for more info.
|
34
43
|
#
|
35
44
|
# Lastly, this is thread safe.
|
36
45
|
def controller=(value)
|
@@ -91,7 +91,9 @@ module Authlogic
|
|
91
91
|
values = value.is_a?(Array) ? value : [value]
|
92
92
|
case values.first
|
93
93
|
when Hash
|
94
|
-
|
94
|
+
if values.first.with_indifferent_access.key?(:remember_me)
|
95
|
+
self.remember_me = values.first.with_indifferent_access[:remember_me]
|
96
|
+
end
|
95
97
|
else
|
96
98
|
r = values.find { |value| value.is_a?(TrueClass) || value.is_a?(FalseClass) }
|
97
99
|
self.remember_me = r if !r.nil?
|
data/lib/authlogic/session/id.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Authlogic
|
2
2
|
module Session
|
3
|
-
# Allows you to separate sessions with an id, ultimately letting you create
|
3
|
+
# Allows you to separate sessions with an id, ultimately letting you create
|
4
|
+
# multiple sessions for the same user.
|
4
5
|
module Id
|
5
6
|
def self.included(klass)
|
6
7
|
klass.class_eval do
|
@@ -15,18 +16,23 @@ module Authlogic
|
|
15
16
|
self.id = values.last if values.last.is_a?(Symbol)
|
16
17
|
end
|
17
18
|
|
18
|
-
# Allows you to set a unique identifier for your session, so that you can
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
19
|
+
# Allows you to set a unique identifier for your session, so that you can
|
20
|
+
# have more than 1 session at a time. A good example when this might be
|
21
|
+
# needed is when you want to have a normal user session and a "secure"
|
22
|
+
# user session. The secure user session would be created only when they
|
23
|
+
# want to modify their billing information, or other sensitive
|
24
|
+
# information. Similar to me.com. This requires 2 user sessions. Just use
|
25
|
+
# an id for the "secure" session and you should be good.
|
22
26
|
#
|
23
|
-
# You can set the id during initialization (see initialize for more
|
27
|
+
# You can set the id during initialization (see initialize for more
|
28
|
+
# information), or as an attribute:
|
24
29
|
#
|
25
30
|
# session.id = :my_id
|
26
31
|
#
|
27
32
|
# Just be sure and set your id before you save your session.
|
28
33
|
#
|
29
|
-
# Lastly, to retrieve your session with the id check out the find class
|
34
|
+
# Lastly, to retrieve your session with the id check out the find class
|
35
|
+
# method.
|
30
36
|
def id
|
31
37
|
@id
|
32
38
|
end
|
@@ -74,14 +74,18 @@ module Authlogic
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
# This method lets authlogic know whether it should allow the
|
78
|
-
#
|
79
|
-
#
|
80
|
-
# in your
|
77
|
+
# This method lets authlogic know whether it should allow the
|
78
|
+
# last_request_at field to be updated with the current time
|
79
|
+
# (Time.now). One thing to note here is that it also checks for the
|
80
|
+
# existence of a last_request_update_allowed? method in your
|
81
|
+
# controller. This allows you to control this method pragmatically in
|
82
|
+
# your controller.
|
81
83
|
#
|
82
|
-
# For example, what if you had a javascript function that polled the
|
83
|
-
#
|
84
|
-
#
|
84
|
+
# For example, what if you had a javascript function that polled the
|
85
|
+
# server updating how much time is left in their session before it
|
86
|
+
# times out. Obviously you would want to ignore this request, because
|
87
|
+
# then the user would never time out. So you can do something like
|
88
|
+
# this in your controller:
|
85
89
|
#
|
86
90
|
# def last_request_update_allowed?
|
87
91
|
# action_name != "update_session_time_left"
|
@@ -89,9 +93,14 @@ module Authlogic
|
|
89
93
|
#
|
90
94
|
# You can do whatever you want with that method.
|
91
95
|
def set_last_request_at? # :doc:
|
92
|
-
|
93
|
-
|
94
|
-
|
96
|
+
if !record || !klass.column_names.include?("last_request_at")
|
97
|
+
return false
|
98
|
+
end
|
99
|
+
if controller.responds_to_last_request_update_allowed? && !controller.last_request_update_allowed?
|
100
|
+
return false
|
101
|
+
end
|
102
|
+
record.last_request_at.blank? ||
|
103
|
+
last_request_at_threshold.to_i.seconds.ago >= record.last_request_at
|
95
104
|
end
|
96
105
|
|
97
106
|
def set_last_request_at
|
@@ -58,7 +58,13 @@ module Authlogic
|
|
58
58
|
return true if attempted_record.nil?
|
59
59
|
[:active, :approved, :confirmed].each do |required_status|
|
60
60
|
if attempted_record.respond_to?("#{required_status}?") && !attempted_record.send("#{required_status}?")
|
61
|
-
errors.add(
|
61
|
+
errors.add(
|
62
|
+
:base,
|
63
|
+
I18n.t(
|
64
|
+
"error_messages.not_#{required_status}",
|
65
|
+
:default => "Your account is not #{required_status}"
|
66
|
+
)
|
67
|
+
)
|
62
68
|
return false
|
63
69
|
end
|
64
70
|
end
|