sorcery 0.9.1 → 0.16.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (199) hide show
  1. checksums.yaml +5 -5
  2. data/.github/FUNDING.yml +1 -0
  3. data/.github/ISSUE_TEMPLATE.md +24 -0
  4. data/.github/PULL_REQUEST_TEMPLATE.md +7 -0
  5. data/.github/workflows/ruby.yml +70 -0
  6. data/.gitignore +3 -0
  7. data/.rubocop.yml +55 -0
  8. data/.rubocop_todo.yml +163 -0
  9. data/CHANGELOG.md +132 -34
  10. data/CODE_OF_CONDUCT.md +14 -0
  11. data/Gemfile +3 -17
  12. data/{LICENSE.txt → LICENSE.md} +1 -1
  13. data/MAINTAINING.md +64 -0
  14. data/README.md +146 -269
  15. data/Rakefile +4 -2
  16. data/SECURITY.md +19 -0
  17. data/gemfiles/rails_52.gemfile +7 -0
  18. data/gemfiles/rails_60.gemfile +7 -0
  19. data/gemfiles/rails_61.gemfile +7 -0
  20. data/gemfiles/rails_70.gemfile +7 -0
  21. data/lib/generators/sorcery/USAGE +1 -1
  22. data/lib/generators/sorcery/helpers.rb +8 -4
  23. data/lib/generators/sorcery/install_generator.rb +41 -35
  24. data/lib/generators/sorcery/templates/initializer.rb +216 -112
  25. data/lib/generators/sorcery/templates/migration/activity_logging.rb +7 -7
  26. data/lib/generators/sorcery/templates/migration/brute_force_protection.rb +5 -5
  27. data/lib/generators/sorcery/templates/migration/core.rb +5 -7
  28. data/lib/generators/sorcery/templates/migration/external.rb +4 -4
  29. data/lib/generators/sorcery/templates/migration/magic_login.rb +9 -0
  30. data/lib/generators/sorcery/templates/migration/remember_me.rb +5 -5
  31. data/lib/generators/sorcery/templates/migration/reset_password.rb +7 -6
  32. data/lib/generators/sorcery/templates/migration/user_activation.rb +6 -6
  33. data/lib/sorcery/adapters/active_record_adapter.rb +11 -21
  34. data/lib/sorcery/adapters/mongoid_adapter.rb +23 -11
  35. data/lib/sorcery/controller/config.rb +27 -23
  36. data/lib/sorcery/controller/submodules/activity_logging.rb +16 -18
  37. data/lib/sorcery/controller/submodules/brute_force_protection.rb +1 -2
  38. data/lib/sorcery/controller/submodules/external.rb +69 -44
  39. data/lib/sorcery/controller/submodules/http_basic_auth.rb +18 -19
  40. data/lib/sorcery/controller/submodules/remember_me.rb +16 -16
  41. data/lib/sorcery/controller/submodules/session_timeout.rb +33 -11
  42. data/lib/sorcery/controller.rb +50 -35
  43. data/lib/sorcery/crypto_providers/aes256.rb +17 -16
  44. data/lib/sorcery/crypto_providers/bcrypt.rb +26 -22
  45. data/lib/sorcery/crypto_providers/common.rb +1 -1
  46. data/lib/sorcery/crypto_providers/md5.rb +5 -5
  47. data/lib/sorcery/crypto_providers/sha1.rb +5 -5
  48. data/lib/sorcery/crypto_providers/sha256.rb +2 -2
  49. data/lib/sorcery/crypto_providers/sha512.rb +3 -3
  50. data/lib/sorcery/engine.rb +19 -11
  51. data/lib/sorcery/model/config.rb +73 -50
  52. data/lib/sorcery/model/submodules/activity_logging.rb +31 -12
  53. data/lib/sorcery/model/submodules/brute_force_protection.rb +38 -31
  54. data/lib/sorcery/model/submodules/external.rb +22 -10
  55. data/lib/sorcery/model/submodules/magic_login.rb +130 -0
  56. data/lib/sorcery/model/submodules/remember_me.rb +19 -7
  57. data/lib/sorcery/model/submodules/reset_password.rb +64 -42
  58. data/lib/sorcery/model/submodules/user_activation.rb +52 -54
  59. data/lib/sorcery/model/temporary_token.rb +30 -7
  60. data/lib/sorcery/model.rb +65 -40
  61. data/lib/sorcery/protocols/oauth.rb +4 -9
  62. data/lib/sorcery/protocols/oauth2.rb +0 -2
  63. data/lib/sorcery/providers/auth0.rb +46 -0
  64. data/lib/sorcery/providers/base.rb +4 -4
  65. data/lib/sorcery/providers/battlenet.rb +51 -0
  66. data/lib/sorcery/providers/discord.rb +52 -0
  67. data/lib/sorcery/providers/facebook.rb +8 -11
  68. data/lib/sorcery/providers/github.rb +5 -7
  69. data/lib/sorcery/providers/google.rb +3 -5
  70. data/lib/sorcery/providers/heroku.rb +7 -8
  71. data/lib/sorcery/providers/instagram.rb +73 -0
  72. data/lib/sorcery/providers/jira.rb +12 -17
  73. data/lib/sorcery/providers/line.rb +63 -0
  74. data/lib/sorcery/providers/linkedin.rb +44 -35
  75. data/lib/sorcery/providers/liveid.rb +4 -7
  76. data/lib/sorcery/providers/microsoft.rb +59 -0
  77. data/lib/sorcery/providers/paypal.rb +60 -0
  78. data/lib/sorcery/providers/salesforce.rb +3 -5
  79. data/lib/sorcery/providers/slack.rb +45 -0
  80. data/lib/sorcery/providers/twitter.rb +4 -6
  81. data/lib/sorcery/providers/vk.rb +8 -9
  82. data/lib/sorcery/providers/wechat.rb +81 -0
  83. data/lib/sorcery/providers/xing.rb +7 -10
  84. data/lib/sorcery/test_helpers/internal/rails.rb +25 -17
  85. data/lib/sorcery/test_helpers/internal.rb +15 -14
  86. data/lib/sorcery/test_helpers/rails/controller.rb +1 -1
  87. data/lib/sorcery/test_helpers/rails/integration.rb +5 -6
  88. data/lib/sorcery/test_helpers/rails/request.rb +20 -0
  89. data/lib/sorcery/version.rb +1 -1
  90. data/lib/sorcery.rb +4 -17
  91. data/sorcery.gemspec +43 -28
  92. data/spec/active_record/user_activation_spec.rb +4 -5
  93. data/spec/active_record/user_activity_logging_spec.rb +4 -6
  94. data/spec/active_record/user_brute_force_protection_spec.rb +5 -6
  95. data/spec/active_record/user_magic_login_spec.rb +15 -0
  96. data/spec/active_record/user_oauth_spec.rb +5 -6
  97. data/spec/active_record/user_remember_me_spec.rb +5 -6
  98. data/spec/active_record/user_reset_password_spec.rb +4 -5
  99. data/spec/active_record/user_spec.rb +7 -17
  100. data/spec/controllers/controller_activity_logging_spec.rb +13 -24
  101. data/spec/controllers/controller_brute_force_protection_spec.rb +8 -10
  102. data/spec/controllers/controller_http_basic_auth_spec.rb +20 -21
  103. data/spec/controllers/controller_oauth2_spec.rb +297 -158
  104. data/spec/controllers/controller_oauth_spec.rb +97 -71
  105. data/spec/controllers/controller_remember_me_spec.rb +49 -36
  106. data/spec/controllers/controller_session_timeout_spec.rb +106 -20
  107. data/spec/controllers/controller_spec.rb +87 -111
  108. data/spec/orm/active_record.rb +3 -3
  109. data/spec/providers/example_provider_spec.rb +17 -0
  110. data/spec/providers/example_spec.rb +17 -0
  111. data/spec/providers/examples_spec.rb +17 -0
  112. data/spec/providers/vk_spec.rb +42 -0
  113. data/spec/rails_app/app/active_record/authentication.rb +1 -1
  114. data/spec/rails_app/app/active_record/user.rb +2 -2
  115. data/spec/rails_app/app/assets/config/manifest.js +1 -0
  116. data/spec/rails_app/app/controllers/application_controller.rb +2 -0
  117. data/spec/rails_app/app/controllers/sorcery_controller.rb +250 -46
  118. data/spec/rails_app/app/mailers/sorcery_mailer.rb +23 -17
  119. data/spec/rails_app/app/views/sorcery_mailer/magic_login_email.html.erb +13 -0
  120. data/spec/rails_app/app/views/sorcery_mailer/magic_login_email.text.erb +6 -0
  121. data/spec/rails_app/config/application.rb +14 -9
  122. data/spec/rails_app/config/boot.rb +2 -2
  123. data/spec/rails_app/config/environment.rb +1 -1
  124. data/spec/rails_app/config/environments/test.rb +1 -1
  125. data/spec/rails_app/config/initializers/compatible_legacy_migration.rb +11 -0
  126. data/spec/rails_app/config/initializers/session_store.rb +3 -3
  127. data/spec/rails_app/config/routes.rb +31 -1
  128. data/spec/rails_app/config/secrets.yml +4 -0
  129. data/spec/rails_app/config.ru +1 -1
  130. data/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb +4 -4
  131. data/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +10 -10
  132. data/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +5 -5
  133. data/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +5 -5
  134. data/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb +3 -3
  135. data/spec/rails_app/db/migrate/invalidate_active_sessions/20180221093235_add_invalidate_active_sessions_before_to_users.rb +9 -0
  136. data/spec/rails_app/db/migrate/magic_login/20170924151831_add_magic_login_to_users.rb +17 -0
  137. data/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +6 -6
  138. data/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +7 -5
  139. data/spec/rails_app/db/schema.rb +7 -9
  140. data/spec/shared_examples/user_activation_shared_examples.rb +177 -58
  141. data/spec/shared_examples/user_activity_logging_shared_examples.rb +47 -41
  142. data/spec/shared_examples/user_brute_force_protection_shared_examples.rb +19 -24
  143. data/spec/shared_examples/user_magic_login_shared_examples.rb +150 -0
  144. data/spec/shared_examples/user_oauth_shared_examples.rb +7 -10
  145. data/spec/shared_examples/user_remember_me_shared_examples.rb +91 -22
  146. data/spec/shared_examples/user_reset_password_shared_examples.rb +153 -58
  147. data/spec/shared_examples/user_shared_examples.rb +328 -145
  148. data/spec/sorcery_crypto_providers_spec.rb +122 -75
  149. data/spec/sorcery_temporary_token_spec.rb +27 -0
  150. data/spec/spec.opts +1 -1
  151. data/spec/spec_helper.rb +19 -14
  152. data/spec/support/migration_helper.rb +29 -0
  153. data/spec/support/providers/example.rb +11 -0
  154. data/spec/support/providers/example_provider.rb +11 -0
  155. data/spec/support/providers/examples.rb +11 -0
  156. metadata +119 -89
  157. data/.travis.yml +0 -132
  158. data/gemfiles/active_record-rails40.gemfile +0 -7
  159. data/gemfiles/active_record-rails41.gemfile +0 -7
  160. data/gemfiles/mongo_mapper-rails40.gemfile +0 -9
  161. data/gemfiles/mongo_mapper-rails41.gemfile +0 -9
  162. data/gemfiles/mongoid-rails40.gemfile +0 -9
  163. data/gemfiles/mongoid-rails41.gemfile +0 -9
  164. data/gemfiles/mongoid3-rails32.gemfile +0 -9
  165. data/lib/sorcery/adapters/data_mapper_adapter.rb +0 -176
  166. data/lib/sorcery/adapters/mongo_mapper_adapter.rb +0 -110
  167. data/lib/sorcery/railties/tasks.rake +0 -6
  168. data/spec/data_mapper/user_activation_spec.rb +0 -10
  169. data/spec/data_mapper/user_activity_logging_spec.rb +0 -14
  170. data/spec/data_mapper/user_brute_force_protection_spec.rb +0 -9
  171. data/spec/data_mapper/user_oauth_spec.rb +0 -9
  172. data/spec/data_mapper/user_remember_me_spec.rb +0 -8
  173. data/spec/data_mapper/user_reset_password_spec.rb +0 -8
  174. data/spec/data_mapper/user_spec.rb +0 -27
  175. data/spec/mongo_mapper/user_activation_spec.rb +0 -9
  176. data/spec/mongo_mapper/user_activity_logging_spec.rb +0 -8
  177. data/spec/mongo_mapper/user_brute_force_protection_spec.rb +0 -8
  178. data/spec/mongo_mapper/user_oauth_spec.rb +0 -8
  179. data/spec/mongo_mapper/user_remember_me_spec.rb +0 -8
  180. data/spec/mongo_mapper/user_reset_password_spec.rb +0 -8
  181. data/spec/mongo_mapper/user_spec.rb +0 -37
  182. data/spec/mongoid/user_activation_spec.rb +0 -9
  183. data/spec/mongoid/user_activity_logging_spec.rb +0 -8
  184. data/spec/mongoid/user_brute_force_protection_spec.rb +0 -8
  185. data/spec/mongoid/user_oauth_spec.rb +0 -8
  186. data/spec/mongoid/user_remember_me_spec.rb +0 -8
  187. data/spec/mongoid/user_reset_password_spec.rb +0 -8
  188. data/spec/mongoid/user_spec.rb +0 -51
  189. data/spec/orm/data_mapper.rb +0 -48
  190. data/spec/orm/mongo_mapper.rb +0 -10
  191. data/spec/orm/mongoid.rb +0 -22
  192. data/spec/rails_app/app/data_mapper/authentication.rb +0 -8
  193. data/spec/rails_app/app/data_mapper/user.rb +0 -7
  194. data/spec/rails_app/app/mongo_mapper/authentication.rb +0 -6
  195. data/spec/rails_app/app/mongo_mapper/user.rb +0 -7
  196. data/spec/rails_app/app/mongoid/authentication.rb +0 -7
  197. data/spec/rails_app/app/mongoid/user.rb +0 -7
  198. data/spec/rails_app/config/initializers/secret_token.rb +0 -7
  199. data/spec/rails_app/log/development.log +0 -1791
