Download & Extend

Only allow users to invite to roles they can also grant

Project:Role Invite
Version:6.x-1.0
Component:Code
Category:feature request
Priority:normal
Assigned:Unassigned
Status:active

Issue Summary

This works very well, but now that I've enabled it, any user with invite permission can invite to any role on the system, which is not ideal on sites where some roles grant special permissions.

I suggest that users only be allowed to invite to roles if they have permission to grant them. This could just be the default 'administer permissions' permission, or a specific set of permissions defined by another module.

Comments

#1

Seconding. Isn't this a major security flaw?

#2

Well, I'd say that it's not a privilege to be granted lightly, but it certainly could be used for privilege escalation.

#3

I think this issue can be solved by adding one alter hook in role_invite_form_alter() so modules can limit the roles available for selection by the inviter.

<?php
/**
* Implementation of hook_form_alter().
*/
function role_invite_form_alter(&$form, $form_state, $form_id)
{
    switch(
$form_id){
    case
'invite_form':
       
$roles = _get_roles();           
       
// call hook_role_invite_roles_alter(&$roles)
        // to let modules prune the roles available to the inviter
       
drupal_alter('role_invite_roles', &$roles); // <------ hook_role_invite_roles_alter
       
if(!empty($roles)){
           
$form['roles'] = array(
               
'#type' => 'checkboxes',
                
'#title' => t('User Roles'),                         
               
'#options' => $roles,
               
'#weight' => -15,
            );
        }
       
// Appending submit_handler for form submit.
       
$form['#submit'] = array_merge($form['#submit'],array("role_invite_submit_handler"));
    break;
    case
'user_register':
       
// In order to prevent caching of the preset e-mail address, we have to disable caching for user/register.
             
$GLOBALS['conf']['cache'] = CACHE_DISABLED;
   
             
$invite = invite_load_from_session();
              if (
$invite){
                if (
invite_validate($invite)) {
                   
$_SESSION[ROLE_INVITE_SESSION] = $invite->reg_code;
                }
              }
        break; 
    }
}
?>

For example, to limit the roles to the inviter's own roles:

<?php
/**
* implementation of hook_role_invite_roles_alter
*
* @param $roles array of (role id => role name)
*/
function MYMODULE_role_invite_roles_alter(&$roles) {
  global
$user;
 
$roles = array_intersect_key($user->roles, $roles);
}
?>

#4

I've never applied a hook before. How would I go about implementing this?