diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php index e431d4b743..32c543ce19 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php @@ -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() ) ); } } diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php index ea2d0d19a7..af806b812f 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php @@ -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() ) ); } diff --git a/tests/phpunit/tests/rest-api/rest-categories-controller.php b/tests/phpunit/tests/rest-api/rest-categories-controller.php index 2e01943158..ac8d02a0ea 100644 --- a/tests/phpunit/tests/rest-api/rest-categories-controller.php +++ b/tests/phpunit/tests/rest-api/rest-categories-controller.php @@ -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' ); diff --git a/tests/phpunit/tests/rest-api/rest-tags-controller.php b/tests/phpunit/tests/rest-api/rest-tags-controller.php index f2cd6a74a8..2b3cd11250 100644 --- a/tests/phpunit/tests/rest-api/rest-tags-controller.php +++ b/tests/phpunit/tests/rest-api/rest-tags-controller.php @@ -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' ); diff --git a/tests/phpunit/tests/rest-api/rest-taxonomies-controller.php b/tests/phpunit/tests/rest-api/rest-taxonomies-controller.php index 635969cb38..3eea3be489 100644 --- a/tests/phpunit/tests/rest-api/rest-taxonomies-controller.php +++ b/tests/phpunit/tests/rest-api/rest-taxonomies-controller.php @@ -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' );