sorcery 0.14.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bfe20ba10b3d52ae3bd1c37f487d5a3e42da98387127033d26978831f523e4a1
4
- data.tar.gz: 5a3f0f7279d060ce1515e8635d9f87c5c52a840d6c15916e064171714b1d26a5
3
+ metadata.gz: 2eacf343e86db96ee2b99e31a647efbdca41cc859dd3aaa5d5300fcf80cb2f6f
4
+ data.tar.gz: 0ab8e2eb73204b108e52ec39c4622e654cf48fa2ec75159bd5a3686a2855156e
5
5
  SHA512:
6
- metadata.gz: a1ff57ddfbfebe031dab7bc2d21bab6a045d48cc03f9b5b1cc50786ce6eb541a89e799d8dc6d68cf4b9995aa89409f101166cc8f0c8aa17056daad4af6bba502
7
- data.tar.gz: 8d3eae6eb8a66f9e93ae312f4e9300587bdea66e6800b3608bcfe87e5c2f437e2af85ccc865575471f27c011a7ba947f80836f880bf00d21229bbb6ccdc3e42f
6
+ metadata.gz: f4d4e09af8fd96f8c4a025a50c7d9d539ae584fac256f443a488063a91acffe2e1539a0a89b7aa4323116fdc6b9a6bb4e881072d91113e5f98be697e2296005b
7
+ data.tar.gz: b61da2da586d75af4f1f4df8046accfc7928428005ba3101e6c59fb30421c27b7e358b8b37f6e702c839a2002987e5b43af8c8de7adfd91e70ee8c749ebabf3d
@@ -3,7 +3,7 @@ inherit_from: .rubocop_todo.yml
3
3
  AllCops:
4
4
  Exclude:
5
5
  - 'lib/generators/sorcery/templates/**/*'
6
- TargetRubyVersion: 2.2
6
+ TargetRubyVersion: 2.6
7
7
 
8
8
  # See: https://github.com/rubocop-hq/rubocop/issues/3344
9
9
  Style/DoubleNegation:
@@ -21,7 +21,7 @@ Metrics/BlockLength:
21
21
  Exclude:
22
22
  - 'lib/**/*'
23
23
  - 'spec/**/*'
24
- Metrics/LineLength:
24
+ Layout/LineLength:
25
25
  Exclude:
26
26
  - 'lib/**/*'
27
27
  - 'spec/**/*'
