devise_saml_authenticatable 1.6.1 → 1.8.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 +4 -4
- data/.github/workflows/ci.yml +52 -0
- data/.gitignore +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +12 -2
- data/README.md +22 -19
- data/app/controllers/devise/saml_sessions_controller.rb +27 -21
- data/lib/devise_saml_authenticatable/logger.rb +2 -2
- data/lib/devise_saml_authenticatable/model.rb +10 -7
- data/lib/devise_saml_authenticatable/saml_config.rb +18 -2
- data/lib/devise_saml_authenticatable/strategy.rb +23 -5
- data/lib/devise_saml_authenticatable/version.rb +1 -1
- data/lib/devise_saml_authenticatable.rb +6 -2
- data/spec/controllers/devise/saml_sessions_controller_spec.rb +203 -145
- data/spec/devise_saml_authenticatable/model_spec.rb +0 -13
- data/spec/devise_saml_authenticatable/saml_config_spec.rb +64 -17
- data/spec/devise_saml_authenticatable/strategy_spec.rb +54 -5
- data/spec/features/saml_authentication_spec.rb +19 -6
- data/spec/support/Gemfile.rails5.2 +2 -13
- data/spec/support/Gemfile.rails6 +18 -0
- data/spec/support/Gemfile.rails6.1 +24 -0
- data/spec/support/idp_settings_adapter.rb.erb +19 -9
- data/spec/support/idp_template.rb +5 -13
- data/spec/support/rails_app.rb +6 -7
- data/spec/support/ruby_saml_support.rb +10 -0
- data/spec/support/saml_idp_controller.rb.erb +1 -6
- data/spec/support/sp_template.rb +21 -18
- metadata +11 -10
- data/.travis.yml +0 -52
- data/spec/support/Gemfile.rails4 +0 -41
- data/spec/support/Gemfile.rails5 +0 -25
- data/spec/support/Gemfile.rails5.1 +0 -25
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rails_helper'
|
2
|
+
require 'support/ruby_saml_support'
|
2
3
|
|
3
4
|
# The important parts from devise
|
4
5
|
class DeviseController < ApplicationController
|
@@ -8,112 +9,122 @@ class DeviseController < ApplicationController
|
|
8
9
|
User
|
9
10
|
end
|
10
11
|
|
11
|
-
def
|
12
|
+
def resource_name
|
13
|
+
'users'
|
14
|
+
end
|
15
|
+
|
16
|
+
def require_no_authentication; end
|
17
|
+
|
18
|
+
def set_flash_message!(key, kind, _options = {})
|
19
|
+
flash[key] = I18n.t("devise.sessions.#{kind}")
|
12
20
|
end
|
13
21
|
end
|
22
|
+
|
14
23
|
class Devise::SessionsController < DeviseController
|
15
24
|
def destroy
|
16
25
|
sign_out
|
17
|
-
redirect_to after_sign_out_path_for(:user)
|
18
|
-
end
|
19
|
-
|
20
|
-
def verify_signed_out_user
|
21
|
-
# no-op for these tests
|
26
|
+
redirect_to after_sign_out_path_for(:user), allow_other_host: true
|
22
27
|
end
|
23
28
|
end
|
24
29
|
|
25
30
|
require_relative '../../../app/controllers/devise/saml_sessions_controller'
|
26
31
|
|
27
32
|
describe Devise::SamlSessionsController, type: :controller do
|
28
|
-
|
33
|
+
include RubySamlSupport
|
34
|
+
|
35
|
+
let(:idp_providers_adapter) { spy('Stub IDPSettings Adaptor') }
|
29
36
|
|
30
37
|
before do
|
31
|
-
@request.env[
|
32
|
-
|
33
|
-
assertion_consumer_service_url:
|
34
|
-
assertion_consumer_service_binding:
|
35
|
-
name_identifier_format:
|
36
|
-
issuer:
|
37
|
-
idp_entity_id:
|
38
|
-
authn_context:
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
@request.env['devise.mapping'] = Devise.mappings[:user]
|
39
|
+
settings = {
|
40
|
+
assertion_consumer_service_url: 'acs_url',
|
41
|
+
assertion_consumer_service_binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
|
42
|
+
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient',
|
43
|
+
issuer: 'sp_issuer',
|
44
|
+
idp_entity_id: 'http://www.example.com',
|
45
|
+
authn_context: '',
|
46
|
+
idp_cert: 'idp_cert'
|
47
|
+
}
|
48
|
+
with_ruby_saml_1_12_or_greater(proc {
|
49
|
+
settings.merge!(
|
50
|
+
idp_slo_service_url: 'http://idp_slo_url',
|
51
|
+
idp_sso_service_url: 'http://idp_sso_url'
|
52
|
+
)
|
53
|
+
}, else_do: proc {
|
54
|
+
settings.merge!(
|
55
|
+
idp_slo_target_url: 'http://idp_slo_url',
|
56
|
+
idp_sso_target_url: 'http://idp_sso_url'
|
57
|
+
)
|
42
58
|
})
|
59
|
+
allow(idp_providers_adapter).to receive(:settings).and_return(settings)
|
43
60
|
end
|
44
61
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
# patch tests using snippet from https://github.com/rails/rails/issues/34790#issuecomment-483607370
|
49
|
-
class ActionController::TestResponse < ActionDispatch::TestResponse
|
50
|
-
def recycle!
|
51
|
-
@mon_mutex_owner_object_id = nil
|
52
|
-
@mon_mutex = nil
|
53
|
-
initialize
|
54
|
-
end
|
55
|
-
end
|
62
|
+
describe '#new' do
|
63
|
+
let(:saml_response) do
|
64
|
+
File.read(File.join(File.dirname(__FILE__), '../../support', 'response_encrypted_nameid.xml.base64'))
|
56
65
|
end
|
57
|
-
end
|
58
66
|
|
59
|
-
|
60
|
-
|
67
|
+
subject(:do_get) do
|
68
|
+
get :new, params: { 'SAMLResponse' => saml_response }
|
69
|
+
end
|
61
70
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
get :new, "SAMLResponse" => saml_response
|
71
|
+
context 'when using the default saml config' do
|
72
|
+
it 'redirects to the IdP SSO target url' do
|
73
|
+
do_get
|
74
|
+
expect(response).to redirect_to(%r{\Ahttp://localhost:8009/saml/auth\?SAMLRequest=})
|
67
75
|
end
|
68
|
-
}
|
69
76
|
|
70
|
-
|
71
|
-
it "redirects to the IdP SSO target url" do
|
77
|
+
it 'stores saml_transaction_id in the session' do
|
72
78
|
do_get
|
73
|
-
|
79
|
+
if OneLogin::RubySaml::Authrequest.public_instance_methods.include?(:request_id)
|
80
|
+
expect(session[:saml_transaction_id]).to be_present
|
81
|
+
end
|
74
82
|
end
|
75
83
|
end
|
76
84
|
|
77
|
-
context
|
85
|
+
context 'with a specified idp' do
|
78
86
|
before do
|
79
87
|
Devise.idp_settings_adapter = idp_providers_adapter
|
80
88
|
end
|
81
89
|
|
82
|
-
it
|
90
|
+
it 'redirects to the associated IdP SSO target url' do
|
83
91
|
do_get
|
84
|
-
expect(response).to redirect_to(%r
|
92
|
+
expect(response).to redirect_to(%r{\Ahttp://idp_sso_url\?SAMLRequest=})
|
85
93
|
end
|
86
94
|
|
87
|
-
it
|
95
|
+
it 'stores saml_transaction_id in the session' do
|
96
|
+
do_get
|
97
|
+
if OneLogin::RubySaml::Authrequest.public_instance_methods.include?(:request_id)
|
98
|
+
expect(session[:saml_transaction_id]).to be_present
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'uses the DefaultIdpEntityIdReader' do
|
88
103
|
expect(DeviseSamlAuthenticatable::DefaultIdpEntityIdReader).to receive(:entity_id)
|
89
104
|
do_get
|
90
105
|
expect(idp_providers_adapter).to have_received(:settings).with(nil)
|
91
106
|
end
|
92
107
|
|
93
|
-
context
|
94
|
-
let(:relay_state) { ->(
|
108
|
+
context 'with a relay_state lambda defined' do
|
109
|
+
let(:relay_state) { ->(_request) { '123' } }
|
95
110
|
|
96
|
-
it
|
111
|
+
it 'includes the RelayState param in the request to the IdP' do
|
97
112
|
expect(Devise).to receive(:saml_relay_state).at_least(:once).and_return(relay_state)
|
98
113
|
do_get
|
99
|
-
expect(response).to redirect_to(%r
|
114
|
+
expect(response).to redirect_to(%r{\Ahttp://idp_sso_url\?SAMLRequest=.*&RelayState=123})
|
100
115
|
end
|
101
116
|
end
|
102
117
|
|
103
|
-
context
|
118
|
+
context 'with a specified idp entity id reader' do
|
104
119
|
class OurIdpEntityIdReader
|
105
120
|
def self.entity_id(params)
|
106
121
|
params[:entity_id]
|
107
122
|
end
|
108
123
|
end
|
109
124
|
|
110
|
-
subject(:do_get)
|
111
|
-
|
112
|
-
|
113
|
-
else
|
114
|
-
get :new, entity_id: "http://www.example.com"
|
115
|
-
end
|
116
|
-
}
|
125
|
+
subject(:do_get) do
|
126
|
+
get :new, params: { entity_id: 'http://www.example.com' }
|
127
|
+
end
|
117
128
|
|
118
129
|
before do
|
119
130
|
@default_reader = Devise.idp_entity_id_reader
|
@@ -124,10 +135,10 @@ describe Devise::SamlSessionsController, type: :controller do
|
|
124
135
|
Devise.idp_entity_id_reader = @default_reader
|
125
136
|
end
|
126
137
|
|
127
|
-
it
|
138
|
+
it 'redirects to the associated IdP SSO target url' do
|
128
139
|
do_get
|
129
|
-
expect(idp_providers_adapter).to have_received(:settings).with(
|
130
|
-
expect(response).to redirect_to(%r
|
140
|
+
expect(idp_providers_adapter).to have_received(:settings).with('http://www.example.com')
|
141
|
+
expect(response).to redirect_to(%r{\Ahttp://idp_sso_url\?SAMLRequest=})
|
131
142
|
end
|
132
143
|
end
|
133
144
|
end
|
@@ -136,7 +147,7 @@ describe Devise::SamlSessionsController, type: :controller do
|
|
136
147
|
describe '#metadata' do
|
137
148
|
let(:saml_config) { Devise.saml_config.dup }
|
138
149
|
|
139
|
-
context
|
150
|
+
context 'with the default configuration' do
|
140
151
|
it 'generates metadata' do
|
141
152
|
get :metadata
|
142
153
|
|
@@ -147,20 +158,20 @@ describe Devise::SamlSessionsController, type: :controller do
|
|
147
158
|
end
|
148
159
|
end
|
149
160
|
|
150
|
-
context
|
151
|
-
let(:saml_config) { controller.saml_config(
|
161
|
+
context 'with a specified IDP' do
|
162
|
+
let(:saml_config) { controller.saml_config('anything') }
|
152
163
|
|
153
164
|
before do
|
154
165
|
Devise.idp_settings_adapter = idp_providers_adapter
|
155
166
|
Devise.saml_configure do |settings|
|
156
|
-
settings.assertion_consumer_service_url =
|
157
|
-
settings.assertion_consumer_service_binding =
|
158
|
-
settings.name_identifier_format =
|
159
|
-
settings.issuer =
|
167
|
+
settings.assertion_consumer_service_url = 'http://localhost:3000/users/saml/auth'
|
168
|
+
settings.assertion_consumer_service_binding = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
|
169
|
+
settings.name_identifier_format = 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'
|
170
|
+
settings.issuer = 'http://localhost:3000'
|
160
171
|
end
|
161
172
|
end
|
162
173
|
|
163
|
-
it
|
174
|
+
it 'generates the same service metadata' do
|
164
175
|
get :metadata
|
165
176
|
|
166
177
|
# Remove ID that can vary across requests
|
@@ -172,79 +183,131 @@ describe Devise::SamlSessionsController, type: :controller do
|
|
172
183
|
end
|
173
184
|
|
174
185
|
describe '#destroy' do
|
175
|
-
|
176
|
-
allow(controller).to receive(:sign_out)
|
177
|
-
end
|
186
|
+
subject { delete :destroy }
|
178
187
|
|
179
|
-
context
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
188
|
+
context 'when user is signed out' do
|
189
|
+
before do
|
190
|
+
class Devise::SessionsController < DeviseController
|
191
|
+
def all_signed_out?
|
192
|
+
true
|
193
|
+
end
|
194
|
+
end
|
184
195
|
end
|
185
|
-
end
|
186
196
|
|
187
|
-
|
188
|
-
|
189
|
-
|
197
|
+
shared_examples 'not create SP initiated logout request' do
|
198
|
+
it do
|
199
|
+
expect(OneLogin::RubySaml::Logoutrequest).not_to receive(:new)
|
200
|
+
subject
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context 'when Devise.saml_sign_out_success_url is set' do
|
205
|
+
before do
|
206
|
+
allow(Devise).to receive(:saml_sign_out_success_url).and_return('http://localhost:8009/logged_out')
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'redirect to saml_sign_out_success_url' do
|
210
|
+
is_expected.to redirect_to 'http://localhost:8009/logged_out'
|
211
|
+
expect(flash[:notice]).to eq I18n.t('devise.sessions.already_signed_out')
|
212
|
+
end
|
213
|
+
|
214
|
+
it_behaves_like 'not create SP initiated logout request'
|
190
215
|
end
|
191
216
|
|
192
|
-
|
193
|
-
|
217
|
+
context 'when Devise.saml_sign_out_success_url is not set' do
|
218
|
+
before do
|
219
|
+
class Devise::SessionsController < DeviseController
|
220
|
+
def after_sign_out_path_for(_)
|
221
|
+
'http://localhost:8009/logged_out'
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
194
225
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
"http://localhost:8009/saml/logout"
|
226
|
+
it "redirect to devise's after sign out path" do
|
227
|
+
is_expected.to redirect_to 'http://localhost:8009/logged_out'
|
228
|
+
expect(flash[:notice]).to eq I18n.t('devise.sessions.already_signed_out')
|
199
229
|
end
|
200
230
|
|
201
|
-
|
202
|
-
expect(actual_settings.name_identifier_value).to eq("user@example.com")
|
203
|
-
expect(actual_settings.sessionindex).to eq("sessionindex")
|
231
|
+
it_behaves_like 'not create SP initiated logout request'
|
204
232
|
end
|
205
233
|
end
|
206
234
|
|
207
|
-
context
|
235
|
+
context 'when user is not signed out' do
|
208
236
|
before do
|
209
|
-
Devise
|
237
|
+
class Devise::SessionsController < DeviseController
|
238
|
+
def all_signed_out?
|
239
|
+
false
|
240
|
+
end
|
241
|
+
end
|
242
|
+
allow(controller).to receive(:sign_out)
|
210
243
|
end
|
211
244
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
245
|
+
context 'when using the default saml config' do
|
246
|
+
it 'signs out and redirects to the IdP' do
|
247
|
+
delete :destroy
|
248
|
+
expect(controller).to have_received(:sign_out)
|
249
|
+
expect(response).to redirect_to(%r{\Ahttp://localhost:8009/saml/logout\?SAMLRequest=})
|
250
|
+
end
|
217
251
|
end
|
218
252
|
|
219
|
-
context
|
220
|
-
|
221
|
-
|
222
|
-
params[:entity_id]
|
223
|
-
end
|
253
|
+
context 'when configured to use a non-transient name identifier' do
|
254
|
+
before do
|
255
|
+
allow(Devise.saml_config).to receive(:name_identifier_format).and_return('urn:oasis:names:tc:SAML:2.0:nameid-format:persistent')
|
224
256
|
end
|
225
257
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
258
|
+
it 'includes a LogoutRequest with the name identifier and session index', :aggregate_failures do
|
259
|
+
controller.current_user = Struct.new(:email, :session_index).new('user@example.com', 'sessionindex')
|
260
|
+
|
261
|
+
actual_settings = nil
|
262
|
+
expect_any_instance_of(OneLogin::RubySaml::Logoutrequest).to receive(:create) do |_, settings|
|
263
|
+
actual_settings = settings
|
264
|
+
'http://localhost:8009/saml/logout'
|
231
265
|
end
|
232
|
-
}
|
233
266
|
|
234
|
-
|
235
|
-
@
|
236
|
-
|
267
|
+
delete :destroy
|
268
|
+
expect(actual_settings.name_identifier_value).to eq('user@example.com')
|
269
|
+
expect(actual_settings.sessionindex).to eq('sessionindex')
|
237
270
|
end
|
271
|
+
end
|
238
272
|
|
239
|
-
|
240
|
-
|
273
|
+
context 'with a specified idp' do
|
274
|
+
before do
|
275
|
+
Devise.idp_settings_adapter = idp_providers_adapter
|
241
276
|
end
|
242
277
|
|
243
|
-
it
|
244
|
-
|
278
|
+
it 'redirects to the associated IdP SSO target url' do
|
279
|
+
expect(DeviseSamlAuthenticatable::DefaultIdpEntityIdReader).to receive(:entity_id)
|
280
|
+
delete :destroy
|
245
281
|
expect(controller).to have_received(:sign_out)
|
246
|
-
expect(
|
247
|
-
|
282
|
+
expect(response).to redirect_to(%r{\Ahttp://idp_slo_url\?SAMLRequest=})
|
283
|
+
end
|
284
|
+
|
285
|
+
context 'with a specified idp entity id reader' do
|
286
|
+
class OurIdpEntityIdReader
|
287
|
+
def self.entity_id(params)
|
288
|
+
params[:entity_id]
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
subject(:do_delete) do
|
293
|
+
delete :destroy, params: { entity_id: 'http://www.example.com' }
|
294
|
+
end
|
295
|
+
|
296
|
+
before do
|
297
|
+
@default_reader = Devise.idp_entity_id_reader
|
298
|
+
Devise.idp_entity_id_reader = OurIdpEntityIdReader # which will have some different behavior
|
299
|
+
end
|
300
|
+
|
301
|
+
after do
|
302
|
+
Devise.idp_entity_id_reader = @default_reader
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'redirects to the associated IdP SLO target url' do
|
306
|
+
do_delete
|
307
|
+
expect(controller).to have_received(:sign_out)
|
308
|
+
expect(idp_providers_adapter).to have_received(:settings).with('http://www.example.com')
|
309
|
+
expect(response).to redirect_to(%r{\Ahttp://idp_slo_url\?SAMLRequest=})
|
310
|
+
end
|
248
311
|
end
|
249
312
|
end
|
250
313
|
end
|
@@ -264,14 +327,10 @@ describe Devise::SamlSessionsController, type: :controller do
|
|
264
327
|
expect(response.status).to eq 500
|
265
328
|
end
|
266
329
|
|
267
|
-
context
|
268
|
-
subject(:do_post)
|
269
|
-
|
270
|
-
|
271
|
-
else
|
272
|
-
post :idp_sign_out, SAMLResponse: "stubbed_response"
|
273
|
-
end
|
274
|
-
}
|
330
|
+
context 'when receiving a logout response from the IdP after redirecting an SP logout request' do
|
331
|
+
subject(:do_post) do
|
332
|
+
post :idp_sign_out, params: { SAMLResponse: 'stubbed_response' }
|
333
|
+
end
|
275
334
|
|
276
335
|
it 'accepts a LogoutResponse and redirects sign_in' do
|
277
336
|
do_post
|
@@ -293,20 +352,18 @@ describe Devise::SamlSessionsController, type: :controller do
|
|
293
352
|
end
|
294
353
|
end
|
295
354
|
|
296
|
-
context
|
297
|
-
subject(:do_post)
|
298
|
-
|
299
|
-
|
300
|
-
else
|
301
|
-
post :idp_sign_out, SAMLRequest: "stubbed_logout_request"
|
302
|
-
end
|
303
|
-
}
|
355
|
+
context 'when receiving an IdP logout request' do
|
356
|
+
subject(:do_post) do
|
357
|
+
post :idp_sign_out, params: { SAMLRequest: 'stubbed_logout_request' }
|
358
|
+
end
|
304
359
|
|
305
|
-
let(:saml_request)
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
360
|
+
let(:saml_request) do
|
361
|
+
double(:slo_logoutrequest, {
|
362
|
+
id: 42,
|
363
|
+
name_id: name_id,
|
364
|
+
issuer: 'http://www.example.com'
|
365
|
+
})
|
366
|
+
end
|
310
367
|
let(:name_id) { '12312312' }
|
311
368
|
before do
|
312
369
|
allow(OneLogin::RubySaml::SloLogoutrequest).to receive(:new).and_return(saml_request)
|
@@ -319,27 +376,28 @@ describe Devise::SamlSessionsController, type: :controller do
|
|
319
376
|
expect(User).to have_received(:reset_session_key_for).with(name_id)
|
320
377
|
end
|
321
378
|
|
322
|
-
context
|
323
|
-
let(:idp_entity_id) {
|
379
|
+
context 'with a specified idp' do
|
380
|
+
let(:idp_entity_id) { 'http://www.example.com' }
|
324
381
|
before do
|
325
382
|
Devise.idp_settings_adapter = idp_providers_adapter
|
326
383
|
end
|
327
384
|
|
328
|
-
it
|
385
|
+
it 'accepts a LogoutResponse for the associated slo_target_url and redirects to sign_in' do
|
329
386
|
do_post
|
330
387
|
expect(response.status).to eq 302
|
331
388
|
expect(idp_providers_adapter).to have_received(:settings).with(idp_entity_id)
|
332
|
-
expect(response).to redirect_to
|
389
|
+
expect(response).to redirect_to 'http://localhost/logout_response'
|
333
390
|
end
|
334
391
|
end
|
335
392
|
|
336
|
-
context
|
337
|
-
let(:relay_state) { ->(
|
393
|
+
context 'with a relay_state lambda defined' do
|
394
|
+
let(:relay_state) { ->(_request) { '123' } }
|
338
395
|
|
339
|
-
it
|
396
|
+
it 'includes the RelayState param in the request to the IdP' do
|
340
397
|
expect(Devise).to receive(:saml_relay_state).at_least(:once).and_return(relay_state)
|
341
398
|
do_post
|
342
|
-
expect(saml_response).to have_received(:create).with(Devise.saml_config, saml_request.id, nil,
|
399
|
+
expect(saml_response).to have_received(:create).with(Devise.saml_config, saml_request.id, nil,
|
400
|
+
{ RelayState: '123' })
|
343
401
|
end
|
344
402
|
end
|
345
403
|
|
@@ -104,12 +104,6 @@ describe Devise::Models::SamlAuthenticatable do
|
|
104
104
|
expect(model.name).to eq('A User')
|
105
105
|
expect(model.saved).to be(true)
|
106
106
|
end
|
107
|
-
|
108
|
-
it "returns nil if it fails to create a user" do
|
109
|
-
expect(Model).to receive(:where).with(email: 'user@example.com').and_return([])
|
110
|
-
expect(Devise).to receive(:saml_update_resource_hook).and_raise(StandardError.new)
|
111
|
-
expect(Model.authenticate_with_saml(response, nil)).to be_nil
|
112
|
-
end
|
113
107
|
end
|
114
108
|
|
115
109
|
context "when configured to update a user and the user is found" do
|
@@ -125,13 +119,6 @@ describe Devise::Models::SamlAuthenticatable do
|
|
125
119
|
expect(model.name).to eq('A User')
|
126
120
|
expect(model.saved).to be(true)
|
127
121
|
end
|
128
|
-
|
129
|
-
it "returns nil if it fails to update a user" do
|
130
|
-
user = Model.new(new_record: false)
|
131
|
-
expect(Model).to receive(:where).with(email: 'user@example.com').and_return([user])
|
132
|
-
expect(Devise).to receive(:saml_update_resource_hook).and_raise(StandardError.new)
|
133
|
-
expect(Model.authenticate_with_saml(response, nil)).to be_nil
|
134
|
-
end
|
135
122
|
end
|
136
123
|
end
|
137
124
|
|