@@ -1,13 +1,11 @@
1
- class SorceryCore < ActiveRecord::Migration
1
+ class SorceryCore < <%= migration_class_name %>
2
2
  def change
3
- create_table :<%= model_class_name.tableize %> do |t|
4
- t.string :email, :null => false
3
+ create_table :<%= tableized_model_class %> do |t|
4
+ t.string :email, null: false, index: { unique: true }
5
5
  t.string :crypted_password
6
6
  t.string :salt
7
7
 
8
- t.timestamps
8
+ t.timestamps null: false
9
9
  end
10
-
11
- add_index :<%= model_class_name.tableize %>, :email, unique: true
12
10
  end
13
- end
11
+ end
@@ -1,10 +1,10 @@
1
- class SorceryExternal < ActiveRecord::Migration
1
+ class SorceryExternal < <%= migration_class_name %>
2
2
  def change
3
3
  create_table :authentications do |t|
4
- t.integer :<%= model_class_name.tableize.singularize %>_id, :null => false
5
- t.string :provider, :uid, :null => false
4
+ t.integer :<%= tableized_model_class.singularize %>_id, null: false
5
+ t.string :provider, :uid, null: false
6
6
 
7
- t.timestamps
7
+ t.timestamps null: false
8
8
  end
9
9
 
