Yii Framework Forum: RBAC и accessRules и updateOwnPost - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

RBAC и accessRules и updateOwnPost Rate Topic: -----

#1 User is offline   yes 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 12
  • Joined: 20-June 09

Posted 20 June 2009 - 12:16 PM

Друзья!
Пытаюсь разобраться с разделением прав и один момент никак не идёт.

Использую CDbAuthManager.
Добавил для пользователя следующие права

$auth = Yii::app()->authManager;
$role = $auth->createRole('manager');
$auth->createOperation('createPost', 'create a post');
$role->addChild('createPost');
$auth->assign('manager', '2');
$auth->createOperation('updatePost','редактирование записи');
$bizRule = 'return Yii::app()->user->id==$params["post"]->authID;';
$task = $auth->createTask('updateOwnPost','редактирование своей записи',$bizRule);
$task->addChild('updatePost');
$role->addChild('updatePost');

сдесь кажется всё понятно, кроме пары моментов
... $params["post"]->authID; ...

сдесь в качестве authID должно быть название поля в таблице где хранится id автора ?
и второе это
$task->addChild('updatePost');

зачем ?
и теперь самое главное и непонятное, а именно:
поидее вышеприведённым кодом, я указал что пользователю группы "manager" делать (я рассчитываю что это редактирование своих постов)) )
и что мне надо указать в функции accessRules контроллера PostController ?!  ???
пробовал вот такой момент

array('allow',
'actions' => array('updateOwnPost'),
'roles' => array('manager'),
),

но не работает, и что-то мне кажется что здесь получается некой дублирование.

Может быть здесь указывать что массив с правами из базы брать ?
мне кажется это логичным но я не нашёл как ?

вот последняя надежда на вас! спасайте!  ;)

0

#2 User is offline   yes 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 12
  • Joined: 20-June 09

Posted 22 June 2009 - 07:45 AM

да ладно вам ;) , признавайтесь, знаете же чем мне помочь !!!
0

#3 User is offline   mc.aser 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 22
  • Joined: 06-March 09

Posted 22 June 2009 - 08:26 AM

Ну
$task->addChild('updatePost');

Вам в коде не нужно будет проверять на
updateOwnPost, а только updatePost, но для пользователей которым разрешено редактировать только свои сообщения будет срабатывать еще и проверка на updateOwnPost, то есть свой ли это пост. То есть для выполнения операции updatePost для данного пользователя будет условием выполнение дополнительного условия проверки на авторство.

А вот как проверять на то что разрешено для меня пока тоже вопрос, по-ходу нужно писать фильтр, сейчас ищу как узнать в фильтре какое из действий выполняется, для составления запроса, названия скорее всего будет имя_операцииИмя_контролера ну и фильтр как-то должен выглядеть типа:
[code=php]
$params = "нужные для данного метода данные";
return Yii::app()->user->checkAccess('methodClass');
[/code]

0

#4 User is offline   mc.aser 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 22
  • Joined: 06-March 09

Posted 22 June 2009 - 10:09 AM

Вот что у меня вышло  ;D
[code=php]
      /**
* @return array action filters
*/
public function filters()
{
return array(
// если нужно тут можно отключить или наоборот указать каким действиям применять фильтр
'accessControlRBAC', // Проверка прав доступа на основе RBAC
);
}

/**/
public function filterAccessControlRBAC($filterChain) {
/**
* id указывается для редактирования пользователя, у нас есть правило что
* пользователь может редактировать только свой профиль, потому собираем параметры
* для бизнес-логики
*/
$params = isset($_GET['id']) ? array('userId'=>intval($_GET['id'])) : (isset($_POST['id']) ? array('userId'=>intval($_POST['id'])) : array()) ;

/* Собираем название действия */
$itemName = strtolower($this->getAction()->getId()).ucwords(strtolower($this->getId()));

/* Проверяем права */
if(!Yii::app()->user->checkAccess($itemName, $params)) {
/* Эсли пользователь не авторизирован отправляем на страницу с формой входа */
if(Yii::app()->user->isGuest)
$this->redirect(array('site/login'));
/**
* Эсли пользователь не гость значит ему не хватает прав доступа, думаю тут можно
* сделать рендер какого-то шаблона если это можно делать в фильтрах не проверял.
*/
else
throw new CHttpException(500,'Страница закрыта. У вас недостаточно прав для просмотра данной страницы.');

return false;
}

/* Ну если все хорошо выполняем остальные фильтры */
$filterChain->run();
return true;
}

						
						
