authenticate 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -46,24 +46,24 @@ describe SecuredAppsController, type: :controller do
46
46
  before { sign_in }
47
47
 
48
48
  it 'allows access to new' do
49
- get :new
49
+ do_get :new
50
50
  expect(subject).to_not deny_access
51
51
  end
52
52
 
53
53
  it 'allows access to show' do
54
- get :show
54
+ do_get :show
55
55
  expect(subject).to_not deny_access
56
56
  end
57
57
  end
58
58
 
59
59
  context 'with an unauthenticated visitor' do
60
60
  it 'allows access to new' do
61
- get :new
61
+ do_get :new
62
62
  expect(subject).to_not deny_access
63
63
  end
64
64
 
65
65
  it 'denies access to show' do
66
- get :show
66
+ do_get :show
67
67
  expect(subject).to deny_access
68
68
  end
69
69
  end
@@ -20,7 +20,7 @@ module Dummy
20
20
  # config.i18n.default_locale = :de
21
21
 
22
22
  # Do not swallow errors in after_commit/after_rollback callbacks.
23
- config.active_record.raise_in_transactional_callbacks = true
23
+ # config.active_record.raise_in_transactional_callbacks = true
24
24
 
25
25
  end
26
26
  end
@@ -13,8 +13,8 @@ Rails.application.configure do
13
13
  config.eager_load = false
14
14
 
15
15
  # Configure static file server for tests with Cache-Control for performance.
16
- config.serve_static_files = true
17
- config.static_cache_control = 'public, max-age=3600'
16
+ # config.serve_static_files = true
17
+ # config.static_cache_control = 'public, max-age=3600'
18
18
 
19
19
  # Show full error reports and disable caching.
20
20
  config.consider_all_requests_local = true
@@ -30,6 +30,7 @@ Rails.application.configure do
30
30
  # The :test delivery method accumulates sent emails in the
31
31
  # ActionMailer::Base.deliveries array.
32
32
  config.action_mailer.delivery_method = :test
33
+ config.action_mailer.perform_deliveries = true
33
34
 
34
35
  # Randomize the order test cases are executed.
35
36
  config.active_support.test_order = :random
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+ require 'support/features/feature_helpers'
3
+
4
+ feature 'create a user with valid attributes' do
5
+
6
+ # this doesn't belong as a feature test but it will catch regressions.
7
+ # consider moving to a request spec or... something.
8
+ scenario 'increases number of users' do
9
+ expect { create_user_with_valid_params }.to change { User.count }.by(1)
10
+ end
11
+
12
+ scenario 'signs in the user after creation' do
13
+ create_user_with_valid_params
14
+ expect_user_to_be_signed_in
15
+ end
16
+
17
+ scenario 'redirects to redirect_url' do
18
+ create_user_with_valid_params
19
+ expect_path_is_redirect_url
20
+ end
21
+ end
22
+
23
+ feature 'visit a protected url, then create user' do
24
+ scenario 'redirects to the protected url after user is created' do
25
+ visit '/welcome'
26
+ create_user_with_valid_params
27
+ expect(current_path).to eq '/welcome'
28
+ end
29
+ end
30
+
31
+ feature 'create user after signed in' do
32
+ scenario 'cannot get to new user page' do
33
+ user = create(:user, email: 'test.user@example.com')
34
+ sign_in_with user.email, user.password
35
+ visit new_users_path
36
+ expect_path_is_redirect_url
37
+ end
38
+ end
39
+
40
+ def create_user_with_valid_params(user_attrs = attributes_for(:user))
41
+ visit new_users_path
42
+ fill_in 'user_email', with: user_attrs[:email]
43
+ fill_in 'user_password', with: user_attrs[:password]
44
+ click_button 'Sign up'
45
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'support/features/feature_helpers'
3
+
4
+ feature 'visitor at new user form, not signed in' do
5
+ scenario 'visit with no arguments' do
6
+ visit new_users_path
7
+ expect(page).to have_current_path new_users_path
8
+ within 'h2' do
9
+ expect(page).to have_content /Sign up/i
10
+ end
11
+ end
12
+
13
+ scenario 'defaults email to value provided in query string' do
14
+ visit new_users_path(user: { email: 'dude@example.com' })
15
+ expect(page).to have_selector 'input[value="dude@example.com"]'
16
+ end
17
+ end
18
+
19
+ feature 'visitor at new user form, already signed in' do
20
+ scenario 'redirects user to redirect_url' do
21
+ user = create(:user, email: 'test.user@example.com')
22
+ sign_in_with 'Test.USER@example.com', user.password
23
+ visit new_users_path
24
+ expect_path_is_redirect_url
25
+ end
26
+ end
@@ -10,6 +10,7 @@ feature 'visitor requests password reset' do
10
10
  visit sign_in_path
