Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I know that roles in WordPress are not hierarchical, but I'm wondering if there is any type of capability to "assign users to roles". All I can see if being able to add users or not.

The real kicker here is, I've used Justin Tadlock's Members plugin to create a new role, called "Clients" which removes all the stuff they should either not need to see, or shouldn't be able to control - which works great.
But, if I give them the ability to create a new user, they can also choose my "super admin" role, which can see everything. So, in a way, they kinda cheat the system a little bit.

Is there anyway to "hide" a certain role from showing up in what a user can set a new user/edit a user to? Or, possibly remove the role identifier from the add/edit user screen based on their role?
I know it sounds a bit off of what WordPress is mean to do for user permissions, but from an administrative stand-point, it sounds useful - at least in my head ;)

Thanks!

share|improve this question
    
Does this one sound a little too crazy? ;) –  Zach Nov 8 '11 at 15:54
    
No, absolutely not :) –  kaiser May 29 '12 at 22:26
add comment

2 Answers

up vote 5 down vote accepted

The UI select element

On user-edit.php, you see the drop-down in the UI. The drop down <select> wrapper is hard coded.

Then the admin interface does a nifty thing 1) according to the inline comment: // Get the highest/primary role for this user. In fact it is getting the first role, that was assigned to the user (this we have to keep in mind).

Then there's basically only a call to wp_dropdown_roles(). This function doesn't do anything else, than looping through the available roles and wrapping them inside <option> elements. But, there's one kool thing it does: It uses the roles retrieved by get_editable_roles(). And here comes the magic! A filter, for the global $wp_roles->roles. By default this returns all roles, but you can jump in and simply unset whatever you want.

// Add this as mu-plugin
function wpse32738_get_editable_roles( $editable_roles )
{
    if ( current_user_can( 'client' ) )
        // unset whatever you need here.

    return $editable_roles;
}
add_filter( 'editable_roles', 'wpse32738_get_editable_roles' );

1) Roles are a "flat" system. A role can have capabilities that overrule other capabilities.

share|improve this answer
1  
Nice! I'll give this a shot and report back. Thanks for the detailed explanation! –  Zach May 30 '12 at 16:01
    
Tried the following without success: pastebin.com/1GPMcWD9 Anything I'm missing? Thanks! –  Zach Jun 4 '12 at 19:16
    
Ah -- $role_names needed to be $editable_roles. Thanks! –  Zach Jun 4 '12 at 19:49
add comment

I've followed Kaiser's instructions and written the following code that allows me to grant user-management capabilities to a specific role and prevent privilege escalation to any built-in role (my code should be tweaked if you define custom intermediary roles).

// add user-management capabilities
add_action('admin_init', function() {
  $role = get_role( 'editor' );

  $role->add_cap( 'list_users' );
  $role->add_cap( 'create_users' );
  $role->add_cap( 'edit_users' );
  $role->add_cap( 'delete_users' );
});

// prevent privilege escalation
add_filter( 'editable_roles', function( $editable_roles ) {
  if ( ! current_user_can( 'promote_users' ) ) {
    // always remove admin roles
    if ( isset($editable_roles['super_admin']) ) {
      unset( $editable_roles['super_admin'] );
    }
    unset( $editable_roles['administrator'] );

    // remove other roles conditionnaly to prevent escalation
    if ( ! current_user_can( 'editor' ) ) {
      unset( $editable_roles['editor'] );

      if ( ! current_user_can( 'author' ) ) {
        unset( $editable_roles['author'] );

        if ( ! current_user_can( 'contributor' ) ) {
          unset( $editable_roles['contributor'] );
        }
      }
    }
  }

  return $editable_roles;
});

With this code, a contributor can be granted user-management capabilities, and he/she should only be able to create other contributors or subscribers.

BEWARE: this is a hacky solution, it hasn't been tested in network mode and no validation of input is made: a malicious user could still escalate privileges!

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.