priklad na acl – konkretny kod

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

Caute, neviete mi niekto odporucat nejaky ukazkovy priklad na sprevadzkovanie ACL?

harmim
Člen | 26
+
+2
-

Určitě stojí za to se podívat na příklad od @PavelJanda https://play.nette.org/…i-acl-vrstvy

Editoval harmim (16. 5. 2016 1:16)

cujan
Člen | 410
+
0
-

skusil som spojazdnit acl podla prikladu…a hodilo mi hlasku

Unable to create service ‚29‘, value returned by factory is not Nette\Security\Permission type.

config.neon

<?php
parameters:


php:
	date.timezone: Europe/Prague


application:
	errorPresenter: Error
	mapping:
		*: App\*Module\Presenters\*Presenter


session:
	expiration: 14 days

latte:
    macros:
        - Nextras\Forms\Bridges\Latte\Macros\BS3InputMacros

services:
	- App\Model\UserManager
	- App\Forms\FormFactory
	- App\Forms\SignFormFactory
	- App\Security\AuthorizatorFactory
	-
	    class: Nette\Security\Permission
	    create: @App\Security\AuthorizatorFactory::create
	router: App\RouterFactory::createRouter
?>
David Matějka
Moderator | 6445
+
0
-

ukaz, jak vypada AuthorizatorFactory

cujan
Člen | 410
+
0
-
<?php
<?php

namespace App\Security;

use Nette,
    Nette\Security\Permission;

/**
 * Description of AuthorizatorFactory
 *
 * @author Holub
 */
class AuthorizatorFactory extends \Nette\Object {

    const ROLE_USER = '2';
    const ROLE_ADMIN = '1';

    public function create(){
	$acl = new Permission;

	/**
	 * Roles 1*
	 */
	$acl ->addRole(self::ROLE_USER);
	$acl->addRole(self::ROLE_ADMIN, self::ROLE_USER);//2*

	/**
         * Resoures 3*
         */
	$acl->addResource('NavstevaReviru');
	$acl->addResource('NavstevaReviru:add', 'NavstevaReviru');

	/**
         * Permissions 4*
         */
	$acl->allow(self::ROLE_ADMIN,'NavstevaReviru:add');
	$acl->deny(self::ROLE_USER,'NavstevaReviru:add');
    }
}
?>
cujan
Člen | 410
+
0
-

kurnik chyba mi tam return $acl;

cujan napsal(a):

<?php
<?php

namespace App\Security;

use Nette,
    Nette\Security\Permission;

/**
 * Description of AuthorizatorFactory
 *
 * @author Holub
 */
class AuthorizatorFactory extends \Nette\Object {

    const ROLE_USER = '2';
    const ROLE_ADMIN = '1';

    public function create(){
	$acl = new Permission;

	/**
	 * Roles 1*
	 */
	$acl ->addRole(self::ROLE_USER);
	$acl->addRole(self::ROLE_ADMIN, self::ROLE_USER);//2*

	/**
         * Resoures 3*
         */
	$acl->addResource('NavstevaReviru');
	$acl->addResource('NavstevaReviru:add', 'NavstevaReviru');

	/**
         * Permissions 4*
         */
	$acl->allow(self::ROLE_ADMIN,'NavstevaReviru:add');
	$acl->deny(self::ROLE_USER,'NavstevaReviru:add');
    }
}
?>
cujan
Člen | 410
+
0
-

neviem preco mam teraz hlasku

Role ‚guest‘ does not exist
ked s guest vobec nerobim…

David Matějka
Moderator | 6445
+
+1
-

„guest“ je defaultni role neprihlaseneho uzivatele

cujan
Člen | 410
+
0
-

hej prave to citam, podla mam este problem so SignPresenter
a overovanim identity, lebo uz mam chybu

Role must be a non-empty string

David Matějka napsal(a):

„guest“ je defaultni role neprihlaseneho uzivatele

Editoval cujan (24. 5. 2016 11:09)

cujan
Člen | 410
+
0
-

BasePresenter vyzera takto

<?php

namespace App\Presenters;

use Nette;
use App\Model;


/**
 * Base presenter for all application presenters.
 */
abstract class BasePresenter extends Nette\Application\UI\Presenter
{



    /**
     * Check authorization
     * @return void
     */