11
11
  click_link 'Forgot Password'
12
12
  expect(current_path).to eq new_password_path
13
+ expect(page).to have_content I18n.t("passwords.new.description")
13
14
  end
14
15
 
15
16
  scenario 'uses valid email' do
@@ -21,11 +22,12 @@ feature 'visitor requests password reset' do
21
22
  expect_password_reset_email_for user
22
23
  end
23
24
 
24
- scenario 'with a non-user-account email' do
25
+ scenario 'with an unknown email' do
25
26
  request_password_reset_for 'fake.email@example.com'
26
27
 
27
28
  expect_password_change_request_success_message
28
29
  expect_mailer_to_have_no_deliveries
30
+ expect(current_path).to eq sign_in_path
29
31
  end
30
32
 
31
33
  scenario 'with invalid email' do
@@ -1,39 +1,111 @@
1
1
  require 'spec_helper'
2
2
  require 'support/features/feature_helpers'
3
3
 
4
+
5
+ feature 'visit password edit screen' do
6
+ scenario 'with valid token in url, redirects to the edit page with the token removed from the url' do
7
+ user = create(:user, :with_password_reset_token_and_timestamp)
8
+ visit_password_reset_page_for(user)
9
+ expect(current_path).to eq edit_users_password_path(user)
10
+ expect(current_path).to_not have_content('token')
11
+ end
12
+
13
+ scenario 'with an invalid token in url, failure and prompt to request a password reset' do
14
+ user = create(:user, :with_password_reset_token_and_timestamp)
15
+ visit_password_reset_page_for(user, 'this is an invalid token')
16
+ expect_forbidden_failure
17
+ end
18
+
19
+ scenario 'with a valid token, but an expired timestamp' do
20
+ user = create(:user, :with_password_reset_token_and_timestamp, password_reset_sent_at: 20.years.ago)
21
+ visit_password_reset_page_for(user)
22
+ expect_token_expired_failure
23
+ end
24
+
25
+ scenario 'with a nil token' do
26
+ user = create(:user)
27
+ visit_password_reset_page_for(user, token: nil)
28
+ expect_forbidden_failure
29
+ end
30
+ end
31
+
32
+
4
33
  feature 'visitor updates password' do
5
34
  before(:each) do
6
35
  @user = create(:user, :with_password_reset_token_and_timestamp)
7
36
  end
8
37
 
9
- scenario 'with a valid password' do
38
+ scenario 'with valid password, signs in user' do
10
39
  update_password @user, 'newpassword'
11
-
12
40
  expect_user_to_be_signed_in
13
41
  end
14
42
 
15
- scenario 'with a blank password' do
16
- update_password @user, ''
17
-
18
- expect(page).to have_content I18n.t('flashes.failure_after_update')
19
- expect_user_to_be_signed_out
43
+ scenario 'with a valid password, password is updated' do
44
+ old_pw = @user.encrypted_password
45
+ update_password @user, 'newpassword'
46
+ expect_password_was_updated(old_pw)
20
47
  end
21
48
 
22
- scenario 'signs in with new password' do
49
+ scenario 'password change signs in user' do
23
50
  update_password @user, 'newpassword'
24
-
25
51
  sign_out
