Pozdní update práv při přihlášení

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

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
+
0
-

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
+
0
-

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
+
0
-

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.