sorcery 0.10.3 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sorcery might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/generators/sorcery/templates/initializer.rb +3 -1
- data/lib/sorcery/controller.rb +12 -6
- data/lib/sorcery/model.rb +29 -5
- data/lib/sorcery/model/submodules/brute_force_protection.rb +13 -5
- data/lib/sorcery/model/submodules/reset_password.rb +7 -4
- data/lib/sorcery/model/submodules/user_activation.rb +15 -5
- data/lib/sorcery/model/temporary_token.rb +26 -5
- data/lib/sorcery/providers/facebook.rb +3 -3
- data/lib/sorcery/test_helpers/internal.rb +1 -1
- data/lib/sorcery/version.rb +1 -1
- data/spec/controllers/controller_brute_force_protection_spec.rb +2 -2
- data/spec/controllers/controller_remember_me_spec.rb +2 -2
- data/spec/controllers/controller_session_timeout_spec.rb +2 -2
- data/spec/controllers/controller_spec.rb +1 -1
- data/spec/shared_examples/user_activation_shared_examples.rb +78 -0
- data/spec/shared_examples/user_reset_password_shared_examples.rb +65 -0
- data/spec/shared_examples/user_shared_examples.rb +25 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc71bccb13f8e3fcbbf0b94f660a98bc34cc4826
|
4
|
+
data.tar.gz: 9c60fb5db29c7a41378e7c45234b0b0e9df47501
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c557af8ef3828be476750ba465ea4d3c7a34f5ccbf975c5c731d0841891de4f77d56fa867dfd55be9424a2eea0eed768cdfe1a104e6ed70ae643207bb2573eb1
|
7
|
+
data.tar.gz: 582ea847785099a70c4866feee1b1f891a411e4f572ff89497ac353914cffe78669102d8a7a6b76c208976894ca932f83e61e590645306e7b5a9c3ebc6868bc2
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,11 @@
|
|
1
1
|
# Changelog
|
2
|
+
## HEAD
|
3
|
+
|
4
|
+
## 0.11.0
|
5
|
+
|
6
|
+
* Refer to User before calling remove_const to avoid NameError [#58](https://github.com/Sorcery/sorcery/pull/58)
|
7
|
+
* Resurrect block authentication, showing auth failure reason. [#41](https://github.com/Sorcery/sorcery/pull/41)
|
8
|
+
* Add github scope option to initializer.rb [#50](https://github.com/Sorcery/sorcery/pull/50)
|
2
9
|
|
3
10
|
## 0.10.3
|
4
11
|
|
@@ -109,12 +109,14 @@ Rails.application.config.sorcery.configure do |config|
|
|
109
109
|
# config.facebook.user_info_mapping = {:email => "name"}
|
110
110
|
# config.facebook.access_permissions = ["email", "publish_actions"]
|
111
111
|
# config.facebook.display = "page"
|
112
|
-
# config.facebook.api_version = "v2.
|
112
|
+
# config.facebook.api_version = "v2.3"
|
113
|
+
# config.facebook.parse = :json
|
113
114
|
#
|
114
115
|
# config.github.key = ""
|
115
116
|
# config.github.secret = ""
|
116
117
|
# config.github.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=github"
|
117
118
|
# config.github.user_info_mapping = {:email => "name"}
|
119
|
+
# config.github.scope = ""
|
118
120
|
#
|
119
121
|
# config.paypal.key = ""
|
120
122
|
# config.paypal.secret = ""
|
data/lib/sorcery/controller.rb
CHANGED
@@ -30,8 +30,16 @@ module Sorcery
|
|
30
30
|
# Runs hooks after login or failed login.
|
31
31
|
def login(*credentials)
|
32
32
|
@current_user = nil
|
33
|
-
|
34
|
-
|
33
|
+
|
34
|
+
user_class.authenticate(*credentials) do |user, failure_reason|
|
35
|
+
if failure_reason
|
36
|
+
after_failed_login!(credentials)
|
37
|
+
|
38
|
+
yield(user, failure_reason) if block_given?
|
39
|
+
|
40
|
+
return
|
41
|
+
end
|
42
|
+
|
35
43
|
old_session = session.dup.to_hash
|
36
44
|
reset_sorcery_session
|
37
45
|
old_session.each_pair do |k, v|
|
@@ -41,10 +49,8 @@ module Sorcery
|
|
41
49
|
|
42
50
|
auto_login(user)
|
43
51
|
after_login!(user, credentials)
|
44
|
-
|
45
|
-
|
46
|
-
after_failed_login!(credentials)
|
47
|
-
nil
|
52
|
+
|
53
|
+
block_given? ? yield(current_user, nil) : current_user
|
48
54
|
end
|
49
55
|
end
|
50
56
|
|
data/lib/sorcery/model.rb
CHANGED
@@ -80,10 +80,12 @@ module Sorcery
|
|
80
80
|
# Takes a username and password,
|
81
81
|
# Finds the user by the username and compares the user's password to the one supplied to the method.
|
82
82
|
# returns the user if success, nil otherwise.
|
83
|
-
def authenticate(*credentials)
|
83
|
+
def authenticate(*credentials, &block)
|
84
84
|
raise ArgumentError, 'at least 2 arguments required' if credentials.size < 2
|
85
85
|
|
86
|
-
|
86
|
+
if credentials[0].blank?
|
87
|
+
return authentication_response(return_value: false, failure: :invalid_login, &block)
|
88
|
+
end
|
87
89
|
|
88
90
|
if @sorcery_config.downcase_username_before_authenticating
|
89
91
|
credentials[0].downcase!
|
@@ -91,13 +93,29 @@ module Sorcery
|
|
91
93
|
|
92
94
|
user = sorcery_adapter.find_by_credentials(credentials)
|
93
95
|
|
94
|
-
|
95
|
-
return
|
96
|
+
unless user
|
97
|
+
return authentication_response(failure: :invalid_login, &block)
|
96
98
|
end
|
97
99
|
|
98
100
|
set_encryption_attributes
|
99
101
|
|
100
|
-
|
102
|
+
unless user.valid_password?(credentials[1])
|
103
|
+
return authentication_response(user: user, failure: :invalid_password, &block)
|
104
|
+
end
|
105
|
+
|
106
|
+
if user.respond_to?(:active_for_authentication?) && !user.active_for_authentication?
|
107
|
+
return authentication_response(user: user, failure: :inactive, &block)
|
108
|
+
end
|
109
|
+
|
110
|
+
@sorcery_config.before_authenticate.each do |callback|
|
111
|
+
success, reason = user.send(callback)
|
112
|
+
|
113
|
+
unless success
|
114
|
+
return authentication_response(user: user, failure: reason, &block)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
authentication_response(user: user, return_value: user, &block)
|
101
119
|
end
|
102
120
|
|
103
121
|
# encrypt tokens using current encryption_provider.
|
@@ -112,6 +130,12 @@ module Sorcery
|
|
112
130
|
|
113
131
|
protected
|
114
132
|
|
133
|
+
def authentication_response(options = {})
|
134
|
+
yield(options[:user], options[:failure]) if block_given?
|
135
|
+
|
136
|
+
options[:return_value]
|
137
|
+
end
|
138
|
+
|
115
139
|
def set_encryption_attributes
|
116
140
|
@sorcery_config.encryption_provider.stretches = @sorcery_config.stretches if @sorcery_config.encryption_provider.respond_to?(:stretches) && @sorcery_config.stretches
|
117
141
|
@sorcery_config.encryption_provider.join_token = @sorcery_config.salt_join_token if @sorcery_config.encryption_provider.respond_to?(:join_token) && @sorcery_config.salt_join_token
|
@@ -41,10 +41,15 @@ module Sorcery
|
|
41
41
|
end
|
42
42
|
|
43
43
|
module ClassMethods
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
# This doesn't check to see if the account is still locked
|
45
|
+
def load_from_unlock_token(token, &block)
|
46
|
+
return if token.blank?
|
47
|
+
|
48
|
+
load_from_token(
|
49
|
+
token,
|
50
|
+
sorcery_config.unlock_token_attribute_name,
|
51
|
+
&block
|
52
|
+
)
|
48
53
|
end
|
49
54
|
|
50
55
|
protected
|
@@ -116,7 +121,10 @@ module Sorcery
|
|
116
121
|
if !login_unlocked? && config.login_lock_time_period != 0
|
117
122
|
login_unlock! if send(config.lock_expires_at_attribute_name) <= Time.now.in_time_zone
|
118
123
|
end
|
119
|
-
|
124
|
+
|
125
|
+
return false, :locked unless login_unlocked?
|
126
|
+
|
127
|
+
true
|
120
128
|
end
|
121
129
|
end
|
122
130
|
end
|
@@ -55,10 +55,13 @@ module Sorcery
|
|
55
55
|
module ClassMethods
|
56
56
|
# Find user by token, also checks for expiration.
|
57
57
|
# Returns the user if token found and is valid.
|
58
|
-
def load_from_reset_password_token(token)
|
59
|
-
|
60
|
-
|
61
|
-
|
58
|
+
def load_from_reset_password_token(token, &block)
|
59
|
+
load_from_token(
|
60
|
+
token,
|
61
|
+
@sorcery_config.reset_password_token_attribute_name,
|
62
|
+
@sorcery_config.reset_password_token_expires_at_attribute_name,
|
63
|
+
&block
|
64
|
+
)
|
62
65
|
end
|
63
66
|
|
64
67
|
protected
|
@@ -59,10 +59,13 @@ module Sorcery
|
|
59
59
|
module ClassMethods
|
60
60
|
# Find user by token, also checks for expiration.
|
61
61
|
# Returns the user if token found and is valid.
|
62
|
-
def load_from_activation_token(token)
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
def load_from_activation_token(token, &block)
|
63
|
+
load_from_token(
|
64
|
+
token,
|
65
|
+
@sorcery_config.activation_token_attribute_name,
|
66
|
+
@sorcery_config.activation_token_expires_at_attribute_name,
|
67
|
+
&block
|
68
|
+
)
|
66
69
|
end
|
67
70
|
|
68
71
|
protected
|
@@ -128,7 +131,14 @@ module Sorcery
|
|
128
131
|
|
129
132
|
def prevent_non_active_login
|
130
133
|
config = sorcery_config
|
131
|
-
|
134
|
+
|
135
|
+
if config.prevent_non_active_users_to_login
|
136
|
+
unless send(config.activation_state_attribute_name) == 'active'
|
137
|
+
return false, :inactive
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
true
|
132
142
|
end
|
133
143
|
end
|
134
144
|
end
|
@@ -16,13 +16,34 @@ module Sorcery
|
|
16
16
|
end
|
17
17
|
|
18
18
|
module ClassMethods
|
19
|
-
def load_from_token(token, token_attr_name, token_expiration_date_attr)
|
20
|
-
return
|
19
|
+
def load_from_token(token, token_attr_name, token_expiration_date_attr = nil, &block)
|
20
|
+
return token_response(failure: :invalid_token, &block) if token.blank?
|
21
|
+
|
21
22
|
user = sorcery_adapter.find_by_token(token_attr_name, token)
|
22
|
-
|
23
|
-
|
23
|
+
|
24
|
+
return token_response(failure: :user_not_found, &block) unless user
|
25
|
+
|
26
|
+
unless check_expiration_date(user, token_expiration_date_attr)
|
27
|
+
return token_response(user: user, failure: :token_expired, &block)
|
24
28
|
end
|
25
|
-
|
29
|
+
|
30
|
+
token_response(user: user, return_value: user, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def check_expiration_date(user, token_expiration_date_attr)
|
36
|
+
return true unless token_expiration_date_attr
|
37
|
+
|
38
|
+
expires_at = user.send(token_expiration_date_attr)
|
39
|
+
|
40
|
+
!expires_at || (Time.now.in_time_zone < expires_at)
|
41
|
+
end
|
42
|
+
|
43
|
+
def token_response(options = {})
|
44
|
+
yield(options[:user], options[:failure]) if block_given?
|
45
|
+
|
46
|
+
options[:return_value]
|
26
47
|
end
|
27
48
|
end
|
28
49
|
end
|
@@ -9,9 +9,9 @@ module Sorcery
|
|
9
9
|
class Facebook < Base
|
10
10
|
include Protocols::Oauth2
|
11
11
|
|
12
|
-
attr_reader :mode, :param_name
|
12
|
+
attr_reader :mode, :param_name
|
13
13
|
attr_accessor :access_permissions, :display, :scope, :token_url,
|
14
|
-
:user_info_path, :auth_path, :api_version
|
14
|
+
:user_info_path, :auth_path, :api_version, :parse
|
15
15
|
|
16
16
|
def initialize
|
17
17
|
super
|
@@ -24,7 +24,7 @@ module Sorcery
|
|
24
24
|
@token_url = 'oauth/access_token'
|
25
25
|
@auth_path = 'dialog/oauth'
|
26
26
|
@mode = :query
|
27
|
-
@parse = :
|
27
|
+
@parse = :json
|
28
28
|
@param_name = 'access_token'
|
29
29
|
end
|
30
30
|
|
@@ -67,7 +67,7 @@ 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
72
|
if User.respond_to?(:reset_column_information)
|
73
73
|
User.reset_column_information
|
data/lib/sorcery/version.rb
CHANGED
@@ -20,7 +20,7 @@ describe SorceryController, type: :controller do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'counts login retries' do
|
23
|
-
allow(User).to receive(:authenticate)
|
23
|
+
allow(User).to receive(:authenticate) { |&block| block.call(nil, :other) }
|
24
24
|
allow(User.sorcery_adapter).to receive(:find_by_credentials).with(['bla@bla.com', 'blabla']).and_return(user)
|
25
25
|
|
26
26
|
expect(user).to receive(:register_failed_login!).exactly(3).times
|
@@ -32,7 +32,7 @@ describe SorceryController, type: :controller do
|
|
32
32
|
# dirty hack for rails 4
|
33
33
|
allow(@controller).to receive(:register_last_activity_time_to_db)
|
34
34
|
|
35
|
-
allow(User).to receive(:authenticate).
|
35
|
+
allow(User).to receive(:authenticate) { |&block| block.call(user, nil) }
|
36
36
|
expect(user).to receive_message_chain(:sorcery_adapter, :update_attribute).with(:failed_logins_count, 0)
|
37
37
|
|
38
38
|
get :test_login, params: { email: 'bla@bla.com', password: 'secret' }
|
@@ -22,7 +22,7 @@ describe SorceryController, type: :controller do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'sets cookie on remember_me!' do
|
25
|
-
expect(User).to receive(:authenticate).with('bla@bla.com', 'secret').
|
25
|
+
expect(User).to receive(:authenticate).with('bla@bla.com', 'secret') { |&block| block.call(user, nil) }
|
26
26
|
expect(user).to receive(:remember_me!)
|
27
27
|
|
28
28
|
post :test_login_with_remember, params: { email: 'bla@bla.com', password: 'secret' }
|
@@ -45,7 +45,7 @@ describe SorceryController, type: :controller do
|
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'login(email,password,remember_me) logs user in and remembers' do
|
48
|
-
expect(User).to receive(:authenticate).with('bla@bla.com', 'secret', '1').
|
48
|
+
expect(User).to receive(:authenticate).with('bla@bla.com', 'secret', '1') { |&block| block.call(user, nil) }
|
49
49
|
expect(user).to receive(:remember_me!)
|
50
50
|
expect(user).to receive(:remember_me_token).and_return('abracadabra').twice
|
51
51
|
|
@@ -39,7 +39,7 @@ describe SorceryController, type: :controller do
|
|
39
39
|
it 'works if the session is stored as a string or a Time' do
|
40
40
|
session[:login_time] = Time.now.to_s
|
41
41
|
# TODO: ???
|
42
|
-
expect(User).to receive(:authenticate).with('bla@bla.com', 'secret').
|
42
|
+
expect(User).to receive(:authenticate).with('bla@bla.com', 'secret') { |&block| block.call(user, nil) }
|
43
43
|
|
44
44
|
get :test_login, params: { email: 'bla@bla.com', password: 'secret' }
|
45
45
|
|
@@ -50,7 +50,7 @@ describe SorceryController, type: :controller do
|
|
50
50
|
context "with 'session_timeout_from_last_action'" do
|
51
51
|
it 'does not logout if there was activity' do
|
52
52
|
sorcery_controller_property_set(:session_timeout_from_last_action, true)
|
53
|
-
expect(User).to receive(:authenticate).with('bla@bla.com', 'secret').
|
53
|
+
expect(User).to receive(:authenticate).with('bla@bla.com', 'secret') { |&block| block.call(user, nil) }
|
54
54
|
|
55
55
|
get :test_login, params: { email: 'bla@bla.com', password: 'secret' }
|
56
56
|
Timecop.travel(Time.now.in_time_zone + 0.3)
|
@@ -52,7 +52,7 @@ describe SorceryController, type: :controller do
|
|
52
52
|
describe '#login' do
|
53
53
|
context 'when succeeds' do
|
54
54
|
before do
|
55
|
-
expect(User).to receive(:authenticate).with('bla@bla.com', 'secret').
|
55
|
+
expect(User).to receive(:authenticate).with('bla@bla.com', 'secret') { |&block| block.call(user, nil) }
|
56
56
|
get :test_login, params: { email: 'bla@bla.com', password: 'secret' }
|
57
57
|
end
|
58
58
|
|
@@ -235,6 +235,27 @@ shared_examples_for 'rails_3_activation_model' do
|
|
235
235
|
|
236
236
|
expect(User.authenticate(user.email, 'secret')).to be_truthy
|
237
237
|
end
|
238
|
+
|
239
|
+
context 'in block mode' do
|
240
|
+
it 'does not allow a non-active user to authenticate' do
|
241
|
+
sorcery_model_property_set(:prevent_non_active_users_to_login, true)
|
242
|
+
|
243
|
+
User.authenticate(user.email, 'secret') do |user2, failure|
|
244
|
+
expect(user2).to eq user
|
245
|
+
expect(user2.activation_state).to eq 'pending'
|
246
|
+
expect(failure).to eq :inactive
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
it 'allows a non-active user to authenticate if configured so' do
|
251
|
+
sorcery_model_property_set(:prevent_non_active_users_to_login, false)
|
252
|
+
|
253
|
+
User.authenticate(user.email, 'secret') do |user2, failure|
|
254
|
+
expect(user2).to eq user
|
255
|
+
expect(failure).to be_nil
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
238
259
|
end
|
239
260
|
|
240
261
|
describe 'load_from_activation_token' do
|
@@ -279,5 +300,62 @@ shared_examples_for 'rails_3_activation_model' do
|
|
279
300
|
|
280
301
|
expect(User.load_from_activation_token(user.activation_token)).to eq user
|
281
302
|
end
|
303
|
+
|
304
|
+
describe '#load_from_activation_token' do
|
305
|
+
context 'in block mode' do
|
306
|
+
it 'yields user when token is found' do
|
307
|
+
User.load_from_activation_token(user.activation_token) do |user2, failure|
|
308
|
+
expect(user2).to eq user
|
309
|
+
expect(failure).to be_nil
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
it 'does NOT yield user when token is NOT found' do
|
314
|
+
User.load_from_activation_token('a') do |user2, failure|
|
315
|
+
expect(user2).to be_nil
|
316
|
+
expect(failure).to eq :user_not_found
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
it 'yields user when token is found and not expired' do
|
321
|
+
sorcery_model_property_set(:activation_token_expiration_period, 500)
|
322
|
+
|
323
|
+
User.load_from_activation_token(user.activation_token) do |user2, failure|
|
324
|
+
expect(user2).to eq user
|
325
|
+
expect(failure).to be_nil
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
it 'yields the user and failure reason when token is found and expired' do
|
330
|
+
sorcery_model_property_set(:activation_token_expiration_period, 0.1)
|
331
|
+
user
|
332
|
+
|
333
|
+
Timecop.travel(Time.now.in_time_zone + 0.5)
|
334
|
+
|
335
|
+
User.load_from_activation_token(user.activation_token) do |user2, failure|
|
336
|
+
expect(user2).to eq user
|
337
|
+
expect(failure).to eq :token_expired
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
it 'yields a failure reason if token is blank' do
|
342
|
+
[nil, ''].each do |token|
|
343
|
+
User.load_from_activation_token(token) do |user2, failure|
|
344
|
+
expect(user2).to be_nil
|
345
|
+
expect(failure).to eq :invalid_token
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
it 'is always valid if expiration period is nil' do
|
351
|
+
sorcery_model_property_set(:activation_token_expiration_period, nil)
|
352
|
+
|
353
|
+
User.load_from_activation_token(user.activation_token) do |user2, failure|
|
354
|
+
expect(user2).to eq user
|
355
|
+
expect(failure).to be_nil
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
282
360
|
end
|
283
361
|
end
|
@@ -128,6 +128,71 @@ shared_examples_for 'rails_3_reset_password_model' do
|
|
128
128
|
expect(User.load_from_reset_password_token('')).to be_nil
|
129
129
|
end
|
130
130
|
|
131
|
+
describe '#load_from_reset_password_token' do
|
132
|
+
context 'in block mode' do
|
133
|
+
it 'yields user when token is found' do
|
134
|
+
user.generate_reset_password_token!
|
135
|
+
updated_user = User.sorcery_adapter.find(user.id)
|
136
|
+
|
137
|
+
User.load_from_reset_password_token(user.reset_password_token) do |user2, failure|
|
138
|
+
expect(user2).to eq updated_user
|
139
|
+
expect(failure).to be_nil
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'does NOT yield user when token is NOT found' do
|
144
|
+
user.generate_reset_password_token!
|
145
|
+
|
146
|
+
User.load_from_reset_password_token('a') do |user2, failure|
|
147
|
+
expect(user2).to be_nil
|
148
|
+
expect(failure).to eq :user_not_found
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'yields user when token is found and not expired' do
|
153
|
+
sorcery_model_property_set(:reset_password_expiration_period, 500)
|
154
|
+
user.generate_reset_password_token!
|
155
|
+
updated_user = User.sorcery_adapter.find(user.id)
|
156
|
+
|
157
|
+
User.load_from_reset_password_token(user.reset_password_token) do |user2, failure|
|
158
|
+
expect(user2).to eq updated_user
|
159
|
+
expect(failure).to be_nil
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'yields user and failure reason when token is found and expired' do
|
164
|
+
sorcery_model_property_set(:reset_password_expiration_period, 0.1)
|
165
|
+
user.generate_reset_password_token!
|
166
|
+
Timecop.travel(Time.now.in_time_zone + 0.5)
|
167
|
+
|
168
|
+
User.load_from_reset_password_token(user.reset_password_token) do |user2, failure|
|
169
|
+
expect(user2).to eq user
|
170
|
+
expect(failure).to eq :token_expired
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'is always valid if expiration period is nil' do
|
175
|
+
sorcery_model_property_set(:reset_password_expiration_period, nil)
|
176
|
+
user.generate_reset_password_token!
|
177
|
+
updated_user = User.sorcery_adapter.find(user.id)
|
178
|
+
|
179
|
+
User.load_from_reset_password_token(user.reset_password_token) do |user2, failure|
|
180
|
+
expect(user2).to eq updated_user
|
181
|
+
expect(failure).to be_nil
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'returns nil if token is blank' do
|
186
|
+
[nil, ''].each do |token|
|
187
|
+
User.load_from_reset_password_token(token) do |user2, failure|
|
188
|
+
expect(user2).to be_nil
|
189
|
+
expect(failure).to eq :invalid_token
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
131
196
|
it "'deliver_reset_password_instructions!' generates a reset_password_token" do
|
132
197
|
expect(user.reset_password_token).to be_nil
|
133
198
|
|
@@ -146,6 +146,31 @@ shared_examples_for 'rails_3_core_model' do
|
|
146
146
|
expect(User.authenticate(user.email, 'secret')).to be_nil
|
147
147
|
end
|
148
148
|
end
|
149
|
+
|
150
|
+
context 'in block mode' do
|
151
|
+
it 'yields the user if credentials are good' do
|
152
|
+
User.authenticate(user.email, 'secret') do |user2, failure|
|
153
|
+
expect(user2).to eq user
|
154
|
+
expect(failure).to be_nil
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'yields the user and proper error if credentials are bad' do
|
159
|
+
User.authenticate(user.email, 'wrong!') do |user2, failure|
|
160
|
+
expect(user2).to eq user
|
161
|
+
expect(failure).to eq :invalid_password
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'yields the proper error if no user exists' do
|
166
|
+
[nil, '', 'not@a.user'].each do |email|
|
167
|
+
User.authenticate(email, 'wrong!') do |user2, failure|
|
168
|
+
expect(user2).to be_nil
|
169
|
+
expect(failure).to eq :invalid_login
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
149
174
|
end
|
150
175
|
|
151
176
|
specify { expect(User).to respond_to(:encrypt) }
|
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.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Noam Ben Ari
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2017-
|
14
|
+
date: 2017-05-16 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: oauth
|
@@ -327,3 +327,4 @@ signing_key:
|
|
327
327
|
specification_version: 4
|
328
328
|
summary: Magical authentication for Rails applications
|
329
329
|
test_files: []
|
330
|
+
has_rdoc:
|