    public function checkRequirements($element)
    {
        if ($element instanceof Nette\Reflection\Method) {
            /**
             * Check permissions for Action/handle methods
             *
             *  - Do not that (rely on presenter authorization)
             */
            return;
        } else {
            /**
             * Check permissions for presenter access
             */
            $resource = $element->getAnnotation('resource'); // 1*
        }

        if (!$this->user->isAllowed($resource)) { // 2*
            if (!$this->user->isLoggedIn()) {
                $this->redirect('Sign:in');
            } else {
                throw new Nette\Application\ForbiddenRequestException;
            }
        }
    }

}

?>
David Matějka
Moderator | 6445
+
0
-

ukaz celou ladenku (html)

cujan
Člen | 410
+
0
-

Nette\InvalidArgumentException

Role must be a non-empty string. search►

Source file

Call stack

…\vendor\nette\security\src\Security\Permission.php:604 source Nette\Security\Permission->checkRole(arguments)

$role
2
…\vendor\nette\security\src\Security\User.php:229 source Nette\Security\Permission->isAllowed(arguments)

$role
2
$resource
„User:Sign“ (9)
$privilege
NULL
…\knihaNavstev\app\presenters\BasePresenter.php:38 source Nette\Security\User->isAllowed(arguments)

28: * – Do not that (rely on presenter authorization)
29: /
30: return;
31: } else {
32: /**
33: * Check permissions for presenter access
34: /
35: $resource = $element->getAnnotation(‚resource‘); // 1

36: }
37:
38: if (!$this->user->isAllowed($resource)) { // 2

39: if (!$this->user->isLoggedIn()) {
40: $this->redirect(‚Sign:in‘);
41: } else {
42: throw new Nette\Application\ForbiddenRequestException;
$resource
„User:Sign“ (9)
…\nette\application\src\Application\UI\Presenter.php:178 source App\Presenters\BasePresenter->checkRequirements(arguments)

…\nette\application\src\Application\Application.php:141 source Nette\Application\UI\Presenter->run(arguments)

…\nette\application\src\Application\Application.php:81 source Nette\Application\Application->processRequest(arguments)

…\data\localweb\projects\knihaNavstev\www\index.php:8 source Nette\Application\Application->run()

David Matějka
Moderator | 6445
+
0
-

A co si udelal s tou „guest“ roli?

cujan
Člen | 410
+
0
-

David Matějka napsal(a):

A co si udelal s tou „guest“ roli?

<?php
class AuthorizatorFactory extends \Nette\Object {

    const ROLE_GUEST = 'guest';
    const ROLE_USER = 'user';
    //const ROLE_ADMIN = '1';

    public function create(){
	$acl = new Permission;

	/**
	 * Roles 1*
	 */
	$acl->addRole(self::ROLE_GUEST);
	//$acl ->addRole(self::ROLE_USER,  self::ROLE_GUEST);
	$acl->addRole(self::ROLE_USER, self::ROLE_GUEST);//2*

	/**
         * Resoures 3*
         */
	$acl->addResource('NavstevaReviru');
	$acl->addResource('NavstevaReviru:add', 'NavstevaReviru');
	$acl->addResource('Homepage');
	$acl->addResource('User');
	$acl->addResource('User:Sign', 'User');

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

        $acl->allow(self::ROLE_USER,  Permission::ALL, Permission::ALL);

	return $acl;
    }
}
?>
Barvoj
Člen | 60
+
0
-

Připadá mi, že se ti tam někde stane ze stringu „2“ int 2 (jedná se o roli USER) a pak to při kontrole v checkRole vyhodí vyjimku. Možná by byl ještě zajímavý kód authenticatoru

Editoval Barvoj (24. 5. 2016 13:03)

cujan
Člen | 410
+
0
-

Barvoj napsal(a):

Připadá mi, že se ti tam někde stane ze stringu „2“ int 2 (jedná se o roli USER) a pak to při kontrole v checkRole vyhodí vyjimku. Možná by byl ještě zajímavý kód authenticatoru

tak ja mam v tabulke users stlpec roleId, kde sa odkazujem do tabulky role a tam si manazujem role, cize roleId je cislo id role…

cujan
Člen | 410
+
0
-

Barvoj napsal(a):

Připadá mi, že se ti tam někde stane ze stringu „2“ int 2 (jedná se o roli USER) a pak to při kontrole v checkRole vyhodí vyjimku. Možná by byl ještě zajímavý kód authenticatoru

