REST API: Use term-specific caps for permission checks in term update and delete endpoints.

See #38505.

git-svn-id: https://develop.svn.wordpress.org/trunk@38960 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Boone Gorges 2016-10-26 14:51:54 +00:00
parent 509a314de8
commit a6a15b1819
2 changed files with 99 additions and 4 deletions

View File

@ -451,8 +451,7 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
return new WP_Error( 'rest_term_invalid', __( "Resource doesn't exist." ), array( 'status' => 404 ) );
}
$taxonomy_obj = get_taxonomy( $this->taxonomy );
if ( ! current_user_can( $taxonomy_obj->cap->edit_terms ) ) {
if ( ! current_user_can( 'edit_term', $term->term_id ) ) {
return new WP_Error( 'rest_cannot_update', __( 'Sorry, you cannot update resource.' ), array( 'status' => rest_authorization_required_code() ) );
}
@ -527,8 +526,8 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
if ( ! $term ) {
return new WP_Error( 'rest_term_invalid', __( "Resource doesn't exist." ), array( 'status' => 404 ) );
}
$taxonomy_obj = get_taxonomy( $this->taxonomy );
if ( ! current_user_can( $taxonomy_obj->cap->delete_terms ) ) {
if ( ! current_user_can( 'delete_term', $term->term_id ) ) {
return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you cannot delete resource.' ), array( 'status' => rest_authorization_required_code() ) );
}
return true;

View File

@ -533,6 +533,54 @@ class WP_Test_REST_Tags_Controller extends WP_Test_REST_Controller_Testcase {
$this->assertErrorResponse( 'rest_cannot_update', $response, 403 );
}
/**
* @ticket 38505
*/
public function test_update_item_with_edit_term_cap_granted() {
wp_set_current_user( self::$subscriber );
$term = $this->factory->tag->create_and_get();
$request = new WP_REST_Request( 'POST', '/wp/v2/tags/' . $term->term_id );
$request->set_param( 'name', 'New Name' );
add_filter( 'map_meta_cap', array( $this, 'grant_edit_term' ), 10, 2 );
$response = $this->server->dispatch( $request );
remove_filter( 'user_has_cap', array( $this, 'grant_edit_term' ), 10, 2 );
$this->assertEquals( 200, $response->get_status() );
$data = $response->get_data();
$this->assertEquals( 'New Name', $data['name'] );
}
public function grant_edit_term( $caps, $cap ) {
if ( 'edit_term' === $cap ) {
$caps = array( 'read' );
}
return $caps;
}
/**
* @ticket 38505
*/
public function test_update_item_with_edit_term_cap_revoked() {
wp_set_current_user( self::$administrator );
$term = $this->factory->tag->create_and_get();
$request = new WP_REST_Request( 'POST', '/wp/v2/tags/' . $term->term_id );
$request->set_param( 'name', 'New Name' );
add_filter( 'map_meta_cap', array( $this, 'revoke_edit_term' ), 10, 2 );
$response = $this->server->dispatch( $request );
remove_filter( 'user_has_cap', array( $this, 'revoke_edit_term' ), 10, 2 );
$this->assertErrorResponse( 'rest_cannot_update', $response, 403 );
}
public function revoke_edit_term( $caps, $cap ) {
if ( 'edit_term' === $cap ) {
$caps = array( 'do_not_allow' );
}
return $caps;
}
public function test_update_item_parent_non_hierarchical_taxonomy() {
wp_set_current_user( self::$administrator );
$term = get_term_by( 'id', $this->factory->tag->create(), 'post_tag' );
@ -578,6 +626,54 @@ class WP_Test_REST_Tags_Controller extends WP_Test_REST_Controller_Testcase {
$this->assertErrorResponse( 'rest_cannot_delete', $response, 403 );
}
/**
* @ticket 38505
*/
public function test_delete_item_with_delete_term_cap_granted() {
wp_set_current_user( self::$subscriber );
$term = get_term_by( 'id', $this->factory->tag->create( array( 'name' => 'Deleted Tag' ) ), 'post_tag' );
$request = new WP_REST_Request( 'DELETE', '/wp/v2/tags/' . $term->term_id );
$request->set_param( 'force', true );
add_filter( 'map_meta_cap', array( $this, 'grant_delete_term' ), 10, 2 );
$response = $this->server->dispatch( $request );
remove_filter( 'map_meta_cap', array( $this, 'grant_delete_term' ), 10, 2 );
$this->assertEquals( 200, $response->get_status() );
$data = $response->get_data();
$this->assertEquals( 'Deleted Tag', $data['name'] );
}
public function grant_delete_term( $caps, $cap ) {
if ( 'delete_term' === $cap ) {
$caps = array( 'read' );
}
return $caps;
}
/**
* @ticket 38505
*/
public function test_delete_item_with_delete_term_cap_revoked() {
wp_set_current_user( self::$administrator );
$term = get_term_by( 'id', $this->factory->tag->create( array( 'name' => 'Deleted Tag' ) ), 'post_tag' );
$request = new WP_REST_Request( 'DELETE', '/wp/v2/tags/' . $term->term_id );
$request->set_param( 'force', true );
add_filter( 'map_meta_cap', array( $this, 'revoke_delete_term' ), 10, 2 );
$response = $this->server->dispatch( $request );
remove_filter( 'map_meta_cap', array( $this, 'revoke_delete_term' ), 10, 2 );
$this->assertErrorResponse( 'rest_cannot_delete', $response, 403 );
}
public function revoke_delete_term( $caps, $cap ) {
if ( 'delete_term' === $cap ) {
$caps = array( 'do_not_allow' );
}
return $caps;
}
public function test_prepare_item() {
$term = get_term_by( 'id', $this->factory->tag->create(), 'post_tag' );
$request = new WP_REST_Request( 'GET', '/wp/v2/tags/' . $term->term_id );