Neměl by IAuthorizator dostávat místo role celou indentitu?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
David Grudl
Nette Core | 8228
+
0
-

Neměl by IAuthorizator dostávat místo role celou indentitu? Tj. nahradit IRole za IIdentity.

Yrwein
Člen | 45
+
0
-

Určitě by bylo logičtější, kdyby celá logika autorizování byla v IAuthorizator. Plus by odpadlo podstrkávání objektům IRole ID uživatele (https://forum.nette.org/…i-permission), přidá-li se do Permission metoda ala getQueriedIdentity. .)

(+1 .])

Editoval Yrwein (25. 6. 2011 13:19)

Jan Tvrdík
Nette guru | 2595
+
0
-

Také mi to přijde (o hodně) lepší, už jen proto, že role k ověřování vůbec nepoužívám.

Doplněno: Vzniká ale problém s nesmazanou identitou při odhlášení.

Yrwein
Člen | 45
+
0
-

@Jan Tvrdík: Imho se to dá řešit podobně/stejně jako nyní s rolemi — pro účely autorizace se vytvoří fake identita s jednou rolí „guest“.

Editoval Yrwein (29. 6. 2011 13:22)

Patrik Votoček
Člen | 2221
+
0
-

Zpětně jsem nad tím celým přemýšlel (díky podnětu na #nettebc) a jsem pro. Pak už nebude takovej problém si udělat IOwner-a.

David Grudl
Nette Core | 8228
+
0
-

Tohle se sice už do 2.0 nedostane, ale dal bych tomu velkou prioritu. Kdyby někdo připravil RFC, bylo by to fajn.

Šaman
Člen | 2666
+
0
-

Jak je na tom tahle fičura, pls? Resp. je nyní nějaký čistý způsob, jak dostat ID uživatele do assert metody? Dřív jsem to řešil staticky, ale teď se snažím o čistý přístup a nějak na nic rozumného nemohu přijít. Díky.

enumag
Člen | 2118
+
0
-

Koukám, že tohle tady nějak zapadlo, nikomu se zřejmě nechtělo sepisovat RFC. Přiznám se, že nějak moc nevím co bych do toho RFC psal. Dneska už se to dá řešit tak že si do authorizatoru injectu celého usera, ale tohle by bylo lepší.

Jan Tvrdík
Nette guru | 2595
+
0
-

@Šaman: Já to řeším tak, že už několik let nepoužívám IAuthorizator.

enumag
Člen | 2118
+
0
-

Díval jsem se jak velký problém by byl tohle implementovat. Bohužel by to ale znamenalo dost drastickou úpravu testů Permission a do toho se mi příliš nechce. Vše ostatní je trivka.

@Jan Tvrdík: Je někde k dispozici ukázka toho co používáš?

@David Grudl: Pokud bych se do toho přeci jen pustil, je šance mergnout to dříve než bude 2.1 final? Vadilo by něčemu kdybych úplně odebral IRole? Smysl tohoto rozhraní mi poněkud uniká.

Editoval enumag (22. 1. 2013 1:18)

Jan Tvrdík
Nette guru | 2595
+
0
-

@enumag: Z toho co je na githubu asi jen https://github.com/…orizator.php

Šaman
Člen | 2666
+
0
-

Zkoušel jsem to vyřešit injectnutím Usera, dokonce to asi nějakou chvíli fungovalo, ale teď jsem se vrátil ke starému projektu, aktualizoval vývojovou verzi Nette a vyhazuje mi to kruhovou závislost, protože User teď vyžaduje v konstruktoru container (wtf?) ze kterého si vezme autenthicator a authorizator.

Připadá mi, že třída User dělá aktivně moc věcí, které by za ni měly řešit pasivně jiné třídy. Když chci vědět, zda má uživatel na něco práva, ptám se přece nějakého managera oprávnění a ne toho uživatele. To už můžu rovnou začít používat ActiveRecord.

Chápu, že je to vývojová verze, ale půlku věcí si nechat injectovat (storage) a druhou půlku tahat z contextu, to není vůbec hezké.


Takže staronová otázka, na které stojí použitelnost celé nettí autorizace: Jak v ACL zjistit id přihlášeného uživatele? Nebo je teď nějaký zcela jiný best practise?

Editoval Šaman (11. 4. 2013 4:53)

enumag
Člen | 2118
+
0
-

@Šaman: Četls RFC? Mimochodem, řešilo by tohle tvůj problém nebo by to též znamenalo cyklickou závislost?

Btw. ve 2.1 už se context nepoužívá.

Editoval enumag (11. 4. 2013 14:05)

Šaman
Člen | 2666
+
0
-

Aha, díky, context jsem našel v API dokumentaci a zapomněl jsem, že to je stable verze, nikoliv dev.

Cyklus vznikl tím, že aktuální implementace třídy User vyžaduje authorizátor. Tedy nemohu authorizatoru předat usera. Pokud authorizátor bude schopný vrátit v metodě getQueriedRole() skutečně objekt identity, tak to nepotřebuji injectovat a dál to neřeším. Ono to předávání aktuálního uživatele byl stejné spíš hack.

Osobně by mi byl milejší samostatný authorizátor, kterého bych se zeptal, zda uživatel má právo na nějaký zdroj. Pak je na mě, zda mu v parametru předám objekty, nebo jen název role a resource. Předávat autorizátor uživateli, abych se mohl ptát přímo jeho, to mi přijde trochu nečisté.

castamir
Člen | 629
+
0
-

Předávat autorizátor uživateli, abych se mohl ptát přímo jeho, to mi přijde trochu nečisté.

@Šaman to není nečisté, to je IMHO celé špatně ;-)

