Skip to:
Content

bbPress.org

Changeset 6874


Ignore:
Timestamp:
12/02/2018 01:15:57 AM (3 years ago)
Author:
johnjamesjacoby
Message:

Akismet: allow "trusted" users to bypass spam post_status enforcement.

  • Adds bbp_bypass_check_for_spam filter ahead of the HTTP request
  • Adds bbp_bypass_spam_enforcement filter ahead of post_status switch
  • Adds current_user_can( 'moderate' ) check to bypass spam enforcement
  • Adds parse_response() method to BBP_Akismet class for future abstraction

This allows for 2 different ways to short-circuit Akismet:

  • Before the HTTP request happens
  • After the HTTP request, but before the status change

bbPress will now trust users that pass the moderator capability check (including per-forum moderators) even if Akismet thinks the content is spammy. The Akismet history will still reflect the catch; the status will just not be enforced.

This addresses issues we've seen on WordPress.org, BuddyPress.org, and bbPress.org, where trusted moderator posts would be caught in the spam queue, even when they have privileges to enter the queue and unspam their own posts.

Fixes #2917. Props tharsheblows for the original patch!

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/includes/extend/akismet.php

    r6867 r6874  
    147147        $_post_content = trim( $post_data['post_title'] . "\n\n" . $post_data['post_content'] );
    148148
    149         // Put post_data back into usable array
    150         $_post = array(
     149        // Check if the post data is spammy...
     150        $_post = $this->maybe_spam( array(
    151151            'comment_author'                 => $user_data['name'],
    152152            'comment_author_email'           => $user_data['email'],
     
    164164            'user_ip'                        => bbp_current_author_ip(),
    165165            'user_role'                      => $this->get_user_roles( $post_data['post_author'] ),
    166         );
    167 
    168         // Check the post_data
    169         $_post = $this->maybe_spam( $_post );
    170 
    171         // Get the result
    172         $post_data['bbp_akismet_result'] = $_post['bbp_akismet_result'];
     166        ) );
     167
     168        // Set the result (from maybe_spam() above)
     169        $post_data['bbp_akismet_result'] = ! empty( $_post['bbp_akismet_result'] )
     170            ? $_post['bbp_akismet_result'] // raw
     171            : esc_html__( 'No response', 'bbpress' );
     172
     173        // Set the data-as-submitted value without the result (recursion avoidance)
    173174        unset( $_post['bbp_akismet_result'] );
    174 
    175         // Store the data as submitted
    176175        $post_data['bbp_post_as_submitted'] = $_post;
     176
     177        // Cleanup to avoid touching this variable again below
     178        unset( $_post );
    177179
    178180        // Allow post_data to be manipulated
    179181        do_action_ref_array( 'bbp_akismet_check_post', $post_data );
    180182
    181         // Spam
     183        // Parse and log the last response
     184        $this->last_post = $this->parse_response( $post_data );
     185
     186        // Return the last response back to the filter
     187        return $this->last_post;
     188    }
     189
     190    /**
     191     * Parse the response from the Akismet service, and alter the post data as
     192     * necessary. For example, switch the status to `spam` if spammy.
     193     *
     194     * Note: this method also skiis responsible for allowing users who can moderate, to
     195     * never have their posts marked as spam. This is because they are "trusted"
     196     * users. However, their posts are still sent to Akismet to be checked.
     197     *
     198     * @since 2.6.0 bbPress (r6873)
     199     *
     200     * @param array $post_data
     201     *
     202     * @return array
     203     */
     204    private function parse_response( $post_data = array() ) {
     205
     206        // Get the parent ID of the post as submitted
     207        $parent_id = ! empty( $post_data['bbp_post_as_submitted']['comment_post_ID'] )
     208            ? absint( $post_data['bbp_post_as_submitted']['comment_post_ID'] )
     209            : 0;
     210
     211        // Allow moderators to skip spam (includes per-forum moderators via $parent_id)
     212        $skip_spam = current_user_can( 'moderate', $parent_id );
     213
     214        // Bail early if current user can skip spam enforcement
     215        if ( apply_filters( 'bbp_bypass_spam_enforcement', $skip_spam, $post_data ) ) {
     216            return $post_data;
     217        }
     218
     219        // Result is spam, so set the status as such
    182220        if ( 'true' === $post_data['bbp_akismet_result'] ) {
    183221
     
    185223            do_action( 'bbp_akismet_spam_caught' );
    186224
    187             // This is spam
     225            // Set post_status to spam
    188226            $post_data['post_status'] = bbp_get_spam_status_id();
    189227
    190             // We don't want your spam tags here
     228            // Filter spammy tags into meta data
    191229            add_filter( 'bbp_new_reply_pre_set_terms', array( $this, 'filter_post_terms' ), 1, 3 );
    192 
    193             // @todo Spam counter?
    194         }
    195 
    196         // @todo Topic/reply moderation? No true/false response - 'pending' or 'draft'
    197         // @todo Auto-delete old spam?
    198 
    199         // Log the last post
    200         $this->last_post = $post_data;
    201 
    202         // Pass the data back to the filter
     230        }
     231
     232        // Return the (potentially modified) post data
    203233        return $post_data;
    204234    }
     
    433463
    434464        // Fire!
    435         $response = $this->http_post( $query_string, $akismet_api_host, $path, $akismet_api_port );
     465        $response = ! apply_filters( 'bbp_bypass_check_for_spam', false, $post_data )
     466            ? $this->http_post( $query_string, $akismet_api_host, $path, $akismet_api_port )
     467            : false;
    436468
    437469        // Check the high-speed cam
     
    442474        }
    443475
    444         // This is ham
     476        // Return the post data, with the results of the external Akismet request
    445477        return $post_data;
    446478    }
Note: See TracChangeset for help on using the changeset viewer.