Uživatelské ROLE a přímé zadání URL
- Joacim
- Člen | 229
Zajímalo by mě, jak mám zamezit(přesměrovat), nějakým hezkým způsobem, přímé zadání url do browseru na které uživatel nemá roly/právo, nechci se v každém presenteru ptát jestli není uživatel admin → přesměruj na default page atd:.
Tzn: user má přístup pouze do Dashboard + Rezervace
admin má přístup všude
ovšem pokud zná uživatel adresu (z historie prohlížeče a pod) a zadá ji do browseru dostane se například do administrace, dá se tohle nastavit v config.neon nebo base presenteru ?
Jak generovat menu jsem již vyřešil v Generovaní menu dle role
Editoval Joacim (1. 4. 2015 14:31)
- Joacim
- Člen | 229
Šlo by poslat nějakou ukázku ? Princip chápu jen se v nette zatím moc neorientuji a hledat správné cesty přes vypsání objektů – var_dump (abych věděl co jaká proměná má uloženo), to se radši zeptám.
Mám si vypsat nette application request nebo existuje lepší cesta jak zjistit na co se uživatel odkazuje ?
- thm
- Člen | 147
// základní presenter
class BasePresenter extends Nette\Application\UI\Presenter{}
// Presenter který bude mít jenom startup - slouží ke kontrolování něčeho pro všechny presentery, které od něho budou dědit
class LoggedUserPresenter extends BasePresenter{
public function startup() {
parent::startup(); //V každém presenteru je NUTNÉ volat startup předka, pokud je startup v presenteru použitý.
if(!$this->user->isLoggedIn()){ //Nebo $user->isAllowed(), $user->isInRole() atd...
$this->flashMessage('Pro přístup do této části aplikace musíte být přihlášeni.');
$this->redirect('Ass:'); //Pošleme do...
}
}
}
// Pak už jenom dědíš od LoggedUserPresenteru a můžeš si být jistý že do view takto zděděných presenterů se dostane pouze přihlášený uživatel (v mém příkladě).
class UserInformationPresenter extends LoggedUserPresenter{
public function startup() {
parent::startup(); //Právě tady (v tomto případě) je nutné volat startup předka, jinak by se provedl startup jenom UserInformationPresenteru... Ale ty potřebuješ aby se provedla kontrola, jestli je uživatel přihlášený, nebo jestli má nějaké oprávnění apod.
...
...
...
//... další kód startupu.. Pokud bys zde (v tomto startupu neměl žádný kód), můžeš ho zcela vynechat.
}
}
Editoval thm (2. 4. 2015 11:02)
- greeny
- Člen | 405
Na tohle můžeš využít metodu Presenter::checkRequirements , např.:
class ProtectedPresenter extends BasePresenter
{
public function checkRequirements($element) {
if (!$this->user->isLoggedIn()) {
$this->redirect('Homepage:default');
}
}
}
- Joacim
- Člen | 229
Dá se to použít v Basepresenteru i na
$this->user->isInRole(‚admin‘) ?
jelikož mám nastaveno
$permission = new Permission();
/* seznam uživatelských rolí */
$permission->addRole('user');
$permission->addRole('admin');
/* seznam zdrojů */
$permission->addResource('Dashboard');
$permission->addResource('Reservations');
$permission->addResource('Setup');
$permission->addResource('Workflow');
/* seznam pravidel oprávnění */
$permission->allow('user', array('Dashboard', 'Reservations'), 'list');
//...
/* admin má práva na všechno */
$permission->allow('admin', Permission::ALL, Permission::ALL);
pro generováníé menu v default šabloně je to ok, teď už jen potřebuji hlídat přímé zadání url a je třeba zmínit že v mojí aplikaci je každý přihlášený, pokud není vidí jen přihlašovací okno
abstract class BasePresenter extends Nette\Application\UI\Presenter {
public function startup() {
parent::startup();
if (!$this->getUser()->isLoggedIn() && ($this->getName() !== "Login")) {
$this->redirect("Login:default");
} else {
if ($this->getUser()->isLoggedIn()) {
$this->template->userLogged = $this->user->identity->getId();
// Někde zde aplikovat pravidlo $this->user->isInRole('admin') a porovnat to s požadavkem na prezenter ?
} else {
$this->template->userLogged = FALSE;
}
}
}
}
Editoval Joacim (2. 4. 2015 13:07)
- Joacim
- Člen | 229
Problém nastane pokud uživatel není oprávněn a já volám redirect
class ProtectedPresenter extends BasePresenter{
public function checkRequirements($param) {
if ($this->user->isAllowed($this->request->presenterName)) {
//var_dump('Je OPRAVNEN');
} else {
//var_dump('Neni OPRAVNEN');
//$this->flashMessage('Nejste oprávněni přistupovat do ' . $this->request->presenterName, "danger");
$this->redirect("Dashboard:default");
}
}
}
dostanu hlášku
User Notice Possible problem: you are sending a HTTP header while already having some data in output buffer. Try Tracy\OutputDebugger or start session earlier.
Všechny presentery které mají omezený přístup dědí z ProtectedPresenter
- Joacim
- Člen | 229
Ted jsem zjistil, že tu hlášku skutečně zapříčinil var_dump() – za to se omlouvám
No zatím mám presenter pouze Setup(do něj muže přistupovat pouze uživatel s rolí admin) a k němu mám více odkazu(User, Users, Workflow) i šablon(user.latte, users.latte atd) a jen si v presenteru Setup volám příslušnou metodu pro kterou mám příslušný model, otázkou je jestli je to v rámci implementace atd dobře a nebo chybně – to zbnamená že pro každý presenter nemám pouze jeden template, ale vícero
<ul class="nav navbar-nav">
<li {ifCurrent Dashboard:} class="active" {/ifCurrent}><a href="{$basePath}/">Dashboard</a></li>
<li {ifCurrent Reservations:} class="active" {/ifCurrent}><a href="{$basePath}/reservations">reservation</a></li>
{if $user->isInRole('admin')}
<li {ifCurrent Approval:} class="active" {/ifCurrent}><a href="{$basePath}/approval">Schvalování</a></li>
<li {ifCurrent Setup:*} class="active" {/ifCurrent} class="dropdown" >
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Nastavení <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a n:href="Setup:users">users</a></li>
<li><a n:href="Setup:teams">teams</a></li>
<li><a n:href="Setup:departments">deprt</a></li>
<li class="divider"></li>
<li><a n:href="Workflow:default">wf</a></li>
</ul>
</li>
{/if}
</ul>
ale potom mám také
<ul class="nav navbar-nav loginAs">
<li class="dropdown" >
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Logged as <b>{$userLogged}</b> <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a n:href="Setup:user">Nastavení</a></li>
<li class="divider"></li>
<li><a n:href="Login:out">Odhlásit</a></li>
</ul>
</li>
</ul>
a nevím jak nastavit vyjímku aby mohl každý uživatel přistoupit do svého nastavení (Za předpokladu že nepoužuji jiný presenter)
<li><a n:href="Setup:user">Nastavení</a></li>
Editoval Joacim (2. 4. 2015 15:10)