Автор Тема: Создание объекта Acl по данным из MySQL  (Прочитано 32703 раз)

0 Пользователей и 1 Гость смотрят эту тему.

Оффлайн IgorN

  • Team
  • Герой
  • ***
  • Сообщений: 2908
  • Карма: 90
    • Мой сайт
Re: Создание объекта Acl по данным из MySQL
« Ответ #60 : Февраль 26, 2009, 19:09:24 »
Игорь, спасибо, все фирменно работает. :)
Только по ходу еще вопрос:
Как добиться назначения прав сразу всем ресурсам, не перечисляя их в базе (используя Вами предложенный вариант)?




Можно попробовать что то типа $this->_acl->allow('guest');
Мой сайт: http://igor-negrutsa.info/
Я знаю только то,что ничего не знаю, а многие не знают даже этого.

Оффлайн w1zard

  • Завсегдатай
  • **
  • Сообщений: 52
  • Карма: 1
Re: Создание объекта Acl по данным из MySQL
« Ответ #61 : Март 09, 2009, 04:06:54 »
Так это получается, все проверки производятся только в одном единственном плагине? Впринципе это очень удобно, но как быть, если мне допустим в шаблоне нужно проверить, если посетитель админ, то вывести ссылку "Админцентр", если другой - не выводить. Как получить объект ICore_Acl внутри контроллера?

Оффлайн rusk

  • Team
  • Опытный
  • ***
  • Сообщений: 99
  • Карма: 11
    • Alexey Suhih
Re: Создание объекта Acl по данным из MySQL
« Ответ #62 : Март 09, 2009, 07:34:17 »
Сделайте Action Helper

public function someAction()
{
    
$this->getHelper('acl')->cheKavo();
}
Лучше сделать и пожалеть, чем не сделать и потом пожалеть еще больше.

Оффлайн w1zard

  • Завсегдатай
  • **
  • Сообщений: 52
  • Карма: 1
Re: Создание объекта Acl по данным из MySQL
« Ответ #63 : Март 09, 2009, 23:08:30 »
Можете более детально показать, как такое сделать? (Не совсем понимаю суть хелперов или просто мало знаком)

Оффлайн Czar

  • Мастер
  • ****
  • Сообщений: 316
  • Карма: 14
Re: Создание объекта Acl по данным из MySQL
« Ответ #64 : Апрель 07, 2009, 13:32:21 »
может кто натолкнёт на мысль...в общем всё что прочситал по этой теме понятно,но ест некоторые ньюансы,например, у меня есть таблица с данными, которые вываливваются на странице построчно...эту таблицу заполняют несколько человек..и вот надо разграничить рпава так чтобы правил строку только тот кто добавил!..этоя понял ка ксделать, но вот как мне сделать так чтобы ссылка на страничке не выводилась если править строку не можешь?

