Skip to content

Commit 84f39c2

Browse files
authored
Merge pull request #287 from wp-cli/fix/disable-http-request-retry-by-default
Add `--insecure` flag to `plugin|theme install` & `plugin\theme update` commands
2 parents 4a018d5 + 062a77f commit 84f39c2

File tree

3 files changed

+61
-39
lines changed

3 files changed

+61
-39
lines changed

src/Plugin_Command.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,9 @@ protected function install_from_repo( $slug, $assoc_args ) {
593593
* [--dry-run]
594594
* : Preview which plugins would be updated.
595595
*
596+
* [--insecure]
597+
* : Retry downloads without certificate validation if TLS handshake fails. Note: This makes the request vulnerable to a MITM attack.
598+
*
596599
* ## EXAMPLES
597600
*
598601
* $ wp plugin update bbpress --version=dev
@@ -737,6 +740,9 @@ protected function filter_item_list( $items, $args ) {
737740
* [--activate-network]
738741
* : If set, the plugin will be network activated immediately after install
739742
*
743+
* [--insecure]
744+
* : Retry downloads without certificate validation if TLS handshake fails. Note: This makes the request vulnerable to a MITM attack.
745+
*
740746
* ## EXAMPLES
741747
*
742748
* # Install the latest version from wordpress.org and activate

src/Theme_Command.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,9 @@ protected function filter_item_list( $items, $args ) {
457457
* [--activate]
458458
* : If set, the theme will be activated immediately after install.
459459
*
460+
* [--insecure]
461+
* : Retry downloads without certificate validation if TLS handshake fails. Note: This makes the request vulnerable to a MITM attack.
462+
*
460463
* ## EXAMPLES
461464
*
462465
* # Install the latest version from wordpress.org and activate
@@ -596,6 +599,9 @@ public function get( $args, $assoc_args ) {
596599
* [--dry-run]
597600
* : Preview which themes would be updated.
598601
*
602+
* [--insecure]
603+
* : Retry downloads without certificate validation if TLS handshake fails. Note: This makes the request vulnerable to a MITM attack.
604+
*
599605
* ## EXAMPLES
600606
*
601607
* # Update multiple themes

src/WP_CLI/CommandWithUpgrade.php

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33
namespace WP_CLI;
44

55
use Composer\Semver\Comparator;
6+
use Exception;
67
use WP_CLI;
8+
use WP_CLI\Fetchers;
9+
use WP_CLI\Loggers;
710
use WP_CLI\Utils;
11+
use WP_Error;
812

913
abstract class CommandWithUpgrade extends \WP_CLI_Command {
1014

@@ -38,7 +42,7 @@ function () {
3842
999
3943
);
4044

41-
$this->fetcher = new WP_CLI\Fetchers\Plugin();
45+
$this->fetcher = new Fetchers\Plugin();
4246
}
4347

4448
abstract protected function get_upgrader_class( $force );
@@ -95,10 +99,10 @@ private function status_all() {
9599
$line .= ' ' . $details['version'];
96100
}
97101

98-
\WP_CLI::line( \WP_CLI::colorize( $line ) );
102+
WP_CLI::line( WP_CLI::colorize( $line ) );
99103
}
100104

101-
\WP_CLI::line();
105+
WP_CLI::line();
102106

103107
$this->show_legend( $items );
104108
}
@@ -135,7 +139,7 @@ private function show_legend( $items ) {
135139
$legend_line[] = '%yU = Update Available%n';
136140
}
137141

138-
\WP_CLI::line( 'Legend: ' . \WP_CLI::colorize( implode( ', ', $legend_line ) ) );
142+
WP_CLI::line( 'Legend: ' . WP_CLI::colorize( implode( ', ', $legend_line ) ) );
139143
}
140144

141145
public function install( $args, $assoc_args ) {
@@ -185,7 +189,7 @@ public function install( $args, $assoc_args ) {
185189
return $new_path;
186190
}
187191

188-
return new \WP_Error( 'wpcli_install_github', "Couldn't move Github-based project to appropriate directory." );
192+
return new WP_Error( 'wpcli_install_github', "Couldn't move Github-based project to appropriate directory." );
189193
};
190194
add_filter( 'upgrader_source_selection', $filter, 10, 3 );
191195
}
@@ -213,7 +217,7 @@ public function install( $args, $assoc_args ) {
213217
WP_CLI::warning( "Couldn't find '$slug' in the WordPress.org {$this->item_type} directory." );
214218
$errors++;
215219
} else {
216-
\WP_CLI::warning( "$slug: " . $result->get_error_message() );
220+
WP_CLI::warning( "$slug: " . $result->get_error_message() );
217221
if ( 'already_installed' !== $key ) {
218222
$errors++;
219223
}
@@ -237,12 +241,12 @@ public function install( $args, $assoc_args ) {
237241
if ( true === $allow_activation && count( $extension ) > 0 ) {
238242
$this->chained_command = true;
239243
if ( Utils\get_flag_value( $assoc_args, 'activate-network' ) ) {
240-
\WP_CLI::log( "Network-activating '$slug'..." );
244+
WP_CLI::log( "Network-activating '$slug'..." );
241245
$this->activate( array( $slug ), array( 'network' => true ) );
242246
}
243247

244248
if ( Utils\get_flag_value( $assoc_args, 'activate' ) ) {
245-
\WP_CLI::log( "Activating '$slug'..." );
249+
WP_CLI::log( "Activating '$slug'..." );
246250
$this->activate( array( $slug ) );
247251
}
248252
$this->chained_command = false;
@@ -306,20 +310,22 @@ protected static function alter_api_response( $response, $version ) {
306310
}
307311

308312
protected function get_upgrader( $assoc_args ) {
309-
$upgrader_class = $this->get_upgrader_class( Utils\get_flag_value( $assoc_args, 'force' ) );
310-
return Utils\get_upgrader( $upgrader_class );
313+
$force = (bool) Utils\get_flag_value( $assoc_args, 'force', false );
314+
$insecure = (bool) Utils\get_flag_value( $assoc_args, 'insecure', false );
315+
$upgrader_class = $this->get_upgrader_class( $force );
316+
return Utils\get_upgrader( $upgrader_class, $insecure );
311317
}
312318

313319
protected function update_many( $args, $assoc_args ) {
314320
call_user_func( $this->upgrade_refresh );
315321

316322
if ( ! empty( $assoc_args['format'] ) && in_array( $assoc_args['format'], [ 'json', 'csv' ], true ) ) {
317-
$logger = new \WP_CLI\Loggers\Quiet();
323+
$logger = new Loggers\Quiet();
318324
WP_CLI::set_logger( $logger );
319325
}
320326

321327
if ( ! Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) {
322-
\WP_CLI::error( "Please specify one or more {$this->item_type}s, or use --all." );
328+
WP_CLI::error( "Please specify one or more {$this->item_type}s, or use --all." );
323329
}
324330

325331
if ( Utils\get_flag_value( $assoc_args, 'minor' ) && Utils\get_flag_value( $assoc_args, 'patch' ) ) {
@@ -336,14 +342,18 @@ protected function update_many( $args, $assoc_args ) {
336342

337343
$items_to_update = wp_list_filter( $items, [ 'update' => true ] );
338344

345+
$minor = (bool) Utils\get_flag_value( $assoc_args, 'minor', false );
346+
$patch = (bool) Utils\get_flag_value( $assoc_args, 'patch', false );
347+
339348
if ( 'plugin' === $this->item_type
340-
&& ( Utils\get_flag_value( $assoc_args, 'minor' )
341-
|| Utils\get_flag_value( $assoc_args, 'patch' ) ) ) {
342-
$type = Utils\get_flag_value( $assoc_args, 'minor' ) ? 'minor' : 'patch';
343-
$items_to_update = self::get_minor_or_patch_updates( $items_to_update, $type );
349+
&& ( $minor || $patch ) ) {
350+
$type = $minor ? 'minor' : 'patch';
351+
$insecure = (bool) Utils\get_flag_value( $assoc_args, 'insecure', false );
352+
353+
$items_to_update = self::get_minor_or_patch_updates( $items_to_update, $type, $insecure );
344354
}
345355

346-
$exclude = WP_CLI\Utils\get_flag_value( $assoc_args, 'exclude' );
356+
$exclude = Utils\get_flag_value( $assoc_args, 'exclude' );
347357
if ( isset( $exclude ) ) {
348358
$exclude_items = explode( ',', trim( $assoc_args['exclude'], ',' ) );
349359
unset( $assoc_args['exclude'] );
@@ -369,29 +379,29 @@ protected function update_many( $args, $assoc_args ) {
369379

370380
if ( Utils\get_flag_value( $assoc_args, 'dry-run' ) ) {
371381
if ( empty( $items_to_update ) ) {
372-
\WP_CLI::log( "No {$this->item_type} updates available." );
382+
WP_CLI::log( "No {$this->item_type} updates available." );
373383

374384
if ( null !== $exclude ) {
375-
\WP_CLI::log( "Skipped updates for: $exclude" );
385+
WP_CLI::log( "Skipped updates for: $exclude" );
376386
}
377387

378388
return;
379389
}
380390

381391
if ( ! empty( $assoc_args['format'] ) && in_array( $assoc_args['format'], [ 'json', 'csv' ], true ) ) {
382-
WP_CLI\Utils\format_items( $assoc_args['format'], $items_to_update, [ 'name', 'status', 'version', 'update_version' ] );
392+
Utils\format_items( $assoc_args['format'], $items_to_update, [ 'name', 'status', 'version', 'update_version' ] );
383393
} elseif ( ! empty( $assoc_args['format'] ) && 'summary' === $assoc_args['format'] ) {
384-
\WP_CLI::log( "Available {$this->item_type} updates:" );
394+
WP_CLI::log( "Available {$this->item_type} updates:" );
385395
foreach ( $items_to_update as $item_to_update => $info ) {
386-
\WP_CLI::log( "{$info['title']} update from version {$info['version']} to version {$info['update_version']}" );
396+
WP_CLI::log( "{$info['title']} update from version {$info['version']} to version {$info['update_version']}" );
387397
}
388398
} else {
389-
\WP_CLI::log( "Available {$this->item_type} updates:" );
399+
WP_CLI::log( "Available {$this->item_type} updates:" );
390400
Utils\format_items( 'table', $items_to_update, [ 'name', 'status', 'version', 'update_version' ] );
391401
}
392402

393403
if ( null !== $exclude ) {
394-
\WP_CLI::log( "Skipped updates for: $exclude" );
404+
WP_CLI::log( "Skipped updates for: $exclude" );
395405
}
396406

397407
return;
@@ -401,7 +411,7 @@ protected function update_many( $args, $assoc_args ) {
401411

402412
// Only attempt to update if there is something to update.
403413
if ( ! empty( $items_to_update ) ) {
404-
$cache_manager = \WP_CLI::get_http_cache_manager();
414+
$cache_manager = WP_CLI::get_http_cache_manager();
405415
foreach ( $items_to_update as $item ) {
406416
$cache_manager->whitelist_package( $item['update_package'], $this->item_type, $item['name'], $item['update_version'] );
407417
}
@@ -429,7 +439,7 @@ protected function update_many( $args, $assoc_args ) {
429439
if ( ! empty( $assoc_args['format'] ) && 'summary' === $assoc_args['format'] ) {
430440
foreach ( $items_to_update as $item_to_update => $info ) {
431441
$message = null !== $result[ $info['update_id'] ] ? 'updated successfully' : 'did not update';
432-
\WP_CLI::log( "{$info['title']} {$message} from version {$info['version']} to version {$info['update_version']}" );
442+
WP_CLI::log( "{$info['title']} {$message} from version {$info['version']} to version {$info['update_version']}" );
433443
}
434444
} else {
435445
$status = array();
@@ -457,7 +467,7 @@ protected function update_many( $args, $assoc_args ) {
457467
$total_updated = Utils\get_flag_value( $assoc_args, 'all' ) ? $num_to_update : count( $args );
458468
Utils\report_batch_operation_results( $this->item_type, 'update', $total_updated, $num_updated, $errors );
459469
if ( null !== $exclude ) {
460-
\WP_CLI::log( "Skipped updates for: $exclude" );
470+
WP_CLI::log( "Skipped updates for: $exclude" );
461471
}
462472
}
463473

@@ -469,7 +479,7 @@ protected function _list( $_, $assoc_args ) {
469479
$all_items = $this->get_all_items();
470480

471481
if ( ! is_array( $all_items ) ) {
472-
\WP_CLI::error( "No {$this->item_type}s found." );
482+
WP_CLI::error( "No {$this->item_type}s found." );
473483
}
474484

475485
foreach ( $all_items as $key => &$item ) {
@@ -568,20 +578,20 @@ private function get_color( $status ) {
568578
/**
569579
* Get the minor or patch version for plugins with available updates
570580
*
571-
* @param array $items Plugins with updates.
572-
* @param string $type Either 'minor' or 'patch'
581+
* @param array $items Plugins with updates.
582+
* @param string $type Either 'minor' or 'patch'.
583+
* @param bool $insecure Whether to retry without certificate validation on TLS handshake failure.
573584
* @return array
574585
*/
575-
private function get_minor_or_patch_updates( $items, $type ) {
586+
private function get_minor_or_patch_updates( $items, $type, $insecure ) {
587+
$wp_org_api = new WpOrgApi( [ 'insecure' => $insecure ] );
576588
foreach ( $items as $i => $item ) {
577-
$wporg_url = sprintf( 'https://api.wordpress.org/plugins/info/1.0/%s.json', $item['name'] );
578-
$response = Utils\http_request( 'GET', $wporg_url );
579-
// Must not be hosted on wp.org
580-
if ( 20 !== absint( substr( $response->status_code, 0, 2 ) ) ) {
589+
try {
590+
$data = $wp_org_api->get_plugin_info( $item['name'] );
591+
} catch ( Exception $exception ) {
581592
unset( $items[ $i ] );
582593
continue;
583594
}
584-
$data = json_decode( $response->body, true );
585595
// No minor or patch versions to access.
586596
if ( empty( $data['versions'] ) ) {
587597
unset( $items[ $i ] );
@@ -658,13 +668,13 @@ protected function _search( $args, $assoc_args ) {
658668
}
659669

660670
if ( is_wp_error( $api ) ) {
661-
\WP_CLI::error( $api->get_error_message() . __( ' Try again' ) );
671+
WP_CLI::error( $api->get_error_message() . __( ' Try again' ) );
662672
}
663673

664674
$plural = $this->item_type . 's';
665675

666676
if ( ! isset( $api->$plural ) ) {
667-
\WP_CLI::error( __( 'API error. Try Again.' ) );
677+
WP_CLI::error( __( 'API error. Try Again.' ) );
668678
}
669679

670680
$items = $api->$plural;
@@ -678,7 +688,7 @@ protected function _search( $args, $assoc_args ) {
678688

679689
if ( 'table' === $format ) {
680690
$count = Utils\get_flag_value( $api->info, 'results', 'unknown' );
681-
\WP_CLI::success( sprintf( 'Showing %s of %s %s.', count( $items ), $count, $plural ) );
691+
WP_CLI::success( sprintf( 'Showing %s of %s %s.', count( $items ), $count, $plural ) );
682692
}
683693

684694
$formatter->display_items( $items );

0 commit comments

Comments
 (0)