0

#5 User is offline   yes 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 12
  • Joined: 20-June 09

Posted 26 June 2009 - 06:21 AM

Спасибо за ответ.

но ваш вариант у меня не сработал. у меня всегда 'true' получается.

$task->addChild('updatePost');

да, это всё понятно ... я запутался с тем, кто у кого child и думаю от этого частично и не получается. + надо в bizrule немного подкорректировать

0

#6 User is offline   yes 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 12
  • Joined: 20-June 09

Posted 26 June 2009 - 06:36 AM

странно получается, с тем списком правил котрый я привёл в первом посте, "updateOwnPost" даже не вызывается, соответственно и не срабатывает.
у меня получается так что пока не выполним
$role->addChild('updateOwnPost');

именно к роли работать не будет

тогда если так, то вот эта часть из мана всё равно не понятна
'updateOwnPost' просто не будет вызываться

$bizRule='return Yii::app()->user->id==$params["post"]->authID;';
$task=$auth->createTask('updateOwnPost','редактирование своей записи',$bizRule);
$task->addChild('updatePost');


растолкуйте если я где-то радикально ошибаюсь

ещё "момент" вот пример mc.aser

/* Собираем название действия */
$itemName = strtolower($this->getAction()->getId()).ucwords(strtolower($this->getId()));

мы в качестве $itemName updateOwnPost никогда не получим.
0

#7 User is offline   seb 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 240
  • Joined: 29-June 09

Posted 29 June 2009 - 10:44 AM

В accesRules нужно писать так:

array('allow',
  'actions' => array('create', 'update'),
  'roles' => array('updateOwnPost'),
),


Т.е в список 'roles' нужно писать не имя роли, а имя допустимых для данного action'a операций (или задач, tasks).
Сама задача, должна быть присвоена как дочерняя для роли:

$role = $auth->createRole('manager');
...
$role->addChild('updateOwnPost');


AuthManager когда будет проверять права для пользователя с ролью 'manager', определит что дочерняя операция 'updateOwnPost' разрешена.
С точки зрения раздачи прав доступа разницы между операциями, задачами и ролями вообще нет.
Тут весь смысл в создании операций, задач и ролей и создании правильных связей между ними:


$auth = Yii::app()->authManager;
$auth->createOperation('createPost', 'create a post');

$op = $auth->createOperation('updatePost','редактирование записи');
// Всем, кому можно создавать посты, можно и редактировать
$op->addChild('createPost');

$role = $auth->createRole('manager');
// Manager может создавать / редактировать записи
$role->addChild('updatePost');

// Пользователь с id=2 получает все права manager
$auth->assign('manager', '2');

// Сохраняем настройки RBAC - это делается только один раз
$auth->save();


Дальше в контроллере:

public function filters()
{
    return array(
    'accessControl', // perform access control for CRUD operations
);
}


public function accessRules()
{
    return array(
array('allow', 
'actions'=>array('create', 'update'),
'roles'=>array('createPost'),
),
array('deny',  // deny all users
'users'=>array('*'),
),
  );
}


Для aсtion'ов 'create' и 'update' разрешен доступ с ролью 'createPost', соответсвенно разрешен доступ и с ролями 'updatePost' и 'manager'.

