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

Fix token decoding during wp-env startup. #220

Merged
merged 10 commits into from
Dec 30, 2024
4 changes: 4 additions & 0 deletions inc/Integrations/Airtable/AirtableIntegration.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

class AirtableIntegration {
public static function init(): void {
add_action( 'init', [ __CLASS__, 'register_blocks' ], 10, 0 );
}

public static function register_blocks(): void {
$data_source_configs = DataSourceCrud::get_configs_by_service( REMOTE_DATA_BLOCKS_AIRTABLE_SERVICE );

foreach ( $data_source_configs as $config ) {
Expand Down
4 changes: 4 additions & 0 deletions inc/Integrations/SalesforceB2C/SalesforceB2CIntegration.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

class SalesforceB2CIntegration {
public static function init(): void {
add_action( 'init', [ __CLASS__, 'register_blocks' ], 10, 0 );
}

public static function register_blocks(): void {
$data_source_configs = DataSourceCrud::get_configs_by_service( REMOTE_DATA_BLOCKS_SALESFORCE_B2C_SERVICE );

foreach ( $data_source_configs as $config ) {
Expand Down
4 changes: 4 additions & 0 deletions inc/Integrations/Shopify/ShopifyIntegration.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

class ShopifyIntegration {
public static function init(): void {
add_action( 'init', [ __CLASS__, 'register_blocks' ], 10, 0 );
}

public static function register_blocks(): void {
$data_source_configs = DataSourceCrud::get_configs_by_service( REMOTE_DATA_BLOCKS_SHOPIFY_SERVICE );

foreach ( $data_source_configs as $config ) {
Expand Down
24 changes: 21 additions & 3 deletions inc/PluginSettings/PluginSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use RemoteDataBlocks\WpdbStorage\DataSourceCrud;
use function wp_get_environment_type;
use function wp_is_development_mode;
use function add_settings_error;

defined( 'ABSPATH' ) || exit();

Expand Down Expand Up @@ -154,19 +155,36 @@ public static function encrypt_option( array $new_value, string|array|bool $old_
}
}

public static function decrypt_option( string $value ): array|null {
public static function decrypt_option( string $value ): array {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

decrypt_option() was also changed to return an empty array [] instead of null on error. Returning null causes a runtime type failure in the parent call to get_config(), which expects to return an array.

$decryptor = new \RemoteDataBlocks\WpdbStorage\DataEncryption();
$is_error = false;

try {
$decrypted = $decryptor->decrypt( $value );
return json_decode( $decrypted, true );

if ( false === $decrypted ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes the original stack trace in the issue description. $decryptor->decrypt() may return false, which causes the original error when json_decode() is called:

PHP Fatal error:  Uncaught TypeError: json_decode(): Argument #1 ($json) must be of type string, bool given in /var/www/html/wp-content/plugins/remote-data-blocks/inc/PluginSettings/PluginSettings.php:162
Stack trace:
#0 /var/www/html/wp-content/plugins/remote-data-blocks/inc/PluginSettings/PluginSettings.php(162): json_decode(false, true)

Copy link
Contributor Author

@alecgeatches alecgeatches Nov 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From testing, I think the reason this fails is that LOGGED_IN_KEY and LOGGED_IN_SALT have different values during wp-env initial setup and once the site is actually running. I tried adding error_log()s in the relevant code where we use these values and both values changed during initialization of wp-env after a version change and during normal website usage.

Because the values are initially encrypted with the site's real LOGGED_IN_ keys, this process only fails during wp-env initialization to a new WordPress version.

$is_error = true;
}
} catch ( \Exception $e ) {
$is_error = true;
}

if ( $is_error ) {
self::show_decryption_error();
return [];
} else {
return json_decode( $decrypted, true );
}
}

private static function show_decryption_error(): void {
// Check that we have add_settings_error() available. This can be unavailable during wp-env startup.
if ( is_admin() ) {
Copy link
Contributor Author

@alecgeatches alecgeatches Nov 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even after the fixes above, I was getting this stack trace for using the add_settings_error() function:

PHP Fatal error:  Uncaught Error: Call to undefined function RemoteDataBlocks\PluginSettings\add_settings_error() in /var/www/html/wp-content/plugins/remote-data-blocks/inc/PluginSettings/PluginSettings.php:176
Stack trace:
#0 /var/www/html/wp-content/plugins/remote-data-blocks/inc/PluginSettings/PluginSettings.php(168): RemoteDataBlocks\PluginSettings\PluginSettings::add_decrypt_error()
#1 /var/www/html/wp-includes/class-wp-hook.php(326): RemoteDataBlocks\PluginSettings\PluginSettings::decrypt_option('r7xSgvl3faIL5qW...')
#2 /var/www/html/wp-includes/plugin.php(205): WP_Hook->apply_filters('r7xSgvl3faIL5qW...', Array)
#3 /var/www/html/wp-includes/option.php(247): apply_filters('option_remote_d...', 'r7xSgvl3faIL5qW...', 'remote_data_blo...')
#4 /var/www/html/wp-content/plugins/remote-data-blocks/inc/WpdbStorage/DataSourceCrud.php(69): get_option('remote_data_blo...', Array)
#5 /var/www/html/wp-content/plugins/remote-data-blocks/inc/WpdbStorage/DataSourceCrud.php(75): RemoteDataBlocks\WpdbStorage\DataSourceCrud::get_config()
#6 /var/www/html/wp-content/plugins/remote-data-blocks/inc/Integrations/Airtable/AirtableIntegration.php(10): RemoteDataBlocks\WpdbStorage\DataSourceCrud::get_data_sources('airtable')
#7 /var/www/html/wp-content/plugins/remote-data-blocks/remote-data-blocks.php(47): RemoteDataBlocks\Integrations\Airtable\AirtableIntegration::init()
#8 /var/www/html/wp-settings.php(526): include_once('/var/www/html/w...')
#9 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1375): require('/var/www/html/w...')
#10 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1294): WP_CLI\Runner->load_wordpress()
#11 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LaunchRunner.php(28): WP_CLI\Runner->start()
#12 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/bootstrap.php(83): WP_CLI\Bootstrap\LaunchRunner->process(Object(WP_CLI\Bootstrap\BootstrapState))
#13 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/wp-cli.php(32): WP_CLI\bootstrap()
#14 phar:///usr/local/bin/wp/php/boot-phar.php(20): include('phar:///usr/loc...')
#15 /usr/local/bin/wp(4): include('phar:///usr/loc...')
#16 {main}
  thrown in /var/www/html/wp-content/plugins/remote-data-blocks/inc/PluginSettings/PluginSettings.php on line 176
Error: There has been a critical error on this website.Learn more about troubleshooting WordPress. There has been a critical error on this website.

The root cause is a bit harder to determine. I think WP_CLI is doing something strange with load order, as wp-settings.php is loaded first (which fires the init action) before admin functions are loaded into memory. This does look similar to WordPress' native load order, but I'm only seeing this error during initialization through WP_CLI. I found some similar-sounding load order concerns in WP_CLI issues like wp-cli/wp-cli#6010.

We can get around this error by ensuring is_admin() is true, which means that add_settings_error() will be defined and actually do something.

add_settings_error(
'remote_data_blocks_settings',
'decryption_error',
__( 'Error decrypting remote-data-blocks settings.', 'remote-data-blocks' )
);
return null;
}
}
}
Loading