authlogic 3.8.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/triage.md +87 -0
- data/.gitignore +2 -1
- data/.rubocop.yml +62 -6
- data/.rubocop_todo.yml +51 -267
- data/.travis.yml +4 -26
- data/CHANGELOG.md +226 -2
- data/CONTRIBUTING.md +15 -5
- data/Gemfile +2 -2
- data/README.md +183 -91
- data/Rakefile +1 -1
- data/UPGRADING.md +20 -0
- data/authlogic.gemspec +25 -16
- data/lib/authlogic.rb +45 -45
- data/lib/authlogic/acts_as_authentic/base.rb +18 -11
- data/lib/authlogic/acts_as_authentic/email.rb +32 -28
- data/lib/authlogic/acts_as_authentic/logged_in_status.rb +1 -1
- data/lib/authlogic/acts_as_authentic/login.rb +32 -42
- data/lib/authlogic/acts_as_authentic/magic_columns.rb +6 -6
- data/lib/authlogic/acts_as_authentic/password.rb +53 -31
- data/lib/authlogic/acts_as_authentic/perishable_token.rb +18 -17
- data/lib/authlogic/acts_as_authentic/persistence_token.rb +7 -12
- data/lib/authlogic/acts_as_authentic/queries/find_with_case.rb +64 -0
- data/lib/authlogic/acts_as_authentic/restful_authentication.rb +11 -3
- data/lib/authlogic/acts_as_authentic/session_maintenance.rb +30 -10
- data/lib/authlogic/acts_as_authentic/single_access_token.rb +4 -4
- data/lib/authlogic/authenticates_many/association.rb +3 -3
- data/lib/authlogic/authenticates_many/base.rb +2 -2
- data/lib/authlogic/config.rb +0 -1
- data/lib/authlogic/controller_adapters/abstract_adapter.rb +11 -4
- data/lib/authlogic/controller_adapters/rack_adapter.rb +7 -3
- data/lib/authlogic/controller_adapters/rails_adapter.rb +2 -0
- data/lib/authlogic/crypto_providers/aes256.rb +1 -1
- data/lib/authlogic/crypto_providers/bcrypt.rb +1 -1
- data/lib/authlogic/crypto_providers/scrypt.rb +6 -6
- data/lib/authlogic/crypto_providers/sha1.rb +10 -5
- data/lib/authlogic/crypto_providers/sha256.rb +11 -8
- data/lib/authlogic/crypto_providers/wordpress.rb +2 -2
- data/lib/authlogic/i18n.rb +4 -2
- data/lib/authlogic/random.rb +10 -28
- data/lib/authlogic/regex.rb +11 -8
- data/lib/authlogic/session/activation.rb +6 -3
- data/lib/authlogic/session/active_record_trickery.rb +13 -9
- data/lib/authlogic/session/base.rb +15 -4
- data/lib/authlogic/session/brute_force_protection.rb +14 -7
- data/lib/authlogic/session/callbacks.rb +53 -30
- data/lib/authlogic/session/cookies.rb +57 -16
- data/lib/authlogic/session/existence.rb +21 -11
- data/lib/authlogic/session/foundation.rb +56 -10
- data/lib/authlogic/session/http_auth.rb +15 -8
- data/lib/authlogic/session/klass.rb +7 -5
- data/lib/authlogic/session/magic_columns.rb +24 -11
- data/lib/authlogic/session/magic_states.rb +11 -4
- data/lib/authlogic/session/params.rb +6 -2
- data/lib/authlogic/session/password.rb +46 -73
- data/lib/authlogic/session/persistence.rb +11 -7
- data/lib/authlogic/session/priority_record.rb +7 -4
- data/lib/authlogic/session/scopes.rb +15 -6
- data/lib/authlogic/session/session.rb +20 -10
- data/lib/authlogic/session/timeout.rb +2 -2
- data/lib/authlogic/session/unauthorized_record.rb +1 -1
- data/lib/authlogic/session/validation.rb +1 -1
- data/lib/authlogic/test_case.rb +65 -2
- data/lib/authlogic/test_case/mock_controller.rb +5 -4
- data/lib/authlogic/test_case/mock_cookie_jar.rb +11 -2
- data/lib/authlogic/test_case/mock_request.rb +5 -1
- data/lib/authlogic/test_case/rails_request_adapter.rb +3 -2
- data/lib/authlogic/version.rb +16 -0
- data/test/acts_as_authentic_test/email_test.rb +33 -34
- data/test/acts_as_authentic_test/logged_in_status_test.rb +1 -1
- data/test/acts_as_authentic_test/login_test.rb +73 -78
- data/test/acts_as_authentic_test/password_test.rb +30 -18
- data/test/acts_as_authentic_test/perishable_token_test.rb +9 -3
- data/test/acts_as_authentic_test/persistence_token_test.rb +4 -0
- data/test/acts_as_authentic_test/session_maintenance_test.rb +66 -14
- data/test/adapter_test.rb +21 -0
- data/test/gemfiles/Gemfile.rails-4.2.x +2 -2
- data/test/gemfiles/Gemfile.rails-5.0.x +2 -2
- data/test/gemfiles/Gemfile.rails-master +6 -0
- data/test/i18n_test.rb +1 -1
- data/test/libs/company.rb +2 -2
- data/test/random_test.rb +7 -37
- data/test/session_test/active_record_trickery_test.rb +4 -3
- data/test/session_test/brute_force_protection_test.rb +8 -8
- data/test/session_test/callbacks_test.rb +1 -1
- data/test/session_test/cookies_test.rb +27 -4
- data/test/session_test/existence_test.rb +15 -4
- data/test/session_test/foundation_test.rb +16 -0
- data/test/session_test/http_auth_test.rb +3 -1
- data/test/session_test/magic_columns_test.rb +10 -12
- data/test/session_test/params_test.rb +4 -1
- data/test/session_test/password_test.rb +7 -7
- data/test/session_test/persistence_test.rb +1 -0
- data/test/session_test/scopes_test.rb +7 -7
- 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/test_helper.rb +111 -103
- metadata +68 -64
- data/test/gemfiles/Gemfile.rails-3.2.x +0 -7
- data/test/gemfiles/Gemfile.rails-4.0.x +0 -7
- data/test/gemfiles/Gemfile.rails-4.1.x +0 -7
@@ -29,14 +29,14 @@ module Authlogic
|
|
29
29
|
# All method, for the single_access token aspect of acts_as_authentic.
|
30
30
|
module Methods
|
31
31
|
def self.included(klass)
|
32
|
-
return
|
32
|
+
return unless klass.column_names.include?("single_access_token")
|
33
33
|
|
34
34
|
klass.class_eval do
|
35
35
|
include InstanceMethods
|
36
|
-
validates_uniqueness_of :single_access_token, :
|
37
|
-
before_validation :reset_single_access_token, :
|
36
|
+
validates_uniqueness_of :single_access_token, if: :single_access_token_changed?
|
37
|
+
before_validation :reset_single_access_token, if: :reset_single_access_token?
|
38
38
|
if respond_to?(:after_password_set)
|
39
|
-
after_password_set(:reset_single_access_token, :
|
39
|
+
after_password_set(:reset_single_access_token, if: :change_single_access_token_with_password?)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -30,20 +30,20 @@ module Authlogic
|
|
30
30
|
end
|
31
31
|
|
32
32
|
[:create, :create!, :find, :new].each do |method|
|
33
|
-
class_eval <<-
|
33
|
+
class_eval <<-EOS, __FILE__, __LINE__
|
34
34
|
def #{method}(*args)
|
35
35
|
klass.with_scope(scope_options) do
|
36
36
|
klass.#{method}(*args)
|
37
37
|
end
|
38
38
|
end
|
39
|
-
|
39
|
+
EOS
|
40
40
|
end
|
41
41
|
alias_method :build, :new
|
42
42
|
|
43
43
|
private
|
44
44
|
|
45
45
|
def scope_options
|
46
|
-
{ :
|
46
|
+
{ find_options: find_options, id: id }
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -51,12 +51,12 @@ module Authlogic
|
|
51
51
|
def authenticates_many(name, options = {})
|
52
52
|
options[:session_class] ||= name.to_s.classify.constantize
|
53
53
|
options[:relationship_name] ||= options[:session_class].klass_name.underscore.pluralize
|
54
|
-
class_eval <<-
|
54
|
+
class_eval <<-EOS, __FILE__, __LINE__
|
55
55
|
def #{name}
|
56
56
|
find_options = #{options[:find_options].inspect} || #{options[:relationship_name]}.where(nil)
|
57
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"})
|
58
58
|
end
|
59
|
-
|
59
|
+
EOS
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
data/lib/authlogic/config.rb
CHANGED
@@ -3,16 +3,19 @@ module Authlogic
|
|
3
3
|
# Allows you to use Authlogic in any framework you want, not just rails. See the RailsAdapter
|
4
4
|
# for an example of how to adapt Authlogic to work with your framework.
|
5
5
|
class AbstractAdapter
|
6
|
+
E_COOKIE_DOMAIN_ADAPTER = "The cookie_domain method has not been " \
|
7
|
+
"implemented by the controller adapter".freeze
|
8
|
+
|
6
9
|
attr_accessor :controller
|
7
10
|
|
8
11
|
def initialize(controller)
|
9
12
|
self.controller = controller
|
10
13
|
end
|
11
14
|
|
12
|
-
def authenticate_with_http_basic
|
15
|
+
def authenticate_with_http_basic
|
13
16
|
@auth = Rack::Auth::Basic::Request.new(controller.request.env)
|
14
|
-
if @auth.provided?
|
15
|
-
|
17
|
+
if @auth.provided? && @auth.basic?
|
18
|
+
yield(*@auth.credentials)
|
16
19
|
else
|
17
20
|
false
|
18
21
|
end
|
@@ -23,7 +26,7 @@ module Authlogic
|
|
23
26
|
end
|
24
27
|
|
25
28
|
def cookie_domain
|
26
|
-
raise NotImplementedError.new(
|
29
|
+
raise NotImplementedError.new(E_COOKIE_DOMAIN_ADAPTER)
|
27
30
|
end
|
28
31
|
|
29
32
|
def params
|
@@ -58,6 +61,10 @@ module Authlogic
|
|
58
61
|
controller.send(:last_request_update_allowed?)
|
59
62
|
end
|
60
63
|
|
64
|
+
def respond_to_missing?(*args)
|
65
|
+
super(*args) || controller.respond_to?(*args)
|
66
|
+
end
|
67
|
+
|
61
68
|
private
|
62
69
|
|
63
70
|
def method_missing(id, *args, &block)
|
@@ -56,10 +56,14 @@ module Authlogic
|
|
56
56
|
Authlogic::Session::Base.controller = self
|
57
57
|
end
|
58
58
|
|
59
|
-
# Rack Requests stores cookies with not just the value, but also with
|
60
|
-
#
|
59
|
+
# Rack Requests stores cookies with not just the value, but also with
|
60
|
+
# flags and expire information in the hash. Authlogic does not like this,
|
61
|
+
# so we drop everything except the cookie value.
|
61
62
|
def cookies
|
62
|
-
controller
|
63
|
+
controller
|
64
|
+
.cookies
|
65
|
+
.map { |key, value_hash| { key => value_hash[:value] } }
|
66
|
+
.inject(:merge) || {}
|
63
67
|
end
|
64
68
|
end
|
65
69
|
end
|
@@ -13,6 +13,8 @@ module Authlogic
|
|
13
13
|
controller.authenticate_with_http_basic(&block)
|
14
14
|
end
|
15
15
|
|
16
|
+
# Returns a `ActionDispatch::Cookies::CookieJar`. See the AC guide
|
17
|
+
# http://guides.rubyonrails.org/action_controller_overview.html#cookies
|
16
18
|
def cookies
|
17
19
|
controller.send(:cookies)
|
18
20
|
end
|
@@ -6,7 +6,7 @@ module Authlogic
|
|
6
6
|
# use this encryption method you must supply it with a key first. In an initializer,
|
7
7
|
# or before your application initializes, you should do the following:
|
8
8
|
#
|
9
|
-
# Authlogic::CryptoProviders::AES256.key = "
|
9
|
+
# Authlogic::CryptoProviders::AES256.key = "long, unique, and random key"
|
10
10
|
#
|
11
11
|
# My final comment is that this is a strong encryption method, but its main weakness
|
12
12
|
# is that it's reversible. If you do not need to reverse the hash then you should
|
@@ -66,7 +66,7 @@ module Authlogic
|
|
66
66
|
|
67
67
|
# Creates a BCrypt hash for the password passed.
|
68
68
|
def encrypt(*tokens)
|
69
|
-
::BCrypt::Password.create(join_tokens(tokens), :
|
69
|
+
::BCrypt::Password.create(join_tokens(tokens), cost: cost)
|
70
70
|
end
|
71
71
|
|
72
72
|
# Does the hash match the tokens? Uses the same tokens that were used to
|
@@ -19,7 +19,7 @@ module Authlogic
|
|
19
19
|
# end
|
20
20
|
class SCrypt
|
21
21
|
class << self
|
22
|
-
DEFAULTS = { :
|
22
|
+
DEFAULTS = { key_len: 32, salt_size: 8, max_time: 0.2, max_mem: 1024 * 1024, max_memfrac: 0.5 }.freeze
|
23
23
|
|
24
24
|
attr_writer :key_len, :salt_size, :max_time, :max_mem, :max_memfrac
|
25
25
|
# Key length - length in bytes of generated key, from 16 to 512.
|
@@ -51,11 +51,11 @@ module Authlogic
|
|
51
51
|
def encrypt(*tokens)
|
52
52
|
::SCrypt::Password.create(
|
53
53
|
join_tokens(tokens),
|
54
|
-
:
|
55
|
-
:
|
56
|
-
:
|
57
|
-
:
|
58
|
-
:
|
54
|
+
key_len: key_len,
|
55
|
+
salt_size: salt_size,
|
56
|
+
max_mem: max_mem,
|
57
|
+
max_memfrac: max_memfrac,
|
58
|
+
max_time: max_time
|
59
59
|
)
|
60
60
|
end
|
61
61
|
|
@@ -2,8 +2,9 @@ require "digest/sha1"
|
|
2
2
|
|
3
3
|
module Authlogic
|
4
4
|
module CryptoProviders
|
5
|
-
# This class was made for the users transitioning from restful_authentication. I
|
6
|
-
# crypto provider as it is far inferior to your other
|
5
|
+
# This class was made for the users transitioning from restful_authentication. I
|
6
|
+
# highly discourage using this crypto provider as it is far inferior to your other
|
7
|
+
# options. Please use any other provider offered by Authlogic.
|
7
8
|
class Sha1
|
8
9
|
class << self
|
9
10
|
def join_token
|
@@ -11,7 +12,8 @@ module Authlogic
|
|
11
12
|
end
|
12
13
|
attr_writer :join_token
|
13
14
|
|
14
|
-
# The number of times to loop through the encryption. This is ten because that is
|
15
|
+
# The number of times to loop through the encryption. This is ten because that is
|
16
|
+
# what restful_authentication defaults to.
|
15
17
|
def stretches
|
16
18
|
@stretches ||= 10
|
17
19
|
end
|
@@ -21,11 +23,14 @@ module Authlogic
|
|
21
23
|
def encrypt(*tokens)
|
22
24
|
tokens = tokens.flatten
|
23
25
|
digest = tokens.shift
|
24
|
-
stretches.times
|
26
|
+
stretches.times do
|
27
|
+
digest = Digest::SHA1.hexdigest([digest, *tokens].join(join_token))
|
28
|
+
end
|
25
29
|
digest
|
26
30
|
end
|
27
31
|
|
28
|
-
# Does the crypted password match the tokens? Uses the same tokens that were used
|
32
|
+
# Does the crypted password match the tokens? Uses the same tokens that were used
|
33
|
+
# to encrypt.
|
29
34
|
def matches?(crypted, *tokens)
|
30
35
|
encrypt(*tokens) == crypted
|
31
36
|
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
|
-
# # the tokens passed will be an array of objects, what type of object
|
12
|
-
# # just do what you need to do with them and return a
|
13
|
-
# # for example, you will most likely join all
|
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
|
-
# # return true if the crypted string matches the tokens.
|
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
|
@@ -3,13 +3,13 @@ module Authlogic
|
|
3
3
|
module CryptoProviders
|
4
4
|
class Wordpress
|
5
5
|
class << self
|
6
|
-
ITOA64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
6
|
+
ITOA64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.freeze
|
7
7
|
|
8
8
|
def matches?(crypted, *tokens)
|
9
9
|
stretches = 1 << ITOA64.index(crypted[3, 1])
|
10
10
|
plain, salt = *tokens
|
11
11
|
hashed = Digest::MD5.digest(salt + plain)
|
12
|
-
stretches.times do
|
12
|
+
stretches.times do
|
13
13
|
hashed = Digest::MD5.digest(hashed + plain)
|
14
14
|
end
|
15
15
|
crypted[0, 12] + encode_64(hashed, 16) == crypted
|
data/lib/authlogic/i18n.rb
CHANGED
@@ -36,7 +36,8 @@ module Authlogic
|
|
36
36
|
# login_blank: can not be blank
|
37
37
|
# login_not_found: is not valid
|
38
38
|
# login_invalid: should use only letters, numbers, spaces, and .-_@+ please.
|
39
|
-
# consecutive_failed_logins_limit_exceeded:
|
39
|
+
# consecutive_failed_logins_limit_exceeded: >
|
40
|
+
# Consecutive failed logins limit exceeded, account is disabled.
|
40
41
|
# email_invalid: should look like an email address.
|
41
42
|
# email_invalid_international: should look like an international email address.
|
42
43
|
# password_blank: can not be blank
|
@@ -46,6 +47,7 @@ module Authlogic
|
|
46
47
|
# not_approved: Your account is not approved
|
47
48
|
# no_authentication_details: You did not provide any details for authentication.
|
48
49
|
# general_credentials_error: Login/Password combination is not valid
|
50
|
+
# session_invalid: Your session is invalid and has the following errors:
|
49
51
|
# models:
|
50
52
|
# user_session: UserSession (or whatever name you are using)
|
51
53
|
# attributes:
|
@@ -83,7 +85,7 @@ module Authlogic
|
|
83
85
|
# for the message. The second is options, see the rails I18n library for a list of
|
84
86
|
# options used.
|
85
87
|
def translate(key, options = {})
|
86
|
-
translator.translate key, { :
|
88
|
+
translator.translate key, { scope: I18n.scope }.merge(options)
|
87
89
|
end
|
88
90
|
alias :t :translate
|
89
91
|
end
|
data/lib/authlogic/random.rb
CHANGED
@@ -1,34 +1,16 @@
|
|
1
|
+
require "securerandom"
|
2
|
+
|
1
3
|
module Authlogic
|
2
|
-
#
|
3
|
-
# this and use it instead. SecureRandom comes with ActiveSupport. So if you are using
|
4
|
-
# this in a rails app you should have this library.
|
4
|
+
# Generates random strings using ruby's SecureRandom library.
|
5
5
|
module Random
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
(defined?(::ActiveSupport::SecureRandom) && ::ActiveSupport::SecureRandom)
|
10
|
-
|
11
|
-
if SecureRandom
|
12
|
-
def hex_token
|
13
|
-
SecureRandom.hex(64)
|
14
|
-
end
|
15
|
-
|
16
|
-
def friendly_token
|
17
|
-
# use base64url as defined by RFC4648
|
18
|
-
SecureRandom.base64(15).tr('+/=', '').strip.delete("\n")
|
19
|
-
end
|
20
|
-
else
|
21
|
-
def hex_token
|
22
|
-
Authlogic::CryptoProviders::Sha512.encrypt(Time.now.to_s + (1..10).collect { rand.to_s }.join)
|
23
|
-
end
|
24
|
-
|
25
|
-
FRIENDLY_CHARS = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
|
6
|
+
def self.hex_token
|
7
|
+
SecureRandom.hex(64)
|
8
|
+
end
|
26
9
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
10
|
+
# Returns a string in base64url format as defined by RFC-3548 and RFC-4648.
|
11
|
+
# We call this a "friendly" token because it is short and safe for URLs.
|
12
|
+
def self.friendly_token
|
13
|
+
SecureRandom.urlsafe_base64(15)
|
32
14
|
end
|
33
15
|
end
|
34
16
|
end
|
data/lib/authlogic/regex.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
module Authlogic
|
3
|
-
# This is a module the contains regular expressions used throughout Authlogic. The point
|
4
|
-
# them out into their own module is to make them easily available to you
|
2
|
+
# This is a module the contains regular expressions used throughout Authlogic. The point
|
3
|
+
# of extracting them out into their own module is to make them easily available to you
|
4
|
+
# for other uses. Ex:
|
5
5
|
#
|
6
6
|
# validates_format_of :my_email_field, :with => Authlogic::Regex.email
|
7
7
|
module Regex
|
@@ -19,12 +19,15 @@ module Authlogic
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
# A draft regular expression for internationalized email addresses.
|
23
|
-
#
|
24
|
-
#
|
22
|
+
# A draft regular expression for internationalized email addresses. Given that the
|
23
|
+
# standard may be in flux, this simply emulates @email_regex but rather than allowing
|
24
|
+
# specific characters for each part, it instead disallows the complement set of
|
25
|
+
# characters:
|
26
|
+
#
|
25
27
|
# - email_name_regex disallows: @[]^ !"#$()*,/:;<=>?`{|}~\ and control characters
|
26
28
|
# - domain_head_regex disallows: _%+ and all characters in email_name_regex
|
27
29
|
# - domain_tld_regex disallows: 0123456789- and all characters in domain_head_regex
|
30
|
+
#
|
28
31
|
# http://en.wikipedia.org/wiki/Email_address#Internationalization
|
29
32
|
# http://tools.ietf.org/html/rfc6530
|
30
33
|
# http://www.unicode.org/faq/idn.html
|
@@ -39,8 +42,8 @@ module Authlogic
|
|
39
42
|
end
|
40
43
|
end
|
41
44
|
|
42
|
-
# A simple regular expression that only allows for letters, numbers, spaces, and
|
43
|
-
# regular expression.
|
45
|
+
# A simple regular expression that only allows for letters, numbers, spaces, and
|
46
|
+
# .-_@+. Just a standard login / username regular expression.
|
44
47
|
def self.login
|
45
48
|
/\A[a-zA-Z0-9_][a-zA-Z0-9\.+\-_@ ]+\z/
|
46
49
|
end
|
@@ -9,8 +9,11 @@ module Authlogic
|
|
9
9
|
# you are using a supported framework, Authlogic takes care of this for you.
|
10
10
|
module Activation
|
11
11
|
class NotActivatedError < ::StandardError # :nodoc:
|
12
|
-
def initialize
|
13
|
-
super(
|
12
|
+
def initialize
|
13
|
+
super(
|
14
|
+
"You must activate the Authlogic::Session::Base.controller with " \
|
15
|
+
"a controller object before creating objects"
|
16
|
+
)
|
14
17
|
end
|
15
18
|
end
|
16
19
|
|
@@ -55,7 +58,7 @@ module Authlogic
|
|
55
58
|
module InstanceMethods
|
56
59
|
# Making sure we are activated before we start creating objects
|
57
60
|
def initialize(*args)
|
58
|
-
raise NotActivatedError
|
61
|
+
raise NotActivatedError unless self.class.activated?
|
59
62
|
super
|
60
63
|
end
|
61
64
|
|
@@ -1,16 +1,18 @@
|
|
1
1
|
module Authlogic
|
2
2
|
module Session
|
3
|
-
# Authlogic looks like ActiveRecord, sounds like ActiveRecord, but its not
|
4
|
-
# This is useful for the various rails
|
5
|
-
#
|
6
|
-
#
|
3
|
+
# Authlogic looks like ActiveRecord, sounds like ActiveRecord, but its not
|
4
|
+
# ActiveRecord. That's the goal here. This is useful for the various rails
|
5
|
+
# helper methods such as form_for, error_messages_for, or any method that
|
6
|
+
# expects an ActiveRecord object. The point is to disguise the object as an
|
7
|
+
# ActiveRecord object so we can take advantage of the many ActiveRecord
|
8
|
+
# tools.
|
7
9
|
module ActiveRecordTrickery
|
8
10
|
def self.included(klass)
|
9
11
|
klass.extend ActiveModel::Naming
|
10
12
|
klass.extend ActiveModel::Translation
|
11
13
|
|
12
14
|
# Support ActiveModel::Name#name for Rails versions before 4.0.
|
13
|
-
|
15
|
+
unless klass.model_name.respond_to?(:name)
|
14
16
|
ActiveModel::Name.module_eval do
|
15
17
|
alias_method :name, :to_s
|
16
18
|
end
|
@@ -21,11 +23,12 @@ module Authlogic
|
|
21
23
|
end
|
22
24
|
|
23
25
|
module ClassMethods
|
24
|
-
# How to name the class, works JUST LIKE ActiveRecord, except it uses
|
26
|
+
# How to name the class, works JUST LIKE ActiveRecord, except it uses
|
27
|
+
# the following namespace:
|
25
28
|
#
|
26
29
|
# authlogic.models.user_session
|
27
|
-
def human_name(*
|
28
|
-
I18n.t("models.#{name.underscore}",
|
30
|
+
def human_name(*)
|
31
|
+
I18n.t("models.#{name.underscore}", count: 1, default: name.humanize)
|
29
32
|
end
|
30
33
|
|
31
34
|
def i18n_scope
|
@@ -34,7 +37,8 @@ module Authlogic
|
|
34
37
|
end
|
35
38
|
|
36
39
|
module InstanceMethods
|
37
|
-
# Don't use this yourself, this is to just trick some of the helpers
|
40
|
+
# Don't use this yourself, this is to just trick some of the helpers
|
41
|
+
# since this is the method it calls.
|
38
42
|
def new_record?
|
39
43
|
new_session?
|
40
44
|
end
|