Problém s ACL – přidělení práv pro roly Guest
- plasmo
- Člen | 66
Tak a mám tu další problém, nevím jestli chybu dělám je, nebo si ze mě nette utahuje :-)
V aplikaci využívám ACL pro autorizaci a následnou autentizaci uživatelů, k některým částem webu potřebuji aby měl přístup tzv. host, např. k HomepagePresenter, ale bohužel i přes nadefinování práv pro hosta nemám šanci k danému presenteru přistoupit, zasílám úryvek kódu, kde definuji práva.
<?php
class Proj_Security_Acl2 extends Permission
{
const GUEST_ROLE = "guest";
const USER_ROLE = "user";
const EDITOR_ROLE = "editor";
const ADMIN_ROLE = "admin";
public function __construct()
{
// role
$this->addRole(self::GUEST_ROLE);
$this->addRole(self::USER_ROLE, self::GUEST_ROLE);
$this->addRole(self::EDITOR_ROLE, self::USER_ROLE);
$this->addRole(self::ADMIN_ROLE);
// zdroje
$this->addResource('HomepagePresenter');
$this->addResource('TestPresenter');
// privilegia
$this->allow(self::GUEST_ROLE,'HomepagePresenter', array('view'));
$this->allow(self::EDITOR_ROLE, 'TestPresenter', Permission::ALL);
$this->allow(self::ADMIN_ROLE, Permission::ALL, Permission::ALL);
}
}
?>
Co dělám špatně, nebo proč se nemůžu k homepage dostat bez přihlášení? Děkuji
EDIT: fixnuté zvýrazňovanie
Editoval kravčo (16. 9. 2010 12:26)
- toka
- Člen | 253
srigi napsal(a):
Rolu guest nepridavaj, tu pridava Nette samo. Vyskusaj, mozno to je problem.
Já tedy v dynamickém ACL roli guest
vždy přidávám sám.
Jenže já si myslím, že aby ti to fungovalo, tak se uživatel musí
úspěšně přihlásit a zároveň být v roli guest
. Takže
pokud platí !isLoggedIn()
, resp. !isAuthenticated()
,
tak zobrazíš to, co chceš ty pro „svého guesta“.
- kravčo
- Člen | 721
plasmo napsal(a):
Roli Guest nepřiřazuju, jen se ji snažím nastavit provilegia, protože nepřihlašený může stránku zobrazit, ale všichni ostatní již mají práv více.
srigi asi myslel niečo takéto:
<?php
class Proj_Security_Acl2 extends Permission
{
// ...
public function __construct()
{
// onedlho cez ServiceLocator, či ako sa bude volať...
$guest_role = Environment::getUser()->guestRole;
// role
$this->addRole($guest_role);
$this->addRole(self::USER_ROLE, $guest_role);
$this->addRole(self::EDITOR_ROLE, self::USER_ROLE);
$this->addRole(self::ADMIN_ROLE);
// ...
}
}
V tomto kóde chybu nevidím. Dôležité je aj to, ako testuješ, či má užívateľ právo na to-ono, tento kód skrátka (mne) nestačí…
// toto by malo fungovať aj bez prihlásenia užívateľa
$acl->isAllowed('guest', 'HomepagePresenter', 'view'); // TRUE
- plasmo
- Člen | 66
V tomto kóde chybu nevidím. Dôležité je aj to, ako testuješ, či má užívateľ právo na to-ono, tento kód skrátka (mne) nestačí…
// toto by malo fungovať aj bez prihlásenia užívateľa $acl->isAllowed('guest', 'HomepagePresenter', 'view'); // TRUE
Aha, no už tomu možná začínám přicházet na kobylku, jak píše asi Toka, k tomu aby mě to vzalo to asi vyžaduje přihlášení a zároveň aby přihlášený uživatel měl roly hosta. Testuju to takto:
<?php
abstract class SecuredPresenter extends BasePresenter
{
public function startup()
{
parent::startup();
$user = $this->getUser();
if (!$user->isLoggedIn()) {
if ($user->getSignOutReason() === User::INACTIVITY) {
$this->flashMessage('Uplynula doba neaktivity! Systém vás z bezpečnostních důvodů odhlásil.', 'warning');
}
$this->flashMessage('Pro vstup do této sekce se musíte přihlásit!', 'warning');
$backlink = $this->getApplication()->storeRequest();
$this->redirect(':Login:', array('backlink' => $backlink));
}else{
if (!$user->isAllowed($this->reflection->name, $this->getAction())) {
$this->flashMessage('Pro vstup do této části nemáte dostatečná opravánění!', 'warning');
$this->redirect(':HomePage:');
}
}
}
}
?>
Editoval plasmo (17. 9. 2010 21:07)
- plasmo
- Člen | 66
Tak jsem to přepracoval následovně:
btw: vycházím z tohoto "tutoriálu ":https://doc.nette.org/…thentication
SecuredPresenter
<?php
abstract class SecuredPresenter extends BasePresenter
{
public function startup()
{
parent::startup();
$user = $this->getUser();
if (!$user->isLoggedIn()) {
if ($user->getSignOutReason() === User::INACTIVITY) {
$this->flashMessage('Uplynula doba neaktivity! Systém vás z bezpečnostních důvodů odhlásil.', 'warning');
}
if (!$user->isAllowed($this->reflection->name, $this->getAction())){
$this->flashMessage('Pro vstup do této části nemáte dostatečná opravánění!', 'warning');
$this->redirect(':HomePage:');
}
}else{
if (!$user->isAllowed($this->reflection->name, $this->getAction())) {
$this->flashMessage('Pro vstup do této části nemáte dostatečná opravánění!', 'warning');
$this->redirect(':HomePage:');
}
}
}
}
?>
HomepagePresnter
<?php
class HomepagePresenter extends SecuredPresenter
{
public function renderDefault()
{
$this->template->anyVariable = 'any value';
}
public function startup()
{
parent::startup();
$user = $this->getUser();
if (!$user->isLoggedIn()) {
if ($user->getSignOutReason() === User::INACTIVITY) {
$this->flashMessage('Uplynula doba neaktivity! Systém vás z bezpečnostních důvodů odhlásil.', 'warning');
}
if (!$user->isAllowed($this->reflection->name, $this->getAction())) {
$this->flashMessage('Pro vstup do této části nemáte dostatečná opravánění!', 'warning');
$this->redirect('Login:');
}
}
else {
if (!$user->isAllowed($this->reflection->name, $this->getAction())) {
$this->flashMessage('Pro vstup do této části nemáte dostatečná opravánění!', 'warning');
$this->redirect('Login:');
}
}
}
public function actionLogout()
{
$this->getUser()->signOut();
$this->flashMessage('Právě jste byl odhlášen.','success');
$this->redirect('Homepage:');
}
}
?>
Jediný co se mi nelíbí je zdvojení podmínky
<?php
if (!$user->isAllowed($this->reflection->name, $this->getAction())) {
$this->flashMessage('Pro vstup do této části nemáte dostatečná opravánění!', 'warning');
$this->redirect('Login:');
}
?>
Je to takhle tedy použitelné co se správnosti týče? Funguje to, takže to já jsem spokojen, jen nechci aby to byla prasárna :)
A prosím ještě jsem nějak nepochopil, proč musí mít ty dva presentery stejnou metodu? Když vlastne Homepage dědí od Secure, proč se startup přetěžuje? Z tut, jsem to nepobral. Děkuji
Editoval plasmo (17. 9. 2010 21:06)
- kravčo
- Člen | 721
Najprv si prosím fixni zdrojáky v predošlých príspevkoch podľa návodu.
Rozhodovanie o prístupe by nemalo závisieť na tom, či je používateľ
prihlásený alebo nie. Malo by sa riadiť výhradne tým, či má používateľ
prístup k danému zdroju. Teda podmienka $user->isLoggedIn()
by sa mala v tvojom prípade využívať nanajvýš na zistenie odhlásenia po
dlhej nečinnosti. Duplikovanie podmienky nechápem, v jednom prípade sa
testuje a inak sa testuje tiež… žiadny rozdiel :)
<?php
abstract class SecuredPresenter extends BasePresenter
{
public function startup()
{
parent::startup();
$user = $this->getUser();
if (!$user->isLoggedIn() && $user->getSignOutReason() === User::INACTIVITY) {
$this->flashMessage('Uplynula doba neaktivity! Systém vás z bezpečnostních důvodů odhlásil.', 'warning');
}
if (!$user->isAllowed($this->reflection->name, $this->getAction())) {
$this->flashMessage('Pro vstup do této části nemáte dostatečná oprávnění!', 'warning');
$this->redirect(':HomePage:');
}
}
}
HomepagePresenter startup()
definovať opäť nemusí, v tomu
tutoriáli ho definuje opäť, pretože sa v niečom líšia…
<?php
class HomepagePresenter extends SecuredPresenter
{
public function renderDefault()
{
$this->template->anyVariable = 'any value';
}
public function actionLogout()
{
$this->getUser()->signOut();
$this->flashMessage('Právě jste byl odhlášen.', 'success');
$this->redirect('Homepage:');
}
}
Ďalší problém je, že prístup k tzv. fallback stránke by nemal byť nijako podmienený. Ak existuje používateľ, ktorý nemá prístup k HomepagePresenteru, pri jeho zobrazení sa mu stránka zacyklí. Preto mi príde správnejšie dediť HomepagePresenter od BasePresenteru a odstatné od SecuredPresenteru. Takisto nemôžeš riadiť prístup k stránke s prihlasovacím formulárom, vznikne rovnako nepríjemné zacyklenie :)
<?php
class HomepagePresenter extends BasePresenter { /* ... */ }
class AnotherPresenter extends SecuredPresenter { /* ... */ }
class YetAnotherPresenter extends SecuredPresenter { /* ... */ }