10
10
use Illuminate \Http \Request ;
11
11
use Illuminate \Support \Facades \Auth ;
12
12
use Illuminate \Support \Facades \Event ;
13
- use Illuminate \Support \Facades \Schema ;
14
13
use Laravel \Fortify \Contracts \LoginViewResponse ;
15
- use Laravel \Fortify \Events \TwoFactorAuthenticationChallenged ;
16
- use Laravel \Fortify \Features ;
17
14
use Laravel \Fortify \LoginRateLimiter ;
18
- use Laravel \Fortify \TwoFactorAuthenticatable ;
19
15
use Mockery ;
20
16
use Orchestra \Testbench \Attributes \WithMigration ;
21
- use PragmaRX \Google2FA \Google2FA ;
22
17
23
18
#[WithMigration]
24
19
class AuthenticatedSessionControllerTest extends OrchestraTestCase
@@ -39,7 +34,7 @@ public function test_the_login_view_is_returned()
39
34
40
35
public function test_user_can_authenticate ()
41
36
{
42
- TestAuthenticationSessionUser ::forceCreate ([
37
+ User ::forceCreate ([
43
38
'name ' => 'Taylor Otwell ' ,
44
39
45
40
'password ' => bcrypt ('secret ' ),
@@ -53,112 +48,9 @@ public function test_user_can_authenticate()
53
48
$ response ->assertRedirect ('/home ' );
54
49
}
55
50
56
- public function test_user_is_redirected_to_challenge_when_using_two_factor_authentication ()
57
- {
58
- Event::fake ();
59
-
60
- app ('config ' )->set ('auth.providers.users.model ' , TestTwoFactorAuthenticationSessionUser::class);
61
-
62
- TestTwoFactorAuthenticationSessionUser::forceCreate ([
63
- 'name ' => 'Taylor Otwell ' ,
64
-
65
- 'password ' => bcrypt ('secret ' ),
66
- 'two_factor_secret ' => 'test-secret ' ,
67
- ]);
68
-
69
- $ response = $ this ->withoutExceptionHandling ()->post ('/login ' , [
70
-
71
- 'password ' => 'secret ' ,
72
- ]);
73
-
74
- $ response ->assertRedirect ('/two-factor-challenge ' );
75
-
76
- Event::assertDispatched (TwoFactorAuthenticationChallenged::class);
77
- }
78
-
79
- public function test_user_is_not_redirected_to_challenge_when_using_two_factor_authentication_that_has_not_been_confirmed_and_confirmation_is_enabled ()
80
- {
81
- Event::fake ();
82
-
83
- app ('config ' )->set ('auth.providers.users.model ' , TestTwoFactorAuthenticationSessionUser::class);
84
- app ('config ' )->set ('fortify.features ' , [
85
- Features::registration (),
86
- Features::twoFactorAuthentication (['confirm ' => true ]),
87
- ]);
88
-
89
- TestTwoFactorAuthenticationSessionUser::forceCreate ([
90
- 'name ' => 'Taylor Otwell ' ,
91
-
92
- 'password ' => bcrypt ('secret ' ),
93
- 'two_factor_secret ' => 'test-secret ' ,
94
- ]);
95
-
96
- $ response = $ this ->withoutExceptionHandling ()->post ('/login ' , [
97
-
98
- 'password ' => 'secret ' ,
99
- ]);
100
-
101
- $ response ->assertRedirect ('/home ' );
102
- }
103
-
104
- public function test_user_is_redirected_to_challenge_when_using_two_factor_authentication_that_has_been_confirmed_and_confirmation_is_enabled ()
105
- {
106
- Event::fake ();
107
-
108
- app ('config ' )->set ('auth.providers.users.model ' , TestTwoFactorAuthenticationSessionUser::class);
109
- app ('config ' )->set ('fortify.features ' , [
110
- Features::registration (),
111
- Features::twoFactorAuthentication (['confirm ' => true ]),
112
- ]);
113
-
114
- Schema::table ('users ' , function ($ table ) {
115
- $ table ->timestamp ('two_factor_confirmed_at ' )->nullable ();
116
- });
117
-
118
- TestTwoFactorAuthenticationSessionUser::forceCreate ([
119
- 'name ' => 'Taylor Otwell ' ,
120
-
121
- 'password ' => bcrypt ('secret ' ),
122
- 'two_factor_secret ' => 'test-secret ' ,
123
- 'two_factor_confirmed_at ' => now (),
124
- ]);
125
-
126
- $ response = $ this ->withoutExceptionHandling ()->post ('/login ' , [
127
-
128
- 'password ' => 'secret ' ,
129
- ]);
130
-
131
- $ response ->assertRedirect ('/two-factor-challenge ' );
132
- }
133
-
134
- public function test_user_can_authenticate_when_two_factor_challenge_is_disabled ()
135
- {
136
- app ('config ' )->set ('auth.providers.users.model ' , TestTwoFactorAuthenticationSessionUser::class);
137
-
138
- $ features = app ('config ' )->get ('fortify.features ' );
139
-
140
- unset($ features [array_search (Features::twoFactorAuthentication (), $ features )]);
141
-
142
- app ('config ' )->set ('fortify.features ' , $ features );
143
-
144
- TestTwoFactorAuthenticationSessionUser::forceCreate ([
145
- 'name ' => 'Taylor Otwell ' ,
146
-
147
- 'password ' => bcrypt ('secret ' ),
148
- 'two_factor_secret ' => 'test-secret ' ,
149
- ]);
150
-
151
- $ response = $ this ->withoutExceptionHandling ()->post ('/login ' , [
152
-
153
- 'password ' => 'secret ' ,
154
- ]);
155
-
156
- $ response ->assertRedirect ('/home ' );
157
- }
158
-
159
51
public function test_validation_exception_returned_on_failure ()
160
52
{
161
- TestAuthenticationSessionUser ::forceCreate ([
53
+ User ::forceCreate ([
162
54
'name ' => 'Taylor Otwell ' ,
163
55
164
56
'password ' => bcrypt ('secret ' ),
@@ -247,151 +139,11 @@ public function test_the_user_can_logout_of_the_application_using_json_request()
247
139
$ this ->assertNull (Auth::guard ()->getUser ());
248
140
}
249
141
250
- public function test_two_factor_challenge_can_be_passed_via_code ()
251
- {
252
- app ('config ' )->set ('auth.providers.users.model ' , TestTwoFactorAuthenticationSessionUser::class);
253
-
254
- $ tfaEngine = app (Google2FA::class);
255
- $ userSecret = $ tfaEngine ->generateSecretKey ();
256
- $ validOtp = $ tfaEngine ->getCurrentOtp ($ userSecret );
257
-
258
- $ user = TestTwoFactorAuthenticationSessionUser::forceCreate ([
259
- 'name ' => 'Taylor Otwell ' ,
260
-
261
- 'password ' => bcrypt ('secret ' ),
262
- 'two_factor_secret ' => encrypt ($ userSecret ),
263
- ]);
264
-
265
- $ response = $ this ->withSession ([
266
- 'login.id ' => $ user ->id ,
267
- 'login.remember ' => false ,
268
- ])->withoutExceptionHandling ()->post ('/two-factor-challenge ' , [
269
- 'code ' => $ validOtp ,
270
- ]);
271
-
272
- $ response ->assertRedirect ('/home ' )
273
- ->assertSessionMissing ('login.id ' );
274
- }
275
-
276
- public function test_two_factor_authentication_preserves_remember_me_selection (): void
277
- {
278
- Event::fake ();
279
-
280
- app ('config ' )->set ('auth.providers.users.model ' , TestTwoFactorAuthenticationSessionUser::class);
281
-
282
- TestTwoFactorAuthenticationSessionUser::forceCreate ([
283
- 'name ' => 'Taylor Otwell ' ,
284
-
285
- 'password ' => bcrypt ('secret ' ),
286
- 'two_factor_secret ' => 'test-secret ' ,
287
- ]);
288
-
289
- $ response = $ this ->withoutExceptionHandling ()->post ('/login ' , [
290
-
291
- 'password ' => 'secret ' ,
292
- 'remember ' => false ,
293
- ]);
294
-
295
- $ response ->assertRedirect ('/two-factor-challenge ' )
296
- ->assertSessionHas ('login.remember ' , false );
297
- }
298
-
299
- public function test_two_factor_challenge_fails_for_old_otp_and_zero_window ()
300
- {
301
- app ('config ' )->set ('auth.providers.users.model ' , TestTwoFactorAuthenticationSessionUser::class);
302
-
303
- //Setting window to 0 should mean any old OTP is instantly invalid
304
- app ('config ' )->set ('fortify.features ' , [
305
- Features::twoFactorAuthentication (['window ' => 0 ]),
306
- ]);
307
-
308
- $ tfaEngine = app (Google2FA::class);
309
- $ userSecret = $ tfaEngine ->generateSecretKey ();
310
- $ currentTs = $ tfaEngine ->getTimestamp ();
311
- $ previousOtp = $ tfaEngine ->oathTotp ($ userSecret , $ currentTs - 1 );
312
-
313
- $ user = TestTwoFactorAuthenticationSessionUser::forceCreate ([
314
- 'name ' => 'Taylor Otwell ' ,
315
-
316
- 'password ' => bcrypt ('secret ' ),
317
- 'two_factor_secret ' => encrypt ($ userSecret ),
318
- ]);
319
-
320
- $ response = $ this ->withSession ([
321
- 'login.id ' => $ user ->id ,
322
- 'login.remember ' => false ,
323
- ])->withoutExceptionHandling ()->post ('/two-factor-challenge ' , [
324
- 'code ' => $ previousOtp ,
325
- ]);
326
-
327
- $ response ->assertRedirect ('/two-factor-challenge ' )
328
- ->assertSessionHas ('login.id ' )
329
- ->assertSessionHasErrors (['code ' ]);
330
- }
331
-
332
- public function test_two_factor_challenge_can_be_passed_via_recovery_code ()
333
- {
334
- app ('config ' )->set ('auth.providers.users.model ' , TestTwoFactorAuthenticationSessionUser::class);
335
-
336
- $ user = TestTwoFactorAuthenticationSessionUser::forceCreate ([
337
- 'name ' => 'Taylor Otwell ' ,
338
-
339
- 'password ' => bcrypt ('secret ' ),
340
- 'two_factor_recovery_codes ' => encrypt (json_encode (['invalid-code ' , 'valid-code ' ])),
341
- ]);
342
-
343
- $ response = $ this ->withSession ([
344
- 'login.id ' => $ user ->id ,
345
- 'login.remember ' => false ,
346
- ])->withoutExceptionHandling ()->post ('/two-factor-challenge ' , [
347
- 'recovery_code ' => 'valid-code ' ,
348
- ]);
349
-
350
- $ response ->assertRedirect ('/home ' )
351
- ->assertSessionMissing ('login.id ' );
352
- $ this ->assertNotNull (Auth::getUser ());
353
- $ this ->assertNotContains ('valid-code ' , json_decode (decrypt ($ user ->fresh ()->two_factor_recovery_codes ), true ));
354
- }
355
-
356
- public function test_two_factor_challenge_can_fail_via_recovery_code ()
357
- {
358
- app ('config ' )->set ('auth.providers.users.model ' , TestTwoFactorAuthenticationSessionUser::class);
359
-
360
- $ user = TestTwoFactorAuthenticationSessionUser::forceCreate ([
361
- 'name ' => 'Taylor Otwell ' ,
362
-
363
- 'password ' => bcrypt ('secret ' ),
364
- 'two_factor_recovery_codes ' => encrypt (json_encode (['invalid-code ' , 'valid-code ' ])),
365
- ]);
366
-
367
- $ response = $ this ->withSession ([
368
- 'login.id ' => $ user ->id ,
369
- 'login.remember ' => false ,
370
- ])->withoutExceptionHandling ()->post ('/two-factor-challenge ' , [
371
- 'recovery_code ' => 'missing-code ' ,
372
- ]);
373
-
374
- $ response ->assertRedirect ('/two-factor-challenge ' )
375
- ->assertSessionHas ('login.id ' )
376
- ->assertSessionHasErrors (['recovery_code ' ]);
377
- $ this ->assertNull (Auth::getUser ());
378
- }
379
-
380
- public function test_two_factor_challenge_requires_a_challenged_user ()
381
- {
382
- app ('config ' )->set ('auth.providers.users.model ' , TestTwoFactorAuthenticationSessionUser::class);
383
-
384
- $ response = $ this ->withSession ([])->withoutExceptionHandling ()->get ('/two-factor-challenge ' );
385
-
386
- $ response ->assertRedirect ('/login ' );
387
- $ this ->assertNull (Auth::getUser ());
388
- }
389
-
390
142
public function test_case_insensitive_usernames_can_be_used ()
391
143
{
392
144
app ('config ' )->set ('fortify.lowercase_usernames ' , true );
393
145
394
- TestAuthenticationSessionUser ::forceCreate ([
146
+ User ::forceCreate ([
395
147
'name ' => 'Taylor Otwell ' ,
396
148
397
149
'password ' => bcrypt ('secret ' ),
@@ -407,7 +159,7 @@ public function test_case_insensitive_usernames_can_be_used()
407
159
408
160
public function test_users_can_logout (): void
409
161
{
410
- $ user = TestAuthenticationSessionUser ::forceCreate ([
162
+ $ user = User ::forceCreate ([
411
163
'name ' => 'Taylor Otwell ' ,
412
164
413
165
'password ' => bcrypt ('secret ' ),
@@ -431,25 +183,4 @@ public function test_must_be_authenticated_to_logout(): void
431
183
$ this ->assertGuest ();
432
184
Event::assertNotDispatched (Logout::class);
433
185
}
434
-
435
- protected function defineEnvironment ($ app )
436
- {
437
- parent ::defineEnvironment ($ app );
438
-
439
- $ app ['config ' ]->set ([
440
- 'auth.providers.users.model ' => TestAuthenticationSessionUser::class,
441
- ]);
442
- }
443
- }
444
-
445
- class TestAuthenticationSessionUser extends User
446
- {
447
- protected $ table = 'users ' ;
448
- }
449
-
450
- class TestTwoFactorAuthenticationSessionUser extends User
451
- {
452
- use TwoFactorAuthenticatable;
453
-
454
- protected $ table = 'users ' ;
455
186
}
0 commit comments