REST API: Return a WP_Error
when a user does not have permission to create or update a post with the provided terms.
Add the 'assign_term' check for post create and update. Props boonebgorges, johnbillion. Fixes #38505. git-svn-id: https://develop.svn.wordpress.org/trunk@39108 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
f2f3b3696b
commit
973ade2a28
@ -459,6 +459,10 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to create new posts.' ), array( 'status' => rest_authorization_required_code() ) );
|
||||
}
|
||||
|
||||
if ( ! $this->check_assign_terms_permission( $request ) ) {
|
||||
return new WP_Error( 'rest_cannot_assign_term', __( 'You do not have permission to assign the provided terms.' ), array( 'status' => rest_authorization_required_code() ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -592,6 +596,10 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
return new WP_Error( 'rest_cannot_assign_sticky', __( 'You do not have permission to make posts sticky.' ), array( 'status' => rest_authorization_required_code() ) );
|
||||
}
|
||||
|
||||
if ( ! $this->check_assign_terms_permission( $request ) ) {
|
||||
return new WP_Error( 'rest_cannot_assign_term', __( 'You do not have permission to assign the provided terms.' ), array( 'status' => rest_authorization_required_code() ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1205,6 +1213,38 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether current user can assign all terms sent with the current request.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @param WP_REST_Request $request The request object with post and terms data.
|
||||
* @return bool Whether the current user can assign the provided terms.
|
||||
*/
|
||||
protected function check_assign_terms_permission( $request ) {
|
||||
$taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
|
||||
foreach ( $taxonomies as $taxonomy ) {
|
||||
$base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
|
||||
|
||||
if ( ! isset( $request[ $base ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $request[ $base ] as $term_id ) {
|
||||
// Invalid terms will be rejected later.
|
||||
if ( ! get_term( $term_id, $taxonomy->name ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'assign_term', (int) $term_id ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given post type can be viewed or managed.
|
||||
*
|
||||
|
@ -18,6 +18,8 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
||||
|
||||
protected static $supported_formats;
|
||||
|
||||
protected $forbidden_cat;
|
||||
|
||||
public static function wpSetUpBeforeClass( $factory ) {
|
||||
self::$post_id = $factory->post->create();
|
||||
|
||||
@ -1504,6 +1506,35 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
||||
$this->assertEquals( array(), $data['categories'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38505
|
||||
*/
|
||||
public function test_create_post_with_categories_that_cannot_be_assigned_by_current_user() {
|
||||
$cats = self::factory()->category->create_many( 2 );
|
||||
$this->forbidden_cat = $cats[1];
|
||||
|
||||
wp_set_current_user( self::$editor_id );
|
||||
$request = new WP_REST_Request( 'POST', '/wp/v2/posts' );
|
||||
$params = $this->set_post_data( array(
|
||||
'password' => 'testing',
|
||||
'categories' => $cats,
|
||||
) );
|
||||
$request->set_body_params( $params );
|
||||
|
||||
add_filter( 'map_meta_cap', array( $this, 'revoke_assign_term' ), 10, 4 );
|
||||
$response = $this->server->dispatch( $request );
|
||||
remove_filter( 'map_meta_cap', array( $this, 'revoke_assign_term' ), 10, 4 );
|
||||
|
||||
$this->assertErrorResponse( 'rest_cannot_assign_term', $response, 403 );
|
||||
}
|
||||
|
||||
public function revoke_assign_term( $caps, $cap, $user_id, $args ) {
|
||||
if ( 'assign_term' === $cap && isset( $args[0] ) && $this->forbidden_cat == $args[0] ) {
|
||||
$caps = array( 'do_not_allow' );
|
||||
}
|
||||
return $caps;
|
||||
}
|
||||
|
||||
public function test_update_item() {
|
||||
wp_set_current_user( self::$editor_id );
|
||||
|
||||
@ -1950,6 +1981,28 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
|
||||
$this->assertEquals( array(), $new_data['categories'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38505
|
||||
*/
|
||||
public function test_update_post_with_categories_that_cannot_be_assigned_by_current_user() {
|
||||
$cats = self::factory()->category->create_many( 2 );
|
||||
$this->forbidden_cat = $cats[1];
|
||||
|
||||
wp_set_current_user( self::$editor_id );
|
||||
$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
|
||||
$params = $this->set_post_data( array(
|
||||
'password' => 'testing',
|
||||
'categories' => $cats,
|
||||
) );
|
||||
$request->set_body_params( $params );
|
||||
|
||||
add_filter( 'map_meta_cap', array( $this, 'revoke_assign_term' ), 10, 4 );
|
||||
$response = $this->server->dispatch( $request );
|
||||
remove_filter( 'map_meta_cap', array( $this, 'revoke_assign_term' ), 10, 4 );
|
||||
|
||||
$this->assertErrorResponse( 'rest_cannot_assign_term', $response, 403 );
|
||||
}
|
||||
|
||||
public function test_delete_item() {
|
||||
$post_id = $this->factory->post->create( array( 'post_title' => 'Deleted post' ) );
|
||||
wp_set_current_user( self::$editor_id );
|
||||
|
Loading…
Reference in New Issue
Block a user