devise_g5_authenticatable 0.1.0
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 +7 -0
- data/.gitignore +21 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +25 -0
- data/Gemfile +23 -0
- data/LICENSE +20 -0
- data/README.md +243 -0
- data/Rakefile +20 -0
- data/app/controllers/devise_g5_authenticatable/registrations_controller.rb +5 -0
- data/app/controllers/devise_g5_authenticatable/sessions_controller.rb +58 -0
- data/circle.yml +4 -0
- data/config/initializers/devise_g5_authenticatable.rb +3 -0
- data/config/locales/en.yml +6 -0
- data/devise_g5_authenticatable.gemspec +24 -0
- data/lib/devise_g5_authenticatable.rb +16 -0
- data/lib/devise_g5_authenticatable/controllers/helpers.rb +37 -0
- data/lib/devise_g5_authenticatable/controllers/url_helpers.rb +13 -0
- data/lib/devise_g5_authenticatable/engine.rb +11 -0
- data/lib/devise_g5_authenticatable/g5.rb +4 -0
- data/lib/devise_g5_authenticatable/g5/auth_password_validator.rb +30 -0
- data/lib/devise_g5_authenticatable/g5/auth_user_creator.rb +48 -0
- data/lib/devise_g5_authenticatable/g5/auth_user_updater.rb +43 -0
- data/lib/devise_g5_authenticatable/g5/user_exporter.rb +61 -0
- data/lib/devise_g5_authenticatable/models/g5_authenticatable.rb +99 -0
- data/lib/devise_g5_authenticatable/models/protected_attributes.rb +16 -0
- data/lib/devise_g5_authenticatable/omniauth.rb +9 -0
- data/lib/devise_g5_authenticatable/routes.rb +58 -0
- data/lib/devise_g5_authenticatable/version.rb +3 -0
- data/lib/tasks/g5/export_users.rake +13 -0
- data/spec/controllers/helpers_spec.rb +295 -0
- data/spec/controllers/sessions_controller_spec.rb +256 -0
- data/spec/controllers/url_helpers_spec.rb +332 -0
- data/spec/dummy/.gitignore +15 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/images/rails.png +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/javascripts/custom_sessions.js +2 -0
- data/spec/dummy/app/assets/javascripts/home.js +2 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/assets/stylesheets/custom_sessions.css +4 -0
- data/spec/dummy/app/assets/stylesheets/home.css +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/custom_registrations_controllers.rb +2 -0
- data/spec/dummy/app/controllers/custom_sessions_controller.rb +2 -0
- data/spec/dummy/app/controllers/home_controller.rb +4 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/helpers/custom_sessions_helper.rb +2 -0
- data/spec/dummy/app/helpers/home_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/admin.rb +3 -0
- data/spec/dummy/app/models/user.rb +10 -0
- data/spec/dummy/app/views/anonymous/new.html.erb +0 -0
- data/spec/dummy/app/views/home/index.html.erb +1 -0
- data/spec/dummy/app/views/layouts/application.html.erb +16 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +64 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml.ci +6 -0
- data/spec/dummy/config/database.yml.sample +13 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +39 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/devise.rb +259 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/devise.en.yml +60 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +70 -0
- data/spec/dummy/db/migrate/20131230235849_devise_create_users.rb +42 -0
- data/spec/dummy/db/migrate/20140102213131_drop_database_authenticatable.rb +16 -0
- data/spec/dummy/db/migrate/20140103032308_drop_recoverable.rb +16 -0
- data/spec/dummy/db/migrate/20140103042329_drop_rememberable.rb +13 -0
- data/spec/dummy/db/migrate/20140103174810_add_omniauth_columns_to_users.rb +18 -0
- data/spec/dummy/db/migrate/20140103191601_add_email_back_to_user.rb +8 -0
- data/spec/dummy/db/migrate/20140113202948_devise_create_admins.rb +42 -0
- data/spec/dummy/db/migrate/20140113233821_add_provider_and_uid_to_admins.rb +8 -0
- data/spec/dummy/db/schema.rb +50 -0
- data/spec/dummy/db/seeds.rb +7 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/lib/tasks/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/robots.txt +5 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/vendor/assets/javascripts/.gitkeep +0 -0
- data/spec/dummy/vendor/assets/stylesheets/.gitkeep +0 -0
- data/spec/dummy/vendor/plugins/.gitkeep +0 -0
- data/spec/factories/admin.rb +10 -0
- data/spec/factories/user.rb +10 -0
- data/spec/features/edit_registration_spec.rb +109 -0
- data/spec/features/registration_spec.rb +99 -0
- data/spec/features/sign_in_spec.rb +91 -0
- data/spec/features/sign_out_spec.rb +7 -0
- data/spec/g5/auth_password_validator_spec.rb +81 -0
- data/spec/g5/auth_user_creator_spec.rb +100 -0
- data/spec/g5/auth_user_updater_spec.rb +113 -0
- data/spec/g5/user_exporter_spec.rb +105 -0
- data/spec/models/g5_authenticatable_spec.rb +540 -0
- data/spec/models/protected_attributes_spec.rb +17 -0
- data/spec/routing/registrations_routing_spec.rb +107 -0
- data/spec/routing/sessions_routing_spec.rb +111 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/support/devise.rb +3 -0
- data/spec/support/omniauth.rb +3 -0
- data/spec/support/shared_contexts/oauth_error.rb +9 -0
- data/spec/support/shared_contexts/rake.rb +21 -0
- data/spec/support/shared_examples/registration_error.rb +15 -0
- data/spec/support/user_feature_methods.rb +26 -0
- data/spec/tasks/export_users_spec.rb +90 -0
- metadata +293 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
+
div.dialog {
|
|
8
|
+
width: 25em;
|
|
9
|
+
padding: 0 4em;
|
|
10
|
+
margin: 4em auto 0 auto;
|
|
11
|
+
border: 1px solid #ccc;
|
|
12
|
+
border-right-color: #999;
|
|
13
|
+
border-bottom-color: #999;
|
|
14
|
+
}
|
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<!-- This file lives in public/404.html -->
|
|
21
|
+
<div class="dialog">
|
|
22
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
|
23
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
|
24
|
+
</div>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
+
div.dialog {
|
|
8
|
+
width: 25em;
|
|
9
|
+
padding: 0 4em;
|
|
10
|
+
margin: 4em auto 0 auto;
|
|
11
|
+
border: 1px solid #ccc;
|
|
12
|
+
border-right-color: #999;
|
|
13
|
+
border-bottom-color: #999;
|
|
14
|
+
}
|
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<!-- This file lives in public/422.html -->
|
|
21
|
+
<div class="dialog">
|
|
22
|
+
<h1>The change you wanted was rejected.</h1>
|
|
23
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
|
24
|
+
</div>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
+
div.dialog {
|
|
8
|
+
width: 25em;
|
|
9
|
+
padding: 0 4em;
|
|
10
|
+
margin: 4em auto 0 auto;
|
|
11
|
+
border: 1px solid #ccc;
|
|
12
|
+
border-right-color: #999;
|
|
13
|
+
border-bottom-color: #999;
|
|
14
|
+
}
|
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<!-- This file lives in public/500.html -->
|
|
21
|
+
<div class="dialog">
|
|
22
|
+
<h1>We're sorry, but something went wrong.</h1>
|
|
23
|
+
</div>
|
|
24
|
+
</body>
|
|
25
|
+
</html>
|
|
File without changes
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
|
3
|
+
|
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
|
6
|
+
require 'rails/commands'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
FactoryGirl.define do
|
|
2
|
+
factory :admin do
|
|
3
|
+
sequence(:email) { |n| "admin.#{n}@test.host" }
|
|
4
|
+
password 'my_new_secret'
|
|
5
|
+
password_confirmation 'my_new_secret'
|
|
6
|
+
provider 'g5'
|
|
7
|
+
sequence(:uid) { |n| "remote-admin-#{n}" }
|
|
8
|
+
sequence(:g5_access_token) { |n| "token-abc123-#{n}" }
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
FactoryGirl.define do
|
|
2
|
+
factory :user do
|
|
3
|
+
sequence(:email) { |n| "user.#{n}@test.host" }
|
|
4
|
+
password 'my_new_secret'
|
|
5
|
+
password_confirmation 'my_new_secret'
|
|
6
|
+
provider 'g5'
|
|
7
|
+
sequence(:uid) { |n| "remote-user-#{n}" }
|
|
8
|
+
sequence(:g5_access_token) { |n| "token-abc123-#{n}" }
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Editing a user registration' do
|
|
4
|
+
subject(:update_registration) { click_button 'Update' }
|
|
5
|
+
|
|
6
|
+
let(:user) { create(:user) }
|
|
7
|
+
|
|
8
|
+
let(:auth_client) { double(:auth_client, update_user: auth_user, me: auth_user) }
|
|
9
|
+
|
|
10
|
+
let(:auth_user) { double(:auth_user, id: user.uid, email: user.email) }
|
|
11
|
+
before do
|
|
12
|
+
allow(G5AuthenticationClient::Client).to receive(:new).and_return(auth_client)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
before do
|
|
16
|
+
visit_path_and_login_with(edit_user_registration_path, user)
|
|
17
|
+
fill_in 'Email', with: email
|
|
18
|
+
fill_in 'Password', with: password
|
|
19
|
+
fill_in 'Password confirmation', with: password_confirmation
|
|
20
|
+
fill_in 'Current password', with: current_password
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
let(:email) { 'new.email@test.host' }
|
|
24
|
+
let(:password) { '' }
|
|
25
|
+
let(:password_confirmation) { password }
|
|
26
|
+
let(:current_password) { user.password }
|
|
27
|
+
|
|
28
|
+
context 'when current password is valid' do
|
|
29
|
+
context 'when password is blank' do
|
|
30
|
+
it 'should update the email locally' do
|
|
31
|
+
update_registration
|
|
32
|
+
user.reload
|
|
33
|
+
expect(user.email).to eq(email)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'should update the email on the auth server' do
|
|
37
|
+
expect(auth_client).to receive(:update_user).with({id: user.uid,
|
|
38
|
+
email: email,
|
|
39
|
+
password: nil,
|
|
40
|
+
password_confirmation: nil})
|
|
41
|
+
update_registration
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context 'when password is updated' do
|
|
46
|
+
let(:password) { 'a brand new password' }
|
|
47
|
+
|
|
48
|
+
it 'should update the password on the auth server' do
|
|
49
|
+
expect(auth_client).to receive(:update_user).with({id: user.uid,
|
|
50
|
+
email: email,
|
|
51
|
+
password: password,
|
|
52
|
+
password_confirmation: password_confirmation})
|
|
53
|
+
update_registration
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
context 'when email is blank' do
|
|
58
|
+
let(:email) { '' }
|
|
59
|
+
|
|
60
|
+
it 'should display an error message' do
|
|
61
|
+
update_registration
|
|
62
|
+
expect(page).to have_content("Email can't be blank")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'should not update the credentials on the auth server' do
|
|
66
|
+
expect(auth_client).to_not receive(:update_user)
|
|
67
|
+
update_registration
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context 'when the auth server returns an error' do
|
|
72
|
+
include_context 'OAuth2::Error'
|
|
73
|
+
before { allow(auth_client).to receive(:update_user).and_raise(oauth_error) }
|
|
74
|
+
|
|
75
|
+
it 'should display an error message' do
|
|
76
|
+
update_registration
|
|
77
|
+
expect(page).to have_content(error_message)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'should not update the email locally' do
|
|
81
|
+
update_registration
|
|
82
|
+
user.reload
|
|
83
|
+
expect(user.email).to_not eq(email)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
context 'when current password is invalid' do
|
|
89
|
+
include_context 'OAuth2::Error'
|
|
90
|
+
let(:error_message) { 'invalid_resource_owner' }
|
|
91
|
+
before { allow(auth_client).to receive(:me).and_raise(oauth_error) }
|
|
92
|
+
|
|
93
|
+
it 'should display an error message' do
|
|
94
|
+
update_registration
|
|
95
|
+
expect(page).to have_content('Current password is invalid')
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it 'should not update the credentials on the auth server' do
|
|
99
|
+
expect(auth_client).to_not receive(:update_user)
|
|
100
|
+
update_registration
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it 'should not update the email locally' do
|
|
104
|
+
update_registration
|
|
105
|
+
user.reload
|
|
106
|
+
expect(user.email).to_not eq(email)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'User registration' do
|
|
4
|
+
subject(:register_user) { click_button 'Sign up' }
|
|
5
|
+
|
|
6
|
+
let(:auth_client) { double(:auth_client, create_user: auth_user) }
|
|
7
|
+
let(:auth_user) { double(:auth_user, id: uid, email: email) }
|
|
8
|
+
before do
|
|
9
|
+
allow(G5AuthenticationClient::Client).to receive(:new).and_return(auth_client)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
visit new_user_registration_path
|
|
14
|
+
fill_in 'Email', with: email
|
|
15
|
+
fill_in 'Password', with: password
|
|
16
|
+
fill_in 'Password confirmation', with: password_confirmation
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
let(:email) { 'fred.rogers@theneighborhood.net' }
|
|
20
|
+
let(:password) { 'wontyoubemyneighbor' }
|
|
21
|
+
let(:password_confirmation) { password }
|
|
22
|
+
let(:uid) { '42-remote-uid' }
|
|
23
|
+
|
|
24
|
+
context 'when registration is valid' do
|
|
25
|
+
it 'should create a user' do
|
|
26
|
+
expect { register_user }.to change { User.count }.by(1)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'should redirect to the root path' do
|
|
30
|
+
register_user
|
|
31
|
+
expect(current_path).to eq(root_path)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'should create the user on the auth server' do
|
|
35
|
+
expect(auth_client).to receive(:create_user).
|
|
36
|
+
with({email: email,
|
|
37
|
+
password: password,
|
|
38
|
+
password_confirmation: password_confirmation}).
|
|
39
|
+
and_return(auth_user)
|
|
40
|
+
register_user
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'needs a token from somewhere - figure it out'
|
|
44
|
+
|
|
45
|
+
it 'should assign the provider and uid to the user' do
|
|
46
|
+
register_user
|
|
47
|
+
user = User.find_by_email(email)
|
|
48
|
+
expect(user.provider).to eq('g5')
|
|
49
|
+
expect(user.uid).to eq(uid)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context 'when there is an error on the auth server' do
|
|
54
|
+
include_context 'OAuth2::Error'
|
|
55
|
+
before { allow(auth_client).to receive(:create_user).and_raise(oauth_error) }
|
|
56
|
+
|
|
57
|
+
it 'should display an error message' do
|
|
58
|
+
register_user
|
|
59
|
+
expect(page).to have_content(error_message)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'should not create the user locally' do
|
|
63
|
+
expect { register_user }.to_not change { User.count }
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context 'when password is blank' do
|
|
68
|
+
let(:password) { ' ' }
|
|
69
|
+
|
|
70
|
+
it_should_behave_like 'a registration validation error' do
|
|
71
|
+
let(:error_message) { "Password can't be blank" }
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context 'when password does not match confirmation' do
|
|
76
|
+
let(:password_confirmation) { 'something else entirely' }
|
|
77
|
+
|
|
78
|
+
it_should_behave_like 'a registration validation error' do
|
|
79
|
+
let(:error_message) { "Password doesn't match confirmation" }
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context 'when email is blank' do
|
|
84
|
+
let(:email) { '' }
|
|
85
|
+
|
|
86
|
+
it_should_behave_like 'a registration validation error' do
|
|
87
|
+
let(:error_message) { "Email can't be blank" }
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context 'when email is not unique' do
|
|
92
|
+
let(:user) { create(:user) }
|
|
93
|
+
let(:email) { user.email }
|
|
94
|
+
|
|
95
|
+
it_should_behave_like 'a registration validation error' do
|
|
96
|
+
let(:error_message) { 'Email has already been taken' }
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Signing in' do
|
|
4
|
+
context 'when visiting a protected page' do
|
|
5
|
+
let(:protected_path) { edit_user_registration_path }
|
|
6
|
+
|
|
7
|
+
context 'with valid credentials' do
|
|
8
|
+
before do
|
|
9
|
+
stub_g5_omniauth(user)
|
|
10
|
+
visit protected_path
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context 'when user exists locally' do
|
|
14
|
+
let(:user) { create(:user) }
|
|
15
|
+
|
|
16
|
+
it 'should sign in the user successfully' do
|
|
17
|
+
expect(page).to have_content('Signed in successfully.')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'should redirect the user to the requested path' do
|
|
21
|
+
expect(current_path).to eq(protected_path)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context 'when user does not exist locally' do
|
|
26
|
+
let(:user) { build(:user, uid: 42) }
|
|
27
|
+
|
|
28
|
+
it 'should display an informative message' do
|
|
29
|
+
expect(page).to have_content('You must sign up before continuing.')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'should redirect the user to the registration page' do
|
|
33
|
+
expect(current_path).to eq(new_user_registration_path)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'should prefill the Email field' do
|
|
37
|
+
expect(find_field('Email').value).to eq(user.email)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context 'with invalid credentials' do
|
|
43
|
+
before do
|
|
44
|
+
stub_g5_invalid_credentials
|
|
45
|
+
visit protected_path
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
let(:user) { create(:user) }
|
|
49
|
+
|
|
50
|
+
it 'should display an error' do
|
|
51
|
+
expect(page).to have_content('Invalid credentials')
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context 'when clicking a login link' do
|
|
57
|
+
before do
|
|
58
|
+
visit root_path
|
|
59
|
+
stub_g5_omniauth(user)
|
|
60
|
+
click_link 'Login'
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
let(:user) { create(:user) }
|
|
64
|
+
|
|
65
|
+
it 'should sign in the user successfully' do
|
|
66
|
+
expect(page).to have_content('Signed in successfully.')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'should redirect the user to the root path' do
|
|
70
|
+
expect(current_path).to eq(root_path)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
context 'when clicking a login link after signing in' do
|
|
75
|
+
before do
|
|
76
|
+
visit_path_and_login_with(edit_user_registration_path, user)
|
|
77
|
+
visit root_path
|
|
78
|
+
click_link 'Login'
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
let(:user) { create(:user) }
|
|
82
|
+
|
|
83
|
+
it 'should warn the user that they are currently signed in' do
|
|
84
|
+
expect(page).to have_content('You are already signed in.')
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'should redirect the user to the root path' do
|
|
88
|
+
expect(current_path).to eq(root_path)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Devise::G5::AuthPasswordValidator do
|
|
4
|
+
let(:validator) { described_class.new(model) }
|
|
5
|
+
|
|
6
|
+
let(:model) { build_stubbed(:user) }
|
|
7
|
+
|
|
8
|
+
describe '#valid_password?' do
|
|
9
|
+
subject(:valid_password?) { validator.valid_password?(password) }
|
|
10
|
+
|
|
11
|
+
let(:password) { 'password to check' }
|
|
12
|
+
|
|
13
|
+
let(:auth_client) { double(:g5_authentication_client, me: auth_user) }
|
|
14
|
+
let(:auth_user) { double(:auth_user, uid: model.uid, email: model.email) }
|
|
15
|
+
|
|
16
|
+
let(:oauth_error) { OAuth2::Error.new(response) }
|
|
17
|
+
let(:response) { double(:oauth_response, parsed: oauth_error_hash).as_null_object }
|
|
18
|
+
|
|
19
|
+
before do
|
|
20
|
+
allow(G5AuthenticationClient::Client).to receive(:new).
|
|
21
|
+
and_return(auth_client)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context 'with valid password' do
|
|
25
|
+
before { valid_password? }
|
|
26
|
+
|
|
27
|
+
it 'should initialize auth client with the username' do
|
|
28
|
+
expect(G5AuthenticationClient::Client).to have_received(:new).
|
|
29
|
+
with(hash_including(username: model.email))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'should initialize auth client with the password' do
|
|
33
|
+
expect(G5AuthenticationClient::Client).to have_received(:new).
|
|
34
|
+
with(hash_including(password: password))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'should retrieve the auth user associated with these credentials' do
|
|
38
|
+
expect(auth_client).to have_received(:me)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'should return true' do
|
|
42
|
+
expect(valid_password?).to be_true
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context 'with invalid password' do
|
|
47
|
+
before { allow(auth_client).to receive(:me).and_raise(oauth_error) }
|
|
48
|
+
|
|
49
|
+
let(:oauth_error_hash) do
|
|
50
|
+
{'error' => 'invalid_resource_owner',
|
|
51
|
+
'error_description' => 'The provided resource owner credentials are not valid, or resource owner cannot be found.'}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'should return false' do
|
|
55
|
+
expect(valid_password?).to be_false
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
context 'with blank password' do
|
|
60
|
+
before { allow(auth_client).to receive(:me).and_raise(runtime_error) }
|
|
61
|
+
let(:runtime_error) { RuntimeError.new('Insufficient credentials for access token. Supply a username/password or authentication code.') }
|
|
62
|
+
|
|
63
|
+
it 'should return false' do
|
|
64
|
+
expect(valid_password?).to be_false
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context 'when an unrelated server error occurs' do
|
|
69
|
+
before { allow(auth_client).to receive(:me).and_raise(oauth_error) }
|
|
70
|
+
|
|
71
|
+
let(:oauth_error_hash) do
|
|
72
|
+
{'error' => 'unauthorized_client',
|
|
73
|
+
'error_description' => 'The client is not authorized to perform this request using this method.'}
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'should re-raise the error' do
|
|
77
|
+
expect { valid_password? }.to raise_error(oauth_error)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|