<?php
public function authenticate(array $credentials)
	{
		list($username, $password) = $credentials;

		$row = $this->database->table(self::TABLE_NAME)->where(self::COLUMN_NAME, $username)->fetch();

		if (!$row) {
			throw new Nette\Security\AuthenticationException('The username is incorrect.', self::IDENTITY_NOT_FOUND);

		} elseif (!Passwords::verify($password, $row[self::COLUMN_PASSWORD_HASH])) {
			throw new Nette\Security\AuthenticationException('The password is incorrect.', self::INVALID_CREDENTIAL);

		} elseif (Passwords::needsRehash($row[self::COLUMN_PASSWORD_HASH])) {
			$row->update(array(
				self::COLUMN_PASSWORD_HASH => Passwords::hash($password),
			));
		}

		$arr = $row->toArray();
		unset($arr[self::COLUMN_PASSWORD_HASH]);
		return new Nette\Security\Identity($row[self::COLUMN_ID], $row[self::COLUMN_ROLE], $arr);

	}
?>
Barvoj
Člen | 60
+
0
-

Pokud je $row[self::COLUMN_ROLE] číslo, tak zkus do posledního řádku dát přetypování na string:

return new Nette\Security\Identity($row[self::COLUMN_ID], (string) $row[self::COLUMN_ROLE], $arr);

EDIT:

A nebo.. $row[self::COLUMN_ROLE] je FK do nějaké tabulky roles.. A v ní máš možná u role i nějaký kód? Tak pracuj s kodama rolí místo s idčkama:

return new Nette\Security\Identity($row[self::COLUMN_ID], $row->role->code, $arr);

Editoval Barvoj (24. 5. 2016 13:16)

cujan
Člen | 410
+
0
-

Barvoj napsal(a):

Pokud je $row[self::COLUMN_ROLE] číslo, tak zkus do posledního řádku dát přetypování na string:

return new Nette\Security\Identity($row[self::COLUMN_ID], (string) $row[self::COLUMN_ROLE], $arr);

EDIT:

A nebo.. $row[self::COLUMN_ROLE] je FK do nějaké tabulky roles.. A v ní máš možná u role i nějaký kód? Tak pracuj s kodama rolí místo s idčkama:

return new Nette\Security\Identity($row[self::COLUMN_ID], $row->role->code, $arr);

nepomohlo ani ani…nechapem…

cujan
Člen | 410
+
0
-

cujan napsal(a):

Barvoj napsal(a):

Pokud je $row[self::COLUMN_ROLE] číslo, tak zkus do posledního řádku dát přetypování na string:

return new Nette\Security\Identity($row[self::COLUMN_ID], (string) $row[self::COLUMN_ROLE], $arr);

EDIT:

A nebo.. $row[self::COLUMN_ROLE] je FK do nějaké tabulky roles.. A v ní máš možná u role i nějaký kód? Tak pracuj s kodama rolí místo s idčkama:

return new Nette\Security\Identity($row[self::COLUMN_ID], $row->role->code, $arr);

nepomohlo ani ani…nechapem…

este jedna vec je divna, ze hoci zmenim v DB typ role, tak ladenka mi hadze stale ze role = 1

Barvoj
Člen | 60
+
0
-

nepomohlo ani ani…nechapem…

Jde o to, že Nette\Security\Permission počítá s tím, že role bude typu string…

V authenticatoru jsi definoval stringové konstanty ROLE_USERROLE_ADMIN

class AuthorizatorFactory extends \Nette\Object {
    const ROLE_USER = '2'; // toto je string
    const ROLE_ADMIN = '1'; // toto je string
}

což by mělo být v pořádku..

Ale při přihlašování uživatele, jsi z databáze načetl id role jako číslo:

public function authenticate(array $credentials)
{
	...
	// $row[self::COLUMN_ROLE] je int 2??
	return new Nette\Security\Identity($row[self::COLUMN_ID], $row[self::COLUMN_ROLE], $arr);
}

proto jsem ti radil, abys tam dal přetypování na string:

public function authenticate(array $credentials)
{
	...
	return new Nette\Security\Identity($row[self::COLUMN_ID], (string) $row[self::COLUMN_ROLE], $arr);
}

este jedna vec je divna, ze hoci zmenim v DB typ role, tak ladenka mi hadze stale ze role = 1

