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
@@ -0,0 +1,81 @@
1
+ module Sorcery
2
+ module Providers
3
+ # This class adds support for OAuth with open.wx.qq.com.
4
+ #
5
+ # config.wechat.key = <key>
6
+ # config.wechat.secret = <secret>
7
+ # ...
8
+ #
9
+ class Wechat < Base
10
+ include Protocols::Oauth2
11
+
12
+ attr_reader :mode, :param_name, :parse
13
+ attr_accessor :auth_url, :scope, :token_url, :user_info_path
14
+
15
+ def initialize
16
+ super
17
+
18
+ @scope = 'snsapi_login'
19
+ @auth_url = 'https://open.weixin.qq.com/connect/qrconnect'
20
+ @user_info_path = 'https://api.weixin.qq.com/sns/userinfo'
21
+ @token_url = 'https://api.weixin.qq.com/sns/oauth2/access_token'
22
+ @state = SecureRandom.hex(16)
23
+ @mode = :body
24
+ @parse = :json
25
+ @param_name = 'access_token'
26
+ end
27
+
28
+ def authorize_url(options = {})
29
+ oauth_params = {
30
+ appid: @key,
31
+ redirect_uri: @callback_url,
32
+ response_type: 'code',
33
+ scope: scope,
34
+ state: @state
35
+ }
36
+ "#{options[:authorize_url]}?#{oauth_params.to_query}#wechat_redirect"
37
+ end
38
+
39
+ def get_user_hash(access_token)
40
+ response = access_token.get(
41
+ user_info_path,
42
+ params: {
43
+ access_token: access_token.token,
44
+ openid: access_token.params['openid']
45
+ }
46
+ )
47
+
48
+ {}.tap do |h|
49
+ h[:user_info] = JSON.parse(response.body)
50
+ h[:uid] = h[:user_info]['unionid']
51
+ end
52
+ end
53
+
54
+ def get_access_token(args, options = {})
55
+ client = build_client(options)
56
+ client.auth_code.get_token(
57
+ args[:code],
58
+ { appid: @key, secret: @secret, parse: parse },
59
+ options
60
+ )
61
+ end
62
+
63
+ def login_url(_params, _session)
64
+ authorize_url authorize_url: auth_url
65
+ end
66
+
67
+ def process_callback(params, _session)
68
+ args = {}.tap do |a|
69
+ a[:code] = params[:code] if params[:code]
70
+ end
71
+
72
+ get_access_token(
73
+ args,
74
+ token_url: token_url,
75
+ mode: mode,
76
+ param_name: param_name
77
+ )
78
+ end
79
+ end
80
+ end
81
+ end
@@ -7,19 +7,17 @@ module Sorcery
7
7
  # ...
8
8
  #
9
9
  class Xing < Base
10
-
11
10
  include Protocols::Oauth
12
11
 
13
12
  attr_accessor :access_token_path, :authorize_path, :request_token_path,
14
13
  :user_info_path
15
14
 
16
-
17
15
  def initialize
18
16
  @configuration = {
19
- site: 'https://api.xing.com/v1',
20
- authorize_path: '/authorize',
21
- request_token_path: '/request_token',
22
- access_token_path: '/access_token'
17
+ site: 'https://api.xing.com/v1',
18
+ authorize_path: '/authorize',
19
+ request_token_path: '/request_token',
20
+ access_token_path: '/access_token'
23
21
  }
24
22
  @user_info_path = '/users/me'
25
23
  end
@@ -40,11 +38,11 @@ module Sorcery
40
38
 
41
39
  # calculates and returns the url to which the user should be redirected,
42
40
  # to get authenticated at the external provider's site.
43
- def login_url(params, session)
41
+ def login_url(_params, session)
44
42
  req_token = get_request_token
45
43
  session[:request_token] = req_token.token
46
44
  session[:request_token_secret] = req_token.secret
47
- authorize_url({ request_token: req_token.token, request_token_secret: req_token.secret })
45
+ authorize_url(request_token: req_token.token, request_token_secret: req_token.secret)
48
46
  end
49
47
 
50
48
  # tries to login the user from access token
@@ -55,10 +53,9 @@ module Sorcery
55
53
  request_token_secret: session[:request_token_secret]
56
54
  }
57
55
 
58
- args.merge!({ code: params[:code] }) if params[:code]
56
+ args[:code] = params[:code] if params[:code]
59
57
  get_access_token(args)
60
58
  end
61
-
62
59
  end
63
60
  end
