jump_in 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +0 -6
- data/lib/generators/jump_in/config_initializer.rb +13 -0
- data/lib/generators/jump_in/install_generator.rb +14 -0
- data/lib/generators/templates/jump_in_initializer.rb +25 -0
- data/lib/jump_in/authentication/cookies.rb +35 -0
- data/lib/jump_in/authentication/session.rb +32 -0
- data/lib/jump_in/authentication.rb +54 -55
- data/lib/jump_in/password_reset.rb +15 -15
- data/lib/jump_in/persistence.rb +2 -0
- data/lib/jump_in/strategies/base.rb +36 -0
- data/lib/jump_in/strategies/by_password.rb +13 -0
- data/lib/jump_in/strategies.rb +2 -0
- data/lib/jump_in/tokenator.rb +25 -0
- data/lib/jump_in/version.rb +1 -1
- data/lib/jump_in.rb +46 -2
- data/spec/dummy/app/models/user_with_secure_password.rb +3 -0
- data/spec/dummy/db/migrate/20150908085412_rename_users_to_user_with_secure_passwords.rb +5 -0
- data/spec/dummy/db/schema.rb +2 -2
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +5280 -0
- data/spec/dummy/spec/classes/configuration_spec.rb +34 -0
- data/spec/dummy/spec/factories.rb +1 -1
- data/spec/dummy/spec/modules/authentication_spec.rb +59 -52
- data/spec/dummy/spec/modules/password_reset_spec.rb +60 -77
- data/spec/dummy/spec/modules/strategies_spec.rb +71 -0
- data/spec/dummy/spec/modules/tokenator_spec.rb +46 -0
- data/spec/dummy/spec/rails_helper.rb +1 -0
- data/spec/dummy/spec/support/common_methods.rb +9 -9
- metadata +29 -42
- data/lib/jump_in/authentication/by_password.rb +0 -13
- data/lib/jump_in/authentication/strategy.rb +0 -16
- data/lib/jump_in/tokenizer.rb +0 -21
- data/spec/dummy/README.rdoc +0 -28
- data/spec/dummy/app/controllers/password_resets_controller.rb +0 -34
- data/spec/dummy/app/controllers/sessions_controller.rb +0 -16
- data/spec/dummy/app/controllers/users_controller.rb +0 -32
- data/spec/dummy/app/mailers/system_mailer.rb +0 -8
- data/spec/dummy/app/models/user.rb +0 -3
- data/spec/dummy/app/views/layouts/application.html.erb +0 -18
- data/spec/dummy/app/views/password_resets/edit.html.erb +0 -9
- data/spec/dummy/app/views/password_resets/new.html.erb +0 -7
- data/spec/dummy/app/views/sessions/new.html.erb +0 -7
- data/spec/dummy/app/views/system_mailer/password_reset.html.erb +0 -2
- data/spec/dummy/app/views/users/show.html.erb +0 -1
- data/spec/dummy/spec/controllers/password_resets_controller_spec.rb +0 -53
- data/spec/dummy/spec/controllers/sessions_controller_spec.rb +0 -36
- data/spec/dummy/spec/controllers/users_controller_spec.rb +0 -20
- data/spec/dummy/spec/integration/logging_spec.rb +0 -18
- data/spec/dummy/spec/integration/reset_password_spec.rb +0 -39
- data/spec/dummy/spec/modules/tokenizer_spec.rb +0 -19
- /data/{README.rdoc → spec/dummy/log/development.log} +0 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
class SomeController < ActionController::Base
|
4
|
+
include JumpIn
|
5
|
+
end
|
6
|
+
|
7
|
+
describe SomeController do
|
8
|
+
|
9
|
+
context "JumpIn.configure not run" do
|
10
|
+
it "has @conf with default values" do
|
11
|
+
expect(JumpIn.conf.permanent).to eq(false)
|
12
|
+
expect(JumpIn.conf.expires).to eq(20.years)
|
13
|
+
expect(JumpIn.conf.expiration_time).to eq(2.hours)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "JumpIn.configure run" do
|
18
|
+
it "has @conf available with proper permanent" do
|
19
|
+
run_config(permanent: true)
|
20
|
+
expect(JumpIn.conf.permanent).to eq(true)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "has @conf available with proper expires" do
|
24
|
+
run_config(expires: 5.years)
|
25
|
+
expect(JumpIn.conf.expires).to eq(5.years)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "has @conf available with proper expiration_time" do
|
29
|
+
run_config(expiration_time: 5.hours)
|
30
|
+
expect(JumpIn.conf.expiration_time).to eq(5.hours)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -2,69 +2,74 @@ require_relative '../spec_helper'
|
|
2
2
|
|
3
3
|
class AuthenticationController < ActionController::Base
|
4
4
|
include JumpIn::Authentication
|
5
|
+
jumpin_use persistence: [:session, :cookies]
|
5
6
|
end
|
6
7
|
|
7
8
|
describe AuthenticationController, type: :controller do
|
8
|
-
let(:
|
9
|
+
let(:user_wsp) { FactoryGirl.create(:user_with_secure_password) }
|
10
|
+
after(:all) { JumpIn.instance_variable_set('@configuration', nil) }
|
11
|
+
|
12
|
+
context ".jumpin_callback" do
|
13
|
+
it "it added default constants while including Session & Cookies" do
|
14
|
+
expect(subject.class.constants).to include(:ON_LOGIN)
|
15
|
+
expect(subject.class.constants).to include(:ON_LOGOUT)
|
16
|
+
expect(subject.class.constants).to include(:GET_CURRENT_USER)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "creates constant with method if constant didn't exist" do
|
20
|
+
subject.class.jumpin_callback :a_callback, :method
|
21
|
+
expect(subject.class.const_get(:A_CALLBACK)).to eq([:method])
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'adds method if constant existed' do
|
25
|
+
subject.class.const_set('B_CALLBACK', [:method_1])
|
26
|
+
subject.class.jumpin_callback :b_callback, :method_2
|
27
|
+
expect(subject.class.const_get(:B_CALLBACK)).to eq([:method_1, :method_2])
|
28
|
+
end
|
29
|
+
end
|
9
30
|
|
10
31
|
context "#jump_in" do
|
11
32
|
it "returns false if user logged_in" do
|
12
33
|
allow_to_receive_logged_in_and_return(true)
|
13
|
-
expect(subject.jump_in(user:
|
34
|
+
expect(subject.jump_in(user: user_wsp, password: user_wsp.password)).to eq(false)
|
14
35
|
end
|
15
36
|
|
16
37
|
it "calls detect_strategy with proper params" do
|
17
38
|
allow_to_receive_logged_in_and_return(false)
|
18
|
-
expect(subject).to receive(:detected_strategy).with(user:
|
19
|
-
exactly(1).times.and_return(JumpIn::
|
20
|
-
subject.jump_in(user:
|
39
|
+
expect(subject).to receive(:detected_strategy).with(user: user_wsp, auth_params: { password: user_wsp.password }).
|
40
|
+
exactly(1).times.and_return(JumpIn::Strategies::ByPassword.new(user: user_wsp, auth_params: { password: user_wsp.password }))
|
41
|
+
subject.jump_in(user: user_wsp, password: user_wsp.password)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "raises an error when no strategy detected" do
|
45
|
+
allow_to_receive_logged_in_and_return(false)
|
46
|
+
expect { subject.jump_in(user: user_wsp) }.to raise_error(JumpIn::AuthenticationStrategyError, "No authentication strategy detected.")
|
21
47
|
end
|
22
48
|
|
23
49
|
it "returns false if user not logged_in and wrong login data provided" do
|
24
50
|
allow_to_receive_logged_in_and_return(false)
|
25
|
-
expect(subject.jump_in(user:
|
51
|
+
expect(subject.jump_in(user: user_wsp, password:'something')).to eq(false)
|
26
52
|
end
|
27
53
|
|
28
54
|
context 'when user not logged_in and authentication successful' do
|
29
55
|
it "returns true" do
|
30
56
|
allow_to_receive_logged_in_and_return(false)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
it "calls 'login' with permanent=false for permanent false by default" do
|
35
|
-
allow_to_receive_logged_in_and_return(false)
|
36
|
-
expect(subject).to receive(:login).with(user:user, permanent:false, expires:nil).exactly(1).times.and_return(true)
|
37
|
-
subject.jump_in(user: user, password: user.password)
|
38
|
-
end
|
39
|
-
|
40
|
-
it "calls 'login' with permanent=false for permanent passed as false" do
|
41
|
-
allow_to_receive_logged_in_and_return(false)
|
42
|
-
expect(subject).to receive(:login).with(user:user, permanent:false, expires:nil).exactly(1).times.and_return(true)
|
43
|
-
subject.jump_in(user: user, password: user.password, permanent: false)
|
44
|
-
end
|
45
|
-
|
46
|
-
it "calls 'login' with permanent=true for permanent passed as true" do
|
47
|
-
allow_to_receive_logged_in_and_return(false)
|
48
|
-
expect(subject).to receive(:login).with(user:user, permanent:true, expires:nil).exactly(1).times.and_return(true)
|
49
|
-
subject.jump_in(user: user, password: user.password, permanent: true)
|
57
|
+
allow(subject).to receive(:login).with(user: user_wsp).and_return(true)
|
58
|
+
expect(subject.jump_in(user: user_wsp, password: user_wsp.password)).to eq(true)
|
50
59
|
end
|
51
60
|
end
|
52
61
|
end
|
53
62
|
|
54
63
|
context "#login" do
|
55
|
-
it "sets session when permanent
|
56
|
-
subject.login(user:
|
57
|
-
expect_only_session_set_for(
|
58
|
-
end
|
59
|
-
|
60
|
-
it "sets session when permanent passed as false" do
|
61
|
-
subject.login(user: user, permanent: false)
|
62
|
-
expect_only_session_set_for(user)
|
64
|
+
it "sets session when @configuration.permanent is false" do
|
65
|
+
subject.login(user: user_wsp)
|
66
|
+
expect_only_session_set_for(user_wsp)
|
63
67
|
end
|
64
68
|
|
65
|
-
it "sets cookies when permanent
|
66
|
-
|
67
|
-
|
69
|
+
it "sets cookies when @configuration.permanent is true" do
|
70
|
+
run_config(permanent: true)
|
71
|
+
subject.login(user: user_wsp)
|
72
|
+
expect_only_cookies_set_for(user_wsp)
|
68
73
|
end
|
69
74
|
|
70
75
|
context 'sets proper value for cookies[:expires]' do
|
@@ -75,14 +80,16 @@ describe AuthenticationController, type: :controller do
|
|
75
80
|
allow(@cookies).to receive(:signed).and_return(@cookies)
|
76
81
|
end
|
77
82
|
|
78
|
-
it "sets 20 years if
|
79
|
-
|
83
|
+
it "sets 20 years if @configuration.expires not set" do
|
84
|
+
run_config(permanent: true)
|
85
|
+
subject.login(user: user_wsp)
|
80
86
|
expect(@cookies.signed[:jump_in_class][:expires]).to be_between(Time.now + 19.years, Time.now + 21.years)
|
81
87
|
expect(@cookies.signed[:jump_in_id][:expires]).to be_between(Time.now + 19.years, Time.now + 21.years)
|
82
88
|
end
|
83
89
|
|
84
|
-
it "sets correct value if
|
85
|
-
|
90
|
+
it "sets correct value if @configuration.expires set" do
|
91
|
+
run_config(permanent: true, expires: 2.hours)
|
92
|
+
subject.login(user: user_wsp)
|
86
93
|
expect(@cookies.signed[:jump_in_class][:expires]).to eq(@cookies.signed[:jump_in_id][:expires])
|
87
94
|
expect(@cookies.signed[:jump_in_class][:expires]).to be_between(Time.now + 1.hours, Time.now + 3.hours)
|
88
95
|
expect(@cookies.signed[:jump_in_id][:expires]).to be_between(Time.now + 1.hours, Time.now + 3.hours)
|
@@ -92,26 +99,26 @@ describe AuthenticationController, type: :controller do
|
|
92
99
|
|
93
100
|
context "#jump_out" do
|
94
101
|
it "clears session when session set" do
|
95
|
-
set_session(
|
96
|
-
expect_session_eq(klass:
|
102
|
+
set_session(user_wsp)
|
103
|
+
expect_session_eq(klass: user_wsp.class.to_s, id: user_wsp.id)
|
97
104
|
subject.jump_out
|
98
105
|
expect_session_eq(klass: nil, id: nil)
|
99
106
|
end
|
100
107
|
|
101
108
|
it "clears cookies when cookies set" do
|
102
|
-
set_cookies(
|
103
|
-
expect_cookies_eq(klass:
|
109
|
+
set_cookies(user_wsp, nil)
|
110
|
+
expect_cookies_eq(klass: user_wsp.class.to_s, id: user_wsp.id)
|
104
111
|
subject.jump_out
|
105
112
|
expect_cookies_eq(klass: nil, id: nil)
|
106
113
|
end
|
107
114
|
|
108
115
|
it "returns true if logged out from session" do
|
109
|
-
set_session(
|
116
|
+
set_session(user_wsp)
|
110
117
|
expect(subject.jump_out).to eq(true)
|
111
118
|
end
|
112
119
|
|
113
120
|
it "returns true if logged out from cookies" do
|
114
|
-
set_cookies(
|
121
|
+
set_cookies(user_wsp, nil)
|
115
122
|
expect(subject.jump_out).to eq(true)
|
116
123
|
end
|
117
124
|
|
@@ -122,13 +129,13 @@ describe AuthenticationController, type: :controller do
|
|
122
129
|
|
123
130
|
context "#current_user" do
|
124
131
|
it "returns user based on session" do
|
125
|
-
set_session(
|
126
|
-
expect(subject.current_user).to eq(
|
132
|
+
set_session(user_wsp)
|
133
|
+
expect(subject.current_user).to eq(user_wsp)
|
127
134
|
end
|
128
135
|
|
129
136
|
it "returns user based on cookies" do
|
130
|
-
set_cookies(
|
131
|
-
expect(subject.current_user).to eq(
|
137
|
+
set_cookies(user_wsp, nil)
|
138
|
+
expect(subject.current_user).to eq(user_wsp)
|
132
139
|
end
|
133
140
|
|
134
141
|
it "returns nil when session and cookie empty" do
|
@@ -138,12 +145,12 @@ describe AuthenticationController, type: :controller do
|
|
138
145
|
|
139
146
|
context "#logged_in?" do
|
140
147
|
it "returns true if current user is set in session" do
|
141
|
-
set_session(
|
148
|
+
set_session(user_wsp)
|
142
149
|
expect(subject.logged_in?).to eq(true)
|
143
150
|
end
|
144
151
|
|
145
152
|
it "returns true if current user is set in cookies" do
|
146
|
-
set_cookies(
|
153
|
+
set_cookies(user_wsp, nil)
|
147
154
|
expect(subject.logged_in?).to eq(true)
|
148
155
|
end
|
149
156
|
end
|
@@ -1,41 +1,40 @@
|
|
1
1
|
require_relative '../spec_helper'
|
2
|
-
include ActiveSupport::Testing::TimeHelpers
|
3
2
|
|
4
3
|
class PasswordResetController < ActionController::Base
|
5
4
|
include JumpIn::PasswordReset
|
6
5
|
end
|
7
6
|
|
8
7
|
describe PasswordResetController, type: :controller do
|
9
|
-
let(:
|
8
|
+
let(:user_wsp) { FactoryGirl.create(:user_with_secure_password) }
|
10
9
|
|
11
10
|
context "#set_password_reset_for" do
|
12
11
|
context "token not uniq_or_empty" do
|
13
12
|
it "calls token_uniq_or_empty? with proper params" do
|
14
13
|
token = 'token'
|
15
|
-
expect(subject).to receive_token_uniq_or_empty_and_return(
|
16
|
-
subject.set_password_reset_for(user:
|
14
|
+
expect(subject).to receive_token_uniq_or_empty_and_return(user_wsp, token, false)
|
15
|
+
subject.set_password_reset_for(user:user_wsp, token:token)
|
17
16
|
end
|
18
17
|
|
19
18
|
it "returns false if token not uniq_or_empty" do
|
20
19
|
token = 'token'
|
21
|
-
allow(subject).to receive_token_uniq_or_empty_and_return(
|
22
|
-
expect(subject.set_password_reset_for(user:
|
20
|
+
allow(subject).to receive_token_uniq_or_empty_and_return(user_wsp, token, false)
|
21
|
+
expect(subject.set_password_reset_for(user:user_wsp, token:token)).to eq(false)
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
25
|
context "token uniq_or_empty" do
|
27
26
|
it "calls set_token with given user & token if token uniq_or_empty" do
|
28
27
|
token = 'token'
|
29
|
-
expect(subject).to receive_token_uniq_or_empty_and_return(
|
30
|
-
expect_set_token_and_return(
|
31
|
-
subject.set_password_reset_for(user:
|
28
|
+
expect(subject).to receive_token_uniq_or_empty_and_return(user_wsp, token, true)
|
29
|
+
expect_set_token_and_return(user_wsp, token, true)
|
30
|
+
subject.set_password_reset_for(user:user_wsp, token:token)
|
32
31
|
end
|
33
32
|
|
34
33
|
it "calls set_token with given user & token=nil if token uniq_or_empty & no token given" do
|
35
34
|
token = nil
|
36
|
-
expect(subject).to receive_token_uniq_or_empty_and_return(
|
37
|
-
expect_set_token_and_return(
|
38
|
-
subject.set_password_reset_for(user:
|
35
|
+
expect(subject).to receive_token_uniq_or_empty_and_return(user_wsp, token, true)
|
36
|
+
expect_set_token_and_return(user_wsp, token, true)
|
37
|
+
subject.set_password_reset_for(user:user_wsp)
|
39
38
|
end
|
40
39
|
end
|
41
40
|
end
|
@@ -43,28 +42,28 @@ describe PasswordResetController, type: :controller do
|
|
43
42
|
context "#set_token" do
|
44
43
|
it "set's given token as user.token" do
|
45
44
|
token = 'token'
|
46
|
-
subject.set_token(user:
|
47
|
-
expect(
|
45
|
+
subject.set_token(user:user_wsp, token:token)
|
46
|
+
expect(user_wsp.password_reset_token).to eq(token)
|
48
47
|
end
|
49
48
|
|
50
49
|
it "generates token for user if token=nil given" do
|
51
|
-
expect(
|
52
|
-
subject.set_token(user:
|
53
|
-
expect(
|
50
|
+
expect(user_wsp.password_reset_token).to eq(nil)
|
51
|
+
subject.set_token(user:user_wsp, token:nil)
|
52
|
+
expect(user_wsp.password_reset_token).to_not eq(nil)
|
54
53
|
end
|
55
54
|
end
|
56
55
|
|
57
56
|
context "#generate_unique_token_for" do
|
58
57
|
it 'generates token' do
|
59
|
-
token = subject.generate_unique_token_for(user:
|
58
|
+
token = subject.generate_unique_token_for(user:user_wsp)
|
60
59
|
expect(token).to_not eq(nil)
|
61
60
|
end
|
62
61
|
|
63
62
|
it 'calls methods #generate_token & #token_uniq?' do
|
64
63
|
token = 'token'
|
65
64
|
expect(subject).to receive(:generate_token).and_return(token)
|
66
|
-
expect(subject).to receive(:token_uniq?).with(user:
|
67
|
-
subject.generate_unique_token_for(user:
|
65
|
+
expect(subject).to receive(:token_uniq?).with(user:user_wsp, token:token).and_return(true)
|
66
|
+
subject.generate_unique_token_for(user:user_wsp)
|
68
67
|
end
|
69
68
|
end
|
70
69
|
|
@@ -77,130 +76,114 @@ describe PasswordResetController, type: :controller do
|
|
77
76
|
|
78
77
|
context "#token_uniq_or_empty?" do
|
79
78
|
it 'returns true if token is nil' do
|
80
|
-
expect(subject.token_uniq_or_empty?(user:
|
79
|
+
expect(subject.token_uniq_or_empty?(user:user_wsp, token:nil)).to eq(true)
|
81
80
|
end
|
82
81
|
|
83
82
|
it 'returns true if token given & unique' do
|
84
83
|
token = 'token'
|
85
|
-
allow(subject).to receive(:token_uniq?).with(user:
|
86
|
-
expect(subject.token_uniq_or_empty?(user:
|
84
|
+
allow(subject).to receive(:token_uniq?).with(user:user_wsp, token:token).and_return(true)
|
85
|
+
expect(subject.token_uniq_or_empty?(user:user_wsp, token:token)).to eq(true)
|
87
86
|
end
|
88
87
|
|
89
88
|
it 'returns false if token give & not unique' do
|
90
89
|
token = 'token'
|
91
|
-
allow(subject).to receive(:token_uniq?).with(user:
|
92
|
-
expect(subject.token_uniq_or_empty?(user:
|
90
|
+
allow(subject).to receive(:token_uniq?).with(user:user_wsp, token:token).and_return(false)
|
91
|
+
expect(subject.token_uniq_or_empty?(user:user_wsp, token:token)).to eq(false)
|
93
92
|
end
|
94
93
|
end
|
95
94
|
|
96
95
|
context "#token_uniq?" do
|
97
96
|
it 'returns true if token unique for user.class' do
|
98
97
|
token = subject.generate_token
|
99
|
-
expect(subject.token_uniq?(user:
|
98
|
+
expect(subject.token_uniq?(user:user_wsp, token:token)).to eq(true)
|
100
99
|
end
|
101
100
|
|
102
101
|
it 'returns false if token not unique for user.class' do
|
103
102
|
token = subject.generate_token
|
104
|
-
|
105
|
-
expect(subject.token_uniq?(user:
|
103
|
+
user_wsp.update_attribute('password_reset_token', token)
|
104
|
+
expect(subject.token_uniq?(user:user_wsp, token:token)).to eq(false)
|
106
105
|
end
|
107
106
|
end
|
108
107
|
|
109
108
|
context "#password_reset_valid?" do
|
110
|
-
|
111
|
-
|
109
|
+
before(:each) { run_config(expiration_time: 2.hours) }
|
110
|
+
it "returns true for token valid" do
|
111
|
+
token = subject.generate_token
|
112
112
|
expect(subject.password_reset_valid?(password_reset_token: token)).to eq(true)
|
113
113
|
end
|
114
114
|
|
115
|
-
it "returns false for token too old
|
115
|
+
it "returns false for token too old" do
|
116
116
|
token = ''
|
117
117
|
travel_to(3.hours.ago) do
|
118
|
-
token =
|
118
|
+
token = subject.generate_token
|
119
119
|
end
|
120
120
|
expect(subject.password_reset_valid?(password_reset_token: token)).to eq(false)
|
121
121
|
end
|
122
|
-
|
123
|
-
it "returns true for token valid with custom expiration time(2.days)" do
|
124
|
-
token = ''
|
125
|
-
travel_to(1.day.ago) do
|
126
|
-
token = JumpIn::Tokenizer.generate_token
|
127
|
-
end
|
128
|
-
expect(subject.password_reset_valid?(password_reset_token: token, expiration_time: 2.days)).to eq(true)
|
129
|
-
end
|
130
|
-
|
131
|
-
it "returns false for token too old with custom expiration time(2.days)" do
|
132
|
-
token = ''
|
133
|
-
travel_to(3.days.ago) do
|
134
|
-
token = JumpIn::Tokenizer.generate_token
|
135
|
-
end
|
136
|
-
expect(subject.password_reset_valid?(password_reset_token: token, expiration_time: 2.days)).to eq(false)
|
137
|
-
end
|
138
|
-
|
139
122
|
end
|
140
123
|
|
141
124
|
context "#update_password_for" do
|
142
125
|
let(:new_password) { 'new_secret_password'}
|
143
|
-
let!(:old_password_digest) {
|
126
|
+
let!(:old_password_digest) { user_wsp.password_digest }
|
144
127
|
|
145
128
|
it "updates password if token belongs to user and is not too old" do
|
146
|
-
|
147
|
-
token =
|
148
|
-
allow_to_receive_token_correct_and_return(
|
129
|
+
user_wsp.update_attribute(:password_reset_token, subject.generate_token)
|
130
|
+
token = user_wsp.password_reset_token
|
131
|
+
allow_to_receive_token_correct_and_return(user_wsp, token, true)
|
149
132
|
|
150
133
|
expect(
|
151
|
-
subject.update_password_for(user:
|
134
|
+
subject.update_password_for(user: user_wsp, password: new_password, password_confirmation: new_password, password_reset_token: token)
|
152
135
|
).to eq(true)
|
153
|
-
expect(
|
136
|
+
expect(user_wsp.password_digest).to_not eq(old_password_digest)
|
154
137
|
end
|
155
138
|
|
156
139
|
it "updates password if token belongs to user and is old" do
|
157
140
|
travel_to(3.days.ago) do
|
158
|
-
|
141
|
+
user_wsp.update_attribute(:password_reset_token, subject.generate_token)
|
159
142
|
end
|
160
|
-
token =
|
161
|
-
allow_to_receive_token_correct_and_return(
|
143
|
+
token = user_wsp.password_reset_token
|
144
|
+
allow_to_receive_token_correct_and_return(user_wsp, token, true)
|
162
145
|
|
163
146
|
expect(
|
164
|
-
subject.update_password_for(user:
|
147
|
+
subject.update_password_for(user: user_wsp, password: new_password, password_confirmation: new_password, password_reset_token: token)
|
165
148
|
).to eq(true)
|
166
|
-
expect(
|
149
|
+
expect(user_wsp.password_digest).to_not eq(old_password_digest)
|
167
150
|
end
|
168
151
|
|
169
152
|
it "does not update password and returns false if token does not belong to user" do
|
170
|
-
|
171
|
-
token =
|
172
|
-
allow_to_receive_token_correct_and_return(
|
153
|
+
user_wsp.update_attribute(:password_reset_token, subject.generate_token)
|
154
|
+
token = subject.generate_token
|
155
|
+
allow_to_receive_token_correct_and_return(user_wsp, token, false)
|
173
156
|
|
174
157
|
expect(
|
175
|
-
subject.update_password_for(user:
|
158
|
+
subject.update_password_for(user: user_wsp, password: new_password, password_confirmation: new_password, password_reset_token: token)
|
176
159
|
).to eq(false)
|
177
|
-
expect(
|
160
|
+
expect(user_wsp.password_digest).to eq(old_password_digest)
|
178
161
|
end
|
179
162
|
|
180
163
|
it "does not update password and returns false if new password invalid" do
|
181
|
-
|
182
|
-
token =
|
183
|
-
allow_to_receive_token_correct_and_return(
|
164
|
+
user_wsp.update_attribute(:password_reset_token, subject.generate_token)
|
165
|
+
token = user_wsp.password_reset_token
|
166
|
+
allow_to_receive_token_correct_and_return(user_wsp, token, true)
|
184
167
|
|
185
168
|
expect(
|
186
|
-
subject.update_password_for(user:
|
169
|
+
subject.update_password_for(user: user_wsp, password: new_password, password_confirmation: 'password', password_reset_token: token)
|
187
170
|
).to eq(false)
|
188
|
-
|
189
|
-
expect(
|
171
|
+
user_wsp.reload
|
172
|
+
expect(user_wsp.password_digest).to eq(old_password_digest)
|
190
173
|
end
|
191
174
|
end
|
192
175
|
|
193
176
|
context "#token_correct?" do
|
194
177
|
it "returns true if given token eq user.token" do
|
195
|
-
|
196
|
-
token =
|
197
|
-
expect(subject.token_correct?(user_token:
|
178
|
+
user_wsp.update_attribute(:password_reset_token, subject.generate_token)
|
179
|
+
token = user_wsp.password_reset_token
|
180
|
+
expect(subject.token_correct?(user_token:user_wsp.password_reset_token, received_token:token)).to eq(true)
|
198
181
|
end
|
199
182
|
|
200
183
|
it "returns false if given token doesn't eq user.token" do
|
201
|
-
|
202
|
-
token =
|
203
|
-
expect(subject.token_correct?(user_token:
|
184
|
+
user_wsp.update_attribute(:password_reset_token, subject.generate_token)
|
185
|
+
token = subject.generate_token
|
186
|
+
expect(subject.token_correct?(user_token:user_wsp.password_reset_token, received_token:token)).to eq(false)
|
204
187
|
end
|
205
188
|
end
|
206
189
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
include JumpIn::Strategies
|
4
|
+
|
5
|
+
describe JumpIn::Strategies do
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
class CustomStrategy < JumpIn::Strategies::Base
|
9
|
+
has_unique_attributes [:custom_attr]
|
10
|
+
|
11
|
+
def authenticate_user
|
12
|
+
@user.authenticate(@auth_params[:custom_attr]) ? true : false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class CustomUser
|
17
|
+
def authenticate(to_verify)
|
18
|
+
return true if to_verify == "authentication_pass"
|
19
|
+
false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
after(:all) do
|
25
|
+
JumpIn::Strategies::Base::STRATEGIES.delete(CustomStrategy)
|
26
|
+
JumpIn::Strategies::Base::DETECTABLE_ATTRIBUTES.delete(CustomStrategy)
|
27
|
+
end
|
28
|
+
|
29
|
+
context ".inherited" do
|
30
|
+
it "STRATEGIES include default strategies" do
|
31
|
+
expect(JumpIn::Strategies::Base::STRATEGIES).to include(JumpIn::Strategies::ByPassword)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "STRATEGIES include custom strategies" do
|
35
|
+
expect(JumpIn::Strategies::Base::STRATEGIES).to include(CustomStrategy)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "#authenticate_user" do
|
40
|
+
it "calls custom authenticate method for custom strategy, returns true" do
|
41
|
+
custom_user = CustomUser.new
|
42
|
+
custom_strategy = CustomStrategy.new(
|
43
|
+
user: custom_user,
|
44
|
+
auth_params: { custom_attr: "authentication_pass" })
|
45
|
+
expect(custom_strategy.authenticate_user).to eq(true)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "calls custom authenticate method for custom strategy, returns false" do
|
49
|
+
custom_user = CustomUser.new
|
50
|
+
custom_strategy = CustomStrategy.new(
|
51
|
+
user: custom_user,
|
52
|
+
auth_params: { custom_attr: "wrong_pass" })
|
53
|
+
expect(custom_strategy.authenticate_user).to eq(false)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context ".has_unique_attribute" do
|
58
|
+
it "adds strategy_unique_attribute to DETECTABLE_ATTRIBUTES" do
|
59
|
+
expect(JumpIn::Strategies::Base::DETECTABLE_ATTRIBUTES.values).to include([:custom_attr])
|
60
|
+
end
|
61
|
+
|
62
|
+
it "raises error when strategy_unique_attribute is not unique, removes strategy from STRATEGIES" do
|
63
|
+
expect {
|
64
|
+
class AnotherCustomStrategy < JumpIn::Strategies::Base
|
65
|
+
has_unique_attributes [:custom_attr]
|
66
|
+
end
|
67
|
+
}.to raise_error(JumpIn::AttributesNotUnique, 'Custom authentication strategy attribute is not unique.')
|
68
|
+
expect(JumpIn::Strategies::Base::STRATEGIES).to_not include(AnotherCustomStrategy)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
class TokenatorController < ActionController::Base
|
4
|
+
include JumpIn::Tokenator
|
5
|
+
end
|
6
|
+
|
7
|
+
describe TokenatorController, type: :controller do
|
8
|
+
let(:random) { 'e3d6ce35f9f6f7ea696cd180' }
|
9
|
+
let(:time) { Time.parse('2015-08-28T19:35:56+02:00') }
|
10
|
+
let(:token) { "ZTNkNmNlMzVmOWY2ZjdlYTY5NmNkMTgwLjIwMTUtMDgtMjhUMTk6MzU6NTYrMDI6MDA=" }
|
11
|
+
|
12
|
+
context ".generate_token" do
|
13
|
+
it 'generates token' do
|
14
|
+
allow(SecureRandom).to receive(:hex).with(12).and_return(random)
|
15
|
+
generated_token = nil
|
16
|
+
travel_to time do
|
17
|
+
generated_token = subject.generate_token
|
18
|
+
end
|
19
|
+
expect(generated_token).to eq(token)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context ".decode_and_split_token" do
|
24
|
+
it "decodes valid token" do
|
25
|
+
expect(subject.decode_and_split_token(token)).to eq([random, time.xmlschema])
|
26
|
+
end
|
27
|
+
|
28
|
+
it "raises JumpIn error for invalid token" do
|
29
|
+
expect { subject.decode_and_split_token("invalid") }.to raise_error(JumpIn::InvalidTokenError, 'Invalid token passed.')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context ".decode_time" do
|
34
|
+
it "decodes time for valid token" do
|
35
|
+
expect(subject.decode_time(token)).to eq(time)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "raises JumpIn error for invalid token" do
|
39
|
+
expect { subject.decode_time("invalid") }.to raise_error(JumpIn::InvalidTokenError, 'Invalid token passed.')
|
40
|
+
end
|
41
|
+
|
42
|
+
it "raises JumpIn error for random passed as token (no delimiter => no time to parse)" do
|
43
|
+
expect { subject.decode_time(random) }.to raise_error(JumpIn::InvalidTokenError, 'Invalid token passed.')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -16,6 +16,7 @@ RSpec.configure do |config|
|
|
16
16
|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
17
17
|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
18
18
|
config.include FactoryGirl::Syntax::Methods
|
19
|
+
config.include ActiveSupport::Testing::TimeHelpers
|
19
20
|
|
20
21
|
config.use_transactional_fixtures = true
|
21
22
|
|
@@ -1,3 +1,12 @@
|
|
1
|
+
|
2
|
+
def run_config(permanent: false, expires: 20.years, expiration_time: 2.hours)
|
3
|
+
JumpIn.configure do |config|
|
4
|
+
config.permanent = permanent
|
5
|
+
config.expires = expires
|
6
|
+
config.expiration_time = expiration_time
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
1
10
|
# module Authentication
|
2
11
|
|
3
12
|
def set_session(object)
|
@@ -53,12 +62,3 @@ def allow_to_receive_token_correct_and_return(user, token, boolean)
|
|
53
62
|
with(user_token: user.password_reset_token, received_token: token).
|
54
63
|
and_return(boolean)
|
55
64
|
end
|
56
|
-
|
57
|
-
# dummy App
|
58
|
-
|
59
|
-
def log_in(email, password)
|
60
|
-
fill_in "session_email", with: email
|
61
|
-
fill_in "session_password", with: password
|
62
|
-
click_button "Log in"
|
63
|
-
end
|
64
|
-
|