Before You Report
Version
1.1.7 (verified against the deployed 1.1.7 assembly source commit and current master).
Description
Removing the root permission (.*) through DefaultPermissionsProvider.RemovePermissions does not revoke root access until the server is restarted.
ReloadPermissions clears SpecialPermissionsSuperset, but it never resets PermissionGroup.IsRoot before rebuilding the derived state:
foreach (PermissionGroup permissionsGroup in _permissionsDictionary.Values)
{
permissionsGroup.SpecialPermissionsSuperset.Clear();
foreach (string permission in permissionsGroup.Permissions)
{
if (permission == ".*")
{
permissionsGroup.IsRoot = true;
break;
}
// ...
}
}
RemovePermissions removes .* from group.Permissions and calls ReloadPermissions, but the previously set IsRoot flag remains true. HasPermission checks that flag before checking the current permission list.
To Reproduce
- Configure a default-provider permission group that contains
.*, and assign a connected player to that group.
- From a plugin, call:
player.RemovePermissions(".*");
bool stillHasAllAccess = player.HasPermission("arbitrary.permission");
- Inspect the resulting
permissions.yml: the .* entry has been removed.
Actual Behavior
stillHasAllAccess remains true for the remainder of the server process, despite the group no longer containing .* and the updated configuration being saved. The root flag is only cleared by constructing a fresh provider after a server restart.
Expected Behavior
Removing .* should immediately revoke root access after the provider reloads its derived state.
Proposed Fix
Reset the derived flag at the start of each group rebuild:
permissionsGroup.IsRoot = false;
permissionsGroup.SpecialPermissionsSuperset.Clear();
Adding a regression test that adds then removes .* without restarting the provider would cover this case.
Before You Report
Version
1.1.7 (verified against the deployed 1.1.7 assembly source commit and current
master).Description
Removing the root permission (
.*) throughDefaultPermissionsProvider.RemovePermissionsdoes not revoke root access until the server is restarted.ReloadPermissionsclearsSpecialPermissionsSuperset, but it never resetsPermissionGroup.IsRootbefore rebuilding the derived state:RemovePermissionsremoves.*fromgroup.Permissionsand callsReloadPermissions, but the previously setIsRootflag remainstrue.HasPermissionchecks that flag before checking the current permission list.To Reproduce
.*, and assign a connected player to that group.permissions.yml: the.*entry has been removed.Actual Behavior
stillHasAllAccessremainstruefor the remainder of the server process, despite the group no longer containing.*and the updated configuration being saved. The root flag is only cleared by constructing a fresh provider after a server restart.Expected Behavior
Removing
.*should immediately revoke root access after the provider reloads its derived state.Proposed Fix
Reset the derived flag at the start of each group rebuild:
Adding a regression test that adds then removes
.*without restarting the provider would cover this case.