64
61
  end
@@ -4,11 +4,11 @@ module Sorcery
4
4
  module Rails
5
5
  include ::Sorcery::TestHelpers::Rails::Controller
6
6
 
7
- SUBMODULES_AUTO_ADDED_CONTROLLER_FILTERS = [
8
- :register_last_activity_time_to_db,
9
- :deny_banned_user,
10
- :validate_session
11
- ]
7
+ SUBMODULES_AUTO_ADDED_CONTROLLER_FILTERS = %i[
8
+ register_last_activity_time_to_db
9
+ deny_banned_user
10
+ validate_session
11
+ ].freeze
12
12
 
13
13
  def sorcery_reload!(submodules = [], options = {})
14
14
  reload_user_class
@@ -17,34 +17,34 @@ module Sorcery
17
17
  ::Sorcery::Controller::Config.init!
18
18
  ::Sorcery::Controller::Config.reset!
19
19
 
20
- # remove all plugin before_filters so they won't fail other tests.
20
+ # remove all plugin before_actions so they won't fail other tests.
21
21
  # I don't like this way, but I didn't find another.
22
22
  # hopefully it won't break until Rails 4.
23
- chain = if Gem::Version.new(::Rails::VERSION::STRING) >= Gem::Version.new("4.1.0")
23
+ chain = if Gem::Version.new(::Rails::VERSION::STRING) >= Gem::Version.new('4.1.0')
24
24
  SorceryController._process_action_callbacks.send :chain
25
25
  else
26
26
  SorceryController._process_action_callbacks
27
27
  end
28
28
 
29
- chain.delete_if {|c| SUBMODULES_AUTO_ADDED_CONTROLLER_FILTERS.include?(c.filter) }
29
+ chain.delete_if { |c| SUBMODULES_AUTO_ADDED_CONTROLLER_FILTERS.include?(c.filter) }
30
30
 
31
31
  # configure
32
32
  ::Sorcery::Controller::Config.submodules = submodules
33
33
  ::Sorcery::Controller::Config.user_class = nil
34
- ActionController::Base.send(:include,::Sorcery::Controller)
35
- ::Sorcery::Controller::Config.user_class = "User"
34
+ ActionController::Base.send(:include, ::Sorcery::Controller)
35
+ ::Sorcery::Controller::Config.user_class = 'User'
36
36
 
37
37
  ::Sorcery::Controller::Config.user_config do |user|
38
- options.each do |property,value|
38
+ options.each do |property, value|
39
39
  user.send(:"#{property}=", value)
40
40
  end
41
41
  end
42
42
  User.authenticates_with_sorcery!
43
- if defined?(DataMapper) and User.ancestors.include?(DataMapper::Resource)
44
- DataMapper.auto_migrate!
45
- User.finalize
46
- Authentication.finalize
47
- end
43
+ return unless defined?(DataMapper) && User.ancestors.include?(DataMapper::Resource)
44
+
45
+ DataMapper.auto_migrate!
46
+ User.finalize
47
+ Authentication.finalize
48
48
  end
49
49
 
50
50
  def sorcery_controller_property_set(property, value)
@@ -60,7 +60,15 @@ module Sorcery
60
60
  # all this without calling the :logout action explicitly.
61
61
  # A dirty dirty hack.
62
62
  def clear_user_without_logout
63
- subject.instance_variable_set(:@current_user,nil)
63
+ subject.instance_variable_set(:@current_user, nil)
64
+ end
65
+
66
+ if ::Rails.version < '5.0.0'
67
+ %w[get post put].each do |method|
68
+ define_method(method) do |action, options = {}|
69
+ super action, options[:params] || {}, options[:session]
70
+ end
71
+ end
64
72
  end
65
73
  end
66
74
  end
@@ -3,7 +3,7 @@ module Sorcery
3
3
  # Internal TestHelpers are used to test the gem, internally, and should not be used to test apps *using* sorcery.
4
4
  # This file will be included in the spec_helper file.
5
5
  module Internal
6
- def self.included(base)
6
+ def self.included(_base)
7
7
  # reducing default cost for specs speed
8
8
  CryptoProviders::BCrypt.class_eval do
9
9
  class << self
@@ -17,38 +17,38 @@ module Sorcery
17
17
  # a patch to fix a bug in testing that happens when you 'destroy' a session twice.
18
18
  # After the first destroy, the session is an ordinary hash, and then when destroy
19
19
  # is called again there's an exception.
