Make WordPress Core

Changeset 61660


Ignore:
Timestamp:
02/17/2026 09:24:56 AM (5 weeks ago)
Author:
audrasjb
Message:

Networks and Sites: Don't automatically mark website as spam when an account is marked as spam.

This changeset does the following:

  • Explicitly add 403 to wp_die() calls for unauthorized actions
  • Introduce the network_user_spam_propagate_to_blogs filter to provide flexibility for developers to control spam status propagation
  • Use is_super_admin() checks for both "spam" and "notspam" actions to prevent unauthorized modification of network administrators
  • Refine the "notspam" logic to ensure that blog status updates are correctly scoped to the current network
  • Add related unit tests coverage

Props ignatiusjeroe, realloc, johnjamesjacoby, westonruter, mukesh27, pratiknawkar94, anukasha.
Fixes #61146.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/network/users.php

    r59784 r61660  
    8787                                            __( 'Warning! User cannot be modified. The user %s is a network administrator.' ),
    8888                                            esc_html( $user->user_login )
    89                                         )
     89                                        ),
     90                                        403
    9091                                    );
    9192                                }
    9293
    9394                                $userfunction = 'all_spam';
    94                                 $blogs        = get_blogs_of_user( $user_id, true );
    95 
    96                                 foreach ( (array) $blogs as $details ) {
    97                                     if ( ! is_main_site( $details->userblog_id ) ) { // Main site is not a spam!
    98                                         update_blog_status( $details->userblog_id, 'spam', '1' );
     95
     96                                /**
     97                                 * Filters whether to propagate the blog status when a user is marked as spam.
     98                                 *
     99                                 * @since 7.0.0
     100                                 *
     101                                 * @param bool $propagate Whether to propagate the blog status. Default false.
     102                                 * @param int  $user_id   User ID.
     103                                 */
     104                                if ( apply_filters( 'propagate_network_user_spam_to_blogs', false, $user_id ) ) {
     105                                    foreach ( get_blogs_of_user( $user_id, true ) as $details ) {
     106                                        // Assuming the main site is not a spam.
     107                                        if ( ! is_main_site( $details->userblog_id ) ) {
     108                                            update_blog_status( $details->userblog_id, 'spam', '1' );
     109                                        }
    99110                                    }
    100111                                }
     
    109120                                $user = get_userdata( $user_id );
    110121
     122                                if ( is_super_admin( $user->ID ) ) {
     123                                    wp_die(
     124                                        sprintf(
     125                                            /* translators: %s: User login. */
     126                                            __( 'Warning! User cannot be modified. The user %s is a network administrator.' ),
     127                                            esc_html( $user->user_login )
     128                                        ),
     129                                        403
     130                                    );
     131                                }
     132
    111133                                $userfunction = 'all_notspam';
    112134                                $blogs        = get_blogs_of_user( $user_id, true );
    113135
    114                                 foreach ( (array) $blogs as $details ) {
    115                                     update_blog_status( $details->userblog_id, 'spam', '0' );
     136                                /** This filter is documented in wp-admin/network/users.php */
     137                                if ( apply_filters( 'propagate_network_user_spam_to_blogs', false, $user_id ) ) {
     138                                    foreach ( get_blogs_of_user( $user_id, true ) as $details ) {
     139                                        if ( ! is_main_site( $details->userblog_id ) && get_current_network_id() === $details->site_id ) {
     140                                            // Assuming main site is never a spam and part of the current network.
     141                                            update_blog_status( $details->userblog_id, 'spam', '0' );
     142                                        }
     143                                    }
    116144                                }
    117145
  • trunk/tests/phpunit/tests/user.php

    r61656 r61660  
    885885
    886886    /**
     887     * Helper to create a user and add them to multiple blogs.
     888     *
     889     * @param int  $num_blogs          Number of additional blogs to create and add the user to.
     890     * @param bool $include_main_site  Whether to add the user to the main site as well.
     891     * @return array Array with 'user_id' and 'blogs' (array of blog IDs).
     892     */
     893    private function create_user_with_blogs( $num_blogs = 1, $include_main_site = false ) {
     894        $user_id = self::factory()->user->create();
     895
     896        $blogs = array();
     897        if ( $include_main_site ) {
     898            add_user_to_blog( get_main_site_id(), $user_id, 'administrator' );
     899            $blogs[] = get_main_site_id();
     900        }
     901
     902        for ( $i = 0; $i < $num_blogs; $i++ ) {
     903            $blog_id = self::factory()->blog->create(
     904                array(
     905                    'site_id' => get_current_network_id(),
     906                )
     907            );
     908            add_user_to_blog( $blog_id, $user_id, 'administrator' );
     909            $blogs[] = $blog_id;
     910        }
     911
     912        return array(
     913            'user_id' => $user_id,
     914            'blogs'   => $blogs,
     915        );
     916    }
     917
     918    /**
     919     * @ticket 61146
     920     */
     921    public function test_default_do_not_propagate_network_user_spam_to_blogs_on_multisite() {
     922        if ( ! is_multisite() ) {
     923            $this->markTestSkipped( 'This test is for multisite only.' );
     924        }
     925
     926        $data    = $this->create_user_with_blogs( 2 );
     927        $user_id = $data['user_id'];
     928        $blogs   = $data['blogs'];
     929
     930        // Mark user spam in user record (this alone should not change blog spam states).
     931        $u = wp_update_user(
     932            array(
     933                'ID'   => $user_id,
     934                'spam' => '1',
     935            )
     936        );
     937        $this->assertNotWPError( $u );
     938        $user = get_userdata( $user_id );
     939        $this->assertSame( '1', $user->spam );
     940
     941        foreach ( $blogs as $blog_id ) {
     942            $this->assertNotSame( '1', get_blog_status( $blog_id, 'spam' ), "Blog {$blog_id} should not be marked spam by default." );
     943        }
     944    }
     945
     946    /**
    887947     * @ticket 28315
    888948     */
Note: See TracChangeset for help on using the changeset viewer.