nette autorizace pomoci acl

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

Ahoj resim zrovna autorizaci a poreboval bych nejak v pomoci Permission definovat tuto podminku:

Administrator muze cokoliv, ale nemuze smazat sam sebe.

mam nejakou svoji tridu

class UserAuthorizator {

    private $users;

    private $user;

    private $acl;

    public function __construct(Users $users, User $user, Permission $acl)
    {
        $this->users = $users;
        $this->user = $user;
        $this->acl = $acl;

        $this->acl->addRole('admin');
		$this->acl->addResource(...);
        $this->acl->allow('admin', Permission::ALL, Permission::ALL); // tady nejak definovat to pravidlo.
    }

    public function isAllowed(...)
    {

    }
}

Jde to nejak definovat jednoduse? Propadne je na to v nette nejaky mechanismus?
Dekuji.

Azathoth
Člen | 495
+
0
-

Já jsem řešil něco podobného, a udělal jsem to tak, že jsem si nadefinoval metodu (dodávám, že MyAdminEntity implementuje IIdentity)

<?php
isAllowedToDeleteAccount(MyAdminEntity $identity, $id) {
	$identity->isAllowedToDeleteAccount($id);
}
?>

a MyAdminEntity má metodu

<?php
isAllowedToDeleteAccount($id) {
	if($this->getId() != $id){
		return true;
	}
    return false;
}
?>

Editoval Azathoth (14. 9. 2014 1:25)

Šaman
Člen | 2640
+
+3
-

Takhle, ale nejde pak volat jednoduše

$presenter->user->isAllowed($resource, $privilege);

, protože Nette předá authorizatoru jen aktuální roli, nikoliv celého uživatele i s id.
Takže já pak oprávnění testuji tak, že si injectnu authorizátor a volám

$authorizator->isAllowed($user, $resource, $privilege);

A abych měl zaručené, že uživatel i zdroje mají veřejně přístupné $id a u mých rolí i $ownerId, tak používám vlastní rozšířená rozhraní.

P.S. Jen pro úplnost – tohle řešení funguje, pokud má každý uživatel jedinou roli (dědění rolí samozřejmě funguje). Jinak by bylo potřeba udělat si vlastní metodu $authorizator->isAllowed, která foreachne všechny uživatelovo role.

Editoval Šaman (13. 9. 2014 16:17)

enumag
Člen | 2118
+
+1
-

Vida, zase situace kdy tahle věc chybí. :-) #trolling

Jinak řešení co uvádí @Šaman je v rámci možností rozumné, doporučuji.

David Ďurika
Člen | 328
+
0
-

ja to robim nasledovne:

<?php
namespace Inzeraz\Authentication;

use Nette;

class Permission extends \Nette\Security\Permission
{

	/**
	 * @param Nette\Security\User $user
	 */
	public function buildAssertions(\Nette\Security\User $user)
	{
		$assertions = new AccessAssertion($user);

		$this->addRole('advertiser');
		$this->addRole('admin');

		$this->addResource('Entity\Foo\Bar');

		$this->allow('advertiser', 'Entity\Foo\Bar', ['view', 'edit'], [$assertions, 'owner']);

		$this->allow('admin', Permission::ALL, Permission::ALL);
	}
}
?>

znasilnenie neonu

	- \Inzeraz\Authentication\Permission

	user:
		class: \Nette\Security\User
		setup:
			- "?->getAuthorizator()->buildAssertions(?);"(@self, @self)
<?php
namespace Inzeraz\Authentication;

use Nette;

class AccessAssertion
{

	/**
	 * @var \Nette\Security\User
	 */
	protected $user;

	/**
	 * @param \Nette\Security\User $user
	 */
	public function __construct(\Nette\Security\User $user)
	{
		$this->user = $user;
	}

	/**
	 * @param \Nette\Security\Permission $acl
	 * @param $role
	 * @param $resource
	 * @param $privilege
	 *
	 * @return bool
	 */
	public function owner(\Nette\Security\Permission $acl, $role, $resource, $privilege) {
		$iResource = $acl->getQueriedResource();

		if($iResource instanceof IOwnerable) {
			return $iResource->getOwnerId() == $this->user->getId();
		}

		return FALSE;
	}
}
?>

pouzitie:

<?php
$entity = new Entity\Foo\Bar;
$presenter->getUser()->isAllowed($entity, 'view');
?>

Editoval David Ďurika (13. 9. 2014 21:01)

marty666
Člen | 26
+
0
-

Diky vsem za inspiraci. Vyresil jsem to, tak ze si vzdy do te me funkce isAllowed predavam id usera a pak podle potreby kontroluju, jestli se mi to id shoduje s aktualne prihlasenym uzivatelem(injektuju ho v konstruktoru).