Skip to content

Make Two-Factor provider settings network-wide on Multisite - #1024

Draft
masteradhoc wants to merge 2 commits into
masterfrom
network-provider-settings
Draft

masteradhoc wants to merge 2 commits into
masterfrom
network-provider-settings

Conversation

@masteradhoc

@masteradhoc masteradhoc commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator

What?

On Multisite, the "Enabled Providers" setting becomes network-wide and can only be changed by super admins, under Network Admin → Settings → Two-Factor. Each site's Settings → Two-Factor shows the network selection read-only. Single site installs are unchanged.

Fixes #894
Supersedes #915

Why?

A user's two-factor configuration is network-wide (user meta), and signing in through any site of a network gives a session that is valid across the network. The enabled-providers setting, however, was stored per site and could be changed by each site's administrators. On Multisite this made the providers that count for an account depend on the site it signs in through, and a per-site restriction didn't really restrict anything, since the user could sign in through another site.

This is how we want to solve #894, so this PR supersedes #915. #915 keeps the per-site settings in effect until a network selection is saved, and offers an optional "subsites may narrow the list" override; both keep the per-site dependency described above. Here the setting is network-only: there is no per-site override, and per-site values are ignored on Multisite. Requiring two-factor for roles (also suggested in #894) isn't part of this PR; that's tracked in #255.

Thanks to @faisalahammad for #915: the empty-selection guard, the validation of submitted provider keys and the read-only view for sites are adapted from it.

How?

  • One place decides the scope. Two_Factor_Core::get_enabled_providers_policy(), update_enabled_providers_policy() and policy_capability(): a network option (two_factor_enabled_providers in sitemeta) and manage_network_options on Multisite; the regular option and manage_options on single site, as before. two_factor_get_enabled_providers_option() stays as a thin wrapper for existing callers.
  • Network Admin → Settings → Two-Factor (two_factor_add_network_settings_page()), saved through edit.php?action=two_factor_settings by Two_Factor_Settings::save_network_settings(): capability and nonce checks; only registered providers are kept, including ones the current selection disables; an empty selection is refused, since it would lock every user with two-factor out of the whole network.
  • Sites keep Settings → Two-Factor for manage_options, but on Multisite it is read-only (Two_Factor_Settings::render_network_managed_page()), with a link to the network page for super admins. It never saves.
  • Upgrade: the main site's previously saved selection is copied to the network option once, flagged by the two_factor_enabled_providers_migrated network option. Selections saved on other sites don't carry over and no longer apply.
  • The settings screen's "list all providers" exception only applies in the network admin on Multisite.
  • Uninstall removes the setting in both scopes. The "Plugin Settings" action link points to the network page, also on Network Admin → Plugins.
  • Docs: readme (settings and Multisite FAQ), AGENTS.md, TESTS.md.

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5.5 Max
Used for: implementing the change, the tests and the docs from my specification; I reviewed the changes and made the design decisions.

Testing Instructions

Multisite (plugin network-activated)

  1. Network Admin → Settings → Two-Factor: untick a provider (e.g. Email) and save. "Settings saved." is shown, and the provider is no longer offered on any site (profile and login).
  2. Untick all providers and save: "At least one provider must be enabled. No changes were saved." is shown, and the previous selection is kept.
  3. As a site administrator who isn't a super admin, open Settings → Two-Factor on a site: the network selection is shown read-only, without a Save button. As a super admin, the page also links to the network settings.
  4. Upgrade path: on master, save one selection on the main site's Settings → Two-Factor and a different one on a subsite. Switch to this branch: the network page shows the main site's selection, and the subsite's selection has no effect anymore (its page and the providers offered when signing in through it match the network selection).
  5. Network Admin → Plugins: "Plugin Settings" links to the network page.

Single site (no multisite)
6. Settings → Two-Factor works as before.

Screenshots or screencast

Before After
View as Superadmin on a Subsite View as Admin on a Subsite
image image
View as Superadmin on a Main Site View as Admin on a Main Site
image not viewable

Changelog Entry

Added - Network-wide Two-Factor provider settings on Multisite, managed by super admins under Network Admin → Settings → Two-Factor. Sites show the selection read-only; per-site selections no longer apply, and the main site's saved selection is carried over.

Open WordPress Playground Preview

On Multisite, the enabled providers are now a network option managed by
super admins under Network Admin → Settings → Two-Factor, and they apply
to every site. Sites show the selection read-only. The main site's saved
selection is carried over once; values saved on other sites are ignored.
Single site installs are unchanged.
@masteradhoc masteradhoc self-assigned this Oct 17, 2026
@masteradhoc masteradhoc added this to the 0.18.0 milestone Oct 17, 2026
@github-actions

Copy link
Copy Markdown

✅ WordPress Plugin Check Report

✅ Status: Passed

📊 Report

All checks passed! No errors or warnings found.


🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check

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.

Add network-level provider settings for WordPress Multisite

1 participant