Podivná chyba s ACL pri overovaní v template

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Gavrilo
Člen | 46
+
0
-

Ahojte,

po nekonečných hodinách trápenia by som vás vážne chcel poprosiť o pomoc. Tvorím dynamické ACL ale vznikol mi dosť zvláštny problém.

AuthorizatorFactory:

<?php
namespace App\Security;

use App\Model\PermissionsManager;
use Nette;
use Nette\Security\Permission;

/**
 * @package App\Security
 */
class AuthorizatorFactory extends Nette\Object
{
    /**
     * Konstanty role
     */
    const ROLE_GUEST = 'guest';
    const ROLE_USER = 'user';

    /** @var PermissionsManager */
    public $permissionsManager;

    /**
     * AuthorizatorFactory constructor.
     * @param PermissionsManager $permissionsManager Automaticky injektovaná instace triedy modelu pre prácu s právami.
     */
    public function __construct(PermissionsManager $permissionsManager)
    {
        $this->permissionsManager = $permissionsManager;
    }

    /**
     * @return Permission
     */
    public function create()
    {
        $acl = new Permission;

        $roles = $this->permissionsManager->getRoles();

        /**
         * Roles
         */
        $acl->addRole(self::ROLE_GUEST);
        $acl->addRole(self::ROLE_USER, self::ROLE_GUEST);
        foreach ($roles as $role) {
            $acl->addRole($role->role, self::ROLE_USER);
        }

        /**
         * Resoures
         */
        /* Admin Module Main */
        $acl->addResource('Admin');
        $acl->addResource('Admin:News', 'Admin');
        $acl->addResource('Admin:Contact', 'Admin');
        $acl->addResource('Admin:Forum', 'Admin');
        $acl->addResource('Admin:Servers', 'Admin');
        $acl->addResource('Admin:Homepage', 'Admin');

        /* Front Module Main */
        $acl->addResource('Front');
        $acl->addResource('Front:News', 'Front');
        $acl->addResource('Front:Homepage', 'Front');

        /**
         * Permissions
         */
        $acl->allow(self::ROLE_GUEST, 'Front');

        foreach ($roles as $perm) {
            $acl->allow($perm->role, explode(",", $perm->resource), explode(",", $perm->allow));
        }

        return $acl;
    }

}

BasePresenter:

/**
     * @param $element
     * @throws ForbiddenRequestException
     */
    public function checkRequirements($element)
    {
        $secured = $element->hasAnnotation('Secured');
        $resource = $this->name;

        if ($this->action == 'default') {
            $action = "read";
        } else {
            $action = $this->action;
        }
        if ($secured == TRUE) {
            if (!$this->user->isAllowed($resource, $action)) {
                throw new ForbiddenRequestException();
            }
        }

    }

NewsPresenter

<?php

namespace App\FrontModule\Presenters;

use App\Model\NewsManager;
use Nette\Application\BadRequestException;
use Nette\Application\UI\Form;
use Nette\Security\Identity;
use Tracy\Debugger;


/**
 * Class NewsPresenter
 * @Secured
 * @package App\FrontModule\Presenters
 * @author  Dominik Gavrecký <dominikgavrecky@icloud.com>
 * Presenter/Model na správu XXX
 */
class NewsPresenter extends BasePresenter
{
...

A teraz k popisu môjho problému. Snažím sa hodiť do template Default podmienku ktorá by mala zabezpečiť to že ak má užívateľ práva na edit alebo delete tak zobrazí odkaz, ale prejde len prvá podmienka druhá je síce TRUE (súdim podľa dumpu) ale vždy je TRUE aj ak ju daná rola nemá priradenú. V permissionsManager mám len klasický fetchAll().

{if $user->isLoggedIn()}
        {if $user->isAllowed('Front:News', 'edit') == TRUE}
                <a href="#"><i class="fa fa-pencil"></i>Upraviť</a>
        {/if}

        {if $user->isAllowed('Front:News', 'delete') == TRUE}
           <a href=""><i class="fa fa-times"></i>Vymazať</a>
       {/if}
{/if}
David Matějka
Moderator | 6445
+
0
-

tim $acl->allow(self::ROLE_GUEST, 'Front'); si povolil guestovi (a i userum, ktery od nej dedi) jakoukoliv akci na Front resource (a od toho Front ti dedi i Front:News)

congi
Člen | 2
+
0
-

Gavrilo napsal(a):

Tvorím dynamické ACL …

Ahojte,

som začiatočnik s Nette frameworkom, a pri rožšírovaní webu by som chcel užívateľom priradiť rôzne role. Prechádzal som rôzne tutoriály, či už tie čo sú v nette dokumentaci (https://doc.nette.org/…thentication), ale aj iné na internete, no pri podkapitole „Autorizace – overovanie oprávnení užívateľov“ som sa zasekol.

1. Vážne, to čo spomínal Gavrilo sú dynamické ACL?

  • dynamické ACL by sa nemali načítať z DB?

2. Mohol by niekto pridať stručný kód alebo poradiť mi, ako rozšíriť môj projekt:
a) aby role boli definované napr. v „AuthorizatorFactory“, a ako sa potom v presentery dotazovať či prihlasený užívateľ má opravnenie pridávať nové príspevky
b) aby sa role načítali z DB. Stačí napr. aby admin mohol pridávať nové príspevky a guest si ich mohol len zobraziť.

v DB budu 2 tabulky napr. takto

1. users s atributmi
id, login, id_role
1, usr1, 1
2, adm1, 2

2. role s atributmi
id, role , resource, action
1, guest, posts , view
2, admin, posts , create

Ďakujem, za každú radu.

Editoval congi (14. 11. 2017 19:28)

jura2.0
Člen | 8
+
+1
-

a)
napiš si config acl.neon

services:
acl:
create: Nette\Security\Permission
setup:
#Roles
- addRole(‚guest‘)
- addRole(‚admin‘)
#Resources
- addResource(‚article‘)
- addResource(‚comment‘)
#ACL
- allow(‚admin‘) # allow all
- allow(‚guest‘, [‚article‘, ‚comment‘], ‚view‘)

který pak vložíš do config.neon, abys tam neměl zbytečný bordel

includes
acl.neon

v presenterech oprávnění testuješ třeba takto

if(!$this->getUser()->isAllowed(‚article‘, ‚add‘)) {
$this->flashMessage(„Nemáš dostatečné oprávnění“);
$this->redirect(self::GTFO);
}
$this->add();

a v latte třeba takto

{if $user->isAllowed(‚article‘, ‚add‘)}
<a n:href=„:Article:add“>Přidat příspěvek</a>
 {/if}

b) je určitě více způsobů, ale tutoriál psát nebudu. Na netu určitě nějaké jsou, nebo se můžeš inspirovat z dřívějších vláken z tohoto fóra a napsat si vlastní, záleží totiž na množství práv, uživatelů apod.

Editoval jura2.0 (14. 11. 2017 21:23)

congi
Člen | 2
+
0
-

Ďakujem.

a) Vyriešené – už tomu rozumiem.

b) Skúsim nájsť niečo. Písal som tu hlavne preto, že prípadné riešenie by som považoval za funkčné a bezpečné. Vygooglene riešenie nemusí byť OK.