From 16bd4bede2440125cde243ad0e0ad4bcb2aadfb2 Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Tue, 1 May 2018 13:58:02 +0000 Subject: [PATCH] Privacy: add user information to the personal data export file. Props TZ-Media, desrosj. See #43547. git-svn-id: https://develop.svn.wordpress.org/trunk@43055 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/default-filters.php | 1 + src/wp-includes/user.php | 99 +++++++++++++++++++++++++++++ tests/phpunit/tests/user.php | 38 +++++++++++ 3 files changed, 138 insertions(+) diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index 797353b961..4ab1114b4f 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -352,6 +352,7 @@ add_action( 'user_request_action_confirmed', '_wp_privacy_account_request_confir add_filter( 'user_request_action_confirmed_message', '_wp_privacy_account_request_confirmed_message', 10, 2 ); add_filter( 'wp_privacy_personal_data_exporters', 'wp_register_comment_personal_data_exporter' ); add_filter( 'wp_privacy_personal_data_exporters', 'wp_register_media_personal_data_exporter' ); +add_filter( 'wp_privacy_personal_data_exporters', 'wp_register_user_personal_data_exporter' ); add_filter( 'wp_privacy_personal_data_erasers', 'wp_register_comment_personal_data_eraser' ); add_action( 'init', 'wp_schedule_delete_old_privacy_export_files' ); add_action( 'wp_privacy_delete_old_export_files', 'wp_privacy_delete_old_export_files' ); diff --git a/src/wp-includes/user.php b/src/wp-includes/user.php index ba2391bcf6..621544e378 100644 --- a/src/wp-includes/user.php +++ b/src/wp-includes/user.php @@ -2825,6 +2825,105 @@ function _wp_privacy_action_request_types() { ); } +/** + * Registers the personal data exporter for users. + * + * @since 4.9.6 + * + * @param array $exporters An array of personal data exporters. + * @return array An array of personal data exporters. + */ +function wp_register_user_personal_data_exporter( $exporters ) { + $exporters[] = array( + 'exporter_friendly_name' => __( 'WordPress User' ), + 'callback' => 'wp_user_personal_data_exporter', + ); + + return $exporters; +} + +/** + * Finds and exports personal data associated with an email address from the user and user_meta table. + * + * @since 4.9.6 + * + * @param string $email_address The users email address. + * @return array An array of personal data. + */ +function wp_user_personal_data_exporter( $email_address ) { + $email_address = trim( $email_address ); + + $data_to_export = array(); + + $user = get_user_by( 'email', $email_address ); + + if ( ! $user ) { + return array( + 'data' => array(), + 'done' => true, + ); + } + + $user_meta = get_user_meta( $user->ID ); + + $user_prop_to_export = array( + 'ID' => __( 'User ID' ), + 'user_login' => __( 'User Login Name' ), + 'user_nicename' => __( 'User Nice Name' ), + 'user_email' => __( 'User Email' ), + 'user_url' => __( 'User URL' ), + 'user_registered' => __( 'User Registration Date' ), + 'display_name' => __( 'User Display Name' ), + 'nickname' => __( 'User Nickname' ), + 'first_name' => __( 'User First Name' ), + 'last_name' => __( 'User Last Name' ), + 'description' => __( 'User Description' ), + ); + + $user_data_to_export = array(); + + foreach ( $user_prop_to_export as $key => $name ) { + $value = ''; + + switch ( $key ) { + case 'ID': + case 'user_login': + case 'user_nicename': + case 'user_email': + case 'user_url': + case 'user_registered': + case 'display_name': + $value = $user->data->$key; + break; + case 'nickname': + case 'first_name': + case 'last_name': + case 'description': + $value = $user_meta[ $key ][0]; + break; + } + + if ( ! empty( $value ) ) { + $user_data_to_export[] = array( + 'name' => $name, + 'value' => $value, + ); + } + } + + $data_to_export[] = array( + 'group_id' => 'user', + 'group_label' => __( 'User' ), + 'item_id' => "user-{$user->ID}", + 'data' => $user_data_to_export, + ); + + return array( + 'data' => $data_to_export, + 'done' => true, + ); +} + /** * Update log when privacy request is confirmed. * diff --git a/tests/phpunit/tests/user.php b/tests/phpunit/tests/user.php index 09a5a0628a..7e018e64d8 100644 --- a/tests/phpunit/tests/user.php +++ b/tests/phpunit/tests/user.php @@ -29,6 +29,8 @@ class Tests_User extends WP_UnitTestCase { 'user_email' => 'blackburn@battlefield3.com', 'user_url' => 'http://tacos.com', 'role' => 'contributor', + 'nickname' => 'Johnny', + 'description' => 'I am a WordPress user that cares about privacy.', ) ); @@ -1580,4 +1582,40 @@ class Tests_User extends WP_UnitTestCase { // Should have the new role. $this->assertSame( array( 'administrator' ), get_userdata( $editor )->roles ); } + + /** + * Testing the `wp_user_personal_data_exporter_no_user` function when no user exists. + * + * @ticket 43547 + */ + function test_wp_user_personal_data_exporter_no_user() { + $actual = wp_user_personal_data_exporter( 'not-a-user-email@test.com' ); + + $expected = array( + 'data' => array(), + 'done' => true, + ); + + $this->assertSame( $expected, $actual ); + } + + /** + * Testing the `wp_user_personal_data_exporter_no_user` function when the requested + * user exists. + * + * @ticket 43547 + */ + function test_wp_user_personal_data_exporter() { + $test_user = new WP_User( self::$contrib_id ); + + $actual = wp_user_personal_data_exporter( $test_user->user_email ); + + $this->assertTrue( $actual['done'] ); + + // Number of exported users. + $this->assertSame( 1, count( $actual['data'] ) ); + + // Number of exported user properties. + $this->assertSame( 12, count( $actual['data'][0]['data'] ) ); + } }