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;
}
}