two_factor = $two_factor; } /** * Run initialization code for the interstitial. */ public function run() { add_action( 'itsec_two_factor_override', array( $this, 'proceed_on_override' ) ); } /** * Proceed to the next interstitial when the user's 2fa code is overridden. * * @param WP_User $user */ public function proceed_on_override( $user ) { if ( ! $user instanceof WP_User ) { return; } foreach ( ITSEC_Login_Interstitial_Session::get_all( $user ) as $session ) { if ( '2fa' === $session->get_current_interstitial() ) { ITSEC_Core::get_login_interstitial()->proceed_to_next( $session ); } } } /** * @inheritDoc */ public function render( ITSEC_Login_Interstitial_Session $session, array $args ) { $user = $session->get_user(); $available_providers = $this->two_factor->get_available_providers_for_user( $user ); if ( ! $provider = $this->get_provider( $session ) ) { echo '

'; printf( esc_html__( 'Invalid Two-Factor provider. Please try %1$slogging in again%2$s.', 'it-l10n-ithemes-security-pro' ), '', '' ); echo '

'; return; } $provider_class = get_class( $provider ); $backup_providers = array_diff_key( $available_providers, array( $provider_class => null ) ); ?> authentication_page( $user ); ?> can_resend_code() ): ?>

get_provider( $session ) ) { $provider->pre_render_authentication_page( $session->get_user() ); do_action( 'itsec_two_factor_interstitial_pre_render', $session, $provider ); } } /** * Get the provider to use. * * @param ITSEC_Login_Interstitial_Session $session * * @return Two_Factor_Provider|null */ private function get_provider( ITSEC_Login_Interstitial_Session $session ) { $available_providers = $this->two_factor->get_available_providers_for_user( $session->get_user() ); $provider = empty( $_GET['provider'] ) ? '' : $_GET['provider']; if ( ! $provider ) { $provider = $this->two_factor->get_primary_provider_for_user( $session->get_user()->ID ); } elseif ( is_string( $provider ) ) { if ( ! isset( $available_providers[ $provider ] ) || ! method_exists( $provider, 'get_instance' ) ) { return null; } $provider = call_user_func( array( $provider, 'get_instance' ) ); } return $provider; } public function has_submit() { return true; } public function submit( ITSEC_Login_Interstitial_Session $session, array $post_data ) { $user = $session->get_user(); $user_id = $user->ID; if ( isset( $post_data['provider'] ) ) { $providers = $this->two_factor->get_available_providers_for_user( $user ); if ( isset( $providers[ $post_data['provider'] ] ) ) { $provider = $providers[ $post_data['provider'] ]; } else { ITSEC_Log::add_debug( 'two_factor', "failed_authentication::$user_id,missing_provider", compact( 'user_id', 'post_data' ), compact( 'user_id' ) ); return new WP_Error( 'itsec-two-factor-missing-provider', esc_html__( 'Invalid Two Factor provider.', 'it-l10n-ithemes-security-pro' ) ); } } else { $provider = $this->two_factor->get_primary_provider_for_user( $user->ID ); } if ( isset( $post_data['itsec_resend_2fa'] ) ) { return new WP_Error( 'itsec-two-factor-resent-2fa', esc_html__( 'Two-Factor code resent.', 'it-l10n-ithemes-security-pro' ), 'message' ); } $provider_class = get_class( $provider ); $user_id = $user->ID; if ( true !== $provider->validate_authentication( $user ) ) { ITSEC_Log::add_debug( 'two_factor', "failed_authentication::$user_id,$provider_class,invalid_code", compact( 'user_id', 'provider_class', 'post_data' ), compact( 'user_id' ) ); $this->failed_provider = $provider; add_filter( 'itsec-filter-failed-login-details', array( $this, 'filter_failed_login_details' ) ); $error = new WP_Error( 'itsec-two-factor-invalid-code', esc_html__( 'ERROR: Invalid Authentication Code.', 'it-l10n-ithemes-security-pro' ) ); do_action( 'wp_login_failed', $user->user_login, $error ); return $error; } $this->current_provider_class = $provider_class; return null; } public function has_async_action() { return true; } public function handle_async_action( ITSEC_Login_Interstitial_Session $session, $action, array $args ) { if ( '2fa-verify-email' !== $action ) { return null; } ITSEC_Core::get_login_interstitial()->proceed_to_next( $session ); return array( 'message' => esc_html__( 'Login authorized. Please continue in your original browser.', 'it-l10n-ithemes-security-pro' ), ); } public function after_submit( ITSEC_Login_Interstitial_Session $session, array $post_data ) { $user_id = $session->get_user()->ID; $provider_class = $this->current_provider_class; ITSEC_Log::add_debug( 'two_factor', "successful_authentication::$user_id,$provider_class", compact( 'user_id', 'provider_class', 'post_data' ), compact( 'user_id' ) ); do_action( 'itsec-two-factor-successful-authentication', $user_id, $provider_class, $post_data ); } public function show_to_user( WP_User $user, $is_requested ) { if ( ! $this->two_factor->is_user_using_two_factor( $user->ID ) ) { return false; } if ( $this->two_factor->is_sync_override_active( $user->ID ) ) { // Sync override is active. Do not request the authentication code. return false; } if ( did_action( 'jetpack_sso_handle_login' ) ) { // This is a Jetpack Single Sign On login. return false; } if ( ITSEC_Modules::get_setting( 'two-factor', 'disable_first_login' ) && ! get_user_meta( $user->ID, '_itsec_has_logged_in', true ) ) { return false; } /** * Filters whether the Two-Factor interstitial should be shown to the given user. * * @param bool $show_to_user * @param WP_User $user * @param bool $is_requested */ return apply_filters( 'itsec_two_factor_interstitial_show_to_user', true, $user, $is_requested ); } public function get_priority() { return 1; } /** * Filter the failed login details. * * @param array $details * * @return array */ public function filter_failed_login_details( $details ) { if ( empty( $this->failed_provider ) ) { $details['authentication_types'] = array( __( 'unknown_two_factor_provider', 'it-l10n-ithemes-security-pro' ), 'unknown' ); } else { $details['authentication_types'] = array( $this->failed_provider->get_label(), get_class( $this->failed_provider ) ); } return $details; } }