В том виде в котором у меня этого не надо, т.к. есть наследование ролей :РАвтор оригинала: Вурдалак
korchasa, т.е. в том виде, что у тебя сделан сейчас ACL так сделать нельзя?![]()
а "стандартных acl" ресурс - это что?аналог ресурса(или привилегии, зависит от реализации), в стандартных acl
// Tables
// roles, resources, acl, user_roles
class User implements lmbRoleProviderInterface {
// ...
protected function onLoad()
{
Acl::instance()->addRole('?', $this->getRoles());
}
public function getRole()
{
return '?';
}
}
// ...
if( $acl->isAllowed($user, 'ban') ) {
// User has the banhammer
}
class Category implements lmbRoleResolver {
function getRoleFor(User $user)
{
if($this->getAdministratorId() === $user->getId())
return 'category_administrator';
}
}
class Category implements accessibleInterface {
public checkAccessFor(User $user)
{
return in_array($user->id, $this->getModeratorList());
}
}
Да ничем почти. Стандартная acl с наследованием ролей. Там сильно по другому и не напишешь. Ну только объектов для ресурсов и ролей у меня нет, и динамический резолвинг. Хотя они его тоже недавно вроде бы написали.Автор оригинала: Вурдалак
korchasa, ну, вопрос скорее по теории, нежели по твоему классу (кстати, чем он от Zend_Acl отличается?). Имена ролей в коде у тебя фигурируют?
class Category implements accessibleInterface {
public checkPrivilegeFor(User $user, $privilege)
{
switch( $privilege ) {
case 'view':
return TRUE;
case 'moderate':
return in_array($user->id, $this->getModeratorList());
default:
return FALSE;
}
}
}
// ...
if( $acl->isAllowed($user, 'category', 'view') ) {
// ...
}
$acl->isAllowed($user, $article, 'view')
{{allowed resource="<name|provider>" [role="<name|provider>"] [privilege="<name>"]}}foo{{/allowed}}
class Category implements lmbRoleResolver {
function getRoleFor(User $user)
{
if($this->getAdministratorId() === $user->getId())
return 'category_administrator';
}
}
class Controller implements lmbResourceProviderInterface
{
// ...
public before()
{
// ...
$acl = Acl::instance();
if( ! $acl->isAllowed($this->getUser(), $this, $this->getRequest()->getAction()) )
{
// Redirect to http://example.com/noaccess.html
}
}
public function getResource()
{
return $this->getRequest()->getController();
}
}
class Controller_Article extends Controller
{
public function actionView($id = NULL)
{
// ...
}
public function actionEdit($id = NULL)
{
// ...
}
}
В общем, я вижу решение в использовании обычных проверок в самом методе в таких скользких случаях. Что-то вродеАвтор оригинала: Вурдалак
Мне не нравится привязка к имени роли в последнем примере. Список ролей хранится в таблице, что само по себе подразумевает возможность удаления таковых.
class Controller_Article extends Controller
{
public function actionView($id = NULL)
{
// ...
}
public function actionEdit($id = NULL)
{
$article = Model::factory('Article')->find($id);
$isModerator = Acl::instance()->isAllowed($this->getUser(), $this, 'edit') AND $article->inModeratorList($this->getUser());
$isOwner = $article->getUser()->getId() == $article->getOwnerId();
if( $isModerator OR $isOwner )
{
// User can edit the article
}
}
}
$acl->addRole('user');
$acl->addRole('owner');
$acl->addRole('moderator', 'owner');
$acl->addResource('article');
$acl->allow('owner', 'article', 'edit');
...
class User implements RoleProvider
{
function getRole()
{
return 'user';
}
}
class Article implements ResourceProvider, RoleResolver
{
function getRoleFor($user)
{
if ($this->isModeratorList($user))
return 'moderator';
if ($this->owner_id = $user->id)
return 'owner';
}
function getResource()
{
return 'article';
}
}
class Controller_Article extends Controller
{
public function actionEdit($id = NULL)
{
$article = Model::factory('Article')->find($id);
if( Acl::instance()->isAllowed($this->getUser(), $article, 'edit') )
{
// User can edit the article
}
}
}
class Acl
{
public static function instance()
{
if( self::$_instance === NULL ) {
// ...
foreach($db->getRoles() as $role) {
$acl->addRole('db:' . $role['name']);
}
foreach($db->getResources() as $resource) {
// Names like "controller:article", "model:article", ...
$acl->addResource(new Zend_Acl_Resource($resource['namespace'] . ':' . $resource['name']));
}
foreach($db->getRules() as $rule) {
// ...
}
// ...
}
return self::$_instance;
}
}
class User implements RoleProvider
{
protected $_role;
// ...
public function getRole()
{
if( $this->_role === NULL ) {
$this->_role = 'user:' . $this->id;
Acl::instance()->addRole($this->_role, $this->getRoles());
}
return $this->_role;
}
}
class Article implements ResourceProvider, RoleResolver
{
protected $_resourceId = 'model:article';
public function onLoad()
{
Acl::instance()
->addRole($_resourceId . ':owner')
->addRole($_resourceId . ':moderator', $_resourceId . ':owner')
->allow($_resourceId . ':owner', $_resourceId, 'edit');
}
public function getRoleFor($role)
{
if( $this->inModeratorList($user) )
return $_resourceId . ':moderator';
if( $this->owner_id = $user->id )
return $_resourceId . ':owner';
}
public function getResource()
{
return $_resourceId;
}
}