Opened 5 years ago
Last modified 16 months ago
#50260 new defect (bug)
Multisite - Getting actual user capabilities with get_role_caps() different with current_user_can()
Reported by: | Mahesh901122 | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | 5.4.1 |
Component: | Role/Capability | Keywords: | dev-feedback needs-docs |
Focuses: | multisite | Cc: |
Description
If I check below user capabilities for Administrator then I get both capabilities as false
.
current_user_can( 'install_plugins' ) current_user_can( 'activate_plugins' )
But, If I check the same capabilities by login to the Super Administrator then both return true
.
The administrator user role has no such capabilities but, If we check the current user capabilities with:
$current_user = wp_get_current_user(); print_r( $current_user->allcaps ); print_r( $current_user->get_role_caps() );
Then for the administrator user role, I get below a list of capabilities:
// Array // ( // [switch_themes] => 1 // [edit_themes] => 1 // [activate_plugins] => 1 // [edit_plugins] => 1 // [edit_users] => 1 // [edit_files] => 1 // [manage_options] => 1 // [moderate_comments] => 1 // [manage_categories] => 1 // [manage_links] => 1 // [upload_files] => 1 // [import] => 1 // [unfiltered_html] => 1 // [edit_posts] => 1 // [edit_others_posts] => 1 // [edit_published_posts] => 1 // [publish_posts] => 1 // [edit_pages] => 1 // [read] => 1 // [level_10] => 1 // [level_9] => 1 // [level_8] => 1 // [level_7] => 1 // [level_6] => 1 // [level_5] => 1 // [level_4] => 1 // [level_3] => 1 // [level_2] => 1 // [level_1] => 1 // [level_0] => 1 // [edit_others_pages] => 1 // [edit_published_pages] => 1 // [publish_pages] => 1 // [delete_pages] => 1 // [delete_others_pages] => 1 // [delete_published_pages] => 1 // [delete_posts] => 1 // [delete_others_posts] => 1 // [delete_published_posts] => 1 // [delete_private_posts] => 1 // [edit_private_posts] => 1 // [read_private_posts] => 1 // [delete_private_pages] => 1 // [edit_private_pages] => 1 // [read_private_pages] => 1 // [delete_users] => 1 // [create_users] => 1 // [unfiltered_upload] => 1 // [edit_dashboard] => 1 // [update_plugins] => 1 // [delete_plugins] => 1 // [install_plugins] => 1 // [update_themes] => 1 // [install_themes] => 1 // [update_core] => 1 // [list_users] => 1 // [remove_users] => 1 // [promote_users] => 1 // [edit_theme_options] => 1 // [delete_themes] => 1 // [export] => 1 // [restrict_content] => 1 // [list_roles] => 1 // [administrator] => 1 // )
Here we can see the Administrator user has the capability:
// [install_plugins] => 1 // [activate_plugins] => 1
But, When we check them with current_user_can()
then both return false.
After debugging in dept I found that the do_not_allow
is set for the Non-super admin users for install_plugins capability.
case 'update_plugins': case 'delete_plugins': case 'install_plugins': case 'upload_plugins': case 'update_themes': case 'delete_themes': case 'install_themes': case 'upload_themes': case 'update_core': ... } elseif ( is_multisite() && ! is_super_admin( $user_id ) ) { $caps[] = 'do_not_allow'; .... break;
Same for the activate_plugins the capabilities are set as ["activate_plugins","manage_network_plugins"]
case 'activate_plugins': case 'deactivate_plugins': case 'activate_plugin': case 'deactivate_plugin': $caps[] = 'activate_plugins'; if ( is_multisite() ) { // update_, install_, and delete_ are handled above with is_super_admin(). $menu_perms = get_site_option( 'menu_items', array() ); if ( empty( $menu_perms['plugins'] ) ) { $caps[] = 'manage_network_plugins'; } } break;
So, Ideally only those capabilities need to return by $current_user->get_role_caps()
.
Those capabilities need to exclude from the list which current user cant perform. E.g. do_not_allow
.
Change History (5)
#3
@
16 months ago
Hi. Sorry for bothering. Is it advised to workaround this problem with plugins or by other means for now (e.g. because existing code relays on the wrong behavior), or is it reasonable to hope for a fix in the future?
I am asking because this unexpected / undocumented behavior causes problems in other plugins, e.g.: https://github.com/elementor/elementor/issues/23302
With kind regards
Dominik
#4
@
16 months ago
- Keywords needs-docs added
The current behaviour is correct in my view, because it gives the ability to discern capabilities between declared and forced where there is a need to do so. If the two functions behave the same, what is the point of having both of them?
I do think a warning should be added to the docblock for get_role_caps
about the super admin discrepancies and others, but no need for code changes.
Regarding the Elementor issue, it looks like current_user_can
is the function being used, not get_role_caps
, so amending get_role_caps
would not have any impact on it anyway. Frankly, the Elementor issue is not even related to multisite at all and looks more related to kses.
In response to the question about working around core bugs, I have a personal view that I could share. On the other hand, I don't think it would be relevant to share, since the issue seems the responsibility of Elementor and not core, and I don't know how promptly bugs tend to get fixed with Elementor.
#5
@
16 months ago
Thank you for your reply. I misread the first post partially and assumed current_user_can would be the one being wrong, while it's get_role_caps as you and the first person said. Sorry. So I guess there's a valid reason to have non-super admins not have unfiltered_html on MultiSites by default (which makes sense if they can't be trusted at all, so they can't destroy the domain reputation e.g. with malicious script content).
I'm getting below capabilities as
false
with current_user_can():and
true
for below: