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,58 @@
|
|
|
1
|
+
module Devise
|
|
2
|
+
class Mapping
|
|
3
|
+
alias :original_initialize :initialize
|
|
4
|
+
|
|
5
|
+
def initialize(name, options)
|
|
6
|
+
set_default_g5_controllers(options)
|
|
7
|
+
original_initialize(name, options)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
def set_default_g5_controllers(options)
|
|
12
|
+
options[:controllers] ||= {}
|
|
13
|
+
options[:controllers].reverse_merge!({
|
|
14
|
+
registrations: 'devise_g5_authenticatable/registrations',
|
|
15
|
+
sessions: 'devise_g5_authenticatable/sessions'
|
|
16
|
+
})
|
|
17
|
+
options
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
module ActionDispatch::Routing
|
|
23
|
+
class Mapper
|
|
24
|
+
protected
|
|
25
|
+
def devise_session(mapping, controllers)
|
|
26
|
+
set_omniauth_path_prefix(mapping)
|
|
27
|
+
build_session_routes(mapping, controllers)
|
|
28
|
+
build_g5_omniauth_routes(mapping, controllers)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def set_omniauth_path_prefix(mapping)
|
|
32
|
+
path_prefix = Devise.omniauth_path_prefix || "/#{mapping.fullpath}/auth".squeeze("/")
|
|
33
|
+
set_omniauth_path_prefix!(path_prefix) unless ::OmniAuth.config.path_prefix.present?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def build_session_routes(mapping, controllers)
|
|
37
|
+
resource :session, only: [], controller: controllers[:sessions], path: '' do
|
|
38
|
+
get :new, path: mapping.path_names[:sign_in], as: :new
|
|
39
|
+
post :create, path: mapping.path_names[:sign_in]
|
|
40
|
+
match :destroy, path: mapping.path_names[:sign_out], as: :destroy, via: mapping.sign_out_via
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def build_g5_omniauth_routes(mapping, controllers)
|
|
45
|
+
match 'auth/g5',
|
|
46
|
+
controller: controllers[:sessions],
|
|
47
|
+
action: 'omniauth_passthru',
|
|
48
|
+
as: :g5_authorize,
|
|
49
|
+
via: [:get, :post]
|
|
50
|
+
|
|
51
|
+
match 'auth/g5/callback',
|
|
52
|
+
controller: controllers[:sessions],
|
|
53
|
+
action: 'create',
|
|
54
|
+
as: :g5_callback,
|
|
55
|
+
via: [:get, :post]
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'devise_g5_authenticatable/g5/user_exporter'
|
|
2
|
+
|
|
3
|
+
namespace :g5 do
|
|
4
|
+
desc "Create an auth user for each row in users table and dump id/password for update in auth server"
|
|
5
|
+
task :export_users, [:authorization_code, :client_id, :client_secret, :redirect_uri, :endpoint] => :environment do |t, args|
|
|
6
|
+
args.with_defaults(client_id: ENV['G5_AUTH_CLIENT_ID'],
|
|
7
|
+
client_secret: ENV['G5_AUTH_CLIENT_SECRET'],
|
|
8
|
+
redirect_uri: ENV['G5_AUTH_REDIRECT_URI'],
|
|
9
|
+
endpoint: ENV['G5_AUTH_ENDPOINT'],
|
|
10
|
+
authorization_code: ENV['G5_AUTH_AUTHORIZATION_CODE'])
|
|
11
|
+
puts G5::UserExporter.new(args).export
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe DeviseG5Authenticatable::Helpers do
|
|
4
|
+
controller(ActionController::Base) do
|
|
5
|
+
include Devise::Controllers::Helpers
|
|
6
|
+
include DeviseG5Authenticatable::Helpers
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe '#clear_blank_passwords' do
|
|
10
|
+
subject(:clear_passwords) { get :index, password_params }
|
|
11
|
+
before { clear_passwords }
|
|
12
|
+
|
|
13
|
+
controller do
|
|
14
|
+
before_filter :clear_blank_passwords, only: :index
|
|
15
|
+
|
|
16
|
+
def index
|
|
17
|
+
render status: 200, text: 'Index'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'when password params are populated' do
|
|
22
|
+
let(:password_params) do
|
|
23
|
+
{
|
|
24
|
+
scope => {
|
|
25
|
+
password: password,
|
|
26
|
+
password_confirmation: password_confirmation,
|
|
27
|
+
current_password: current_password,
|
|
28
|
+
email: 'foo@test.host'
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
let(:scope) { :user }
|
|
34
|
+
|
|
35
|
+
let(:password) { 'some_secret' }
|
|
36
|
+
let(:password_confirmation) { 'some_other_secret' }
|
|
37
|
+
let(:current_password) { 'current_secret' }
|
|
38
|
+
|
|
39
|
+
context 'with user scope' do
|
|
40
|
+
let(:scope) { :user }
|
|
41
|
+
|
|
42
|
+
context 'with non-blank password params' do
|
|
43
|
+
it 'should not change the password param' do
|
|
44
|
+
expect(controller.params[:user][:password]).to eq(password)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'should not change the password_confirmation param' do
|
|
48
|
+
expect(controller.params[:user][:password_confirmation]).to eq(password_confirmation)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'should not change the current_password param' do
|
|
52
|
+
expect(controller.params[:user][:current_password]).to eq(current_password)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'should not change the non-password param' do
|
|
56
|
+
expect(controller.params[:user][:email]).to eq(password_params[:user][:email])
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
context 'when password is nil' do
|
|
61
|
+
let(:password) {}
|
|
62
|
+
|
|
63
|
+
it 'should set the password param to nil' do
|
|
64
|
+
expect(controller.params[:user][:password]).to be_nil
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'should not change the password confirmation param' do
|
|
68
|
+
expect(controller.params[:user][:password_confirmation]).to eq(password_confirmation)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'should not change the current_password param' do
|
|
72
|
+
expect(controller.params[:user][:current_password]).to eq(current_password)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context 'when password is blank' do
|
|
77
|
+
let(:password) { ' ' }
|
|
78
|
+
|
|
79
|
+
it 'should set the password param to nil' do
|
|
80
|
+
expect(controller.params[:user][:password]).to be_nil
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'should not change the password confirmation param' do
|
|
84
|
+
expect(controller.params[:user][:password_confirmation]).to eq(password_confirmation)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'should not change the current_password param' do
|
|
88
|
+
expect(controller.params[:user][:current_password]).to eq(current_password)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
context 'when password confirmation is nil' do
|
|
93
|
+
let(:password_confirmation) {}
|
|
94
|
+
|
|
95
|
+
it 'should not change the password param' do
|
|
96
|
+
expect(controller.params[:user][:password]).to eq(password)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it 'should set the password_confirmation param to nil' do
|
|
100
|
+
expect(controller.params[:user][:password_confirmation]).to be_nil
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it 'should not change the current_password param' do
|
|
104
|
+
expect(controller.params[:user][:current_password]).to eq(current_password)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
context 'when password confirmation is blank' do
|
|
109
|
+
let(:password_confirmation) { ' ' }
|
|
110
|
+
|
|
111
|
+
it 'should not change the password param' do
|
|
112
|
+
expect(controller.params[:user][:password]).to eq(password)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it 'should set the password_confirmation param to nil' do
|
|
116
|
+
expect(controller.params[:user][:password_confirmation]).to be_nil
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it 'should not change the current_password param' do
|
|
120
|
+
expect(controller.params[:user][:current_password]).to eq(current_password)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
context 'when current_password is nil' do
|
|
125
|
+
let(:current_password) {}
|
|
126
|
+
|
|
127
|
+
it 'should not change the password param' do
|
|
128
|
+
expect(controller.params[:user][:password]).to eq(password)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it 'should not change the password_confirmation param' do
|
|
132
|
+
expect(controller.params[:user][:password_confirmation]).to eq(password_confirmation)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it 'should set the current password param to nil' do
|
|
136
|
+
expect(controller.params[:user][:current_password]).to be_nil
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
context 'when current_password is blank' do
|
|
141
|
+
let(:current_password) { ' ' }
|
|
142
|
+
|
|
143
|
+
it 'should not change the password param' do
|
|
144
|
+
expect(controller.params[:user][:password]).to eq(password)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it 'should not change the password_confirmation param' do
|
|
148
|
+
expect(controller.params[:user][:password_confirmation]).to eq(password_confirmation)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it 'should set the current password param to nil' do
|
|
152
|
+
expect(controller.params[:user][:current_password]).to be_nil
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
context 'with admin scope' do
|
|
158
|
+
let(:scope) { :admin }
|
|
159
|
+
|
|
160
|
+
context 'when password is blank' do
|
|
161
|
+
let(:password) { ' ' }
|
|
162
|
+
|
|
163
|
+
it 'should set the admin password param to nil' do
|
|
164
|
+
expect(controller.params[:admin][:password]).to be_nil
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
context 'when password confirmation is blank' do
|
|
169
|
+
let(:password_confirmation) { ' ' }
|
|
170
|
+
|
|
171
|
+
it 'should set the admin password confirmation to nil' do
|
|
172
|
+
expect(controller.params[:admin][:password_confirmation]).to be_nil
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
context 'when current password is blank' do
|
|
177
|
+
let(:current_password) { ' ' }
|
|
178
|
+
|
|
179
|
+
it 'should set the admin current password param to nil' do
|
|
180
|
+
expect(controller.params[:admin][:current_password]).to be_nil
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
context 'when there are no password params' do
|
|
187
|
+
let(:password_params) { Hash.new }
|
|
188
|
+
|
|
189
|
+
it 'should not change any params' do
|
|
190
|
+
expect(controller.params[:user]).to be_nil
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
describe '#set_updated_by_user' do
|
|
196
|
+
subject(:set_updated_by_user) { post :create, user_params }
|
|
197
|
+
|
|
198
|
+
controller do
|
|
199
|
+
define_helpers(:user)
|
|
200
|
+
define_helpers(:admin)
|
|
201
|
+
|
|
202
|
+
before_filter :set_updated_by_user, only: :create
|
|
203
|
+
|
|
204
|
+
def create
|
|
205
|
+
render status: 200, text: 'Create'
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
before { sign_in :user, current_user }
|
|
210
|
+
let(:current_user) { create(:user) }
|
|
211
|
+
|
|
212
|
+
before { set_updated_by_user }
|
|
213
|
+
|
|
214
|
+
context 'when there is a user param' do
|
|
215
|
+
let(:user_params) { {user: attributes_for(:user)} }
|
|
216
|
+
|
|
217
|
+
it 'should set the user updated_by' do
|
|
218
|
+
expect(controller.params[:user][:updated_by]).to eq(current_user)
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
context 'when there is no user param' do
|
|
223
|
+
let(:user_params) { Hash.new }
|
|
224
|
+
|
|
225
|
+
it 'should set the updated_by' do
|
|
226
|
+
expect(controller.params[:updated_by]).to eq(current_user)
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
describe '#set_updated_by_admin' do
|
|
232
|
+
subject(:set_updated_by_admin) { post :create, admin_params }
|
|
233
|
+
|
|
234
|
+
controller do
|
|
235
|
+
define_helpers(:user)
|
|
236
|
+
define_helpers(:admin)
|
|
237
|
+
|
|
238
|
+
before_filter :set_updated_by_admin, only: :create
|
|
239
|
+
|
|
240
|
+
def create
|
|
241
|
+
render status: 200, text: 'Create'
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
before { sign_in :admin, current_admin }
|
|
246
|
+
let(:current_admin) { create(:admin) }
|
|
247
|
+
|
|
248
|
+
before { set_updated_by_admin }
|
|
249
|
+
|
|
250
|
+
context 'when there is an admin param' do
|
|
251
|
+
let(:admin_params) { {admin: attributes_for(:admin)} }
|
|
252
|
+
|
|
253
|
+
it 'should set the admin updated_by' do
|
|
254
|
+
expect(controller.params[:admin][:updated_by]).to eq(current_admin)
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
context 'when there is no admin param' do
|
|
259
|
+
let(:admin_params) { Hash.new }
|
|
260
|
+
|
|
261
|
+
it 'should set the updated_by' do
|
|
262
|
+
expect(controller.params[:updated_by]).to eq(current_admin)
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
describe '#handle_resource_error' do
|
|
268
|
+
subject(:action_with_error) { post :create }
|
|
269
|
+
|
|
270
|
+
before { request.env['devise.mapping'] = Devise.mappings[:user] }
|
|
271
|
+
|
|
272
|
+
controller(DeviseController) do
|
|
273
|
+
rescue_from ActiveRecord::RecordNotSaved, with: :handle_resource_error
|
|
274
|
+
|
|
275
|
+
def create
|
|
276
|
+
self.resource = resource_class.new
|
|
277
|
+
raise ActiveRecord::RecordNotSaved.new('my_error')
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
before { action_with_error }
|
|
282
|
+
|
|
283
|
+
it 'should be successful' do
|
|
284
|
+
expect(response).to be_success
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
it 'should set the base error on the resource' do
|
|
288
|
+
expect(controller.resource.errors[:base]).to eq(['my_error'])
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
it 'should render the model creation form' do
|
|
292
|
+
expect(response).to render_template('anonymous/new')
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
end
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe DeviseG5Authenticatable::SessionsController do
|
|
4
|
+
before { request.env['devise.mapping'] = Devise.mappings[scope] }
|
|
5
|
+
let(:scope) { :user }
|
|
6
|
+
|
|
7
|
+
describe '#new' do
|
|
8
|
+
subject(:new_session) { get :new }
|
|
9
|
+
|
|
10
|
+
context 'with user scope' do
|
|
11
|
+
it 'should redirect to the scoped authorize path' do
|
|
12
|
+
expect(new_session).to redirect_to(user_g5_authorize_path)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context 'with admin scope' do
|
|
17
|
+
let(:scope) { :admin }
|
|
18
|
+
|
|
19
|
+
it 'should redirect to the scoped authorize path' do
|
|
20
|
+
expect(new_session).to redirect_to(admin_g5_authorize_path)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe '#omniauth_passthru' do
|
|
26
|
+
subject(:passthru) { get :omniauth_passthru }
|
|
27
|
+
|
|
28
|
+
it 'should return a 404' do
|
|
29
|
+
expect(passthru).to be_not_found
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe '#create' do
|
|
34
|
+
subject(:create_session) { post :create }
|
|
35
|
+
|
|
36
|
+
let(:auth_hash) do
|
|
37
|
+
OmniAuth::AuthHash.new({
|
|
38
|
+
provider: 'g5',
|
|
39
|
+
uid: '45',
|
|
40
|
+
info: {name: 'Foo Bar',
|
|
41
|
+
email: 'foo@bar.com'},
|
|
42
|
+
credentials: {token: 'abc123'}
|
|
43
|
+
})
|
|
44
|
+
end
|
|
45
|
+
before { request.env['omniauth.auth'] = auth_hash }
|
|
46
|
+
|
|
47
|
+
context 'when local model exists' do
|
|
48
|
+
let(:model) do
|
|
49
|
+
stub_model(model_class, provider: auth_hash.provider,
|
|
50
|
+
uid: auth_hash.uid,
|
|
51
|
+
email: auth_hash.email,
|
|
52
|
+
g5_access_token: auth_hash.credentials.token,
|
|
53
|
+
save!: true,
|
|
54
|
+
update_g5_credentials: true,
|
|
55
|
+
email_changed?: false)
|
|
56
|
+
end
|
|
57
|
+
before { model_class.stub(find_and_update_for_g5_oauth: model) }
|
|
58
|
+
|
|
59
|
+
context 'with user scope' do
|
|
60
|
+
let(:model_class) { User }
|
|
61
|
+
let(:scope) { :user }
|
|
62
|
+
|
|
63
|
+
it 'should find the user and update the oauth credentials' do
|
|
64
|
+
User.should_receive(:find_and_update_for_g5_oauth).with(auth_hash).and_return(model)
|
|
65
|
+
create_session
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'should set the flash message' do
|
|
69
|
+
create_session
|
|
70
|
+
expect(flash[:notice]).to eq('Signed in successfully.')
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'should sign in the user' do
|
|
74
|
+
expect { create_session }.to change { controller.current_user }.from(nil).to(model)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'should redirect the user' do
|
|
78
|
+
create_session
|
|
79
|
+
expect(response).to be_a_redirect
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context 'with admin scope' do
|
|
84
|
+
let(:model_class) { Admin }
|
|
85
|
+
let(:scope) { :admin }
|
|
86
|
+
|
|
87
|
+
it 'should find the admin and update the oauth credentials' do
|
|
88
|
+
Admin.should_receive(:find_and_update_for_g5_oauth).with(auth_hash).and_return(model)
|
|
89
|
+
create_session
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it 'should sign in the admin' do
|
|
93
|
+
expect { create_session }.to change { controller.current_admin }.from(nil).to(model)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
context 'when local model does not exist' do
|
|
99
|
+
before { model_class.stub(find_and_update_for_g5_oauth: nil) }
|
|
100
|
+
|
|
101
|
+
context 'with user scope' do
|
|
102
|
+
let(:scope) { :user }
|
|
103
|
+
let(:model_class) { User }
|
|
104
|
+
|
|
105
|
+
it 'should set the flash message' do
|
|
106
|
+
create_session
|
|
107
|
+
expect(flash[:alert]).to eq('You must sign up before continuing.')
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it 'should not sign in a user' do
|
|
111
|
+
expect { create_session }.to_not change { controller.current_user }
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it 'should redirect to the user registration path' do
|
|
115
|
+
expect(create_session).to redirect_to(new_user_registration_path)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it 'should set the auth data on the session' do
|
|
119
|
+
expect { create_session }.to change { session['omniauth.auth'] }.to(auth_hash)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
context 'with admin scope' do
|
|
124
|
+
let(:scope) { :admin }
|
|
125
|
+
let(:model_class) { Admin }
|
|
126
|
+
|
|
127
|
+
it 'should redirect to the admin registration path' do
|
|
128
|
+
expect(create_session).to redirect_to(new_admin_registration_path)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it 'should set the auth data on the session' do
|
|
132
|
+
expect { create_session }.to change { session['omniauth.auth'] }.to(auth_hash)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
describe '#destroy' do
|
|
139
|
+
subject(:destroy_session) { delete :destroy }
|
|
140
|
+
|
|
141
|
+
let(:auth_client) { double(:auth_client, sign_out_url: auth_sign_out_url) }
|
|
142
|
+
let(:auth_sign_out_url) { 'https://auth.test.host/sign_out?redirect_url=http%3A%2F%2Ftest.host%2F' }
|
|
143
|
+
before do
|
|
144
|
+
allow(G5AuthenticationClient::Client).to receive(:new).and_return(auth_client)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
let(:model) { create(scope) }
|
|
148
|
+
|
|
149
|
+
before do
|
|
150
|
+
sign_in(scope, model)
|
|
151
|
+
allow(model).to receive(:revoke_g5_credentials!)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
context 'with user scope' do
|
|
155
|
+
let(:scope) { :user }
|
|
156
|
+
|
|
157
|
+
it 'should sign out the user locally' do
|
|
158
|
+
expect { destroy_session }.to change { controller.current_user }.to(nil)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it 'should construct the sign out URL with the correct redirect URL' do
|
|
162
|
+
expect(auth_client).to receive(:sign_out_url).
|
|
163
|
+
with(root_url).
|
|
164
|
+
and_return(auth_sign_out_url)
|
|
165
|
+
destroy_session
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it 'should redirect to the auth server to sign out globally' do
|
|
169
|
+
expect(destroy_session).to redirect_to(auth_sign_out_url)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it 'should revoke the g5 access token' do
|
|
173
|
+
expect(controller.current_user).to receive(:revoke_g5_credentials!)
|
|
174
|
+
destroy_session
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
context 'with admin scope' do
|
|
179
|
+
let(:scope) { :admin }
|
|
180
|
+
|
|
181
|
+
it 'should sign out the admin locally' do
|
|
182
|
+
expect { destroy_session }.to change { controller.current_admin }.to(nil)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
it 'should revoke the g5 access token' do
|
|
186
|
+
expect(controller.current_admin).to receive(:revoke_g5_credentials!)
|
|
187
|
+
destroy_session
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
describe '#failure' do
|
|
193
|
+
subject(:failure) do
|
|
194
|
+
# We need some trickery here because the failure action is actually rack
|
|
195
|
+
# rather than rails
|
|
196
|
+
rack_response = described_class.action(:failure).call(request.env)
|
|
197
|
+
@response = ActionDispatch::TestResponse.from_response(rack_response.last)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
before do
|
|
201
|
+
request.env['omniauth.error'] = error
|
|
202
|
+
request.env['omniauth.error.strategy'] = omniauth_strategy
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
let(:omniauth_strategy) { double(:omniauth_strategy, name: 'G5') }
|
|
206
|
+
|
|
207
|
+
context 'with error_reason' do
|
|
208
|
+
let(:error) { double(:error, error_reason: reason) }
|
|
209
|
+
let(:reason) { 'The error reason' }
|
|
210
|
+
|
|
211
|
+
it 'should set the flash message' do
|
|
212
|
+
failure
|
|
213
|
+
expect(flash[:alert]).to eq("Could not authenticate you from G5 because \"#{reason}\".")
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
it 'should be a redirect' do
|
|
217
|
+
failure
|
|
218
|
+
expect(response).to be_a_redirect
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
it 'should redirect to root path' do
|
|
222
|
+
failure
|
|
223
|
+
expect(response).to redirect_to(root_path)
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
context 'with error string' do
|
|
228
|
+
let(:error) { double(:error, error: message) }
|
|
229
|
+
let(:message) { 'The error string' }
|
|
230
|
+
|
|
231
|
+
it 'should set the flash message' do
|
|
232
|
+
failure
|
|
233
|
+
expect(flash[:alert]).to eq("Could not authenticate you from G5 because \"#{message}\".")
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
it 'should redirect to the root path' do
|
|
237
|
+
expect(failure).to redirect_to(root_path)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
context 'with omniauth error type' do
|
|
242
|
+
before { request.env['omniauth.error.type'] = :invalid_credentials }
|
|
243
|
+
let(:humanized_type) { 'Invalid credentials' }
|
|
244
|
+
let(:error) { Object.new }
|
|
245
|
+
|
|
246
|
+
it 'should set the flash message' do
|
|
247
|
+
failure
|
|
248
|
+
expect(flash[:alert]).to eq("Could not authenticate you from G5 because \"#{humanized_type}\".")
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
it 'should redirect to the root path' do
|
|
252
|
+
expect(failure).to redirect_to(root_path)
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|