From 800cfa8a8287c23b12afb5dde89a9690d3911e7c Mon Sep 17 00:00:00 2001 From: Jake Spurlock Date: Mon, 22 Jun 2020 22:38:11 +0000 Subject: [PATCH] Privacy: Use relative paths for exported personal data. Ensures back-compat while moving to paths off of the /exports directory. Fixes: #44038. Props: allendav, mrTall, desrosj, garrett-eclipse, cameronamcintyre, nmenescardi, xkon, whyisjake, davidbaumwald. git-svn-id: https://develop.svn.wordpress.org/trunk@48127 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/privacy-tools.php | 50 ++++++++++++++++--- ...wpPrivacyProcessPersonalDataExportPage.php | 30 +++++++++-- .../wpPrivacySendPersonalDataExportEmail.php | 8 +-- 3 files changed, 73 insertions(+), 15 deletions(-) diff --git a/src/wp-admin/includes/privacy-tools.php b/src/wp-admin/includes/privacy-tools.php index a23a1732bb..9c320b1db2 100644 --- a/src/wp-admin/includes/privacy-tools.php +++ b/src/wp-admin/includes/privacy-tools.php @@ -468,17 +468,46 @@ function wp_privacy_generate_personal_data_export_file( $request_id ) { * filename, to avoid breaking any URLs that may have been previously sent * via email. */ - $error = false; + $error = false; + + // This postmeta is used from version 5.4. + $archive_filename = get_post_meta( $request_id, '_export_file_name', true ); + + // These are used for backwards compatibility. $archive_url = get_post_meta( $request_id, '_export_file_url', true ); $archive_pathname = get_post_meta( $request_id, '_export_file_path', true ); - if ( empty( $archive_pathname ) || empty( $archive_url ) ) { - $archive_filename = $file_basename . '.zip'; + // If archive_filename exists, make sure to remove deprecated postmeta. + if ( ! empty( $archive_filename ) ) { $archive_pathname = $exports_dir . $archive_filename; $archive_url = $exports_url . $archive_filename; - update_post_meta( $request_id, '_export_file_url', $archive_url ); - update_post_meta( $request_id, '_export_file_path', wp_normalize_path( $archive_pathname ) ); + // Remove the deprecated postmeta. + delete_post_meta( $request_id, '_export_file_url' ); + delete_post_meta( $request_id, '_export_file_path' ); + } elseif ( ! empty( $archive_pathname ) ) { + // Check if archive_pathname exists. If not, create the new postmeta and remove the deprecated. + $archive_filename = basename( $archive_pathname ); + $archive_url = $exports_url . $archive_filename; + + // Add the new postmeta that is used since version 5.4. + update_post_meta( $request_id, '_export_file_name', wp_normalize_path( $archive_filename ) ); + + // Remove the deprecated postmeta. + delete_post_meta( $request_id, '_export_file_url' ); + delete_post_meta( $request_id, '_export_file_path' ); + } else { + // If there's no archive_filename or archive_pathname create a new one. + $archive_filename = $file_basename . '.zip'; + $archive_url = $exports_url . $archive_filename; + $archive_pathname = $exports_dir . $archive_filename; + + // Add the new postmeta that is used since version 5.4. + update_post_meta( $request_id, '_export_file_name', wp_normalize_path( $archive_filename ) ); + + // Remove the deprecated postmeta. + delete_post_meta( $request_id, '_export_file_url' ); + delete_post_meta( $request_id, '_export_file_path' ); } if ( ! empty( $archive_pathname ) && file_exists( $archive_pathname ) ) { @@ -539,6 +568,10 @@ function wp_privacy_send_personal_data_export_email( $request_id ) { // Get the request. $request = wp_get_user_request( $request_id ); + // Get the export file URL. + $exports_url = wp_privacy_exports_url(); + $export_file_name = get_post_meta( $request_id, '_export_file_name', true ); + if ( ! $request || 'export_personal_data' !== $request->action_name ) { return new WP_Error( 'invalid_request', __( 'Invalid request ID when sending personal data export email.' ) ); } @@ -556,7 +589,7 @@ function wp_privacy_send_personal_data_export_email( $request_id ) { $expiration = apply_filters( 'wp_privacy_export_expiration', 3 * DAY_IN_SECONDS ); $expiration_date = date_i18n( get_option( 'date_format' ), time() + $expiration ); - $export_file_url = get_post_meta( $request_id, '_export_file_url', true ); + $export_file_url = $exports_url . $export_file_name; $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); $site_url = home_url(); @@ -820,7 +853,10 @@ function wp_privacy_process_personal_data_export_page( $response, $exporter_inde _wp_privacy_completed_request( $request_id ); } else { // Modify the response to include the URL of the export file so the browser can fetch it. - $export_file_url = get_post_meta( $request_id, '_export_file_url', true ); + $exports_url = wp_privacy_exports_url(); + $export_file_name = get_post_meta( $request_id, '_export_file_name', true ); + $export_file_url = $exports_url . $export_file_name; + if ( ! empty( $export_file_url ) ) { $response['url'] = $export_file_url; } diff --git a/tests/phpunit/tests/privacy/wpPrivacyProcessPersonalDataExportPage.php b/tests/phpunit/tests/privacy/wpPrivacyProcessPersonalDataExportPage.php index 736f0ad7f4..ab5c633b60 100644 --- a/tests/phpunit/tests/privacy/wpPrivacyProcessPersonalDataExportPage.php +++ b/tests/phpunit/tests/privacy/wpPrivacyProcessPersonalDataExportPage.php @@ -44,9 +44,27 @@ class Tests_Privacy_WpPrivacyProcessPersonalDataExportPage extends WP_UnitTestCa protected static $response_last_page; /** - * Export File Url. + * Export Url. * - * @since 5.2.0 + * @since 5.5.0 + * + * @var string $export_url + */ + protected static $export_url; + + /** + * Export File Name. + * + * @since 5.5.0 + * + * @var string $export_file_name + */ + protected static $export_file_name; + + /** + * Export File URL. + * + * @since 5.5.0 * * @var string $export_file_url */ @@ -131,7 +149,9 @@ class Tests_Privacy_WpPrivacyProcessPersonalDataExportPage extends WP_UnitTestCa */ public static function wpSetUpBeforeClass( $factory ) { self::$requester_email = 'requester@example.com'; - self::$export_file_url = wp_privacy_exports_url() . 'wp-personal-data-file-Wv0RfMnGIkl4CFEDEEkSeIdfLmaUrLsl.zip'; + self::$export_url = wp_privacy_exports_url(); + self::$export_file_name = 'wp-personal-data-file-Wv0RfMnGIkl4CFEDEEkSeIdfLmaUrLsl.zip'; + self::$export_file_url = self::$export_url . self::$export_file_name; self::$request_id = wp_create_user_request( self::$requester_email, 'export_personal_data' ); self::$page_index_first = 1; self::$page_index_last = 2; @@ -502,7 +522,7 @@ class Tests_Privacy_WpPrivacyProcessPersonalDataExportPage extends WP_UnitTestCa * @ticket 44233 */ public function test_return_response_with_export_file_url_when_not_sent_as_email_for_last_exporter_on_last_page() { - update_post_meta( self::$request_id, '_export_file_url', self::$export_file_url ); + update_post_meta( self::$request_id, '_export_file_name', self::$export_file_name ); // Process data, given the last exporter, on the last page and not send as email. $actual_response = wp_privacy_process_personal_data_export_page( @@ -528,7 +548,7 @@ class Tests_Privacy_WpPrivacyProcessPersonalDataExportPage extends WP_UnitTestCa * @ticket 44233 */ public function test_return_response_without_export_file_url_when_sent_as_email_for_last_exporter_on_last_page() { - update_post_meta( self::$request_id, '_export_file_url', self::$export_file_url ); + update_post_meta( self::$request_id, '_export_file_name', self::$export_file_name ); // Process data, given the last exporter, on the last page and send as email. $actual_response = wp_privacy_process_personal_data_export_page( diff --git a/tests/phpunit/tests/privacy/wpPrivacySendPersonalDataExportEmail.php b/tests/phpunit/tests/privacy/wpPrivacySendPersonalDataExportEmail.php index 54860b11e9..85de3c1ff4 100644 --- a/tests/phpunit/tests/privacy/wpPrivacySendPersonalDataExportEmail.php +++ b/tests/phpunit/tests/privacy/wpPrivacySendPersonalDataExportEmail.php @@ -104,8 +104,10 @@ class Tests_Privacy_WpPrivacySendPersonalDataExportEmail extends WP_UnitTestCase * The function should send an export link to the requester when the user request is confirmed. */ public function test_function_should_send_export_link_to_requester() { - $archive_url = wp_privacy_exports_url() . 'wp-personal-data-file-Wv0RfMnGIkl4CFEDEEkSeIdfLmaUrLsl.zip'; - update_post_meta( self::$request_id, '_export_file_url', $archive_url ); + $archive_url = wp_privacy_exports_url(); + $archive_file_name = 'wp-personal-data-file-Wv0RfMnGIkl4CFEDEEkSeIdfLmaUrLsl.zip'; + $archive_file_url = $archive_url . $archive_file_name; + update_post_meta( self::$request_id, '_export_file_name', $archive_file_name ); $email_sent = wp_privacy_send_personal_data_export_email( self::$request_id ); $mailer = tests_retrieve_phpmailer_instance(); @@ -113,7 +115,7 @@ class Tests_Privacy_WpPrivacySendPersonalDataExportEmail extends WP_UnitTestCase $this->assertSame( 'request-confirmed', get_post_status( self::$request_id ) ); $this->assertSame( self::$requester_email, $mailer->get_recipient( 'to' )->address ); $this->assertContains( 'Personal Data Export', $mailer->get_sent()->subject ); - $this->assertContains( $archive_url, $mailer->get_sent()->body ); + $this->assertContains( $archive_file_url, $mailer->get_sent()->body ); $this->assertContains( 'please download it', $mailer->get_sent()->body ); $this->assertTrue( $email_sent ); }