Skip to content

PHPCS: Allowlist custom capabilities instead of disabling the sniff#580

Closed
obenland wants to merge 4 commits intotrunkfrom
fix/phpcs-custom-capabilities
Closed

PHPCS: Allowlist custom capabilities instead of disabling the sniff#580
obenland wants to merge 4 commits intotrunkfrom
fix/phpcs-custom-capabilities

Conversation

@obenland
Copy link
Copy Markdown
Member

@obenland obenland commented Mar 31, 2026

Summary

  • Replace the blanket <severity>0</severity> override on WordPress.WP.Capabilities.Unknown with an explicit allowlist of all custom capabilities used across the codebase, grouped by plugin.
  • Fix four capability bugs surfaced by enabling the sniff:
    • Plugin Directory: ES Status tool used the role name plugin_admin instead of a capability — replaced with plugin_approve.
    • Plugin Directory: Comment row actions checked manage_comments, which is not a WordPress capability — replaced with moderate_comments.
    • Photo Directory: Moderation used the role name photos_moderator instead of a capability — replaced with edit_photos.
    • BuddyPress: Admin redirect checked four role names (contributor, author, editor, administrator) instead of capabilities — replaced with a single edit_posts check.

Test plan

  • Run composer install && vendor/bin/phpcs --sniffs=WordPress.WP.Capabilities . and confirm no warnings or errors
  • Verify the Plugin Directory ES Index Status tool is still accessible to plugin admins
  • Verify Plugin Directory internal note comment actions still work for reviewers
  • Verify Photo Directory moderation capabilities still work for photo moderators
  • Verify BuddyPress admin redirect still allows contributors and above into wp-admin

🤖 Generated with Claude Code

Replace the blanket severity override for WordPress.WP.Capabilities.Unknown
with an explicit allowlist of all custom capabilities used across the codebase.

This also fixes two capability bugs surfaced by enabling the sniff:

- Plugin Directory ES Status tool used the role name `plugin_admin` instead of
  a capability. Replace with `plugin_approve`, which is the distinguishing
  capability for the plugin admin role.
- Plugin Directory comment row actions checked `manage_comments`, which is not
  a WordPress capability. Replace with `moderate_comments`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 31, 2026 19:23
@github-actions
Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props obenland.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens PHPCS capability checking by replacing a blanket disable of the “unknown capability” sniff with an explicit allowlist of custom capabilities used in the WordPress.org environment, and fixes a couple of incorrect capability checks in the Plugin Directory admin UI.

Changes:

  • Replace the WordPress.WP.Capabilities.Unknown severity override with an explicit custom_capabilities allowlist in phpcs.xml.dist.
  • Fix Plugin Directory ES Status tool permissions by replacing the role name plugin_admin with the capability plugin_approve.
  • Fix internal-note comment row action gating by replacing the non-existent manage_comments capability with moderate_comments.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/tools/class-elasticsearch-status.php Updates menu and AJAX permission checks to use a real capability (plugin_approve).
wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-customizations.php Fixes internal-note row action permissions by using moderate_comments.
phpcs.xml.dist Introduces an explicit allowlist for custom capabilities under the WPCS capabilities sniffs.
Comments suppressed due to low confidence (1)

wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-customizations.php:826

  • The docblock above this logic says internal-note actions are limited to replying for plugin reviewers and that plugin admins can additionally trash/untrash/quickedit. However, the gate here is current_user_can( 'moderate_comments' ), and the plugin-directory plugin_reviewer role is granted moderate_comments (see class-capabilities.php), so reviewers will also see trash/untrash/quickedit. Please update the docblock to match the actual permission model (or change the capability check to the intended one).
	 *
	 * Actions for internal notes can be limited to replying for plugin reviewers.
	 * Plugin Admins can additionally trash, untrash, and quickedit a note.
	 *
	 * @param array       $actions An array of comment actions. Default actions include:
	 *                             'Approve', 'Unapprove', 'Edit', 'Reply', 'Spam',
	 *                             'Delete', and 'Trash'.
	 * @param \WP_Comment $comment The comment object.
	 * @return array Array of comment actions.
	 */
	public function custom_comment_row_actions( $actions, $comment ) {
		if ( 'internal-note' === $comment->comment_type && isset( $_REQUEST['mode'] ) && 'single' === $_REQUEST['mode'] ) {
			$allowed_actions = array( 'reply' => true );

			if ( current_user_can( 'moderate_comments' ) ) {
				$allowed_actions['trash']     = true;
				$allowed_actions['untrash']   = true;
				$allowed_actions['quickedit'] = true;
			}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Add singular theme caps (suspend_theme, reinstate_theme) and bbPress
  caps (bbp_forums_admin, edit_topic, edit_reply, read_topic) to the
  allowlist.
- Photo Directory used the role name photos_moderator instead of a
  capability. Replace with edit_photos.
- BuddyPress checked four role names instead of capabilities in the
  admin redirect. Replace with a single edit_posts check, which all
  contributors and above have.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@obenland
Copy link
Copy Markdown
Member Author

@dd32 Wanted to give you a chance to veto. It's a long allowlist, but it enables catching misuses like the other changes in this PR.

…p filter.

Calling user_can() for edit_photos inside a user_has_cap filter that
handles edit_photos would cause infinite recursion. Check the allcaps
array directly instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bazza bazza closed this Mar 31, 2026
@bazza bazza deleted the fix/phpcs-custom-capabilities branch March 31, 2026 20:12
Copilot AI added a commit to obenland/wordpress.org that referenced this pull request Mar 31, 2026
… and capability fixes

Agent-Logs-Url: https://github.com/obenland/wordpress.org/sessions/96f2f701-fe73-444a-829b-7bb3a541fbea

Co-authored-by: obenland <1398304+obenland@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants