authlogic 3.8.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/authlogic/acts_as_authentic/base.rb +33 -36
- data/lib/authlogic/acts_as_authentic/email.rb +8 -141
- data/lib/authlogic/acts_as_authentic/logged_in_status.rb +17 -10
- data/lib/authlogic/acts_as_authentic/login.rb +14 -165
- data/lib/authlogic/acts_as_authentic/magic_columns.rb +13 -10
- data/lib/authlogic/acts_as_authentic/password.rb +186 -254
- data/lib/authlogic/acts_as_authentic/perishable_token.rb +30 -22
- data/lib/authlogic/acts_as_authentic/persistence_token.rb +19 -18
- data/lib/authlogic/acts_as_authentic/queries/case_sensitivity.rb +53 -0
- data/lib/authlogic/acts_as_authentic/queries/find_with_case.rb +83 -0
- data/lib/authlogic/acts_as_authentic/session_maintenance.rb +94 -62
- data/lib/authlogic/acts_as_authentic/single_access_token.rb +28 -14
- data/lib/authlogic/config.rb +29 -10
- data/lib/authlogic/controller_adapters/abstract_adapter.rb +43 -13
- data/lib/authlogic/controller_adapters/rack_adapter.rb +11 -5
- data/lib/authlogic/controller_adapters/rails_adapter.rb +11 -29
- data/lib/authlogic/controller_adapters/sinatra_adapter.rb +8 -2
- data/lib/authlogic/cookie_credentials.rb +63 -0
- data/lib/authlogic/crypto_providers/bcrypt.rb +24 -18
- data/lib/authlogic/crypto_providers/md5/v2.rb +35 -0
- data/lib/authlogic/crypto_providers/md5.rb +8 -6
- data/lib/authlogic/crypto_providers/scrypt.rb +24 -17
- data/lib/authlogic/crypto_providers/sha1/v2.rb +41 -0
- data/lib/authlogic/crypto_providers/sha1.rb +12 -5
- data/lib/authlogic/crypto_providers/sha256/v2.rb +58 -0
- data/lib/authlogic/crypto_providers/sha256.rb +18 -9
- data/lib/authlogic/crypto_providers/sha512/v2.rb +39 -0
- data/lib/authlogic/crypto_providers/sha512.rb +9 -26
- data/lib/authlogic/crypto_providers.rb +77 -1
- data/lib/authlogic/errors.rb +35 -0
- data/lib/authlogic/i18n/translator.rb +4 -1
- data/lib/authlogic/i18n.rb +29 -20
- data/lib/authlogic/random.rb +12 -28
- data/lib/authlogic/session/base.rb +2087 -33
- data/lib/authlogic/session/magic_column/assigns_last_request_at.rb +46 -0
- data/lib/authlogic/test_case/mock_controller.rb +7 -4
- data/lib/authlogic/test_case/mock_cookie_jar.rb +19 -3
- data/lib/authlogic/test_case/mock_logger.rb +2 -0
- data/lib/authlogic/test_case/mock_request.rb +8 -3
- data/lib/authlogic/test_case/rails_request_adapter.rb +5 -2
- data/lib/authlogic/test_case.rb +74 -2
- data/lib/authlogic/version.rb +22 -0
- data/lib/authlogic.rb +33 -54
- metadata +208 -234
- data/.github/ISSUE_TEMPLATE.md +0 -13
- data/.gitignore +0 -14
- data/.rubocop.yml +0 -33
- data/.rubocop_todo.yml +0 -391
- data/.travis.yml +0 -48
- data/CHANGELOG.md +0 -5
- data/CONTRIBUTING.md +0 -60
- data/Gemfile +0 -5
- data/LICENSE +0 -20
- data/README.md +0 -294
- data/Rakefile +0 -21
- data/authlogic.gemspec +0 -27
- data/lib/authlogic/acts_as_authentic/restful_authentication.rb +0 -70
- data/lib/authlogic/acts_as_authentic/validations_scope.rb +0 -32
- data/lib/authlogic/authenticates_many/association.rb +0 -50
- data/lib/authlogic/authenticates_many/base.rb +0 -65
- data/lib/authlogic/crypto_providers/aes256.rb +0 -66
- data/lib/authlogic/crypto_providers/wordpress.rb +0 -43
- data/lib/authlogic/regex.rb +0 -48
- data/lib/authlogic/session/activation.rb +0 -70
- data/lib/authlogic/session/active_record_trickery.rb +0 -61
- data/lib/authlogic/session/brute_force_protection.rb +0 -120
- data/lib/authlogic/session/callbacks.rb +0 -105
- data/lib/authlogic/session/cookies.rb +0 -244
- data/lib/authlogic/session/existence.rb +0 -93
- data/lib/authlogic/session/foundation.rb +0 -55
- data/lib/authlogic/session/http_auth.rb +0 -100
- data/lib/authlogic/session/id.rb +0 -48
- data/lib/authlogic/session/klass.rb +0 -70
- data/lib/authlogic/session/magic_columns.rb +0 -116
- data/lib/authlogic/session/magic_states.rb +0 -76
- data/lib/authlogic/session/params.rb +0 -116
- data/lib/authlogic/session/password.rb +0 -308
- data/lib/authlogic/session/perishable_token.rb +0 -23
- data/lib/authlogic/session/persistence.rb +0 -71
- data/lib/authlogic/session/priority_record.rb +0 -35
- data/lib/authlogic/session/scopes.rb +0 -119
- data/lib/authlogic/session/session.rb +0 -67
- data/lib/authlogic/session/timeout.rb +0 -103
- data/lib/authlogic/session/unauthorized_record.rb +0 -51
- data/lib/authlogic/session/validation.rb +0 -93
- data/test/acts_as_authentic_test/base_test.rb +0 -25
- data/test/acts_as_authentic_test/email_test.rb +0 -240
- data/test/acts_as_authentic_test/logged_in_status_test.rb +0 -62
- data/test/acts_as_authentic_test/login_test.rb +0 -156
- data/test/acts_as_authentic_test/magic_columns_test.rb +0 -27
- data/test/acts_as_authentic_test/password_test.rb +0 -249
- data/test/acts_as_authentic_test/perishable_token_test.rb +0 -90
- data/test/acts_as_authentic_test/persistence_token_test.rb +0 -56
- data/test/acts_as_authentic_test/restful_authentication_test.rb +0 -37
- data/test/acts_as_authentic_test/session_maintenance_test.rb +0 -96
- data/test/acts_as_authentic_test/single_access_test.rb +0 -44
- data/test/authenticates_many_test.rb +0 -31
- data/test/config_test.rb +0 -36
- data/test/crypto_provider_test/aes256_test.rb +0 -14
- data/test/crypto_provider_test/bcrypt_test.rb +0 -14
- data/test/crypto_provider_test/scrypt_test.rb +0 -14
- data/test/crypto_provider_test/sha1_test.rb +0 -23
- data/test/crypto_provider_test/sha256_test.rb +0 -14
- data/test/crypto_provider_test/sha512_test.rb +0 -14
- 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/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
- data/test/gemfiles/Gemfile.rails-4.2.x +0 -7
- data/test/gemfiles/Gemfile.rails-5.0.x +0 -6
- data/test/gemfiles/Gemfile.rails-5.1.x +0 -6
- data/test/gemfiles/Gemfile.rails-5.2.x +0 -6
- data/test/i18n/lol.yml +0 -4
- data/test/i18n_test.rb +0 -33
- data/test/libs/affiliate.rb +0 -7
- data/test/libs/company.rb +0 -6
- data/test/libs/employee.rb +0 -7
- data/test/libs/employee_session.rb +0 -2
- data/test/libs/ldaper.rb +0 -3
- data/test/libs/project.rb +0 -3
- data/test/libs/user.rb +0 -7
- data/test/libs/user_session.rb +0 -25
- data/test/random_test.rb +0 -43
- data/test/session_test/activation_test.rb +0 -43
- data/test/session_test/active_record_trickery_test.rb +0 -75
- data/test/session_test/brute_force_protection_test.rb +0 -108
- data/test/session_test/callbacks_test.rb +0 -34
- data/test/session_test/cookies_test.rb +0 -201
- data/test/session_test/credentials_test.rb +0 -0
- data/test/session_test/existence_test.rb +0 -75
- data/test/session_test/foundation_test.rb +0 -6
- data/test/session_test/http_auth_test.rb +0 -56
- data/test/session_test/id_test.rb +0 -17
- data/test/session_test/klass_test.rb +0 -40
- data/test/session_test/magic_columns_test.rb +0 -62
- data/test/session_test/magic_states_test.rb +0 -58
- data/test/session_test/params_test.rb +0 -53
- data/test/session_test/password_test.rb +0 -105
- data/test/session_test/perishability_test.rb +0 -15
- data/test/session_test/persistence_test.rb +0 -32
- data/test/session_test/scopes_test.rb +0 -60
- data/test/session_test/session_test.rb +0 -78
- data/test/session_test/timeout_test.rb +0 -82
- data/test/session_test/unauthorized_record_test.rb +0 -13
- data/test/session_test/validation_test.rb +0 -23
- data/test/test_helper.rb +0 -233
@@ -1,93 +0,0 @@
|
|
1
|
-
module Authlogic
|
2
|
-
module Session
|
3
|
-
# Provides methods to create and destroy objects. Basically controls their "existence".
|
4
|
-
module Existence
|
5
|
-
class SessionInvalidError < ::StandardError # :nodoc:
|
6
|
-
def initialize(session)
|
7
|
-
super("Your session is invalid and has the following errors: #{session.errors.full_messages.to_sentence}")
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.included(klass)
|
12
|
-
klass.class_eval do
|
13
|
-
extend ClassMethods
|
14
|
-
include InstanceMethods
|
15
|
-
attr_accessor :new_session, :record
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
module ClassMethods
|
20
|
-
# A convenience method. The same as:
|
21
|
-
#
|
22
|
-
# session = UserSession.new(*args)
|
23
|
-
# session.save
|
24
|
-
#
|
25
|
-
# Instead you can do:
|
26
|
-
#
|
27
|
-
# UserSession.create(*args)
|
28
|
-
def create(*args, &block)
|
29
|
-
session = new(*args)
|
30
|
-
session.save(&block)
|
31
|
-
session
|
32
|
-
end
|
33
|
-
|
34
|
-
# Same as create but calls create!, which raises an exception when validation fails.
|
35
|
-
def create!(*args)
|
36
|
-
session = new(*args)
|
37
|
-
session.save!
|
38
|
-
session
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
module InstanceMethods
|
43
|
-
# Clears all errors and the associated record, you should call this terminate a session, thus requiring
|
44
|
-
# the user to authenticate again if it is needed.
|
45
|
-
def destroy
|
46
|
-
before_destroy
|
47
|
-
save_record
|
48
|
-
errors.clear
|
49
|
-
@record = nil
|
50
|
-
after_destroy
|
51
|
-
true
|
52
|
-
end
|
53
|
-
|
54
|
-
# Returns true if the session is new, meaning no action has been taken on it and a successful save
|
55
|
-
# has not taken place.
|
56
|
-
def new_session?
|
57
|
-
new_session != false
|
58
|
-
end
|
59
|
-
|
60
|
-
# After you have specified all of the details for your session you can try to save it. This will
|
61
|
-
# run validation checks and find the associated record, if all validation passes. If validation
|
62
|
-
# does not pass, the save will fail and the errors will be stored in the errors object.
|
63
|
-
def save(&block)
|
64
|
-
result = nil
|
65
|
-
if valid?
|
66
|
-
self.record = attempted_record
|
67
|
-
|
68
|
-
before_save
|
69
|
-
new_session? ? before_create : before_update
|
70
|
-
new_session? ? after_create : after_update
|
71
|
-
after_save
|
72
|
-
|
73
|
-
save_record
|
74
|
-
self.new_session = false
|
75
|
-
result = true
|
76
|
-
else
|
77
|
-
result = false
|
78
|
-
end
|
79
|
-
|
80
|
-
yield result if block_given?
|
81
|
-
result
|
82
|
-
end
|
83
|
-
|
84
|
-
# Same as save but raises an exception of validation errors when validation fails
|
85
|
-
def save!
|
86
|
-
result = save
|
87
|
-
raise SessionInvalidError.new(self) unless result
|
88
|
-
result
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
@@ -1,55 +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
|
-
def initialize(*args)
|
16
|
-
self.credentials = args
|
17
|
-
end
|
18
|
-
|
19
|
-
# The credentials you passed to create your session. See credentials= for more
|
20
|
-
# info.
|
21
|
-
def credentials
|
22
|
-
[]
|
23
|
-
end
|
24
|
-
|
25
|
-
# Set your credentials before you save your session. You can pass a hash of
|
26
|
-
# credentials:
|
27
|
-
#
|
28
|
-
# session.credentials = {:login => "my login", :password => "my password", :remember_me => true}
|
29
|
-
#
|
30
|
-
# or you can pass an array of objects:
|
31
|
-
#
|
32
|
-
# session.credentials = [my_user_object, true]
|
33
|
-
#
|
34
|
-
# and if you need to set an id, just pass it last. This value need be the last
|
35
|
-
# item in the array you pass, since the id is something that you control yourself,
|
36
|
-
# it should never be set from a hash or a form. Examples:
|
37
|
-
#
|
38
|
-
# session.credentials = [{:login => "my login", :password => "my password", :remember_me => true}, :my_id]
|
39
|
-
# session.credentials = [my_user_object, true, :my_id]
|
40
|
-
def credentials=(values)
|
41
|
-
end
|
42
|
-
|
43
|
-
def inspect
|
44
|
-
"#<#{self.class.name}: #{credentials.blank? ? "no credentials provided" : credentials.inspect}>"
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def build_key(last_part)
|
50
|
-
last_part
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,100 +0,0 @@
|
|
1
|
-
module Authlogic
|
2
|
-
module Session
|
3
|
-
# Handles all authentication that deals with basic HTTP auth. Which is authentication built into the HTTP protocol:
|
4
|
-
#
|
5
|
-
# http://username:password@whatever.com
|
6
|
-
#
|
7
|
-
# Also, if you are not comfortable letting users pass their raw username and password you can always use the single
|
8
|
-
# access token. See Authlogic::Session::Params for more info.
|
9
|
-
module HttpAuth
|
10
|
-
def self.included(klass)
|
11
|
-
klass.class_eval do
|
12
|
-
extend Config
|
13
|
-
include InstanceMethods
|
14
|
-
persist :persist_by_http_auth, :if => :persist_by_http_auth?
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
# Configuration for the HTTP basic auth feature of Authlogic.
|
19
|
-
module Config
|
20
|
-
# Do you want to allow your users to log in via HTTP basic auth?
|
21
|
-
#
|
22
|
-
# I recommend keeping this enabled. The only time I feel this should be disabled is if you are not comfortable
|
23
|
-
# having your users provide their raw username and password. Whatever the reason, you can disable it here.
|
24
|
-
#
|
25
|
-
# * <tt>Default:</tt> true
|
26
|
-
# * <tt>Accepts:</tt> Boolean
|
27
|
-
def allow_http_basic_auth(value = nil)
|
28
|
-
rw_config(:allow_http_basic_auth, value, true)
|
29
|
-
end
|
30
|
-
alias_method :allow_http_basic_auth=, :allow_http_basic_auth
|
31
|
-
|
32
|
-
# Whether or not to request HTTP authentication
|
33
|
-
#
|
34
|
-
# If set to true and no HTTP authentication credentials are sent with
|
35
|
-
# the request, the Rails controller method
|
36
|
-
# authenticate_or_request_with_http_basic will be used and a '401
|
37
|
-
# Authorization Required' header will be sent with the response. In
|
38
|
-
# most cases, this will cause the classic HTTP authentication popup to
|
39
|
-
# appear in the users browser.
|
40
|
-
#
|
41
|
-
# If set to false, the Rails controller method
|
42
|
-
# authenticate_with_http_basic is used and no 401 header is sent.
|
43
|
-
#
|
44
|
-
# Note: This parameter has no effect unless allow_http_basic_auth is
|
45
|
-
# true
|
46
|
-
#
|
47
|
-
# * <tt>Default:</tt> false
|
48
|
-
# * <tt>Accepts:</tt> Boolean
|
49
|
-
def request_http_basic_auth(value = nil)
|
50
|
-
rw_config(:request_http_basic_auth, value, false)
|
51
|
-
end
|
52
|
-
alias_method :request_http_basic_auth=, :request_http_basic_auth
|
53
|
-
|
54
|
-
# HTTP authentication realm
|
55
|
-
#
|
56
|
-
# Sets the HTTP authentication realm.
|
57
|
-
#
|
58
|
-
# Note: This option has no effect unless request_http_basic_auth is true
|
59
|
-
#
|
60
|
-
# * <tt>Default:</tt> 'Application'
|
61
|
-
# * <tt>Accepts:</tt> String
|
62
|
-
def http_basic_auth_realm(value = nil)
|
63
|
-
rw_config(:http_basic_auth_realm, value, 'Application')
|
64
|
-
end
|
65
|
-
alias_method :http_basic_auth_realm=, :http_basic_auth_realm
|
66
|
-
end
|
67
|
-
|
68
|
-
# Instance methods for the HTTP basic auth feature of authlogic.
|
69
|
-
module InstanceMethods
|
70
|
-
private
|
71
|
-
|
72
|
-
def persist_by_http_auth?
|
73
|
-
allow_http_basic_auth? && login_field && password_field
|
74
|
-
end
|
75
|
-
|
76
|
-
def persist_by_http_auth
|
77
|
-
login_proc = Proc.new do |login, password|
|
78
|
-
if !login.blank? && !password.blank?
|
79
|
-
send("#{login_field}=", login)
|
80
|
-
send("#{password_field}=", password)
|
81
|
-
valid?
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
if self.class.request_http_basic_auth
|
86
|
-
controller.authenticate_or_request_with_http_basic(self.class.http_basic_auth_realm, &login_proc)
|
87
|
-
else
|
88
|
-
controller.authenticate_with_http_basic(&login_proc)
|
89
|
-
end
|
90
|
-
|
91
|
-
false
|
92
|
-
end
|
93
|
-
|
94
|
-
def allow_http_basic_auth?
|
95
|
-
self.class.allow_http_basic_auth == true
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
data/lib/authlogic/session/id.rb
DELETED
@@ -1,48 +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 self.included(klass)
|
7
|
-
klass.class_eval do
|
8
|
-
attr_writer :id
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
# Setting the id if it is passed in the credentials.
|
13
|
-
def credentials=(value)
|
14
|
-
super
|
15
|
-
values = value.is_a?(Array) ? value : [value]
|
16
|
-
self.id = values.last if values.last.is_a?(Symbol)
|
17
|
-
end
|
18
|
-
|
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.
|
26
|
-
#
|
27
|
-
# You can set the id during initialization (see initialize for more
|
28
|
-
# information), or as an attribute:
|
29
|
-
#
|
30
|
-
# session.id = :my_id
|
31
|
-
#
|
32
|
-
# Just be sure and set your id before you save your session.
|
33
|
-
#
|
34
|
-
# Lastly, to retrieve your session with the id check out the find class
|
35
|
-
# method.
|
36
|
-
def id
|
37
|
-
@id
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
# Used for things like cookie_key, session_key, etc.
|
43
|
-
def build_key(last_part)
|
44
|
-
[id, super].compact.join("_")
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
@@ -1,70 +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 automatically try User
|
20
|
-
# * <tt>Accepts:</tt> an ActiveRecord class
|
21
|
-
def authenticate_with(klass)
|
22
|
-
@klass_name = klass.name
|
23
|
-
@klass = klass
|
24
|
-
end
|
25
|
-
alias_method :authenticate_with=, :authenticate_with
|
26
|
-
|
27
|
-
# The name of the class that this session is authenticating with. For example, the UserSession class will
|
28
|
-
# authenticate with the User class unless you specify otherwise in your configuration. See authenticate_with
|
29
|
-
# for information on how to change this value.
|
30
|
-
def klass
|
31
|
-
@klass ||= klass_name ? klass_name.constantize : nil
|
32
|
-
end
|
33
|
-
|
34
|
-
# The string of the model name class guessed from the actual session class name.
|
35
|
-
def klass_name
|
36
|
-
return @klass_name if defined?(@klass_name)
|
37
|
-
@klass_name = name.scan(/(.*)Session/)[0]
|
38
|
-
@klass_name = klass_name ? klass_name[0] : nil
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
module InstanceMethods
|
43
|
-
# Creating an alias method for the "record" method based on the klass name, so that we can do:
|
44
|
-
#
|
45
|
-
# session.user
|
46
|
-
#
|
47
|
-
# instead of:
|
48
|
-
#
|
49
|
-
# session.record
|
50
|
-
def initialize(*args)
|
51
|
-
if !self.class.configured_klass_methods
|
52
|
-
self.class.send(:alias_method, klass_name.demodulize.underscore.to_sym, :record)
|
53
|
-
self.class.configured_klass_methods = true
|
54
|
-
end
|
55
|
-
super
|
56
|
-
end
|
57
|
-
|
58
|
-
private
|
59
|
-
|
60
|
-
def klass
|
61
|
-
self.class.klass
|
62
|
-
end
|
63
|
-
|
64
|
-
def klass_name
|
65
|
-
self.class.klass_name
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
@@ -1,116 +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 up the magic columns feature.
|
47
|
-
module InstanceMethods
|
48
|
-
private
|
49
|
-
|
50
|
-
def increase_failed_login_count
|
51
|
-
if invalid_password? && attempted_record.respond_to?(:failed_login_count)
|
52
|
-
attempted_record.failed_login_count ||= 0
|
53
|
-
attempted_record.failed_login_count += 1
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def update_info
|
58
|
-
if record.respond_to?(:login_count)
|
59
|
-
record.login_count = (record.login_count.blank? ? 1 : record.login_count + 1)
|
60
|
-
end
|
61
|
-
|
62
|
-
if record.respond_to?(:failed_login_count)
|
63
|
-
record.failed_login_count = 0
|
64
|
-
end
|
65
|
-
|
66
|
-
if record.respond_to?(:current_login_at)
|
67
|
-
record.last_login_at = record.current_login_at if record.respond_to?(:last_login_at)
|
68
|
-
record.current_login_at = klass.default_timezone == :utc ? Time.now.utc : Time.now
|
69
|
-
end
|
70
|
-
|
71
|
-
if record.respond_to?(:current_login_ip)
|
72
|
-
record.last_login_ip = record.current_login_ip if record.respond_to?(:last_login_ip)
|
73
|
-
record.current_login_ip = controller.request.ip
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
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.
|
83
|
-
#
|
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:
|
89
|
-
#
|
90
|
-
# def last_request_update_allowed?
|
91
|
-
# action_name != "update_session_time_left"
|
92
|
-
# end
|
93
|
-
#
|
94
|
-
# You can do whatever you want with that method.
|
95
|
-
def set_last_request_at? # :doc:
|
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
|
104
|
-
end
|
105
|
-
|
106
|
-
def set_last_request_at
|
107
|
-
record.last_request_at = klass.default_timezone == :utc ? Time.now.utc : Time.now
|
108
|
-
end
|
109
|
-
|
110
|
-
def last_request_at_threshold
|
111
|
-
self.class.last_request_at_threshold
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
@@ -1,76 +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
|
-
def validate_magic_states
|
58
|
-
return true if attempted_record.nil?
|
59
|
-
[:active, :approved, :confirmed].each do |required_status|
|
60
|
-
if attempted_record.respond_to?("#{required_status}?") && !attempted_record.send("#{required_status}?")
|
61
|
-
errors.add(
|
62
|
-
:base,
|
63
|
-
I18n.t(
|
64
|
-
"error_messages.not_#{required_status}",
|
65
|
-
:default => "Your account is not #{required_status}"
|
66
|
-
)
|
67
|
-
)
|
68
|
-
return false
|
69
|
-
end
|
70
|
-
end
|
71
|
-
true
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
@@ -1,116 +0,0 @@
|
|
1
|
-
module Authlogic
|
2
|
-
module Session
|
3
|
-
# This module is responsible for authenticating the user via params, which ultimately
|
4
|
-
# allows the user to log in using a URL like the following:
|
5
|
-
#
|
6
|
-
# https://www.domain.com?user_credentials=4LiXF7FiGUppIPubBPey
|
7
|
-
#
|
8
|
-
# Notice the token in the URL, this is a single access token. A single access token is
|
9
|
-
# used for single access only, it is not persisted. Meaning the user provides it,
|
10
|
-
# Authlogic grants them access, and that's it. If they want access again they need to
|
11
|
-
# provide the token again. Authlogic will *NEVER* try to persist the session after
|
12
|
-
# authenticating through this method.
|
13
|
-
#
|
14
|
-
# For added security, this token is *ONLY* allowed for RSS and ATOM requests. You can
|
15
|
-
# change this with the configuration. You can also define if it is allowed dynamically
|
16
|
-
# by defining a single_access_allowed? method in your controller. For example:
|
17
|
-
#
|
18
|
-
# class UsersController < ApplicationController
|
19
|
-
# private
|
20
|
-
# def single_access_allowed?
|
21
|
-
# action_name == "index"
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# Also, by default, this token is permanent. Meaning if the user changes their
|
25
|
-
# password, this token will remain the same. It will only change when it is explicitly
|
26
|
-
# reset.
|
27
|
-
#
|
28
|
-
# You can modify all of this behavior with the Config sub module.
|
29
|
-
module Params
|
30
|
-
def self.included(klass)
|
31
|
-
klass.class_eval do
|
32
|
-
extend Config
|
33
|
-
include InstanceMethods
|
34
|
-
attr_accessor :single_access
|
35
|
-
persist :persist_by_params
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# Configuration for the params / single access feature.
|
40
|
-
module Config
|
41
|
-
# Works exactly like cookie_key, but for params. So a user can login via
|
42
|
-
# params just like a cookie or a session. Your URL would look like:
|
43
|
-
#
|
44
|
-
# http://www.domain.com?user_credentials=my_single_access_key
|
45
|
-
#
|
46
|
-
# You can change the "user_credentials" key above with this
|
47
|
-
# configuration option. Keep in mind, just like cookie_key, if you
|
48
|
-
# supply an id the id will be appended to the front. Check out
|
49
|
-
# cookie_key for more details. Also checkout the "Single Access /
|
50
|
-
# Private Feeds Access" section in the README.
|
51
|
-
#
|
52
|
-
# * <tt>Default:</tt> cookie_key
|
53
|
-
# * <tt>Accepts:</tt> String
|
54
|
-
def params_key(value = nil)
|
55
|
-
rw_config(:params_key, value, cookie_key)
|
56
|
-
end
|
57
|
-
alias_method :params_key=, :params_key
|
58
|
-
|
59
|
-
# Authentication is allowed via a single access token, but maybe this is
|
60
|
-
# something you don't want for your application as a whole. Maybe this
|
61
|
-
# is something you only want for specific request types. Specify a list
|
62
|
-
# of allowed request types and single access authentication will only be
|
63
|
-
# allowed for the ones you specify.
|
64
|
-
#
|
65
|
-
# * <tt>Default:</tt> ["application/rss+xml", "application/atom+xml"]
|
66
|
-
# * <tt>Accepts:</tt> String of a request type, or :all or :any to
|
67
|
-
# allow single access authentication for any and all request types
|
68
|
-
def single_access_allowed_request_types(value = nil)
|
69
|
-
rw_config(:single_access_allowed_request_types, value, ["application/rss+xml", "application/atom+xml"])
|
70
|
-
end
|
71
|
-
alias_method :single_access_allowed_request_types=, :single_access_allowed_request_types
|
72
|
-
end
|
73
|
-
|
74
|
-
# The methods available for an Authlogic::Session::Base object that make
|
75
|
-
# up the params / single access feature.
|
76
|
-
module InstanceMethods
|
77
|
-
private
|
78
|
-
|
79
|
-
def persist_by_params
|
80
|
-
return false if !params_enabled?
|
81
|
-
self.unauthorized_record = search_for_record("find_by_single_access_token", params_credentials)
|
82
|
-
self.single_access = valid?
|
83
|
-
end
|
84
|
-
|
85
|
-
def params_enabled?
|
86
|
-
return false if !params_credentials || !klass.column_names.include?("single_access_token")
|
87
|
-
return controller.single_access_allowed? if controller.responds_to_single_access_allowed?
|
88
|
-
|
89
|
-
case single_access_allowed_request_types
|
90
|
-
when Array
|
91
|
-
single_access_allowed_request_types.include?(controller.request_content_type) ||
|
92
|
-
single_access_allowed_request_types.include?(:all)
|
93
|
-
else
|
94
|
-
[:all, :any].include?(single_access_allowed_request_types)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def params_key
|
99
|
-
build_key(self.class.params_key)
|
100
|
-
end
|
101
|
-
|
102
|
-
def single_access?
|
103
|
-
single_access == true
|
104
|
-
end
|
105
|
-
|
106
|
-
def single_access_allowed_request_types
|
107
|
-
self.class.single_access_allowed_request_types
|
108
|
-
end
|
109
|
-
|
110
|
-
def params_credentials
|
111
|
-
controller.params[params_key]
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|