Vanilla 1 is no longer supported or maintained. If you need a copy, you can get it here.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

Changing User Role Problem

edited January 2008 in Vanilla 1.0 Help
Users with the 'Can change User Role' permission should not be able to change the roles of users with a higher ranked role than themselves, as defined by the sortable role list.

I'm sure this was meant to be included in the core, otherwise there isn't really a use for the sortable list.


  • *bump
  • I'm not entirely sure that the roles in Vanilla are meant to be a ranked seems more to me that it's a true/false type of thing where if you have someone who has change roles enabled, it's a global variable no matter your rank.

    For instance, if you have 2 author-type roles with different titles, just because author 1 is above author 2 does that mean that they should have more power? That doesn't seem right.

    Since there isn't anything in the documentation about it, I'm not 100%.
  • Well it's mainly that if you're creating a forum for some group of people with a strict hierarchy, they like to keep it. I need to assign role privileges so that those lower down the ranks can bump up people who are below them, but can't immediately boost themselves up to Administrator, mainly as a prevention of havoc.
  • Well, I have created a role, but when I drag to reorder, it doesn't stick. Does anybody else have this issue? Should my discussion go elsewhere? I am finding the forum hard to navigate other than with search.
  • BenBen
    edited November 2007
    I'm just going to bump this again..

    I have 2 ranks in a forum who should be able to edit Roles, but they're still restricted concerning most of the administrative features.
    My problem is that although the roles can be clearly ordered in a hierarchical fashion, if I assign role changing privileges to the lower-ranked of these two roles, they can still edit the role of the ones above them. It's possible for them to ban the roles above them and raise themselves to Administrator where they can edit all sorts of settings I'd rather they didn't; if they were so inclined of course.

    I just want them to only be able to raise the Role of those beneath them.. a Corporal shouldn't be able to promote a Private to Captain, or dismiss the General...
  • There should be a way to do this.. there's a column in the Role table entitled 'Priority', generated by the order you arrange the Roles in through drag & drop.
  • edited January 2008
    ok yes, i'd like to be able to do this too.

    I don't think you can change your own role, but if you have a "Change user roles" permission you could sign up to the forum with a new account and assign that account an admin role and once you have the admin role you can do everything.

    I don't like this for lots of reasons.

    If a user has a "Change user roles" permission, wouldn't it be better to only allow them to assign roles up to and including their rank/priority or "pay grade"?
  • that's odd

    I had the same concerns as you when I have the moderators of my forum the power to change roles. For the sake of argument we'll say my forum has three roles: admin (me - can anything); moderator (can do a bunch of stuff mods do) and user.

    I tested it and discovered they were unable to change my role (as admin) and were unable to change themselves to admin or indeed change users to admin (although I haven't tested to see if they can change users into moderators but I would worry about that as I trust them.

    So therefore I didn't have a problem and I assumed the functionality was in built as you requested in the first post - unless I'm reading this all wrong

    if so, sorry - and please ignore ;)
  • I'm having this same issue. I hear what your saying conradslater, but I cant say my forum works in the same way. Basically the priority level (order) of each role doesnt seem to affect who can give who what role. Any answers or add ons for this issue? Its crazy that a moderater can change a members role to one which is higher than themselfs! Cheers.
  • edited January 2008
    yes it is crazy, it shouldn't be an addon that solves this problem, it should be in the core.
  • Agreed. But how do we get this into the development cycle, or at least for the meantime - make an extension for this?
  • I'd suggest someone adds it to the bug tracker.
  • How do we do this?
  • I can do it. I'm sure this issue has come up so many times in the past and been resolved though. It's strange it works for some and not others...
  • @minisweeper I think what IS in the core is not being able to edit the role of admin, or maybe only the first account (1). but what ISN'T in the core is not being able to change the role of someone w/ a higher hierarchy; at least that's the conclusion I have come to.
  • I see what you mean there. This would explain the confusion. I really hope something can be sorted. I'm hoping to use Vanilla for one of my sites due to be released within the next few months, but this sort of thing is essential really. Since there is the functionality built into the database tables (priority), is there an easy way to create an extension for the time being?
  • edited January 2008
    i don't know how to make an extension of it, i think you would need some delegates added, but this seems to work maybe someone can use it and make the extension:

    you have to edit three files.

    First: library/People/People.Class.RoleManager lines 30-37 - Add a "Priority" field to the select statment array on line 33
    30 function GetRoleBuilder($GetUnauthenticated = '0') { 31 $s = $this->Context->ObjectFactory->NewContextObject($this->Context, 'SqlBuilder'); 32 $s->SetMainTable('Role', 'r'); 33 $s->AddSelect(array('Priority', 'RoleID', 'Name', 'Icon', 'Description', 'PERMISSION_SIGN_IN', 'PERMISSION_RECEIVE_APPLICATION_NOTIFICATION', 'PERMISSION_HTML_ALLOWED', 'Permissions', 'Unauthenticated'), 'r'); 34 $s->AddWhere('r', 'Active', '', '1', '='); 35 if (!$GetUnauthenticated) $s->AddWhere('r', 'Unauthenticated', '', '0', '='); 36 return $s; 37 }

    Next: library/People/People.Class.Role - Add a Priority property to the Role class
    so three edits will do it -
    add this property
    var $Priority;
    this line to the Clear method
    $this->Priority = 0;
    and this line to the GetPropertiesFromDataSet method
    $this->Priority = ForceInt(@$DataSet['Priority'], 0);

    And last but not least: library/Vanilla/Vanilla.Control.AccountRoleForm.php - you need to compare the users role level(priority) against the role level(priority) being assigned

    you need to change the following piece of code
    36 if ($this->PostBackAction == 'ProcessRole' && $this->IsValidFormPostBack() && $this->Context->Session->UserID != $User->UserID && $this->Context->Session->User->Permission('PERMISSION_CHANGE_USER_ROLE')) { 37 $urh = $this->Context->ObjectFactory->NewObject($this->Context, 'UserRoleHistory'); 38 $urh->GetPropertiesFromForm(); 39 if ($UserManager->AssignRole($urh)) $Redirect = 1; 40 }

    to note: line 39 is the only line changed
    36 if ($this->PostBackAction == 'ProcessRole' && $this->IsValidFormPostBack() && $this->Context->Session->UserID != $User->UserID && $this->Context->Session->User->Permission('PERMISSION_CHANGE_USER_ROLE')) { 37 $urh = $this->Context->ObjectFactory->NewObject($this->Context, 'UserRoleHistory'); 38 $urh->GetPropertiesFromForm(); $rm = $this->Context->ObjectFactory->NewContextObject($this->Context, 'RoleManager'); $UserRole = $rm->GetRoleById($this->Context->Session->User->RoleID); $NewRole = $rm->GetRoleById(($urh->RoleID)); if ($NewRole->Priority > $UserRole->Priority) { $this->Context->WarningCollector->Add('You cannot change a users role to a level higher than yours.'); } elseif ($UserManager->AssignRole($urh)) { $Redirect = 1; } 40 }
  • Thanks Gerry! This is fantastic, well done. I'm a bit cautious of making changes like that though, as I just know they will break when we upgrade the version. Can we somehow 'suggest' your code for the next update of Vanilla?
  • edited January 2008
    Just checked out your fix Gerry, and it works great for refusing access to a higher level than yourself (great work! see image), but unfortunately it still lets you 'demote' a level higher than you.

    So e.g. a moderator can change an administrator to member. Is it easy to change this aspect using the same method?


    I suppose what we have to do is add another elseif to the last file. So we would say if CurrentUserRole priority is lower than UserRole priority, then it returns a different error. 'You cannot change the role of a user higher than yourself'.

    CurrentUserRole being the role of the person who is trying to edit someone else.
    UserRole being the role of the person who you are editing.
  • edited January 2008
    ok, this should do it.

    $rm = $this->Context->ObjectFactory->NewContextObject($this->Context, 'RoleManager');
    $um = $this->Context->ObjectFactory->NewContextObject($this->Context, 'UserManager');

    $UserRole = $rm->GetRoleById($this->Context->Session->User->RoleID);
    $NewRole = $rm->GetRoleById(($urh->RoleID));
    $sOldRole = $um->GetUserById($urh->UserID);
    $OldRole = $rm->GetRoleById($sOldRole->RoleID);

    if ($NewRole->Priority > $UserRole->Priority) {
    $this->Context->WarningCollector->Add('You cannot change a users role to a level higher than yours.');
    } elseif ($OldRole->Priority >= $UserRole->Priority) {
    $this->Context->WarningCollector->Add('You cannot change the role of a user of a higher or equal level role than you.');
    } elseif ($UserManager->AssignRole($urh)) {
    $Redirect = 1;

    there's already a UserManager, so:
    $rm = $this->Context->ObjectFactory->NewContextObject($this->Context, 'RoleManager'); $UserRole = $rm->GetRoleById($this->Context->Session->User->RoleID); $NewRole = $rm->GetRoleById(($urh->RoleID)); $sOldRole = $UserManager->GetUserById($urh->UserID); $OldRole = $rm->GetRoleById($sOldRole->RoleID); if ($NewRole->Priority > $UserRole->Priority) { $this->Context->WarningCollector->Add('You cannot change a users role to a level higher than yours.'); } elseif ($OldRole->Priority >= $UserRole->Priority) { $this->Context->WarningCollector->Add('You cannot change the role of a user with a higher or equal level role than you.'); } elseif ($UserManager->AssignRole($urh)) { $Redirect = 1; }
This discussion has been closed.