How to set up Authorisation Factory from database?

8 months ago

+
0
-

I am reading the docs at https://doc.nette.org/…cess-control to create roles from a database.

I am getting error when connecting to database.

Error
Using $this when not in object context

Of course, create() is a static function, and $this cannot be used, but are roles loaded from database here?
If $this is replaced with self:: then the error will be that create() is not callable.
How do I load the roles from the database correctly?

This is the code..

<?php
declare(strict_types=1);

namespace App\Model;

class AuthorizationFactory
{
        private $context;

        public function __construct( Nette\Database\Context $context )
        {
                $this->context = $context;
        }


        public static function create(): \Nette\Security\Permission
        {
                $acl = new \Nette\Security\Permission;

                // if we want, we can load roles from database
                $roles = $this->context->table('user_group_role');

                $acl->addRole('admin');
                $acl->addRole('guest');

                $acl->addResource('backend');

                $acl->allow('admin', 'backend');
                $acl->deny('guest', 'backend');

                // example A: role admin has lower weight than role guest
                $acl->addRole('john', ['admin', 'guest']);
                $acl->isAllowed('john', 'backend'); // false

                // example B: role admin has greater weight than role guest
                $acl->addRole('mary', ['guest', 'admin']);
                $acl->isAllowed('mary', 'backend'); // true

                return $acl;
        }
}
?>

8 months ago

n3t
Member | 28
+
+1
-

You cannot use $this in static method (there is no object, so no $this), just let DI to inject proper context for you

class AuthorizationFactory
{
        public static function create(\Nette\Database\Context $context): \Nette\Security\Permission
        {
                ...
        }
}
?>

8 months ago

CZechBoY
Member | 3588
+
0
-

or if you want class, then just remove static keyword from method definition. and show us how you use this service and how you define it in config.

8 months ago

+
0
-

If I remove the static keyword, the error is

Deprecated
Non-static method App\Model\AuthorizationFactory::create() should not be called statically

So, I guess it is called statically internally.

8 months ago

n3t
Member | 28
+
0
-

It is called statically because of your config, as CzechBoy mentioned. In your config.neon (or any configuration file you use) you have propably something like this:

services:
	authorizator: App\Scadi\Authorizator::create

This means to get autorizator Nette will call this static method. If you want to use class you will have to change your config and Authorizator to reflect this. Or use approach I mentioned and you are done.

8 months ago

CZechBoY
Member | 3588
+
0
-

Register that class as service and then create authorizer from that service.

services:
  authorizatorFactory: App\Security\AuthorizatorFactory
  authorizator: @authorizatorFactory::createAuthorizator