dynamická správa rolí a nastavení config.neon
- spiider
- Člen | 162
Vím že se to tu již dost řešilo a taky jsem dost našel ale nikde jsem
nenašel kam nejlépe umístit ony soubory vytvořené na základě návodu
"":https://doc.nette.org/…oli-a-zdroju
Podle dokumentace jsem si vytvořil vlastní autentikátor ale nevím jak zapsat
acl do congif.neon
Již tam mám toto:authenticator:
class: Authenticator
Takže když to shrnu chtěl bych klidně i v bodech vědět: 1) Kam
umístit Acl.php a AclModel.php podle odkazu výše. 2) Jak vše registrovat
v config.neon
Poradíte někdo pls? Snad jsem to tu někde nepřehlédl.
Díky moc
- bojovyletoun
- Člen | 667
vytvořil bych si třeba továrnu, a do configu to zapsal takto. Ještě je třeba dolat věci jako dědičnost atd. V příkladu počítám s tím, že si do configu třeba budeš psát jen role, zbytek zůstává. Zatím to nedává moc smysl, ale nápad je snad jasný, jak předat parametry do továrny.
function createAuth($class,$roles)
{
$q=new $class;
foreach ($roles as $value) {
$q->addRole($value)
}
// konfigurace
přidat resource a povolit
return $q;
}
}
+config
services:
authorizator:
factory: createauth
arguments:
- \Nette\Security\Permission
- [admin,user]
Editoval bojovyletoun (1. 12. 2011 0:57)
- spiider
- Člen | 162
Role bych do configu nechtel psat, ty chci mit ulozene v DB, přesně jako v ukázkovém příkladu. Mám zatím vytvořeny dva soubory Acl.php který obsahuje toto:
class Acl extends \Nette\Security\Permission{
public function __construct() {
$model = new \AclModel();
foreach($model->getRoles() as $role)
$this->addRole($role->name, $role->parent_name);
foreach($model->getResources() as $resource)
$this->addResource($resource->name);
foreach($model->getRules() as $rule)
$this->{$rule->allowed == 'Y' ? 'allow' : 'deny'}($rule->role, $rule->resource, $rule->privilege);
}
}
a soubor AclModel.php který osahuje toto:
class AclModel extends Nette\Object {
const ACL_TABLE = 'acl';
const PRIVILEGES_TABLE = 'privileges';
const RESOURCES_TABLE = 'resources';
const ROLES_TABLE = 'roles';
public function getRoles() {
return dibi::fetchAll('SELECT r1.name, r2.name as parent_name
FROM ['. self::ROLES_TABLE . '] r1
LEFT JOIN ['. self::ROLES_TABLE . '] r2 ON (r1.parent_id = r2.id)
');
}
public function getResources() {
return dibi::fetchAll('SELECT name FROM ['. self::RESOURCES_TABLE . '] ');
}
public function getRules() {
return dibi::fetchAll('
SELECT
a.allowed as allowed,
ro.name as role,
re.name as resource,
p.name as privilege
FROM [' . self::ACL_TABLE . '] a
JOIN [' . self::ROLES_TABLE . '] ro ON (a.role_id = ro.id)
LEFT JOIN [' . self::RESOURCES_TABLE . '] re ON (a.resource_id = re.id)
LEFT JOIN [' . self::PRIVILEGES_TABLE . '] p ON (a.privilege_id = p.id)
ORDER BY a.id ASC
');
}
}
Kam tyto dva soubory nejlepe umístit? snazil jsem se vyčíst i něco z návodu na statické role a tam je, že se má vytvořit složka v libs/Acl a tam umístit soubor
A jak správně tyto soubory zaregistrovat v configu?
Popř. máte někdo jiné řešení?
Díky
- bojovyletoun
- Člen | 667
jo aha, ty už máš vše hotové a jde jenom o to, do které
složky uložiz.
Předpokládám, že ti běží RobotLoader, takže to dej do nějaké složky
kam vidí robotloader – defaultně prohledává libsDir a appDir (/app) –
takže do složky app/services třeba – oboje soubory přičemž do ještě
musíš nějak sdělit, že službu authorizator tvoří třída Acl. Možností
máš několik, třeba v bootstrap.php zavolat
$container->addService('authorizator',new Acl);
nebo do
configu:
services:
auhorizator: Acl
- JuniorJR
- Člen | 181
@spiider: No, lepší než to dávat ke každé akci, tak si to hoď v univerzální podobě do startup() a ještě lépe do nějakého SecuredPresenteru, od kterého budeš pak dědit dále všechny presentery, které mají být zabezpečené :)
class SecuredPresenter extends BasePresenter
{
protected function startup()
{
if ($this->user->isAllowed($this->name, $this->action)) {
...
} else {
$this->flashMessage('Action not allowed.');
}
}
}
Editoval JuniorJR (1. 12. 2011 15:16)
- bojovyletoun
- Člen | 667
spider: ta ukázka se mi moc nelíbí. 1)
$acl = new Acl();
je pohřbení DI pro získání autorizatoru použij
$this->context->authorizator
Ohledně toho zbytku, furt vypisovat zjistíš, že je to nuda. Říkáš, že
kontroluješ u akcí, tak by se hodilo v Basepresenteru přepsat metodu
checkRequirements.co tahle metoda dělá? je volána před každou akcí a
render a jejím úkolem je tedy vyhodit vyjímku, pokud user nemá práva.
Podívej se „https://api.nette.org/nette/2.0/source-Application.UI.Presenter.php.html#265“ – tahle metoda dělá podobnou věc, jen místo pro akce je volána pro presenter. Této funkci checkrequirements je předána reflection volané metody. TO že si ji můžeš přepsat sám, ti dá volnost. Můžeš kontrolovat úplně každou metodu nebo jen pokud má anotaci. Zároveň nemusíš ani nijak uvádět jméno to se zjistí z reflection.
Dost řečí, ukázka řekne víc. Související téma
public function checkRequirements($refl)
{
$act = substr($refl->name, 6); //uřízne 'action'
if ($refl->getAnnotation('auth') && !$this->presenter->user->isAllowed($act)) {
throw new Application\ForbiddenRequestException;
}
}
/** @auth */
function action FormatDisk($ip){}
Editoval bojovyletoun (1. 12. 2011 19:35)