From 93a90a9aa401c4e347055bf904f63d88cca27e72 Mon Sep 17 00:00:00 2001 From: iandunn Date: Wed, 2 May 2018 01:07:22 +0000 Subject: [PATCH] Privacy: Limit export and erasure to super admins on Multisite. Multisite networks have a variety of use cases, and in many of them single-site administrators are not trusted to take actions that affect the whole network, require making decisions about legal compliance, etc. By default, those actions should require super admin capabilities. Plugins can be used to override that behavior if a particular site's use case calls for it. Props allendav, jeremyfelt, iandunn. Fixes #43919. Built from https://develop.svn.wordpress.org/trunk@43085 git-svn-id: http://core.svn.wordpress.org/trunk@42914 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/includes/ajax-actions.php | 5 +++-- wp-admin/includes/user.php | 18 ++++++++++++------ wp-includes/capabilities.php | 4 ++++ wp-includes/version.php | 2 +- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php index 1a52e3e0fb..6d2f3e650f 100644 --- a/wp-admin/includes/ajax-actions.php +++ b/wp-admin/includes/ajax-actions.php @@ -4344,7 +4344,7 @@ function wp_ajax_wp_privacy_export_personal_data() { wp_send_json_error( __( 'Invalid request ID.' ) ); } - if ( ! current_user_can( 'manage_options' ) ) { + if ( ! current_user_can( 'export_others_personal_data' ) ) { wp_send_json_error( __( 'Invalid request.' ) ); } @@ -4522,7 +4522,8 @@ function wp_ajax_wp_privacy_erase_personal_data() { wp_send_json_error( __( 'Invalid request ID.' ) ); } - if ( ! current_user_can( 'delete_users' ) ) { + // Both capabilities are required to avoid confusion, see `_wp_personal_data_removal_page()`. + if ( ! current_user_can( 'erase_others_personal_data' ) || ! current_user_can( 'delete_users' ) ) { wp_send_json_error( __( 'Invalid request.' ) ); } diff --git a/wp-admin/includes/user.php b/wp-admin/includes/user.php index e242322e35..939ad167bd 100644 --- a/wp-admin/includes/user.php +++ b/wp-admin/includes/user.php @@ -785,8 +785,8 @@ function _wp_personal_data_cleanup_requests() { * @access private */ function _wp_personal_data_export_page() { - if ( ! current_user_can( 'manage_options' ) ) { - wp_die( esc_html__( 'Sorry, you are not allowed to manage privacy on this site.' ) ); + if ( ! current_user_can( 'export_others_personal_data' ) ) { + wp_die( __( 'Sorry, you are not allowed to export personal data on this site.' ) ); } _wp_personal_data_handle_actions(); @@ -850,8 +850,14 @@ function _wp_personal_data_export_page() { * @access private */ function _wp_personal_data_removal_page() { - if ( ! current_user_can( 'delete_users' ) ) { - wp_die( esc_html__( 'Sorry, you are not allowed to manage privacy on this site.' ) ); + /* + * Require both caps in order to make it explicitly clear that delegating + * erasure from network admins to single-site admins will give them the + * ability to affect global users, rather than being limited to the site + * that they administer. + */ + if ( ! current_user_can( 'erase_others_personal_data' ) || ! current_user_can( 'delete_users' ) ) { + wp_die( __( 'Sorry, you are not allowed to erase data on this site.' ) ); } _wp_personal_data_handle_actions(); @@ -917,8 +923,8 @@ function _wp_personal_data_removal_page() { * @access private */ function _wp_privacy_hook_requests_page() { - add_submenu_page( 'tools.php', __( 'Export Personal Data' ), __( 'Export Personal Data' ), 'manage_options', 'export_personal_data', '_wp_personal_data_export_page' ); - add_submenu_page( 'tools.php', __( 'Remove Personal Data' ), __( 'Remove Personal Data' ), 'manage_options', 'remove_personal_data', '_wp_personal_data_removal_page' ); + add_submenu_page( 'tools.php', __( 'Export Personal Data' ), __( 'Export Personal Data' ), 'export_others_personal_data', 'export_personal_data', '_wp_personal_data_export_page' ); + add_submenu_page( 'tools.php', __( 'Remove Personal Data' ), __( 'Remove Personal Data' ), 'erase_others_personal_data', 'remove_personal_data', '_wp_personal_data_removal_page' ); } // TODO: move the following classes in new files. diff --git a/wp-includes/capabilities.php b/wp-includes/capabilities.php index a81761db15..efc3dd2e4c 100644 --- a/wp-includes/capabilities.php +++ b/wp-includes/capabilities.php @@ -555,6 +555,10 @@ function map_meta_cap( $cap, $user_id ) { $caps[] = 'update_core'; } break; + case 'export_others_personal_data': + case 'erase_others_personal_data': + $caps[] = is_multisite() ? 'manage_network' : 'manage_options'; + break; default: // Handle meta capabilities for custom post types. global $post_type_meta_caps; diff --git a/wp-includes/version.php b/wp-includes/version.php index 4f1981c2f1..fd4a4a4f38 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,7 +4,7 @@ * * @global string $wp_version */ -$wp_version = '5.0-alpha-43081'; +$wp_version = '5.0-alpha-43085'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.