Skip to content

Commit 66b43ae

Browse files
Tidy up and run it further downstream.
Props Kaspars for the suggestion to relocate to keep the function signatures. Co-Authored-By: Kaspars Dambis <hi@kaspars.net>
1 parent 1f0035b commit 66b43ae

File tree

1 file changed

+34
-20
lines changed

1 file changed

+34
-20
lines changed

‎class-two-factor-core.php‎

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ public static function get_enabled_providers_for_user( $user = null ) {
547547
* @see Two_Factor_Core::get_enabled_providers_for_user()
548548
*
549549
* @param int|WP_User $user Optional. User ID, or WP_User object of the the user. Defaults to current user.
550-
* @return array|WP_Error List of provider instances, or a WP_Error if all configured providers are unavailable.
550+
* @return array List of provider instances.
551551
*/
552552
public static function get_available_providers_for_user( $user = null ) {
553553
$user = self::fetch_user( $user );
@@ -557,30 +557,26 @@ public static function get_available_providers_for_user( $user = null ) {
557557

558558
$providers = self::get_supported_providers_for_user( $user ); // Returns full objects.
559559
$enabled_providers = self::get_enabled_providers_for_user( $user ); // Returns just the keys.
560-
$configured_providers = array();
561560
$user_providers_raw = get_user_meta( $user->ID, self::ENABLED_PROVIDERS_USER_META_KEY, true );
561+
$configured_providers = array();
562562

563563
/**
564564
* If the user had enabled providers, but none of them exist currently,
565565
* if emailed codes is available force it to be on, so that deprecated
566566
* or removed providers don't result in the two-factor requirement being
567567
* removed and 'failing open'.
568-
*
568+
*
569569
* Possible enhancement: add a filter to change the fallback method?
570570
*/
571571
if ( empty( $enabled_providers ) && $user_providers_raw ) {
572572
if ( isset( $providers['Two_Factor_Email'] ) ) {
573573
// Force Emailed codes to 'on'.
574574
$enabled_providers[] = 'Two_Factor_Email';
575575
} else {
576-
return new WP_Error(
577-
'no_available_2fa_methods',
578-
__( 'Error: You have Two Factor method(s) enabled, but the provider(s) no longer exist. Please contact a site administrator for assistance.', 'two-factor' ),
579-
array(
580-
'user_providers_raw' => $user_providers_raw,
581-
'available_providers' => array_keys( $providers ),
582-
)
583-
);
576+
// Email isn't available? Okay, then you get nothing. Downstream should verify
577+
// there aren't any that have gone away before allowing authentication when trying
578+
// to login.
579+
return $configured_providers;
584580
}
585581
}
586582

@@ -621,7 +617,7 @@ public static function get_provider_for_user( $user = null, $preferred_provider
621617

622618
if ( is_string( $preferred_provider ) ) {
623619
$providers = self::get_available_providers_for_user( $user );
624-
if ( ! is_wp_error( $providers ) && isset( $providers[ $preferred_provider ] ) ) {
620+
if ( is_array( $providers ) && isset( $providers[ $preferred_provider ] ) ) {
625621
return $providers[ $preferred_provider ];
626622
}
627623
}
@@ -668,9 +664,6 @@ public static function get_primary_provider_for_user( $user = null ) {
668664
// If there's only one available provider, force that to be the primary.
669665
if ( empty( $available_providers ) ) {
670666
return null;
671-
} elseif ( is_wp_error( $available_providers ) ) {
672-
// If it returned an error, the configured methods don't exist, and it couldn't swap in a replacement.
673-
wp_die( $available_providers );
674667
} elseif ( 1 === count( $available_providers ) ) {
675668
$provider = key( $available_providers );
676669
} else {
@@ -963,9 +956,30 @@ public static function login_html( $user, $login_nonce, $redirect_to, $error_msg
963956

964957
$rememberme = intval( self::rememberme() );
965958

966-
if ( is_wp_error( $available_providers ) ) {
967-
// If it returned an error, the configured methods don't exist, and it couldn't swap in a replacement.
968-
wp_die( $available_providers );
959+
if ( empty( $available_providers ) ) {
960+
$user_providers_raw = get_user_meta( $user->ID, self::ENABLED_PROVIDERS_USER_META_KEY, true );
961+
if ( $user_providers_raw ) {
962+
// The user has a provider configured according to usermeta, but none are currently available.
963+
$error = new WP_Error(
964+
'no_available_2fa_methods',
965+
__( 'Error: You have Two Factor method(s) enabled, but the provider(s) no longer exist. Please contact a site administrator for assistance.', 'two-factor' ),
966+
array(
967+
'user_providers_raw' => $user_providers_raw,
968+
'available_providers' => array_keys( $available_providers ),
969+
)
970+
);
971+
972+
/**
973+
* Provide an opportunity for other code to change this fail-closed behavior, or listen for its events.
974+
*
975+
* @param WP_Error|mixed $error The WP_Error indicating there are no available 2FA Methods. To allow anyways, just return anything else.
976+
*/
977+
$error = apply_filters( 'two_factor_error_no_available_methods', $error );
978+
979+
if ( is_wp_error( $error ) ) {
980+
wp_die( $error );
981+
}
982+
}
969983
}
970984

971985
if ( ! function_exists( 'login_header' ) ) {
@@ -2164,15 +2178,15 @@ public static function user_two_factor_options_update( $user_id ) {
21642178
array(
21652179
'two-factor-provider' => '',
21662180
'two-factor-login' => time(),
2167-
)
2181+
)
21682182
);
21692183
} elseif ( $existing_providers && ! $enabled_providers ) {
21702184
// We've disabled two-factor, remove session metadata.
21712185
self::update_current_user_session(
21722186
array(
21732187
'two-factor-provider' => null,
21742188
'two-factor-login' => null,
2175-
)
2189+
)
21762190
);
21772191
}
21782192
}

0 commit comments

Comments
 (0)