Nette\Security\Permission s namespaces
- cmelis
- Člen | 26
Ahoj, zkouším rozchodit modulární aplikaci, oprávnění a role ale mám problém s resources:
Class Acl.php:
<?php
use Nette\Security\Permission;
class Acl extends Permission
{
public function __construct()
{
// roles
$this->addRole('guest');
$this->addRole('registered', 'guest');
$this->addRole('editor', 'registered');
$this->addRole('admin');
// resources
$this->addResource('AdminModule/DefaultPresenter');
$this->addResource('AdminModule/PagePresenter');
$this->addResource('AdminModule/UserPresenter');
// privileges
$this->allow('registered', 'AdminModule/DefaultPresenter', Permission::ALL);
$this->allow('editor', 'AdminModule/PagePresenter', Permission::ALL);
$this->allow('admin', Permission::ALL, Permission::ALL);
}
}
?>
v config.ini mám:
service.Nette-Security-IAuthenticator = Auth
service.Nette-Security-IAuthorizator = Acl
a když se přihlásím, tak mi aplikace vyhodí InvalidStateException a to přesněji: „Resource ‚AdminModule\DefaultPresenter‘ does not exist.“
Do $this->addResource(‚AdminModule/DefaultPresenter‘); jsem zkoušel zadat i ‚Admin:Default‘, ‚Default‘, ‚default‘.
Chtěl jsem se zeptat co tam má být uvedeno, když presenter je AdminModule/DefaultPresenter, případně kde by mohla být příčina problému pokud je někde jinde?
Předem mockrát děkuji za rady.
- westrem
- Člen | 398
Moznoze je tato otazka uz niekde zodpovedana, no minimalne v quick starte a ani v seriali som nenasiel ani zmienku o tom, ze by bolo mozne takto nastavovat pristup ludom priamo k metodam presenteru:
Ak spravne chapem uvedeny priklad, tak napriklad kod:
<?php
$this->allow('registered', 'AdminModule/DefaultPresenter', 'edit');
?>
by userovi v roli registered spristupnilo metodu editAction v presenteru AdminModule/DefaultPresenter, je to tak?
Ak ano, handluje toto Nette automaticky, alebo mas na to potom v presenteru napisany nejaky kus kodu, ktory to osetruje?
PS: Este jedna otazocka na zaver, pred niekolkymi mesiacmi, ked este quick start nebol v takej podobe v akej je teraz, tak sa mi vidi, ze niecoho podobneho sa dalo dosiahnut pomocou anotacii, je to stale mozne? Ak ano, vie niekto poskytnut ukazkovy kod? Neviem sa totiz teraz k tomu nijak preklikat. Dakujem
- Aurielle
- Člen | 1281
Nevím o tom, že by to Nette nějak řešilo automaticky… používám
mírně upravenou anotační metodu:
basePresenter:
protected function startup()
{
$this->authCheck();
parent::startup();
}
/**
* Provides an authentication check on methods and classes marked with @secured annotation
* @return
*/
protected function authCheck()
{
$annotation = 'secured';
$actionMethod = $this->formatActionMethod($this->action);
$signalMethod = $this->formatSignalMethod($this->signal);
$renderMethod = $this->formatRenderMethod($this->view);
if($this->hasAnnotation($annotation))
{
$authenticate = TRUE;
$flag = $this->getAnnotation($this->getReflection(), $annotation);
}
elseif($this->hasMethodAnnotation($actionMethod, $annotation))
{
$authenticate = TRUE;
$reflection = MethodReflection::from($this, $actionMethod);
$flag = $this->getAnnotation($reflection, $annotation);
}
elseif($this->isSignalReceiver($this) && $this->hasMethodAnnotation($signalMethod, $annotation))
{
$authenticate = TRUE;
$reflection = MethodReflection::from($this, $signalMethod);
$flag = $this->getAnnotation($reflection, $annotation);
}
elseif($this->hasMethodAnnotation($renderMethod, $annotation))
{
$authenticate = TRUE;
$reflection = MethodReflection::from($this, $renderMethod);
$flag = $this->getAnnotation($reflection, $annotation);
}
else
{
$authenticate = FALSE;
$flag = NULL;
}
$user = Environment::getUser();
if($authenticate)
{
if(!$user->isLoggedIn())
{
if($user->getLogoutReason() === User::INACTIVITY)
{
$this->flashMessage('Pro neaktivitu jste byl odhlášen. Přihlaste se prosím znovu.', 'warning');
}
$this->flashMessage('Pro přístup k této operaci se prosím přihlaste.', 'warning');
$backlink = $this->getApplication()->storeRequest();
$this->redirect(':Viewer:Auth:login', array('backlink' => $backlink));
}
elseif(is_string($flag) || is_array($flag))
{
if(!$user->hasFlag($flag))
{
$this->flashMessage('Nemáte oprávnění pro přístup k této operaci.', 'error');
$this->redirect(':Viewer:Banlist:list');
}
}
}
}
/**
* Checks if class has a given annotation
* @param string $annotation
* @return bool
*/
protected function hasAnnotation($annotation)
{
return $this->getReflection()->hasAnnotation($annotation);
}
/**
* Checks if given method has a given annotation
* @param string $method
* @param string $annotation
* @return bool
*/
protected function hasMethodAnnotation($method, $annotation)
{
if(!$this->getReflection()->hasMethod($method)) return FALSE;
$rm = MethodReflection::from($this->getReflection()->getName(), $method);
return $rm->hasAnnotation($annotation);
}
/**
* Get all anotations of given name
* @param object $reflection
* @param string $name
* @return mixed
*/
protected function getAnnotation($reflection, $name)
{
$res = $reflection->getAnnotations();
if(isset($res[$name]))
{
if(sizeof($res[$name]) > 1)
{
return $res[$name];
}
else
{
return end($res[$name]);
}
}
else
{
return NULL;
}
}
Toto řešení je dělané na flagy a kopíroval jsem ho přímo z kódu, takže tam může ještě něco chybět… Původní návod se tu někde válí.