Práva na úrovni uživatelů

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

Ahoj,
potřebuji v aplikaci vyřešit problém, kdy každý uživatel může disponovat různými právy k určitým objektům. V tuhle chvíli mi však rozdělení práv na úrovni rolí nestačí. Samozřejmě, že vztahy jsou uložené někde v databázi. Otázkou je jak elegantně s těmito vztahy pracovat?

Používáte někdo nějaké rozšíření, návrh nad klasickým Nette\Security a Permissions, který by tohle řešil? Jde mi o přístup $user->isAllowed($article, $id). Vytvořit ze všech článků zdroje a uložit je do Permissions vidím snad správně jako hloupost.

Díky za odpovědi

PS: Google jsem použil, ale skoro všechno je 4 a více let staré a těžko říct, jestli to stále platí :-)

Editoval Climber007 (6. 11. 2014 15:37)

Jan Tvrdík
Nette guru | 2595
+
+4
-

Doporučuji vůbec rozhraní IAuthorizator a třídu Permissions nepoužívat. Napiš si na to vlastní třídu na míru tvojí aplikace. Může vypadat například takto.

Climber007
Člen | 105
+
0
-

Díky, tohle vypadá moc dobře :-)

MYPS
Člen | 2
+
+1
-

Nehledáš něco takového? https://github.com/myps/security

thm
Člen | 147
+
0
-

Osobně jsem řešil podobnou věc a nakonec jsem to vyřešil tak, že jsem si podědil Permission kde jsem přidal metodu:

/**
* Extended function of isAllowed, when id is set, checks if user has special permission to do this for item with ID of resource
* @param string $role
* @param string $resource
* @param string $privilege
* @param int $id
* @return bool
*/
public function isAllowedExt($role = self::ALL, $resource = self::ALL, $privilege = self::ALL, $id = NULL){
	$result = $this->isAllowed($role, $resource, $privilege);

	//Checks for permissions loaded on signIn to SessionSection acl->usersPermisssions
	if($id && !$result && $this->getSession()->usersPermissions)
		$result = in_array(array('role' => $role, 'resource' => $resource, 'privilege' => $privilege, 'id' => $id), $this->getSession()->usersPermissions);

	return $result;
}

A pozměnil jsem třídu User a její metodu isAllowed:

public function isAllowed($resource = IAuthorizator::ALL, $privilege = IAuthorizator::ALL, $id = NULL)
	{
		foreach ($this->getRoles() as $role) {
			if ($this->getAuthorizator()->isAllowedExt($role, $resource, $privilege, $id)) {
				return TRUE;
			}
		}

		return FALSE;
	}

Při přihlášení uživatele načtu do session jeho speciální práva ke konkrétním položkám s id (např. role = uzivatel1, resource = article, privilege = edit, id = 1).

V presenteru volám například:

$this->user->isAllowed('articles', 'edit', 1);

A když původní $result = $this->isAllowed($role, $resource, $privilege); vrátí FALSE, tak zkontroluju obsah session jestli se ta kombinace tam nevyskytuje a pokud ano, vrátím TRUE.

Vím že to asi není njsprávnějěší, pořád se s OOP a NETTE peru, ale takhle mi to prostě funguje.

Editoval thm (10. 11. 2014 11:34)