authlogic-nicho 6.5
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 +116 -0
- data/lib/authlogic/acts_as_authentic/email.rb +30 -0
- data/lib/authlogic/acts_as_authentic/logged_in_status.rb +85 -0
- data/lib/authlogic/acts_as_authentic/login.rb +63 -0
- data/lib/authlogic/acts_as_authentic/magic_columns.rb +38 -0
- data/lib/authlogic/acts_as_authentic/password.rb +357 -0
- data/lib/authlogic/acts_as_authentic/perishable_token.rb +122 -0
- data/lib/authlogic/acts_as_authentic/persistence_token.rb +70 -0
- 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 +186 -0
- data/lib/authlogic/acts_as_authentic/single_access_token.rb +83 -0
- data/lib/authlogic/config.rb +43 -0
- data/lib/authlogic/controller_adapters/abstract_adapter.rb +119 -0
- data/lib/authlogic/controller_adapters/rack_adapter.rb +72 -0
- data/lib/authlogic/controller_adapters/rails_adapter.rb +47 -0
- data/lib/authlogic/controller_adapters/sinatra_adapter.rb +67 -0
- data/lib/authlogic/cookie_credentials.rb +63 -0
- data/lib/authlogic/crypto_providers/bcrypt.rb +113 -0
- data/lib/authlogic/crypto_providers/md5/v2.rb +35 -0
- data/lib/authlogic/crypto_providers/md5.rb +36 -0
- data/lib/authlogic/crypto_providers/scrypt.rb +92 -0
- data/lib/authlogic/crypto_providers/sha1/v2.rb +41 -0
- data/lib/authlogic/crypto_providers/sha1.rb +42 -0
- data/lib/authlogic/crypto_providers/sha256/v2.rb +58 -0
- data/lib/authlogic/crypto_providers/sha256.rb +59 -0
- data/lib/authlogic/crypto_providers/sha512/v2.rb +39 -0
- data/lib/authlogic/crypto_providers/sha512.rb +38 -0
- data/lib/authlogic/crypto_providers.rb +87 -0
- data/lib/authlogic/errors.rb +50 -0
- data/lib/authlogic/i18n/translator.rb +18 -0
- data/lib/authlogic/i18n.rb +100 -0
- data/lib/authlogic/random.rb +18 -0
- data/lib/authlogic/session/base.rb +2207 -0
- data/lib/authlogic/session/magic_column/assigns_last_request_at.rb +46 -0
- data/lib/authlogic/test_case/mock_api_controller.rb +52 -0
- data/lib/authlogic/test_case/mock_controller.rb +58 -0
- data/lib/authlogic/test_case/mock_cookie_jar.rb +109 -0
- data/lib/authlogic/test_case/mock_logger.rb +12 -0
- data/lib/authlogic/test_case/mock_request.rb +35 -0
- data/lib/authlogic/test_case/rails_request_adapter.rb +39 -0
- data/lib/authlogic/test_case.rb +215 -0
- data/lib/authlogic/version.rb +22 -0
- data/lib/authlogic.rb +44 -0
- metadata +382 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8ad4cd9e890d43f43836ade14ecbf8df7dee14e5adaa4b1fee938f6da376261e
|
4
|
+
data.tar.gz: 8c033ffc5009db9c533b6d1b2015b2cb43715d28d89f3631c4552f9484c6bffc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e5b64a65cb7af995b92d3cd1eff8b47313a28241aac981373593437ca7a430d40c5c6046d01c5451e8040e60f6c66384eac8e6b242a98c1366fa599fee0d7270
|
7
|
+
data.tar.gz: 1e7edcbcc47eb555d5a28a668a0840f37d56f99deff602001a98bbacddb48037e528c575660a5dc5282cf538e2aceb7ee20bca28859fbae836f99566a636f7df
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Authlogic
|
4
|
+
module ActsAsAuthentic
|
5
|
+
# Provides the base functionality for acts_as_authentic
|
6
|
+
module Base
|
7
|
+
def self.included(klass)
|
8
|
+
klass.class_eval do
|
9
|
+
class_attribute :acts_as_authentic_modules
|
10
|
+
self.acts_as_authentic_modules ||= []
|
11
|
+
extend Authlogic::Config
|
12
|
+
extend Config
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# The primary configuration of a model (often, `User`) for use with
|
17
|
+
# authlogic. These methods become class methods of ::ActiveRecord::Base.
|
18
|
+
module Config
|
19
|
+
# This includes a lot of helpful methods for authenticating records
|
20
|
+
# which the Authlogic::Session module relies on. To use it just do:
|
21
|
+
#
|
22
|
+
# class User < ApplicationRecord
|
23
|
+
# acts_as_authentic
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# Configuration is easy:
|
27
|
+
#
|
28
|
+
# acts_as_authentic do |c|
|
29
|
+
# c.my_configuration_option = my_value
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# See the various sub modules for the configuration they provide.
|
33
|
+
def acts_as_authentic
|
34
|
+
yield self if block_given?
|
35
|
+
return unless db_setup?
|
36
|
+
acts_as_authentic_modules.each { |mod| include mod }
|
37
|
+
end
|
38
|
+
|
39
|
+
# Since this part of Authlogic deals with another class, ActiveRecord,
|
40
|
+
# we can't just start including things in ActiveRecord itself. A lot of
|
41
|
+
# these module includes need to be triggered by the acts_as_authentic
|
42
|
+
# method call. For example, you don't want to start adding in email
|
43
|
+
# validations and what not into a model that has nothing to do with
|
44
|
+
# Authlogic.
|
45
|
+
#
|
46
|
+
# That being said, this is your tool for extending Authlogic and
|
47
|
+
# "hooking" into the acts_as_authentic call.
|
48
|
+
def add_acts_as_authentic_module(mod, action = :append)
|
49
|
+
modules = acts_as_authentic_modules.clone
|
50
|
+
case action
|
51
|
+
when :append
|
52
|
+
modules << mod
|
53
|
+
when :prepend
|
54
|
+
modules = [mod] + modules
|
55
|
+
end
|
56
|
+
modules.uniq!
|
57
|
+
self.acts_as_authentic_modules = modules
|
58
|
+
end
|
59
|
+
|
60
|
+
# This is the same as add_acts_as_authentic_module, except that it
|
61
|
+
# removes the module from the list.
|
62
|
+
def remove_acts_as_authentic_module(mod)
|
63
|
+
modules = acts_as_authentic_modules.clone
|
64
|
+
modules.delete(mod)
|
65
|
+
self.acts_as_authentic_modules = modules
|
66
|
+
end
|
67
|
+
|
68
|
+
# Some Authlogic modules requires a database connection with a existing
|
69
|
+
# users table by the moment when you call the `acts_as_authentic`
|
70
|
+
# method. If you try to call `acts_as_authentic` without a database
|
71
|
+
# connection, it will raise a `Authlogic::ModelSetupError`.
|
72
|
+
#
|
73
|
+
# If you rely on the User model before the database is setup correctly,
|
74
|
+
# set this field to false.
|
75
|
+
# * <tt>Default:</tt> false
|
76
|
+
# * <tt>Accepts:</tt> Boolean
|
77
|
+
def raise_on_model_setup_error(value = nil)
|
78
|
+
rw_config(:raise_on_model_setup_error, value, false)
|
79
|
+
end
|
80
|
+
alias raise_on_model_setup_error= raise_on_model_setup_error
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def db_setup?
|
85
|
+
column_names
|
86
|
+
true
|
87
|
+
rescue StandardError
|
88
|
+
raise ModelSetupError if raise_on_model_setup_error
|
89
|
+
false
|
90
|
+
end
|
91
|
+
|
92
|
+
def first_column_to_exist(*columns_to_check)
|
93
|
+
if db_setup?
|
94
|
+
columns_to_check.each do |column_name|
|
95
|
+
if column_names.include?(column_name.to_s)
|
96
|
+
return column_name.to_sym
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
columns_to_check.first&.to_sym
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
::ActiveRecord::Base.send :include, Authlogic::ActsAsAuthentic::Base
|
108
|
+
::ActiveRecord::Base.send :include, Authlogic::ActsAsAuthentic::Email
|
109
|
+
::ActiveRecord::Base.send :include, Authlogic::ActsAsAuthentic::LoggedInStatus
|
110
|
+
::ActiveRecord::Base.send :include, Authlogic::ActsAsAuthentic::Login
|
111
|
+
::ActiveRecord::Base.send :include, Authlogic::ActsAsAuthentic::MagicColumns
|
112
|
+
::ActiveRecord::Base.send :include, Authlogic::ActsAsAuthentic::Password
|
113
|
+
::ActiveRecord::Base.send :include, Authlogic::ActsAsAuthentic::PerishableToken
|
114
|
+
::ActiveRecord::Base.send :include, Authlogic::ActsAsAuthentic::PersistenceToken
|
115
|
+
::ActiveRecord::Base.send :include, Authlogic::ActsAsAuthentic::SessionMaintenance
|
116
|
+
::ActiveRecord::Base.send :include, Authlogic::ActsAsAuthentic::SingleAccessToken
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Authlogic
|
4
|
+
module ActsAsAuthentic
|
5
|
+
# Sometimes models won't have an explicit "login" or "username" field.
|
6
|
+
# Instead they want to use the email field. In this case, authlogic provides
|
7
|
+
# validations to make sure the email submited is actually a valid email.
|
8
|
+
# Don't worry, if you do have a login or username field, Authlogic will
|
9
|
+
# still validate your email field. One less thing you have to worry about.
|
10
|
+
module Email
|
11
|
+
def self.included(klass)
|
12
|
+
klass.class_eval do
|
13
|
+
extend Config
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Configuration to modify how Authlogic handles the email field.
|
18
|
+
module Config
|
19
|
+
# The name of the field that stores email addresses.
|
20
|
+
#
|
21
|
+
# * <tt>Default:</tt> :email, if it exists
|
22
|
+
# * <tt>Accepts:</tt> Symbol
|
23
|
+
def email_field(value = nil)
|
24
|
+
rw_config(:email_field, value, first_column_to_exist(nil, :email, :email_address))
|
25
|
+
end
|
26
|
+
alias email_field= email_field
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Authlogic
|
4
|
+
module ActsAsAuthentic
|
5
|
+
# Since web applications are stateless there is not sure fire way to tell if
|
6
|
+
# a user is logged in or not, from the database perspective. The best way to
|
7
|
+
# do this is to provide a "timeout" based on inactivity. So if that user is
|
8
|
+
# inactive for a certain amount of time we assume they are logged out.
|
9
|
+
# That's what this module is all about.
|
10
|
+
module LoggedInStatus
|
11
|
+
def self.included(klass)
|
12
|
+
klass.class_eval do
|
13
|
+
extend Config
|
14
|
+
add_acts_as_authentic_module(Methods)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# All configuration for the logged in status feature set.
|
19
|
+
module Config
|
20
|
+
# The timeout to determine when a user is logged in or not.
|
21
|
+
#
|
22
|
+
# * <tt>Default:</tt> 10.minutes
|
23
|
+
# * <tt>Accepts:</tt> Fixnum
|
24
|
+
def logged_in_timeout(value = nil)
|
25
|
+
rw_config(:logged_in_timeout, (!value.nil? && value.to_i) || value, 10.minutes.to_i)
|
26
|
+
end
|
27
|
+
alias logged_in_timeout= logged_in_timeout
|
28
|
+
end
|
29
|
+
|
30
|
+
# All methods for the logged in status feature seat.
|
31
|
+
module Methods
|
32
|
+
def self.included(klass)
|
33
|
+
return unless klass.column_names.include?("last_request_at")
|
34
|
+
|
35
|
+
klass.class_eval do
|
36
|
+
include InstanceMethods
|
37
|
+
scope(
|
38
|
+
:logged_in,
|
39
|
+
lambda do
|
40
|
+
where(
|
41
|
+
"last_request_at > ? and current_login_at IS NOT NULL",
|
42
|
+
logged_in_timeout.seconds.ago
|
43
|
+
)
|
44
|
+
end
|
45
|
+
)
|
46
|
+
scope(
|
47
|
+
:logged_out,
|
48
|
+
lambda do
|
49
|
+
where(
|
50
|
+
"last_request_at is NULL or last_request_at <= ?",
|
51
|
+
logged_in_timeout.seconds.ago
|
52
|
+
)
|
53
|
+
end
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# :nodoc:
|
59
|
+
module InstanceMethods
|
60
|
+
# Returns true if the last_request_at > logged_in_timeout.
|
61
|
+
def logged_in?
|
62
|
+
unless respond_to?(:last_request_at)
|
63
|
+
raise(
|
64
|
+
"Can not determine the records login state because " \
|
65
|
+
"there is no last_request_at column"
|
66
|
+
)
|
67
|
+
end
|
68
|
+
!last_request_at.nil? && last_request_at > logged_in_timeout.seconds.ago
|
69
|
+
end
|
70
|
+
|
71
|
+
# Opposite of logged_in?
|
72
|
+
def logged_out?
|
73
|
+
!logged_in?
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def logged_in_timeout
|
79
|
+
self.class.logged_in_timeout
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "authlogic/acts_as_authentic/queries/case_sensitivity"
|
4
|
+
require "authlogic/acts_as_authentic/queries/find_with_case"
|
5
|
+
|
6
|
+
module Authlogic
|
7
|
+
module ActsAsAuthentic
|
8
|
+
# Handles everything related to the login field.
|
9
|
+
module Login
|
10
|
+
def self.included(klass)
|
11
|
+
klass.class_eval do
|
12
|
+
extend Config
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Configuration for the login field.
|
17
|
+
module Config
|
18
|
+
# The name of the login field in the database.
|
19
|
+
#
|
20
|
+
# * <tt>Default:</tt> :login or :username, if they exist
|
21
|
+
# * <tt>Accepts:</tt> Symbol
|
22
|
+
def login_field(value = nil)
|
23
|
+
rw_config(:login_field, value, first_column_to_exist(nil, :login, :username))
|
24
|
+
end
|
25
|
+
alias login_field= login_field
|
26
|
+
|
27
|
+
# This method allows you to find a record with the given login. If you
|
28
|
+
# notice, with Active Record you have the UniquenessValidator class.
|
29
|
+
# They give you a :case_sensitive option. I handle this in the same
|
30
|
+
# manner that they handle that. If you are using the login field, set
|
31
|
+
# false for the :case_sensitive option in
|
32
|
+
# validates_uniqueness_of_login_field_options and the column doesn't
|
33
|
+
# have a case-insensitive collation, this method will modify the query
|
34
|
+
# to look something like:
|
35
|
+
#
|
36
|
+
# "LOWER(#{quoted_table_name}.#{login_field}) = LOWER(#{login})"
|
37
|
+
#
|
38
|
+
# If you don't specify this it just uses a regular case-sensitive search
|
39
|
+
# (with the binary modifier if necessary):
|
40
|
+
#
|
41
|
+
# "BINARY #{login_field} = #{login}"
|
42
|
+
#
|
43
|
+
# The above also applies for using email as your login, except that you
|
44
|
+
# need to set the :case_sensitive in
|
45
|
+
# validates_uniqueness_of_email_field_options to false.
|
46
|
+
#
|
47
|
+
# @api public
|
48
|
+
def find_by_smart_case_login_field(login)
|
49
|
+
field = login_field || email_field
|
50
|
+
sensitive = Queries::CaseSensitivity.new(self, field).sensitive?
|
51
|
+
find_with_case(field, login, sensitive)
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# @api private
|
57
|
+
def find_with_case(field, value, sensitive)
|
58
|
+
Queries::FindWithCase.new(self, field, value, sensitive).execute
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Authlogic
|
4
|
+
module ActsAsAuthentic
|
5
|
+
# Magic columns are like ActiveRecord's created_at and updated_at columns.
|
6
|
+
# They are "magically" maintained for you. Authlogic has the same thing, but
|
7
|
+
# these are maintained on the session side. Please see "Magic Columns" in
|
8
|
+
# `Session::Base` for more details. This module merely adds validations for
|
9
|
+
# the magic columns if they exist.
|
10
|
+
module MagicColumns
|
11
|
+
def self.included(klass)
|
12
|
+
klass.class_eval do
|
13
|
+
add_acts_as_authentic_module(Methods)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Methods relating to the magic columns
|
18
|
+
module Methods
|
19
|
+
def self.included(klass)
|
20
|
+
klass.class_eval do
|
21
|
+
if column_names.include?("login_count")
|
22
|
+
validates_numericality_of :login_count,
|
23
|
+
only_integer: true,
|
24
|
+
greater_than_or_equal_to: 0,
|
25
|
+
allow_nil: true
|
26
|
+
end
|
27
|
+
if column_names.include?("failed_login_count")
|
28
|
+
validates_numericality_of :failed_login_count,
|
29
|
+
only_integer: true,
|
30
|
+
greater_than_or_equal_to: 0,
|
31
|
+
allow_nil: true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|