Ticket #44500: 44500.3.diff
File 44500.3.diff, 15.9 KB (added by , 6 years ago) |
---|
-
src/wp-admin/includes/user.php
778 778 $request_ids = $requests_query->posts; 779 779 780 780 foreach ( $request_ids as $request_id ) { 781 wp_update_post( 782 array( 783 'ID' => $request_id, 784 'post_status' => 'request-failed', 785 'post_password' => '', 786 ) 787 ); 781 wp_mark_user_request_failed( $request_id ); 788 782 } 789 783 } 790 784 -
src/wp-includes/user.php
3528 3528 /** 3529 3529 * Validate a user request by comparing the key with the request's key. 3530 3530 * 3531 * If determined that the request is expired, it will be transitioned to the `request-failed` status. 3532 * 3531 3533 * @since 4.9.6 3532 3534 * 3533 3535 * @param string $request_id ID of the request being confirmed. … … 3583 3585 } 3584 3586 3585 3587 if ( ! $expiration_time || time() > $expiration_time ) { 3588 wp_mark_user_request_failed( $request_id ); 3586 3589 return new WP_Error( 'expired_key', __( 'The confirmation email has expired.' ) ); 3587 3590 } 3588 3591 … … 3609 3612 } 3610 3613 3611 3614 /** 3615 * Marks a user_request post as failed. 3616 * 3617 * @since 4.9.9 3618 * 3619 * @param int $request_id User request ID. 3620 * @return int|WP_Error Post ID when updated successfully, WP_Error on failure. 3621 */ 3622 function wp_mark_user_request_failed( $request_id ) { 3623 $post = get_post( $request_id ); 3624 3625 if ( ! $post ) { 3626 return new WP_Error( 'invalid_request_id', __( 'Invalid request ID.' ) ); 3627 } elseif ('user_request' !== $post->post_type ) { 3628 return new WP_Error( 'invalid_post_type', __( 'Invalid request post type.' ) ); 3629 } 3630 3631 if ( 'request-completed' === $post->post_status ) { 3632 return new WP_Error( 'already_completed', __( 'The request has already been completed.' ) ); 3633 } 3634 3635 return wp_update_post( 3636 array( 3637 'ID' => $request_id, 3638 'post_status' => 'request-failed', 3639 'post_password' => '', 3640 ), 3641 true 3642 ); 3643 } 3644 3645 /** 3612 3646 * WP_User_Request class. 3613 3647 * 3614 3648 * Represents user request data loaded from a WP_Post object. -
tests/phpunit/tests/privacy/wpPersonalDataCleanupRequests.php
1 <?php 2 /** 3 * Test the `_wp_personal_data_cleanup_requests()` function. 4 * 5 * @package WordPress 6 * @subpackage UnitTests 7 * @since 4.9.9 8 */ 9 10 /** 11 * Tests_WpPersonalDataCleanupRequests class. 12 * 13 * @group privacy 14 * @covers wp_mark_user_request_failed 15 * 16 * @since 4.9.9 17 */ 18 class Tests_WpPersonalDataCleanupRequests extends WP_UnitTestCase { 19 20 /** 21 * Utility method for creating user requests. 22 * 23 * @since 4.9.9 24 * 25 * @param int $number Number of posts to create. Default is 4. 26 * @param array $args Post arguments. Default is none. @see wp_insert_post(). 27 */ 28 public function _create_requests( $number = 4, $args = array() ) { 29 $defaults = array( 30 'post_type' => 'user_request', 31 'post_name' => 'export_personal_data', 32 'post_status' => 'request-pending', 33 ); 34 $args = wp_parse_args( $args, $defaults ); 35 $this->factory->post->create_many( $number, $args ); 36 } 37 38 /** 39 * Utility method for getting a list of request IDs with a given status. 40 * 41 * @since 4.9.9 42 * 43 * @param string $status Request status to query. Default is pending. 44 * @return array List of request post IDs. 45 */ 46 public function _get_request_ids( $status = 'request-pending' ) { 47 $failed_requests = new WP_Query( 48 array( 49 'post_type' => 'user_request', 50 'post_status' => $status, 51 'fields' => 'ids', 52 'posts_per_page' => 100, 53 ) 54 ); 55 56 return $failed_requests->posts; 57 } 58 59 /** 60 * The function should not mark unexpired requests as failed. 61 * 62 * @ticket 44500 63 */ 64 public function test_function_does_not_move_pending_requests_with_time_remaining() { 65 $this->_create_requests(); 66 67 _wp_personal_data_cleanup_requests(); 68 69 $this->assertSame( 4, count( $this->_get_request_ids() ) ); 70 $this->assertSame( 0, count( $this->_get_request_ids( 'request-failed' ) ) ); 71 } 72 73 /** 74 * The function should mark all unexpired requests as failed. 75 * 76 * @ticket 44500 77 */ 78 public function test_function_moves_all_expired_pending_requests() { 79 $this->_create_requests( 4, array( 80 'post_date' => date( 'Y-m-d H:i:s', strtotime( '4 days ago' ) ), 81 ) ); 82 83 _wp_personal_data_cleanup_requests(); 84 85 $this->assertSame( 0, count( $this->_get_request_ids() ) ); 86 $this->assertSame( 4, count( $this->_get_request_ids( 'request-failed' ) ) ); 87 } 88 89 /** 90 * The function should only mark expired requests as failed when there is a mix, even if requests with other 91 * statuses would be considered expired. 92 * 93 * @ticket 44500 94 */ 95 public function test_function_udpates_correct_requests_with_mixed_status_requests() { 96 $this->_create_requests( 2 ); 97 $this->_create_requests( 2, array( 98 'post_date' => date( 'Y-m-d H:i:s', strtotime( '5 days ago' ) ), 99 'post_status' => 'request-completed', 100 ) ); 101 $this->_create_requests( 2, array( 102 'post_date' => date( 'Y-m-d H:i:s', strtotime( '4 days ago' ) ), 103 ) ); 104 105 _wp_personal_data_cleanup_requests(); 106 107 $this->assertSame( 2, count( $this->_get_request_ids() ) ); 108 $this->assertSame( 2, count( $this->_get_request_ids( 'request-completed' ) ) ); 109 $this->assertSame( 2, count( $this->_get_request_ids( 'request-failed' ) ) ); 110 } 111 112 /** 113 * The function should mark only expired requests as failed, even when there are export and erase requests mixed. 114 * 115 * @ticket 44500 116 */ 117 public function test_function_updates_correct_requests_with_mixed_export_erase() { 118 $this->_create_requests( 2 ); 119 $this->_create_requests( 2, array( 120 'post_name' => 'remove_personal_data', 121 ) ); 122 $this->_create_requests( 2, array( 123 'post_date' => date( 'Y-m-d H:i:s', strtotime( '2 days ago' ) ), 124 ) ); 125 $this->_create_requests( 2, array( 126 'post_name' => 'remove_personal_data', 127 'post_date' => date( 'Y-m-d H:i:s', strtotime( '2 days ago' ) ), 128 ) ); 129 130 add_filter( 'user_request_key_expiration', array( $this, 'filter_request_expiration_time' ) ); 131 _wp_personal_data_cleanup_requests(); 132 133 $this->assertSame( 4, count( $this->_get_request_ids() ) ); 134 $this->assertSame( 4, count( $this->_get_request_ids( 'request-failed' ) ) ); 135 } 136 137 /** 138 * The function should mark only expired requests as failed when the expiration time is filtered. 139 * 140 * @ticket 44500 141 */ 142 public function test_function_updates_correct_requests_with_filtered_expiration() { 143 $this->_create_requests( 2 ); 144 $this->_create_requests( 2, array( 145 'post_status' => 'request-completed', 146 'post_date' => date( 'Y-m-d H:i:s', strtotime( '2 days ago' ) ), 147 ) ); 148 $this->_create_requests( 2, array( 149 'post_date' => date( 'Y-m-d H:i:s', strtotime( '2 days ago' ) ), 150 ) ); 151 152 add_filter( 'user_request_key_expiration', array( $this, 'filter_request_expiration_time' ) ); 153 _wp_personal_data_cleanup_requests(); 154 155 $this->assertSame( 2, count( $this->_get_request_ids() ) ); 156 $this->assertSame( 2, count( $this->_get_request_ids( 'request-completed' ) ) ); 157 $this->assertSame( 2, count( $this->_get_request_ids( 'request-failed' ) ) ); 158 } 159 160 /** 161 * Filter the privacy data request expiration time. 162 * 163 * @since 4.9.9 164 * 165 * @return int Expiration time in seconds 166 */ 167 public function filter_request_expiration_time() { 168 return DAY_IN_SECONDS * 1; 169 } 170 } -
tests/phpunit/tests/user/wpMarkUserRequestFailed.php
1 <?php 2 /** 3 * Test the `wp_mark_user_request_failed()` function. 4 * 5 * @package WordPress 6 * @subpackage UnitTests 7 * @since 4.9.9 8 */ 9 10 /** 11 * Tests_WpMarkUserRequestFailed class. 12 * 13 * @group privacy 14 * @ticket 44500 15 16 * @covers wp_mark_user_request_failed 17 * 18 * @since 4.9.9 19 */ 20 class Tests_WpMarkUserRequestFailed extends WP_UnitTestCase { 21 /** 22 * Current test request ID. 23 * 24 * @since 4.9.9 25 * 26 * @var int $request_id 27 */ 28 protected static $request_id; 29 30 /** 31 * Create fixtures. 32 * 33 * @since 4.9.9 34 */ 35 public function setUp() { 36 parent::setUp(); 37 38 self::$request_id = wp_create_user_request( 'requester@example.com', 'export_personal_data' ); 39 } 40 41 /** 42 * The function should return an error when an invalid request post ID is passed. 43 * 44 * @since 4.9.9 45 */ 46 public function test_function_throws_error_when_invalid_request_id() { 47 $actual = wp_mark_user_request_failed( null ); 48 49 $this->assertWPError( $actual ); 50 $this->assertSame( 'Invalid request ID.', $actual->get_error_message() ); 51 } 52 53 /** 54 * The function should return an error when an invalid request post ID is passed. 55 * 56 * @ticket 44500 57 */ 58 public function test_function_throws_error_when_invalid_request_type() { 59 $non_request_post_id = $this->factory->post->create( 60 array( 61 'post_type' => 'post', 62 ) 63 ); 64 65 $actual = wp_mark_user_request_failed( $non_request_post_id ); 66 67 $this->assertWPError( $actual ); 68 $this->assertSame( 'Invalid request post type.', $actual->get_error_message() ); 69 } 70 71 /** 72 * The function should return an error when the request has already been completed. 73 * 74 * @ticket 44500 75 */ 76 public function test_function_throws_error_when_request_already_completed() { 77 wp_update_post( 78 array( 79 'ID' => self::$request_id, 80 'post_status' => 'request-completed', 81 ) 82 ); 83 84 $actual = wp_mark_user_request_failed( self::$request_id ); 85 86 $this->assertWPError( $actual ); 87 $this->assertSame( 'The request has already been completed.', $actual->get_error_message() ); 88 } 89 90 /** 91 * The function should return an error when an invalid request post ID is passed. 92 * 93 * @ticket 44500 94 */ 95 public function test_function_succeeds() { 96 $actual = wp_mark_user_request_failed( self::$request_id ); 97 98 $this->assertSame( self::$request_id, $actual ); 99 $this->assertSame( 'request-failed', get_post_status( self::$request_id ) ); 100 } 101 } -
tests/phpunit/tests/user/wpValidateUserRequestKey.php
1 <?php 2 /** 3 * Test the `wp_validate_user_request_key()` function. 4 * 5 * @package WordPress 6 * @subpackage UnitTests 7 * @since 4.9.9 8 */ 9 10 /** 11 * Tests_WpValidateUserRequestKey class. 12 * 13 * @group user 14 * @group privacy 15 * @covers wp_validate_user_request_key 16 * 17 * @since 4.9.9 18 */ 19 class Tests_WpValidateUserRequestKey extends WP_UnitTestCase { 20 /** 21 * Request ID 22 * 23 * @since 4.9.9 24 * 25 * @var int $request_id 26 */ 27 protected static $request_id; 28 29 /** 30 * Request confirmation key. 31 * 32 * @since 4.9.9 33 * 34 * @var string $request_key 35 */ 36 protected static $request_key; 37 38 /** 39 * Create fixtures. 40 * 41 * @since 4.9.9 42 * 43 * @param WP_UnitTest_Factory $factory Factory. 44 */ 45 public static function wpSetUpBeforeClass( $factory ) { 46 self::$request_id = wp_create_user_request( 'requester@example.com', 'export_personal_data' ); 47 self::$request_key = wp_generate_user_request_key( self::$request_id ); 48 } 49 50 /** 51 * A WP_Error should be returned when an invalid request ID value is passed. 52 * 53 * @ticket 44500 54 */ 55 public function test_invalid_request() { 56 $actual = wp_validate_user_request_key( null, self::$request_key ); 57 58 $this->assertWPError( $actual ); 59 $this->assertSame( 'invalid_request', $actual->get_error_code() ); 60 } 61 62 /** 63 * A WP_Error should be returned when a request ID that does not exist. 64 * 65 * @ticket 44500 66 */ 67 public function test_invalid_request_does_not_exist() { 68 $actual = wp_validate_user_request_key( 1234567, self::$request_key ); 69 70 $this->assertWPError( $actual ); 71 $this->assertSame( 'invalid_request', $actual->get_error_code() ); 72 } 73 74 /** 75 * A WP_Error should be returned when the request is not pending or failed. 76 * 77 * @ticket 44500 78 */ 79 public function test_request_not_pending_or_failed() { 80 wp_update_post( 81 array( 82 'ID' => self::$request_id, 83 'post_status' => 'request-confirmed', 84 ) 85 ); 86 87 $actual = wp_validate_user_request_key( self::$request_id, self::$request_key ); 88 89 $this->assertWPError( $actual ); 90 $this->assertSame( 'expired_link', $actual->get_error_code() ); 91 } 92 93 /** 94 * A WP_Error should be returned when an empty key is passed. 95 * 96 * @ticket 44500 97 */ 98 public function test_empty_key() { 99 $actual = wp_validate_user_request_key( self::$request_id, '' ); 100 101 $this->assertWPError( $actual ); 102 $this->assertSame( 'invalid_key', $actual->get_error_code() ); 103 } 104 105 /** 106 * A WP_Error should be returned when a request does not have a confirmation key stored. 107 * 108 * @ticket 44500 109 */ 110 public function test_empty_post_password() { 111 wp_update_post( 112 array( 113 'ID' => self::$request_id, 114 'post_password' => '', 115 ) 116 ); 117 118 $actual = wp_validate_user_request_key( self::$request_id, self::$request_key ); 119 120 $this->assertWPError( $actual ); 121 $this->assertSame( 'invalid_key', $actual->get_error_code() ); 122 } 123 124 /** 125 * A WP_Error should be returned when the passed key does not match. 126 * 127 * @ticket 44500 128 */ 129 public function test_mismatched_keys() { 130 $actual = wp_validate_user_request_key( self::$request_id, 'abcdefg' ); 131 132 $this->assertWPError( $actual ); 133 $this->assertSame( 'invalid_key', $actual->get_error_code() ); 134 } 135 136 /** 137 * A WP_Error should be returned when key has expired. 138 * 139 * @ticket 44500 140 */ 141 public function test_expired_key() { 142 global $wpdb; 143 144 $wpdb->update( 145 $wpdb->posts, 146 array( 147 'post_modified_gmt' => gmdate( 'Y-m-d H:i:s', ( time() - 5 * DAY_IN_SECONDS ) ), 148 ), 149 array( 150 'ID' => self::$request_id, 151 ) 152 ); 153 154 $actual = wp_validate_user_request_key( self::$request_id, self::$request_key ); 155 156 $this->assertWPError( $actual ); 157 $this->assertSame( 'expired_key', $actual->get_error_code() ); 158 } 159 160 /** 161 * A WP_Error should be returned when the key has expired and the expiration time is filtered. 162 * 163 * @ticket 44500 164 */ 165 public function test_expired_key_filtered() { 166 global $wpdb; 167 168 $wpdb->update( 169 $wpdb->posts, 170 array( 171 'post_modified_gmt' => gmdate( 'Y-m-d H:i:s', ( time() - 2 * DAY_IN_SECONDS ) ), 172 ), 173 array( 174 'ID' => self::$request_id, 175 ) 176 ); 177 178 add_filter( 'user_request_key_expiration', array( $this, 'filter_request_key_expiration' ) ); 179 $actual = wp_validate_user_request_key( self::$request_id, self::$request_key ); 180 181 $this->assertWPError( $actual ); 182 $this->assertSame( 'expired_key', $actual->get_error_code() ); 183 } 184 185 /** 186 * Filter the key expiration time. 187 * 188 * @since 4.9.9 189 * 190 * @param $expiration Expiration time in seconds. 191 * @return int New expiration time. 192 */ 193 public function filter_request_key_expiration( $expiration ) { 194 return DAY_IN_SECONDS; 195 } 196 197 /** 198 * Test a key validation that should succeed. 199 * 200 * @ticket 44500 201 */ 202 public function test_key_validates() { 203 $this->assertTrue( wp_validate_user_request_key( self::$request_id, self::$request_key ) ); 204 } 205 206 /** 207 * Test an erase request key validation that should succeed. 208 * 209 * @ticket 44500 210 */ 211 public function test_key_validates_erase() { 212 wp_update_post( 213 array( 214 'ID' => self::$request_id, 215 'post_name' => 'remove_personal_data' 216 ) 217 ); 218 219 $this->assertTrue( wp_validate_user_request_key( self::$request_id, self::$request_key ) ); 220 } 221 }