Skip to content
Closed
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
9 changes: 9 additions & 0 deletions src/wp-admin/options-connectors.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,18 @@
// Set parent file for menu highlighting.
$parent_file = 'options-general.php';

/*
* Connector plugins are installed via `wp.updates.installPlugin()` when the
* filesystem method requires credentials which have not been stored.
*/
wp_enqueue_script( 'updates' );

require_once ABSPATH . 'wp-admin/admin-header.php';

// Render the Connectors page.
wp_options_connectors_wp_admin_render_page();

wp_print_request_filesystem_credentials_modal();
wp_print_admin_notice_templates();

require_once ABSPATH . 'wp-admin/admin-footer.php';
23 changes: 23 additions & 0 deletions src/wp-includes/connectors.php
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,7 @@ function _wp_connectors_pass_default_keys_to_ai_client(): void {
* Exposes connector settings to the connectors-wp-admin script module.
*
* @since 7.0.0
* @since 7.2.0 Added the `filesystemCredentialsRequired` flag.
* @access private
*
* @param array<string, mixed> $data Existing script module data.
Expand All @@ -911,6 +912,10 @@ function _wp_connectors_get_connector_script_module_data( array $data ): array {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}

if ( ! function_exists( 'request_filesystem_credentials' ) ) {
require_once ABSPATH . 'wp-admin/includes/file.php';
}

$connectors = array();
foreach ( wp_get_connectors() as $connector_id => $connector_data ) {
$auth = $connector_data['authentication'];
Expand Down Expand Up @@ -965,6 +970,24 @@ function _wp_connectors_get_connector_script_module_data( array $data ): array {
ksort( $connectors );
$data['connectors'] = $connectors;
$data['isFileModDisabled'] = ! wp_is_file_mod_allowed( 'install_plugins' );

/*
* The REST API plugins endpoint rejects install requests when the filesystem
* method requires credentials which have not been stored. In that case, the
* client installs via `wp.updates.installPlugin()` instead, which prompts for
* the credentials with the "Connection Information" modal.
*
* This mirrors WP_REST_Plugins_Controller::is_filesystem_available().
*/
$data['filesystemCredentialsRequired'] = false;
if ( ! $data['isFileModDisabled'] && 'direct' !== get_filesystem_method() ) {
ob_start();
$filesystem_credentials_are_stored = request_filesystem_credentials( self_admin_url() );
ob_end_clean();

$data['filesystemCredentialsRequired'] = ! $filesystem_credentials_are_stored;
}

return $data;
}
add_filter( 'script_module_data_options-connectors-wp-admin', '_wp_connectors_get_connector_script_module_data' );
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,65 @@ public function test_environment_variable_password_may_contain_colons(): void {
$this->assertSame( 'env', $auth['keySource'] );
$this->assertTrue( $auth['isConnected'] );
}

/**
* @ticket 65223
*/
public function test_filesystem_credentials_not_required_for_direct_filesystem_method(): void {
$this->set_filesystem_method( 'direct' );

$data = _wp_connectors_get_connector_script_module_data( array() );

$this->assertFalse( $data['filesystemCredentialsRequired'] );
}

/**
* @ticket 65223
*/
public function test_filesystem_credentials_required_when_credentials_are_not_stored(): void {
$this->set_filesystem_method( 'ftpext' );

$data = _wp_connectors_get_connector_script_module_data( array() );

$this->assertTrue( $data['filesystemCredentialsRequired'] );
}

/**
* @ticket 65223
*/
public function test_filesystem_credentials_not_required_when_credentials_are_stored(): void {
$this->set_filesystem_method( 'ftpext' );
add_filter( 'request_filesystem_credentials', '__return_true' );

$data = _wp_connectors_get_connector_script_module_data( array() );

$this->assertFalse( $data['filesystemCredentialsRequired'] );
}

/**
* @ticket 65223
*/
public function test_filesystem_credentials_not_required_when_file_modifications_are_disallowed(): void {
$this->set_filesystem_method( 'ftpext' );
add_filter( 'file_mod_allowed', '__return_false' );

$data = _wp_connectors_get_connector_script_module_data( array() );

$this->assertTrue( $data['isFileModDisabled'] );
$this->assertFalse( $data['filesystemCredentialsRequired'] );
}

/**
* Forces the filesystem method returned by get_filesystem_method().
*
* @param string $method Filesystem method.
*/
private function set_filesystem_method( string $method ): void {
add_filter(
'filesystem_method',
static function () use ( $method ) {
return $method;
}
);
}
}
Loading