Make WordPress Core

Opened 2 months ago

Closed 2 months ago

Last modified 2 months ago

#64153 closed defect (bug) (fixed)

REST API: 403 error occur when resolving or reopening note

Reported by: wildworks's profile wildworks Owned by: wildworks's profile wildworks
Milestone: 6.9 Priority: normal
Severity: normal Version:
Component: Editor Keywords: has-patch
Focuses: Cc:

Description (last modified by wildworks)

Originally reported on https://github.com/WordPress/gutenberg/issues/72690

When resolving or reopening a note, the comment meta _wp_note_status is updated. This itself works correctly, but a 403 error occurs with a message Sorry, you are not allowed to edit the _wp_note_status custom field..

My understanding is that because the meta key has an underscore prefix, it is treated as a protected meta key. Therefore, I believe that the auth_callback that was deleted here is still necessary.

Change History (42)

#1 @wildworks
2 months ago

  • Component changed from General to Editor

#2 @wildworks
2 months ago

  • Description modified (diff)

#3 follow-up: @wildworks
2 months ago

Strangely, this issue is reproducible in the release version of Beta 1, but it does not occur when building the wordpress-develop repository locally. The problem might have already been fixed in the trunk. I'd like to test it again once Beta2 is released.

#4 in reply to: ↑ 3 @desrosj
2 months ago

Replying to wildworks:

Strangely, this issue is reproducible in the release version of Beta 1, but it does not occur when building the wordpress-develop repository locally. The problem might have already been fixed in the trunk. I'd like to test it again once Beta2 is released.

I came to report this same problem and had the same findings as @wildworks.

This ticket was mentioned in Slack in #core-test by jeffr0. View the logs.


2 months ago

#6 @desrosj
2 months ago

#64162 was marked as a duplicate.

This ticket was mentioned in PR #10430 on WordPress/wordpress-develop by @wildworks.


2 months ago
#7

  • Keywords has-patch added

#8 @wildworks
2 months ago

but it does not occur when building the wordpress-develop repository locally

Sorry, this was because my local environment is a multisite setup, and I was logged in as a super admin user. The super admin user has all caps: https://github.com/WordPress/wordpress-develop/blob/781fb28d4773147edb17b0fd7eefa52671b5daa6/src/wp-includes/class-wp-user.php#L786-L792

My understanding is that because the meta key has an underscore prefix, it is treated as a protected meta key. Therefore, I believe that the auth_callback that was deleted here is still necessary.

In the end, I think this prediction was correct. The PR 10430 should solve the problem.

@Mamaduka commented on PR #10430:


2 months ago
#9

Do you have any ideas why unit tests didn't catch this failure? Why isn't test_create_empty_note_with_resolution_meta test failing on trunk?

It would be nice to have unit test coverage for _wp_note_status updated and permissions.

@Mamaduka commented on PR #10430:


2 months ago
#10

I was just doing more tests and realized that running only test_create_empty_note_with_resolution_meta properly fails on trunk, but it passes when running the whole test suite.

Unfortunately, I'm not sure what is causing this different behavior. @desrosj, @TimothyBJacobs, any ideas?

npm run test:php -- --filter test_create_empty_note_with_resolution_meta

@wildworks commented on PR #10430:


2 months ago
#11

I also noticed this and was in the process of investigating the cause. As a result of this, adding new tests and testing them becomes somewhat complicated 😅

@wildworks commented on PR #10430:


2 months ago
#12

If the problem cannot be resolved, I plan to split the test into two parts, without using a data provider.

@Mamaduka commented on PR #10430:


2 months ago
#13

If the problem cannot be resolved, I plan to split the test into two parts, without using a data provider.