вот этого догнать пока не могу:(

Оффлайн IgorN

  • Team
  • Герой
  • ***
  • Сообщений: 2908
  • Карма: 90
    • Мой сайт
Re: Создание объекта Acl по данным из MySQL
« Ответ #65 : Апрель 07, 2009, 15:34:35 »
напиши хэлпер
Мой сайт: http://igor-negrutsa.info/
Я знаю только то,что ничего не знаю, а многие не знают даже этого.

Оффлайн Czar

  • Мастер
  • ****
  • Сообщений: 316
  • Карма: 14
Re: Создание объекта Acl по данным из MySQL
« Ответ #66 : Апрель 07, 2009, 16:05:26 »
я просто не могу понять ка кыцепить совпадения..
в обще делаю так...
у меня есть в базе таблица юзеров по которым строятся роли <name, role>
далее у меня есть таблица куда эти юзеры заносят свои данные и там указывается их имя <value,date,user>

$acl 
= new Zend_Acl();
	
	
### основные роли
	
	
$acl->addRole(new Zend_Acl_Role('guest'))
	
	
	
->
addRole(new Zend_Acl_Role('staff'), 'guest')
	
	
	
->
addRole(new Zend_Acl_Role('editor'), 'staff')
	
	
	
->
addRole(new Zend_Acl_Role('administrator'))
	
	
;
	
	
### формируем основные ресурсы
	
	
$acl->add(new Zend_Acl_Resource('view'))
	
	
	
->
add(new Zend_Acl_Resource('add'),'view')
	
	
	
->
add(new Zend_Acl_Resource('edit'),'add')
	
	
	
->
add(new Zend_Acl_Resource('delete'),'edit')
	
	
;
	
	

	
	
#
                ### формируем роли по пользователям
	
	
$traders = new FlowTraders();
	
	

	
	
foreach(
$traders->getList()->toArray() as $usr)
	
	
{
	
	
	
$acl->addRole(new Zend_Acl_Role($usr['name']), $usr['role']);
	
	
}


и вот тут застряю, потому что в мануале пишут что, чтобы добавить исклучение нужно в метод allow четвёртым параметром добавить свой клас которы йбудет поределять разрешать или нет.. ну и так далее...то есть:

### разрешаем удалять или редактировать только свои срочки
$acl->allow('staff', array('edit''delete'),null, new isMine());


это тоже понятно, не понятно как в этом методе выловитьнужные мн е данные:(
пыталься делать так, но у меня роль вылазит стаф всё время.. вобще тут у меня ступор...
тут и там гдже проверяю в контроллере

<?php

class isMine implements Zend_Acl_Assert_Interface
{
    public function 
assert(Zend_Acl $acl,
                           
Zend_Acl_Role_Interface $role null,
                           
Zend_Acl_Resource_Interface $resource null,
                           
$privilege null)
    {
 
	
	
return 
$this->_isMine($role);
    }

    protected function 
_isMine($role)
    {
        
$auth Zend_Auth::getInstance();
	
	
if(!
$auth->hasIdentity()) return false;
	
	

	
	
return (
$auth->getIdentity() == $role->getRoleId()) ? true false;
    }
}

и если хелпер писать, то чтоон будет помагать?
или я просто неправильно строю сам клас ACL?



Оффлайн IgorN

  • Team
  • Герой
  • ***
  • Сообщений: 2908
  • Карма: 90
    • Мой сайт
Re: Создание объекта Acl по данным из MySQL
« Ответ #67 : Апрель 07, 2009, 16:19:54 »
Так ты добавил исключения для роли стаф $acl->allow('staff', array('edit', 'delete'),null, new isMine()); а хочешь для всех ролей или я не понял что то?
Мой сайт: http://igor-negrutsa.info/
Я знаю только то,что ничего не знаю, а многие не знают даже этого.

Оффлайн Czar

  • Мастер
  • ****
  • Сообщений: 316
  • Карма: 14
Re: Создание объекта Acl по данным из MySQL
« Ответ #68 : Апрель 07, 2009, 16:43:14 »
да.. видать я неправильно понял мануал...
да..я хочу для всех сделать, чтобы автоматом выбиралось.. но получается,что так не получится...
получается мне для каждего юзера и каждой строчки базы данных строить разрешения.. блин..

Оффлайн IgorN

  • Team
  • Герой
  • ***
  • Сообщений: 2908
  • Карма: 90
    • Мой сайт
Re: Создание объекта Acl по данным из MySQL
« Ответ #69 : Апрель 07, 2009, 16:47:36 »
да.. видать я неправильно понял мануал...
да..я хочу для всех сделать, чтобы автоматом выбиралось.. но получается,что так не получится...
получается мне для каждего юзера и каждой строчки базы данных строить разрешения.. блин..

Обратите внимание на строку в мануале $acl->allow(null, null, null, new CleanIPAssertion());
Это значит для всех ролей и всех ресурсов
Мой сайт: http://igor-negrutsa.info/
Я знаю только то,что ничего не знаю, а многие не знают даже этого.

Оффлайн Czar

  • Мастер
  • ****
  • Сообщений: 316
  • Карма: 14
Re: Создание объекта Acl по данным из MySQL
« Ответ #70 : Апрель 07, 2009, 17:36:45 »
так этоя понял...
мне просто не понятно, как вылавливать внутри класса, который даёт исключения, то что мне нужно,а нужно мне имя добавившего строку или id строки...потому как уже после создания класса ACL я что-то не нашёл ничего такого чтобы можно было передавать параметрами.
вобщем я пока пошёл лёгким путём и делал просто для каждой роли свои разрешения..благо их у меня меньше десяти.
в общем делаю так


### формируем роли по пользователям
	
	
$traders = new FlowTraders();
	
	

	
	
foreach(
$traders->getList()->toArray() as $usr)
	
	
{
	
	
	
$acl->addRole(new Zend_Acl_Role($usr['name']), $usr['role']);
	
	
	
$acl->add(new Zend_Acl_Resource('edit:'.$usr['name']),'edit');
	
	
	
$acl->add(new Zend_Acl_Resource('delete:'.$usr['name']),'edit');
	
	
	
$acl->allow($usr['name'],null,array('edit:'.$usr['name'], 'delete:'.$usr['name']));
	
	
}

а далеев контроллере

$edit
	
$this->_acl->isAllowed($this->user,null,'edit:'.$user) ? true false;


и в общем то у меня получается то,чтоя хотел... правда пока не допонял сути этого всего класса, но нужного достиг...надо глубже разбираться, так как проект будет расти и всё сложнее будет костыли вставлять...
« Последнее редактирование: Апрель 07, 2009, 17:39:04 от Czar »

Оффлайн IgorN

  • Team
  • Герой
  • ***
  • Сообщений: 2908
  • Карма: 90
    • Мой сайт
Re: Создание объекта Acl по данным из MySQL
« Ответ #71 : Апрель 07, 2009, 17:56:31 »
Имя можно узнать так же как вы роль узнаете

protected function _isMine($role)
    {
        
$auth Zend_Auth::getInstance();
	
	
if(!
$auth->hasIdentity()) return false;
	
	

	
	
return (
$auth->getIdentity() == $role->getRoleId()) ? true false;
    }


черещ объект $auth. Айди строки тут уже сложнее может как то из ресурса вытянуть или из строки запроса. Думать надо и гуглить .
Мой сайт: http://igor-negrutsa.info/
Я знаю только то,что ничего не знаю, а многие не знают даже этого.

Оффлайн Czar

  • Мастер
  • ****
  • Сообщений: 316
  • Карма: 14
Re: Создание объекта Acl по данным из MySQL
« Ответ #72 : Апрель 07, 2009, 18:57:05 »
кончно можно.. прочитав мануал,
Цитировать
Методу assert() объекта утверждения передаются ACL, роль, ресурс и привилегия, к которым применяется запрос на авторизацию (например, isAllowed()). Это нужно для предоставления контекста классу утверждения и определения его условий там, где это нужно.
я подумал, что когда я буду делать
$acl->isAllowed($role,null,$priv)

то у меня в мой класс IsMine будет передаваться роль которая проверяется... оказалось я неправ и передаётся роль, которая передапвалась прпи вормировании метода allow, то есть
$acl->allow($ThisRoleIsPassingToIsMine,null,'edit',new IsMine())

что мне совсем не подошло.

Оффлайн IgorN

  • Team
  • Герой
  • ***
  • Сообщений: 2908
  • Карма: 90
    • Мой сайт
Re: Создание объекта Acl по данным из MySQL
« Ответ #73 : Апрель 08, 2009, 10:19:21 »
Думаю гугл, помог бы, данную задачку думаю не вы первый решаете.
Мой сайт: http://igor-negrutsa.info/
Я знаю только то,что ничего не знаю, а многие не знают даже этого.

Оффлайн vovikha

  • Завсегдатай
  • **
  • Сообщений: 30
  • Карма: 3
Re: Создание объекта Acl по данным из MySQL
« Ответ #74 : Июль 28, 2009, 18:55:20 »
после нескольких ухищрений создал свой вариант ACL из базы данных


class Core_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
{
	
public function 
preDispatch(Zend_Controller_Request_Abstract $request)
	
{
	
	
//get Acl Model
	
	
$model = new Core_Controller_Plugin_Acl_Model_DbTable();
	
	
//create Acl Obj
	
	
$acl = new Zend_Acl();
	
	
//add roles
	
	
foreach(
$model->getRoles() as $v){
	
	
	
if(
$v['parent'] == null){
	
	
	
	
$acl->addRole(new Zend_Acl_Role($v['role']));
	
	
	
}else{
	
	
	
	
$acl->addRole(new Zend_Acl_Role($v['role']), $v['parent']);
	
	
	
}
	
	
}
	
	
//add resources
	
	
foreach(
$model->getResources() as $v){
	
	
	
if(
$v['parent'] == null){
	
	
	
	
$acl->add(new Zend_Acl_Resource($v['resource']));
	
	
	
}else{
	
	
	
	
$acl->add(new Zend_Acl_Resource($v['resource']), $v['parent']);
	
	
	
}
	
	
}
	
	
//add rules
	
	
foreach(
$model->getRules() as $v){
	
	
	
switch(
$v['ruleType']){
	
	
	
	
case 
'allow' :
	
	
	
	
	
$acl->allow($v['role'], $v['resource'], $v['privilege']);
	
	
	
	
break;
	
	
	
	
case 
'deny' :
	
	
	
	
	
$acl->deny($v['role'], $v['resource'], $v['privilege']);
	
	
	
	
break;
	
	
	
}
	
	
}
	
	
//save ACL object
	
	
Zend_Registry::set('ZendAcl'$acl);
	
}

}


Дальше самое интерестное - модель


class Core_Controller_Plugin_Acl_Model_DbTable 
{
	
protected 
$_dbAdapter;
	
public function 
__construct(){
	
	
$this->_dbAdapter Zend_Registry::get('dbAdapter');
	
	
$this->_dbAdapter->setFetchMode(Zend_Db::FETCH_ASSOC);
	
}
	

	
public function 
getRoles()
	
{
	
	
//@todo unique roles
	
	
$sql "SELECT DISTINCT r.name AS role, 
	
	
	
	
p.name AS parent
	
	
	
FROM role AS r
	
	
	
	
LEFT JOIN role AS p
	
	
	
	
ON r.status = 1 
	
	
	
	
	
AND p.status = 1 
	
	
	
	
	
AND r.role_id = p.id"
;

	
	
$result $this->_dbAdapter->fetchAll($sql);
	
	
return 
$result;
	
}
	

	
public function 
getResources()
	
{
	
	
//@todo unique resources
	
	
$sql "SELECT DISTINCT r.name AS resource, 
	
	
	
	
p.name AS parent
	
	
	
FROM resource AS r
	
	
	
	
LEFT JOIN resource AS p
	
	
	
	
ON r.status = 1 
	
	
	
	
	
AND p.status = 1 
	
	
	
	
	
AND r.resource_id = p.id"
;
	
	

	
	
$result $this->_dbAdapter->fetchAll($sql);
	
	
return 
$result;
	
}
	

	
public function 
getRules()
	
{
	
	
$sql "SELECT DISTINCT
	
	
	
rule.id as ruleId,
	
	
	
rule.type as ruleType,
	
	
	
role.name as role,
	
	
	
resource.name as resource,
	
	
	
privilege.name as privilege
	
	
	
FROM rule, role, resource, privilege
	
	
	
WHERE rule.status = 1
	
	
	
	
AND role.status = 1
	
	
	
	
AND resource.status = 1
	
	
	
	
AND privilege.status = 1
	
	
	
	
AND rule.role_id = role.id 
	
	
	
	
AND rule.resource_id = resource.id
	
	
	
	
AND rule.privilege_id = privilege.id
	
	
	
ORDER BY rule.order"
;

	
	
$result $this->_dbAdapter->fetchAll($sql);
	
	

	
	
return 
$result;
	
}
}


Сама база



-- -----------------------------------------------------
-- 
Table `privilege`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `privilege` (
  `
idINT(11NOT NULL AUTO_INCREMENT ,
  `
nameVARCHAR(45CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL ,
  `
statusTINYINT(1NULL DEFAULT ,
  `
descriptionTEXT CHARACTER SET 'utf8' COLLATE 'utf8_bin' NULL DEFAULT NULL ,
  
PRIMARY KEY (`id`) ,
  
UNIQUE INDEX `name_UNIQUE` (`nameASC) )
ENGINE InnoDB
AUTO_INCREMENT 
3
DEFAULT CHARACTER SET utf8
COLLATE 
utf8_bin;


-- -----------------------------------------------------
-- 
Table `resource`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `resource` (
  `
idINT(11NOT NULL AUTO_INCREMENT ,
  `
nameVARCHAR(45CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL ,
  `
statusTINYINT(1NULL DEFAULT ,
  `
descriptionTEXT CHARACTER SET 'utf8' COLLATE 'utf8_bin' NULL DEFAULT NULL ,
  `
resource_idINT(11NULL DEFAULT NULL ,
  
PRIMARY KEY (`id`) ,
  
INDEX `fk_resource_resource1` (`resource_idASC) ,
  
UNIQUE INDEX `name_UNIQUE` (`nameASC) ,
  
CONSTRAINT `fk_resource_resource1`
    
FOREIGN KEY (`resource_id` )
    
REFERENCES `resource` (`id` )
    
ON DELETE NO ACTION
    ON UPDATE NO ACTION
)
ENGINE InnoDB
AUTO_INCREMENT 
3
DEFAULT CHARACTER SET utf8
COLLATE 
utf8_bin;


-- -----------------------------------------------------
-- 
Table `role`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `role` (
  `
idINT(11NOT NULL AUTO_INCREMENT ,
  `
nameVARCHAR(45CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL ,
  `
statusTINYINT(1NULL DEFAULT ,
  `
descriptionTEXT CHARACTER SET 'utf8' COLLATE 'utf8_bin' NULL DEFAULT NULL ,
  `
role_idINT(11NULL DEFAULT NULL ,
  
PRIMARY KEY (`id`) ,
  
INDEX `fk_role_role1` (`role_idASC) ,
  
UNIQUE INDEX `name_UNIQUE` (`nameASC) ,
  
CONSTRAINT `fk_role_role1`
    
FOREIGN KEY (`role_id` )
    
REFERENCES `role` (`id` )
    
ON DELETE NO ACTION
    ON UPDATE NO ACTION
)
ENGINE InnoDB
AUTO_INCREMENT 
3
DEFAULT CHARACTER SET utf8
COLLATE 
utf8_bin;


-- -----------------------------------------------------
-- 
Table `rule`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `rule` (
  `
idINT(11NOT NULL AUTO_INCREMENT ,
  `
role_idINT(11NULL ,
  `
resource_idINT(11NULL ,
  `
privilege_idINT(11NULL ,
  `
orderINT(11UNSIGNED NOT NULL ,
  `
typeENUM('allow','deny'CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL ,
  `
statusTINYINT(1NULL DEFAULT ,
  
PRIMARY KEY (`id`) ,
  
INDEX `fk_rule_role1` (`role_idASC) ,
  
INDEX `fk_rule_resource1` (`resource_idASC) ,
  
INDEX `fk_rule_privilege1` (`privilege_idASC) ,
  
UNIQUE INDEX `order_UNIQUE` (`orderASC) ,
  
CONSTRAINT `fk_rule_privilege1`
    
FOREIGN KEY (`privilege_id` )
    
REFERENCES `privilege` (`id` )
    
ON DELETE NO ACTION
    ON UPDATE NO ACTION
,
  
CONSTRAINT `fk_rule_resource1`
    
FOREIGN KEY (`resource_id` )
    
REFERENCES `resource` (`id` )
    
ON DELETE NO ACTION
    ON UPDATE NO ACTION
,
  
CONSTRAINT `fk_rule_role1`
    
FOREIGN KEY (`role_id` )
    
REFERENCES `role` (`id` )
    
ON DELETE NO ACTION
    ON UPDATE NO ACTION
)
ENGINE InnoDB
DEFAULT CHARACTER SET utf8
COLLATE 
utf8_bin;


И еще пример использования


$aclResult 
$acl->isAllowed($role$resource$privilege) ? "allowed" "denied";
//$role - роль пользователя
//$resource - ресурс
//$privilege - уровень доступа (view, edit, etc.)


Не забываем подключить плагин в загрузчике

Основная идея была в проектировании хорошей и гибкой базы данных
насколько вышло судить вам.
« Последнее редактирование: Июль 13, 2011, 15:33:16 от vovikha »