20
- class ::Hash
20
+ class ::Hash # rubocop:disable Style/ClassAndModuleChildren
21
21
  def destroy
22
22
  clear
23
23
  end
24
24
  end
25
25
 
26
26
  def build_new_user(attributes_hash = nil)
27
- user_attributes_hash = attributes_hash || {:username => 'gizmo', :email => "bla@bla.com", :password => 'secret'}
27
+ user_attributes_hash = attributes_hash || { username: 'gizmo', email: 'bla@bla.com', password: 'secret' }
28
28
  @user = User.new(user_attributes_hash)
29
29
  end
30
30
 
31
31
  def create_new_user(attributes_hash = nil)
32
32
  @user = build_new_user(attributes_hash)
33
- @user.sorcery_adapter.save(:raise_on_failure => true)
33
+ @user.sorcery_adapter.save(raise_on_failure: true)
34
34
  @user
35
35
  end
36
36
 
37
37
  def create_new_external_user(provider, attributes_hash = nil)
38
- user_attributes_hash = attributes_hash || {:username => 'gizmo'}
38
+ user_attributes_hash = attributes_hash || { username: 'gizmo' }
39
39
  @user = User.new(user_attributes_hash)
40
- @user.sorcery_adapter.save(:raise_on_failure => true)
41
- @user.authentications.create!({:provider => provider, :uid => 123})
40
+ @user.sorcery_adapter.save(raise_on_failure: true)
41
+ @user.authentications.create!(provider: provider, uid: 123)
42
42
  @user
43
43
  end
44
44
 
45
45
  def custom_create_new_external_user(provider, authentication_class, attributes_hash = nil)
46
46
  authentication_association = authentication_class.name.underscore.pluralize
47
47
 
48
- user_attributes_hash = attributes_hash || {:username => 'gizmo'}
48
+ user_attributes_hash = attributes_hash || { username: 'gizmo' }
49
49
  @user = User.new(user_attributes_hash)
50
- @user.sorcery_adapter.save(:raise_on_failure => true)
51
- @user.send(authentication_association).create!({:provider => provider, :uid => 123})
50
+ @user.sorcery_adapter.save(raise_on_failure: true)
51
+ @user.send(authentication_association).create!(provider: provider, uid: 123)
52
52
  @user
53
53
  end
54
54
 
@@ -67,11 +67,12 @@ module Sorcery
67
67
  # reload user class between specs
68
68
  # so it will be possible to test the different submodules in isolation
69
69
  def reload_user_class
70
- Object.send(:remove_const, "User")
70
+ User && Object.send(:remove_const, 'User')
71
71
  load 'user.rb'
72
- if User.respond_to?(:reset_column_information)
73
- User.reset_column_information
74
- end
72
+
73
+ return unless User.respond_to?(:reset_column_information)
74
+
75
+ User.reset_column_information
75
76
  end
76
77
  end
77
78
  end
@@ -2,7 +2,7 @@ module Sorcery
2
2
  module TestHelpers
3
3
  module Rails
4
4
  module Controller
5
- def login_user(user = nil, test_context = {})
5
+ def login_user(user = nil, _test_context = {})
6
6
  user ||= @user
7
7
  @controller.send(:auto_login, user)
8
8
  @controller.send(:after_login!, user, [user.send(user.sorcery_config.username_attribute_names.first), 'secret'])
@@ -2,20 +2,19 @@ module Sorcery
2
2
  module TestHelpers
3
3
  module Rails
4
4
  module Integration
5
-
6
- #Accepts arguments for user to login, route to use and HTTP method
7
- #Defaults - @user, 'sessions_url' and POST
5
+ # Accepts arguments for user to login, route to use and HTTP method
6
+ # Defaults - @user, 'sessions_url' and POST
8
7
  def login_user(user = nil, route = nil, http_method = :post)
9
8
  user ||= @user
10
9
  route ||= sessions_url
11
10
 
12
11
  username_attr = user.sorcery_config.username_attribute_names.first
13
12
  username = user.send(username_attr)
14
- page.driver.send(http_method, route, { :"#{username_attr}" => username, :password => 'secret' })
13
+ page.driver.send(http_method, route, :"#{username_attr}" => username, :password => 'secret')
15
14
  end
16
15
 
17
- #Accepts route and HTTP method arguments
18
- #Default - 'logout_url' and GET
16
+ # Accepts route and HTTP method arguments
17
+ # Default - 'logout_url' and GET
19
18
  def logout_user(route = nil, http_method = :get)