The test is still passing for me, even after removing the data provider (at least that's the case in the Gutenberg repo). I can only fail it when running the command above.

@adamsilverstein commented on PR #10430:


2 months ago
#14

test_create_empty_note_with_resolution_meta properly fails on trunk, but it passes when running the whole test suite.

Odd, that sounds like some other test is causing a side effect. 👀

@adamsilverstein commented on PR #10430:


2 months ago
#15

When I run the test in isolation, the response error is: Sorry, you are not allowed to edit the _wp_note_status custom field

@wildworks commented on PR #10430:


2 months ago
#16

When I run the test in isolation, the response error is: Sorry, you are not allowed to edit the _wp_note_status custom field

Yes, for some reason, the comment metadata itself is either not registered or the authentication has failed.

@adamsilverstein commented on PR #10430:


2 months ago
#17

The underlying cause here was the meta was no longer registered after the first test ran - the test controller probably cleans up all meta registration between test runs. The solution was to add the meta registration to the set_up method, after this change the test fails in isolation and when run with other tests. I added the change to this PR - https://github.com/WordPress/wordpress-develop/pull/10430/commits/27bd29d5ff011ae3abe15fb8b84a16fa65d3ec4d assuming you are trying to fix this issue, but feel free to remove it if it belongs elsewhere.

@Mamaduka commented on PR #10430:


2 months ago
#18

the test controller probably cleans up all meta registration between test runs.

That's unexpected.

@adamsilverstein commented on PR #10430:


2 months ago
#19

the test controller probably cleans up all meta registration between test runs.

That's unexpected.

Looking into this further, the meta registrations are stored in the $wp_meta_keys global, so the registration must run before the test. Whats unclear to me so far is why the init hook isn't firing for every run, it could have to do with where we are calling add_action( 'init'. I'm looking further.

@adamsilverstein commented on PR #10430:


2 months ago
#20

the test controller probably cleans up all meta registration between test runs.

That's unexpected.

It happens as part of the top level tear down, see https://github.com/WordPress/wordpress-develop/blob/828a3fe5e225dd0c3206f5b7ec2f5b7b1d9afb4e/tests/phpunit/includes/abstract-testcase.php#L457

@adamsilverstein commented on PR #10430:


2 months ago
#21

it could have to do with where we are calling add_action( 'init'. I'm looking further.

This wasn't the issue, although I we should probably move that hook to src/wp-includes/default-filters.php like every other core default hook.

@adamsilverstein commented on PR #10430:


2 months ago
#22

it could have to do with where we are calling add_action( 'init'. I'm looking further.

This wasn't the issue, although I we should probably move that hook to src/wp-includes/default-filters.php like every other core default hook.

Actually this was entirely the issue. The test suite fires "rest_api_init" - https://github.com/WordPress/wordpress-develop/blob/828a3fe5e225dd0c3206f5b7ec2f5b7b1d9afb4e/tests/phpunit/includes/testcase-rest-controller.php#L13 so moving the hook there fixed the issue. After https://github.com/WordPress/wordpress-develop/pull/10430/commits/55011513596eebd858824299737eb1926fc97405 tests now pass locally and I see the meta values being set.

@adamsilverstein commented on PR #10430:


2 months ago
#23

Some tests were failing,I tried regenerating fixtures to see if that is related.

@adamsilverstein commented on PR #10430:


2 months ago
#24

Some tests were failing,I tried regenerating fixtures to see if that is related.

@adamsilverstein commented on PR #10430:


2 months ago
#25

The failures here were actually because REST API fixture generation was failing (not sure when this started, possibly related to commit 8c2ec298ad). The code in embed.php uses file_get_contents() to read the wp-embed.js file, which doesn't exist in the src directory where tests are run (it's a built asset). It became apparent here because this PR results in a fixture change.

Other oEmbed tests already handle this touch()ing the expected file in their set_up() method to create an empty placeholder file. The REST schema fixture generation test was missing this setup, causing it to fail.

Fixed in 05e386cbbff046adf03f8ddc2028738fde457e39, I reverted my other changes.

cc: @westonruter fun times

@adamsilverstein commented on PR #10430:


2 months ago
#26

Working in https://github.com/WordPress/wordpress-develop/pull/10434 to avoid too much noise here, I see one other failing test thaat is meta related, once I have those tests green, I'll merge the changes back here

@westonruter commented on PR #10430:


2 months ago
#27

The failures here were actually because REST API fixture generation was failing (not sure when this started, possibly related to commit 8c2ec29). The code in embed.php uses file_get_contents() to read the wp-embed.js file, which doesn't exist in the src directory where tests are run (it's a built asset). It became apparent here because this PR results in a fixture change.

Other oEmbed tests already handle this touch()ing the expected file in their set_up() method to create an empty placeholder file. The REST schema fixture generation test was missing this setup, causing it to fail.

Fixed in 05e386c, I reverted my other changes.

Indeed!

https://github.com/WordPress/wordpress-develop/blob/87cbbb1dfcf19fcfc128fc66603462a649d01502/tests/phpunit/tests/oembed/controller.php#L38-L39

https://github.com/WordPress/wordpress-develop/blob/87cbbb1dfcf19fcfc128fc66603462a649d01502/tests/phpunit/tests/oembed/getResponseData.php#L11-L12

https://github.com/WordPress/wordpress-develop/blob/87cbbb1dfcf19fcfc128fc66603462a649d01502/tests/phpunit/tests/oembed/wpOembed.php#L38-L39

@adamsilverstein commented on PR #10430:


2 months ago
#28

@adamsilverstein commented on PR #10430:


2 months ago
#29

@westonruter can you give this another review, see my last comment for an explanation of the additional changes.

@adamsilverstein commented on PR #10430:


2 months ago
#30

@t-hamano Apologies for taking over your ticket, I was trying to help with the failing tests and went down a bit of a rabbit hole. I am done making changes here!

@wildworks commented on PR #10430:


2 months ago
#31

@adamsilverstein Thank you so much for the detailed investigation!

My only concern is that with this hook, the timing for registering the comment meta might be a little late. There might be cases where someone wants to access this comment meta before the REST API is initialized.

What are your thoughts on directly executing the callback function within the set_up method? Also, note that +add_action is being moved to default-filters.php.

  • src/wp-includes/comment.php

    diff --git a/src/wp-includes/comment.php b/src/wp-includes/comment.php
    index acc3379bbe..aa841bfda9 100644
    a b function wp_create_initial_comment_meta() { 
    41354135               )
    41364136       );
    41374137}
    4138 add_action( 'rest_api_init', 'wp_create_initial_comment_meta' );
  • src/wp-includes/default-filters.php

    diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php
    index 5dc54c3686..f59d25b4fd 100644
    a b add_filter( 'update_term_metadata_cache', 'wp_check_term_meta_support_prefilter' 
    151151add_action( 'added_comment_meta', 'wp_cache_set_comments_last_changed' );
    152152add_action( 'updated_comment_meta', 'wp_cache_set_comments_last_changed' );
    153153add_action( 'deleted_comment_meta', 'wp_cache_set_comments_last_changed' );
     154add_action( 'init', 'wp_create_initial_comment_meta' );
    154155
    155156// Places to balance tags on input.
    156157foreach ( array( 'content_save_pre', 'excerpt_save_pre', 'comment_save_pre', 'pre_comment_content' ) as $filter ) {
  • tests/phpunit/tests/rest-api/rest-comments-controller.php

    diff --git a/tests/phpunit/tests/rest-api/rest-comments-controller.php b/tests/phpunit/tests/rest-api/rest-comments-controller.php
    index d1e1de9012..7a5109b25d 100644
    a b class WP_Test_REST_Comments_Controller extends WP_Test_REST_Controller_Testcase 
    170170       public function set_up() {
    171171               parent::set_up();
    172172               $this->endpoint = new WP_REST_Comments_Controller();
     173               wp_create_initial_comment_meta();
     174
    173175               if ( is_multisite() ) {
    174176                       update_site_option( 'site_admins', array( 'superadmin' ) );
    175177               }

@adamsilverstein commented on PR #10430:


2 months ago
#32

Yes that works and aligns with how meta is usually registered so maybe better.

@wildworks commented on PR #10430:


2 months ago
#33

I pushed the following changes.

  • 713c73cf5c05a176266745c2c19bf0125467b69f: In the setup method, I explicitly executed wp_create_initial_comment_meta. At the same time, I moved the hook to default-filters.php.
  • 1c75fb910d14ce9c2daea3f072bd2d5b7008f109: I reverted some of the changes because they didn't seem to affect the test results. Are these changes necessary in this pull request?

@Mamaduka commented on PR #10430:


2 months ago
#34

Thanks for debugging this, folks. I think this is good to commit.

Sidenote: The unregister_all_meta_keys makes testing meta values for REST controllers somewhat unpredictable. Do you know if this behavior is documented somewhere?

@wildworks commented on PR #10430:


2 months ago
#35

May I try to commit this pull request myself? I believe I have the SVN environment set up locally: https://wordpress.slack.com/archives/C18723MQ8/p1761227412356249

I created the following commit message, and I would appreciate it if you could review it.

Editor: Add `auth_callback` to `_wp_note_status` comment meta.

Adds an `auth_callback` to the `_wp_note_status` comment meta so that only users with the `edit_comment` capability can update this meta field via the REST API. 

This is necessary to ensure that users can properly resolve or reopen Notes.

Props wildworks, adamsilverstein, westonruter, mamaduka, desrosj.
Fixes #64153.

@Mamaduka commented on PR #10430:


2 months ago
#36

The commit message looks good to me 👍

@wildworks commented on PR #10430:


2 months ago
#37

Thank you! I'm going to start preparing for the commit now...

#38 @wildworks
2 months ago

  • Owner set to wildworks
  • Resolution set to fixed
  • Status changed from new to closed

In 61089:

Editor: Add auth_callback to _wp_note_status comment meta.

Adds an auth_callback to the _wp_note_status comment meta so that only users with the edit_comment capability can update this meta field via the REST API.

This is necessary to ensure that users can properly resolve or reopen Notes.

Props wildworks, adamsilverstein, westonruter, mamaduka, desrosj.
Fixes #64153.

@wildworks commented on PR #10430:


2 months ago
#39

The commit appears to have completed successfully 👍

@JeffPaul commented on PR #10430:


2 months ago
#40

Congrats @t-hamano!

@adamsilverstein commented on PR #10430:


2 months ago
#41

Nice work on your first commit to core @t-hamano! 🎉 🎉 🎉

1c75fb9: I reverted some of the changes because they didn't seem to affect the test results. Are these changes necessary in this pull request?

Thats fine; these fix some CI errors I noticed, but they aren't blockers - I can add in a future commit.

#42 @jorbin
2 months ago

In 61138:

Coding Standards: Fix alignment

In [61089], auth_callback was added which is causing phpcs to complain about the alignment with the other arguments in the array.

Follow-up to [61089] and [61036].

See #64153, #63168.

Note: See TracTickets for help on using tickets.