sorcery 0.17.0 → 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 +4 -1
- data/README.md +8 -5
- data/lib/generators/sorcery/helpers.rb +1 -1
- data/lib/generators/sorcery/install_generator.rb +9 -18
- data/lib/generators/sorcery/templates/initializer.rb +24 -10
- data/lib/sorcery/adapters/active_record_adapter.rb +12 -14
- data/lib/sorcery/adapters/mongoid_adapter.rb +6 -8
- 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 +11 -11
- 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 +36 -18
- 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 +21 -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 +21 -25
- 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/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 +21 -150
- data/.devcontainer/Dockerfile +0 -10
- data/.devcontainer/devcontainer.json +0 -29
- data/.devcontainer/postcreate.sh +0 -4
- data/.document +0 -5
- data/.github/FUNDING.yml +0 -1
- data/.github/ISSUE_TEMPLATE.md +0 -24
- data/.github/PULL_REQUEST_TEMPLATE.md +0 -7
- data/.github/workflows/ruby.yml +0 -54
- data/.gitignore +0 -60
- 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/MAINTAINING.md +0 -64
- data/Rakefile +0 -8
- data/SECURITY.md +0 -19
- data/gemfiles/rails_61.gemfile +0 -7
- data/gemfiles/rails_70.gemfile +0 -7
- data/gemfiles/rails_71.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 -168
- data/spec/controllers/controller_spec.rb +0 -200
- 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/examples_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 -370
- 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/spec/support/providers/examples.rb +0 -11
|
@@ -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!
|
|
@@ -146,7 +152,9 @@ module Sorcery
|
|
|
146
152
|
def clear_reset_password_token
|
|
147
153
|
config = sorcery_config
|
|
148
154
|
send(:"#{config.reset_password_token_attribute_name}=", nil)
|
|
149
|
-
|
|
155
|
+
return unless config.reset_password_expiration_period
|
|
156
|
+
|
|
157
|
+
send(:"#{config.reset_password_token_expires_at_attribute_name}=", nil)
|
|
150
158
|
end
|
|
151
159
|
end
|
|
152
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
|
|
@@ -18,18 +18,18 @@ module Sorcery
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
module ClassMethods
|
|
21
|
-
def load_from_token(token, token_attr_name, token_expiration_date_attr = nil, &
|
|
22
|
-
return token_response(failure: :invalid_token, &
|
|
21
|
+
def load_from_token(token, token_attr_name, token_expiration_date_attr = nil, &)
|
|
22
|
+
return token_response(failure: :invalid_token, &) if token.blank?
|
|
23
23
|
|
|
24
24
|
user = sorcery_adapter.find_by_token(token_attr_name, token)
|
|
25
25
|
|
|
26
|
-
return token_response(failure: :user_not_found, &
|
|
26
|
+
return token_response(failure: :user_not_found, &) unless user
|
|
27
27
|
|
|
28
28
|
unless check_expiration_date(user, token_expiration_date_attr)
|
|
29
|
-
return token_response(user: user, failure: :token_expired, &
|
|
29
|
+
return token_response(user: user, failure: :token_expired, &)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
token_response(user: user, return_value: user, &
|
|
32
|
+
token_response(user: user, return_value: user, &)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
protected
|
data/lib/sorcery/model.rb
CHANGED
|
@@ -17,7 +17,7 @@ module Sorcery
|
|
|
17
17
|
include_required_submodules!
|
|
18
18
|
|
|
19
19
|
# This runs the options block set in the initializer on the model class.
|
|
20
|
-
::Sorcery::Controller::Config.user_config.tap { |blk| blk
|
|
20
|
+
::Sorcery::Controller::Config.user_config.tap { |blk| blk&.call(@sorcery_config) }
|
|
21
21
|
|
|
22
22
|
define_base_fields
|
|
23
23
|
init_orm_hooks!
|
|
@@ -48,14 +48,10 @@ module Sorcery
|
|
|
48
48
|
@sorcery_config.submodules = ::Sorcery::Controller::Config.submodules
|
|
49
49
|
@sorcery_config.submodules.each do |mod|
|
|
50
50
|
# TODO: Is there a cleaner way to handle missing submodules?
|
|
51
|
-
# rubocop:disable
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
# don't stop on a missing submodule. Needed because some submodules are only defined
|
|
56
|
-
# in the controller side.
|
|
57
|
-
end
|
|
58
|
-
# rubocop:enable Lint/HandleExceptions
|
|
51
|
+
include Submodules.const_get(mod.to_s.split('_').map(&:capitalize).join) # rubocop:disable Layout/EmptyLinesAfterModuleInclusion
|
|
52
|
+
rescue NameError
|
|
53
|
+
# don't stop on a missing submodule. Needed because some submodules are only defined
|
|
54
|
+
# in the controller side.
|
|
59
55
|
end
|
|
60
56
|
end
|
|
61
57
|
end
|
|
@@ -86,19 +82,13 @@ module Sorcery
|
|
|
86
82
|
def authenticate(*credentials, &block)
|
|
87
83
|
raise ArgumentError, 'at least 2 arguments required' if credentials.size < 2
|
|
88
84
|
|
|
89
|
-
if credentials[0].blank?
|
|
90
|
-
return authentication_response(return_value: false, failure: :invalid_login, &block)
|
|
91
|
-
end
|
|
85
|
+
return authentication_response(return_value: false, failure: :invalid_login, &block) if credentials[0].blank?
|
|
92
86
|
|
|
93
|
-
if @sorcery_config.downcase_username_before_authenticating
|
|
94
|
-
credentials[0].downcase!
|
|
95
|
-
end
|
|
87
|
+
credentials[0].downcase! if @sorcery_config.downcase_username_before_authenticating
|
|
96
88
|
|
|
97
89
|
user = sorcery_adapter.find_by_credentials(credentials)
|
|
98
90
|
|
|
99
|
-
unless user
|
|
100
|
-
return authentication_response(failure: :invalid_login, &block)
|
|
101
|
-
end
|
|
91
|
+
return authentication_response(failure: :invalid_login, &block) unless user
|
|
102
92
|
|
|
103
93
|
set_encryption_attributes
|
|
104
94
|
|
|
@@ -109,9 +99,7 @@ module Sorcery
|
|
|
109
99
|
@sorcery_config.before_authenticate.each do |callback|
|
|
110
100
|
success, reason = user.send(callback)
|
|
111
101
|
|
|
112
|
-
unless success
|
|
113
|
-
return authentication_response(user: user, failure: reason, &block)
|
|
114
|
-
end
|
|
102
|
+
return authentication_response(user: user, failure: reason, &block) unless success
|
|
115
103
|
end
|
|
116
104
|
|
|
117
105
|
unless user.valid_password?(credentials[1])
|
|
@@ -134,9 +122,15 @@ module Sorcery
|
|
|
134
122
|
# FIXME: This method of passing config to the hashing provider is
|
|
135
123
|
# questionable, and has been refactored in Sorcery v1.
|
|
136
124
|
def set_encryption_attributes
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
125
|
+
if @sorcery_config.encryption_provider.respond_to?(:stretches) && @sorcery_config.stretches
|
|
126
|
+
@sorcery_config.encryption_provider.stretches = @sorcery_config.stretches
|
|
127
|
+
end
|
|
128
|
+
if @sorcery_config.encryption_provider.respond_to?(:join_token) && @sorcery_config.salt_join_token
|
|
129
|
+
@sorcery_config.encryption_provider.join_token = @sorcery_config.salt_join_token
|
|
130
|
+
end
|
|
131
|
+
return unless @sorcery_config.encryption_provider.respond_to?(:pepper) && @sorcery_config.pepper
|
|
132
|
+
|
|
133
|
+
@sorcery_config.encryption_provider.pepper = @sorcery_config.pepper
|
|
140
134
|
end
|
|
141
135
|
|
|
142
136
|
protected
|
|
@@ -193,7 +187,9 @@ module Sorcery
|
|
|
193
187
|
# encrypts password with salt and saves it.
|
|
194
188
|
def encrypt_password
|
|
195
189
|
config = sorcery_config
|
|
196
|
-
|
|
190
|
+
unless config.salt_attribute_name.nil?
|
|
191
|
+
send(:"#{config.salt_attribute_name}=", new_salt = TemporaryToken.generate_random_token)
|
|
192
|
+
end
|
|
197
193
|
send(:"#{config.crypted_password_attribute_name}=", self.class.encrypt(send(config.password_attribute_name), new_salt))
|
|
198
194
|
end
|
|
199
195
|
|