20
19
  route ||= logout_url
21
20
  page.driver.send(http_method, route)
@@ -0,0 +1,20 @@
1
+ module Sorcery
2
+ module TestHelpers
3
+ module Rails
4
+ module Request
5
+ # Accepts arguments for user to login, the password, route to use and HTTP method
6
+ # Defaults - @user, 'secret', 'user_sessions_url' and http_method: POST
7
+ def login_user(user = nil, password = 'secret', route = nil, http_method = :post)
8
+ user ||= @user
9
+ route ||= user_sessions_url
10
+
11
+ username_attr = user.sorcery_config.username_attribute_names.first
12
+ username = user.send(username_attr)
13
+ password_attr = user.sorcery_config.password_attribute_name
14
+
15
+ send(http_method, route, params: { "#{username_attr}": username, "#{password_attr}": password })
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  module Sorcery
2
- VERSION = "0.9.1"
2
+ VERSION = '0.16.3'.freeze
3
3
  end
data/lib/sorcery.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  require 'sorcery/version'
2
2
 
3
3
  module Sorcery
4
-
5
4
  require 'sorcery/model'
6
5
 
7
6
  module Adapters
@@ -12,7 +11,6 @@ module Sorcery
12
11
  require 'sorcery/model/temporary_token'
13
12
  require 'sorcery/model/config'
14
13
 
15
-
16
14
  module Submodules
17
15
  require 'sorcery/model/submodules/user_activation'
18
16
  require 'sorcery/model/submodules/reset_password'
@@ -20,6 +18,7 @@ module Sorcery
20
18
  require 'sorcery/model/submodules/activity_logging'
21
19
  require 'sorcery/model/submodules/brute_force_protection'
22
20
  require 'sorcery/model/submodules/external'
21
+ require 'sorcery/model/submodules/magic_login'
23
22
  end
24
23
  end
25
24
 
@@ -58,17 +57,17 @@ module Sorcery
58
57
  module Rails
59
58
  require 'sorcery/test_helpers/rails/controller'
60
59
  require 'sorcery/test_helpers/rails/integration'
60
+ require 'sorcery/test_helpers/rails/request'
61
61
  end
62
62
 
63
63
  module Internal
64
64
  require 'sorcery/test_helpers/internal/rails'
65
65
  end
66
-
67
66
  end
68
67
 
69
68
  require 'sorcery/adapters/base_adapter'
70
69
 
71
- if defined?(ActiveRecord)
70
+ if defined?(ActiveRecord::Base)
72
71
  require 'sorcery/adapters/active_record_adapter'
73
72
  ActiveRecord::Base.extend Sorcery::Model
74
73
 
@@ -81,7 +80,7 @@ module Sorcery
81
80
  end
82
81
  end
83
82
 
84
- if defined?(Mongoid)
83
+ if defined?(Mongoid::Document)
85
84
  require 'sorcery/adapters/mongoid_adapter'
86
85
  Mongoid::Document::ClassMethods.send :include, Sorcery::Model
87
86
 
@@ -94,17 +93,5 @@ module Sorcery
94
93
  end
95
94
  end
96
95
 
97
- if defined?(MongoMapper)
98
- require 'sorcery/adapters/mongo_mapper_adapter'
99
- MongoMapper::Document.send(:plugin, Sorcery::Adapters::MongoMapperAdapter::Wrapper)
100
- end
101
-
102
- if defined?(DataMapper)
103
- require 'sorcery/adapters/data_mapper_adapter'
104
- DataMapper::Model.append_extensions(Sorcery::Model)
105
-
106
- DataMapper::Model.append_inclusions(Sorcery::Adapters::DataMapperAdapter::Wrapper)
107
- end
108
-
109
96
  require 'sorcery/engine' if defined?(Rails)
110
97
  end
data/sorcery.gemspec CHANGED
@@ -1,34 +1,49 @@
1
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
  require 'sorcery/version'
4
4
 
5
+ # rubocop:disable Metrics/BlockLength
5
6
  Gem::Specification.new do |s|
6
- s.name = "sorcery"
7
+ s.name = 'sorcery'
7
8
  s.version = Sorcery::VERSION