26
52
  sign_in_with @user.email, 'newpassword'
27
53
  expect_user_to_be_signed_in
28
54
  end
55
+
56
+ scenario 'signs in, redirects user' do
57
+ update_password @user, 'newpassword'
58
+ expect_path_is_redirect_url
59
+ end
60
+ end
61
+
62
+ feature 'visitor updates password with invalid password' do
63
+ before(:each) do
64
+ @user = create(:user, :with_password_reset_token_and_timestamp)
65
+ end
66
+
67
+ scenario 'with a blank password, signs out user' do
68
+ update_password @user, ''
69
+ expect_invalid_password
70
+ expect_user_to_be_signed_out
71
+ end
72
+
73
+ scenario 'with a short password, flashes invalid password' do
74
+ update_password @user, 'short'
75
+ expect_invalid_password
76
+ expect_user_to_be_signed_out
77
+ end
29
78
  end
30
79
 
80
+
31
81
  def update_password(user, password)
32
82
  visit_password_reset_page_for user
33
83
  fill_in 'password_reset_password', with: password
34
84
  click_button 'Save this password'
35
85
  end
36
86
 
37
- def visit_password_reset_page_for(user)
38
- visit edit_users_password_path(id: user, token: user.password_reset_token)
87
+ def visit_password_reset_page_for(user, token = user.password_reset_token)
88
+ visit edit_users_password_path(id: user, token: token)
89
+ end
90
+
91
+ def expect_invalid_password
92
+ expect(page).to have_content I18n.t('flashes.failure_after_update')
93
+ end
94
+
95
+ def expect_forbidden_failure
96
+ expect(page).to have_content I18n.t('passwords.new.description')
97
+ expect(page).to have_content I18n.t('flashes.failure_when_forbidden')
98
+ end
99
+
100
+ def expect_token_expired_failure
101
+ expect(page).to have_content 'Sign in'
102
+ expect(page).to have_content I18n.t('flashes.failure_token_expired')
103
+ end
104
+
105
+ # def expect_path_is_redirect_url
106
+ # expect(current_path).to eq(Authenticate.configuration.redirect_url)
107
+ # end
108
+
109
+ def expect_password_was_updated(old_password)
110
+ expect(@user.reload.encrypted_password).not_to eq old_password
39
111
  end
@@ -27,3 +27,22 @@ feature 'visitor signs in' do
27
27
  expect_user_to_be_signed_out
28
28
  end
29
29
  end
30
+
31
+ feature 'visitor goes to sign in page' do
32
+ scenario 'signed out user is not redirected' do
33
+ visit sign_in_path
34
+ expect_sign_in_path
35
+ end
36
+
37
+ scenario 'signed in user is redirected' do
38
+ user = create(:user)
39
+ sign_in_with user.email, user.password
40
+ visit sign_in_path
41
+ expect_path_is_redirect_url
42
+ expect_user_to_be_signed_in
43
+ end
44
+ end
45
+
46
+ def expect_sign_in_path
47
+ expect(current_path).to eq sign_in_path
48
+ end
@@ -12,10 +12,21 @@ feature 'visitor signs out' do
12
12
  expect_user_to_be_signed_out
13
13
  end
14
14
 
15
- scenario 'sign out and sign out again' do
15
+ scenario 'sign out again' do
16
16
  sign_in_with(@user.email, @user.password)
17
17
  visit sign_out_path
18
18
  visit sign_out_path
19
19
  expect_user_to_be_signed_out
20
20
  end
21
+
22
+ scenario 'redirects to sign in' do
23
+ sign_in_with(@user.email, @user.password)
24
+ visit sign_out_path
25
+ expect_sign_in_path
26
+ end
27
+ end
28
+
29
+
30
+ def expect_sign_in_path
31
+ expect(current_path).to eq sign_in_path
21
32
  end
@@ -40,7 +40,7 @@ describe Authenticate::Model::PasswordReset do
40
40
  context '#update_password' do
41
41
  subject { create(:user) }
