ACL – ROLE isAllowed vrací false

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

Zdravím,

stále zápasím s ACL.

Uživatele přihlašuji takto:

return new Security\Identity( $userObject->id, array( "registered" ), $user );

Ovšem mi stále vrací false (přitom role je na tvrdo nastavená na „registered“):

dump( $this->getUser()->isAllowed( 'pool', 'add' ) );

dump( $this->getUser() );:

Nette\Security\User #02e8
guestRole => "guest" (5)
authenticatedRole => "authenticated" (13)
onLoggedIn => NULL
onLoggedOut => NULL
storage private => Nette\Http\UserStorage #3159
namespace private => ""
sessionHandler private => Nette\Http\Session #31c1
regenerated private => NULL
options private => array (14) [ ... ]
request private => Nette\Http\Request #8340 { ... }
response private => Nette\Http\Response #e7da { ... }
sessionSection private => NULL
authenticator private => App\Model\Authenticator #51aa
userRepository private => App\Model\User #a093
tableName protected => "user" (4)
dbContext private => Nette\Database\Context #94b9 { ... }
authorizator private => App\Authorizator #d393

dump( $this->getUser()->getIdentity() );:

Nette\Security\Identity #ec7d
id private => 8
roles private => array (1)
0 => "registered" (10)
data private => array (9)

Uživatel opravdu má roli „registered“.
K čemu je slouží guestRole a authenticatedRole?

vvoody
Člen | 910
+
0
-

Tvoj authenticator by si nám nechcel ukázať?

motorcb
Člen | 552
+
0
-

Authenticator.php:

use Nette;

class Authorizator extends Nette\Object implements Nette\Security\IAuthorizator
{
    public function isAllowed( $role, $resource, $privilege )
    {

    }
}

Authenticator.php

class Authenticator extends Nette\Object implements Nette\Security\IAuthenticator
{
...

    public function authenticate( array $credentials )
    {
        list($email, $password) = $credentials;
        $row = $this->userRepository->findByEmail( $email );

        if ( !$row )
        {
            throw new Security\AuthenticationException( 'Neexistující uživatel', self::IDENTITY_NOT_FOUND );
        }

        if ( $row->password !== $this->calculateHash( $password ) )
        {
            throw new Security\AuthenticationException( "Špatné heslo", self::INVALID_CREDENTIAL );
        }

        $roles = array();
        $userArray = $row->toArray();
        unset( $userArray[ 'password' ] );
        $roles = array( "registered" );
        return new Security\Identity( $row->id, $roles, $userArray );
    }
...
}
vvoody
Člen | 910
+
0
-

pardon myslel som autorizátor, proste kde máš zadefinované že registrovaný user môže vykonať add nad pool

Šaman
Člen | 2666
+
0
-

GuestRole slouží k označení nepřihlášeného uživatele. I bez přihlášení máš totiž k dispozici $presenter->getUser() a vrací reálnou instanci (nikoliv NULL, jak by si mohl někdo myslet). Onen nepřihlášený uživatel má roli ‚guest‘ (a s ní můžeš v ACL normálně pracovat).
AuthenticatedRole bude asi podobná záležitost, ale nikdy jsem ji zatím nepoužil.

Hoď sem ACL, nebo zkus oprávnění kontrolovat jednodušeji $presenter->user->isInRole('registered');

motorcb
Člen | 552
+
0
-

@vvoody:

$this->getUser()->setAuthorizator( new App\Authorizator() );
$acl = new Nette\Security\Permission;

// definujeme role
$acl->addRole('guest');
$acl->addRole('registered', 'guest'); // registered dědí od guest
$acl->addRole('administrator', 'registered'); // a od něj dědí administrator

//zdroje
$acl->addResource('pool');


// opraveni
$acl->allow('guest', 'pool', 'view');

// registrovaný dědí právo od guesta
$acl->allow('registered', 'pool', 'add');

// administrátor může prohlížet a editovat cokoliv
$acl->allow('administrator', Nette\Security\Permission::ALL, array('view', 'edit', 'add'));

Pokud jsem prihlasen: dump( $this->getUser()->isInRole(‚registered‘) ); ⇒ FALSE
přitom:
dump( $this->getUser()->getIdentity() );:

Nette\Security\Identity #ba91
id private => 8
roles private => array (1)
0 => "registered" (10)
data private => array (9)

Jsem roli registered mám…

vvoody
Člen | 910
+
0
-

V akom je kontexte tento kód? Čo sa ďalej deje s tým $acl objektom?

motorcb
Člen | 552
+
0
-

@vvoody:
A ACL se pak nic nedělá. To bude asi ten problém :-) Co bych pak měl dělat s ACL?
Kod je v base presenteru:

