[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()),авовторых,проверятьлокальныеправанаобъект,тоесть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 и т.п. (см. Система -> Безопасность -> Контроль доступа -> Политики доступа)