Skip to content

fix: gate the network column renderers on the network capability - #467

Merged
josephfusco merged 2 commits into
WordPress:mainfrom
jigneshbhavani:fix/137-multisite-boundary-audit
Sep 4, 2026
Merged

josephfusco merged 2 commits into
WordPress:mainfrom
jigneshbhavani:fix/137-multisite-boundary-audit

Conversation

@jigneshbhavani

Copy link
Copy Markdown
Contributor

Fixes #137

Both Network Admin render callbacks returned network-wide presence to any caller, since only the column registration was gated. That holds while ours is the only thing that can put a column called presence_online on those screens, which is not a property this plugin controls. Called as a subscriber:

Uncapped call main this branch
wp_presence_render_network_users_column( '', 'presence_online', $editor ) localhost:8891/testpath0000025/ returns $output untouched
wp_presence_render_network_sites_column( 'presence_online', $blog_id ) avatar stack and count nothing

Notes:

  • Gated rather than pinned as unreachable with a test, which was the open question on the issue. Two lines, it matches every other entry point in those files, and unreachability stops being true the moment another plugin registers the name.
  • The cross-site denial the issue asks for already holds, so that test is a regression guard rather than a fix. Same for the site-scoped read.
  • test_users_column_shows_a_dash_for_an_offline_user called the renderer uncapped and passed because the user was offline. It becomes a network admin first, which is what it always meant to assert.
  • The wp_presence_network_capability docblock now says what a lowered value grants.

Testing:

  • npm run test:multisite: 466 tests, 986 assertions, 3 skipped.
  • npm test: 466 tests, 739 assertions, 131 skipped.
  • composer phpcs: clean.
  • Mutations: caps read from the main site inside the switch fails the denial test, the read pinned to $wpdb->base_prefix fails the isolation test, deleting either gate fails that column's test, and nothing else moves.
  • Browser: an mu-plugin filtering the capability to do_not_allow and registering its own presence_online column, which is the third-plugin case above. On main that viewer sees the avatar stacks and the site names; on this branch both columns are empty. A super admin sees no change either way.
Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5
Used for: Drafting the gate, the tests and this description. I ran the measurements, the mutation checks and the browser comparison, and reviewed what landed.

Both render callbacks returned network-wide data to any caller: the users
column named the sites a user is online on, the sites column drew the avatar
stack and count. Only the column registration was gated, which holds as long
as nothing else can put a column called presence_online on those screens.

Also states on the wp_presence_network_capability filter what a lowered value
grants, since a site-level capability there hands every holder presence for
sites they are not a member of.
The site boundary was true by construction while every read was scoped by
table prefix, so nothing asserted it. Covers the two halves the audit asks
for: an editor is denied the admin room on a site they are not a member of,
and a row written on one site is not readable from another.

test_users_column_shows_a_dash_for_an_offline_user() called the renderer with
no capability and passed because the user was offline rather than because
anything gated it. It becomes a network admin now, which is what it always
meant to assert.
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

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 bejignesh, joefusco.

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

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

🛝 WordPress Playgrounds

Built from 774fa21

5 users 40 users
Single site Launch single site, 5 users Launch single site, 40 users
Multisite Launch multisite, 5 users Launch multisite, 40 users

@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.96%. Comparing base (f8d578d) to head (774fa21).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main     #467      +/-   ##
============================================
+ Coverage     95.89%   95.96%   +0.07%     
  Complexity      255      255              
============================================
  Files            21       21              
  Lines          3047     3052       +5     
============================================
+ Hits           2922     2929       +7     
+ Misses          125      123       -2     
Flag Coverage Δ
multisite 95.96% <100.00%> (+0.07%) ⬆️
phpunit 71.10% <0.00%> (-0.06%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@josephfusco josephfusco left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, good add!

@josephfusco
josephfusco merged commit 75868a7 into WordPress:main Sep 4, 2026
20 checks passed
@josephfusco josephfusco added [Area] Multisite Network-wide presence, aggregation, and Network Admin surfaces Privacy Work relates to privacy of presence data labels Sep 27, 2026
@josephfusco josephfusco added this to the 0.4.0 milestone Sep 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Area] Multisite Network-wide presence, aggregation, and Network Admin surfaces Privacy Work relates to privacy of presence data

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Audit multisite behavior before core proposal

2 participants