How to use simple roles for authorization in application?
- chemix
- Nette Core | 1310
What i want to use?
I want use roles for a simple application access.
<?php
...
if ($user->isInRole('photograph')){
// can upload images
}
if ($user->isInRole('supervisor')){
// can public article
}
...
?>
is this good way? or bad way? I want use the simplest way :)
How i setup config and authenticator
services:
authenticator: Authenticator
authorizator:
class: Nette\Security\Permission
setup:
- addRole('user')
- addRole('photograph', 'user')
- addRole('writer', 'photograph')
- addRole('supervisor', 'writer')
- addRole('adsmanager', 'supervisor')
- addRole('admin', 'adsmanager')
- addRole('root', 'admin')
from authenticate method:
<?php
...
$arr = $row->toArray();
unset($arr['password']);
return new Nette\Security\Identity($row->id, $row->role, $arr);
...
?>
Problem
i hope i get all roles for user chemix, ex. if chemix is in role admin (db row: username ⇒ chemix, role ⇒ admin) i expect that has also roles adsmanager, supervisor,…
but this dump said no :-(
<?php
class DashboardPresenter extends BasePresenter {
/**
* @var \Nette\Security\IAuthorizator @inject
*/
var $auth;
public function renderDefault()
{
dump($this->auth->getRoles());
echo '-';
dump($this->user->getRoles());
echo '-';
dump($this->user->isInRole('root'));
dump($this->user->isInRole('admin'));
dump($this->user->isInRole('adsmanager'));
dump($this->user->isInRole('supervisor'));
dump($this->user->isInRole('writer'));
dump($this->user->isInRole('photograph'));
dump($this->user->isInRole('user'));
}
}
?>
returns
array (7)
0 => "user" (4)
1 => "photograph" (10)
2 => "writer" (6)
3 => "supervisor" (10)
4 => "adsmanager" (10)
5 => "admin" (5)
6 => "root" (4)
-
array (1)
0 => "admin" (5)
-
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
is this behaviour correct?, and only i don't understand how to us it? or is it fault?
(tested on Nette 2.1.0-RC4)
- enumag
- Member | 2118
The roles in Permission are all roles that can be used in the application. However which roles the current user has depends on what roles you give him in your authenticator when you're creating the Identity.
return new Nette\Security\Identity($row->id, $row->role, $arr); // $row->role is probably just a string "admin"
Last edited by enumag (2013-12-20 11:53)
- chemix
- Nette Core | 1310
Thanks. I mixed two different things, Identity and Permissions. Now i know that Identity has no idea about Permissions, and roles inheritance works only with Permissions.
So how i resolve my task? There is two possibilities.
Simple way (but maybe not the right way :-)
i changed enum column to set, for specify more roles for user. And update code for new Identity
<?php
...
$arr = $row->toArray();
unset($arr['password']);
return new Nette\Security\Identity($row->id, explode(',',$row->role), $arr);
...
?>
now i have in db
(db row: username => chemix, role => "admin,user,photograph,writer,supervisor,adsmanager"
)
i removed authorizator section from config
and dump is
<?php
class DashboardPresenter extends BasePresenter {
public function renderDefault()
{
dump($this->user->getRoles());
echo '-';
dump($this->user->isInRole('root'));
dump($this->user->isInRole('admin'));
dump($this->user->isInRole('adsmanager'));
dump($this->user->isInRole('supervisor'));
dump($this->user->isInRole('writer'));
dump($this->user->isInRole('photograph'));
dump($this->user->isInRole('user'));
}
}
?>
array (6)
0 => "admin" (5)
1 => "adsmanager" (10)
2 => "supervisor" (10)
3 => "writer" (6)
4 => "photograph" (10)
5 => "user" (4)
-
FALSE
TRUE
TRUE
TRUE
TRUE
TRUE
TRUE
it's work :) maybe dirty way, but works
second way is
Use Permissions (better, but not harder ;-)
database scheme
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL,
`salt` char(32) NOT NULL,
`password` char(64) NOT NULL,
`email` varchar(255) NOT NULL,
`role` enum('root','admin','adsmanager','supervisor','writer','photograph','user') NOT NULL DEFAULT 'user',
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
config.neon
services:
authenticator: Authenticator
authorizator:
class: Nette\Security\Permission
setup:
- addRole('user')
- addRole('photograph', 'user')
- addRole('writer', 'photograph')
- addRole('supervisor', 'writer')
- addRole('adsmanager', 'supervisor')
- addRole('admin', 'adsmanager')
- addRole('root', 'admin')
- addResource('Ads')
- addResource('Photos')
- addResource('Articles')
- addResource('Users')
- allow('adsmanager', 'Ads', 'view')
- allow('adsmanager', 'Ads', 'add')
- allow('adsmanager', 'Ads', 'edit')
- allow('photograph', 'Photos', 'add')
- allow('writer', 'Articles', 'view')
- allow('writer', 'Articles', 'add')
- allow('supervisor', 'Articles', 'publish')
- allow('admin', 'Users', 'view')
- allow('admin', 'Users', 'add')
Authenticator
<?php
...
$arr = $row->toArray();
unset($arr['password']);
return new Nette\Security\Identity($row->id, $row->role, $arr);
...
?>
and tests
<?php
class DashboardPresenter extends BasePresenter {
public function renderDefault()
{
dump($this->user->isAllowed('Photos', 'add'));
dump($this->user->isAllowed('Articles', 'publish'));
dump($this->user->isAllowed('Ads', 'view'));
dump($this->user->isAllowed('Ads', 'add'));
dump($this->user->isAllowed('Users', 'add'));
}
}
?>
returns for user = chemix with role = adsmanager
TRUE
TRUE
TRUE
TRUE
FALSE
wow, amazing :) the inherittence works perfect, and it's more powerful and open for future that only asking for a user role.
Once again thanks to enumag and his help on jabber and his comment https://forum.nette.org/…-permissions#…
- enumag
- Member | 2118
I'd like to recommend you one more think. I don't think its good to set this up in the config file because you can't have the rules stored in database and you can't use permission assertion callbacks. I recommend using this: https://forum.nette.org/…zace-pouziti#….