30 июня 2013 г., 11:20
[REVO] Проверка прав доступов к объектам MODX программно на примере доступов к modResource
Увидел вопрос, который остается без ответа уже 12 часов, и решил написать статью по этому поводу (вообще писал коммент, но он получился слишком большой :-)).
Уверен, пригодится многим. Тема очень деликатная, так как политики безопасности в Рево настолько совершенны, на сколько и сложны.
Автору:
Могу дать наколку. Смотрите сниппет Wayfinder. Там вам поможет метод Wayfinder.class.php ::getData();
В нем много чего написано. Наиболее интересные моменты, это
$c = $this->modx->newQuery('modResource');
$c->leftJoin('modResourceGroupResource','ResourceGroupResources');
$c->query['distinct'] = 'DISTINCT';
if (
$this->modx->user->hasSessionContext('mgr')
&& $this->modx->hasPermission('view_unpublished')
&& $this->_config['previewUnpublished']
) {
}
else {
$c->where(array('modResource.published:=' => 1));
}
и
if (
(!empty($this->_config['permissions'])) && (!$doc->checkPolicy($this->_config['permissions']))
){
continue;
}
То есть проверять надо во-первых, опубликован документ или нет, и есть ли право просматривать неопубликованные (то есть это относится к сфере проверки глобальных прав $modx->hasPermission()), а во-вторых, проверять локальные права на объект, то есть $doc->checkPolicy();
Это в общем. А в частности стоит уяснить, что локальные ограничения к ресурсу могут быть ограничены только на уровне Групп ресурсов? по-этому Wayfinder в целях экономии ресурсов и проверяет сразу, относится ресурс к какой-либо группе или нет, так как если он не в группе, то никаких прав и не может быть прописано, и не стоит выполнять более нагруженную операцию проверки прав. То есть действуют правила «Если документ не отнесен к группе ресурсов, то можно все», и «Если на группу ресурсов в конкретном контексте не назначено хоть одной политики доступа, то тоже можно все».
Вот вам пример (данный скрипт я выполнял через админку, потому делаю смену контекста и текущего пользователя):
print '<pre>';
$doc_id = 7;
$user_id = 9;
$doc = $modx->getObject('modResource', $doc_id);
$modx->switchContext('web');
$modx->user = $modx->getObject('modUser', $user_id);
print_r($doc->findPolicy('web')); // Можно указать конкретный контекст для проверки
print "<br />". ($doc->checkPolicy('list') ? '1' : '0');
В данном примере вот этот метод $doc->findPolicy('web') и вернет вам массив назначенных доступов к ресурсу. Если вы увидите что-то типа
Array
(
[modAccessResourceGroup] => Array
(
[1] => Array
(
[0] => Array
(
[principal] => 2
[authority] => 1000
[policy] => Array
(
[load] => 1
)
)
)
)
)
значит к ресурсу назначены права доступа. В нашем случае это load. То есть пользователь должен иметь права load к этому ресурсу. Их вы и проверите методом $doc->checkPolicy('load')
Ежели вы увидите просто пустой массив, значит прав на ресурс не назначено, а значит любой пользователь имеет доступ.
Но имейте ввиду, что в разных контекстах могут быть назначены разные права к группам ресурсов.
Таким образом можно проверить любые права, типа load, view и т.п. (см. Система -> Безопасность -> Контроль доступа -> Политики доступа)