enumag
Člen | 2118
+
0
-

@castamir: Nechceš sepsat RFC? :-)

castamir
Člen | 629
+
0
-

@enumag Sám to potřebuju konečně rozseknout, takže se k tomu časem i dostanu, ale ne dřív než ve druhé polovině června =/

Šaman
Člen | 2666
+
0
-

V tom případě mám otázku obecnějšího rázu – dá se v configu dostat k identitě přihlášeného uživatele? Když nemohu předat celého uživatele, identita by problém neměla dělat, jen nevím, jak ji v configu vytáhnout z @user.

enumag
Člen | 2118
+
0
-

@Šaman: @user->identity?

Šaman
Člen | 2666
+
0
-

Toto bohužel nefunguje. Navíc se vlastně nezbavím té kruhové zavislosti – authorizátor potřebuje při vytváření uživatele a uživatel se vytvoří, až se mu předá mimo jiné authorizátor.

Nakonec tu identitu řeším setterem v bootstrapu. Ale stydím se za to :)

enumag
Člen | 2118
+
0
-

Jo, jasně… Teď to asi nech plavat, pokud se to během pár měsíců v Nette nevyřeší tak z toho RFC udělám addon.

Honza Marek
Člen | 1664
+
0
-

Šaman napsal(a):

Nakonec tu identitu řeším setterem v bootstrapu. Ale stydím se za to :)

No jo, ale co když se odhlásíš nebo přihlásíš? Pak se aktuálně přihlášená identita kompletně vymění / smaže, ale tobě zůstává nasetovaná ta stará. Pravděpodobně se po přihlášení přesměrováváš, takže ten problém není potřeba řešit. Ale chci poukázat na to, že identita je spíše value object, takže její nedostupnost jako servisy je naprosto v pořádku.

Šaman
Člen | 2666
+
0
-

Jen taková malá prudící otázka – pohnulo se toto už nějak?

Případně je někde ukázka použití nad aktuálním Nette? Možná to jen používám špatně, ale při doporučvaném(?) použití $this->user->isAllowed($book, 'read') stále nejsem schopen zjistit, o jakého uživatele se vlastně jedná (mám jen roli).

Tak nevím, jestli toto ostatní nepoužívají, mají vlastní řešení, nebo to jen neumím napsat správně.

enumag
Člen | 2118
+
0
-

@Šaman:

Nepohnulo, protože David to chce jinak. Před pár dny jsem z toho RFC udělal extension, ale ještě jsem ani neměl čas vyzkoušet, že opravdu funguje. Máš-li zájem to extension použít, mohu ho hodit na GitHub, ale použití je na vlastní nebezpečí. ;-) Předem upozorňuji, že to extension je psané pouze pro Nette 2.1, pro 2.0 by sis to musel upravit.

Ostatní používají buď hack na který jsem odkázal v RFC nebo nějakou vlastní implementaci bez IAuthorizatoru. Že to neumíš se současným autorizátorem napsat mne nepřekvapuje, řekl bych, že to neumí nikdo.

Editoval enumag (27. 6. 2013 15:20)

Šaman
Člen | 2666
+
0
-

Tak vyřešeno. Stejně v mém návrhu má každý uživatel jen jednu roli.
Přidal jsem tedy všem mým entitám implementaci IResource a uživateli navíc IRole.
Nyní mohu předávat ACLku entitu uživate a entitu zdroje a s tím už si vystačím.
Volání $this->user->isAllowed() jsem zavrhl, protože neumožňuje předat roli jako objekt uživatele.

Pro práci s více rolemi by bylo potřeba vytvořit nějaký objekt Role, který by obsahoval data o dotyčném uživateli, ale měl přiřazenou roli na kterou se právě ptám. A přetížit $acl->isAllowed tak, aby práci s tímto User/Role podporovalo.

Identitu, resp. $this->user používám tedy jen k udržení ID aktuálně přihlášeného uživatele a k informaci na debug baru. Musím říct, že teď mi tam systémový uživatel spíš překáží.

//Edit: Zbavil jsem se tak všech závislostí uživatele na něčem, nutnosti předat ACLku identitu a všeho WTF chování. Měnit ACL vůbec nebylo potřeba.
Jen nechápu, proč vestavěná defaultní implementace ($this->user->isAllowed) nepodporuje fičuru, kterou sám David před 4 roky označil jako dobrou vychytávku.

Editoval Šaman (2. 7. 2013 18:25)

Climber007
Člen | 105
+
0
-

Jak to zatím vypadá s nějakou úpravou? Mám v aplikaci trochu komplikovanější přidělování privilegií a zatím nejefektivnějším způsobem pro mě zůstává identita se všemi možnými informacemi. Jinak bych musel při každé žádosti pokládat dotaz(y) do databáze, což mi nepřijde ideální.