jak zaimplementovat acl do kódu

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

Ahoj,

chtěl bych rozdělit na webu práva, ale zdá se že nepřehlednější je to pomocí autentizátoru.

Víceméně je všechno zřejmé z dokumentace.

Nicméně si nevím moc rady. Nemá někdo k dispozici příklad, který pracuje s db?

Mám v podstatě udělanou tu první část dokumentace kde se pak ptám: isInRole()..

ale to si myslim, že je dobrý tak na skrývání odkazů nebo tak.

echo
Člen | 134
+
0
-

Zdravím,
viděl jsem i systém, který pracuje jenom s rolemi. Místo rolí admin, user apod. se používaly konkrétní role ARTICLE_ADD, ARTICLE_REMOVE…

Jinak si implementuj vlastní Nette\Security\IAuthorizator, který bude pracovat s databází. Nebo druhou možností je služba, která z databáze stáhne potřebné a nastaví Nette\Security\Permission.

qteck
Člen | 164
+
0
-

ten by měl být v modelu?

class MyAuthenticator extends Nette\Security\Permission
{
$this->addRole('guest');
$this->addRole('registered', 'guest'); // registered dědí od guest
$this->addRole('admin', 'registered'); // a od něj dědí administrator

// teď definuju zdroje, což úplně nevím co si pod tím představit ale zřejmě akce presenterů, nebo jednotlivé stránky?

$this->addResource('article');
$this->addResource('comment');
$this->addResource('poll');

// a pak si nastavím jednotlivá práva:
$this->allow('guest', array('article', 'comment', 'poll'), 'view');
$this->allow('guest', 'poll', 'vote');

// registrovaný dědí právo od guesta, ale má i právo komentovat
$this->allow('registered', 'comment', 'add');

// administrátor může prohlížet a editovat cokoliv
$this->allow('admin', Permission::ALL, array('view', 'edit', 'add'));
}

teoreticky by to mohlo vypadat něják takto?

já bych konrkténě chtěl, abych mohl vhodit výjimku, pokud někdo vleze na stránku kam nemá práva.

echo
Člen | 134
+
0
-

To by šlo. V presenteru vyhodíš výjimku:

if(!$this->user->isAllowed($resource, $privilege)) {
	throw new Exception(...);
}

Mrkni ještě do API. Je to tam dobře srozumitelné.

Editoval echo (6. 7. 2014 15:03)

qteck
Člen | 164
+
0
-

oka, jen by mě zajímalo jak je to s těmi zdroji, co to je teda?

jsou to stránky, nebo presentery?

mám třeba stránku

model/Upload.php
presenters/UploadPresenter.php
view/Upload.php

tak ten zdroj bude vypadat pouze takto: addResource(‚upload‘);

je to tak?

ještě bych doplnil.

Teďka mám implementovanej zvlášť jako třídu iAuthenticator pro login a pak mám třídu ACL která dědí Permission ve další složce MyAcl.php.

Editoval qteck (6. 7. 2014 16:11)

echo
Člen | 134
+
0
-
  1. Zdroj je cokoliv, co si určíš. Já o nich přemýšlím jako o všem, co mění stav aplikace. (registrace, přidání článku, editace, výmaz, apod.) Jinak řečeno testuji právo vykonat Event v aplikaci https://en.wikipedia.org/…architecture
  2. Dědit cokoliv jenom kvůli nastavení se považuje za antipattern. Měl by jsi mít továrničku:
class ACLFactory
{

	public function create()
	{
		$acl = new Permission;
		// tvoje nastavení
		return $acl;
	}

}
  1. Authenticator přihlašuje, Authorizator ověřuje oprávnění přihlášeného. K oběma je interface, takže buď vlastní implementace nebo použití existujícího. To je na tobě.
qteck
Člen | 164
+
0
-

okay, díky za rady, ale stejně, ještě se musím zeptat jednou, asi je to blbost, ale já nechápu podle čeho ty zdroje definovat.

řekněme třeba, že mám ten upload.

uploadPresenter.php
---class Upload {}

a chci aby do ní měl přístup jenom admin
$this->addResource('Upload:')

$this->addRole('guest');
$this->addRole('registered', 'guest'); // registered dědí od guest
$this->addRole('admin', 'registered'); // a od něj dědí administrator

// a pak si nastavím jednotlivá práva:
// administrátor může prohlížet a editovat cokoliv
$this->allow('admin', Permission::ALL, array('view', 'edit', 'add')); <----- třeba tady kde se vzalo ono view, edit, add. Je to z dokumentace.

já to teď vidím tak, že si vytvořím továrničku, tam si vytvořim instaci od permission a pod to nadeinfuju zbytek a už nebudu muset nikde na nic sahat a budu to mít všechno pohromadě, doufám že tomu rozumim správně.

Editoval qteck (6. 7. 2014 19:21)

echo
Člen | 134
+
0
-

Zdroje si definuješ sám. Říkáš upload, ale čeho? Obrázků ke článku nebo jiných souborů? Pro to první třeba takto:

$acl->allow($role, 'article', 'imageUpload');

Zdroj je cokoliv, co ti dává smysl. (článek, komentář) Privilegium pak operace nad tím zdrojem. (přidat, smazat)

qteck
Člen | 164
+
0
-

Jo počkej, už tomu rozumim, to zamená že to pak budu muset třeba v prezenterech kontrolovat, popřípadě v pohledech.

to v podstatě udělá jen to, že mi to nějákým způsobem naplní pole. takže budu mít co kdo může, ale obsluhu co se zobrazí a co né si budu muset napsat sám?

jsem právě myslel, že si to nadefinuju v té továrně a ono se to udělá samo. jakože třeba napíšu
acl->allowed(„admin“, „article_edit“,null);

a znemaná to, že admin když si klikne na stránku/article_edit/
tak se mu zobrazí a ostatním rolím automaticky vyhodí výjimku.

echo
Člen | 134
+
0
-

Všechnu obsluhu si píšeš v presenteru sám. Má to výhodu nezávislosti. Pokud by jsi to chtěl nějak zautomatizovat, zkusil bych Kdyby\Events a eventy Nette\Application\Application::$onRequest/$onPresenter. Ale nedoporučuji to, zavádíš tak magii, kde není třeba.

Nebo kontrolovat v Presenter::startup().

if($this->user->isAllowed($this, $this->getAction())) {
	throw new Exception;
}

Samozřejmě by presenter musel implementovat Nette\Security\IResource.

Editoval echo (6. 7. 2014 20:56)

qteck
Člen | 164
+
0
-

Oukej echo, díky za pomoc :-)