Николай Ланец
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 и т.п. (см. Система -> Безопасность -> Контроль доступа -> Политики доступа)

Добавить комментарий