10
10
  add_index :authentications, [:provider, :uid]
@@ -0,0 +1,9 @@
1
+ class SorceryMagicLogin < <%= migration_class_name %>
2
+ def change
3
+ add_column :<%= tableized_model_class %>, :magic_login_token, :string, default: nil
4
+ add_column :<%= tableized_model_class %>, :magic_login_token_expires_at, :datetime, default: nil
5
+ add_column :<%= tableized_model_class %>, :magic_login_email_sent_at, :datetime, default: nil
6
+
7
+ add_index :<%= tableized_model_class %>, :magic_login_token
8
+ end
9
+ end
@@ -1,8 +1,8 @@
1
- class SorceryRememberMe < ActiveRecord::Migration
1
+ class SorceryRememberMe < <%= migration_class_name %>
2
2
  def change
3
- add_column :<%= model_class_name.tableize %>, :remember_me_token, :string, :default => nil
4
- add_column :<%= model_class_name.tableize %>, :remember_me_token_expires_at, :datetime, :default => nil
3
+ add_column :<%= tableized_model_class %>, :remember_me_token, :string, default: nil
4
+ add_column :<%= tableized_model_class %>, :remember_me_token_expires_at, :datetime, default: nil
5
5
 
6
- add_index :<%= model_class_name.tableize %>, :remember_me_token
6
+ add_index :<%= tableized_model_class %>, :remember_me_token
7
7
  end
