sorcery 0.16.1 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -1
- data/README.md +9 -8
- data/lib/generators/sorcery/helpers.rb +1 -1
- data/lib/generators/sorcery/install_generator.rb +9 -11
- data/lib/generators/sorcery/templates/initializer.rb +34 -10
- data/lib/generators/sorcery/templates/migration/core.rb +1 -3
- data/lib/sorcery/adapters/active_record_adapter.rb +12 -14
- data/lib/sorcery/adapters/mongoid_adapter.rb +7 -9
- data/lib/sorcery/controller/config.rb +27 -29
- data/lib/sorcery/controller/submodules/activity_logging.rb +4 -7
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +4 -1
- data/lib/sorcery/controller/submodules/external.rb +12 -12
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +7 -2
- data/lib/sorcery/controller/submodules/remember_me.rb +2 -1
- data/lib/sorcery/controller/submodules/session_timeout.rb +2 -2
- data/lib/sorcery/controller.rb +37 -19
- data/lib/sorcery/crypto_providers/aes256.rb +4 -2
- data/lib/sorcery/crypto_providers/bcrypt.rb +2 -1
- data/lib/sorcery/crypto_providers/md5.rb +1 -0
- data/lib/sorcery/crypto_providers/sha1.rb +1 -0
- data/lib/sorcery/crypto_providers/sha256.rb +1 -0
- data/lib/sorcery/crypto_providers/sha512.rb +1 -0
- data/lib/sorcery/engine.rb +6 -4
- data/lib/sorcery/errors.rb +10 -0
- data/lib/sorcery/model/config.rb +20 -31
- data/lib/sorcery/model/submodules/activity_logging.rb +8 -6
- data/lib/sorcery/model/submodules/brute_force_protection.rb +16 -14
- data/lib/sorcery/model/submodules/external.rb +8 -10
- data/lib/sorcery/model/submodules/magic_login.rb +8 -4
- data/lib/sorcery/model/submodules/remember_me.rb +3 -3
- data/lib/sorcery/model/submodules/reset_password.rb +23 -13
- data/lib/sorcery/model/submodules/user_activation.rb +19 -17
- data/lib/sorcery/model/temporary_token.rb +5 -5
- data/lib/sorcery/model.rb +29 -28
- data/lib/sorcery/protocols/oauth2.rb +1 -0
- data/lib/sorcery/providers/base.rb +1 -1
- data/lib/sorcery/providers/facebook.rb +2 -2
- data/lib/sorcery/providers/github.rb +3 -3
- data/lib/sorcery/providers/heroku.rb +1 -2
- data/lib/sorcery/providers/jira.rb +3 -2
- data/lib/sorcery/providers/line.rb +2 -4
- data/lib/sorcery/providers/microsoft.rb +1 -1
- data/lib/sorcery/providers/slack.rb +1 -1
- data/lib/sorcery/providers/twitter.rb +2 -2
- data/lib/sorcery/providers/vk.rb +4 -4
- data/lib/sorcery/providers/xing.rb +3 -2
- data/lib/sorcery/test_helpers/internal/rails.rb +5 -22
- data/lib/sorcery/test_helpers/internal.rb +4 -6
- data/lib/sorcery/test_helpers/rails/integration.rb +1 -1
- data/lib/sorcery/test_helpers/rails/request.rb +1 -1
- data/lib/sorcery/version.rb +1 -1
- data/lib/sorcery.rb +6 -1
- metadata +23 -157
- data/.document +0 -5
- data/.github/FUNDING.yml +0 -1
- data/.github/ISSUE_TEMPLATE.md +0 -20
- data/.github/PULL_REQUEST_TEMPLATE.md +0 -5
- data/.github/workflows/ruby.yml +0 -49
- data/.gitignore +0 -59
- data/.rspec +0 -1
- data/.rubocop.yml +0 -55
- data/.rubocop_todo.yml +0 -163
- data/CODE_OF_CONDUCT.md +0 -14
- data/Gemfile +0 -8
- data/Rakefile +0 -8
- data/SECURITY.md +0 -19
- data/gemfiles/rails_52.gemfile +0 -7
- data/gemfiles/rails_60.gemfile +0 -7
- data/sorcery.gemspec +0 -49
- data/spec/active_record/user_activation_spec.rb +0 -17
- data/spec/active_record/user_activity_logging_spec.rb +0 -15
- data/spec/active_record/user_brute_force_protection_spec.rb +0 -15
- data/spec/active_record/user_magic_login_spec.rb +0 -15
- data/spec/active_record/user_oauth_spec.rb +0 -15
- data/spec/active_record/user_remember_me_spec.rb +0 -15
- data/spec/active_record/user_reset_password_spec.rb +0 -15
- data/spec/active_record/user_spec.rb +0 -27
- data/spec/controllers/controller_activity_logging_spec.rb +0 -113
- data/spec/controllers/controller_brute_force_protection_spec.rb +0 -41
- data/spec/controllers/controller_http_basic_auth_spec.rb +0 -67
- data/spec/controllers/controller_oauth2_spec.rb +0 -568
- data/spec/controllers/controller_oauth_spec.rb +0 -266
- data/spec/controllers/controller_remember_me_spec.rb +0 -130
- data/spec/controllers/controller_session_timeout_spec.rb +0 -166
- data/spec/controllers/controller_spec.rb +0 -194
- data/spec/orm/active_record.rb +0 -21
- data/spec/providers/example_provider_spec.rb +0 -17
- data/spec/providers/example_spec.rb +0 -17
- data/spec/providers/vk_spec.rb +0 -42
- data/spec/rails_app/app/active_record/authentication.rb +0 -3
- data/spec/rails_app/app/active_record/user.rb +0 -5
- data/spec/rails_app/app/active_record/user_provider.rb +0 -3
- data/spec/rails_app/app/assets/config/manifest.js +0 -1
- data/spec/rails_app/app/controllers/application_controller.rb +0 -2
- data/spec/rails_app/app/controllers/sorcery_controller.rb +0 -489
- data/spec/rails_app/app/helpers/application_helper.rb +0 -2
- data/spec/rails_app/app/mailers/sorcery_mailer.rb +0 -38
- data/spec/rails_app/app/views/application/index.html.erb +0 -17
- data/spec/rails_app/app/views/layouts/application.html.erb +0 -14
- data/spec/rails_app/app/views/sorcery_mailer/activation_email.html.erb +0 -17
- data/spec/rails_app/app/views/sorcery_mailer/activation_email.text.erb +0 -9
- data/spec/rails_app/app/views/sorcery_mailer/activation_needed_email.html.erb +0 -17
- data/spec/rails_app/app/views/sorcery_mailer/activation_success_email.html.erb +0 -17
- data/spec/rails_app/app/views/sorcery_mailer/activation_success_email.text.erb +0 -9
- data/spec/rails_app/app/views/sorcery_mailer/magic_login_email.html.erb +0 -13
- data/spec/rails_app/app/views/sorcery_mailer/magic_login_email.text.erb +0 -6
- data/spec/rails_app/app/views/sorcery_mailer/reset_password_email.html.erb +0 -16
- data/spec/rails_app/app/views/sorcery_mailer/reset_password_email.text.erb +0 -8
- data/spec/rails_app/app/views/sorcery_mailer/send_unlock_token_email.text.erb +0 -1
- data/spec/rails_app/config/application.rb +0 -61
- data/spec/rails_app/config/boot.rb +0 -4
- data/spec/rails_app/config/database.yml +0 -22
- data/spec/rails_app/config/environment.rb +0 -5
- data/spec/rails_app/config/environments/test.rb +0 -37
- data/spec/rails_app/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/rails_app/config/initializers/compatible_legacy_migration.rb +0 -11
- data/spec/rails_app/config/initializers/inflections.rb +0 -10
- data/spec/rails_app/config/initializers/mime_types.rb +0 -5
- data/spec/rails_app/config/initializers/session_store.rb +0 -12
- data/spec/rails_app/config/locales/en.yml +0 -5
- data/spec/rails_app/config/routes.rb +0 -81
- data/spec/rails_app/config/secrets.yml +0 -4
- data/spec/rails_app/config.ru +0 -4
- data/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb +0 -17
- data/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +0 -19
- data/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +0 -13
- data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +0 -16
- data/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb +0 -22
- data/spec/rails_app/db/migrate/invalidate_active_sessions/20180221093235_add_invalidate_active_sessions_before_to_users.rb +0 -9
- data/spec/rails_app/db/migrate/magic_login/20170924151831_add_magic_login_to_users.rb +0 -17
- data/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +0 -15
- data/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +0 -15
- data/spec/rails_app/db/schema.rb +0 -21
- data/spec/rails_app/db/seeds.rb +0 -7
- data/spec/shared_examples/user_activation_shared_examples.rb +0 -361
- data/spec/shared_examples/user_activity_logging_shared_examples.rb +0 -106
- data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +0 -151
- data/spec/shared_examples/user_magic_login_shared_examples.rb +0 -150
- data/spec/shared_examples/user_oauth_shared_examples.rb +0 -33
- data/spec/shared_examples/user_remember_me_shared_examples.rb +0 -129
- data/spec/shared_examples/user_reset_password_shared_examples.rb +0 -358
- data/spec/shared_examples/user_shared_examples.rb +0 -678
- data/spec/sorcery_crypto_providers_spec.rb +0 -245
- data/spec/sorcery_temporary_token_spec.rb +0 -27
- data/spec/spec.opts +0 -2
- data/spec/spec_helper.rb +0 -50
- data/spec/support/migration_helper.rb +0 -29
- data/spec/support/providers/example.rb +0 -11
- data/spec/support/providers/example_provider.rb +0 -11
data/lib/sorcery/controller.rb
CHANGED
|
@@ -3,22 +3,17 @@ module Sorcery
|
|
|
3
3
|
def self.included(klass)
|
|
4
4
|
klass.class_eval do
|
|
5
5
|
include InstanceMethods
|
|
6
|
+
|
|
6
7
|
Config.submodules.each do |mod|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
begin
|
|
10
|
-
include Submodules.const_get(mod.to_s.split('_').map(&:capitalize).join)
|
|
11
|
-
rescue NameError
|
|
12
|
-
# don't stop on a missing submodule.
|
|
13
|
-
end
|
|
14
|
-
# rubocop:enable Lint/HandleExceptions
|
|
8
|
+
submodule_name = mod.to_s.split('_').map(&:capitalize).join
|
|
9
|
+
include Submodules.const_get(submodule_name) if Submodules.const_defined?(submodule_name, false)
|
|
15
10
|
end
|
|
16
11
|
end
|
|
17
12
|
Config.update!
|
|
18
13
|
Config.configure!
|
|
19
14
|
end
|
|
20
15
|
|
|
21
|
-
module InstanceMethods
|
|
16
|
+
module InstanceMethods # rubocop:disable Metrics/ModuleLength
|
|
22
17
|
# To be used as before_action.
|
|
23
18
|
# Will trigger auto-login attempts via the call to logged_in?
|
|
24
19
|
# If all attempts to auto-login fail, the failure callback will be called.
|
|
@@ -54,7 +49,6 @@ module Sorcery
|
|
|
54
49
|
old_session.each_pair do |k, v|
|
|
55
50
|
session[k.to_sym] = v
|
|
56
51
|
end
|
|
57
|
-
form_authenticity_token
|
|
58
52
|
|
|
59
53
|
auto_login(user, credentials[2])
|
|
60
54
|
after_login!(user, credentials)
|
|
@@ -63,6 +57,14 @@ module Sorcery
|
|
|
63
57
|
end
|
|
64
58
|
end
|
|
65
59
|
|
|
60
|
+
def login!(...)
|
|
61
|
+
user = login(...)
|
|
62
|
+
|
|
63
|
+
raise Sorcery::InvalidCredentials if user.nil?
|
|
64
|
+
|
|
65
|
+
user
|
|
66
|
+
end
|
|
67
|
+
|
|
66
68
|
def reset_sorcery_session
|
|
67
69
|
reset_session # protect from session fixation attacks
|
|
68
70
|
end
|
|
@@ -85,9 +87,7 @@ module Sorcery
|
|
|
85
87
|
# attempts to auto-login from the sources defined (session, basic_auth, cookie, etc.)
|
|
86
88
|
# returns the logged in user if found, nil if not
|
|
87
89
|
def current_user
|
|
88
|
-
unless defined?(@current_user)
|
|
89
|
-
@current_user = login_from_session || login_from_other_sources || nil
|
|
90
|
-
end
|
|
90
|
+
@current_user = login_from_session || login_from_other_sources || nil unless defined?(@current_user)
|
|
91
91
|
@current_user
|
|
92
92
|
end
|
|
93
93
|
|
|
@@ -97,8 +97,24 @@ module Sorcery
|
|
|
97
97
|
|
|
98
98
|
# used when a user tries to access a page while logged out, is asked to login,
|
|
99
99
|
# and we want to return him back to the page he originally wanted.
|
|
100
|
-
def redirect_back_or_to(
|
|
101
|
-
|
|
100
|
+
def redirect_back_or_to(...)
|
|
101
|
+
if Config.use_redirect_back_or_to_by_rails
|
|
102
|
+
super
|
|
103
|
+
else
|
|
104
|
+
Sorcery.deprecator.warn(
|
|
105
|
+
'`redirect_back_or_to` overrides the method of the same name defined in Rails 7. ' \
|
|
106
|
+
'To avoid overriding, set `config.use_redirect_back_or_to_by_rails = true` and use `redirect_to_before_login_path`. ' \
|
|
107
|
+
'In a future release, `config.use_redirect_back_or_to_by_rails = true` will become the default.'
|
|
108
|
+
)
|
|
109
|
+
redirect_to_before_login_path(...)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def redirect_to_before_login_path(url, **options)
|
|
114
|
+
allow_other_host = options[:allow_other_host].nil? ? _allow_other_host : options[:allow_other_host]
|
|
115
|
+
flash = options.except(:allow_other_host)
|
|
116
|
+
|
|
117
|
+
redirect_to(session[:return_to_url] || url, flash:, allow_other_host:)
|
|
102
118
|
session[:return_to_url] = nil
|
|
103
119
|
end
|
|
104
120
|
|
|
@@ -137,9 +153,7 @@ module Sorcery
|
|
|
137
153
|
end
|
|
138
154
|
|
|
139
155
|
def login_from_session
|
|
140
|
-
@current_user = if session[:user_id]
|
|
141
|
-
user_class.sorcery_adapter.find_by_id(session[:user_id])
|
|
142
|
-
end
|
|
156
|
+
@current_user = (user_class.sorcery_adapter.find_by_id(session[:user_id]) if session[:user_id])
|
|
143
157
|
end
|
|
144
158
|
|
|
145
159
|
def after_login!(user, credentials = [])
|
|
@@ -162,10 +176,14 @@ module Sorcery
|
|
|
162
176
|
Config.after_remember_me.each { |c| send(c, user) }
|
|
163
177
|
end
|
|
164
178
|
|
|
179
|
+
def after_login_lock!(credentials)
|
|
180
|
+
Config.after_login_lock.each { |c| send(c, credentials) }
|
|
181
|
+
end
|
|
182
|
+
|
|
165
183
|
def user_class
|
|
166
184
|
@user_class ||= Config.user_class.to_s.constantize
|
|
167
185
|
rescue NameError
|
|
168
|
-
raise ArgumentError, 'You have incorrectly defined user_class or have forgotten to define it in
|
|
186
|
+
raise ArgumentError, 'You have incorrectly defined user_class or have forgotten to define it in the initializer file (config.user_class = \'User\').'
|
|
169
187
|
end
|
|
170
188
|
end
|
|
171
189
|
end
|
|
@@ -36,13 +36,15 @@ module Sorcery
|
|
|
36
36
|
def decrypt(crypted)
|
|
37
37
|
aes.decrypt
|
|
38
38
|
aes.key = @key
|
|
39
|
-
(aes.update(crypted.
|
|
39
|
+
(aes.update(crypted.unpack1('m')) + aes.final)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
private
|
|
43
43
|
|
|
44
44
|
def aes
|
|
45
|
-
|
|
45
|
+
if @key.nil? || @key == ''
|
|
46
|
+
raise ArgumentError, "#{name} expects a 32 bytes long key. Please use Sorcery::Model::Config.encryption_key to set it."
|
|
47
|
+
end
|
|
46
48
|
|
|
47
49
|
@aes ||= OpenSSL::Cipher.new('AES-256-ECB')
|
|
48
50
|
end
|
|
@@ -44,6 +44,7 @@ module Sorcery
|
|
|
44
44
|
# Basically it's equivalent to :salt_join_token option, but have a different name to ensure
|
|
45
45
|
# backward compatibility in generating/matching passwords.
|
|
46
46
|
attr_accessor :pepper
|
|
47
|
+
|
|
47
48
|
# This is the :cost option for the BCrpyt library.
|
|
48
49
|
# The higher the cost the more secure it is and the longer is take the generate a hash. By default this is 10.
|
|
49
50
|
# Set this to whatever you want, play around with it to get that perfect balance between
|
|
@@ -87,7 +88,7 @@ module Sorcery
|
|
|
87
88
|
private
|
|
88
89
|
|
|
89
90
|
def join_tokens(tokens)
|
|
90
|
-
tokens.
|
|
91
|
+
tokens.join.concat(pepper.to_s) # make sure to add pepper in case tokens have only one element
|
|
91
92
|
end
|
|
92
93
|
|
|
93
94
|
def new_from_hash(hash)
|
data/lib/sorcery/engine.rb
CHANGED
|
@@ -7,20 +7,22 @@ module Sorcery
|
|
|
7
7
|
class Engine < Rails::Engine
|
|
8
8
|
config.sorcery = ::Sorcery::Controller::Config
|
|
9
9
|
|
|
10
|
+
initializer 'sorcery.deprecator' do |app|
|
|
11
|
+
app.deprecators[:sorcery] = Sorcery.deprecator
|
|
12
|
+
end
|
|
13
|
+
|
|
10
14
|
# TODO: Should this include a modified version of the helper methods?
|
|
11
15
|
initializer 'extend Controller with sorcery' do
|
|
12
16
|
# FIXME: on_load is needed to fix Rails 6 deprecations, but it breaks
|
|
13
17
|
# applications due to undefined method errors.
|
|
14
18
|
# ActiveSupport.on_load(:action_controller_api) do
|
|
15
|
-
if defined?(ActionController::API)
|
|
16
|
-
ActionController::API.send(:include, Sorcery::Controller)
|
|
17
|
-
end
|
|
19
|
+
ActionController::API.include Sorcery::Controller if defined?(ActionController::API)
|
|
18
20
|
|
|
19
21
|
# FIXME: on_load is needed to fix Rails 6 deprecations, but it breaks
|
|
20
22
|
# applications due to undefined method errors.
|
|
21
23
|
# ActiveSupport.on_load(:action_controller_base) do
|
|
22
24
|
if defined?(ActionController::Base)
|
|
23
|
-
ActionController::Base.
|
|
25
|
+
ActionController::Base.include Sorcery::Controller
|
|
24
26
|
ActionController::Base.helper_method :current_user
|
|
25
27
|
ActionController::Base.helper_method :logged_in?
|
|
26
28
|
end
|
data/lib/sorcery/model/config.rb
CHANGED
|
@@ -31,8 +31,8 @@ module Sorcery
|
|
|
31
31
|
# an array of method names to call before authentication completes. used internally.
|
|
32
32
|
attr_accessor :before_authenticate
|
|
33
33
|
# method to send email related
|
|
34
|
-
# options: `:deliver_later`, `:deliver_now
|
|
35
|
-
# Default: :
|
|
34
|
+
# options: `:deliver_later`, `:deliver_now`
|
|
35
|
+
# Default: :deliver_now
|
|
36
36
|
# method to send email related
|
|
37
37
|
attr_accessor :email_delivery_method
|
|
38
38
|
# an array of method names to call after configuration by user. used internally.
|
|
@@ -51,25 +51,25 @@ module Sorcery
|
|
|
51
51
|
|
|
52
52
|
def initialize
|
|
53
53
|
@defaults = {
|
|
54
|
-
:@submodules
|
|
55
|
-
:@username_attribute_names
|
|
56
|
-
:@password_attribute_name
|
|
54
|
+
:@submodules => [],
|
|
55
|
+
:@username_attribute_names => [:email],
|
|
56
|
+
:@password_attribute_name => :password,
|
|
57
57
|
:@downcase_username_before_authenticating => false,
|
|
58
|
-
:@email_attribute_name
|
|
59
|
-
:@crypted_password_attribute_name
|
|
60
|
-
:@encryption_algorithm
|
|
61
|
-
:@encryption_provider
|
|
62
|
-
:@custom_encryption_provider
|
|
63
|
-
:@encryption_key
|
|
64
|
-
:@pepper
|
|
65
|
-
:@salt_join_token
|
|
66
|
-
:@salt_attribute_name
|
|
67
|
-
:@stretches
|
|
68
|
-
:@subclasses_inherit_config
|
|
69
|
-
:@before_authenticate
|
|
70
|
-
:@after_config
|
|
71
|
-
:@email_delivery_method
|
|
72
|
-
:@token_randomness
|
|
58
|
+
:@email_attribute_name => :email,
|
|
59
|
+
:@crypted_password_attribute_name => :crypted_password,
|
|
60
|
+
:@encryption_algorithm => :bcrypt,
|
|
61
|
+
:@encryption_provider => CryptoProviders::BCrypt,
|
|
62
|
+
:@custom_encryption_provider => nil,
|
|
63
|
+
:@encryption_key => nil,
|
|
64
|
+
:@pepper => '',
|
|
65
|
+
:@salt_join_token => '',
|
|
66
|
+
:@salt_attribute_name => :salt,
|
|
67
|
+
:@stretches => nil,
|
|
68
|
+
:@subclasses_inherit_config => false,
|
|
69
|
+
:@before_authenticate => [],
|
|
70
|
+
:@after_config => [],
|
|
71
|
+
:@email_delivery_method => :deliver_now,
|
|
72
|
+
:@token_randomness => 15
|
|
73
73
|
}
|
|
74
74
|
reset!
|
|
75
75
|
end
|
|
@@ -103,17 +103,6 @@ module Sorcery
|
|
|
103
103
|
else raise ArgumentError, "Encryption algorithm supplied, #{algo}, is invalid"
|
|
104
104
|
end
|
|
105
105
|
end
|
|
106
|
-
|
|
107
|
-
private
|
|
108
|
-
|
|
109
|
-
def default_email_delivery_method
|
|
110
|
-
# Rails 4.2 deprecates #deliver
|
|
111
|
-
rails_version_bigger_than_or_equal?('4.2.0') ? :deliver_now : :deliver
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def rails_version_bigger_than_or_equal?(version)
|
|
115
|
-
Gem::Version.new(version) <= Gem::Version.new(Rails.version)
|
|
116
|
-
end
|
|
117
106
|
end
|
|
118
107
|
end
|
|
119
108
|
end
|
|
@@ -25,11 +25,11 @@ module Sorcery
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
base.sorcery_config.instance_eval do
|
|
28
|
-
@defaults.merge!(:@last_login_at_attribute_name
|
|
29
|
-
:@last_logout_at_attribute_name
|
|
30
|
-
:@last_activity_at_attribute_name
|
|
31
|
-
:@last_login_from_ip_address_name
|
|
32
|
-
:@activity_timeout
|
|
28
|
+
@defaults.merge!(:@last_login_at_attribute_name => :last_login_at,
|
|
29
|
+
:@last_logout_at_attribute_name => :last_logout_at,
|
|
30
|
+
:@last_activity_at_attribute_name => :last_activity_at,
|
|
31
|
+
:@last_login_from_ip_address_name => :last_login_from_ip_address,
|
|
32
|
+
:@activity_timeout => 10 * 60)
|
|
33
33
|
reset!
|
|
34
34
|
end
|
|
35
35
|
|
|
@@ -63,7 +63,9 @@ module Sorcery
|
|
|
63
63
|
# shows if user is logged in, but it not show if user is online - see online?
|
|
64
64
|
def logged_in?
|
|
65
65
|
return false if send(sorcery_config.last_login_at_attribute_name).nil?
|
|
66
|
-
|
|
66
|
+
if send(sorcery_config.last_login_at_attribute_name).present? && send(sorcery_config.last_logout_at_attribute_name).nil?
|
|
67
|
+
return true
|
|
68
|
+
end
|
|
67
69
|
|
|
68
70
|
send(sorcery_config.last_login_at_attribute_name) > send(sorcery_config.last_logout_at_attribute_name)
|
|
69
71
|
end
|
|
@@ -21,15 +21,15 @@ module Sorcery
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
base.sorcery_config.instance_eval do
|
|
24
|
-
@defaults.merge!(:@failed_logins_count_attribute_name
|
|
25
|
-
:@lock_expires_at_attribute_name
|
|
26
|
-
:@consecutive_login_retries_amount_limit
|
|
27
|
-
:@login_lock_time_period
|
|
28
|
-
|
|
29
|
-
:@unlock_token_attribute_name
|
|
30
|
-
:@unlock_token_email_method_name
|
|
31
|
-
:@unlock_token_mailer_disabled
|
|
32
|
-
:@unlock_token_mailer
|
|
24
|
+
@defaults.merge!(:@failed_logins_count_attribute_name => :failed_logins_count,
|
|
25
|
+
:@lock_expires_at_attribute_name => :lock_expires_at,
|
|
26
|
+
:@consecutive_login_retries_amount_limit => 50,
|
|
27
|
+
:@login_lock_time_period => 60 * 60,
|
|
28
|
+
|
|
29
|
+
:@unlock_token_attribute_name => :unlock_token,
|
|
30
|
+
:@unlock_token_email_method_name => :send_unlock_token_email,
|
|
31
|
+
:@unlock_token_mailer_disabled => false,
|
|
32
|
+
:@unlock_token_mailer => nil)
|
|
33
33
|
reset!
|
|
34
34
|
end
|
|
35
35
|
|
|
@@ -41,13 +41,13 @@ module Sorcery
|
|
|
41
41
|
|
|
42
42
|
module ClassMethods
|
|
43
43
|
# This doesn't check to see if the account is still locked
|
|
44
|
-
def load_from_unlock_token(token, &
|
|
44
|
+
def load_from_unlock_token(token, &)
|
|
45
45
|
return if token.blank?
|
|
46
46
|
|
|
47
47
|
load_from_token(
|
|
48
48
|
token,
|
|
49
49
|
sorcery_config.unlock_token_attribute_name,
|
|
50
|
-
&
|
|
50
|
+
&
|
|
51
51
|
)
|
|
52
52
|
end
|
|
53
53
|
|
|
@@ -69,7 +69,9 @@ module Sorcery
|
|
|
69
69
|
|
|
70
70
|
sorcery_adapter.increment(config.failed_logins_count_attribute_name)
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
unless send(config.failed_logins_count_attribute_name) >= config.consecutive_login_retries_amount_limit
|
|
73
|
+
return
|
|
74
|
+
end
|
|
73
75
|
|
|
74
76
|
login_lock!
|
|
75
77
|
end
|
|
@@ -117,8 +119,8 @@ module Sorcery
|
|
|
117
119
|
# Runs as a hook before authenticate.
|
|
118
120
|
def prevent_locked_user_login
|
|
119
121
|
config = sorcery_config
|
|
120
|
-
if !login_unlocked? && config.login_lock_time_period != 0
|
|
121
|
-
login_unlock!
|
|
122
|
+
if !login_unlocked? && config.login_lock_time_period != 0 && send(config.lock_expires_at_attribute_name) <= Time.now.in_time_zone
|
|
123
|
+
login_unlock!
|
|
122
124
|
end
|
|
123
125
|
|
|
124
126
|
return false, :locked unless login_unlocked?
|
|
@@ -23,10 +23,10 @@ module Sorcery
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
base.sorcery_config.instance_eval do
|
|
26
|
-
@defaults.merge!(:@authentications_class
|
|
26
|
+
@defaults.merge!(:@authentications_class => nil,
|
|
27
27
|
:@authentications_user_id_attribute_name => :user_id,
|
|
28
|
-
:@provider_attribute_name
|
|
29
|
-
:@provider_uid_attribute_name
|
|
28
|
+
:@provider_attribute_name => :provider,
|
|
29
|
+
:@provider_uid_attribute_name => :uid)
|
|
30
30
|
|
|
31
31
|
reset!
|
|
32
32
|
end
|
|
@@ -41,7 +41,9 @@ module Sorcery
|
|
|
41
41
|
config = sorcery_config
|
|
42
42
|
authentication = config.authentications_class.sorcery_adapter.find_by_oauth_credentials(provider, uid)
|
|
43
43
|
# Return user if matching authentication found
|
|
44
|
-
|
|
44
|
+
return unless authentication
|
|
45
|
+
|
|
46
|
+
sorcery_adapter.find_by_id(authentication.send(config.authentications_user_id_attribute_name))
|
|
45
47
|
end
|
|
46
48
|
|
|
47
49
|
def create_and_validate_from_provider(provider, uid, attrs)
|
|
@@ -60,9 +62,7 @@ module Sorcery
|
|
|
60
62
|
user.send(:"#{k}=", v)
|
|
61
63
|
end
|
|
62
64
|
|
|
63
|
-
if block_given?
|
|
64
|
-
return false unless yield user
|
|
65
|
-
end
|
|
65
|
+
return false if block_given? && !yield(user)
|
|
66
66
|
|
|
67
67
|
sorcery_adapter.transaction do
|
|
68
68
|
user.sorcery_adapter.save(validate: false)
|
|
@@ -83,9 +83,7 @@ module Sorcery
|
|
|
83
83
|
user.send(:"#{k}=", v)
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
-
if block_given?
|
|
87
|
-
return false unless yield user
|
|
88
|
-
end
|
|
86
|
+
return false if block_given? && !yield(user)
|
|
89
87
|
|
|
90
88
|
user
|
|
91
89
|
end
|
|
@@ -52,12 +52,12 @@ module Sorcery
|
|
|
52
52
|
module ClassMethods
|
|
53
53
|
# Find user by token, also checks for expiration.
|
|
54
54
|
# Returns the user if token found and is valid.
|
|
55
|
-
def load_from_magic_login_token(token, &
|
|
55
|
+
def load_from_magic_login_token(token, &)
|
|
56
56
|
load_from_token(
|
|
57
57
|
token,
|
|
58
58
|
@sorcery_config.magic_login_token_attribute_name,
|
|
59
59
|
@sorcery_config.magic_login_token_expires_at_attribute_name,
|
|
60
|
-
&
|
|
60
|
+
&
|
|
61
61
|
)
|
|
62
62
|
end
|
|
63
63
|
|
|
@@ -67,7 +67,9 @@ module Sorcery
|
|
|
67
67
|
# when magic_login_mailer_disabled is false
|
|
68
68
|
def validate_mailer_defined
|
|
69
69
|
msg = 'To use magic_login submodule, you must define a mailer (config.magic_login_mailer_class = YourMailerClass).'
|
|
70
|
-
|
|
70
|
+
if @sorcery_config.magic_login_mailer_class.nil? && @sorcery_config.magic_login_mailer_disabled == false
|
|
71
|
+
raise ArgumentError, msg
|
|
72
|
+
end
|
|
71
73
|
end
|
|
72
74
|
|
|
73
75
|
def define_magic_login_fields
|
|
@@ -85,7 +87,9 @@ module Sorcery
|
|
|
85
87
|
config.magic_login_token_attribute_name => TemporaryToken.generate_random_token,
|
|
86
88
|
config.magic_login_email_sent_at_attribute_name => Time.now.in_time_zone
|
|
87
89
|
}
|
|
88
|
-
|
|
90
|
+
if config.magic_login_expiration_period
|
|
91
|
+
attributes[config.magic_login_token_expires_at_attribute_name] = Time.now.in_time_zone + config.magic_login_expiration_period
|
|
92
|
+
end
|
|
89
93
|
|
|
90
94
|
sorcery_adapter.update_attributes(attributes)
|
|
91
95
|
end
|
|
@@ -14,10 +14,10 @@ module Sorcery
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
base.sorcery_config.instance_eval do
|
|
17
|
-
@defaults.merge!(:@remember_me_token_attribute_name
|
|
17
|
+
@defaults.merge!(:@remember_me_token_attribute_name => :remember_me_token,
|
|
18
18
|
:@remember_me_token_expires_at_attribute_name => :remember_me_token_expires_at,
|
|
19
|
-
:@remember_me_token_persist_globally
|
|
20
|
-
:@remember_me_for
|
|
19
|
+
:@remember_me_token_persist_globally => false,
|
|
20
|
+
:@remember_me_for => 7 * 60 * 60 * 24)
|
|
21
21
|
|
|
22
22
|
reset!
|
|
23
23
|
end
|
|
@@ -34,16 +34,16 @@ module Sorcery
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
base.sorcery_config.instance_eval do
|
|
37
|
-
@defaults.merge!(:@reset_password_token_attribute_name
|
|
37
|
+
@defaults.merge!(:@reset_password_token_attribute_name => :reset_password_token,
|
|
38
38
|
:@reset_password_token_expires_at_attribute_name => :reset_password_token_expires_at,
|
|
39
39
|
:@reset_password_page_access_count_attribute_name =>
|
|
40
40
|
:access_count_to_reset_password_page,
|
|
41
|
-
:@reset_password_email_sent_at_attribute_name
|
|
42
|
-
:@reset_password_mailer
|
|
43
|
-
:@reset_password_mailer_disabled
|
|
44
|
-
:@reset_password_email_method_name
|
|
45
|
-
:@reset_password_expiration_period
|
|
46
|
-
:@reset_password_time_between_emails
|
|
41
|
+
:@reset_password_email_sent_at_attribute_name => :reset_password_email_sent_at,
|
|
42
|
+
:@reset_password_mailer => nil,
|
|
43
|
+
:@reset_password_mailer_disabled => false,
|
|
44
|
+
:@reset_password_email_method_name => :reset_password_email,
|
|
45
|
+
:@reset_password_expiration_period => nil,
|
|
46
|
+
:@reset_password_time_between_emails => 5 * 60)
|
|
47
47
|
|
|
48
48
|
reset!
|
|
49
49
|
end
|
|
@@ -59,12 +59,12 @@ module Sorcery
|
|
|
59
59
|
module ClassMethods
|
|
60
60
|
# Find user by token, also checks for expiration.
|
|
61
61
|
# Returns the user if token found and is valid.
|
|
62
|
-
def load_from_reset_password_token(token, &
|
|
62
|
+
def load_from_reset_password_token(token, &)
|
|
63
63
|
load_from_token(
|
|
64
64
|
token,
|
|
65
65
|
@sorcery_config.reset_password_token_attribute_name,
|
|
66
66
|
@sorcery_config.reset_password_token_expires_at_attribute_name,
|
|
67
|
-
&
|
|
67
|
+
&
|
|
68
68
|
)
|
|
69
69
|
end
|
|
70
70
|
|
|
@@ -74,7 +74,9 @@ module Sorcery
|
|
|
74
74
|
# when reset_password_mailer_disabled is false
|
|
75
75
|
def validate_mailer_defined
|
|
76
76
|
message = 'To use reset_password submodule, you must define a mailer (config.reset_password_mailer = YourMailerClass).'
|
|
77
|
-
|
|
77
|
+
if @sorcery_config.reset_password_mailer.nil? && @sorcery_config.reset_password_mailer_disabled == false
|
|
78
|
+
raise ArgumentError, message
|
|
79
|
+
end
|
|
78
80
|
end
|
|
79
81
|
|
|
80
82
|
def define_reset_password_fields
|
|
@@ -90,7 +92,9 @@ module Sorcery
|
|
|
90
92
|
config = sorcery_config
|
|
91
93
|
attributes = { config.reset_password_token_attribute_name => TemporaryToken.generate_random_token,
|
|
92
94
|
config.reset_password_email_sent_at_attribute_name => Time.now.in_time_zone }
|
|
93
|
-
|
|
95
|
+
if config.reset_password_expiration_period
|
|
96
|
+
attributes[config.reset_password_token_expires_at_attribute_name] = Time.now.in_time_zone + config.reset_password_expiration_period
|
|
97
|
+
end
|
|
94
98
|
|
|
95
99
|
sorcery_adapter.update_attributes(attributes)
|
|
96
100
|
end
|
|
@@ -100,7 +104,9 @@ module Sorcery
|
|
|
100
104
|
mail = false
|
|
101
105
|
config = sorcery_config
|
|
102
106
|
# hammering protection
|
|
103
|
-
|
|
107
|
+
if config.reset_password_time_between_emails.present? && send(config.reset_password_email_sent_at_attribute_name) && send(config.reset_password_email_sent_at_attribute_name) > config.reset_password_time_between_emails.seconds.ago.utc
|
|
108
|
+
return false
|
|
109
|
+
end
|
|
104
110
|
|
|
105
111
|
self.class.sorcery_adapter.transaction do
|
|
106
112
|
generate_reset_password_token!
|
|
@@ -131,6 +137,8 @@ module Sorcery
|
|
|
131
137
|
end
|
|
132
138
|
|
|
133
139
|
def change_password!(new_password)
|
|
140
|
+
raise ArgumentError, 'Blank password passed to change_password!' if new_password.blank?
|
|
141
|
+
|
|
134
142
|
change_password(new_password, raise_on_failure: true)
|
|
135
143
|
end
|
|
136
144
|
|
|
@@ -144,7 +152,9 @@ module Sorcery
|
|
|
144
152
|
def clear_reset_password_token
|
|
145
153
|
config = sorcery_config
|
|
146
154
|
send(:"#{config.reset_password_token_attribute_name}=", nil)
|
|
147
|
-
|
|
155
|
+
return unless config.reset_password_expiration_period
|
|
156
|
+
|
|
157
|
+
send(:"#{config.reset_password_token_expires_at_attribute_name}=", nil)
|
|
148
158
|
end
|
|
149
159
|
end
|
|
150
160
|
end
|
|
@@ -29,15 +29,15 @@ module Sorcery
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
base.sorcery_config.instance_eval do
|
|
32
|
-
@defaults.merge!(:@activation_state_attribute_name
|
|
33
|
-
:@activation_token_attribute_name
|
|
34
|
-
:@activation_token_expires_at_attribute_name
|
|
35
|
-
:@activation_token_expiration_period
|
|
36
|
-
:@user_activation_mailer
|
|
37
|
-
:@activation_mailer_disabled
|
|
38
|
-
:@activation_needed_email_method_name
|
|
39
|
-
:@activation_success_email_method_name
|
|
40
|
-
:@prevent_non_active_users_to_login
|
|
32
|
+
@defaults.merge!(:@activation_state_attribute_name => :activation_state,
|
|
33
|
+
:@activation_token_attribute_name => :activation_token,
|
|
34
|
+
:@activation_token_expires_at_attribute_name => :activation_token_expires_at,
|
|
35
|
+
:@activation_token_expiration_period => nil,
|
|
36
|
+
:@user_activation_mailer => nil,
|
|
37
|
+
:@activation_mailer_disabled => false,
|
|
38
|
+
:@activation_needed_email_method_name => :activation_needed_email,
|
|
39
|
+
:@activation_success_email_method_name => :activation_success_email,
|
|
40
|
+
:@prevent_non_active_users_to_login => true)
|
|
41
41
|
reset!
|
|
42
42
|
end
|
|
43
43
|
|
|
@@ -59,12 +59,12 @@ module Sorcery
|
|
|
59
59
|
module ClassMethods
|
|
60
60
|
# Find user by token, also checks for expiration.
|
|
61
61
|
# Returns the user if token found and is valid.
|
|
62
|
-
def load_from_activation_token(token, &
|
|
62
|
+
def load_from_activation_token(token, &)
|
|
63
63
|
load_from_token(
|
|
64
64
|
token,
|
|
65
65
|
@sorcery_config.activation_token_attribute_name,
|
|
66
66
|
@sorcery_config.activation_token_expires_at_attribute_name,
|
|
67
|
-
&
|
|
67
|
+
&
|
|
68
68
|
)
|
|
69
69
|
end
|
|
70
70
|
|
|
@@ -74,7 +74,9 @@ module Sorcery
|
|
|
74
74
|
# when activation_mailer_disabled is false
|
|
75
75
|
def validate_mailer_defined
|
|
76
76
|
message = 'To use user_activation submodule, you must define a mailer (config.user_activation_mailer = YourMailerClass).'
|
|
77
|
-
|
|
77
|
+
if @sorcery_config.user_activation_mailer.nil? && @sorcery_config.activation_mailer_disabled == false
|
|
78
|
+
raise ArgumentError, message
|
|
79
|
+
end
|
|
78
80
|
end
|
|
79
81
|
|
|
80
82
|
def define_user_activation_fields
|
|
@@ -92,7 +94,9 @@ module Sorcery
|
|
|
92
94
|
generated_activation_token = TemporaryToken.generate_random_token
|
|
93
95
|
send(:"#{config.activation_token_attribute_name}=", generated_activation_token)
|
|
94
96
|
send(:"#{config.activation_state_attribute_name}=", 'pending')
|
|
95
|
-
|
|
97
|
+
return unless config.activation_token_expiration_period
|
|
98
|
+
|
|
99
|
+
send(:"#{config.activation_token_expires_at_attribute_name}=", Time.now.in_time_zone + config.activation_token_expiration_period)
|
|
96
100
|
end
|
|
97
101
|
|
|
98
102
|
# clears activation code, sets the user as 'active' and optionaly sends a success email.
|
|
@@ -132,10 +136,8 @@ module Sorcery
|
|
|
132
136
|
def prevent_non_active_login
|
|
133
137
|
config = sorcery_config
|
|
134
138
|
|
|
135
|
-
if config.prevent_non_active_users_to_login
|
|
136
|
-
|
|
137
|
-
return false, :inactive
|
|
138
|
-
end
|
|
139
|
+
if config.prevent_non_active_users_to_login && send(config.activation_state_attribute_name) != 'active'
|
|
140
|
+
return false, :inactive
|
|
139
141
|
end
|
|
140
142
|
|
|
141
143
|
true
|