Making WordPress.org


Ignore:
Timestamp:
04/27/2021 04:24:21 AM (3 years ago)
Author:
dd32
Message:

Login: Allow registrations with "low reCaptcha scores" to register, but go into a pending-moderation state.

This will allow legitimate users who receive a "Please try again" error to be manually approved.

This will also allow us to experiment with more aggressive anti-spam measures, as the majority of current spam registrations are human generated.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-login/admin/class-user-registrations-list-table.php

    r10901 r10928  
    22
    33class User_Registrations_List_Table extends WP_List_Table {
     4
     5    function get_views() {
     6        global $wpdb;
     7
     8        $views = [
     9            [
     10                'all',
     11                'All',
     12            ],
     13            [
     14                'pending',
     15                'Pending Email Confirmation',
     16            ],
     17            [
     18                'registered',
     19                'Completed registration',
     20            ],
     21            [
     22                'spam',
     23                'Caught in spam',
     24            ],
     25            [
     26                'akismet',
     27                'Akismet said no',
     28            ]
     29        ];
     30
     31        $default      = 'all';
     32        $current_view = $_REQUEST['view'] ?? $default;
     33
     34        if ( isset( $_GET['s'] ) ) {
     35            $default = 'search';
     36            $views[0] = [
     37                'search', 'All search results'
     38            ];
     39
     40            array_unshift( $views, [ 'all', 'All' ] );
     41
     42            if ( 'all' === $current_view ) {
     43                $current_view = 'search';
     44            }
     45        }
     46
     47        return array_map(
     48            function( $item ) use ( $current_view ) {
     49                global $wpdb;
     50
     51                $count = $wpdb->get_var(
     52                    "SELECT count(*) FROM {$wpdb->base_prefix}user_pending_registrations WHERE " .
     53                    $this->get_where_sql( $item[0] )
     54                );
     55
     56                $url = admin_url( 'index.php?page=user-registrations' );
     57                if ( !empty( $_GET['s'] ) && 'all' != $item[0] ) {
     58                    $url = add_query_arg( 's', urlencode( $_GET['s'] ), $url );
     59                }
     60
     61                $url = add_query_arg( 'view', $item[0], $url );
     62
     63                return sprintf(
     64                    '<a href="%s" class="%s">%s <span class="count">(%s)</span></a>',
     65                    $url,
     66                    $current_view === $item[0] ? 'current' : '',
     67                    $item[1],
     68                    number_format_i18n( $count ),
     69                );
     70            }, $views
     71        );
     72    }
     73
     74    protected function get_view_sql_where( $view ) {
     75        switch ( $view ) {
     76            case 'pending':
     77                return 'created = 0 AND cleared = 1';
     78            case 'spam':
     79                return 'cleared = 0';
     80            case 'akismet':
     81                return "meta LIKE '%akismet_result\":\"spam%'";
     82            case 'registered':
     83                return 'created = 1';
     84            default:
     85            case 'all':
     86                return '1=1';
     87        }
     88    }
     89
     90    protected function get_where_sql( $view = null ) {
     91        global $wpdb;
     92
     93        $where = $this->get_view_sql_where( $view ?: ( $_REQUEST['view'] ?? 'all' ) );
     94
     95        if ( isset( $_GET['s'] ) && 'all' != $view ) {
     96             $search_like = '%' . $wpdb->esc_like( wp_unslash( $_GET['s'] ) ) . '%';
     97             $where .= $wpdb->prepare(
     98                 " AND ( user_login LIKE %s OR user_email LIKE %s OR meta LIKE %s )",
     99                 $search_like, $search_like, $search_like
     100            );
     101        }
     102
     103        return $where;
     104    }
    4105
    5106    function get_columns() {
    6107        return [
    7             'pending_id'      => 'ID',
    8             'created'         => 'Created',
    9108            'user_login'      => 'User Login',
    10             'user_email'      => 'User Email',
    11             'user_ip'         => 'IP',
    12             'scores'          => 'reCaptcha',
    13             'akismet'         => 'Akismet',
    14             'user_registered' => 'Registered Date',
    15             'created_date'    => 'Created Date',
     109            'meta'            => 'Meta',
     110            'scores'          => 'Anti-spam<br>reCaptcha Akismet',
     111            'user_registered' => 'Registered',
    16112        ];
    17113     }
     
    19115     public function get_sortable_columns() {
    20116        return [
    21             'pending_id'      => array( 'pending_id', false ),
    22             'created'         => array( 'created', true ),
    23117            'user_login'      => array( 'user_login', true ),
    24             'user_email'      => array( 'user_email', true ),
    25118            'scores'          => array( 'scores', true ),
    26             'akismet'         => array( 'akismet', true ),
    27119            'user_registered' => array( 'user_registered', true ),
    28             'created_date'    => array( 'created_date', true ),
    29120        ];
    30121     }
     
    52143       $current_page = $this->get_pagenum();
    53144
    54        $where = '1 = 1 ';
    55        if ( isset( $_GET['s'] ) ) {
    56             $search_like = '%' . $wpdb->esc_like( $_GET['s'] ) . '%';
    57             $where .= $wpdb->prepare(
    58                 "AND ( user_login LIKE %s OR user_email LIKE %s OR meta LIKE %s )",
    59                 $search_like, $search_like, $search_like
    60            );
    61        }
     145       $where = $this->get_where_sql();
    62146
    63147       $per_page_offset = ($current_page-1) * $per_page;
     
    82166    }
    83167
    84     function column_created( $item ) {
    85         echo ( $item->created ? 'Yes' : 'No' );
    86 
    87         if ( ! $item->created ) {
    88             $url = add_query_arg(
    89                 'email',
    90                 urlencode( $item->user_email ),
    91                 admin_url( 'admin-post.php?action=login_resend_email' )
    92             );
    93             $url = wp_nonce_url( $url, 'resend_' . $item->user_email );
    94             echo $this->row_actions( [
    95                 'resend' => '<a href="' . esc_url( $url ) . '">Resend Email</a>',
    96             ] );
    97         }
    98     }
    99 
    100168    function column_user_registered( $item ) {
    101169        printf(
     
    104172            human_time_diff( strtotime( $item->user_registered ) )
    105173        );
    106     }
    107 
    108     function column_created_date( $item ) {
     174
    109175        if ( $item->created_date && '0000-00-00 00:00:00' !== $item->created_date ) {
    110176            printf(
    111                 '<abbr title="%s">%s ago</abbr>',
     177                '<br>Created: <abbr title="%s">%s ago</abbr>',
    112178                esc_attr( $item->created_date ),
    113179                human_time_diff( strtotime( $item->created_date ) )
    114180            );
    115         } else {
    116             echo '&nbsp;';
    117181        }
    118182    }
     
    122186            $url = esc_url( 'https://profiles.wordpress.org/' . $item->user_login . '/' );
    123187            echo "<a href='$url'>" . esc_html( $item->user_login ) . '</a>';
     188
     189            if (
     190                ( $user = get_user_by( 'login', $item->user_login ) ) &&
     191                'BLOCKED' === substr( $user->user_pass, 0, 7 )
     192            ) {
     193                echo ' <span class="delete-red">(blocked)</span>';
     194            }
     195
    124196        } else {
    125197            echo esc_html( $item->user_login );
    126198        }
    127     }
    128 
    129     function column_user_email( $item ) {
     199
     200        echo '<hr>';
     201
    130202        list( $email_user, $domain ) = explode( '@', $item->user_email, 2 );
    131203
     
    136208            esc_html( $domain )
    137209        );
    138     }
    139 
    140 
    141     function column_user_ip( $item ) {
     210
     211        $row_actions = [];
     212
     213        if ( ! $item->created && $item->cleared ) {
     214            $url = add_query_arg(
     215                'email',
     216                urlencode( $item->user_email ),
     217                admin_url( 'admin-post.php?action=login_resend_email' )
     218            );
     219            $url = wp_nonce_url( $url, 'resend_' . $item->user_email );
     220
     221            $row_actions['resend'] = '<a href="' . esc_url( $url ) . '">Resend Email</a>';
     222        }
     223
     224        if ( ! $item->created ) {
     225            if ( $item->user_activation_key ) {
     226                $url = add_query_arg(
     227                    'email',
     228                    urlencode( $item->user_email ),
     229                    admin_url( 'admin-post.php?action=login_block' )
     230                );
     231                $url = wp_nonce_url( $url, 'block_' . $item->user_email );
     232   
     233                $row_actions['block'] = '<a href="' . esc_url( $url ) . '">Block Registration</a>';
     234            }
     235
     236            $url = add_query_arg(
     237                'email',
     238                urlencode( $item->user_email ),
     239                admin_url( 'admin-post.php?action=login_delete' )
     240            );
     241            $url = wp_nonce_url( $url, 'delete_' . $item->user_email );
     242
     243            $row_actions['delete'] = '<a href="' . esc_url( $url ) . '">Delete</a>';
     244
     245        } else {
     246            $url = add_query_arg(
     247                'email',
     248                urlencode( $item->user_email ),
     249                admin_url( 'admin-post.php?action=login_block_account' )
     250            );
     251            $url = wp_nonce_url( $url, 'block_account_' . $item->user_email );
     252
     253            if (
     254                ! ( $user = get_user_by( 'login', $item->user_login ) ) ||
     255                'BLOCKED' !== substr( $user->user_pass, 0, 7 )
     256            ) {
     257                $row_actions['block-account'] = '<a href="' . esc_url( $url ) . '">Block Account</a>';
     258            }
     259
     260        }
     261
     262        if ( $row_actions ) {
     263            echo $this->row_actions( $row_actions );
     264        }
     265
     266    }
     267
     268
     269    function column_meta( $item ) {
    142270        $meta = json_decode( $item->meta );
    143271
     
    158286            )
    159287        );
     288        echo '<hr>';
     289
     290        foreach ( [ 'url', 'from', 'occ', 'interests' ] as $field ) {
     291            if ( !empty( $meta->$field ) ) {
     292                printf( "%s: %s<br>", esc_html( $field ), esc_html( $meta->$field ) );
     293            }
     294        }
    160295    }
    161296
    162297    function column_scores( $item ) {
     298
     299        echo ( $item->cleared ? 'Passed' : 'Failed' ) . '<br>';
     300
    163301        foreach ( json_decode( $item->scores ) as $type => $val ) {
    164302            printf(
     
    168306            );
    169307        }
    170     }
    171 
    172     function column_akismet( $item ) {
    173         $meta = json_decode( $item->meta, true );
    174 
    175         echo $meta['akismet_result'] ?? '';
     308
     309        $meta    = json_decode( $item->meta );
     310        $akismet = $meta->akismet_result ?? '';
     311        if ( $akismet ) {
     312            printf(
     313                '<abbr title="%s">%s</abbr> ',
     314                esc_attr( 'Akismet' ),
     315                esc_html( strtolower( $akismet ) )
     316            );
     317        }
     318
     319        $row_actions = [];
     320
     321        if ( ! $item->created && $item->user_activation_key ) {
     322            $url = add_query_arg(
     323                'email',
     324                urlencode( $item->user_email ),
     325                admin_url( 'admin-post.php?action=login_block' )
     326            );
     327            $url = wp_nonce_url( $url, 'block_' . $item->user_email );
     328
     329            $row_actions['block'] = '<a href="' . esc_url( $url ) . '">Block Registration</a>';
     330        }
     331
     332        if ( ! $item->cleared ) {
     333            $url = add_query_arg(
     334                'email',
     335                urlencode( $item->user_email ),
     336                admin_url( 'admin-post.php?action=login_mark_as_cleared' )
     337            );
     338            $url = wp_nonce_url( $url, 'clear_' . $item->user_email );
     339            $row_actions['approve-reg'] = '<a href="' . esc_url( $url ) . '">Approve</a>';
     340        }
     341
     342        if ( $row_actions ) {
     343            echo $this->row_actions( $row_actions );
     344        }
    176345    }
    177346
Note: See TracChangeset for help on using the changeset viewer.