8
- end
8
+ end
@@ -1,9 +1,10 @@
1
- class SorceryResetPassword < ActiveRecord::Migration
1
+ class SorceryResetPassword < <%= migration_class_name %>
2
2
  def change
3
- add_column :<%= model_class_name.tableize %>, :reset_password_token, :string, :default => nil
4
- add_column :<%= model_class_name.tableize %>, :reset_password_token_expires_at, :datetime, :default => nil
5
- add_column :<%= model_class_name.tableize %>, :reset_password_email_sent_at, :datetime, :default => nil
3
+ add_column :<%= tableized_model_class %>, :reset_password_token, :string, default: nil
4
+ add_column :<%= tableized_model_class %>, :reset_password_token_expires_at, :datetime, default: nil
5
+ add_column :<%= tableized_model_class %>, :reset_password_email_sent_at, :datetime, default: nil
6
+ add_column :<%= tableized_model_class %>, :access_count_to_reset_password_page, :integer, default: 0
6
7
 
7
- add_index :<%= model_class_name.tableize %>, :reset_password_token
8
+ add_index :<%= tableized_model_class %>, :reset_password_token
8
9
  end
9
- end
10
+ end
@@ -1,9 +1,9 @@
1
- class SorceryUserActivation < ActiveRecord::Migration
1
+ class SorceryUserActivation < <%= migration_class_name %>
2
2
  def change
3
- add_column :<%= model_class_name.tableize %>, :activation_state, :string, :default => nil
4
- add_column :<%= model_class_name.tableize %>, :activation_token, :string, :default => nil
5
- add_column :<%= model_class_name.tableize %>, :activation_token_expires_at, :datetime, :default => nil
3
+ add_column :<%= tableized_model_class %>, :activation_state, :string, default: nil
4
+ add_column :<%= tableized_model_class %>, :activation_token, :string, default: nil
5
+ add_column :<%= tableized_model_class %>, :activation_token_expires_at, :datetime, default: nil
6
6
 
7
- add_index :<%= model_class_name.tableize %>, :activation_token
7
+ add_index :<%= tableized_model_class %>, :activation_token
8
8
  end
9
- end
9
+ end
@@ -6,12 +6,13 @@ module Sorcery
6
6
  @model.send(:"#{name}=", value)
7
7
  end
8
8
  primary_key = @model.class.primary_key
9
- @model.class.where(:"#{primary_key}" => @model.send(:"#{primary_key}")).update_all(attrs)
9
+ updated_count = @model.class.where(:"#{primary_key}" => @model.send(:"#{primary_key}")).update_all(attrs)
10
+ updated_count == 1
10
11
  end
11
12
 
12
13
  def save(options = {})
13
14
  mthd = options.delete(:raise_on_failure) ? :save! : :save
14
- @model.send(mthd, options)
15
+ @model.send(mthd, **options)
15
16
  end
16
17
 
17
18
  def increment(field)
@@ -29,12 +30,12 @@ module Sorcery
29
30
  end
30
31
 
31
32
  class << self
32
- def define_field(name, type, options={})
33
+ def define_field(name, type, options = {})
33
34
  # AR fields are defined through migrations, only validator here
34
35
  end
35
36
 
36
- def define_callback(time, event, method_name, options={})
37
- @klass.send "#{time}_#{event}", method_name, options.slice(:if)
37
+ def define_callback(time, event, method_name, options = {})
38
+ @klass.send "#{time}_#{event}", method_name, **options.slice(:if, :on)
38
39
  end
