Pozdní update práv při přihlášení
- maarlin
- Člen | 207
Mám napsaný authorization handler na přihlašování uživatelů s právy
a nějak nechápu důvod aktuálního řešení identity…
Po přihlášení se nastaví identita takto:
return new NIdentity($row->username, $row->role_key, $row);
Samozřejmě data o uživateli z té identity se používají v celé
aplikaci, ale neupdatují, resp. updatují až po
odhlášení/přihlášení.
Tedy pokud je uživatel přihlášen a někdo mu změní jeho úroveň
oprávnění (role_key), tak se tato změna nijak nepromítne… Leda bych si
připsal do BasePresenteru do startupu dotaz na aktuální role_key v databázi
a pak to updatnul pomocí getIdentity()->setRoles()… Jiné řešení asi
není, že?
Ovšem data o uživateli jako takovém se mi nijak nedaří updatovat… Co kdyby se user třeba překlepnul (ve jménu, příjmení, emailu… čemkoliv) a v databázi by došlo k opravě? Pak aby se to projevilo, musí provést relogin? To mi nepřijde ideální…
Řekněte mi někdo, že to řeším jinak, než bych měl a že to jde lépe… :)
- Aurielle
- Člen | 1281
Změnu práv neřeším (v mé aplikaci to bude hodně ojedinělý případ), ale identita se updatuje vždy, když si uživatel změní profil (samozřejmě vždy se změní i příslušný záznam v databázi):
/**
* Update user's identity
* @return void
*/
public static function updateIdentity($args)
{
$args = func_get_args();
if(sizeof($args) == 1)
{
if(is_array($args[0]))
{
foreach($args[0] as $col => $value)
{
Environment::getUser()->getIdentity()->$col = $value;
}
}
}
else if(sizeof($args) == 2)
{
Environment::getUser()->getIdentity()->$args[0] = $args[1];
}
else
{
throw new InvalidArgumentException("Arguments passed for " . __METHOD__ . "() are invalid.");
}
}
Editoval gmvasek (31. 12. 2009 20:58)
- Ondřej Mirtes
- Člen | 1536
Při změně práv v aplikaci můžeš ručně aktuální identitu změnit. Pokud ručně měníš DB, je to problém no :)
- Panda
- Člen | 569
Při změně práv v aplikaci se identita bude měnit docela těžko. Je to aplikovatelné jen na případ, kdy si uživatel mění práva sám sobě. Identity jiných uživatelů nemáš normálně k dispozici, protože se ukládají do session (a procházet serializované sessions a hledat tam identity onoho uživatele není úplně nejelegantnější).
Řešení tam ale je, napadla mě hned dvě.
První z nich je trochu univerzálnější. Spočívá ve vytvoření
vlastního globálního úložiště identit a podědění třídy
User
tak, aby toto úložiště využívala – při přiřazení
identity uživateli (setIdentity()
) by se identita neukládala
přímo do session, ale uložila by se do onoho globálního úložiště pod
nějakým klíčem (pozor, jeden uživatel může mít více identit, takže
klíče budou 2: uživatelské jméno a nějaké vygenerované UID) a až ten
pak uložit do session. V metodě getIdentity()
by pak nová
třída User
hledala novou identitu v globálním úložišti.
Toto úložiště by pak samozřejmě bylo dostupné kdekoliv v aplikaci a při
změně práv či profilu by šly údaje změnit pro všechny aktuální
identity uživatele.
Druhá se týká jen oprávnění s využitím třídy
Permission
. Pro každého uživatele by do objektu
Permission
vytvořila „pseudorole“ s jeho uživatelským
jménem, která by za rodiče měla všechny role daného uživatele (v Tvém
případě by ta role byla jen jedna – role_key
z databáze).
Uživateli by se pak do identity nastavila tato „pseudorole“. Při změně
oprávnění by se invalidoval objekt Permission
v cache a role by
se sestavily znovu – tentokrát by ale „pseudorole“ uživatele měla
jiné rodičovské role a tak by se promítla nová oprávnění. Aby se
předešlo velkému množství rolí v objektu „Permission“, šlo by
rozdělit jeho sestavování do 2 fází – sestavení obecného objektu
Permission
(společný základ pro všechny uživatele) a
přidání oné „pseudorole“ pro každého uživatele zvlášť. Do cache by
se pak mohl uložit i objekt pro daného uživatele (samozřejmě pod pro něj
unikátním klíčem – uživatelské jméno) a nastavit mu závislost na
obecný objekt Permission
v cache. Při invalidaci onoho obecného
objektu by se automaticky invalidovaly i objekty závislé a oprávnění by se
opět aktualizovala.