| @@ -977,10 +977,12 @@ | ||
| 977 | 977 | * emailed code. So the question is asked per account, not per site. |
| 978 | 978 | * |
| 979 | 979 | * The order is what keeps it closed at both ends: |
| 980 | 980 | * |
| 981 | - * 1. An enrolment already made wins. It is the strongest factor the account | |
| 982 | - * has and it is ready to use, wherever in the network it was set up. | |
| 981 | + * 1. An enrolment already made wins while some site asking for a second | |
| 982 | + * factor asks for an authenticator app. It is the strongest factor the | |
| 983 | + * account has and it is ready to use, wherever in the network it was set | |
| 984 | + * up. | |
| 983 | 985 | * 2. Otherwise, if any site asking for a second factor asks for email, email |
| 984 | 986 | * handles it. Email needs no enrolment, so it can never fall into the |
| 985 | 987 | * branch that lets a login through for lack of one. |
| 986 | 988 | * 3. Only when every site asking wants an authenticator app does TOTP handle |
| @@ -985,9 +987,17 @@ | ||
| 985 | 987 | * branch that lets a login through for lack of one. |
| 986 | 988 | * 3. Only when every site asking wants an authenticator app does TOTP handle |
| 987 | 989 | * it, which is the case the grace period was written for. |
| 988 | 990 | * |
| 991 | + * The condition on the first step came in 2.11.11. Without it an enrolment | |
| 992 | + * left from a time when the site asked for an app outranked the method the | |
| 993 | + * site asks for now: a single site set to email asked those accounts for an | |
| 994 | + * authenticator code, which 2.11.9 never did and which locks out whoever | |
| 995 | + * removed the app after the switch. Dropping that enrolment opens nothing, | |
| 996 | + * because the account then goes to email, which needs no enrolment. | |
| 997 | + * | |
| 989 | 998 | * @since 2.11.10 |
| 999 | + * @since 2.11.11 An enrolment only wins while an authenticator app is asked for. | |
| 990 | 1000 | * |
| 991 | 1001 | * @param WP_User $user User being authenticated. |
| 992 | 1002 | * @param bool $enrolled Whether the account has a TOTP enrolment anywhere. |
| 993 | 1003 | * @return string 'email', 'totp', or '' when nothing asks. |
| @@ -998,9 +1008,9 @@ | ||
| 998 | 1008 | if ( ! $methods ) { |
| 999 | 1009 | return ''; |
| 1000 | 1010 | } |
| 1001 | 1011 | |
| 1002 | - if ( $enrolled ) { | |
| 1012 | + if ( $enrolled && in_array( 'totp', $methods, true ) ) { | |
| 1003 | 1013 | return 'totp'; |
| 1004 | 1014 | } |
| 1005 | 1015 | |
| 1006 | 1016 | return in_array( 'email', $methods, true ) ? 'email' : 'totp'; |
| @@ -1035,9 +1045,12 @@ | ||
| 1035 | 1045 | * yet can log in through any of them and the cookie is valid everywhere. |
| 1036 | 1046 | * Asking only the sites they belong to left the account with the most |
| 1037 | 1047 | * power in the network outside the policy, which is the bypass upside |
| 1038 | 1048 | * down. So for them every site of the network is consulted. There are |
| 1039 | - * few super administrators and this runs at login, not per request. | |
| 1049 | + * few super administrators. It does not only run at login, though, which | |
| 1050 | + * this note claimed until 2.11.11: the dashboard hooks of the TOTP class | |
| 1051 | + * ask it on every admin screen of every site of a network, at least once | |
| 1052 | + * per hook. | |
| 1040 | 1053 | */ |
| 1041 | 1054 | if ( is_super_admin( $user->ID ) ) { |
| 1042 | 1055 | $blog_ids = array_merge( $blog_ids, get_sites( array( 'fields' => 'ids', 'number' => 200 ) ) ); |
| 1043 | 1056 | } |