39
40
 
40
41
  def find_by_oauth_credentials(provider, uid)
@@ -61,11 +62,11 @@ module Sorcery
61
62
  condition = @klass.arel_table[attribute].eq(credentials[0])
62
63
  end
63
64
 
64
- if relation.nil?
65
- relation = condition
66
- else
67
- relation = relation.or(condition)
68
- end
65
+ relation = if relation.nil?
66
+ condition
67
+ else
68
+ relation.or(condition)
69
+ end
69
70
  end
70
71
 
71
72
  @klass.where(relation).first
@@ -100,21 +101,10 @@ module Sorcery
100
101
  @klass.where(@klass.sorcery_config.email_attribute_name => email).first
101
102
  end
102
103
 
103
- def get_current_users
104
- config = @klass.sorcery_config
105
-
106
- @klass
107
- .where("#{config.last_activity_at_attribute_name} IS NOT NULL") \
108
- .where("#{config.last_logout_at_attribute_name} IS NULL OR #{config.last_activity_at_attribute_name} > #{config.last_logout_at_attribute_name}") \
109
- .where("#{config.last_activity_at_attribute_name} > ? ", config.activity_timeout.seconds.ago.utc.to_s(:db))
110
- end
111
-
112
104
  def transaction(&blk)
113
105
  @klass.tap(&blk)
114
106
  end
115
107
  end
116
108
  end
117
-
118
-
119
109
  end
120
110
  end
@@ -10,7 +10,7 @@ module Sorcery
10
10
  attrs[name] = value.utc if value.is_a?(ActiveSupport::TimeWithZone)
11
11
  @model.send(:"#{name}=", value)
12
12
  end
13
- @model.class.where(:_id => @model.id).update_all(attrs)
13
+ @model.class.where(_id: @model.id).update_all(attrs)
14
14
  end
15
15
 
16
16
  def update_attribute(name, value)
@@ -23,21 +23,29 @@ module Sorcery
23
23
  end
24
24
 
25
25
  def mongoid_4?
26
- Gem::Version.new(::Mongoid::VERSION) >= Gem::Version.new("4.0.0.alpha")
26
+ Gem::Version.new(::Mongoid::VERSION) >= Gem::Version.new('4.0.0.alpha')
27
27
  end
28
28
 
29
29
  class << self
30
-
31
- def define_field(name, type, options={})
30
+ def define_field(name, type, options = {})
32
31
  @klass.field name, options.slice(:default).merge(type: type)
33
32
  end
34
33
 
35
- def define_callback(time, event, method_name, options={})
36
- @klass.send "#{time}_#{event}", method_name, options.slice(:if)
34
+ def define_callback(time, event, method_name, options = {})
35
+ @klass.send callback_name(time, event, options), method_name, **options.slice(:if)
36
+ end
37
+
38
+ def callback_name(time, event, options)
39
+ if event == :commit
40
+ options[:on] == :create ? "#{time}_create" : "#{time}_save"
41
+ else
42
+ "#{time}_#{event}"
43
+ end
37
44
  end
38
45
 
39
46
  def credential_regex(credential)
