WordPress.org

Making WordPress.org

Changeset 6748


Ignore:
Timestamp:
02/26/2018 01:22:21 AM (3 years ago)
Author:
dd32
Message:

2FA: WPORG_Two_Factor now extends Two_Factor_Core so that we can override some of the larger surface methods.

This is being done to allow us to customise how some functionality of the plugin works.

See #77.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-two-factor/wporg-two-factor.php

    r6747 r6748  
    1111 */
    1212
    13 class WPORG_Two_Factor {
     13class WPORG_Two_Factor extends Two_Factor_Core {
     14
    1415    public function __construct() {
    1516        add_filter( 'two_factor_providers', [ $this, 'two_factor_providers' ] );
     
    2324        }
    2425
    25         add_action( 'wp_ajax_two-factor-totp-verify-code',[ $this, 'ajax_verify_code' ] );
    26         add_action( 'wp_ajax_two-factor-disable',[ $this, 'ajax_disable' ] );
    27     }
    28 
    29     public function two_factor_providers( $providers ) {
    30         // Limit 2FA to certain users during Development.
    31         if ( ! is_user_logged_in() || ! in_array( get_current_user_id(), [ 148148, 196012, 8772187 ] ) ) {
    32             return array();
    33         }
    34 
     26        add_action( 'wp_ajax_two-factor-totp-verify-code', [ $this, 'ajax_verify_code' ] );
     27        add_action( 'wp_ajax_two-factor-disable',          [ $this, 'ajax_disable' ] );
     28
     29        // Auth cookie unsetting.
     30        remove_action( 'wp_login',                [ 'Two_Factor_Core', 'wp_login' ], 10, 2 );
     31        remove_action( 'login_form_validate_2fa', [ 'Two_Factor_Core', 'login_form_validate_2fa' ] );
     32        remove_action( 'login_form_backup_2fa',   [ 'Two_Factor_Core', 'backup_2fa' ] );
     33
     34        add_action( 'wp_login',                [ $this, 'wp_login' ], 10, 2 );
     35        add_action( 'login_form_validate_2fa', [ $this, 'login_form_validate_2fa' ] );
     36        add_action( 'login_form_backup_2fa',   [ $this, 'backup_2fa' ] );
     37
     38    }
     39
     40    /**
     41     * Handle the browser-based login.
     42     *
     43     * @since 0.1-dev
     44     *
     45     * @param string  $user_login Username.
     46     * @param WP_User $user WP_User object of the logged-in user.
     47     */
     48    public static function wp_login( $user_login, $user ) {
     49        if ( ! self::is_user_using_two_factor( $user->ID ) ) {
     50            return;
     51        }
     52
     53        wp_clear_auth_cookie();
     54
     55        self::show_two_factor_login( $user );
     56        exit;
     57    }
     58
     59    /**
     60     * Login form validation.
     61     *
     62     * @since 0.1-dev
     63     */
     64    public static function login_form_validate_2fa() {
     65        if ( ! isset( $_POST['wp-auth-id'], $_POST['wp-auth-nonce'] ) ) {
     66            return;
     67        }
     68
     69        $user = get_userdata( $_POST['wp-auth-id'] );
     70        if ( ! $user ) {
     71            return;
     72        }
     73
     74        $nonce = $_POST['wp-auth-nonce'];
     75        if ( true !== self::verify_login_nonce( $user->ID, $nonce ) ) {
     76            wp_safe_redirect( get_bloginfo( 'url' ) );
     77            exit;
     78        }
     79
     80        if ( isset( $_POST['provider'] ) ) {
     81            $providers = self::get_available_providers_for_user( $user );
     82            if ( isset( $providers[ $_POST['provider'] ] ) ) {
     83                $provider = $providers[ $_POST['provider'] ];
     84            } else {
     85                wp_die( esc_html__( 'Cheatin’ uh?' ), 403 );
     86            }
     87        } else {
     88            $provider = self::get_primary_provider_for_user( $user->ID );
     89        }
     90
     91        // Allow the provider to re-send codes, etc.
     92        if ( true === $provider->pre_process_authentication( $user ) ) {
     93            $login_nonce = self::create_login_nonce( $user->ID );
     94            if ( ! $login_nonce ) {
     95                wp_die( esc_html__( 'Failed to create a login nonce.', 'two-factor' ) );
     96            }
     97
     98            self::login_html( $user, $login_nonce['key'], $_REQUEST['redirect_to'], '', $provider );
     99            exit;
     100        }
     101
     102        // Ask the provider to verify the second factor.
     103        if ( true !== $provider->validate_authentication( $user ) ) {
     104            do_action( 'wp_login_failed', $user->user_login );
     105
     106            $login_nonce = self::create_login_nonce( $user->ID );
     107            if ( ! $login_nonce ) {
     108                wp_die( esc_html__( 'Failed to create a login nonce.', 'two-factor' ) );
     109            }
     110
     111            self::login_html( $user, $login_nonce['key'], $_REQUEST['redirect_to'], esc_html__( 'ERROR: Invalid verification code.', 'two-factor' ), $provider );
     112            exit;
     113        }
     114
     115        self::delete_login_nonce( $user->ID );
     116
     117        $rememberme = false;
     118        if ( isset( $_REQUEST['rememberme'] ) && $_REQUEST['rememberme'] ) {
     119            $rememberme = true;
     120        }
     121
     122        wp_set_auth_cookie( $user->ID, $rememberme );
     123
     124        // Must be global because that's how login_header() uses it.
     125        global $interim_login;
     126        $interim_login = isset( $_REQUEST['interim-login'] ); // WPCS: override ok.
     127
     128        if ( $interim_login ) {
     129            $customize_login = isset( $_REQUEST['customize-login'] );
     130            if ( $customize_login ) {
     131                wp_enqueue_script( 'customize-base' );
     132            }
     133            $message = '<p class="message">' . __( 'You have logged in successfully.' ) . '</p>';
     134            $interim_login = 'success'; // WPCS: override ok.
     135            login_header( '', $message ); ?>
     136            </div>
     137            <?php
     138            /** This action is documented in wp-login.php */
     139            do_action( 'login_footer' ); ?>
     140            <?php if ( $customize_login ) : ?>
     141                <script type="text/javascript">setTimeout( function(){ new wp.customize.Messenger({ url: '<?php echo wp_customize_url(); /* WPCS: XSS OK. */ ?>', channel: 'login' }).send('login') }, 1000 );</script>
     142            <?php endif; ?>
     143            </body></html>
     144            <?php
     145            exit;
     146        }
     147        $redirect_to = apply_filters( 'login_redirect', $_REQUEST['redirect_to'], $_REQUEST['redirect_to'], $user );
     148        wp_safe_redirect( $redirect_to );
     149
     150        exit;
     151    }
     152
     153
     154    /**
     155     * Add short description. @todo
     156     *
     157     * @since 0.1-dev
     158     */
     159    public static function backup_2fa() {
     160        if ( ! isset( $_GET['wp-auth-id'], $_GET['wp-auth-nonce'], $_GET['provider'] ) ) {
     161            return;
     162        }
     163
     164        $user = get_userdata( $_GET['wp-auth-id'] );
     165        if ( ! $user ) {
     166            return;
     167        }
     168
     169        $nonce = $_GET['wp-auth-nonce'];
     170        if ( true !== self::verify_login_nonce( $user->ID, $nonce ) ) {
     171            wp_safe_redirect( get_bloginfo( 'url' ) );
     172            exit;
     173        }
     174
     175        $providers = self::get_available_providers_for_user( $user );
     176        if ( isset( $providers[ $_GET['provider'] ] ) ) {
     177            $provider = $providers[ $_GET['provider'] ];
     178        } else {
     179            wp_die( esc_html__( 'Cheatin&#8217; uh?' ), 403 );
     180        }
     181
     182        self::login_html( $user, $_GET['wp-auth-nonce'], $_GET['redirect_to'], '', $provider );
     183
     184        exit;
     185    }
     186
     187    public function two_factor_providers( $providers) {
    35188        $wporg_providers = array(
    36189            'WPORG_Two_Factor_Email'        => __DIR__ . '/providers/class-wporg-two-factor-email.php',
     
    48201     * @param \WP_User $user User object.
    49202     */
    50     public function user_two_factor_options( $user ) {
     203    public static function user_two_factor_options( $user ) {
    51204        wp_enqueue_script( 'two-factor-edit', plugins_url( 'js/profile-edit.js' , __FILE__ ), [ 'jquery' ], 1, true );
    52205
Note: See TracChangeset for help on using the changeset viewer.