Making WordPress.org


Ignore:
Timestamp:
09/23/2019 03:52:23 AM (5 years ago)
Author:
dd32
Message:

Login: Store user registrations in a custom table until they confirm their email address (at which time, we create the actual wp_users records).

This is to combat the significant number of unconfirmed accounts that are created, by separating them it's easier to purge them periodically, but also easier to add extra anti-spam checks as needed.

See #4739.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-login/functions-registration.php

    r6493 r9146  
    1313
    1414    $resp = wp_remote_post( 'https://www.google.com/recaptcha/api/siteverify', array( 'body' => $verify ) );
    15 
    1615    if ( is_wp_error( $resp ) || 200 != wp_remote_retrieve_response_code( $resp ) ) {
    1716        return false;
     
    2423
    2524/**
    26  * Handles registrations and redirects thereafter
    27  */
    28 function wporg_login_create_user( $user_login, $user_email, $user_mailinglist = false ) {
    29     global $wpdb;
     25 * Handles creating a "Pending" registration that will later be converted to an actual user  account.
     26 */
     27function wporg_login_create_pending_user( $user_login, $user_email, $user_mailinglist = false ) {
     28    global $wpdb, $wp_hasher;
    3029
    3130    // Allow for w.org plugins to block registrations based on spam checks, etc.
     
    3736    }
    3837
    39     $user_id = wpmu_create_user( wp_slash( $user_login ), wp_generate_password(), wp_slash( $user_email ) );
    40     if ( ! $user_id ) {
     38    $activation_key = wp_generate_password( 24, false, false );
     39    $profile_key    = wp_generate_password( 24, false, false );
     40
     41    $hashed_activation_key = time() . ':' . wp_hash_password( $activation_key );
     42    $hashed_profile_key    = time() . ':' . wp_hash_password( $profile_key );
     43
     44    $pending_user = array(
     45        'user_login' => $user_login,
     46        'user_email' => $user_email,
     47        'user_registered' => gmdate('Y-m-d  H:i:s'),
     48        'user_activation_key' => $hashed_activation_key,
     49        'user_profile_key' => $hashed_profile_key,
     50        'meta' => array(
     51            'user_mailinglist' => $user_mailinglist,
     52            'registration_ip'  => $_SERVER['REMOTE_ADDR'], // Spam & fraud control. Will be discarded after the account is created.
     53        ),
     54        'scores' => array()
     55    );
     56
     57    $inserted = wporg_update_pending_user( $pending_user );
     58    if ( ! $inserted ) {
    4159        wp_die( __( 'Error! Something went wrong with your registration. Try again?', 'wporg' ) );
    42     }
    43 
    44     // Insert a hashed activation key
    45     $activation_key = wp_generate_password( 24, false, false );
    46     if ( empty( $wp_hasher ) ) {
    47         require_once ABSPATH . WPINC . '/class-phpass.php';
    48         $wp_hasher = new PasswordHash( 8, true );
    49     }
    50     $hashed_activation_key = time() . ':' . $wp_hasher->HashPassword( $activation_key );
    51 
    52     $wpdb->update( $wpdb->users, array( 'user_activation_key' => $hashed_activation_key ), array( 'ID' => $user_id ) );
    53     clean_user_cache( $user_id );
    54 
    55     if ( $user_mailinglist ) {
    56         update_user_meta( $user_id, 'notify_list', 'true' );
    5760    }
    5861
     
    6265    $body .= sprintf( __( 'Your username is: %s', 'wporg' ), $user_login ) . "\n";
    6366    $body .= __( 'You can create a password at the following URL:', 'wporg' ) . "\n";
    64     $body .= home_url( "/register/confirm/{$user_login}/{$activation_key}/" );
     67    $body .= home_url( "/register/create/{$user_login}/{$activation_key}/" );
    6568    $body .= "\n\n";
    6669    $body .= __( '-- The WordPress.org Team', 'wporg' );
     
    7578    );
    7679
    77     wp_set_current_user( $user_id );
    78     $nonce = wp_create_nonce( 'login-register-profile-edit' );
    79     wp_set_current_user( 0 );
    80 
    81     wp_safe_redirect( '/register/profile/' . $user_login . '/' . $nonce );
     80    $url = home_url( sprintf(
     81        '/register/create-profile/%s/%s/',
     82        $user_login,
     83        $profile_key
     84    ) );
     85
     86    wp_safe_redirect( $url );
    8287    die();
    8388}
    8489
    85 function wporg_login_save_profile_fields() {
     90/**
     91 * Fetches a pending user record from the database by username or Email.
     92 */
     93function wporg_get_pending_user( $login_or_email ) {
     94    global $wpdb;
     95
     96    $pending_user = $wpdb->get_row( $wpdb->prepare(
     97        "SELECT * FROM `{$wpdb->base_prefix}user_pending_registrations` WHERE ( `user_login` = %s OR `user_email` = %s ) LIMIT 1",
     98        $login_or_email,
     99        $login_or_email
     100    ), ARRAY_A );
     101
     102    if ( ! $pending_user ) {
     103        return false;
     104    }
     105
     106    $pending_user['meta']   = json_decode( $pending_user['meta'], true );
     107    $pending_user['scores'] = json_decode( $pending_user['scores'], true );
     108
     109    return $pending_user;
     110}
     111
     112/**
     113 * Update the pending user record, similar to `wp_update_user()` but for the not-yet-created user record.
     114 */
     115function wporg_update_pending_user( $pending_user ) {
     116    global $wpdb;
     117    $pending_user['meta']   = json_encode( $pending_user['meta'] );
     118    $pending_user['scores'] = json_encode( $pending_user['scores'] );
     119
     120    if ( empty( $pending_user['pending_id'] ) ) {
     121        unset( $pending_user['pending_id'] );
     122        return $wpdb->insert(
     123            "{$wpdb->base_prefix}user_pending_registrations",
     124            $pending_user
     125        );
     126    } else {
     127        return $wpdb->update(
     128            "{$wpdb->base_prefix}user_pending_registrations",
     129            $pending_user,
     130            array( 'pending_id' => $pending_user['pending_id'] )
     131        );
     132    }
     133
     134}
     135
     136/**
     137 * Create a user record from a pending record.
     138 */
     139function wporg_login_create_user_from_pending( $pending_user, $password = false ) {
     140    global $wpdb;
     141
     142    // Insert user, no password tho.
     143    $user_login = $pending_user['user_login'];
     144    $user_email = $pending_user['user_email'];
     145    $user_mailinglist = !empty( $pending_user['meta']['user_mailinglist'] ) && $pending_user['meta']['user_mailinglist'];
     146
     147    if ( ! $password ) {
     148        $password = wp_generate_password();
     149    }
     150
     151    $user_id = wpmu_create_user(
     152        wp_slash( $user_login ),
     153        $password,
     154        wp_slash( $user_email )
     155    );
     156    if ( ! $user_id ) {
     157        wp_die( __( 'Error! Something went wrong with your registration. Try again?', 'wporg' ) );
     158    }
     159
     160    // Update the registration date to the earlier one.
     161    wp_update_user( array(
     162        'ID' => $user_id,
     163        'user_registered' => $pending_user['user_registered']
     164    ) );
     165
     166    // Update the pending record with the new details.
     167    $pending_user['created'] = 1;
     168    $pending_user['created_date'] = gmdate( 'Y-m-d H:i:s' );
     169    $pending_user['meta']['confirmed_ip'] = $_SERVER['REMOTE_ADDR']; // Spam/Fraud purposes, will be deleted once not needed.
     170    wporg_update_pending_user( $pending_user );
     171
     172    if ( $user_mailinglist ) {
     173        update_user_meta( $user_id, 'notify_list', 'true' );
     174    }
     175
     176    foreach ( array( 'url', 'from', 'occ', 'interests' ) as $field ) {
     177        if ( !empty( $pending_user['meta'][ $field ] ) ) {
     178            $value = $pending_user['meta'][ $field ];
     179            if ( 'url' == $field ) {
     180                wp_update_user( array( 'ID' => $user_id, 'user_url' => $value ) );
     181            } else {
     182                if ( $value ) {
     183                    update_user_meta( $user_id, $field, $value );
     184                } else {
     185                    delete_user_meta( $user_id, $field );
     186                }
     187            }
     188        }
     189    }
     190
     191    return get_user_by( 'id', $user_id );
     192}
     193
     194/**
     195 * Save the user profile fields, potentially prior to user creation and prior to email confirmation.
     196 */
     197function wporg_login_save_profile_fields( $pending_user = false ) {
    86198    if ( ! $_POST || empty( $_POST['user_fields'] ) ) {
    87         return;
     199        return false;
    88200    }
    89201    $fields = array( 'url', 'from', 'occ', 'interests' );
     
    93205            $value = sanitize_text_field( wp_unslash( $_POST['user_fields'][ $field ] ) );
    94206            if ( 'url' == $field ) {
    95                 wp_update_user( array(
    96                     'ID' => get_current_user_id(),
    97                     'user_url' => esc_url_raw( $value ),
    98                 ) );
     207                if ( $pending_user ) {
     208                    $pending_user['meta'][ $field ] = esc_url_raw( $value );
     209                } else {
     210                    wp_update_user( array(
     211                        'ID' => get_current_user_id(),
     212                        'user_url' => esc_url_raw( $value ),
     213                    ) );
     214                }
    99215            } else {
    100                 update_user_meta( get_current_user_id(), $field, $value );
     216                if ( $pending_user ) {
     217                    $pending_user['meta'][ $field ] = $value;
     218                } else {
     219                    if ( $value ) {
     220                        update_user_meta( get_current_user_id(), $field, $value );
     221                    } else {
     222                        delete_user_meta( get_current_user_id(), $field );
     223                    }
     224                }
    101225            }
    102226        }
    103227    }
    104 }
     228
     229    if ( $pending_user ) {
     230        wporg_update_pending_user( $pending_user );
     231    }
     232
     233    return true;
     234}
Note: See TracChangeset for help on using the changeset viewer.