From 76e99cfa3acc84c9c72f44f2537b5ff2475da152 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Tue, 8 Nov 2016 07:00:11 -0800 Subject: [PATCH] Use `--prompt=` to prompt for specific associative args For instance: ``` wp core config --dbname=testing --dbuser=wp --prompt=dbpass < password.txt ``` This approach lets users avoid exposing secure data in bash history. --- features/core.feature | 20 ++++++++++++++++++++ php/WP_CLI/Dispatcher/Subcommand.php | 16 ++++++++++++++++ php/commands/core.php | 8 ++++++++ php/config-spec.php | 4 ++-- 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/features/core.feature b/features/core.feature index 1659b71849..de3d601d0e 100644 --- a/features/core.feature +++ b/features/core.feature @@ -66,6 +66,26 @@ Feature: Manage WordPress installation http://localhost:8001 """ + Scenario: Install WordPress by prompting for the admin email and password + Given an empty directory + And WP files + And wp-config.php + And a database + And a session file: + """ + wpcli + admin@example.com + """ + + When I run `wp core install --url=localhost:8001 --title=Test --admin_user=wpcli --prompt=admin_email,admin_password < session` + Then STDOUT should not be empty + + When I run `wp eval 'echo home_url();'` + Then STDOUT should be: + """ + http://localhost:8001 + """ + Scenario: Install WordPress with an https scheme Given an empty directory And WP files diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 6b832514a7..4d394ff25a 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -142,11 +142,27 @@ private function prompt_args( $args, $assoc_args ) { $spec = array_values( $spec ); + $prompt_args = WP_CLI::get_config( 'prompt' ); + if ( true !== $prompt_args ) { + $prompt_args = explode( ',', $prompt_args ); + } + // 'positional' arguments are positional (aka zero-indexed) // so $args needs to be reset before prompting for new arguments $args = array(); foreach( $spec as $key => $spec_arg ) { + // When prompting for specific arguments (e.g. --prompt=user_pass), + // ignore all arguments that don't match + if ( is_array( $prompt_args ) ) { + if ( 'assoc' !== $spec_arg['type'] ) { + continue; + } + if ( ! in_array( $spec_arg['name'], $prompt_args, true ) ) { + continue; + } + } + $current_prompt = ( $key + 1 ) . '/' . count( $spec ) . ' '; $default = ( $spec_arg['optional'] ) ? '' : false; diff --git a/php/commands/core.php b/php/commands/core.php index 063c4e3ac8..e5a5b665f7 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -336,6 +336,10 @@ private static function get_initial_locale() { * $ define( 'WP_DEBUG_LOG', true ); * $ PHP * Success: Generated 'wp-config.php' file. + * + * # Avoid disclosing password to bash history by reading from password.txt + * $ wp core config --dbname=testing --dbuser=wp --prompt=dbpass < password.txt + * Success: Generated 'wp-config.php' file. */ public function config( $_, $assoc_args ) { global $wp_version; @@ -469,8 +473,12 @@ public function is_installed( $_, $assoc_args ) { * * ## EXAMPLES * + * # Install WordPress in 5 seconds * $ wp core install --url=example.com --title=Example --admin_user=supervisor --admin_password=strongpassword --admin_email=info@example.com * Success: WordPress installed successfully. + * + * # Install WordPress without disclosing admin_password to bash history + * $ wp core install --url=example.com --title=Example --admin_user=supervisor --admin_email=info@example.com --prompt=admin_password < admin_password.txt */ public function install( $args, $assoc_args ) { if ( $this->_install( $assoc_args ) ) { diff --git a/php/config-spec.php b/php/config-spec.php index 11c6fffbd4..63725e725b 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -85,10 +85,10 @@ ), 'prompt' => array( - 'runtime' => '', + 'runtime' => '[=]', 'file' => false, 'default' => false, - 'desc' => 'Prompt the user to enter values for all command arguments.', + 'desc' => 'Prompt the user to enter values for all command arguments, or a subset specified as comma-separated values.', ), 'quiet' => array(