8
- s.authors = ["Noam Ben Ari", "Kir Shatrov", "Grzegorz Witek"]
9
- s.email = "nbenari@gmail.com"
10
- s.description = "Provides common authentication needs such as signing in/out, activating by email and resetting password."
11
- s.summary = "Magical authentication for Rails 3 & 4 applications"
12
- s.homepage = "http://github.com/NoamB/sorcery"
13
-
14
- s.files = `git ls-files`.split($/)
15
- s.require_paths = ["lib"]
16
-
17
- s.licenses = ["MIT"]
18
-
19
- s.required_ruby_version = '>= 1.9.3'
20
-
21
- s.add_dependency "oauth", "~> 0.4", ">= 0.4.4"
22
- s.add_dependency "oauth2", ">= 0.8.0"
23
- s.add_dependency "bcrypt", "~> 3.1"
24
-
25
- s.add_development_dependency "abstract", ">= 1.0.0"
26
- s.add_development_dependency "json", ">= 1.7.7"
27
- s.add_development_dependency "yard", "~> 0.6.0"
28
-
29
- s.add_development_dependency "timecop"
30
- s.add_development_dependency "simplecov", ">= 0.3.8"
31
- s.add_development_dependency "rspec", "~> 3.0.0"
32
- s.add_development_dependency "rspec-rails", "~> 3.0.0"
9
+ s.authors = [
10
+ 'Noam Ben Ari',
11
+ 'Kir Shatrov',
12
+ 'Grzegorz Witek',
13
+ 'Chase Gilliam',
14
+ 'Josh Buker'
15
+ ]
16
+ s.email = [
17
+ 'crypto@joshbuker.com'
18
+ ]
19
+
20
+ # TODO: Cleanup formatting.
21
+ # rubocop:disable Layout/LineLength
22
+ s.description = 'Provides common authentication needs such as signing in/out, activating by email and resetting password.'
23
+ s.summary = 'Magical authentication for Rails applications'
24
+ s.homepage = 'https://github.com/Sorcery/sorcery'
25
+ s.post_install_message = "As of version 1.0 oauth/oauth2 won't be automatically bundled so you may need to add those dependencies to your Gemfile.\n"
26
+ s.post_install_message += 'You may need oauth2 if you use external providers such as any of these: https://github.com/Sorcery/sorcery/tree/master/lib/sorcery/providers'
27
+ # rubocop:enable Layout/LineLength
28
+
29
+ s.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
30
+ s.require_paths = ['lib']
31
+
32
+ s.licenses = ['MIT']
33
+
34
+ s.required_ruby_version = '>= 2.4.9'
35
+
36
+ s.add_dependency 'bcrypt', '~> 3.1'
37
+ s.add_dependency 'oauth', '~> 0.5', '>= 0.5.5'
38
+ s.add_dependency 'oauth2', '~> 1.0', '>= 0.8.0'
39
+
40
+ s.add_development_dependency 'byebug', '~> 10.0.0'
41
+ s.add_development_dependency 'rspec-rails', '~> 3.7.0'
42
+ s.add_development_dependency 'rubocop'
43
+ s.add_development_dependency 'simplecov', '>= 0.3.8'
44
+ s.add_development_dependency 'test-unit', '~> 3.2.0'
45
+ s.add_development_dependency 'timecop'
46
+ s.add_development_dependency 'webmock', '~> 3.3.0'
47
+ s.add_development_dependency 'yard', '~> 0.9.0', '>= 0.9.12'
33
48
  end
34
-
49
+ # rubocop:enable Metrics/BlockLength
@@ -3,16 +3,15 @@ require 'spec_helper'
3
3
  require 'rails_app/app/mailers/sorcery_mailer'
4
4
  require 'shared_examples/user_activation_shared_examples'
5
5
 
6
- describe User, "with activation submodule", :active_record => true do
6
+ describe User, 'with activation submodule', active_record: true do
7
7
  before(:all) do
8
- ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activation")
8
+ MigrationHelper.migrate("#{Rails.root}/db/migrate/activation")
9
9
  User.reset_column_information
10
10
  end
11
11
 
12
12
  after(:all) do
13
- ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation")
13
+ MigrationHelper.rollback("#{Rails.root}/db/migrate/activation")
14
14
  end
15
15
 
16
- it_behaves_like "rails_3_activation_model"
17
-
16
+ it_behaves_like 'rails_3_activation_model'
18
17
  end
@@ -1,17 +1,15 @@
1
1
  require 'spec_helper'
2
2
  require 'shared_examples/user_activity_logging_shared_examples'
3
3
 
4
- describe User, "with activity logging submodule", :active_record => true do
5
-
4
+ describe User, 'with activity logging submodule', active_record: true do
6
5
  before(:all) do
