Make WordPress Core

Opened 9 years ago

Closed 9 years ago

Last modified 22 months ago

#28374 closed defect (bug) (fixed)

Calling WP_User::add_cap does not flush capabilities

Reported by: rmccue's profile rmccue Owned by: rachelbaker's profile rachelbaker
Milestone: 4.2 Priority: normal
Severity: normal Version: 2.0
Component: Users Keywords: has-patch dev-feedback
Focuses: Cc:

Description

After calling $user->add_cap(), both $user->get_role_caps() and $user->update_user_level_from_caps() need to be called to update $user->allcaps. Ditto $user->remove_cap().

Both $user->add_role() and $user->remove_role() do this automatically.

Steps to reproduce:

$user = wp_get_current_user();
$user->add_cap('some_test_cap');
$user->has_cap('some_test_cap');

// -> false

Possibly related to #19747.

Attachments (1)

28374.patch (1.4 KB) - added by rachelbaker 9 years ago.
patch with unit test

Download all attachments as: .zip

Change History (11)

#1 @jdgrimes
9 years ago

  • Version set to 2.0

Related: #10201

I'm surprised that (what seems like) such a simple bug hasn't received any attention. However, given #10201, this could one day be moot.

@rachelbaker
9 years ago

patch with unit test

#2 @rachelbaker
9 years ago

  • Keywords has-patch dev-feedback added
  • Milestone changed from Awaiting Review to 4.2

#3 @rachelbaker
9 years ago

  • Owner set to rachelbaker
  • Status changed from new to accepted

Related #19747

#4 @wonderboymusic
9 years ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 31190:

In WP_User, ->get_role_caps() and ->update_user_level_from_caps() must be called inside ->add_cap() and ->remove_cap() after updating user meta. ->has_cap() checks are currently failing directly after calling ->add_cap().

Adds unit test.

Props rachelbaker.
Fixes #28374.

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


9 years ago

#6 @lgladdy
9 years ago

#19747 was marked as a duplicate.

#7 @rmccue
9 years ago

Found another instance of this one: adding a cap to a role that the current user has. Requires a page reload for it to kick in.

Not sure how to get around that; maybe allcaps needs to be deprecated and replaced with a __get accessor instead?

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


5 years ago

#9 @pikamander2
22 months ago

This appears to still be an issue, at least in 5.8.

I was facing the exact same problem as @lgladdy where my custom role wasn't receiving the capability that I added to it via add_cap().

His blog post (https://stormconsultancy.co.uk/blog/storm-news/custom-roles-in-wordpress-not-appearing-in-author-lists/) mentioned changing their role to something else and back as a workaround, but instead of trying that I just deleted the user and recreated them, at which point they had the new capability.

Is it possible that there was a regression here at some point?

I see that 5.9 is going to be fixing a semi-related longstanding issue (https://core.trac.wordpress.org/ticket/16841), so I'd be curious to know if that happens to fix it on its own.

Version 0, edited 22 months ago by pikamander2 (next)

#10 @pikamander2
22 months ago

I just tried @lgladdy's suggested workaround (changing their role to something else and back) on another affected account and that also fixed it, so it definitely seems like the original bug is still around.

For reference, I'm on WordPress 5.8.2.

Note: See TracTickets for help on using tickets.