42
42
 
43
- context 'within time time' do
43
+ context 'within time limit' do
44
44
  before(:each) { subject.password_reset_sent_at = 1.minutes.ago }
45
45
 
46
46
  it 'allows password update within time limit' do
@@ -57,19 +57,21 @@ describe Authenticate::Model::PasswordReset do
57
57
  subject.update_password 'password2'
58
58
  expect(subject.session_token).to_not eq(token)
59
59
  end
60
-
61
- it 'prevents update if token is nil'
62
60
  end
63
61
 
64
- it 'stops password update after time limit' do
65
- subject.password_reset_sent_at = 6.minutes.ago
66
- expect(subject.update_password('password2')).to be_falsey
62
+ context 'after time limit' do
63
+ it 'stops password update' do
64
+ subject.password_reset_sent_at = 6.minutes.ago
65
+ expect(subject.update_password('password2')).to be_falsey
66
+ end
67
67
  end
68
68
 
69
- it 'stops password update if password_reset_token set but password_reset_sent_at isnt' do
70
- subject.password_reset_sent_at = nil
71
- subject.password_reset_token = 'notNilResetToken'
72
- expect(subject.update_password('password2')).to be_falsey
69
+ context 'password_reset_sent_at is nil' do
70
+ it 'stops password update' do
71
+ subject.password_reset_sent_at = nil
72
+ subject.password_reset_token = 'notNilResetToken'
73
+ expect(subject.update_password('password2')).to be_falsey
74
+ end
73
75
  end
74
76
  end
75
77
  end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'CSRF rotation' do
4
+ around do |example|
5
+ ActionController::Base.allow_forgery_protection = true
6
+ example.run
7
+ ActionController::Base.allow_forgery_protection = false
8
+ end
9
+
10
+ context 'Authenticate configuration is set to rotate CSRF token on sign in' do
11
+ describe 'sign in' do
12
+ before do
13
+ @user = create(:user, password: 'password')
14
+ end
15
+ it 'rotates the CSRF token' do
16
+ Authenticate.configure { |config| config.rotate_csrf_on_sign_in = true }
17
+
18
+ # go to sign in screen, generating csrf
19
+ get sign_in_path
20
+ original_token = csrf_token
21
+
22
+ # post a login
23
+ do_post session_path, params: { **session_params }
24
+
25
+ # expect that we now have a new csrf token
26
+ expect(csrf_token).not_to eq original_token
27
+ expect(csrf_token).to be_present
28
+ end
29
+ end
30
+ end
31
+
32
+ def csrf_token
33
+ session[:_csrf_token]
34
+ end
35
+
36
+ def session_params
37
+ { session: { email: @user.email, password: @user.password }, authenticity_token: csrf_token }
38
+ end
39
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'session key assignment' do
4
+ context 'user signs in' do
5
+ before do
6
+ @user = create(:user)
7
+ do_post session_path, params: { session: { email: @user.email, password: @user.password } }
8
+ end
9
+
10
+ it 'sets user session token' do
11
+ @user.reload
12
+ expect(@user.session_token).to_not be_nil
13
+ end
14
+
15
+ it 'sets session token in cookie' do
16
+ expect(cookies['authenticate_session_token']).to_not be_nil
17
+ end
18
+
19
+ it 'sets current_user' do
20
+ expect(controller.current_user).to eq(@user)
21
+ end
22
+
23
+ context 'user signs out' do
24
+ it 'rotates user session token' do
25
+ old_session = @user.session_token
26
+ do_get sign_out_path
27
+ @user.reload
28
+ expect(@user.session_token).to_not eq old_session
29
+ end
30
+
31
+ it 'removes session cookie' do
32
+ do_get sign_out_path
33
+ expect(cookies['authenticate_session_token']).to eq ''
34
+ end
35
+
36
+ it 'sets current_user to nil' do
37
+ do_get sign_out_path
38
+ expect(controller.current_user).to be_nil
39
+ end
40
+ end
41
+ end
42
+ end