Když se přihlásíš, tak se data o uživateli uloží do session. Musíš se pak odhlásit a znovu přihlásit, aby se změny projevily.

Háže ti to pořád stejnou chybu i když jsi tam dal to přetypování na string? A odhlásil a přihlásil se?

Editoval Barvoj (24. 5. 2016 13:39)

cujan
Člen | 410
+
0
-

oki pohol som sa, prepojil som si to na stringy

a mam v base presenter vynimku

Nette\Application\ForbiddenRequestException #403 search►

Source file

File: …\knihaNavstev\app\presenters\BasePresenter.php:42

32: /**
33: * Check permissions for presenter access
34: /
35: $resource = $element->getAnnotation(‚resource‘); // 1

36: }
37:
38: if (!$this->user->isAllowed($resource)) { // 2*
39: if (!$this->user->isLoggedIn()) {
40: $this->redirect(‚Sign:in‘);
41: } else {
42: throw new Nette\Application\ForbiddenRequestException;
43: }
44: }
45: }
46:

Barvoj napsal(a):

nepomohlo ani ani…nechapem…

Jde o to, že Nette\Security\Permission počítá s tím, že role bude typu string…

V authenticatoru jsi definoval stringové konstanty ROLE_USERROLE_ADMIN

class AuthorizatorFactory extends \Nette\Object {
    const ROLE_USER = '2'; // toto je string
    const ROLE_ADMIN = '1'; // toto je string
}

což by mělo být v pořádku..

Ale při přihlašování uživatele, jsi z databáze načetl id role jako číslo:

public function authenticate(array $credentials)
{
	...
	// $row[self::COLUMN_ROLE] je int 2??
	return new Nette\Security\Identity($row[self::COLUMN_ID], $row[self::COLUMN_ROLE], $arr);
}

proto jsem ti radil, abys tam dal přetypování na string:

public function authenticate(array $credentials)
{
	...
	return new Nette\Security\Identity($row[self::COLUMN_ID], (string) $row[self::COLUMN_ROLE], $arr);
}

este jedna vec je divna, ze hoci zmenim v DB typ role, tak ladenka mi hadze stale ze role = 1

Když se přihlásíš, tak se data o uživateli uloží do session. Musíš se pak odhlásit a znovu přihlásit, aby se změny projevily.

Háže ti to pořád stejnou chybu i když jsi tam dal to přetypování na string? A odhlásil a přihlásil se?

Barvoj
Člen | 60
+
+1
-

To už by měla být chyba nedostatečného oprávnění:) Takže by to vlastně mělo bát dobře..

Asi jsi se přihlásil jako user a přistupuješ do nějaké sekce, kde user nemá mít přístup? :)

cujan
Člen | 410
+
0
-

Huraaaaaaaaa funguje vsetko ako ma…

este jedna vec, daju sa podla prav aj napr. zobrazit alebo nezobrazit odkazy?

CZechBoY
Člen | 3608
+
0
-

Da se cokoliv. Konkretne u odkazu:

<a n:href="Homepage:" n:if="$user->isAllowed('Homepage', 'default')">homepage</a>

Editoval CZechBoY (24. 5. 2016 15:24)

cujan
Člen | 410
+
0
-

CZechBoY napsal(a):

Da se cokoliv. Konkretne u odkazu:

<a n:href="Homepage:" n:if="$user->isAllowed('Homepage', 'default')">homepage</a>

Este mam jeden problemik, mam presenter ZoznamClenov, a vramci neho mam odkaz na add – pridanie noveho clena, potrebujem, aby user mohol pristupit do ZoznamClenov ale nemohol uz pristupit na ZoznamClenov/add

acl ma nadefinovane takto, ale nejako to nefunguj, proste user pristupuje aj do add…

<?php
$acl->addResource('ZoznamClenov');
	$acl->addResource('ZoznamClenov:add','ZoznamClenov');

$acl->allow(self::ROLE_USER,'ZoznamClenov');
	$acl->deny(self::ROLE_USER, 'ZoznamClenov:add');
?>

a zdroj je v ZoznamClenovPreseter nastaveny na

/**
*@resource ZoznamClenov
*/

greeny
Člen | 405
+
0
-

Ta resource ZoznamClenov:add by neměla dědit od ZoznamClenov, protože pak kdokoliv kdo má přístup na ZoznamClenov má přístup i na ZoznamClenov:add