From cb38e921dc3ab208420ab93ef20a5bca5e44807b Mon Sep 17 00:00:00 2001 From: ryan Date: Tue, 6 Jan 2009 22:00:05 +0000 Subject: [PATCH] Add get_editable_roles() and role filtering. Props jeremyclarke. fixes #8770 git-svn-id: http://svn.automattic.com/wordpress/trunk@10323 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/includes/template.php | 7 ++--- wp-admin/includes/user.php | 55 +++++++++++++++++++++++++++++----- wp-admin/users.php | 6 ++-- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/wp-admin/includes/template.php b/wp-admin/includes/template.php index 0ffc73c10..460e321a3 100644 --- a/wp-admin/includes/template.php +++ b/wp-admin/includes/template.php @@ -2621,11 +2621,10 @@ function wp_dropdown_roles( $selected = false ) { $p = ''; $r = ''; - $role_names = $wp_roles->role_names; - $role_names = apply_filters('role_names_listing', $role_names); + $editable_roles = get_editable_roles(); - foreach( $role_names as $role => $name ) { - $name = translate_with_context($name); + foreach( $editable_roles as $role => $details ) { + $name = translate_with_context($details['name']); if ( $selected == $role ) // Make default first in list $p = "\n\t"; else diff --git a/wp-admin/includes/user.php b/wp-admin/includes/user.php index 5709cc184..ab4d8594e 100644 --- a/wp-admin/includes/user.php +++ b/wp-admin/includes/user.php @@ -9,9 +9,12 @@ /** * Creates a new user from the "Users" form using $_POST information. * - * {@internal Missing Long Description}} + * It seems that the first half is for backwards compatibility, but only + * has the ability to alter the user's role. Wordpress core seems to + * use this function only in the second way, running edit_user() with + * no id so as to create a new user. * - * @since unknown + * @since 2.0 * * @param int $user_id Optional. User ID. * @return null|WP_Error|int Null when adding user, WP_Error or User ID integer when no parameters. @@ -22,7 +25,13 @@ function add_user() { $user_id = (int) func_get_arg( 0 ); if ( isset( $_POST['role'] ) ) { + // Don't let anyone with 'edit_users' (admins) edit their own role to something without it. if( $user_id != $current_user->id || $wp_roles->role_objects[$_POST['role']]->has_cap( 'edit_users' ) ) { + // If the new role isn't editable by the logged-in user die with error + $editable_roles = get_editable_roles(); + if (!$editable_roles[$_POST['role']]) + wp_die(__('You can’t give users that role.')); + $user = new WP_User( $user_id ); $user->set_role( $_POST['role'] ); } @@ -34,14 +43,14 @@ function add_user() { } /** - * {@internal Missing Short Description}} + * Edit user settings based on contents of $_POST * - * {@internal Missing Long Description}} + * Used on user-edit.php and profile.php to manage and process user options, passwords etc. * - * @since unknown + * @since 2.0 * * @param int $user_id Optional. User ID. - * @return unknown + * @return int user id of the updated user */ function edit_user( $user_id = 0 ) { global $current_user, $wp_roles, $wpdb; @@ -65,8 +74,15 @@ function edit_user( $user_id = 0 ) { $pass2 = $_POST['pass2']; if ( isset( $_POST['role'] ) && current_user_can( 'edit_users' ) ) { + + // Don't let anyone with 'edit_users' (admins) edit their own role to something without it. if( $user_id != $current_user->id || $wp_roles->role_objects[$_POST['role']]->has_cap( 'edit_users' )) - $user->role = $_POST['role']; + $user->role = $_POST['role']; + + // If the new role isn't editable by the logged-in user die with error + $editable_roles = get_editable_roles(); + if (!$editable_roles[$_POST['role']]) + wp_die(__('You can’t give users that role.')); } if ( isset( $_POST['email'] )) @@ -241,6 +257,31 @@ function get_editable_user_ids( $user_id, $exclude_zeros = true, $post_type = 'p return $wpdb->get_col( $query ); } +/** + * Fetch a filtered list of user roles that the current user is + * allowed to edit. + * + * Simple function who's main purpose is to allow filtering of the + * list of roles in the $wp_roles object so that plugins can remove + * innappropriate ones depending on the situation or user making edits. + * Specifically because without filtering anyone with the edit_users + * capability can edit others to be administrators, even if they are + * only editors or authors. This filter allows admins to delegate + * user management. + * + * @since 2.8 + * + * @return unknown + */ +function get_editable_roles() { + global $wp_roles; + + $all_roles = $wp_roles->roles; + $editable_roles = apply_filters('editable_roles', $all_roles); + + return $editable_roles; +} + /** * {@internal Missing Short Description}} * diff --git a/wp-admin/users.php b/wp-admin/users.php index 61fd687dc..6e1f9a38c 100644 --- a/wp-admin/users.php +++ b/wp-admin/users.php @@ -39,6 +39,7 @@ if ( empty($_REQUEST) ) { switch ($doaction) { +/* Bulk Dropdown menu Role changes */ case 'promote': check_admin_referer('bulk-users'); @@ -47,8 +48,9 @@ case 'promote': exit(); } - if ( !current_user_can('edit_users') ) - wp_die(__('You can’t edit users.')); + $editable_roles = get_editable_roles(); + if (!$editable_roles[$_REQUEST['new_role']]) + wp_die(__('You can’t give users that role.')); $userids = $_REQUEST['users']; $update = 'promote';