40
- return { :$regex => /^#{Regexp.escape(credential)}$/i } if (@klass.sorcery_config.downcase_username_before_authenticating)
47
+ return { :$regex => /^#{Regexp.escape(credential)}$/i } if @klass.sorcery_config.downcase_username_before_authenticating
48
+
41
49
  credential
42
50
  end
43
51
 
@@ -73,7 +81,7 @@ module Sorcery
73
81
  end
74
82
 
75
83
  def find_by_username(username)
76
- query = @klass.sorcery_config.username_attribute_names.map {|name| {name => username}}
84
+ query = @klass.sorcery_config.username_attribute_names.map { |name| { name => username } }
77
85
  @klass.any_of(*query).first
78
86
  end
79
87
 
@@ -87,9 +95,13 @@ module Sorcery
87
95
 
88
96
  def get_current_users
89
97
  config = @klass.sorcery_config
90
- @klass.where(config.last_activity_at_attribute_name.ne => nil) \
91
- .where("this.#{config.last_logout_at_attribute_name} == null || this.#{config.last_activity_at_attribute_name} > this.#{config.last_logout_at_attribute_name}") \
92
- .where(config.last_activity_at_attribute_name.gt => config.activity_timeout.seconds.ago.utc).order_by([:_id,:asc])
98
+ @klass.where(
99
+ config.last_activity_at_attribute_name.ne => nil
100
+ ).where(
101
+ "this.#{config.last_logout_at_attribute_name} == null || this.#{config.last_activity_at_attribute_name} > this.#{config.last_logout_at_attribute_name}"
102
+ ).where(
103
+ config.last_activity_at_attribute_name.gt => config.activity_timeout.seconds.ago.utc
104
+ ).order_by(%i[_id asc])
93
105
  end
94
106
  end
95
107
  end
@@ -2,32 +2,35 @@ module Sorcery
2
2
  module Controller
3
3
  module Config
4
4
  class << self
5
- attr_accessor :submodules,
6
- :user_class, # what class to use as the user class.
7
- :not_authenticated_action, # what controller action to call for non-authenticated users.
5
+ attr_accessor :submodules
6
+ # what class to use as the user class.
7
+ attr_accessor :user_class
8
+ # what controller action to call for non-authenticated users.
9
+ attr_accessor :not_authenticated_action
10
+ # when a non logged in user tries to enter a page that requires login,
11
+ # save the URL he wanted to reach, and send him there after login.
12
+ attr_accessor :save_return_to_url
13
+ # set domain option for cookies
14
+ attr_accessor :cookie_domain
8
15
 
9
- :save_return_to_url, # when a non logged in user tries to enter a page that requires
10
- # login, save the URL he wanted to reach,
11
- # and send him there after login.
12
-
13
- :cookie_domain, # set domain option for cookies
14
-
15
- :login_sources,
16
- :after_login,
17
- :after_failed_login,
18
- :before_logout,
19
- :after_logout
16
+ attr_accessor :login_sources
17
+ attr_accessor :after_login
18
+ attr_accessor :after_failed_login
19
+ attr_accessor :before_logout
20
+ attr_accessor :after_logout
21
+ attr_accessor :after_remember_me
20
22
 
21
23
  def init!
22
24
  @defaults = {
23
25
  :@user_class => nil,
24
26
  :@submodules => [],
25
27
  :@not_authenticated_action => :not_authenticated,
26
- :@login_sources => [],
27
- :@after_login => [],
28
- :@after_failed_login => [],
29
- :@before_logout => [],
30
- :@after_logout => [],
28
+ :@login_sources => Set.new,
29
+ :@after_login => Set.new,
30
+ :@after_failed_login => Set.new,
31
+ :@before_logout => Set.new,
32
+ :@after_logout => Set.new,
33
+ :@after_remember_me => Set.new,
31
34
  :@save_return_to_url => true,
32
35
  :@cookie_domain => nil
33
36
  }
@@ -35,14 +38,14 @@ module Sorcery
35
38
 
36
39
  # Resets all configuration options to their default values.
37
40
  def reset!
38
- @defaults.each do |k,v|
39
- instance_variable_set(k,v)
41
+ @defaults.each do |k, v|
42
+ instance_variable_set(k, v)
40
43
  end
41
44
  end
42
45
 
43
46
  def update!
44
- @defaults.each do |k,v|
45
- instance_variable_set(k,v) if !instance_variable_defined?(k)
47
+ @defaults.each do |k, v|
48
+ instance_variable_set(k, v) unless instance_variable_defined?(k)
46
49
  end
47
50
  end
48
51
 
@@ -58,6 +61,7 @@ module Sorcery
58
61
  @configure_blk.call(self) if @configure_blk
59
62
  end
60
63
  end
64
+
61
65
  init!
62
66
  reset!
63
67
  end
@@ -25,40 +25,36 @@ module Sorcery
25
25
  @defaults.merge!(:@register_login_time => true,
26
26
  :@register_logout_time => true,
27
27
  :@register_last_activity_time => true,
28
- :@register_last_ip_address => true
29
- )
28
+ :@register_last_ip_address => true)
30
29
  end
31
30
  end
32
31
  merge_activity_logging_defaults!
33
32
  end
34
- Config.after_login << :register_login_time_to_db
35
- Config.after_login << :register_last_ip_address
36
- Config.before_logout << :register_logout_time_to_db
37
- base.after_filter :register_last_activity_time_to_db
38
- end
39
33
 
40
- module InstanceMethods
41
- # Returns an array of the active users.
42
- def current_users
43
- ActiveSupport::Deprecation.warn("Sorcery: `current_users` method is deprecated. Read more on Github: https://github.com/NoamB/sorcery/issues/602")
34
+ Config.after_login << :register_login_time_to_db
35
+ Config.after_login << :register_last_ip_address
36
+ Config.before_logout << :register_logout_time_to_db
44
37
 
45
- user_class.current_users
46
- end
38
+ base.after_action :register_last_activity_time_to_db
39
+ end
47
40
 
41
+ module InstanceMethods
48
42
  protected
49
43
 
50
44
  # registers last login time on every login.
51
45
  # This runs as a hook just after a successful login.
52
- def register_login_time_to_db(user, credentials)
46
+ def register_login_time_to_db(user, _credentials)
53
47
  return unless Config.register_login_time
48
+
54
49
  user.set_last_login_at(Time.now.in_time_zone)
55
50
  end
56
51
 
57
52
  # registers last logout time on every logout.
58
53
  # This runs as a hook just before a logout.
59
- def register_logout_time_to_db(user)
54
+ def register_logout_time_to_db
60
55
  return unless Config.register_logout_time
61
- user.set_last_logout_at(Time.now.in_time_zone)
56
+
57
+ current_user.set_last_logout_at(Time.now.in_time_zone)
62
58
  end
63
59
 
64
60
  # Updates last activity time on every request.
@@ -66,14 +62,16 @@ module Sorcery
66
62
  def register_last_activity_time_to_db
67
63
  return unless Config.register_last_activity_time
68
64
  return unless logged_in?
65
+
69
66
  current_user.set_last_activity_at(Time.now.in_time_zone)
70
67
  end
71
68
 
72
69
  # Updates IP address on every login.
73
70
  # This runs as a hook just after a successful login.
74
- def register_last_ip_address(user, credentials)
71
+ def register_last_ip_address(_user, _credentials)
75
72
  return unless Config.register_last_ip_address
76
- current_user.set_last_ip_addess(request.remote_ip)
73
+
74
+ current_user.set_last_ip_address(request.remote_ip)
77
75
  end
78
76
  end
79
77
  end
@@ -16,7 +16,6 @@ module Sorcery
16
16
  end
17
17
 
18
18
  module InstanceMethods
19
-
20
19
  protected
21
20
 
22
21
  # Increments the failed logins counter on every failed login.
@@ -28,7 +27,7 @@ module Sorcery
28
27
 
29
28
  # Resets the failed logins counter.
30
29
  # Runs as a hook after a successful login.
31
- def reset_failed_logins_count!(user, credentials)
30
+ def reset_failed_logins_count!(user, _credentials)
32
31
  user.sorcery_adapter.update_attribute(user_class.sorcery_config.failed_logins_count_attribute_name, 0)
33
32
  end
34
33
  end
@@ -19,6 +19,15 @@ module Sorcery
19
19
  require 'sorcery/providers/google'
20
20
  require 'sorcery/providers/jira'
21
21
  require 'sorcery/providers/salesforce'
22
+ require 'sorcery/providers/paypal'
23
+ require 'sorcery/providers/slack'
24
+ require 'sorcery/providers/wechat'
25
+ require 'sorcery/providers/microsoft'
26
+ require 'sorcery/providers/instagram'
27
+ require 'sorcery/providers/auth0'
28
+ require 'sorcery/providers/line'
29
+ require 'sorcery/providers/discord'
30
+ require 'sorcery/providers/battlenet'
22
31
 
23
32
  Config.module_eval do
24
33
  class << self
@@ -29,17 +38,17 @@ module Sorcery
29
38
  @external_providers = providers
30
39
 
31
40
  providers.each do |name|
32
- class_eval <<-E
41
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
33
42
  def self.#{name}
34
- @#{name} ||= Sorcery::Providers.const_get('#{name}'.to_s.capitalize).new
43
+ @#{name} ||= Sorcery::Providers.const_get('#{name}'.to_s.camelcase).new
35
44
  end
36
- E
45
+ RUBY
37
46
  end
38
47
  end
39
48
 
40
49
  def merge_external_defaults!
41
50
  @defaults.merge!(:@external_providers => [],
42
- :@ca_file => File.join(File.expand_path(File.dirname(__FILE__)), '../../protocols/certs/ca-bundle.crt'))
51
+ :@ca_file => File.join(__dir__, '../../protocols/certs/ca-bundle.crt'))
43
52
  end