public function startup()
{
   parent::startup();

   $this->getUser()->setAuthorizator( new App\Authorizator() );
   $acl = new Nette\Security\Permission;

   // definujeme role
   $acl->addRole('guest');
   $acl->addRole('registered', 'guest'); // registered dědí od guest
   $acl->addRole('administrator', 'registered'); // a od něj dědí administrator

   //zdroje
   $acl->addResource('pool');


   // opraveni
   $acl->allow('guest', 'pool', 'view');

   // registrovaný dědí právo od guesta
   $acl->allow('registered', 'pool', 'add');

   // administrátor může prohlížet a editovat cokoliv
   $acl->allow('administrator', Nette\Security\Permission::ALL, array('view', 'edit', 'add'));
}
Šaman
Člen | 2666
+
+1
-

Jeden postřeh, který s problémem nesouvisí: Neděď od guesta. Když teď guestovi zakážeš view, tak ho tím zakážeš i registrovanýmu. Já nedědím ani admina, to je jiná kategorie uživatelů, než user. Ber to jako v klasickém OOP. Je registrovaný uživatel speciální případ guesta? Ne – takže nedědit. U admina záleží na interpretaci – podle mě admin není obyč user, protože když uživateli něco zakážeš, admin by na to mít práva stále měl.

A teď k věci: problém bude v tom „Pokud jsem prihlasen: dump( $this->getUser()->isInRole(‚registered‘) ); ⇒ FALSE“. To je divné.
Akorát mě nenapadá proč by se to mělo dít. Zkus to na čistém sandboxu (jakou máš vlastně verzi Nette?) který jsi stáhnul spolu s Nette a jen uprav přihlašování (nastavení role) a pak zkus jestli to hlásí isInRole správně. Jestli ano, tak zkus přidat i to acl.
Ještě si zkus dumpnout přímo $this->user->getRoles().

Mimochodem v aktuálním Nette nemusíš psát roli do pole (pokud je jen jedna), ono si to zpracuje samo.

vvoody
Člen | 910
+
0
-

motorcb napsal(a):

@vvoody:
A ACL se pak nic nedělá. To bude asi ten problém :-) Co bych pak měl dělat s ACL?
\--

Tak logicky zvyšok objektov o existencii acl netuší keď ho ďalej nepredáš. Tak skús tentokrát niečo zistiť aj sám. Ktorý objekt asi tak to acl potrebuje? Má ten objekt nejakú metódu, ktorou sa mu dá nastaviť? (treba pozrieť api)

kudlajz
Člen | 70
+
0
-

Hele, prijde mi, ze to mas nejake kostrbate.

Ja osobne mam tridu ACL, ktera dedi Nette\Security\Permission a tuto tridu mam zadefinovanou v config.neon mezi services, v constructoru pak definuji role a prostredky.

motorcb
Člen | 552
+
0
-

@Šaman:

Ano, to dědění nedává smysl. Díky za nasměrování. Vycházel jsem z dokumentace: https://doc.nette.org/…thentication

Kam bych měl ukládat to $acl?

Vyzkouším čistý sandbox.

Díky

Šaman
Člen | 2666
+
0
-

ACL, resp. Permission je jen implementace rozhraní IAuthorizator, které si aplikace (resp. ten $presenter->user) najde samo. Takže tuto třídu stačí nechat vytvořit v kontejneru (tedy zapsat do configu). Ale s tím, že ti to špatně hlásí isInRole() to nesouvisí, to vůbec nepotřebuje authorizator.


Aha, ty to máš celé z dokumentace.. problém je, že poslední dobou se mi dokumentace moc nelíbí :/
Ty příklady jsou třeba z pohledu ukázky algoritmu správně, ale nejsou vhodné k reálnému nasazení i na jednoduchých projektech..

Editoval Šaman (27. 12. 2013 14:14)

vvoody
Člen | 910
+
0
-

ffs tak si odpoviem sám

Ktorý objekt asi tak to acl potrebuje?

No samozrejme User!

Má ten objekt nejakú metódu, ktorou sa mu dá nastaviť? (treba pozrieť api)

Samozrejme že má, stačí pozrieť sem https://api.nette.org/…ty/User.html

To že sa Authorizator a Authenticator dá zaregistrovať do DIC ako službu a automaticky sa predá do objektu User je síce pekné, ale dokiaľ si to určitý ľudia nevyskúšajú „ručne“ tak ich reči o DIC a autowiringu budú len miasť a budú si mylne myslieť že ich použitie je nevyhnutné, resp že to je jediné správne/funkčné riešenie ktoré framework ponúka.

enumag
Člen | 2118
+
0
-

Poslední dobou tenhle odkaz kopíruju nějak často… https://forum.nette.org/…zace-pouziti#…

Editoval enumag (28. 12. 2013 10:55)

motorcb
Člen | 552
+
0
-

@enumag:
Díky, pomohlo. Máš u mne pivo :-)