From e445660ee3c4aa204a152e0a6dbd250d1896abde Mon Sep 17 00:00:00 2001 From: desrosj Date: Wed, 14 Apr 2021 23:24:04 +0000 Subject: [PATCH] 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. Built from https://develop.svn.wordpress.org/trunk@50717 git-svn-id: http://core.svn.wordpress.org/trunk@50326 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- .../class-wp-rest-posts-controller.php | 61 ++++++++++++++++--- wp-includes/version.php | 2 +- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php index 775f415dc5..16e3c91edf 100644 --- a/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php +++ b/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php @@ -31,6 +31,14 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { */ protected $meta; + /** + * Passwordless post access permitted. + * + * @since 5.7.1 + * @var int[] + */ + protected $password_check_passed = array(); + /** * Constructor. * @@ -148,6 +156,38 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { return true; } + /** + * Override the result of the post password check for REST requested posts. + * + * Allow users to read the content of password protected posts if they have + * previously passed a permission check or if they have the `edit_post` capability + * for the post being checked. + * + * @since 5.7.1 + * + * @param bool $required Whether the post requires a password check. + * @param WP_Post $post The post been password checked. + * @return bool Result of password check taking in to account REST API considerations. + */ + public function check_password_required( $required, $post ) { + if ( ! $required ) { + return $required; + } + + $post = get_post( $post ); + + if ( ! $post ) { + return $required; + } + + if ( ! empty( $this->password_check_passed[ $post->ID ] ) ) { + // Password previously checked and approved. + return false; + } + + return ! current_user_can( 'edit_post', $post->ID ); + } + /** * Retrieves a collection of posts. * @@ -314,7 +354,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { // Allow access to all password protected posts if the context is edit. if ( 'edit' === $request['context'] ) { - add_filter( 'post_password_required', '__return_false' ); + add_filter( 'post_password_required', array( $this, 'check_password_required' ), 10, 2 ); } $posts = array(); @@ -330,7 +370,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { // Reset filter. if ( 'edit' === $request['context'] ) { - remove_filter( 'post_password_required', '__return_false' ); + remove_filter( 'post_password_required', array( $this, 'check_password_required' ) ); } $page = (int) $query_args['paged']; @@ -445,7 +485,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { // Allow access to all password protected posts if the context is edit. if ( 'edit' === $request['context'] ) { - add_filter( 'post_password_required', '__return_false' ); + add_filter( 'post_password_required', array( $this, 'check_password_required' ), 10, 2 ); } if ( $post ) { @@ -473,8 +513,14 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { return false; } - // Edit context always gets access to password-protected posts. - if ( 'edit' === $request['context'] ) { + /* + * Users always gets access to password protected content in the edit + * context if they have the `edit_post` meta capability. + */ + if ( + 'edit' === $request['context'] && + current_user_can( 'edit_post', $post->ID ) + ) { return true; } @@ -1728,8 +1774,9 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { $has_password_filter = false; if ( $this->can_access_password_content( $post, $request ) ) { + $this->password_check_passed[ $post->ID ] = true; // Allow access to the post, permissions already checked before. - add_filter( 'post_password_required', '__return_false' ); + add_filter( 'post_password_required', array( $this, 'check_password_required' ), 10, 2 ); $has_password_filter = true; } @@ -1767,7 +1814,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { if ( $has_password_filter ) { // Reset filter. - remove_filter( 'post_password_required', '__return_false' ); + remove_filter( 'post_password_required', array( $this, 'check_password_required' ) ); } if ( rest_is_field_included( 'author', $fields ) ) { diff --git a/wp-includes/version.php b/wp-includes/version.php index fd9143d561..dd8fad9ff4 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -13,7 +13,7 @@ * * @global string $wp_version */ -$wp_version = '5.8-alpha-50714'; +$wp_version = '5.8-alpha-50717'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.