- Aplikace
- Databáze
- Šablony
- Formuláře
- Knihovny
- Návody
Permission
Třída Permission obstarává práci s uživatelskými rolemi a jejich právy a přístupy. Díky této třídě budou Vaše aplikace bezpečné a programování uživatelského zabezpečení bude hračka.
Než si vysvětlíme co a jak, bylo by vhodné vysvětlit a připomenout pojmy, se kterými budeme operovat.
- Role – je role uživatele, pomocí role sdružujeme oprávnění, které
budeme na dané uživatele aplikovat. (př.:
guest,member,admin) - Resource – je oblast, nad kterou budeme definovat jednotlivá
přístupová práva. (př.:
clanky,administrace,nastenka) - Actions – jsou akce, které uživatel v roli role provádět nad
resource (př.:
edit,delete,show)
Základní práce se třídou bude tedy spočívat na nadefinování rolí a resource a následnému propojení, co kdy daný uživatel může na dané oblasti dělat. Jednotlivé uživatelské role se můžou navzájem dědit. Rodiče dané role definujeme pomocí druhému parametru. Jako rodiče předáme jeho jméno, nebo pole se jmény požadovaných rodičů.
Role guest je definována automaticky po vytvoření třídy
Permission.
$acl = new Permission();
$acl->addRole('member', 'guest');
$acl->addRole('admin', 'member');
$acl->addResource('clanky');
$acl->addResource('komentare');
Dále musím definovat jednotlivé propojení mezi zdroji a rolemi. Pokud
nejsou u dané role definovány jednotlivé zdroje nebo akce, pak vrací metoda
isAllowed false. Z toho vyplývá, že přístupnějším systéme
definice jednotlivých vazeb je odspodu, od guest, a následné povolování
přístupu jednotlivým rolím.
Vazby vytváříme pomocí metody allow(), respektive pomocí
deny(), jako první parametr zadáváme role, jako druhý zdroje a
jako třetí akce.
$acl->allow('member', 'posts', 'comment');
Jednotlivé parametry předáváme jako řetězec, případně jako pole řetězců. Velmi užitečným nástrojem nám může být kvantifikátor *. Díky hvězdičce nemusíme vyjmenovávat všechny zdroje / akce, ale jednoduše můžeme nastavit práva pro celou danou oblast.
Hvězdička se smí použít pouze po nadefinování zdrojů a akcí. Na později přidané zdroje a akce nebude mít vliv!
$acl = new Permission();
# roles
$acl->addRole('member', 'guest');
$acl->addRole('admin', 'member');
$acl->addRole('superadmin', 'admin');
# resource
$acl->addResource('comments');
$acl->addResource('posts');
# privilegies
$acl->allow('guest', array('posts', 'comments'), 'view');
$acl->allow('member', 'comments', 'add');
$acl->allow('admin', 'posts', array('add', 'edit', 'delete'));
$acl->allow('superadmin', '*', '*');
# returns true
$acl->isAllowed('guest', 'posts', 'view');
$acl->isAllowed('guest', 'comments', 'view');
$acl->isAllowed('member', 'comments', 'view');
$acl->isAllowed('admin', 'comments', 'add');
$acl->isAllowed('admin', 'posts', 'view');
$acl->isAllowed('superadmin', 'posts', 'delete');
$acl->isAllowed('superadmin', 'comments', 'delete');
# returns false
$acl->isAllowed('guest', 'comments', 'add');
$acl->isAllowed('guest', 'posts', 'add');
$acl->isAllowed('member', 'comments', 'delete');
$acl->isAllowed('admin', 'comments', 'delete');
Dynamický správa přístupu
Dynamickou správu přísupu využijete tehdy, když budete potřebovat se rozhodnout na základě jiných faktorů, než je pouze jméno zdroje a akce.
class TimeAssertion extends PermissionAssertion
{
public function assert(Permission $acl, $resource, $action)
{
return date('H') > 12;
}
}
Třída, jenž bude provádět validaci musí být potomkem od třídy
PermissionAssertion a musí definovat metodu assert,
jak je uvedeno v ukázce (včetně stejných parametrů). Metodě assert je
předán objekt Permission, dále název zdroje a název action. V této
ukázce povolíme hostovi přístup ke všemu, ale až po poledni.
$acl = new Permission;
$acl->allow('guest', '*', '*', new TimeAssertion);
Dynamický správa zdrojů
Často nastane situace, kdy je třeba povolit uživateli přístup pouze k části zdrojů, například k té, které je vlastníkem. I tento složitý mechanismus třída Permission zvládne. Využijeme k tomu dynamickou správu přístupu a přidáme ještě objektové zastoupení zdroje.
class MediaResource extends Resource
{
public $author_id;
protected $name = 'media';
}
class MediaAssertion extends PermissionAssertion
{
public function assert(Permission $acl, $resource, $action)
{
return $this->resource->author_id == 1234;
}
}
Třída dynamického zdroje musí být potomkem třídy Resource
a musí mít nadefinovanou členskou proměnnou $name. Proměnná
$name by měla obsahovat jméno zdroje.
$acl = new Permission;
$acl->addRole('author');
$acl->addResource('media');
$acl->allow('author', 'media', '*', new MediaAssertion);
$media = new MediaResource;
$media->author_id = 1234;
# returns true
$acl->isAllowed('author', $media);
$acl->isAllowed('author', $media, 'view');
