Make WordPress Core


Ignore:
Timestamp:
04/14/2021 11:22:07 PM (5 years ago)
Author:
desrosj
Message:

REST API: Allow authors to read their own password protected posts.

Allow authenticated users to read the contents of password protected posts if they have the edit_post meta capability for the post.

Props xknown, zieladam, peterwilsoncc, swissspidy, timothyblynjacobs.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

    r50505 r50717  
    3131         */
    3232        protected $meta;
     33
     34        /**
     35         * Passwordless post access permitted.
     36         *
     37         * @since 5.7.1
     38         * @var int[]
     39         */
     40        protected $password_check_passed = array();
    3341
    3442        /**
     
    150158
    151159        /**
     160         * Override the result of the post password check for REST requested posts.
     161         *
     162         * Allow users to read the content of password protected posts if they have
     163         * previously passed a permission check or if they have the `edit_post` capability
     164         * for the post being checked.
     165         *
     166         * @since 5.7.1
     167         *
     168         * @param bool    $required Whether the post requires a password check.
     169         * @param WP_Post $post     The post been password checked.
     170         * @return bool Result of password check taking in to account REST API considerations.
     171         */
     172        public function check_password_required( $required, $post ) {
     173                if ( ! $required ) {
     174                        return $required;
     175                }
     176
     177                $post = get_post( $post );
     178
     179                if ( ! $post ) {
     180                        return $required;
     181                }
     182
     183                if ( ! empty( $this->password_check_passed[ $post->ID ] ) ) {
     184                        // Password previously checked and approved.
     185                        return false;
     186                }
     187
     188                return ! current_user_can( 'edit_post', $post->ID );
     189        }
     190
     191        /**
    152192         * Retrieves a collection of posts.
    153193         *
     
    315355                // Allow access to all password protected posts if the context is edit.
    316356                if ( 'edit' === $request['context'] ) {
    317                         add_filter( 'post_password_required', '__return_false' );
     357                        add_filter( 'post_password_required', array( $this, 'check_password_required' ), 10, 2 );
    318358                }
    319359
     
    331371                // Reset filter.
    332372                if ( 'edit' === $request['context'] ) {
    333                         remove_filter( 'post_password_required', '__return_false' );
     373                        remove_filter( 'post_password_required', array( $this, 'check_password_required' ) );
    334374                }
    335375
     
    446486                // Allow access to all password protected posts if the context is edit.
    447487                if ( 'edit' === $request['context'] ) {
    448                         add_filter( 'post_password_required', '__return_false' );
     488                        add_filter( 'post_password_required', array( $this, 'check_password_required' ), 10, 2 );
    449489                }
    450490
     
    474514                }
    475515
    476                 // Edit context always gets access to password-protected posts.
    477                 if ( 'edit' === $request['context'] ) {
     516                /*
     517                 * Users always gets access to password protected content in the edit
     518                 * context if they have the `edit_post` meta capability.
     519                 */
     520                if (
     521                        'edit' === $request['context'] &&
     522                        current_user_can( 'edit_post', $post->ID )
     523                ) {
    478524                        return true;
    479525                }
     
    17291775
    17301776                if ( $this->can_access_password_content( $post, $request ) ) {
     1777                        $this->password_check_passed[ $post->ID ] = true;
    17311778                        // Allow access to the post, permissions already checked before.
    1732                         add_filter( 'post_password_required', '__return_false' );
     1779                        add_filter( 'post_password_required', array( $this, 'check_password_required' ), 10, 2 );
    17331780
    17341781                        $has_password_filter = true;
     
    17681815                if ( $has_password_filter ) {
    17691816                        // Reset filter.
    1770                         remove_filter( 'post_password_required', '__return_false' );
     1817                        remove_filter( 'post_password_required', array( $this, 'check_password_required' ) );
    17711818                }
    17721819
Note: See TracChangeset for help on using the changeset viewer.