@@ -1,7 +1,145 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2018-11-01 18:13:47 -0700 using RuboCop version 0.59.2.
3
+ # on 2019-12-18 16:18:24 -0800 using RuboCop version 0.78.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ # Configuration parameters: Include.
11
+ # Include: **/*.gemspec
12
+ Gemspec/RequiredRubyVersion:
13
+ Exclude:
14
+ - 'sorcery.gemspec'
15
+
16
+ # Offense count: 1
17
+ # Cop supports --auto-correct.
18
+ # Configuration parameters: AllowAdjacentOneLineDefs, NumberOfEmptyLines.
19
+ Layout/EmptyLineBetweenDefs:
20
+ Exclude:
21
+ - 'lib/sorcery/providers/line.rb'
22
+
23
+ # Offense count: 83
24
+ # Cop supports --auto-correct.
25
+ # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
26
+ # SupportedHashRocketStyles: key, separator, table
27
+ # SupportedColonStyles: key, separator, table
28
+ # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
29
+ Layout/HashAlignment:
30
+ Enabled: false
31
+
32
+ # Offense count: 2
33
+ # Configuration parameters: AllowSafeAssignment.
34
+ Lint/AssignmentInCondition:
35
+ Exclude:
36
+ - 'spec/rails_app/app/controllers/sorcery_controller.rb'
37
+
38
+ # Offense count: 1
39
+ # Cop supports --auto-correct.
40
+ Lint/NonDeterministicRequireOrder:
41
+ Exclude:
42
+ - 'spec/spec_helper.rb'
43
+
44
+ # Offense count: 4
45
+ # Cop supports --auto-correct.
46
+ Lint/RedundantCopDisableDirective:
47
+ Exclude:
48
+ - 'lib/sorcery/controller.rb'
49
+ - 'lib/sorcery/model.rb'
50
+ - 'spec/rails_app/config/application.rb'
51
+ - 'spec/shared_examples/user_shared_examples.rb'
52
+
53
+ # Offense count: 4
54
+ # Cop supports --auto-correct.
55
+ Lint/SendWithMixinArgument:
56
+ Exclude:
57
+ - 'lib/sorcery.rb'
58
+ - 'lib/sorcery/engine.rb'
59
+ - 'lib/sorcery/test_helpers/internal/rails.rb'
60
+
61
+ # Offense count: 4
62
+ # Configuration parameters: AllowComments.
63
+ Lint/SuppressedException:
64
+ Exclude:
65
+ - 'lib/sorcery/controller.rb'
66
+ - 'lib/sorcery/model.rb'
67
+ - 'spec/rails_app/config/application.rb'
68
+ - 'spec/shared_examples/user_shared_examples.rb'
69
+
70
+ # Offense count: 2
71
+ # Cop supports --auto-correct.
72
+ # Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
73
+ Lint/UnusedBlockArgument:
74
+ Exclude:
75
+ - 'spec/shared_examples/user_shared_examples.rb'
76
+
77
+ # Offense count: 1
78
+ # Configuration parameters: EnforcedStyle.
79
+ # SupportedStyles: annotated, template, unannotated
80
+ Style/FormatStringToken:
81
+ Exclude:
82
+ - 'lib/generators/sorcery/install_generator.rb'
83
+
84
+ # Offense count: 121
85
+ # Cop supports --auto-correct.
86
+ # Configuration parameters: EnforcedStyle.
87
+ # SupportedStyles: always, never
88
+ Style/FrozenStringLiteralComment:
89
+ Enabled: false
90
+
91
+ # Offense count: 3
92
+ # Configuration parameters: MinBodyLength.
93
+ Style/GuardClause:
94
+ Exclude:
95
+ - 'lib/sorcery/controller/submodules/brute_force_protection.rb'
96
+ - 'lib/sorcery/controller/submodules/http_basic_auth.rb'
97
+ - 'lib/sorcery/controller/submodules/remember_me.rb'
98
+
99
+ # Offense count: 3
100
+ # Cop supports --auto-correct.
101
+ # Configuration parameters: EnforcedStyle, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
102
+ # SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
103
+ Style/HashSyntax:
104
+ Exclude:
105
+ - 'lib/sorcery/adapters/active_record_adapter.rb'
106
+ - 'lib/sorcery/test_helpers/rails/integration.rb'
107
+
108
+ # Offense count: 49
109
+ # Cop supports --auto-correct.
110
+ Style/IfUnlessModifier:
111
+ Enabled: false
112
+
113
+ # Offense count: 2
114
+ # Cop supports --auto-correct.
115
+ Style/RedundantBegin:
116
+ Exclude:
117
+ - 'lib/sorcery/controller.rb'
118
+ - 'lib/sorcery/model.rb'
119
+
120
+ # Offense count: 4
121
+ # Cop supports --auto-correct.
122
+ # Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods.
123
+ # AllowedMethods: present?, blank?, presence, try, try!
124
+ Style/SafeNavigation:
125
+ Exclude:
126
+ - 'lib/sorcery/controller/config.rb'
127
+ - 'lib/sorcery/controller/submodules/brute_force_protection.rb'
128
+ - 'lib/sorcery/controller/submodules/remember_me.rb'
129
+ - 'lib/sorcery/model.rb'
130
+
131
+ # Offense count: 7
132
+ # Cop supports --auto-correct.
133
+ # Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
134
+ # SupportedStyles: single_quotes, double_quotes
135
+ Style/StringLiterals:
136
+ Exclude:
137
+ - 'spec/controllers/controller_oauth2_spec.rb'
138
+ - 'spec/sorcery_crypto_providers_spec.rb'
139
+
140
+ # Offense count: 2
141
+ # Cop supports --auto-correct.
142
+ Style/UnpackFirst:
143
+ Exclude:
144
+ - 'lib/sorcery/crypto_providers/aes256.rb'
145
+ - 'spec/sorcery_crypto_providers_spec.rb'
@@ -1,12 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.9
4
- - 2.3.6
5
- - 2.4.3
6
- - 2.5.0
3
+ - 2.4.9
4
+ - 2.5.7
5
+ - 2.6.5
7
6
 
8
7
  gemfile:
9
8
  - Gemfile
10
-
11
- before_script:
12
- - mysql -e 'create database sorcery_test;'
@@ -1,6 +1,23 @@
1
1
  # Changelog
2
2
  ## HEAD
3
3
 
