Make WordPress Core

Changeset 56075


Ignore:
Timestamp:
06/27/2023 05:24:44 PM (19 months ago)
Author:
kadamwhite
Message:

REST API: Check post meta update authorization only when value is changed.

Resolves a bug where a post save will be reported as failed if the post includes any meta keys the current user does not have authorization to update, even when those meta values are unchanged.
Write authorization is now checked for a meta key only when the value of that key has changed, so that passing a REST response back unchanged will not cause failures.
Authorization is only needed when data will be updated.

Props ckoerner, TimothyBlynJacobs, spacedmonkey

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php

    r54133 r56075  
    369369        $meta_type = $this->get_meta_type();
    370370
     371        // Do the exact same check for a duplicate value as in update_metadata() to avoid update_metadata() returning false.
     372        $old_value = get_metadata( $meta_type, $object_id, $meta_key );
     373        $subtype   = get_object_subtype( $meta_type, $object_id );
     374
     375        if ( is_array( $old_value ) && 1 === count( $old_value )
     376            && $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $old_value[0], $value )
     377        ) {
     378            return true;
     379        }
     380
    371381        if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) {
    372382            return new WP_Error(
     
    379389                )
    380390            );
    381         }
    382 
    383         // Do the exact same check for a duplicate value as in update_metadata() to avoid update_metadata() returning false.
    384         $old_value = get_metadata( $meta_type, $object_id, $meta_key );
    385         $subtype   = get_object_subtype( $meta_type, $object_id );
    386 
    387         if ( is_array( $old_value ) && 1 === count( $old_value )
    388             && $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $old_value[0], $value )
    389         ) {
    390             return true;
    391391        }
    392392
  • trunk/tests/phpunit/tests/rest-api/rest-post-meta-fields.php

    r55562 r56075  
    23012301
    23022302    /**
     2303     * @ticket 57745
     2304     */
     2305    public function test_update_meta_with_unchanged_values_and_custom_authentication() {
     2306        register_post_meta(
     2307            'post',
     2308            'authenticated',
     2309            array(
     2310                'single'        => true,
     2311                'type'          => 'boolean',
     2312                'default'       => false,
     2313                'show_in_rest'  => true,
     2314                'auth_callback' => '__return_false',
     2315            )
     2316        );
     2317
     2318        add_post_meta( self::$post_id, 'authenticated', false );
     2319
     2320        $this->grant_write_permission();
     2321
     2322        $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     2323        $request->set_body_params(
     2324            array(
     2325                'meta' => array(
     2326                    'authenticated' => false,
     2327                ),
     2328            )
     2329        );
     2330
     2331        $response = rest_get_server()->dispatch( $request );
     2332        $this->assertSame( 200, $response->get_status() );
     2333
     2334        $data = $response->get_data();
     2335        $this->assertSame( false, $data['meta']['authenticated'] );
     2336    }
     2337
     2338    /**
    23032339     * @ticket 43392
    23042340     */
Note: See TracChangeset for help on using the changeset viewer.