Práva na úrovni uživatelů
- Climber007
- Člen | 105
Ahoj,
potřebuji v aplikaci vyřešit problém, kdy každý uživatel může
disponovat různými právy k určitým objektům. V tuhle chvíli mi však
rozdělení práv na úrovni rolí nestačí. Samozřejmě, že vztahy jsou
uložené někde v databázi. Otázkou je jak elegantně s těmito vztahy
pracovat?
Používáte někdo nějaké rozšíření, návrh nad klasickým
Nette\Security a Permissions, který by tohle řešil? Jde mi o přístup
$user->isAllowed($article, $id)
. Vytvořit ze všech článků
zdroje a uložit je do Permissions vidím snad správně jako hloupost.
Díky za odpovědi
PS: Google jsem použil, ale skoro všechno je 4 a více let staré a těžko říct, jestli to stále platí :-)
Editoval Climber007 (6. 11. 2014 15:37)
- Jan Tvrdík
- Nette guru | 2595
Doporučuji vůbec rozhraní IAuthorizator
a třídu
Permissions
nepoužívat. Napiš si na to vlastní třídu na míru
tvojí aplikace. Může vypadat například takto.
- thm
- Člen | 147
Osobně jsem řešil podobnou věc a nakonec jsem to vyřešil tak, že jsem si podědil Permission kde jsem přidal metodu:
/**
* Extended function of isAllowed, when id is set, checks if user has special permission to do this for item with ID of resource
* @param string $role
* @param string $resource
* @param string $privilege
* @param int $id
* @return bool
*/
public function isAllowedExt($role = self::ALL, $resource = self::ALL, $privilege = self::ALL, $id = NULL){
$result = $this->isAllowed($role, $resource, $privilege);
//Checks for permissions loaded on signIn to SessionSection acl->usersPermisssions
if($id && !$result && $this->getSession()->usersPermissions)
$result = in_array(array('role' => $role, 'resource' => $resource, 'privilege' => $privilege, 'id' => $id), $this->getSession()->usersPermissions);
return $result;
}
A pozměnil jsem třídu User a její metodu isAllowed:
public function isAllowed($resource = IAuthorizator::ALL, $privilege = IAuthorizator::ALL, $id = NULL)
{
foreach ($this->getRoles() as $role) {
if ($this->getAuthorizator()->isAllowedExt($role, $resource, $privilege, $id)) {
return TRUE;
}
}
return FALSE;
}
Při přihlášení uživatele načtu do session jeho speciální práva ke konkrétním položkám s id (např. role = uzivatel1, resource = article, privilege = edit, id = 1).
V presenteru volám například:
$this->user->isAllowed('articles', 'edit', 1);
A když původní
$result = $this->isAllowed($role, $resource, $privilege);
vrátí FALSE, tak zkontroluju obsah session jestli se ta kombinace tam
nevyskytuje a pokud ano, vrátím TRUE.
Vím že to asi není njsprávnějěší, pořád se s OOP a NETTE peru, ale takhle mi to prostě funguje.
Editoval thm (10. 11. 2014 11:34)