7
- ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activity_logging")
6
+ MigrationHelper.migrate("#{Rails.root}/db/migrate/activity_logging")
8
7
  User.reset_column_information
9
8
  end
10
9
 
11
10
  after(:all) do
12
- ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activity_logging")
11
+ MigrationHelper.rollback("#{Rails.root}/db/migrate/activity_logging")
13
12
  end
14
13
 
15
- it_behaves_like "rails_3_activity_logging_model"
16
-
14
+ it_behaves_like 'rails_3_activity_logging_model'
17
15
  end
@@ -1,16 +1,15 @@
1
1
  require 'spec_helper'
2
2
  require 'shared_examples/user_brute_force_protection_shared_examples'
3
3
 
4
- describe User, "with brute_force_protection submodule", :active_record => true do
4
+ describe User, 'with brute_force_protection submodule', active_record: true do
5
5
  before(:all) do
6
- ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/brute_force_protection")
6
+ MigrationHelper.migrate("#{Rails.root}/db/migrate/brute_force_protection")
7
7
  User.reset_column_information
8
8
  end
9
9
 
10
10
  after(:all) do
11
- ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/brute_force_protection")
11
+ MigrationHelper.rollback("#{Rails.root}/db/migrate/brute_force_protection")
12
12
  end
13
13
 
14
- it_behaves_like "rails_3_brute_force_protection_model"
15
-
16
- end
14
+ it_behaves_like 'rails_3_brute_force_protection_model'
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+ require 'shared_examples/user_magic_login_shared_examples'
3
+
4
+ describe User, 'with magic_login submodule', active_record: true do
5
+ before(:all) do
6
+ MigrationHelper.migrate("#{Rails.root}/db/migrate/magic_login")
7
+ User.reset_column_information
8
+ end
9
+
10
+ after(:all) do
11
+ MigrationHelper.rollback("#{Rails.root}/db/migrate/magic_login")
12
+ end
13
+
14
+ it_behaves_like 'magic_login_model'
15
+ end
@@ -1,16 +1,15 @@
1
1
  require 'spec_helper'
2
2
  require 'shared_examples/user_oauth_shared_examples'
3
3
 
4
- describe User, "with oauth submodule", :active_record => true do
4
+ describe User, 'with oauth submodule', active_record: true do
5
5
  before(:all) do
6
- ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/external")
6
+ MigrationHelper.migrate("#{Rails.root}/db/migrate/external")
7
7
  User.reset_column_information
8
8
  end
9
9
 
10
10
  after(:all) do
11
- ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/external")
11
+ MigrationHelper.rollback("#{Rails.root}/db/migrate/external")
12
12
  end
13
13
 
14
- it_behaves_like "rails_3_oauth_model"
15
-
16
- end
14
+ it_behaves_like 'rails_3_oauth_model'
15
+ end
@@ -1,16 +1,15 @@
1
1
  require 'spec_helper'
2
2
  require 'shared_examples/user_remember_me_shared_examples'
3
3
 
4
- describe User, "with remember_me submodule", :active_record => true do
4
+ describe User, 'with remember_me submodule', active_record: true do
5
5
  before(:all) do
6
- ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/remember_me")
6
+ MigrationHelper.migrate("#{Rails.root}/db/migrate/remember_me")
7
7
  User.reset_column_information
8
8
  end
9
9
 
10
10
  after(:all) do
11
- ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/remember_me")
11
+ MigrationHelper.rollback("#{Rails.root}/db/migrate/remember_me")
12
12
  end
13
13
 
14
- it_behaves_like "rails_3_remember_me_model"
15
-
16
- end
14
+ it_behaves_like 'rails_3_remember_me_model'
15
+ end
@@ -1,16 +1,15 @@
1
1
  require 'spec_helper'
2
2
  require 'shared_examples/user_reset_password_shared_examples'
3
3
 
4
- describe User, "with reset_password submodule", :active_record => true do
4
+ describe User, 'with reset_password submodule', active_record: true do
5
5
  before(:all) do
6
- ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/reset_password")
6
+ MigrationHelper.migrate("#{Rails.root}/db/migrate/reset_password")
7
7
  User.reset_column_information
8
8
  end
9
9
 
10
10
  after(:all) do
11
- ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/reset_password")
11
+ MigrationHelper.rollback("#{Rails.root}/db/migrate/reset_password")
12
12
  end
13
13
 
14
- it_behaves_like "rails_3_reset_password_model"
15
-
14
+ it_behaves_like 'rails_3_reset_password_model'
16
15
  end