ACL – vice roli, vlastnictvi zdroje
- libik
- Člen | 96
Ahoj,
mam nasledujici autorizator:
<?php
namespace App\Services;
use Nette\Security\IAuthorizator,
Nette\Security\Permission,
Nette\Security\IResource;
class AuthorizatorFactory
{
/**
* @return IAuthorizator
*/
public function create()
{
$authorizator = new Permission;
$authorizator->addRole("host");
$authorizator->addRole("redaktor");
$authorizator->addRole("editor");
$authorizator->addRole("superAdministrator");
$authorizator->addResource('entity');
$authorizator->addResource('Menu', 'entity');
$authorizator->addResource('User', 'entity');
$authorizator->allow('superAdministrator', 'entity', IAuthorizator::ALL);
$authorizator->allow('host', 'Menu', array('edit','delete'), [$this, 'isOwner']);
$authorizator->allow('editor', 'Menu', array('edit','delete'), [$this, 'isOwner']);
$authorizator->allow('redaktor', 'Menu', 'edit', [$this, 'isOwner']);
return $authorizator;
}
/**
* Zjisti, zda je uzivatel role vlastnikem zdroje
*
* @return bool
*/
public function isOwner(Permission $permission, $role, $resource, $privilege)
{
if ($permission->getQueriedResource() instanceof IResource)
{
$resourceOwners = $permission->getQueriedResource()->getOwnerId(); //vrati pole vlastniku zdroje
$roleOwner = $permission->getQueriedRole()->getId(); // vrati id vlastnika role
$resourceRole = $permission->getQueriedResource()->getOwnerRole($permission->getQueriedRole()->getId()); // vrati typ vlastnictvi (role) zdroje
$resourceRoleName = $resourceRole->getRole();
// pokud je vlastnikem a zaroven typ vlastnictvi odpovida jeho roli, vraci TRUE
return in_array($roleOwner, $resourceOwners) && $role == $resourceRoleName;
} else
{
return TRUE;
}
}
}
A ted mam problem v tom, ze user muze mit roli vic a nektery zdroj vlastnit jako host, nektery jako editor:
Nette\Security\Identity #0320
id private => 13
roles private => array (3)
5 => "editor"
6 => "redaktor"
7 => "host"
data private => array (1)
userName => "user.name"
Kontrola pres:
$this->acl->isAllowed(UserEntity $ue,MenuEntity $um14, 'delete');
Metoda isOwner() se vola vzdy jen pro roli ‚editor‘ a nevrati TRUE pro zdroj $um14, ve kterem ma uzivatel nastaveno vlastnictvi jako host (protoze podminka editor !== host).
Jak s tim pohnout? Nebo je to slepa ulicka?
Diky za rady.
- David Matějka
- Moderator | 6445
Ahoj, zkus mrknout na moji prednasku z posoboty, o necem podobnem tam povidam :)
- libik
- Člen | 96
Ahoj, diky. Videl jsem a zkousim implementovat. Zasekl jsem se na prazdne identite – Authorizator mi v getRoles() hlasi Call to a member function getRoles() on null.
User Entity mam:
<?php
namespace App\Model\Entities;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use App\Model\Entities\Role;
use App\Services\Security\Identity;
/**
* Users
* @package App\Model\Entities
* @ORM\Table(name="17_user", uniqueConstraints={@ORM\UniqueConstraint(name="name_UNIQUE", columns={"name"})})
* @ORM\Entity
*/
class User
{
const MAX_LENGTH_NAME = 50;
const MAX_LENGTH_EMAIL = 100;
public function __construct()
{
$this->roles = new ArrayCollection();
$this->menuPermission = new ArrayCollection();
}
/** @var Identity */
private $identity;
/**
*
* @return Identity
*/
public function getIdentity()
{
return $this->identity;
}
...
Identity class:
<?php
namespace App\Services\Security;
use Nette\SmartObject;
class Identity implements \Nette\Security\IIdentity
{
use SmartObject;
const ROLE_SUPERADMIN = 'superAdmin';
const ROLE_REDAKTOR = 'redaktor';
const ROLE_EDITOR = 'editor';
const ROLE_HOST = 'host';
private $id;
private $roles = [];
public function getRoles()
{
return $this->roles;
}
public function getId()
{
return $this->id;
}
}
A v permission create:
public function create()
{
$permission = new Permission();
$permission->addResource(Menu::class);
$permission->addRole(Identity::ROLE_SUPERADMIN);
$permission->addRole(Identity::ROLE_EDITOR);
$permission->addRole(Identity::ROLE_REDAKTOR);
$permission->addRole(Identity::ROLE_HOST);
$permission->addRole(Menu::MENU_OWNER);
$this->allow($permission, Menu::MENU_OWNER, Menu::ACTION_EDIT);
$permission->allow(Identity::ROLE_SUPERADMIN, $permission::ALL, $permission::ALL);
return $permission;
}
Mam chaos v te Identite, kde ji vezmu, kdyz ne klasickou Nette\Security.
Diky.
- David Matějka
- Moderator | 6445
identita v tom ACL neodpovida identite z nette/security. v tvem pripade klidne entita User muze vystupovat jako identita. mrkni kdyztak na GH na example – https://github.com/…tion-example (jen nevim, jestli funguje, psal jsem to tenkrat narychlo ve vlaku :))
- libik
- Člen | 96
Tak uz jsem to rozchodil, diky!
Mam jeste jednu vec, ktera primo s problemem implementace nesouvisi, ale
premyslim, jak to udelat nejlepe.
Mam stromovou strukturu podobnou adresarove strukture (pro zjednoduseni).
Prava muzu pridelovat bud na konkretnim adresari nebo jen konkretnimu
souboru.
Uzivatel (admin) muze mit pravo nakladat s celym adresarem nebo jen konkretnimi
soubory (jako user) v jinem adresari, kde neni vedeny jako admin. Jiny uzivatel
muze mit pravo pouze k jednomu souboru (jako user).
Vaham, zda:
- je nejlepsi prima rekurze (tedy pravo nastavene adresari explicitne ulozim i ke vsem souborum, ktere obsahuje) a pri zjistovani opravneni u souboru se nemusim dotazovat na prava nastavena na adresari.
- nebo setrivejsi zpusob, a to ukladat jen user opravneni, protoze kdyz bude u adresare uzivatel s opravnenim jako admin, ma pristup k souborum jasny. Ale tady zase musim zjistovat prava dvakrat, na soubor – pokud ne, na adresar.