Arachne / Security

Authentication and authorization for Nette framework. Deals with cases that are difficult to implement with nette/security.
MIT License
2 stars 7 forks source link

Can't make example setup working #1

Closed foxycode closed 7 years ago

foxycode commented 7 years ago

I read article https://pehapkari.cz/blog/2017/08/21/arachne-security-simplified-authorizator-and-fixed-acl-callbacks/ and wanted to test your lib, but can't get it working. It will return error:

Interface Arachne\Security\Authorization\AuthorizatorInterface used in service 'admin.authorizator' must have just one non-static method create() or get().

config.neon

extensions:
    arachne.serviceCollections: Arachne\ServiceCollections\DI\ServiceCollectionsExtension
    arachne.security: Arachne\Security\DI\SecurityExtension

arachne.security:
    firewalls:
        admin: App\Libs\Security\AdminFirewall

services:
    admin.authorizator:
        implement: Arachne\Security\Authorization\AuthorizatorInterface
        factory: App\Libs\Security\AuthorizatorFactory::create
        tags:
            arachne.security.authorizator: admin
    admin.identityValidator:
        class: App\Libs\Security\AdminIdentityValidator
        tags:
            arachne.security.identityValidator: admin

AdminFirewall.php

<?php

declare(strict_types=1);

namespace App\Libs\Security;

use Arachne\Security\Authentication\Firewall;

final class AdminFirewall extends Firewall
{
}

AdminIdentityValidator.php

<?php

declare(strict_types=1);

namespace App\Libs\Security;

use App\Model\Entities\User;
use Arachne\Security\Authentication\IdentityValidatorInterface;
use Kdyby\Doctrine\EntityManager;
use Nette\Security\Identity;
use Nette\Security\IIdentity;

final class AdminIdentityValidator implements IdentityValidatorInterface
{
    /**
     * @var EntityManager
     */
    private $entityManager;

    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function validateIdentity(IIdentity $identity): ?IIdentity
    {
        $user = $this->entityManager->getRepository(User::class)->find($identity->getId());

        if (!$user) {
            return NULL;
        }

        return new Identity(
            $user->userId,
            $user->roles,
            [
                'login' => $user->login,
                'name' => $user->name,
            ]
        );
    }
}

AuthroizationFactory.php

<?php

declare(strict_types=1);

namespace App\Libs\Security;

use Arachne\Security\Authorization\AuthorizatorInterface;
use Arachne\Security\Authorization\Permission;
use Arachne\Security\Authorization\PermissionAuthorizator;

final class AuthorizatorFactory
{
    /**
     * @var AdminFirewall
     */
    private $firewall;

    public function __construct(AdminFirewall $adminFirewall)
    {
        $this->firewall = $adminFirewall;
    }

    public function create(): AuthorizatorInterface
    {
        $permission = new Permission;

        $permission->addRole('admin');

        $permission->addResource('datacenter');
        $permission->addResource('ipAddress');
        $permission->addResource('ipRange');
        $permission->addResource('macAddress');

        $permission->allow('admin', ['datacenter', 'ipAddress', 'ipRange', 'macAddress'], 'view');

        return new PermissionAuthorizator($this->firewall, $permission);
    }
}

Am I doing something wrong?

enumag commented 7 years ago

Looks like I have made a mistake when writing the example configuration. Try removing the implement: Arachne\Security\Authorization\AuthorizatorInterface line in config, that should help.

foxycode commented 7 years ago

Working, thanks.

enumag commented 7 years ago

Thanks, I'll fix it in the article. Let me know if you find anything else that it unclear.