REST API: Tweak permission checks for taxonomy and term endpoints

To match behaviour in the Classic Editor, we need to slightly loosen permissions on taxonomy and term endpoints. This allows users to create terms to assign to a post that they're editing.

Props danielbachhuber.
Fixes #44096.



git-svn-id: https://develop.svn.wordpress.org/trunk@43440 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Gary Pendergast 2018-07-13 04:23:35 +00:00
parent 585c862faf
commit 46c238ca78
5 changed files with 60 additions and 4 deletions

View File

@ -84,7 +84,7 @@ class WP_REST_Taxonomies_Controller extends WP_REST_Controller {
$taxonomies = get_taxonomies( '', 'objects' );
}
foreach ( $taxonomies as $taxonomy ) {
if ( ! empty( $taxonomy->show_in_rest ) && current_user_can( $taxonomy->cap->manage_terms ) ) {
if ( ! empty( $taxonomy->show_in_rest ) && current_user_can( $taxonomy->cap->assign_terms ) ) {
return true;
}
}
@ -113,7 +113,7 @@ class WP_REST_Taxonomies_Controller extends WP_REST_Controller {
}
$data = array();
foreach ( $taxonomies as $tax_type => $value ) {
if ( empty( $value->show_in_rest ) || ( 'edit' === $request['context'] && ! current_user_can( $value->cap->manage_terms ) ) ) {
if ( empty( $value->show_in_rest ) || ( 'edit' === $request['context'] && ! current_user_can( $value->cap->assign_terms ) ) ) {
continue;
}
$tax = $this->prepare_item_for_response( $value, $request );
@ -145,7 +145,7 @@ class WP_REST_Taxonomies_Controller extends WP_REST_Controller {
if ( empty( $tax_obj->show_in_rest ) ) {
return false;
}
if ( 'edit' === $request['context'] && ! current_user_can( $tax_obj->cap->manage_terms ) ) {
if ( 'edit' === $request['context'] && ! current_user_can( $tax_obj->cap->assign_terms ) ) {
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to manage terms in this taxonomy.' ), array( 'status' => rest_authorization_required_code() ) );
}
}

View File

@ -380,7 +380,10 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
}
$taxonomy_obj = get_taxonomy( $this->taxonomy );
if ( ! current_user_can( $taxonomy_obj->cap->edit_terms ) ) {
if ( ( is_taxonomy_hierarchical( $this->taxonomy )
&& ! current_user_can( $taxonomy_obj->cap->edit_terms ) )
|| ( ! is_taxonomy_hierarchical( $this->taxonomy )
&& ! current_user_can( $taxonomy_obj->cap->assign_terms ) ) ) {
return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to create new terms.' ), array( 'status' => rest_authorization_required_code() ) );
}

View File

@ -12,6 +12,7 @@
*/
class WP_Test_REST_Categories_Controller extends WP_Test_REST_Controller_Testcase {
protected static $administrator;
protected static $contributor;
protected static $subscriber;
public static function wpSetUpBeforeClass( $factory ) {
@ -20,6 +21,11 @@ class WP_Test_REST_Categories_Controller extends WP_Test_REST_Controller_Testcas
'role' => 'administrator',
)
);
self::$contributor = $factory->user->create(
array(
'role' => 'subscriber',
)
);
self::$subscriber = $factory->user->create(
array(
'role' => 'subscriber',
@ -726,6 +732,14 @@ class WP_Test_REST_Categories_Controller extends WP_Test_REST_Controller_Testcas
$this->assertErrorResponse( 'rest_cannot_create', $response, 403 );
}
public function test_create_item_incorrect_permissions_contributor() {
wp_set_current_user( self::$contributor );
$request = new WP_REST_Request( 'POST', '/wp/v2/categories' );
$request->set_param( 'name', 'Incorrect permissions' );
$response = rest_get_server()->dispatch( $request );
$this->assertErrorResponse( 'rest_cannot_create', $response, 403 );
}
public function test_create_item_missing_arguments() {
wp_set_current_user( self::$administrator );
$request = new WP_REST_Request( 'POST', '/wp/v2/categories' );

View File

@ -13,6 +13,7 @@ class WP_Test_REST_Tags_Controller extends WP_Test_REST_Controller_Testcase {
protected static $superadmin;
protected static $administrator;
protected static $editor;
protected static $contributor;
protected static $subscriber;
public static function wpSetUpBeforeClass( $factory ) {
@ -32,6 +33,11 @@ class WP_Test_REST_Tags_Controller extends WP_Test_REST_Controller_Testcase {
'role' => 'editor',
)
);
self::$contributor = $factory->user->create(
array(
'role' => 'contributor',
)
);
self::$subscriber = $factory->user->create(
array(
'role' => 'subscriber',
@ -624,6 +630,22 @@ class WP_Test_REST_Tags_Controller extends WP_Test_REST_Controller_Testcase {
$this->assertEquals( 'so-awesome', $data['slug'] );
}
public function test_create_item_contributor() {
wp_set_current_user( self::$contributor );
$request = new WP_REST_Request( 'POST', '/wp/v2/tags' );
$request->set_param( 'name', 'My Awesome Term' );
$request->set_param( 'description', 'This term is so awesome.' );
$request->set_param( 'slug', 'so-awesome' );
$response = rest_get_server()->dispatch( $request );
$this->assertEquals( 201, $response->get_status() );
$headers = $response->get_headers();
$data = $response->get_data();
$this->assertContains( '/wp/v2/tags/' . $data['id'], $headers['Location'] );
$this->assertEquals( 'My Awesome Term', $data['name'] );
$this->assertEquals( 'This term is so awesome.', $data['description'] );
$this->assertEquals( 'so-awesome', $data['slug'] );
}
public function test_create_item_incorrect_permissions() {
wp_set_current_user( self::$subscriber );
$request = new WP_REST_Request( 'POST', '/wp/v2/tags' );

View File

@ -62,6 +62,23 @@ class WP_Test_REST_Taxonomies_Controller extends WP_Test_REST_Controller_Testcas
$this->assertEquals( 'tags', $data['post_tag']['rest_base'] );
}
public function test_get_items_context_edit() {
wp_set_current_user( self::$contributor_id );
$request = new WP_REST_Request( 'GET', '/wp/v2/taxonomies' );
$request->set_param( 'context', 'edit' );
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$taxonomies = $this->get_public_taxonomies( get_taxonomies( '', 'objects' ) );
$this->assertEquals( count( $taxonomies ), count( $data ) );
$this->assertEquals( 'Categories', $data['category']['name'] );
$this->assertEquals( 'category', $data['category']['slug'] );
$this->assertEquals( true, $data['category']['hierarchical'] );
$this->assertEquals( 'Tags', $data['post_tag']['name'] );
$this->assertEquals( 'post_tag', $data['post_tag']['slug'] );
$this->assertEquals( false, $data['post_tag']['hierarchical'] );
$this->assertEquals( 'tags', $data['post_tag']['rest_base'] );
}
public function test_get_items_invalid_permission_for_context() {
wp_set_current_user( 0 );
$request = new WP_REST_Request( 'GET', '/wp/v2/taxonomies' );