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
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.
I'm sure this was meant to be included in the core, otherwise there isn't really a use for the sortable list.
0
This discussion has been closed.
Comments
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%.
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...
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"?
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
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 }
So e.g. a moderator can change an administrator to member. Is it easy to change this aspect using the same method?
Cheers.
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.
$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; }