mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-22 00:33:59 +00:00
Removal of permission defaults (in favour of permission cascading) (#3937)
This commit is contained in:
parent
1eabc3fe75
commit
6d8833ccd3
@ -682,7 +682,7 @@ class Server{
|
||||
$this->operators->set(strtolower($name), true);
|
||||
|
||||
if(($player = $this->getPlayerExact($name)) !== null){
|
||||
$player->onOpStatusChange(true);
|
||||
$player->setBasePermission(DefaultPermissions::ROOT_OPERATOR, true);
|
||||
}
|
||||
$this->operators->save();
|
||||
}
|
||||
@ -691,7 +691,7 @@ class Server{
|
||||
$this->operators->remove(strtolower($name));
|
||||
|
||||
if(($player = $this->getPlayerExact($name)) !== null){
|
||||
$player->onOpStatusChange(false);
|
||||
$player->unsetBasePermission(DefaultPermissions::ROOT_OPERATOR);
|
||||
}
|
||||
$this->operators->save();
|
||||
}
|
||||
|
@ -76,10 +76,6 @@ class ConsoleCommandSender implements CommandSender{
|
||||
return "CONSOLE";
|
||||
}
|
||||
|
||||
public function onOpStatusChange(bool $value) : void{
|
||||
|
||||
}
|
||||
|
||||
public function getScreenLineHeight() : int{
|
||||
return $this->lineHeight ?? PHP_INT_MAX;
|
||||
}
|
||||
|
@ -95,6 +95,7 @@ use pocketmine\network\mcpe\protocol\types\PlayerListEntry;
|
||||
use pocketmine\network\mcpe\protocol\types\PlayerPermissions;
|
||||
use pocketmine\network\mcpe\protocol\UpdateAttributesPacket;
|
||||
use pocketmine\network\NetworkSessionManager;
|
||||
use pocketmine\permission\DefaultPermissions;
|
||||
use pocketmine\player\GameMode;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\player\PlayerInfo;
|
||||
@ -722,8 +723,9 @@ class NetworkSession{
|
||||
|
||||
//TODO: permission flags
|
||||
|
||||
$pk->commandPermission = ($for->isOp() ? AdventureSettingsPacket::PERMISSION_OPERATOR : AdventureSettingsPacket::PERMISSION_NORMAL);
|
||||
$pk->playerPermission = ($for->isOp() ? PlayerPermissions::OPERATOR : PlayerPermissions::MEMBER);
|
||||
$isOp = $for->hasPermission(DefaultPermissions::ROOT_OPERATOR);
|
||||
$pk->commandPermission = ($isOp ? AdventureSettingsPacket::PERMISSION_OPERATOR : AdventureSettingsPacket::PERMISSION_NORMAL);
|
||||
$pk->playerPermission = ($isOp ? PlayerPermissions::OPERATOR : PlayerPermissions::MEMBER);
|
||||
$pk->entityUniqueId = $for->getId();
|
||||
|
||||
$this->sendDataPacket($pk);
|
||||
|
@ -26,98 +26,103 @@ namespace pocketmine\permission;
|
||||
abstract class DefaultPermissions{
|
||||
public const ROOT = "pocketmine";
|
||||
|
||||
public static function registerPermission(Permission $perm, ?Permission $parent = null) : Permission{
|
||||
if($parent instanceof Permission){
|
||||
$parent->addChild($perm->getName(), true);
|
||||
}
|
||||
PermissionManager::getInstance()->addPermission($perm);
|
||||
public const ROOT_OPERATOR = "pocketmine.group.operator";
|
||||
public const ROOT_USER = "pocketmine.group.user";
|
||||
|
||||
return PermissionManager::getInstance()->getPermission($perm->getName());
|
||||
/**
|
||||
* @param Permission[] $grantedBy
|
||||
* @param Permission[] $deniedBy
|
||||
*/
|
||||
public static function registerPermission(Permission $candidate, array $grantedBy = [], array $deniedBy = []) : Permission{
|
||||
foreach($grantedBy as $permission){
|
||||
$permission->addChild($candidate->getName(), true);
|
||||
}
|
||||
foreach($deniedBy as $permission){
|
||||
$permission->addChild($candidate->getName(), false);
|
||||
}
|
||||
PermissionManager::getInstance()->addPermission($candidate);
|
||||
|
||||
return PermissionManager::getInstance()->getPermission($candidate->getName());
|
||||
}
|
||||
|
||||
public static function registerCorePermissions() : void{
|
||||
$parent = self::registerPermission(new Permission(self::ROOT, "Allows using all PocketMine commands and utilities"));
|
||||
|
||||
$broadcasts = self::registerPermission(new Permission(self::ROOT . ".broadcast", "Allows the user to receive all broadcast messages"), $parent);
|
||||
self::registerPermission(new Permission(self::ROOT . ".broadcast.admin", "Allows the user to receive administrative broadcasts", Permission::DEFAULT_OP), $broadcasts);
|
||||
self::registerPermission(new Permission(self::ROOT . ".broadcast.user", "Allows the user to receive user broadcasts", Permission::DEFAULT_TRUE), $broadcasts);
|
||||
$broadcasts->recalculatePermissibles();
|
||||
$operatorRoot = self::registerPermission(new Permission(self::ROOT_OPERATOR, "Grants all operator permissions"), [$parent]);
|
||||
$everyoneRoot = self::registerPermission(new Permission(self::ROOT_USER, "Grants all non-sensitive permissions that everyone gets by default"), [$operatorRoot]);
|
||||
|
||||
$commands = self::registerPermission(new Permission(self::ROOT . ".command", "Allows using all PocketMine commands"), $parent);
|
||||
$broadcastRoot = self::registerPermission(new Permission(self::ROOT . ".broadcast", "Allows the user to receive all broadcast messages"), [$parent]);
|
||||
|
||||
$whitelist = self::registerPermission(new Permission(self::ROOT . ".command.whitelist", "Allows the user to modify the server whitelist", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.add", "Allows the user to add a player to the server whitelist"), $whitelist);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.remove", "Allows the user to remove a player from the server whitelist"), $whitelist);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.reload", "Allows the user to reload the server whitelist"), $whitelist);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.enable", "Allows the user to enable the server whitelist"), $whitelist);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.disable", "Allows the user to disable the server whitelist"), $whitelist);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.list", "Allows the user to list all players on the server whitelist"), $whitelist);
|
||||
$whitelist->recalculatePermissibles();
|
||||
self::registerPermission(new Permission(self::ROOT . ".broadcast.admin", "Allows the user to receive administrative broadcasts"), [$operatorRoot, $broadcastRoot]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".broadcast.user", "Allows the user to receive user broadcasts"), [$everyoneRoot, $broadcastRoot]);
|
||||
|
||||
$ban = self::registerPermission(new Permission(self::ROOT . ".command.ban", "Allows the user to ban people", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.ban.player", "Allows the user to ban players"), $ban);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.ban.ip", "Allows the user to ban IP addresses"), $ban);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.ban.list", "Allows the user to list banned players"), $ban);
|
||||
$ban->recalculatePermissibles();
|
||||
//this allows using ALL commands if assigned, irrespective of what group the player is in
|
||||
$commandRoot = self::registerPermission(new Permission(self::ROOT . ".command", "Allows using all PocketMine commands"), [$parent]);
|
||||
$operatorCommand = [$commandRoot, $operatorRoot];
|
||||
$everyoneCommand = [$commandRoot, $everyoneRoot];
|
||||
|
||||
$unban = self::registerPermission(new Permission(self::ROOT . ".command.unban", "Allows the user to unban people", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.unban.player", "Allows the user to unban players"), $unban);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.unban.ip", "Allows the user to unban IP addresses"), $unban);
|
||||
$unban->recalculatePermissibles();
|
||||
$whitelist = self::registerPermission(new Permission(self::ROOT . ".command.whitelist", "Allows the user to modify the server whitelist"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.add", "Allows the user to add a player to the server whitelist"), [$whitelist]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.remove", "Allows the user to remove a player from the server whitelist"), [$whitelist]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.reload", "Allows the user to reload the server whitelist"), [$whitelist]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.enable", "Allows the user to enable the server whitelist"), [$whitelist]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.disable", "Allows the user to disable the server whitelist"), [$whitelist]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.whitelist.list", "Allows the user to list all players on the server whitelist"), [$whitelist]);
|
||||
|
||||
$op = self::registerPermission(new Permission(self::ROOT . ".command.op", "Allows the user to change operators", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.op.give", "Allows the user to give a player operator status"), $op);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.op.take", "Allows the user to take a player's operator status"), $op);
|
||||
$op->recalculatePermissibles();
|
||||
$ban = self::registerPermission(new Permission(self::ROOT . ".command.ban", "Allows the user to ban people"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.ban.player", "Allows the user to ban players"), [$ban]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.ban.ip", "Allows the user to ban IP addresses"), [$ban]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.ban.list", "Allows the user to list banned players"), [$ban]);
|
||||
|
||||
$save = self::registerPermission(new Permission(self::ROOT . ".command.save", "Allows the user to save the worlds", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.save.enable", "Allows the user to enable automatic saving"), $save);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.save.disable", "Allows the user to disable automatic saving"), $save);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.save.perform", "Allows the user to perform a manual save"), $save);
|
||||
$save->recalculatePermissibles();
|
||||
$unban = self::registerPermission(new Permission(self::ROOT . ".command.unban", "Allows the user to unban people"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.unban.player", "Allows the user to unban players"), [$unban]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.unban.ip", "Allows the user to unban IP addresses"), [$unban]);
|
||||
|
||||
$time = self::registerPermission(new Permission(self::ROOT . ".command.time", "Allows the user to alter the time", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.time.add", "Allows the user to fast-forward time"), $time);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.time.set", "Allows the user to change the time"), $time);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.time.start", "Allows the user to restart the time"), $time);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.time.stop", "Allows the user to stop the time"), $time);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.time.query", "Allows the user query the time"), $time);
|
||||
$time->recalculatePermissibles();
|
||||
$op = self::registerPermission(new Permission(self::ROOT . ".command.op", "Allows the user to change operators"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.op.give", "Allows the user to give a player operator status"), [$op]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.op.take", "Allows the user to take a player's operator status"), [$op]);
|
||||
|
||||
$kill = self::registerPermission(new Permission(self::ROOT . ".command.kill", "Allows the user to kill players", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.kill.self", "Allows the user to commit suicide", Permission::DEFAULT_TRUE), $kill);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.kill.other", "Allows the user to kill other players"), $kill);
|
||||
$kill->recalculatePermissibles();
|
||||
$save = self::registerPermission(new Permission(self::ROOT . ".command.save", "Allows the user to save the worlds"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.save.enable", "Allows the user to enable automatic saving"), [$save]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.save.disable", "Allows the user to disable automatic saving"), [$save]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.save.perform", "Allows the user to perform a manual save"), [$save]);
|
||||
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.me", "Allows the user to perform a chat action", Permission::DEFAULT_TRUE), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.tell", "Allows the user to privately message another player", Permission::DEFAULT_TRUE), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.say", "Allows the user to talk as the console", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.give", "Allows the user to give items to players", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.effect", "Allows the user to give/take potion effects", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.enchant", "Allows the user to enchant items", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.particle", "Allows the user to create particle effects", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.teleport", "Allows the user to teleport players", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.kick", "Allows the user to kick players", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.stop", "Allows the user to stop the server", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.list", "Allows the user to list all online players", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.help", "Allows the user to view the help menu", Permission::DEFAULT_TRUE), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.plugins", "Allows the user to view the list of plugins", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.version", "Allows the user to view the version of the server", Permission::DEFAULT_TRUE), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.gamemode", "Allows the user to change the gamemode of players", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.defaultgamemode", "Allows the user to change the default gamemode", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.seed", "Allows the user to view the seed of the world", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.status", "Allows the user to view the server performance", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.gc", "Allows the user to fire garbage collection tasks", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.dumpmemory", "Allows the user to dump memory contents", Permission::DEFAULT_FALSE), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.timings", "Allows the user to records timings for all plugin events", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.spawnpoint", "Allows the user to change player's spawnpoint", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.setworldspawn", "Allows the user to change the world spawn", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.transferserver", "Allows the user to transfer self to another server", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.title", "Allows the user to send a title to the specified player", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.difficulty", "Allows the user to change the game difficulty", Permission::DEFAULT_OP), $commands);
|
||||
$time = self::registerPermission(new Permission(self::ROOT . ".command.time", "Allows the user to alter the time"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.time.add", "Allows the user to fast-forward time"), [$time]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.time.set", "Allows the user to change the time"), [$time]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.time.start", "Allows the user to restart the time"), [$time]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.time.stop", "Allows the user to stop the time"), [$time]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.time.query", "Allows the user query the time"), [$time]);
|
||||
|
||||
$commands->recalculatePermissibles();
|
||||
$kill = self::registerPermission(new Permission(self::ROOT . ".command.kill", "Allows the user to kill players"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.kill.self", "Allows the user to commit suicide"), [$kill, $everyoneRoot]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.kill.other", "Allows the user to kill other players"), [$kill]);
|
||||
|
||||
$parent->recalculatePermissibles();
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.me", "Allows the user to perform a chat action"), $everyoneCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.tell", "Allows the user to privately message another player"), $everyoneCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.say", "Allows the user to talk as the console"), [$commandRoot, $operatorRoot]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.give", "Allows the user to give items to players"), [$commandRoot, $operatorRoot]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.effect", "Allows the user to give/take potion effects"), [$commandRoot, $operatorRoot]);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.enchant", "Allows the user to enchant items"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.particle", "Allows the user to create particle effects"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.teleport", "Allows the user to teleport players"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.kick", "Allows the user to kick players"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.stop", "Allows the user to stop the server"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.list", "Allows the user to list all online players"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.help", "Allows the user to view the help menu"), $everyoneCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.plugins", "Allows the user to view the list of plugins"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.version", "Allows the user to view the version of the server"), $everyoneCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.gamemode", "Allows the user to change the gamemode of players"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.defaultgamemode", "Allows the user to change the default gamemode"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.seed", "Allows the user to view the seed of the world"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.status", "Allows the user to view the server performance"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.gc", "Allows the user to fire garbage collection tasks"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.dumpmemory", "Allows the user to dump memory contents"), [$commandRoot]); //TODO: this should be exclusively granted to CONSOLE
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.timings", "Allows the user to records timings for all plugin events"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.spawnpoint", "Allows the user to change player's spawnpoint"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.setworldspawn", "Allows the user to change the world spawn"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.transferserver", "Allows the user to transfer self to another server"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.title", "Allows the user to send a title to the specified player"), $operatorCommand);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.difficulty", "Allows the user to change the game difficulty"), $operatorCommand);
|
||||
}
|
||||
}
|
||||
|
@ -27,9 +27,25 @@ use pocketmine\plugin\Plugin;
|
||||
|
||||
interface Permissible{
|
||||
|
||||
public function isOp() : bool;
|
||||
/**
|
||||
* Assigns a baseline permission to the permissible. This is **always** calculated before anything else, which means
|
||||
* that permissions set using addAttachment() will always override base permissions.
|
||||
* You probably don't want to use this if you're not assigning (denying) operator permissions.
|
||||
*
|
||||
* @internal
|
||||
* @see Permissible::addAttachment() for normal permission assignments
|
||||
* @param Permission|string $name
|
||||
*/
|
||||
public function setBasePermission($name, bool $grant) : void;
|
||||
|
||||
public function onOpStatusChange(bool $value) : void;
|
||||
/**
|
||||
* Unsets a baseline permission previously set. If it wasn't already set, this will have no effect.
|
||||
* Note that this might have different results than setting the permission to false.
|
||||
*
|
||||
* @internal
|
||||
* @param Permission|string $name
|
||||
*/
|
||||
public function unsetBasePermission($name) : void;
|
||||
|
||||
/**
|
||||
* Checks if this instance has a permission overridden
|
||||
|
@ -29,12 +29,17 @@ use pocketmine\timings\Timings;
|
||||
use function spl_object_id;
|
||||
|
||||
class PermissibleBase implements Permissible{
|
||||
/** @var bool */
|
||||
private $op;
|
||||
|
||||
/** @var Permissible|null */
|
||||
private $parent;
|
||||
|
||||
/**
|
||||
* @var bool[]
|
||||
* @phpstan-var array<string, bool>
|
||||
*/
|
||||
private $rootPermissions = [
|
||||
DefaultPermissions::ROOT_USER => true
|
||||
];
|
||||
|
||||
/** @var PermissionAttachment[] */
|
||||
private $attachments = [];
|
||||
|
||||
@ -43,7 +48,12 @@ class PermissibleBase implements Permissible{
|
||||
|
||||
public function __construct(?Permissible $permissible, bool $isOp){
|
||||
$this->parent = $permissible;
|
||||
$this->op = $isOp;
|
||||
|
||||
//TODO: we can't setBasePermission here directly due to bad architecture that causes recalculatePermissions to explode
|
||||
//so, this hack has to be done here to prevent permission recalculations until it's fixed...
|
||||
if($isOp){
|
||||
$this->rootPermissions[DefaultPermissions::ROOT_OPERATOR] = true;
|
||||
}
|
||||
//TODO: permissions need to be recalculated here, or inherited permissions won't work
|
||||
}
|
||||
|
||||
@ -51,12 +61,16 @@ class PermissibleBase implements Permissible{
|
||||
return $this->parent ?? $this;
|
||||
}
|
||||
|
||||
public function isOp() : bool{
|
||||
return $this->op;
|
||||
public function setBasePermission($name, bool $grant) : void{
|
||||
if($name instanceof Permission){
|
||||
$name = $name->getName();
|
||||
}
|
||||
$this->rootPermissions[$name] = $grant;
|
||||
$this->getRootPermissible()->recalculatePermissions();
|
||||
}
|
||||
|
||||
public function onOpStatusChange(bool $value) : void{
|
||||
$this->op = $value;
|
||||
public function unsetBasePermission($name) : void{
|
||||
unset($this->rootPermissions[$name instanceof Permission ? $name->getName() : $name]);
|
||||
$this->getRootPermissible()->recalculatePermissions();
|
||||
}
|
||||
|
||||
@ -117,14 +131,16 @@ class PermissibleBase implements Permissible{
|
||||
public function recalculatePermissions() : void{
|
||||
Timings::$permissibleCalculationTimer->startTiming();
|
||||
|
||||
$this->clearPermissions();
|
||||
$permManager = PermissionManager::getInstance();
|
||||
$defaults = $permManager->getDefaultPermissions($this->isOp());
|
||||
$permManager->subscribeToDefaultPerms($this->isOp(), $this->getRootPermissible());
|
||||
$permManager->unsubscribeFromAllPermissions($this->getRootPermissible());
|
||||
$this->permissions = [];
|
||||
|
||||
foreach($defaults as $perm){
|
||||
$name = $perm->getName();
|
||||
$this->permissions[$name] = new PermissionAttachmentInfo($this->getRootPermissible(), $name, null, true);
|
||||
foreach($this->rootPermissions as $name => $isGranted){
|
||||
$perm = $permManager->getPermission($name);
|
||||
if($perm === null){
|
||||
throw new \InvalidStateException("Unregistered root permission $name");
|
||||
}
|
||||
$this->permissions[$name] = new PermissionAttachmentInfo($this->getRootPermissible(), $name, null, $isGranted);
|
||||
$permManager->subscribeToPermission($name, $this->getRootPermissible());
|
||||
$this->calculateChildPermissions($perm->getChildren(), false, null);
|
||||
}
|
||||
@ -137,11 +153,7 @@ class PermissibleBase implements Permissible{
|
||||
}
|
||||
|
||||
public function clearPermissions() : void{
|
||||
$permManager = PermissionManager::getInstance();
|
||||
$permManager->unsubscribeFromAllPermissions($this->getRootPermissible());
|
||||
|
||||
$permManager->unsubscribeFromDefaultPerms(false, $this->getRootPermissible());
|
||||
$permManager->unsubscribeFromDefaultPerms(true, $this->getRootPermissible());
|
||||
PermissionManager::getInstance()->unsubscribeFromAllPermissions($this->getRootPermissible());
|
||||
|
||||
$this->permissions = [];
|
||||
}
|
||||
|
@ -30,12 +30,18 @@ trait PermissibleDelegateTrait{
|
||||
/** @var PermissibleBase */
|
||||
private $perm;
|
||||
|
||||
public function isOp() : bool{
|
||||
return $this->perm->isOp();
|
||||
/**
|
||||
* @param Permission|string $name
|
||||
*/
|
||||
public function setBasePermission($name, bool $value) : void{
|
||||
$this->perm->setBasePermission($name, $value);
|
||||
}
|
||||
|
||||
public function onOpStatusChange(bool $value) : void{
|
||||
$this->perm->onOpStatusChange($value);
|
||||
/**
|
||||
* @param Permission|string $name
|
||||
*/
|
||||
public function unsetBasePermission($name) : void{
|
||||
$this->perm->unsetBasePermission($name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -31,14 +31,6 @@ namespace pocketmine\permission;
|
||||
* Represents a permission
|
||||
*/
|
||||
class Permission{
|
||||
public const DEFAULT_OP = "op";
|
||||
public const DEFAULT_NOT_OP = "notop";
|
||||
public const DEFAULT_TRUE = "true";
|
||||
public const DEFAULT_FALSE = "false";
|
||||
|
||||
/** @var string */
|
||||
public static $DEFAULT_PERMISSION = self::DEFAULT_OP;
|
||||
|
||||
/** @var string */
|
||||
private $name;
|
||||
|
||||
@ -51,19 +43,15 @@ class Permission{
|
||||
*/
|
||||
private $children;
|
||||
|
||||
/** @var string */
|
||||
private $defaultValue;
|
||||
|
||||
/**
|
||||
* Creates a new Permission object to be attached to Permissible objects
|
||||
*
|
||||
* @param bool[] $children
|
||||
* @phpstan-param array<string, bool> $children
|
||||
*/
|
||||
public function __construct(string $name, ?string $description = null, ?string $defaultValue = null, array $children = []){
|
||||
public function __construct(string $name, ?string $description = null, array $children = []){
|
||||
$this->name = $name;
|
||||
$this->description = $description ?? "";
|
||||
$this->defaultValue = $defaultValue ?? self::$DEFAULT_PERMISSION;
|
||||
$this->children = $children;
|
||||
|
||||
$this->recalculatePermissibles();
|
||||
@ -81,17 +69,6 @@ class Permission{
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
public function getDefault() : string{
|
||||
return $this->defaultValue;
|
||||
}
|
||||
|
||||
public function setDefault(string $value) : void{
|
||||
if($value !== $this->defaultValue){
|
||||
$this->defaultValue = $value;
|
||||
$this->recalculatePermissibles();
|
||||
}
|
||||
}
|
||||
|
||||
public function getDescription() : string{
|
||||
return $this->description;
|
||||
}
|
||||
@ -110,8 +87,6 @@ class Permission{
|
||||
public function recalculatePermissibles() : void{
|
||||
$perms = $this->getPermissibles();
|
||||
|
||||
PermissionManager::getInstance()->recalculatePermissionDefaults($this);
|
||||
|
||||
foreach($perms as $p){
|
||||
$p->recalculatePermissions();
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\permission;
|
||||
|
||||
use pocketmine\timings\Timings;
|
||||
use function count;
|
||||
use function spl_object_id;
|
||||
|
||||
@ -41,16 +40,8 @@ class PermissionManager{
|
||||
|
||||
/** @var Permission[] */
|
||||
protected $permissions = [];
|
||||
/** @var Permission[] */
|
||||
protected $defaultPerms = [];
|
||||
/** @var Permission[] */
|
||||
protected $defaultPermsOp = [];
|
||||
/** @var Permissible[][] */
|
||||
protected $permSubs = [];
|
||||
/** @var Permissible[] */
|
||||
protected $defSubs = [];
|
||||
/** @var Permissible[] */
|
||||
protected $defSubsOp = [];
|
||||
|
||||
public function getPermission(string $name) : ?Permission{
|
||||
return $this->permissions[$name] ?? null;
|
||||
@ -59,7 +50,6 @@ class PermissionManager{
|
||||
public function addPermission(Permission $permission) : bool{
|
||||
if(!isset($this->permissions[$permission->getName()])){
|
||||
$this->permissions[$permission->getName()] = $permission;
|
||||
$this->calculatePermissionDefault($permission);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -78,45 +68,6 @@ class PermissionManager{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Permission[]
|
||||
*/
|
||||
public function getDefaultPermissions(bool $op) : array{
|
||||
if($op){
|
||||
return $this->defaultPermsOp;
|
||||
}else{
|
||||
return $this->defaultPerms;
|
||||
}
|
||||
}
|
||||
|
||||
public function recalculatePermissionDefaults(Permission $permission) : void{
|
||||
if(isset($this->permissions[$permission->getName()])){
|
||||
unset($this->defaultPermsOp[$permission->getName()]);
|
||||
unset($this->defaultPerms[$permission->getName()]);
|
||||
$this->calculatePermissionDefault($permission);
|
||||
}
|
||||
}
|
||||
|
||||
private function calculatePermissionDefault(Permission $permission) : void{
|
||||
Timings::$permissionDefaultTimer->startTiming();
|
||||
if($permission->getDefault() === Permission::DEFAULT_OP or $permission->getDefault() === Permission::DEFAULT_TRUE){
|
||||
$this->defaultPermsOp[$permission->getName()] = $permission;
|
||||
$this->dirtyPermissibles(true);
|
||||
}
|
||||
|
||||
if($permission->getDefault() === Permission::DEFAULT_NOT_OP or $permission->getDefault() === Permission::DEFAULT_TRUE){
|
||||
$this->defaultPerms[$permission->getName()] = $permission;
|
||||
$this->dirtyPermissibles(false);
|
||||
}
|
||||
Timings::$permissionDefaultTimer->stopTiming();
|
||||
}
|
||||
|
||||
private function dirtyPermissibles(bool $op) : void{
|
||||
foreach($this->getDefaultPermSubscriptions($op) as $p){
|
||||
$p->recalculatePermissions();
|
||||
}
|
||||
}
|
||||
|
||||
public function subscribeToPermission(string $permission, Permissible $permissible) : void{
|
||||
if(!isset($this->permSubs[$permission])){
|
||||
$this->permSubs[$permission] = [];
|
||||
@ -149,33 +100,6 @@ class PermissionManager{
|
||||
return $this->permSubs[$permission] ?? [];
|
||||
}
|
||||
|
||||
public function subscribeToDefaultPerms(bool $op, Permissible $permissible) : void{
|
||||
if($op){
|
||||
$this->defSubsOp[spl_object_id($permissible)] = $permissible;
|
||||
}else{
|
||||
$this->defSubs[spl_object_id($permissible)] = $permissible;
|
||||
}
|
||||
}
|
||||
|
||||
public function unsubscribeFromDefaultPerms(bool $op, Permissible $permissible) : void{
|
||||
if($op){
|
||||
unset($this->defSubsOp[spl_object_id($permissible)]);
|
||||
}else{
|
||||
unset($this->defSubs[spl_object_id($permissible)]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Permissible[]
|
||||
*/
|
||||
public function getDefaultPermSubscriptions(bool $op) : array{
|
||||
if($op){
|
||||
return $this->defSubsOp;
|
||||
}
|
||||
|
||||
return $this->defSubs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Permission[]
|
||||
*/
|
||||
@ -185,7 +109,5 @@ class PermissionManager{
|
||||
|
||||
public function clearPermissions() : void{
|
||||
$this->permissions = [];
|
||||
$this->defaultPerms = [];
|
||||
$this->defaultPermsOp = [];
|
||||
}
|
||||
}
|
||||
|
@ -23,31 +23,34 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\permission;
|
||||
|
||||
use function count;
|
||||
use function is_array;
|
||||
use function is_bool;
|
||||
use function ksort;
|
||||
use function strtolower;
|
||||
|
||||
class PermissionParser{
|
||||
|
||||
public const DEFAULT_OP = "op";
|
||||
public const DEFAULT_NOT_OP = "notop";
|
||||
public const DEFAULT_TRUE = "true";
|
||||
public const DEFAULT_FALSE = "false";
|
||||
|
||||
public const DEFAULT_STRING_MAP = [
|
||||
"op" => Permission::DEFAULT_OP,
|
||||
"isop" => Permission::DEFAULT_OP,
|
||||
"operator" => Permission::DEFAULT_OP,
|
||||
"isoperator" => Permission::DEFAULT_OP,
|
||||
"admin" => Permission::DEFAULT_OP,
|
||||
"isadmin" => Permission::DEFAULT_OP,
|
||||
"op" => self::DEFAULT_OP,
|
||||
"isop" => self::DEFAULT_OP,
|
||||
"operator" => self::DEFAULT_OP,
|
||||
"isoperator" => self::DEFAULT_OP,
|
||||
"admin" => self::DEFAULT_OP,
|
||||
"isadmin" => self::DEFAULT_OP,
|
||||
|
||||
"!op" => Permission::DEFAULT_NOT_OP,
|
||||
"notop" => Permission::DEFAULT_NOT_OP,
|
||||
"!operator" => Permission::DEFAULT_NOT_OP,
|
||||
"notoperator" => Permission::DEFAULT_NOT_OP,
|
||||
"!admin" => Permission::DEFAULT_NOT_OP,
|
||||
"notadmin" => Permission::DEFAULT_NOT_OP,
|
||||
"!op" => self::DEFAULT_NOT_OP,
|
||||
"notop" => self::DEFAULT_NOT_OP,
|
||||
"!operator" => self::DEFAULT_NOT_OP,
|
||||
"notoperator" => self::DEFAULT_NOT_OP,
|
||||
"!admin" => self::DEFAULT_NOT_OP,
|
||||
"notadmin" => self::DEFAULT_NOT_OP,
|
||||
|
||||
"true" => Permission::DEFAULT_TRUE,
|
||||
"false" => Permission::DEFAULT_FALSE,
|
||||
"true" => self::DEFAULT_TRUE,
|
||||
"false" => self::DEFAULT_FALSE,
|
||||
];
|
||||
|
||||
/**
|
||||
@ -75,25 +78,27 @@ class PermissionParser{
|
||||
* @param mixed[][] $data
|
||||
* @phpstan-param array<string, array<string, mixed>> $data
|
||||
*
|
||||
* @return Permission[]
|
||||
* @return Permission[][]
|
||||
* @phpstan-return array<string, list<Permission>>
|
||||
*/
|
||||
public static function loadPermissions(array $data, string $default = Permission::DEFAULT_OP) : array{
|
||||
public static function loadPermissions(array $data, string $default = self::DEFAULT_OP) : array{
|
||||
$result = [];
|
||||
foreach($data as $key => $entry){
|
||||
$result[] = self::loadPermission($key, $entry, $default, $result);
|
||||
self::loadPermission($key, $entry, $default, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $data
|
||||
* @param Permission[] $output reference parameter
|
||||
* @param mixed[] $data
|
||||
* @param Permission[][] $output reference parameter
|
||||
* @phpstan-param array<string, mixed> $data
|
||||
* @phpstan-param array<string, list<Permission>> $output
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function loadPermission(string $name, array $data, string $default = Permission::DEFAULT_OP, array &$output = []) : Permission{
|
||||
public static function loadPermission(string $name, array $data, string $default = self::DEFAULT_OP, array &$output = []) : void{
|
||||
$desc = null;
|
||||
$children = [];
|
||||
if(isset($data["default"])){
|
||||
@ -104,7 +109,7 @@ class PermissionParser{
|
||||
if(is_array($data["children"])){
|
||||
foreach($data["children"] as $k => $v){
|
||||
if(is_array($v)){
|
||||
$output[] = self::loadPermission($k, $v, $default, $output);
|
||||
self::loadPermission($k, $v, $default, $output);
|
||||
}
|
||||
$children[$k] = true;
|
||||
}
|
||||
@ -117,6 +122,6 @@ class PermissionParser{
|
||||
$desc = $data["description"];
|
||||
}
|
||||
|
||||
return new Permission($name, $desc, $default, $children);
|
||||
$output[$default][] = new Permission($name, $desc, $children);
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,10 @@ class PluginDescription{
|
||||
/** @var PluginEnableOrder */
|
||||
private $order;
|
||||
|
||||
/** @var Permission[] */
|
||||
/**
|
||||
* @var Permission[][]
|
||||
* @phpstan-var array<string, list<Permission>>
|
||||
*/
|
||||
private $permissions = [];
|
||||
|
||||
/**
|
||||
@ -286,7 +289,8 @@ class PluginDescription{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Permission[]
|
||||
* @return Permission[][]
|
||||
* @phpstan-return array<string, list<Permission>>
|
||||
*/
|
||||
public function getPermissions() : array{
|
||||
return $this->permissions;
|
||||
|
@ -31,7 +31,9 @@ use pocketmine\event\plugin\PluginDisableEvent;
|
||||
use pocketmine\event\plugin\PluginEnableEvent;
|
||||
use pocketmine\event\RegisteredListener;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\permission\DefaultPermissions;
|
||||
use pocketmine\permission\PermissionManager;
|
||||
use pocketmine\permission\PermissionParser;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\timings\TimingsHandler;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
@ -162,8 +164,32 @@ class PluginManager{
|
||||
}
|
||||
|
||||
$permManager = PermissionManager::getInstance();
|
||||
foreach($description->getPermissions() as $perm){
|
||||
$permManager->addPermission($perm);
|
||||
$opRoot = $permManager->getPermission(DefaultPermissions::ROOT_OPERATOR);
|
||||
$everyoneRoot = $permManager->getPermission(DefaultPermissions::ROOT_USER);
|
||||
foreach($description->getPermissions() as $default => $perms){
|
||||
foreach($perms as $perm){
|
||||
$permManager->addPermission($perm);
|
||||
switch($default){
|
||||
case PermissionParser::DEFAULT_TRUE:
|
||||
$everyoneRoot->addChild($perm->getName(), true);
|
||||
break;
|
||||
case PermissionParser::DEFAULT_OP:
|
||||
$opRoot->addChild($perm->getName(), true);
|
||||
break;
|
||||
case PermissionParser::DEFAULT_NOT_OP:
|
||||
//TODO: I don't think anyone uses this, and it currently relies on some magic inside PermissibleBase
|
||||
//to ensure that the operator override actually applies.
|
||||
//Explore getting rid of this.
|
||||
//The following grants this permission to anyone who has the "everyone" root permission.
|
||||
//However, if the operator root node (which has higher priority) is present, the
|
||||
//permission will be denied instead.
|
||||
$everyoneRoot->addChild($perm->getName(), true);
|
||||
$opRoot->addChild($perm->getName(), false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -445,6 +445,11 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/plugin/PluginBase.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method addChild\\(\\) on pocketmine\\\\permission\\\\Permission\\|null\\.$#"
|
||||
count: 4
|
||||
path: ../../../src/plugin/PluginManager.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$closure of static method pocketmine\\\\utils\\\\Utils\\:\\:getNiceClosureName\\(\\) expects Closure, Closure\\|null given\\.$#"
|
||||
count: 2
|
||||
|
Loading…
x
Reference in New Issue
Block a user