44
53
  end
45
54
  merge_external_defaults!
@@ -52,6 +61,7 @@ module Sorcery
52
61
  # save the singleton ProviderClient instance into @provider
53
62
  def sorcery_get_provider(provider_name)
54
63
  return unless Config.external_providers.include?(provider_name.to_sym)
64
+
55
65
  Config.send(provider_name.to_sym)
56
66
  end
57
67
 
@@ -60,12 +70,11 @@ module Sorcery
60
70
  def sorcery_login_url(provider_name, args = {})
61
71
  @provider = sorcery_get_provider provider_name
62
72
  sorcery_fixup_callback_url @provider
63
- if @provider.respond_to?(:login_url) && @provider.has_callback?
64
- @provider.state = args[:state]
65
- return @provider.login_url(params, session)
66
- else
67
- return nil
68
- end
73
+
74
+ return nil unless @provider.respond_to?(:login_url) && @provider.has_callback?
75
+
76
+ @provider.state = args[:state]
77
+ @provider.login_url(params, session)
69
78
  end
70
79
 
71
80
  # get the user hash from a provider using information from the params and session.
@@ -84,25 +93,26 @@ module Sorcery
84
93
  # cache them in instance variables.
85
94
  @access_token ||= @provider.process_callback(params, session) # sends request to oauth agent to get the token
86
95
  @user_hash ||= @provider.get_user_hash(@access_token) # uses the token to send another request to the oauth agent requesting user info
96
+ nil
87
97
  end
88
98
 
89
99
  # for backwards compatibility
90
- def access_token(*args)
100
+ def access_token(*_args)
91
101
  @access_token
92
102
  end
93
103
 
94
-
95
104
  # this method should be somewhere else. It only does something once per application per provider.
96
105
  def sorcery_fixup_callback_url(provider)
97
106
  provider.original_callback_url ||= provider.callback_url
