From 7f544b912b48717c02b4f485e8eae84d6a5d227b Mon Sep 17 00:00:00 2001 From: Aaron Jorbin Date: Tue, 11 Dec 2018 04:12:56 +0000 Subject: [PATCH] REST API: Declare unfiltered_html capability in links. Because user capabilities can be modified at runtime, the REST API needs to expose them in some evaluated but declarative manner for clients to interpret. JSON Hyper Schema targetSchema provides an appropriate paradigm for doing so. Merges [43682] to trunk. Props timothyblynjacobs. Fixes #45014. git-svn-id: https://develop.svn.wordpress.org/trunk@43974 602fd350-edb4-49c9-b593-d223f7449a82 --- .../class-wp-rest-posts-controller.php | 20 +++++++++++ .../tests/rest-api/rest-posts-controller.php | 36 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php index 472115e121..bff977e40c 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php @@ -1781,6 +1781,10 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { $rels[] = 'https://api.w.org/action-publish'; } + if ( current_user_can( 'unfiltered_html' ) ) { + $rels[] = 'https://api.w.org/action-unfiltered-html'; + } + if ( 'post' === $post_type->name ) { if ( current_user_can( $post_type->cap->edit_others_posts ) && current_user_can( $post_type->cap->publish_posts ) ) { $rels[] = 'https://api.w.org/action-sticky'; @@ -2190,6 +2194,22 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { ); } + $links[] = array( + 'rel' => 'https://api.w.org/action-unfiltered-html', + 'title' => __( 'The current user can post unfiltered HTML markup and JavaScript.' ), + 'href' => $href, + 'targetSchema' => array( + 'type' => 'object', + 'properties' => array( + 'content' => array( + 'raw' => array( + 'type' => 'string', + ), + ), + ), + ), + ); + if ( 'post' === $this->post_type ) { $links[] = array( 'rel' => 'https://api.w.org/action-sticky', diff --git a/tests/phpunit/tests/rest-api/rest-posts-controller.php b/tests/phpunit/tests/rest-api/rest-posts-controller.php index 0de10c9651..ded82940ee 100644 --- a/tests/phpunit/tests/rest-api/rest-posts-controller.php +++ b/tests/phpunit/tests/rest-api/rest-posts-controller.php @@ -3992,6 +3992,42 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te $this->assertArrayHasKey( 'https://api.w.org/action-assign-tags', $links ); } + public function test_assign_unfiltered_html_action_superadmin() { + $post_id = self::factory()->post->create(); + wp_set_current_user( self::$superadmin_id ); + $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . $post_id ); + $request->set_param( 'context', 'edit' ); + $response = rest_do_request( $request ); + $links = $response->get_links(); + $this->assertArrayHasKey( 'https://api.w.org/action-unfiltered-html', $links ); + } + + public function test_assign_unfiltered_html_action_editor() { + $post_id = self::factory()->post->create(); + wp_set_current_user( self::$editor_id ); + $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . $post_id ); + $request->set_param( 'context', 'edit' ); + $response = rest_do_request( $request ); + $links = $response->get_links(); + // Editors can only unfiltered html on single site. + if ( is_multisite() ) { + $this->assertArrayNotHasKey( 'https://api.w.org/action-unfiltered-html', $links ); + } else { + $this->assertArrayHasKey( 'https://api.w.org/action-unfiltered-html', $links ); + } + } + + public function test_assign_unfiltered_html_action_author() { + $post_id = self::factory()->post->create(); + wp_set_current_user( self::$author_id ); + $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . $post_id ); + $request->set_param( 'context', 'edit' ); + $response = rest_do_request( $request ); + $links = $response->get_links(); + // Authors can't ever unfiltered html + $this->assertArrayNotHasKey( 'https://api.w.org/action-unfiltered-html', $links ); + } + public function tearDown() { _unregister_post_type( 'youseeeme' ); if ( isset( $this->attachment_id ) ) {