Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable WebAuthn plugin in wp-admin #153

Merged
merged 10 commits into from
May 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .wp-env.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"plugins": [
".",
"https://downloads.wordpress.org/plugin/gutenberg.latest-stable.zip",
"https://downloads.wordpress.org/plugin/bbpress.latest-stable.zip",
"WordPress/two-factor"
"WordPress/two-factor",
"https://downloads.wordpress.org/plugin/two-factor-provider-webauthn.latest-stable.zip",
"."
],
"mappings": {
"wp-content/themes/wporg-support": "WordPress/wordpress.org/wordpress.org/public_html/wp-content/themes/pub/wporg-support/",
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ WordPress.org-specific customizations for the Two Factor plugin

## Setup

1. Set up a local WP site.
1. Set up a local WP Multisite.
1. Add this code to your `wp-config.php`:
```php
define( 'WP_ENVIRONMENT_TYPE', 'local' );
Expand Down Expand Up @@ -44,14 +44,14 @@ WordPress.org-specific customizations for the Two Factor plugin
add_action( 'init', __NAMESPACE__ . '\add_rewrite_rules' );
```
1. Install, build, and activate the `wporg-support` theme.
1. Install `bbPress` and `Gutenberg`. You might need to clone & build `trunk` branch of `Gutenberg` if we happen to be using any new features.
1. Install `two-factor-provider-webauthn`, `bbPress` and `Gutenberg`. You might need to clone & build `trunk` branch of `Gutenberg` if we happen to be using any new features.
1. `git clone` https://github.com/WordPress/two-factor/ into `wp-content/plugins` and follow their setup instructions.
1. `git clone` this repo into `wp-content/plugins`
1. `cd wporg-two-factor && composer install`
1. `yarn && yarn workspaces run build`
1. Setup environment tools `yarn setup:tools`
1. Start the environment: `yarn wp-env start`
1. Activate all four plugins.
1. Network-activate all of the plugins.
1. If you want to make JS changes, then `yarn workspaces run start`
1. Open `wp-admin/options-general.php?page=bbpress` and uncheck `Prefix all forum content with the Forum Root slug (Recommended)`, then save.
1. Visit https://example.org/users/{username}/edit/account/ to view the custom settings UI. If you get a `404` error, visit `wp-admin/options-permalinks.php` and then try again.
Expand Down
4 changes: 4 additions & 0 deletions settings/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ function register_block() {
* @codeCoverageIgnore
*/
function replace_core_ui_with_custom() : void {
/*
@todo Temporarily commented so that WebAuthn can be managed via wp-admin. Restore this when our custom WebAuthn UI is ready.
See https://github.com/WordPress/wporg-two-factor/issues/114, https://github.com/WordPress/wporg-two-factor/issues/87.
remove_action( 'show_user_profile', array( 'Two_Factor_Core', 'user_two_factor_options' ) );
remove_action( 'edit_user_profile', array( 'Two_Factor_Core', 'user_two_factor_options' ) );
remove_action( 'personal_options_update', array( 'Two_Factor_Core', 'user_two_factor_options_update' ) );
remove_action( 'edit_user_profile_update', array( 'Two_Factor_Core', 'user_two_factor_options_update' ) );
*/

add_action( 'bbp_user_edit_account', __NAMESPACE__ . '\render_custom_ui' );

Expand Down
1 change: 1 addition & 0 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ function _manually_load_plugin() {

require_once dirname( __DIR__, 3 ) . '/mu-plugins/pub/mu-plugins/loader.php';
require dirname( __DIR__, 2 ) . '/two-factor/two-factor.php';
require dirname( __DIR__, 2 ) . '/two-factor-provider-webauthn/index.php';
require dirname( __DIR__ ) . '/wporg-two-factor.php';
}
tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
Expand Down
4 changes: 1 addition & 3 deletions tests/test-wporg-two-factor.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,9 @@ public function tear_down() : void {
*/
public function test_two_factor_providers() : void {
$actual = Two_Factor_Core::get_providers();

$this->assertArrayHasKey( 'Two_Factor_Totp', $actual );
$this->assertArrayHasKey( 'Two_Factor_Backup_Codes', $actual );
// @todo enable after https://github.com/WordPress/two-factor/issues/427 merges
//$this->assertArrayHasKey( 'Two_Factor_WebAuthn', $actual );
$this->assertArrayHasKey( 'TwoFactor_Provider_WebAuthn', $actual );

$this->assertArrayNotHasKey( 'Two_Factor_Email', $actual );
$this->assertArrayNotHasKey( 'Two_Factor_Dummy', $actual );
Expand Down
35 changes: 31 additions & 4 deletions wporg-two-factor.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace WordPressdotorg\Two_Factor;
use Two_Factor_Core;
use WildWolf\WordPress\TwoFactorWebAuthn\Plugin as WebAuthn_Plugin;
use WP_User, WP_Error;

defined( 'WPINC' ) || die();
Expand All @@ -28,21 +29,31 @@ function is_2fa_beta_tester() : bool {

require_once __DIR__ . '/settings/settings.php';

/*
* Make sure the WebAuthn plugin loads early, because all of our functions that call
* `Two_Factor_Core::is_user_using_two_factor()` etc assume that all providers are loaded. If WebAuthn is loaded
* too late, then `remove_capabilities_until_2fa_enabled()` would cause `get_enable_2fa_notice()` to be shown on
* the front end if WebAuthn is enabled and TOTP isn't.
*/
$webauthn = WebAuthn_Plugin::instance();
$webauthn->init();
iandunn marked this conversation as resolved.
Show resolved Hide resolved
$webauthn->maybe_update_schema(); // This needs to run before plugins_loaded, as jetpack and wporg-two-factor do things way too early to the $current_user.

add_filter( 'two_factor_providers', __NAMESPACE__ . '\two_factor_providers', 99 ); // Must run _after_ all other plugins.
add_filter( 'two_factor_primary_provider_for_user', __NAMESPACE__ . '\set_primary_provider_for_user', 10, 2 );
add_filter( 'two_factor_totp_issuer', __NAMESPACE__ . '\set_totp_issuer' );
add_action( 'set_current_user', __NAMESPACE__ . '\remove_super_admins_until_2fa_enabled', 1 ); // Must run _before_ all other plugins.
add_action( 'login_redirect', __NAMESPACE__ . '\redirect_to_2fa_settings', 105, 3 ); // After `wporg_remember_where_user_came_from_redirect()`, before `WP_WPorg_SSO::redirect_to_policy_update()`.
add_action( 'user_has_cap', __NAMESPACE__ . '\remove_capabilities_until_2fa_enabled', 99, 4 ); // Must run _after_ all other plugins.

add_action( 'current_screen', __NAMESPACE__ . '\block_webauthn_settings_page' );

/**
* Determine which providers should be available to users.
*/
function two_factor_providers( array $providers ) : array {
// Match the name => file path format of input var, but the path isn't needed.
$desired_providers = array(
'Two_Factor_WebAuthn' => '',
'TwoFactor_Provider_WebAuthn' => '',
'Two_Factor_Totp' => '',
'Two_Factor_Backup_Codes' => '',
);
Expand All @@ -57,8 +68,8 @@ function set_primary_provider_for_user( string $provider, int $user_id ) : strin
$user = get_user_by( 'id', $user_id );
$available_providers = Two_Factor_Core::get_available_providers_for_user( $user );

if ( isset( $available_providers['Two_Factor_WebAuthn'] ) ) {
$provider = 'Two_Factor_WebAuthn';
if ( isset( $available_providers['TwoFactor_Provider_WebAuthn'] ) ) {
$provider = 'TwoFactor_Provider_WebAuthn';
} elseif ( isset( $available_providers['Two_Factor_Totp'] ) ) {
$provider = 'Two_Factor_Totp';
} elseif ( 'Two_Factor_Backup_Codes' === $provider && 1 === count( $available_providers ) ) {
Expand Down Expand Up @@ -226,6 +237,22 @@ function get_enable_2fa_notice( string $existing_notices = '' ) : string {
return $two_factor_notice . $existing_notices;
}

/*
* Remove the 2FA settings page from the admin menu.
*
* We don't want site admins making changes, etc.
*/
function block_webauthn_settings_page() {
$screen = get_current_screen();

// Prevent direct access.
if ( $screen->id === 'settings_page_2fa-webauthn' ) {
wp_die( 'Access Denied.' );
}

remove_submenu_page( 'options-general.php', '2fa-webauthn' );
}

/**
* Get the URL of the Edit Account screen.
*
Expand Down