authlogic 4.0.1 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +43 -1
- data/.rubocop_todo.yml +23 -132
- data/CHANGELOG.md +12 -0
- data/CONTRIBUTING.md +10 -3
- data/Gemfile +2 -2
- data/Rakefile +6 -6
- data/authlogic.gemspec +13 -12
- data/lib/authlogic/acts_as_authentic/base.rb +12 -7
- data/lib/authlogic/acts_as_authentic/email.rb +16 -6
- data/lib/authlogic/acts_as_authentic/logged_in_status.rb +10 -5
- data/lib/authlogic/acts_as_authentic/login.rb +11 -5
- data/lib/authlogic/acts_as_authentic/password.rb +111 -57
- data/lib/authlogic/acts_as_authentic/perishable_token.rb +6 -2
- data/lib/authlogic/acts_as_authentic/persistence_token.rb +1 -1
- data/lib/authlogic/acts_as_authentic/queries/find_with_case.rb +2 -2
- data/lib/authlogic/acts_as_authentic/restful_authentication.rb +31 -3
- data/lib/authlogic/acts_as_authentic/session_maintenance.rb +11 -3
- data/lib/authlogic/acts_as_authentic/single_access_token.rb +14 -2
- data/lib/authlogic/acts_as_authentic/validations_scope.rb +6 -6
- data/lib/authlogic/authenticates_many/association.rb +2 -2
- data/lib/authlogic/authenticates_many/base.rb +27 -19
- data/lib/authlogic/controller_adapters/rack_adapter.rb +1 -1
- data/lib/authlogic/controller_adapters/rails_adapter.rb +6 -3
- data/lib/authlogic/controller_adapters/sinatra_adapter.rb +2 -2
- data/lib/authlogic/crypto_providers.rb +2 -0
- data/lib/authlogic/crypto_providers/bcrypt.rb +15 -9
- data/lib/authlogic/crypto_providers/md5.rb +2 -1
- data/lib/authlogic/crypto_providers/scrypt.rb +12 -7
- data/lib/authlogic/crypto_providers/sha256.rb +2 -1
- data/lib/authlogic/crypto_providers/wordpress.rb +31 -2
- data/lib/authlogic/i18n.rb +22 -17
- data/lib/authlogic/regex.rb +57 -29
- data/lib/authlogic/session/activation.rb +1 -1
- data/lib/authlogic/session/brute_force_protection.rb +2 -2
- data/lib/authlogic/session/callbacks.rb +43 -36
- data/lib/authlogic/session/cookies.rb +4 -2
- data/lib/authlogic/session/existence.rb +1 -1
- data/lib/authlogic/session/foundation.rb +5 -1
- data/lib/authlogic/session/http_auth.rb +2 -2
- data/lib/authlogic/session/klass.rb +2 -1
- data/lib/authlogic/session/magic_columns.rb +4 -2
- data/lib/authlogic/session/magic_states.rb +9 -10
- data/lib/authlogic/session/params.rb +11 -4
- data/lib/authlogic/session/password.rb +72 -38
- data/lib/authlogic/session/perishable_token.rb +2 -1
- data/lib/authlogic/session/persistence.rb +2 -1
- data/lib/authlogic/session/scopes.rb +26 -16
- data/lib/authlogic/session/unauthorized_record.rb +12 -7
- data/lib/authlogic/session/validation.rb +1 -1
- data/lib/authlogic/test_case/mock_controller.rb +1 -1
- data/lib/authlogic/test_case/mock_cookie_jar.rb +1 -1
- data/lib/authlogic/test_case/mock_request.rb +1 -1
- data/lib/authlogic/version.rb +1 -1
- data/test/acts_as_authentic_test/base_test.rb +1 -1
- data/test/acts_as_authentic_test/email_test.rb +11 -11
- data/test/acts_as_authentic_test/logged_in_status_test.rb +4 -4
- data/test/acts_as_authentic_test/login_test.rb +2 -2
- data/test/acts_as_authentic_test/magic_columns_test.rb +1 -1
- data/test/acts_as_authentic_test/password_test.rb +1 -1
- data/test/acts_as_authentic_test/perishable_token_test.rb +2 -2
- data/test/acts_as_authentic_test/persistence_token_test.rb +1 -1
- data/test/acts_as_authentic_test/restful_authentication_test.rb +12 -3
- data/test/acts_as_authentic_test/session_maintenance_test.rb +1 -1
- data/test/acts_as_authentic_test/single_access_test.rb +1 -1
- data/test/adapter_test.rb +3 -3
- data/test/authenticates_many_test.rb +1 -1
- data/test/config_test.rb +9 -9
- data/test/crypto_provider_test/aes256_test.rb +1 -1
- data/test/crypto_provider_test/bcrypt_test.rb +1 -1
- data/test/crypto_provider_test/scrypt_test.rb +1 -1
- data/test/crypto_provider_test/sha1_test.rb +1 -1
- data/test/crypto_provider_test/sha256_test.rb +1 -1
- data/test/crypto_provider_test/sha512_test.rb +1 -1
- data/test/crypto_provider_test/wordpress_test.rb +24 -0
- data/test/i18n_test.rb +3 -3
- data/test/libs/user_session.rb +2 -2
- data/test/random_test.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 +1 -1
- data/test/session_test/callbacks_test.rb +9 -3
- data/test/session_test/cookies_test.rb +11 -11
- data/test/session_test/existence_test.rb +1 -1
- data/test/session_test/foundation_test.rb +1 -1
- data/test/session_test/http_auth_test.rb +6 -6
- data/test/session_test/id_test.rb +1 -1
- data/test/session_test/klass_test.rb +1 -1
- data/test/session_test/magic_columns_test.rb +1 -1
- data/test/session_test/magic_states_test.rb +1 -1
- data/test/session_test/params_test.rb +7 -4
- data/test/session_test/password_test.rb +1 -1
- data/test/session_test/perishability_test.rb +1 -1
- data/test/session_test/persistence_test.rb +1 -1
- data/test/session_test/scopes_test.rb +9 -3
- data/test/session_test/session_test.rb +2 -2
- data/test/session_test/timeout_test.rb +1 -1
- data/test/session_test/unauthorized_record_test.rb +1 -1
- data/test/session_test/validation_test.rb +1 -1
- data/test/test_helper.rb +34 -14
- metadata +6 -4
@@ -14,7 +14,8 @@ module Authlogic
|
|
14
14
|
private
|
15
15
|
|
16
16
|
def reset_perishable_token!
|
17
|
-
if record.respond_to?(:reset_perishable_token) &&
|
17
|
+
if record.respond_to?(:reset_perishable_token) &&
|
18
|
+
!record.disable_perishable_token_maintenance?
|
18
19
|
record.reset_perishable_token
|
19
20
|
end
|
20
21
|
end
|
@@ -28,7 +28,8 @@ module Authlogic
|
|
28
28
|
# @current_user = current_user_session && current_user_session.user
|
29
29
|
# end
|
30
30
|
#
|
31
|
-
# Also, this method accepts a single parameter as the id, to find
|
31
|
+
# Also, this method accepts a single parameter as the id, to find
|
32
|
+
# session that you marked with an id:
|
32
33
|
#
|
33
34
|
# UserSession.find(:secure)
|
34
35
|
#
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "request_store"
|
2
2
|
|
3
3
|
module Authlogic
|
4
4
|
module Session
|
@@ -25,10 +25,10 @@ module Authlogic
|
|
25
25
|
RequestStore.store[:authlogic_scope]
|
26
26
|
end
|
27
27
|
|
28
|
-
# What with_scopes focuses on is scoping the query when finding the
|
29
|
-
# name of the cookie / session. It works very similar to
|
30
|
-
# ActiveRecord::Base#with_scopes. It accepts a hash with any of the
|
31
|
-
# options:
|
28
|
+
# What with_scopes focuses on is scoping the query when finding the
|
29
|
+
# object and the name of the cookie / session. It works very similar to
|
30
|
+
# ActiveRecord::Base#with_scopes. It accepts a hash with any of the
|
31
|
+
# following options:
|
32
32
|
#
|
33
33
|
# * <tt>find_options:</tt> any options you can pass into ActiveRecord::Base.find.
|
34
34
|
# This is used when trying to find the record.
|
@@ -37,21 +37,27 @@ module Authlogic
|
|
37
37
|
#
|
38
38
|
# Here is how you use it:
|
39
39
|
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
40
|
+
# ```
|
41
|
+
# UserSession.with_scope(find_options: {conditions: "account_id = 2"}, id: "account_2") do
|
42
|
+
# UserSession.find
|
43
|
+
# end
|
44
|
+
# ```
|
43
45
|
#
|
44
|
-
# Essentially what the above does is scope the searching of the object
|
45
|
-
# sql you provided. So instead of:
|
46
|
+
# Essentially what the above does is scope the searching of the object
|
47
|
+
# with the sql you provided. So instead of:
|
46
48
|
#
|
47
|
-
#
|
49
|
+
# ```
|
50
|
+
# User.where("login = 'ben'").first
|
51
|
+
# ```
|
48
52
|
#
|
49
53
|
# it would be:
|
50
54
|
#
|
51
|
-
#
|
55
|
+
# ```
|
56
|
+
# User.where("login = 'ben' and account_id = 2").first
|
57
|
+
# ```
|
52
58
|
#
|
53
|
-
# You will also notice the :id option. This works just like the id
|
54
|
-
# scopes your cookies. So the name of your cookie will be:
|
59
|
+
# You will also notice the :id option. This works just like the id
|
60
|
+
# method. It scopes your cookies. So the name of your cookie will be:
|
55
61
|
#
|
56
62
|
# account_2_user_credentials
|
57
63
|
#
|
@@ -59,9 +65,13 @@ module Authlogic
|
|
59
65
|
#
|
60
66
|
# user_credentials
|
61
67
|
#
|
62
|
-
# What is also nifty about scoping with an :id is that it merges your
|
68
|
+
# What is also nifty about scoping with an :id is that it merges your
|
69
|
+
# id's. So if you do:
|
63
70
|
#
|
64
|
-
# UserSession.with_scope(
|
71
|
+
# UserSession.with_scope(
|
72
|
+
# find_options: { conditions: "account_id = 2"},
|
73
|
+
# id: "account_2"
|
74
|
+
# ) do
|
65
75
|
# session = UserSession.new
|
66
76
|
# session.id = :secure
|
67
77
|
# end
|
@@ -4,18 +4,23 @@ module Authlogic
|
|
4
4
|
#
|
5
5
|
# UserSession.create(my_user_object)
|
6
6
|
#
|
7
|
-
# Be careful with this, because Authlogic is assuming that you have already
|
8
|
-
# user is who he says he is.
|
7
|
+
# Be careful with this, because Authlogic is assuming that you have already
|
8
|
+
# confirmed that the user is who he says he is.
|
9
9
|
#
|
10
|
-
# For example, this is the method used to persist the session internally.
|
11
|
-
# the persistence token. At this point we know
|
12
|
-
#
|
13
|
-
#
|
10
|
+
# For example, this is the method used to persist the session internally.
|
11
|
+
# Authlogic finds the user with the persistence token. At this point we know
|
12
|
+
# the user is who he says he is, so Authlogic just creates a session with
|
13
|
+
# the record. This is particularly useful for 3rd party authentication
|
14
|
+
# methods, such as OpenID. Let that method verify the identity, once it's
|
15
|
+
# verified, pass the object and create a session.
|
14
16
|
module UnauthorizedRecord
|
15
17
|
def self.included(klass)
|
16
18
|
klass.class_eval do
|
17
19
|
attr_accessor :unauthorized_record
|
18
|
-
validate
|
20
|
+
validate(
|
21
|
+
:validate_by_unauthorized_record,
|
22
|
+
if: :authenticating_with_unauthorized_record?
|
23
|
+
)
|
19
24
|
end
|
20
25
|
end
|
21
26
|
|
@@ -14,7 +14,7 @@ module Authlogic
|
|
14
14
|
yield http_user, http_password
|
15
15
|
end
|
16
16
|
|
17
|
-
def authenticate_or_request_with_http_basic(realm =
|
17
|
+
def authenticate_or_request_with_http_basic(realm = "DefaultRealm")
|
18
18
|
self.realm = realm
|
19
19
|
@http_auth_requested = true
|
20
20
|
yield http_user, http_password
|
@@ -33,7 +33,7 @@ module Authlogic
|
|
33
33
|
def [](val)
|
34
34
|
signed_message = @parent_jar[val]
|
35
35
|
if signed_message
|
36
|
-
payload, signature = signed_message.split(
|
36
|
+
payload, signature = signed_message.split("--")
|
37
37
|
raise "Invalid signature" unless Digest::SHA1.hexdigest(payload) == signature
|
38
38
|
payload
|
39
39
|
end
|
data/lib/authlogic/version.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "test_helper"
|
2
2
|
|
3
3
|
module ActsAsAuthenticTest
|
4
4
|
class EmailTest < ActiveSupport::TestCase
|
@@ -46,7 +46,7 @@ module ActsAsAuthenticTest
|
|
46
46
|
BAD_UTF8_EMAILS = [
|
47
47
|
"",
|
48
48
|
".みんな", # https://github.com/binarylogic/authlogic/issues/176#issuecomment-55829320
|
49
|
-
|
49
|
+
"δκιμή@παράδεγμα.δ", # short TLD
|
50
50
|
"öm(@ava.fi", # L paren
|
51
51
|
"é)@domain.com", # R paren
|
52
52
|
"é[@example.com", # L bracket
|
@@ -94,10 +94,10 @@ module ActsAsAuthenticTest
|
|
94
94
|
|
95
95
|
def test_validates_format_of_email_field_options_config
|
96
96
|
default = {
|
97
|
-
with: Authlogic::Regex
|
97
|
+
with: Authlogic::Regex::EMAIL,
|
98
98
|
message: proc do
|
99
99
|
I18n.t(
|
100
|
-
|
100
|
+
"error_messages.email_invalid",
|
101
101
|
default: "should look like an email address."
|
102
102
|
)
|
103
103
|
end
|
@@ -122,10 +122,10 @@ module ActsAsAuthenticTest
|
|
122
122
|
assert_equal default, User.validates_format_of_email_field_options
|
123
123
|
|
124
124
|
with_email_nonascii = {
|
125
|
-
with: Authlogic::Regex
|
126
|
-
message:
|
125
|
+
with: Authlogic::Regex::EMAIL_NONASCII,
|
126
|
+
message: proc do
|
127
127
|
I18n.t(
|
128
|
-
|
128
|
+
"error_messages.email_invalid_international",
|
129
129
|
default: "should look like an international email address."
|
130
130
|
)
|
131
131
|
end
|
@@ -140,11 +140,11 @@ module ActsAsAuthenticTest
|
|
140
140
|
# ensure we successfully loaded the test locale
|
141
141
|
assert I18n.available_locales.include?(:lol), "Test locale failed to load"
|
142
142
|
|
143
|
-
I18n.with_locale(
|
143
|
+
I18n.with_locale("lol") do
|
144
144
|
message = I18n.t("authlogic.error_messages.email_invalid")
|
145
145
|
|
146
146
|
cat = User.new
|
147
|
-
cat.email =
|
147
|
+
cat.email = "meow"
|
148
148
|
cat.valid?
|
149
149
|
|
150
150
|
# filter duplicate error messages
|
@@ -213,11 +213,11 @@ module ActsAsAuthenticTest
|
|
213
213
|
|
214
214
|
def test_validates_format_of_nonascii_email_field
|
215
215
|
(GOOD_ASCII_EMAILS + GOOD_ISO88591_EMAILS + GOOD_UTF8_EMAILS).each do |e|
|
216
|
-
assert e =~
|
216
|
+
assert e =~ Authlogic::Regex::EMAIL_NONASCII, "Good email should validate: #{e}"
|
217
217
|
end
|
218
218
|
|
219
219
|
(BAD_ASCII_EMAILS + BAD_ISO88591_EMAILS + BAD_UTF8_EMAILS).each do |e|
|
220
|
-
assert e !~
|
220
|
+
assert e !~ Authlogic::Regex::EMAIL_NONASCII, "Bad email should not validate: #{e}"
|
221
221
|
end
|
222
222
|
end
|
223
223
|
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require
|
1
|
+
require "test_helper"
|
2
2
|
|
3
3
|
module ActsAsAuthenticTest
|
4
4
|
class LoggedInStatusTest < ActiveSupport::TestCase
|
5
|
-
ERROR_MSG =
|
5
|
+
ERROR_MSG = "Multiple calls to %s should result in different relations".freeze
|
6
6
|
|
7
7
|
def test_logged_in_timeout_config
|
8
8
|
assert_equal 10.minutes.to_i, User.logged_in_timeout
|
@@ -25,7 +25,7 @@ module ActsAsAuthenticTest
|
|
25
25
|
query1 = User.logged_in.to_sql
|
26
26
|
sleep 0.1
|
27
27
|
query2 = User.logged_in.to_sql
|
28
|
-
assert query1 != query2, ERROR_MSG %
|
28
|
+
assert query1 != query2, ERROR_MSG % "#logged_in"
|
29
29
|
|
30
30
|
assert_equal 0, User.logged_in.count
|
31
31
|
user = User.first
|
@@ -43,7 +43,7 @@ module ActsAsAuthenticTest
|
|
43
43
|
|
44
44
|
# for rails 5 I've changed the where_values to to_sql to compare
|
45
45
|
|
46
|
-
assert User.logged_in.to_sql != User.logged_out.to_sql, ERROR_MSG %
|
46
|
+
assert User.logged_in.to_sql != User.logged_out.to_sql, ERROR_MSG % "#logged_out"
|
47
47
|
|
48
48
|
assert_equal 3, User.logged_out.count
|
49
49
|
User.first.update_attribute(:last_request_at, Time.now)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "test_helper"
|
2
2
|
|
3
3
|
module ActsAsAuthenticTest
|
4
4
|
# Tests for configuration option: `validates_format_of_login_field_options`
|
@@ -36,7 +36,7 @@ module ActsAsAuthenticTest
|
|
36
36
|
with: /\A[a-zA-Z0-9_][a-zA-Z0-9\.+\-_@ ]+\z/,
|
37
37
|
message: proc do
|
38
38
|
I18n.t(
|
39
|
-
|
39
|
+
"error_messages.login_invalid",
|
40
40
|
default: "should use only letters, numbers, spaces, and .-_@+ please."
|
41
41
|
)
|
42
42
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "test_helper"
|
2
2
|
|
3
3
|
module ActsAsAuthenticTest
|
4
4
|
class PerishableTokenTest < ActiveSupport::TestCase
|
@@ -89,7 +89,7 @@ module ActsAsAuthenticTest
|
|
89
89
|
|
90
90
|
def test_find_perishable_token_with_bang
|
91
91
|
assert_raises ActiveRecord::RecordNotFound do
|
92
|
-
User.find_using_perishable_token!(
|
92
|
+
User.find_using_perishable_token!("some_bad_value")
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|
@@ -1,7 +1,16 @@
|
|
1
|
-
require
|
1
|
+
require "test_helper"
|
2
2
|
|
3
3
|
module ActsAsAuthenticTest
|
4
4
|
class RestfulAuthenticationTest < ActiveSupport::TestCase
|
5
|
+
def setup
|
6
|
+
@old_deprecation_behavior = ::ActiveSupport::Deprecation.behavior
|
7
|
+
::ActiveSupport::Deprecation.behavior = :silence
|
8
|
+
end
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
::ActiveSupport::Deprecation.behavior = @old_deprecation_behavior
|
12
|
+
end
|
13
|
+
|
5
14
|
def test_act_like_restful_authentication_config
|
6
15
|
refute User.act_like_restful_authentication
|
7
16
|
refute Employee.act_like_restful_authentication
|
@@ -10,7 +19,7 @@ module ActsAsAuthenticTest
|
|
10
19
|
assert User.act_like_restful_authentication
|
11
20
|
assert_equal Authlogic::CryptoProviders::Sha1, User.crypto_provider
|
12
21
|
assert defined?(::REST_AUTH_SITE_KEY)
|
13
|
-
assert_equal
|
22
|
+
assert_equal "", ::REST_AUTH_SITE_KEY
|
14
23
|
assert_equal 1, Authlogic::CryptoProviders::Sha1.stretches
|
15
24
|
|
16
25
|
User.act_like_restful_authentication false
|
@@ -27,7 +36,7 @@ module ActsAsAuthenticTest
|
|
27
36
|
User.transition_from_restful_authentication = true
|
28
37
|
assert User.transition_from_restful_authentication
|
29
38
|
assert defined?(::REST_AUTH_SITE_KEY)
|
30
|
-
assert_equal
|
39
|
+
assert_equal "", ::REST_AUTH_SITE_KEY
|
31
40
|
assert_equal 1, Authlogic::CryptoProviders::Sha1.stretches
|
32
41
|
|
33
42
|
User.transition_from_restful_authentication false
|
data/test/adapter_test.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "test_helper"
|
2
2
|
|
3
3
|
module Authlogic
|
4
4
|
module ControllerAdapters
|
@@ -6,7 +6,7 @@ module Authlogic
|
|
6
6
|
def test_controller
|
7
7
|
controller = Class.new(MockController) do
|
8
8
|
def controller.an_arbitrary_method
|
9
|
-
|
9
|
+
"bar"
|
10
10
|
end
|
11
11
|
end.new
|
12
12
|
adapter = Authlogic::ControllerAdapters::AbstractAdapter.new(controller)
|
@@ -14,7 +14,7 @@ module Authlogic
|
|
14
14
|
assert_equal controller, adapter.controller
|
15
15
|
assert controller.params.equal?(adapter.params)
|
16
16
|
assert adapter.respond_to?(:an_arbitrary_method)
|
17
|
-
assert_equal
|
17
|
+
assert_equal "bar", adapter.an_arbitrary_method
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
data/test/config_test.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "test_helper"
|
2
2
|
|
3
3
|
class ConfigTest < ActiveSupport::TestCase
|
4
4
|
def setup
|
@@ -6,7 +6,7 @@ class ConfigTest < ActiveSupport::TestCase
|
|
6
6
|
extend Authlogic::Config
|
7
7
|
|
8
8
|
def self.foobar(value = nil)
|
9
|
-
rw_config(:foobar_field, value,
|
9
|
+
rw_config(:foobar_field, value, "default_foobar")
|
10
10
|
end
|
11
11
|
}
|
12
12
|
|
@@ -18,19 +18,19 @@ class ConfigTest < ActiveSupport::TestCase
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def test_rw_config_read_with_default
|
21
|
-
assert
|
21
|
+
assert "default_foobar", @klass.foobar
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_rw_config_write
|
25
|
-
assert_equal
|
26
|
-
assert_equal
|
25
|
+
assert_equal "my_foobar", @klass.foobar("my_foobar")
|
26
|
+
assert_equal "my_foobar", @klass.foobar
|
27
27
|
|
28
|
-
assert_equal
|
29
|
-
assert_equal
|
28
|
+
assert_equal "my_new_foobar", @klass.foobar("my_new_foobar")
|
29
|
+
assert_equal "my_new_foobar", @klass.foobar
|
30
30
|
end
|
31
31
|
|
32
32
|
def test_subclass_rw_config_write
|
33
|
-
assert_equal
|
34
|
-
assert_equal
|
33
|
+
assert_equal "subklass_foobar", @subklass.foobar("subklass_foobar")
|
34
|
+
assert_equal "default_foobar", @klass.foobar
|
35
35
|
end
|
36
36
|
end
|