WordPress.org

Make WordPress Core

Opened 2 weeks ago

Last modified 2 weeks ago

#48764 new defect (bug)

RESTI API explicitly checks for publish_posts capability without post ID

Reported by: djzone Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: REST API Keywords: has-patch
Focuses: rest-api Cc:
PR Number:

Description

Recently we have developed a custom editorial workflow on the top of the wp-admin, and we had a feature that only enabled publish if the post_parent is a certain page.

So basically we had a user with author role, that only has publish_posts capability if the pages's post_parent is a certain page. We are checking this access with a filter on user_has_cap, and there if the $args['2'] is present we check the parent (or actually the whole ancestor chain) and if the parent is in the chain we grant the access.

This worked pretty well for us, in PHP and in Gutenberg as well up until a point, where we found out, that the REST API Posts Controller fails to publish the post and throws a rest_cannot_post error, because in the handle_status_param() function current_user_can filter explicitly checks for the publish_posts capability without including the page ID, therefore the capability won't be added to the $allcaps array in has_caps because the ID is not provided.

Of course we've built around that by parsing the REST API url, and at the end there's the page id, but it's just not elegant, and I beleive this is a bug in the Posts Controller.



Attachments (3)

class-wp-rest-posts-controller.php.patch (2.2 KB) - added by djzone 2 weeks ago.
48764.patch (1.9 KB) - added by dkarfa 2 weeks ago.
48764.1.patch (4.4 KB) - added by dkarfa 2 weeks ago.
Code refactoring

Download all attachments as: .zip

Change History (6)

This ticket was mentioned in Slack in #core by djzone. View the logs.


2 weeks ago

@dkarfa
2 weeks ago

@dkarfa
2 weeks ago

Code refactoring

#2 @SergeyBiryukov
2 weeks ago

Hi there, thanks for the patch!

This seems intentional, as the publish_posts (plural) capability does not require a post ID, and there are a lot of other places in core that don't pass an ID.

Only the publish_post (singular) meta capability requires an ID. By default, it falls back to publish_posts, or edit_others_posts if the associated post type is no longer available.

#3 @SergeyBiryukov
2 weeks ago

To summarize a bit, the publish_posts capability should be used for checking whether the user can publish posts in general, not a specific post. For the latter, publish_post should be used.

Related: comment:2:ticket:48415

Note: See TracTickets for help on using tickets.