Что же касается бизнес-правил, то я и сам еще до конца с ними не разобрался, но похоже, что они автоматически проверятся не могут, т.к. нужны дополнительные параметры, т.е. их можно использовать для дополнительного ограничения доступа уже внутри action'ов.

Кстати еще я не понял в чем отличие "операции" (operation) от "задачи" (task) - и тем и другим можно назначать дочерние операции и бизнес-правила.

Вообще, на мой взгляд, описание RBAC в "The Definitive Guide to Yii" 
непонятное и несколько вводящее в заблуждение - как раз куска на счет применения в accessRules() там не хватает.

0

#8 User is offline   mc.aser 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 22
  • Joined: 06-March 09

Posted 30 June 2009 - 04:24 AM

Quote

Вообще, на мой взгляд, описание RBAC в "The Definitive Guide to Yii" 

непонятное и несколько вводящее в заблуждение - как раз куска на счет применения в accessRules() там не хватает.


Абсолютно согласен, фильтр свой я и придумал что бы автоматом можно было передавать доп параметры для бизнес правил.
Кто общается с разработчиками попросите описать эту часть в документации...
0

#9 User is offline   yes 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 12
  • Joined: 20-June 09

Posted 30 June 2009 - 04:35 AM

Друзья, я кажется разобрался, спасибо большое за участие.
только я вот что думаю: если мы используем authManager, то есть создаём роли таски и операции, то корректнее в фильтре вызывать checkAccess, а не как в демке статично происать массив.
Или я не прав ?!

Хотя второй вариант поидее быстрее работать будет.
0

#10 User is offline   seb 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 240
  • Joined: 29-June 09

Posted 30 June 2009 - 04:58 AM

Quote

Абсолютно согласен, фильтр свой я и придумал что бы автоматом можно было передавать доп параметры для бизнес правил.

Кто общается с разработчиками попросите описать эту часть в документации...

Уже попросил, обещают описать - http://www.yiiframew...2.html#msg16312.

Quote

Друзья, я кажется разобрался, спасибо большое за участие.

только я вот что думаю: если мы используем authManager, то есть создаём роли таски и операции, то корректнее в фильтре вызывать checkAccess, а не как в демке статично происать массив.

Или я не прав ?!



Хотя второй вариант поидее быстрее работать будет.

Роли, таски и операции создаются один раз и сохраняются в базу или в файл.
Потом мы их можем использовать в методе accessRules(), тогда доступ проверяется автоматически. Или в фильтре вызывать checkAccess - но это имеет смысл только для операций с бизнес правилами, которым нужно передавать дополнительные параметры.
Хотя с другой стороны, можно вообще не писать бизнес-правила, а доступ проверять уже внутри action'a:

public function actionUpdate()
{
    if (Yii::app()->user->checkAccess('updateOwnPost') &&
        !Yii::app()->user->checkAccess('updatePost')) {
        // проверить, что пользователь пытается редактировать свой пост
    }
}  



0

#11 User is offline   mc.aser 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 22
  • Joined: 06-March 09

Posted 02 July 2009 - 07:23 AM

Quote

Хотя с другой стороны, можно вообще не писать бизнес-правила, а доступ проверять уже внутри action'a:


public function actionUpdate()
{
    if (Yii::app()->user->checkAccess('updateOwnPost') &&
        !Yii::app()->user->checkAccess('updatePost')) {
        // проверить, что пользователь пытается редактировать свой пост
    }
}  


Но это как-то не по спортивному  ;D
тогда можно уже использовать
[code=php]
  // optional, a PHP exp​ression whose value indicates whether this rule applies
  // This option is available since version 1.0.3.
  'exp​ression'=>'!$user->isGuest && $user->level==2',
[/code]
в accessRules()

array(
  'allow',  // or 'deny'
  'actions'=>array('edit', 'delete'),
  'roles'=>array('updatePost'),
  'exp​ression'=>'$post->authId = Yii::app()->user->getId()',
)

*это не рабочий код, это набросок....
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users