1. The forums will be archived and moved to a read only mode in about 2 weeks (mid march).

Solved Permission wildcards

Discussion in 'Development' started by Michel5F30, May 1, 2018.

  1. Michel5F30

    Michel5F30 Silverfish

    Messages:
    22
    Hi there,

    i just wrote a pretty huge permission management plugin (including groups, inheritances, rank ladders, user & group prefixes, ...) and i'm wondering about how to handle wildcards (permissions containing *).

    As far as i know those wildcards were a bukkit feature and part of craftbukkit code (since i didn't develop a permissions plugin in bukkit, i'm not sure)?
    Does PMMP support a similar permission wildcard feature?
    If not, might there be an option to implement a wildcard mechanism plugin-side (i don't see any since you need to predict all possible sub-permissions)?

    Btw. i'm thinking of releasing this plugin to publicity. Is a GitHub account really necessary to release things on poggit? I never used GitHub for prior software development and i don't really want to start with it now only because of poggit.

    Greetings,
    Michel5F30
     
  2. Primus

    Primus Zombie Pigman

    Messages:
    749
    Reinvent the wheel? Just take a look on how PurePerms did it. To be honest, I don't quite get what You're asking for, permissions are handled by PocketMine. You are simply referring to permission that has child nodes (nodes? childs? can't remember), and when you give player that permission, all of it's childrens will be granted aswell.

    Oh yeah, tip: Read the source of the API you are writing for.

    No more spoon feeding. I'm sure You'll find your answer there.
     
    Last edited: May 2, 2018
  3. Thunder33345

    Thunder33345 Moderator Staff Member

    Messages:
    2,137
    GitHub:
    Thunder33345
    theres nothing wrong with reinventing the triangle wheel to make it more rounder
    tip for OP: pureperm just try to get child permission nodes of say a.b if it's a wildcard it sets all the child note to a positive
     
    SOFe, HimbeersaftLP and Muqsit like this.
  4. Michel5F30

    Michel5F30 Silverfish

    Messages:
    22
    Of course they are... but by looking into the sourcecode of "pocketmine\permission\PermissibleBase", it doesn't look like PM is using any of this "pocketmine\permission\Permission" child mechanism.

    I developed my plugin by this guide, the PM doxygen and looking through the PM sourcecode. I didn't find many things regarding childs. PM only seems to save an array of string (the permission name) and boolean (the permission value TRUE / FALSE).

    Maybe i miss the obvious... i'll try some things, starting with this:
    EDIT: "pocketmine\permission\PermissibleBase#recalculatePermissions" does some child stuff, so it might work out.
    EDIT2: It does not. Final solution see below.
     
    Last edited: May 3, 2018
    SOFe and Primus like this.
  5. Thunder33345

    Thunder33345 Moderator Staff Member

    Messages:
    2,137
    GitHub:
    Thunder33345
  6. Michel5F30

    Michel5F30 Silverfish

    Messages:
    22
    I encountered a problem.
    By trying to get all registered permissions like using "pocketmine\plugin\PluginManager#getPermissions" or similar, a permission needs to be registered.
    Most plugins are just using "pocketmine\Player#hasPermission" to check a permission by a string, which doesn't need this permission to be registered, so there is no possible option to find it out?

    Example code of any plugin (which should be affected by my permission plugin):
    PHP:
    public function onChat(PlayerChatEvent $event) {
      if (
    $event->getPlayer()->hasPermission("test.a")) $event->getPlayer()->sendMessage("You have got \"test.a\"");
      else 
    $event->getPlayer()->sendMessage("You haven't got \"test.a\"");
    }
    Since the permission "test.a" is only given within the sourcecode of any other plugin, it's not a registered permission, so i can't receive it by "pocketmine\plugin\PluginManager#getPermissions", so i can't set it as TRUE, if the player has "test.*".

    @Primus do you get my problem now?
    @Thunder33345 thanks a lot so far.

    Part of my permissions plugin:
    PHP:
    $this->main->getServer()->getPluginManager()->getPermissions();
    // does NOT return "test.a", so how may I find out about "test.a" and set it as TRUE, when the player has "test.*"
     
    Last edited: May 2, 2018
  7. Thunder33345

    Thunder33345 Moderator Staff Member

    Messages:
    2,137
    GitHub:
    Thunder33345
    if they didnt include it in plugins.yml there's not much that can be done
     
  8. Michel5F30

    Michel5F30 Silverfish

    Messages:
    22
    I have had a look into the sourcecode of Bukkit's PermissionsEx. It seems to use the only possible option, replacing the players PermissibleBase by their own class which extends PermissibleBase. This gives the opportunity to hook into the #hasPermission command and execute a custom permission evaluation.

    This basically might be possible in pocketmine, too.
    Creating your own class which extends "pocketmine\permission\PermissibleBase" and make your own permission evaluation, which supports wildcards recognized by strings split by dot.

    I just have no idea, if there is something like java reflections for PHP.
    You would need to replace the private class field "\pocketmine\Player#perm" by our own classes instance...
    Not sure if it is worth the effort.

    EDIT: o_O PHP reflection is a real thing... http://php.net/manual/de/class.reflection.php
    EDIT2: ;) Just tested reflections... it really seems to be possible like described above.
     
    Last edited: May 3, 2018
  9. Michel5F30

    Michel5F30 Silverfish

    Messages:
    22
    I'm pretty sure to get it handled liked described before.
    For who is interested, this is my approach:
    PHP:
    namespace michel5f30\permission;
    /*
     * ... some imports ...
     */
    class Main extends PluginBase {
      
    /*
       * ... some other variables ...
       */
      
    private $permProp;
      public function 
    onLoad() {
        
    $this->getLogger()->info("Hooking into pocketmine...");
        
    $playerClass = new \ReflectionClass("\pocketmine\Player");
        
    $this->permProp $playerClass->getProperty("perm");
        
    $this->permProp->setAccessible(true);
      }
      public function 
    invokePerms(Player $player) {
        
    $this->permProp->setValue($player, new PermissibleExtension($player));
      }
      
    /*
       * ... some other code ...
       */
    }
    PHP:
    namespace michel5f30\permission;
    use 
    pocketmine\permission\PermissibleBase;
    class 
    PermissibleExtension extends PermissibleBase {
      
    /*
       * here Comes my own #hasPermission method
       *  > which needs to do exactly the same than "pocketmine\permission\PermissibleBase#hasPermission"
       *  > plus evaluating wildcards
       */
    }
    PHP:
    namespace michel5f30\permission;
    /*
     * ... some imports ...
     */
    class Events implements Listener {
      public function 
    onPreLogin(PlayerPreLoginEvent $event) {
        
    $this->main->invokePerms($event->getPlayer()); // main is my plugin instance passed by constructor
      
    }
      
    /*
       * ... some other code ...
       */
    }
    I actually did not.
    I found it at https://github.com/PEXPlugins/PermissionsEx.
    I'll mark the thread as solved until i might encounter new problems.
    And yes, this will exclude all entities and consolesenders from using wildcards (players only), but i don't care about them (yet).
     
    Last edited: May 3, 2018
  10. Thunder33345

    Thunder33345 Moderator Staff Member

    Messages:
    2,137
    GitHub:
    Thunder33345
    not a bad fix, good job, looking forward to the release
     
  11. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    Protip: DevTools has a command to check permisisons.
     
  12. Michel5F30

    Michel5F30 Silverfish

    Messages:
    22
    Thanks for the hint. But i'm pretty sure it will only find registered permissions by the plugin.yml of each plugin?

    The hard thing is to handle not registered permissions like in the PHP example at #6, just checked by #hasPermission. Most people doesn't register their permissions in the plugin.yml (at least i guess so). And i want unregistered permissions to be handled.

    Btw. the code above is approved as working:
    PHP:
    namespace michel5f30\permission;
    use 
    pocketmine\permission\PermissibleBase;
    use 
    pocketmine\permission\Permission;
    use 
    pocketmine\permission\ServerOperator;
    class 
    PermissibleExtension extends PermissibleBase {
      private 
    $main;
      public function 
    __construct(Main $pluginServerOperator $opable) {
        
    $this->main $plugin;
        
    parent::__construct($opable);
      }
      public function 
    hasPermission($name) : bool {
        if(
    $name instanceof Permission$this->main->getLogger()->info("Checking for " $name->getName());
        else 
    $this->main->getLogger()->info("Checking for " $name);
        return 
    parent::hasPermission($name);
      }
    }
    Code:
    [18:29:48] [Server thread/INFO]: [myPermission] Checking for test.a
    [18:29:48] [Server thread/INFO]: [myPermission] Checking for test.b
    [18:29:48] [Server thread/INFO]: [myPermission] Checking for test.c
    [18:29:48] [Server thread/INFO]: [myPermission] Checking for test.d
    [18:29:48] [Server thread/INFO]: [myPermission] Checking for test.e
    [18:29:48] [Server thread/INFO]: [myPermission] Checking for test.f
    [18:29:48] [Server thread/INFO]: [myPermission] Checking for test.g
    EDIT: I might implement a PlayerPermissionCheckEvent...:cool:
     
  13. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    Actually plugins should register the permissions in plugin.yml. If they do not, they have a problem. Maybe we should check it in the hasPermission() call...
     
  14. Michel5F30

    Michel5F30 Silverfish

    Messages:
    22
    While my bukkit times i mostly did not register them. And i don't know why i should now... #hasPermission(string) works flawlessly.

    Ok, maybe registering the permissions you're checking for might be a more safer software structure... but writing this permission YAML really is annoying work.

    I would recommend to register not registered permissions when they are checked for. This would make permissions inside of the plugin.yml superfluous?

    EDIT: Of course an administrator using a plugin needs to know all permissions in detail. This is why a proper documentation is necessary at the download page. But i don't know any administrator, who reads the plugin.yml when he/she searches a permission.
     
    Primus likes this.
  15. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    The permissions API was developed single-handedly by @shoghicp based on Bukkit's permissions system, and after that, remained the least touched part of the software because of the unclear aims of what we really want.

    Permissions are supposed to be registered if they are to be listed in a permissions manager.
    The permissions API is very poorly documented, after all... (Just as everything else @shoghicp developed in the first few months of core-rewrite)

    I don't think dynamically registering permissions would be helpful. Permission plugins just can't rely on these dynamic values if they scan them at startup.
     
  16. Primus

    Primus Zombie Pigman

    Messages:
    749
    It has never (maybe not 'never' but in most cases - usually) caused an issue. Can you give any example situation from user perspective?
     
  17. Michel5F30

    Michel5F30 Silverfish

    Messages:
    22
    What exactly has never caused an issue and what situation you want a example for?
    I pointed out several things in the post you quoted.
     
  18. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    If you could document it in the download page, why don't you just document it in the plugin.yml and link users to the plugin.yml in the download page(+_+)
     
  19. Michel5F30

    Michel5F30 Silverfish

    Messages:
    22
    That... would be too simple i guess. I'm quite surprised, that i actually never thought of that...

    Anyway, there always will be plugins checking for permissions without registring them (except pmmp would check it while #hasPermission is executed and disables the calling plugin or throws an exception, which i wouldn't like i guess).
    So this is why i want to hook into PermissibleBase to be able to handle wildcards on not registered permissions (btw. i'm still not sure how i will do that since i won't iterate over all permissions due to performance reasons).
     
  20. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    I am thinking about rewriting the permissions system. The hasPermission() layer will be backward-compatible, but it will make sure the permission was registered. It is really a mistake that it wasn't.
     
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.