4
+ ## 0.15.0
5
+
6
+ * Fix brute force vuln due to callbacks no being ran [#235](https://github.com/Sorcery/sorcery/pull/235)
7
+ * Revert on_load change due to breaking existing applications [#234](https://github.com/Sorcery/sorcery/pull/234)
8
+ * Add forget_me! and force_forget_me! test cases [#216](https://github.com/Sorcery/sorcery/pull/216)
9
+ * In `generic_send_email`, check responds_to [#211](https://github.com/Sorcery/sorcery/pull/211)
10
+ * Fix typo [#219](https://github.com/Sorcery/sorcery/pull/219)
11
+ * Fix deprecation warnings in Rails 6 [#209](https://github.com/Sorcery/sorcery/pull/209)
12
+ * Add ruby 2.6.5 to the travis build [#215](https://github.com/Sorcery/sorcery/pull/215)
13
+ * Add discord provider [#185](https://github.com/Sorcery/sorcery/pull/185)
14
+ * Remove MySQL database creation call [#214](https://github.com/Sorcery/sorcery/pull/214)
15
+ * Use id instead of uid for VK provider [#199](https://github.com/Sorcery/sorcery/pull/199)
16
+ * Don't :return_t JSON requests after login [#197](https://github.com/Sorcery/sorcery/pull/197)
17
+ * Fix email scope for LinkedIn Provider [#191](https://github.com/Sorcery/sorcery/pull/191)
18
+ * Ignore cookies when undefined cookies [#187](https://github.com/Sorcery/sorcery/pull/187)
19
+ * Allow for custom providers with multi-word class names. [#190](https://github.com/Sorcery/sorcery/pull/190)
20
+
4
21
  ## 0.14.0
5
22
 
6
23
  * Update LinkedIn to use OAuth 2 [#189](https://github.com/Sorcery/sorcery/pull/189)
@@ -88,11 +88,19 @@ Rails.application.config.sorcery.configure do |config|
88
88
  #
89
89
  # config.ca_file =
90
90
 
91
+ # Linkedin requires r_emailaddress scope to fetch user's email address.
92
+ # You can skip including the email field if you use an intermediary signup form. (using build_from method).
93
+ # The r_emailaddress scope is only necessary if you are using the create_from method directly.
94
+ #
91
95
  # config.linkedin.key = ""
92
96
  # config.linkedin.secret = ""
93
97
  # config.linkedin.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=linkedin"
94
- # config.linkedin.user_info_mapping = {first_name: "firstName", last_name: "lastName"}
95
- # config.linkedin.scope = "r_basicprofile"
98
+ # config.linkedin.user_info_mapping = {
99
+ # first_name: 'localizedFirstName',
100
+ # last_name: 'localizedLastName',
101
+ # email: 'emailAddress'
102
+ # }
103
+ # config.linkedin.scope = "r_liteprofile r_emailaddress"
96
104
  #
97
105
  #
98
106
  # For information about XING API:
@@ -215,6 +223,12 @@ Rails.application.config.sorcery.configure do |config|
215
223
  # config.line.secret = ""
216
224
  # config.line.callback_url = "http://mydomain.com:3000/oauth/callback?provider=line"
217
225
 
226
+ # For infromation about Discord API
227
+ # https://discordapp.com/developers/docs/topics/oauth2
228
+ # config.discord.key = "xxxxxx"
229
+ # config.discord.secret = "xxxxxx"
230
+ # config.discord.callback_url = "http://localhost:3000/oauth/callback?provider=discord"
231
+ # config.discord.scope = "email guilds"
218
232
  # --- user config ---
219
233
  config.user_config do |user|
220
234
  # -- core --
@@ -25,7 +25,10 @@ module Sorcery
25
25
  def require_login
26
26
  return if logged_in?
27
27
 
28
- session[:return_to_url] = request.url if Config.save_return_to_url && request.get? && !request.xhr?
28
+ if Config.save_return_to_url && request.get? && !request.xhr? && !request.format.json?
29
+ session[:return_to_url] = request.url
30
+ end
31
+
29
32
  send(Config.not_authenticated_action)
30
33
  end
31
34
 
@@ -26,6 +26,7 @@ module Sorcery
26
26
  require 'sorcery/providers/instagram'
27
27
  require 'sorcery/providers/auth0'
28
28
  require 'sorcery/providers/line'
29
+ require 'sorcery/providers/discord'
29
30
 
30
31
  Config.module_eval do
31
32
  class << self
@@ -38,7 +39,7 @@ module Sorcery
38
39
  providers.each do |name|
39
40
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
40
41
  def self.#{name}
41
- @#{name} ||= Sorcery::Providers.const_get('#{name}'.to_s.capitalize).new
42
+ @#{name} ||= Sorcery::Providers.const_get('#{name}'.to_s.classify).new
42
43
  end
43
44
  RUBY
44
45
  end
@@ -59,7 +59,7 @@ module Sorcery
59
59
  # and logs the user in if found.
60
60
  # Runs as a login source. See 'current_user' method for how it is used.
61
61
  def login_from_cookie
62
- user = cookies.signed[:remember_me_token] && user_class.sorcery_adapter.find_by_remember_me_token(cookies.signed[:remember_me_token])
62
+ user = cookies.signed[:remember_me_token] && user_class.sorcery_adapter.find_by_remember_me_token(cookies.signed[:remember_me_token]) if defined? cookies
63
63
  if user && user.has_remember_me_token?
64
64
  set_remember_me_cookie!(user)
65
65
  session[:user_id] = user.id.to_s
@@ -7,12 +7,18 @@ module Sorcery
7
7
  class Engine < Rails::Engine
8
8
  config.sorcery = ::Sorcery::Controller::Config
9
9
 
10
+ # TODO: Should this include a modified version of the helper methods?
10
11
  initializer 'extend Controller with sorcery' do
11
- # TODO: Should this include a modified version of the helper methods?
12
+ # FIXME: on_load is needed to fix Rails 6 deprecations, but it breaks
13
+ # applications due to undefined method errors.
14
+ # ActiveSupport.on_load(:action_controller_api) do
12
15
  if defined?(ActionController::API)
13
16
  ActionController::API.send(:include, Sorcery::Controller)
14
17
  end
15
18
 
19
+ # FIXME: on_load is needed to fix Rails 6 deprecations, but it breaks
20
+ # applications due to undefined method errors.
21
+ # ActiveSupport.on_load(:action_controller_base) do
16
22
  if defined?(ActionController::Base)
17
23
  ActionController::Base.send(:include, Sorcery::Controller)
18
24
  ActionController::Base.helper_method :current_user
@@ -102,10 +102,6 @@ module Sorcery
102
102
 
103
103
  set_encryption_attributes
104
104
 
105
- unless user.valid_password?(credentials[1])
106
- return authentication_response(user: user, failure: :invalid_password, &block)
107
- end
108
-
109
105
  if user.respond_to?(:active_for_authentication?) && !user.active_for_authentication?
110
106
  return authentication_response(user: user, failure: :inactive, &block)
111
107
  end
@@ -118,6 +114,10 @@ module Sorcery
118
114
  end
119
115
  end
120
116
 
117
+ unless user.valid_password?(credentials[1])
118
+ return authentication_response(user: user, failure: :invalid_password, &block)
119
+ end
120
+
121
121
  authentication_response(user: user, return_value: user, &block)
122
122
  end
123
123
 
@@ -206,7 +206,7 @@ module Sorcery
206
206
  def generic_send_email(method, mailer)
207
207
  config = sorcery_config
208
208
  mail = config.send(mailer).send(config.send(method), self)
209
- return unless defined?(ActionMailer) && config.send(mailer).is_a?(Class) && config.send(mailer) < ActionMailer::Base
209
+ return unless mail.respond_to?(config.email_delivery_method)
210
210
 
211
211
  mail.send(config.email_delivery_method)
212
212
  end
@@ -0,0 +1,52 @@
1
+ module Sorcery
2
+ module Providers
3
+ # This class adds support for OAuth with discordapp.com
4
+
5
+ class Discord < Base
6
+ include Protocols::Oauth2
7
+
8
+ attr_accessor :auth_path, :scope, :token_url, :user_info_path
9
+
10
+ def initialize
11
+ super
12
+
13
+ @scope = 'identify'
14
+ @site = 'https://discordapp.com/'
15
+ @auth_path = '/api/oauth2/authorize'
16
+ @token_url = '/api/oauth2/token'
17
+ @user_info_path = '/api/users/@me'
18
+ @state = SecureRandom.hex(16)
19
+ end
20
+
21
+ def get_user_hash(access_token)
22
+ response = access_token.get(user_info_path)
23
+ body = JSON.parse(response.body)
24
+ auth_hash(access_token).tap do |h|
25
+ h[:user_info] = body
26
+ h[:uid] = body['id']
27
+ end
28
+ end
29
+
30
+ # calculates and returns the url to which the user should be redirected,
31
+ # to get authenticated at the external provider's site.
32
+ def login_url(_params, _session)
33
+ authorize_url(authorize_url: auth_path)
34
+ end
35
+
36
+ # tries to login the user from access token
37
+ def process_callback(params, _session)
38
+ args = {}.tap do |a|
39
+ a[:code] = params[:code] if params[:code]
40
+ end
41
+ get_access_token(
42
+ args,
43
+ token_url: token_url,
44
+ client_id: @key,
45
+ client_secret: @secret,
46
+ grant_type: 'authorization_code',
47
+ token_method: :post
48
+ )
49
+ end
50
+ end
51
+ end
52
+ end
@@ -9,25 +9,26 @@ module Sorcery
9
9
  class Linkedin < Base
10
10
  include Protocols::Oauth2
11
11
 
12
- attr_accessor :auth_url, :scope, :token_url, :user_info_url
12
+ attr_accessor :auth_url, :scope, :token_url, :user_info_url, :email_info_url
13
13
 
14
14
  def initialize
15
15
  super
16
16
 
17
- @site = 'https://api.linkedin.com'
18
- @auth_url = '/oauth/v2/authorization'
19
- @token_url = '/oauth/v2/accessToken'
20
- @user_info_url = 'https://api.linkedin.com/v2/me'
21
- @scope = 'r_liteprofile'
22
- @state = SecureRandom.hex(16)
17
+ @site = 'https://api.linkedin.com'
18
+ @auth_url = '/oauth/v2/authorization'
19
+ @token_url = '/oauth/v2/accessToken'
20
+ @user_info_url = 'https://api.linkedin.com/v2/me'
21
+ @email_info_url = 'https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))'
22
+ @scope = 'r_liteprofile r_emailaddress'
23
+ @state = SecureRandom.hex(16)
23
24
  end
24
25
 
25
26
  def get_user_hash(access_token)
26
- response = access_token.get(user_info_url)
27
+ user_info = get_user_info(access_token)
27
28
 
28
29
  auth_hash(access_token).tap do |h|
29
- h[:user_info] = JSON.parse(response.body)
30
- h[:uid] = h[:user_info]['id']
30
+ h[:user_info] = user_info
31
+ h[:uid] = h[:user_info]['id']
31
32
  end
32
33
  end
33
34
 
@@ -45,6 +46,30 @@ module Sorcery
45
46
 
46
47
  get_access_token(args, token_url: token_url, token_method: :post)
47
48
  end
49
+
50
+ def get_user_info(access_token)
51
+ response = access_token.get(user_info_url)
52
+ user_info = JSON.parse(response.body)
53
+
54
+ if email_in_scope?
55
+ email = fetch_email(access_token)
56
+
57
+ return user_info.merge(email)
58
+ end
59
+
60
+ user_info
61
+ end
62
+
63
+ def email_in_scope?
64
+ scope.include?('r_emailaddress')
65
+ end
66
+
67
+ def fetch_email(access_token)
68
+ email_response = access_token.get(email_info_url)
69
+ email_info = JSON.parse(email_response.body)['elements'].first
70
+
71
+ email_info['handle~']
72
+ end
48
73
  end
49
74
  end
50
75
  end
@@ -37,7 +37,7 @@ module Sorcery
37
37
  user_hash[:user_info] = user_hash[:user_info]['response'][0]
38
38
  user_hash[:user_info]['full_name'] = [user_hash[:user_info]['first_name'], user_hash[:user_info]['last_name']].join(' ')
39
39
 
40
- user_hash[:uid] = user_hash[:user_info]['uid']
40
+ user_hash[:uid] = user_hash[:user_info]['id']
41
41
  user_hash[:user_info]['email'] = access_token.params['email']
42
42
  end
43
43
  user_hash
@@ -1,3 +1,3 @@
1
1
  module Sorcery
2
- VERSION = '0.14.0'.freeze
2
+ VERSION = '0.15.0'.freeze
3
3
  end
@@ -19,20 +19,20 @@ Gem::Specification.new do |s|
19
19
  ]
20
20
 
21
21
  # TODO: Cleanup formatting.
22
- # rubocop:disable Metrics/LineLength
22
+ # rubocop:disable Layout/LineLength
23
23
  s.description = 'Provides common authentication needs such as signing in/out, activating by email and resetting password.'
24
24
  s.summary = 'Magical authentication for Rails applications'
25
25
  s.homepage = 'https://github.com/Sorcery/sorcery'
26
26
  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"
27
27
  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'
28
- # rubocop:enable Metrics/LineLength
28
+ # rubocop:enable Layout/LineLength
29
29
 
30
30
  s.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
31
31
  s.require_paths = ['lib']
32
32
 
33
33
  s.licenses = ['MIT']
34
34
 
35
- s.required_ruby_version = '>= 2.2.9'
35
+ s.required_ruby_version = '>= 2.4.9'
36
36
 
37
37
  s.add_dependency 'bcrypt', '~> 3.1'
38
38
  s.add_dependency 'oauth', '~> 0.4', '>= 0.4.4'
@@ -155,7 +155,7 @@ describe SorceryController, active_record: true, type: :controller do
155
155
  expect(flash[:notice]).to eq 'Success!'
156
156
  end
157
157
 
158
- %i[github google liveid vk salesforce paypal slack wechat microsoft instagram auth0].each do |provider|
158
+ %i[github google liveid vk salesforce paypal slack wechat microsoft instagram auth0 discord].each do |provider|
159
159
  describe "with #{provider}" do
160
160
  it 'login_at redirects correctly' do
161
161
  get :"login_at_test_#{provider}"
@@ -217,6 +217,7 @@ describe SorceryController, active_record: true, type: :controller do
217
217
  instagram
218
218
  auth0
219
219
  line
220
+ discord
220
221
  ]
221
222
  )
222
223
 
@@ -261,6 +262,9 @@ describe SorceryController, active_record: true, type: :controller do
261
262
  sorcery_controller_external_property_set(:line, :key, "eYVNBjBDi33aa9GkA3w")
262
263
  sorcery_controller_external_property_set(:line, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
263
264
  sorcery_controller_external_property_set(:line, :callback_url, "http://blabla.com")
265
+ sorcery_controller_external_property_set(:discord, :key, 'eYVNBjBDi33aa9GkA3w')
266
+ sorcery_controller_external_property_set(:discord, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8')
267
+ sorcery_controller_external_property_set(:discord, :callback_url, 'http://blabla.com')
264
268
  end
265
269
 
266
270
  after(:each) do
@@ -283,7 +287,7 @@ describe SorceryController, active_record: true, type: :controller do
283
287
  expect(ActionMailer::Base.deliveries.size).to eq old_size
284
288
  end
285
289
 
286
- %i[github google liveid vk salesforce paypal wechat microsoft instagram auth0].each do |provider|
290
+ %i[github google liveid vk salesforce paypal wechat microsoft instagram auth0 discord].each do |provider|
287
291
  it "does not send activation email to external users (#{provider})" do
288
292
  old_size = ActionMailer::Base.deliveries.size
289
293
  create_new_external_user provider
@@ -307,7 +311,7 @@ describe SorceryController, active_record: true, type: :controller do
307
311
  sorcery_reload!(%i[activity_logging external])
308
312
  end
309
313
 
310
- %w[facebook github google liveid vk salesforce slack].each do |provider|
314
+ %w[facebook github google liveid vk salesforce slack discord].each do |provider|
311
315
  context "when #{provider}" do
312
316
  before(:each) do
313
317
  sorcery_controller_property_set(:register_login_time, true)
@@ -346,7 +350,7 @@ describe SorceryController, active_record: true, type: :controller do
346
350
 
347
351
  let(:user) { double('user', id: 42) }
348
352
 
349
- %w[facebook github google liveid vk salesforce slack].each do |provider|
353
+ %w[facebook github google liveid vk salesforce slack discord].each do |provider|
350
354
  context "when #{provider}" do
351
355
  before(:each) do
352
356
  sorcery_model_property_set(:authentications_class, Authentication)
@@ -427,7 +431,7 @@ describe SorceryController, active_record: true, type: :controller do
427
431
  # response for VK auth
428
432
  'response' => [
429
433
  {
430
- 'uid' => '123',
434
+ 'id' => '123',
431
435
  'first_name' => 'Noam',
432
436
  'last_name' => 'Ben Ari'
433
437
  }
@@ -479,6 +483,7 @@ describe SorceryController, active_record: true, type: :controller do
479
483
  instagram
480
484
  auth0
481
485
  line
486
+ discord
482
487
  ]
483
488
  )
484
489
  sorcery_controller_external_property_set(:facebook, :key, 'eYVNBjBDi33aa9GkA3w')
@@ -521,6 +526,9 @@ describe SorceryController, active_record: true, type: :controller do
521
526
  sorcery_controller_external_property_set(:line, :key, "eYVNBjBDi33aa9GkA3w")
522
527
  sorcery_controller_external_property_set(:line, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
523
528
  sorcery_controller_external_property_set(:line, :callback_url, "http://blabla.com")
529
+ sorcery_controller_external_property_set(:discord, :key, 'eYVNBjBDi33aa9GkA3w')
530
+ sorcery_controller_external_property_set(:discord, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8')
531
+ sorcery_controller_external_property_set(:discord, :callback_url, 'http://blabla.com')
524
532
  end
525
533
 
526
534
  def provider_url(provider)
@@ -535,7 +543,8 @@ describe SorceryController, active_record: true, type: :controller do
535
543
  wechat: "https://open.weixin.qq.com/connect/qrconnect?appid=#{::Sorcery::Controller::Config.wechat.key}&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=snsapi_login&state=#wechat_redirect",
536
544
  microsoft: "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=#{::Sorcery::Controller::Config.microsoft.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=openid+email+https%3A%2F%2Fgraph.microsoft.com%2FUser.Read&state",
537
545
  instagram: "https://api.instagram.com/oauth/authorize?client_id=#{::Sorcery::Controller::Config.instagram.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=#{::Sorcery::Controller::Config.instagram.scope}&state",
538
- auth0: "https://sorcery-test.auth0.com/authorize?client_id=#{::Sorcery::Controller::Config.auth0.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=openid+profile+email&state"
546
+ auth0: "https://sorcery-test.auth0.com/authorize?client_id=#{::Sorcery::Controller::Config.auth0.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=openid+profile+email&state",
547
+ discord: "https://discordapp.com/api/oauth2/authorize?client_id=#{::Sorcery::Controller::Config.discord.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=identify&state"
539
548
  }[provider]
540
549
  end
541
550
  end
@@ -6,14 +6,19 @@ describe SorceryController, type: :controller do
6
6
  # ----------------- REMEMBER ME -----------------------
7
7
  context 'with remember me features' do
8
8
  before(:all) do
9
+ if SORCERY_ORM == :active_record
10
+ MigrationHelper.migrate("#{Rails.root}/db/migrate/remember_me")
11
+ User.reset_column_information
12
+ end
13
+
9
14
  sorcery_reload!([:remember_me])
10
15
  end
11
16
 
12
- # TODO: Unused, remove?
13
- # after(:each) do
14
- # session = nil
15
- # cookies = nil
16
- # end
17
+ after(:all) do
18
+ if SORCERY_ORM == :active_record
19
+ MigrationHelper.rollback("#{Rails.root}/db/migrate/remember_me")
20
+ end
21
+ end
17
22
 
18
23
  before(:each) do
19
24
  allow(user).to receive(:remember_me_token)
@@ -32,19 +37,17 @@ describe SorceryController, type: :controller do
32
37
  end
33
38
 
34
39
  it 'clears cookie on forget_me!' do
35
- cookies['remember_me_token'] = { value: 'asd54234dsfsd43534', expires: 3600 }
36
- get :test_logout
40
+ request.cookies[:remember_me_token] = { value: 'asd54234dsfsd43534', expires: 3600 }
41
+ get :test_logout_with_forget_me
37
42
 
38
- pending 'Test previously broken, functionality might not be working here.'
39
- expect(cookies['remember_me_token']).to be_nil
43
+ expect(response.cookies[:remember_me_token]).to be_nil
40
44
  end
41
45
 
42
46
  it 'clears cookie on force_forget_me!' do
43
- cookies['remember_me_token'] = { value: 'asd54234dsfsd43534', expires: 3600 }
47
+ request.cookies[:remember_me_token] = { value: 'asd54234dsfsd43534', expires: 3600 }
44
48
  get :test_logout_with_force_forget_me
45
49
 
46
- pending 'Test previously broken, functionality might not be working here.'
47
- expect(cookies['remember_me_token']).to be_nil
50
+ expect(response.cookies[:remember_me_token]).to be_nil
48
51
  end
49
52
 
50
53
  it 'login(email,password,remember_me) logs user in and remembers' do
@@ -150,6 +150,16 @@ describe SorceryController, type: :controller do
150
150
  end
151
151
  end
152
152
 
153
+ it 'require_login before_action does not save the url for JSON requests' do
154
+ get :some_action, format: :json
155
+ expect(session[:return_to_url]).to be_nil
156
+ end
157
+
158
+ it 'require_login before_action does not save the url for XHR requests' do
159
+ get :some_action, xhr: true
160
+ expect(session[:return_to_url]).to be_nil
161
+ end
162
+
153
163
  it 'on successful login the user is redirected to the url he originally wanted' do
154
164
  session[:return_to_url] = 'http://test.host/some_action'
155
165
  post :test_return_to, params: { email: 'bla@bla.com', password: 'secret' }
@@ -161,7 +171,7 @@ describe SorceryController, type: :controller do
161
171
  # --- auto_login(user) ---
162
172
  specify { should respond_to(:auto_login) }
163
173
 
164
- it 'auto_login(user) los in a user instance' do
174
+ it 'auto_login(user) logs in a user instance' do
165
175
  session[:user_id] = nil
166
176
  subject.auto_login(user)
167
177
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'sorcery/providers/base'
5
+
6
+ describe Sorcery::Providers::ExampleProvider do
7
+ before(:all) do
8
+ sorcery_reload!([:external])
9
+ sorcery_controller_property_set(:external_providers, [:example_provider])
10
+ end
11
+
12
+ context 'fetching a multi-word custom provider' do
13
+ it 'returns the provider' do
14
+ expect(Sorcery::Controller::Config.example_provider).to be_a(Sorcery::Providers::ExampleProvider)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'sorcery/providers/base'
5
+
6
+ describe Sorcery::Providers::Example do
7
+ before(:all) do
8
+ sorcery_reload!([:external])
9
+ sorcery_controller_property_set(:external_providers, [:example])
10
+ end
11
+
12
+ context 'fetching a single-word custom provider' do
13
+ it 'returns the provider' do
14
+ expect(Sorcery::Controller::Config.example).to be_a(Sorcery::Providers::Example)
15
+ end
16
+ end
17
+ end
@@ -6,6 +6,7 @@ class SorceryController < ActionController::Base
6
6
  before_action :require_login_from_http_basic, only: [:test_http_basic_auth]
7
7
  before_action :require_login, only: %i[
8
8
  test_logout
9
+ test_logout_with_forget_me
9
10
  test_logout_with_force_forget_me
10
11
  test_should_be_logged_in
11
12
  some_action
@@ -50,6 +51,13 @@ class SorceryController < ActionController::Base
50
51
  head :ok
51
52
  end
52
53
 
54
+ def test_logout_with_forget_me
55
+ remember_me!
56
+ forget_me!
57
+ logout
58
+ head :ok
59
+ end
60
+
53
61
  def test_logout_with_force_forget_me
54
62
  remember_me!
55
63
  force_forget_me!
@@ -158,6 +166,10 @@ class SorceryController < ActionController::Base
158
166
  login_at(:auth0)
159
167
  end
160
168
 
169
+ def login_at_test_discord
170
+ login_at(:discord)
171
+ end
172
+
161
173
  def test_login_from_twitter
162
174
  if (@user = login_from(:twitter))
163
175
  redirect_to 'bla', notice: 'Success!'
@@ -280,6 +292,14 @@ class SorceryController < ActionController::Base
280
292
  end
281
293
  end
282
294
 
295
+ def test_login_from_discord
296
+ if (@user = login_from(:discord))
297
+ redirect_to 'bla', notice: 'Success!'
298
+ else
299
+ redirect_to 'blu', alert: 'Failed!'
300
+ end
301
+ end
302
+
283
303
  def test_return_to_with_external_twitter
284
304
  if (@user = login_from(:twitter))
285
305
  redirect_back_or_to 'bla', notice: 'Success!'
@@ -402,6 +422,14 @@ class SorceryController < ActionController::Base
402
422
  end
403
423
  end
404
424
 
425
+ def test_return_to_with_external_discord
426
+ if (@user = login_from(:discord))
427
+ redirect_back_or_to 'bla', notice: 'Success!'
428
+ else
429
+ redirect_to 'blu', alert: 'Failed!'
430
+ end
431
+ end
432
+
405
433
  def test_create_from_provider
406
434
  provider = params[:provider]
407
435
  login_from(provider)
@@ -11,6 +11,7 @@ AppRoot::Application.routes.draw do
11
11
  get :test_login_from_cookie
12
12
  get :test_login_from
13
13
  get :test_logout_with_remember
14
+ get :test_logout_with_forget_me
14
15
  get :test_logout_with_force_forget_me
15
16
  get :test_invalidate_active_session
16
17
  get :test_should_be_logged_in
@@ -33,6 +34,7 @@ AppRoot::Application.routes.draw do
33
34
  get :test_login_from_instagram
34
35
  get :test_login_from_auth0
35
36
  get :test_login_from_line
37
+ get :test_login_from_discord
36
38
  get :login_at_test
37
39
  get :login_at_test_twitter
38
40
  get :login_at_test_facebook
@@ -49,6 +51,7 @@ AppRoot::Application.routes.draw do
49
51
  get :login_at_test_instagram
50
52
  get :login_at_test_auth0
51
53
  get :login_at_test_line
54
+ get :login_at_test_discord
52
55
  get :test_return_to_with_external
53
56
  get :test_return_to_with_external_twitter
54
57
  get :test_return_to_with_external_facebook
@@ -65,6 +68,7 @@ AppRoot::Application.routes.draw do
65
68
  get :test_return_to_with_external_instagram
66
69
  get :test_return_to_with_external_auth0
67
70
  get :test_return_to_with_external_line
71
+ get :test_return_to_with_external_discord
68
72
  get :test_http_basic_auth
69
73
  get :some_action_making_a_non_persisted_change_to_the_user
70
74
  post :test_login_with_remember
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sorcery/providers/base'
4
+
5
+ module Sorcery
6
+ module Providers
7
+ class Example < Base
8
+ include Protocols::Oauth2
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sorcery/providers/base'
4
+
5
+ module Sorcery
6
+ module Providers
7
+ class ExampleProvider < Base
8
+ include Protocols::Oauth2
9
+ end
10
+ end
11
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorcery
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.0
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Noam Ben Ari
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2019-05-23 00:00:00.000000000 Z
15
+ date: 2020-05-02 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bcrypt
@@ -52,22 +52,22 @@ dependencies:
52
52
  name: oauth2
53
53
  requirement: !ruby/object:Gem::Requirement
54
54
  requirements:
55
- - - "~>"
56
- - !ruby/object:Gem::Version
57
- version: '1.0'
58
55
  - - ">="
59
56
  - !ruby/object:Gem::Version
60
57
  version: 0.8.0
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.0'
61
61
  type: :runtime
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '1.0'
68
65
  - - ">="
69
66
  - !ruby/object:Gem::Version
70
67
  version: 0.8.0
68
+ - - "~>"
69
+ - !ruby/object:Gem::Version
70
+ version: '1.0'
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: byebug
73
73
  requirement: !ruby/object:Gem::Requirement
@@ -254,6 +254,7 @@ files:
254
254
  - lib/sorcery/protocols/oauth2.rb
255
255
  - lib/sorcery/providers/auth0.rb
256
256
  - lib/sorcery/providers/base.rb
257
+ - lib/sorcery/providers/discord.rb
257
258
  - lib/sorcery/providers/facebook.rb
258
259
  - lib/sorcery/providers/github.rb
259
260
  - lib/sorcery/providers/google.rb
@@ -295,10 +296,13 @@ files:
295
296
  - spec/controllers/controller_session_timeout_spec.rb
296
297
  - spec/controllers/controller_spec.rb
297
298
  - spec/orm/active_record.rb
299
+ - spec/providers/example_provider_spec.rb
300
+ - spec/providers/example_spec.rb
298
301
  - spec/providers/vk_spec.rb
299
302
  - spec/rails_app/app/active_record/authentication.rb
300
303
  - spec/rails_app/app/active_record/user.rb
301
304
  - spec/rails_app/app/active_record/user_provider.rb
305
+ - spec/rails_app/app/assets/config/manifest.js
302
306
  - spec/rails_app/app/controllers/sorcery_controller.rb
303
307
  - spec/rails_app/app/helpers/application_helper.rb
304
308
  - spec/rails_app/app/mailers/sorcery_mailer.rb
@@ -352,6 +356,8 @@ files:
352
356
  - spec/spec.opts
353
357
  - spec/spec_helper.rb
354
358
  - spec/support/migration_helper.rb
359
+ - spec/support/providers/example.rb
360
+ - spec/support/providers/example_provider.rb
355
361
  homepage: https://github.com/Sorcery/sorcery
356
362
  licenses:
357
363
  - MIT
@@ -366,15 +372,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
366
372
  requirements:
367
373
  - - ">="
368
374
  - !ruby/object:Gem::Version
369
- version: 2.2.9
375
+ version: 2.4.9
370
376
  required_rubygems_version: !ruby/object:Gem::Requirement
371
377
  requirements:
372
378
  - - ">="
373
379
  - !ruby/object:Gem::Version
374
380
  version: '0'
375
381
  requirements: []
376
- rubyforge_project:
377
- rubygems_version: 2.7.7
382
+ rubygems_version: 3.0.8
378
383
  signing_key:
379
384
  specification_version: 4
380
385
  summary: Magical authentication for Rails applications