98
- if provider.original_callback_url.present? && provider.original_callback_url[0] == '/'
99
- uri = URI.parse(request.url.gsub(/\?.*$/,''))
100
- uri.path = ''
101
- uri.query = nil
102
- uri.scheme = 'https' if(request.env['HTTP_X_FORWARDED_PROTO'] == 'https')
103
- host = uri.to_s
104
- provider.callback_url = "#{host}#{@provider.original_callback_url}"
105
- end
107
+
108
+ return unless provider.original_callback_url.present? && provider.original_callback_url[0] == '/'
109
+
110
+ uri = URI.parse(request.url.gsub(/\?.*$/, ''))
111
+ uri.path = ''
112
+ uri.query = nil
113
+ uri.scheme = 'https' if request.env['HTTP_X_FORWARDED_PROTO'] == 'https'
114
+ host = uri.to_s
115
+ provider.callback_url = "#{host}#{@provider.original_callback_url}"
106
116
  end
107
117
 
108
118
  # sends user to authenticate at the provider's website.
@@ -115,31 +125,31 @@ module Sorcery
115
125
  def login_from(provider_name, should_remember = false)
116
126
  sorcery_fetch_user_hash provider_name
117
127
 
118
- if user = user_class.load_from_provider(provider_name, @user_hash[:uid].to_s)
119
- # we found the user.
120
- # clear the session
121
- return_to_url = session[:return_to_url]
122
- reset_sorcery_session
123
- session[:return_to_url] = return_to_url
128
+ return unless (user = user_class.load_from_provider(provider_name, @user_hash[:uid].to_s))
124
129
 
125
- # sign in the user
126
- auto_login(user, should_remember)
127
- after_login!(user)
130
+ # we found the user.
131
+ # clear the session
132
+ return_to_url = session[:return_to_url]
133
+ reset_sorcery_session
134
+ session[:return_to_url] = return_to_url
128
135
 
129
- # return the user
130
- user
131
- end
136
+ # sign in the user
137
+ auto_login(user, should_remember)
138
+ after_login!(user)
139
+
140
+ # return the user
141
+ user
132
142
  end
133
143
 
134
144
  # If user is logged, he can add all available providers into his account
135
145
  def add_provider_to_user(provider_name)
136
146
  sorcery_fetch_user_hash provider_name
137
- config = user_class.sorcery_config
147
+ # config = user_class.sorcery_config # TODO: Unused, remove?
138
148
 
139
149
  current_user.add_provider_to_user(provider_name.to_s, @user_hash[:uid].to_s)
140
150
  end
141
151
 
142
- # Initialize new user from provider informations.
152
+ # Initialize new user from provider informations.
143
153
  # If a provider doesn't give required informations or username/email is already taken,
144
154
  # we store provider/user infos into a session and can be rendered into registration form
145
155
  def create_and_validate_from(provider_name)
@@ -150,12 +160,14 @@ module Sorcery
150
160
 
151
161
  user, saved = user_class.create_and_validate_from_provider(provider_name, @user_hash[:uid], attrs)
152
162
 
153
- session[:incomplete_user] = {
154
- :provider => {config.provider_uid_attribute_name => @user_hash[:uid], config.provider_attribute_name => provider_name},
155
- :user_hash => attrs
156
- } unless saved
163
+ unless saved
164
+ session[:incomplete_user] = {
165
+ provider: { config.provider_uid_attribute_name => @user_hash[:uid], config.provider_attribute_name => provider_name },
166
+ user_hash: attrs
167
+ }
168
+ end
157
169
 
158
- return user
170
+ user
159
171
  end
160
172
 
161
173
  # this method automatically creates a new user from the data in the external user hash.
@@ -176,23 +188,36 @@ module Sorcery
176
188
  #
177
189
  def create_from(provider_name, &block)
178
190
  sorcery_fetch_user_hash provider_name
179
- config = user_class.sorcery_config
191
+ # config = user_class.sorcery_config # TODO: Unused, remove?
180
192
 
181
193
  attrs = user_attrs(@provider.user_info_mapping, @user_hash)
182
194
  @user = user_class.create_from_provider(provider_name, @user_hash[:uid], attrs, &block)
183
195
  end
184
196
 
197
+ # follows the same patterns as create_from, but builds the user instead of creating
198
+ def build_from(provider_name, &block)
199
+ sorcery_fetch_user_hash provider_name
200
+ # config = user_class.sorcery_config # TODO: Unused, remove?
201
+
202
+ attrs = user_attrs(@provider.user_info_mapping, @user_hash)
203
+ @user = user_class.build_from_provider(attrs, &block)
204
+ end
205
+
185
206
  def user_attrs(user_info_mapping, user_hash)
186
207
  attrs = {}
187
- user_info_mapping.each do |k,v|
188
- if (varr = v.split("/")).size > 1
189
- attribute_value = varr.inject(user_hash[:user_info]) {|hash, value| hash[value]} rescue nil
208
+ user_info_mapping.each do |k, v|
209
+ if (varr = v.split('/')).size > 1
210
+ attribute_value = begin
211
+ varr.inject(user_hash[:user_info]) { |hash, value| hash[value] }
212
+ rescue StandardError
213
+ nil
214
+ end
190
215
  attribute_value.nil? ? attrs : attrs.merge!(k => attribute_value)
191
216
  else
192
217
  attrs.merge!(k => user_hash[:user_info][v])
193
218
  end
194
219
  end
195
- return attrs
220
+ attrs
196
221
  end
197
222
  end
198
223
  end