@@ -314,6 +314,12 @@ public static function should_require_mfa($url, $preventredirect) {
314
314
// Remove all params before comparison.
315
315
$ url ->remove_all_params ();
316
316
317
+ // Dont redirect if already on auth.php
318
+ $ authurl = new \moodle_url ('/admin/tool/mfa/auth.php ' );
319
+ if ($ url ->compare ($ authurl )) {
320
+ return self ::NO_REDIRECT ;
321
+ }
322
+
317
323
// Soft maintenance mode.
318
324
if (!empty ($ CFG ->maintenance_enabled )) {
319
325
return self ::NO_REDIRECT ;
@@ -362,17 +368,20 @@ public static function should_require_mfa($url, $preventredirect) {
362
368
}
363
369
364
370
// Site policy.
365
- if (isset ($ USER ->policyagreed ) && !$ USER ->policyagreed
366
- && defined ('NO_SITEPOLICY_CHECK ' ) && !NO_SITEPOLICY_CHECK ) {
371
+ if (isset ($ USER ->policyagreed ) && !$ USER ->policyagreed ) {
367
372
$ manager = new \core_privacy \local \sitepolicy \manager ();
368
373
$ policyurl = $ manager ->get_redirect_url (false );
369
- if (!empty ($ policyurl )) {
374
+ if (!empty ($ policyurl ) && $ url -> compare ( $ policyurl ) ) {
370
375
return self ::NO_REDIRECT ;
371
376
}
372
377
}
373
378
374
379
// WS/AJAX check.
375
380
if (WS_SERVER || AJAX_SCRIPT ) {
381
+ if (isset ($ SESSION ->mfa_pending ) && !empty ($ SESSION ->mfa_pending )) {
382
+ // Allow AJAX and WS, but never from auth.php
383
+ return self ::NO_REDIRECT ;
384
+ }
376
385
return self ::REDIRECT_EXCEPTION ;
377
386
}
378
387
@@ -385,9 +394,8 @@ public static function should_require_mfa($url, $preventredirect) {
385
394
}
386
395
387
396
// Circular checks.
388
- $ authurl = new \moodle_url ('/admin/tool/mfa/auth.php ' );
389
- if (isset ($ SESSION ->mfa_redir_referer ) &&
390
- $ SESSION ->mfa_redir_referer != $ authurl ) {
397
+ if (isset ($ SESSION ->mfa_redir_referer )
398
+ && $ SESSION ->mfa_redir_referer != $ authurl ) {
391
399
if ($ SESSION ->mfa_redir_referer == get_local_referer (true )) {
392
400
// Possible redirect loop.
393
401
if (!isset ($ SESSION ->mfa_redir_count )) {
@@ -406,10 +414,6 @@ public static function should_require_mfa($url, $preventredirect) {
406
414
// Set referer after checks.
407
415
$ SESSION ->mfa_redir_referer = get_local_referer (true );
408
416
409
- $ safe = new \moodle_url ('/admin/tool/mfa/auth.php ' );
410
- if ($ safe ->compare ($ url )) {
411
- return self ::NO_REDIRECT ;
412
- }
413
417
return self ::REDIRECT ;
414
418
}
415
419
@@ -419,10 +423,10 @@ public static function should_require_mfa($url, $preventredirect) {
419
423
* @return array
420
424
*/
421
425
public static function get_factor_no_redirect_urls () {
422
- $ factors = \tool_mfa \plugininfo \factor::get_enabled_factors ();
426
+ $ factors = \tool_mfa \plugininfo \factor::get_factors ();
423
427
$ urls = array ();
424
428
foreach ($ factors as $ factor ) {
425
- $ urls += $ factor ->get_no_redirect_urls ();
429
+ $ urls = array_merge ( $ urls , $ factor ->get_no_redirect_urls () );
426
430
}
427
431
return $ urls ;
428
432
}
@@ -464,7 +468,17 @@ public static function require_auth($courseorid = null, $autologinguest = null,
464
468
465
469
if (empty ($ SESSION ->tool_mfa_authenticated ) || !$ SESSION ->tool_mfa_authenticated ) {
466
470
$ cleanurl = new \moodle_url ($ ME );
471
+ $ authurl = new \moodle_url ('/admin/tool/mfa/auth.php ' );
472
+
467
473
$ redir = self ::should_require_mfa ($ cleanurl , $ preventredirect );
474
+
475
+ if ($ redir == self ::NO_REDIRECT && !$ cleanurl ->compare ($ authurl )) {
476
+ // A non-MFA page that should take precedence.
477
+ // This check is for any pages, such as site policy, that must occur before MFA.
478
+ // This check allows AJAX and WS requests to fire on these pages without throwing an exception.
479
+ $ SESSION ->mfa_pending = true ;
480
+ }
481
+
468
482
if ($ redir == self ::REDIRECT ) {
469
483
if (empty ($ SESSION ->wantsurl )) {
470
484
!empty ($ setwantsurltome )
@@ -473,9 +487,16 @@ public static function require_auth($courseorid = null, $autologinguest = null,
473
487
474
488
$ SESSION ->tool_mfa_setwantsurl = true ;
475
489
}
476
- redirect (new \moodle_url ('/admin/tool/mfa/auth.php ' ));
490
+ // Remove pending status.
491
+ // We must now auth with MFA, now that pending statuses are resolved.
492
+ unset($ SESSION ->mfa_pending );
493
+ redirect ($ authurl );
477
494
} else if ($ redir == self ::REDIRECT_EXCEPTION ) {
478
- throw new \moodle_exception ('redirecterrordetected ' , 'error ' );
495
+ if (!empty ($ SESSION ->mfa_redir_referer )) {
496
+ throw new \moodle_exception ('redirecterrordetected ' , 'tool_mfa ' , $ SESSION ->mfa_redir_referer );
497
+ } else {
498
+ throw new \moodle_exception ('redirecterrordetected ' , 'error ' );
499
+ }
479
500
}
480
501
}
481
502
}
0 commit comments