Распределение доступа CakePHP на основе конкретного доступа к данным - PullRequest
1 голос
/ 16 июня 2011

Требования моего проекта примерно такие:

Сверху будет администратор, который будет иметь все права доступа, первый уровень

В разделе «Администратор» будут присутствовать главы департаментов, которые будут иметь все права доступа, кроме создания глав департаментов

При Главе Департамента будут другие Члены, которые будут управлять своими распределенными мудрыми данными.

Теперь у всех разных руководителей отделов будет своя собственная информация и члены, а у всех руководителей отделов / членов будет доступ к своим собственным конкретным записям, которые они вводят / управляют.

Теперь, с помощью ACL-компонента CakePHP, я могу разделить роли и уровень их доступа, но все руководители отделов могут видеть информацию о других начальниках отделов, так как у них будет одинаковый уровень доступа, а все остальные участники могут видеть других участников. информация о различных отделах, так как они будут иметь одинаковый уровень доступа.

Сложность моего проекта заключается в том, что они должны видеть только свою назначенную или созданную информацию / данные, хотя у них такие же уровни / роли, как и у других.

Может кто-нибудь предложить мне наиболее подходящий вариант, чтобы управлять всеми этими вещами с помощью уже доступных плагинов с CakePHP.

Я могу работать, настраивая компонент ACL по умолчанию, но это займет больше времени, чем ожидалось.

Любые лучшие идеи / предложения будут оценены!

1 Ответ

2 голосов
/ 16 июня 2011

Как я понимаю, ACL не такой уж волшебный. Например: ACL может управлять разрешениями, чтобы определить, кто имеет доступ для добавления / редактирования / удаления продукта ... но он не сможет изменить запрос для фильтрации продуктов в соответствии с определенными разрешениями (например, «пользователи из отдела A могут только см. продукты из отдела A ") .. на самом деле это ложь, ACL может справиться с этим, но это может оказаться непрактичным, потому что каждый раз, когда вы добавляете продукт, вам нужно будет создать ACO и установить разрешение в таблице AROS_ACOS и поскольку AROS является древовидной структурой, она может легко превратиться в пустяк, если вы планируете запросить данные

Я бы использовал ACL только для группы , чтобы контролировать доступ к определенным страницам / действиям и устанавливать правила, такие как:

  • "Начальник отдела может получить доступ к странице «список продуктов» и добавить / удалить / изменить продукты "
  • "Администраторы могут получить доступ все страницы "
  • "Другие пользователи могут получить доступ «список продуктов», и они могут добавить продукты, но не удалять их "

и я настроил бы свои запросы соответственно подключенному пользователю, поэтому на контроллере страницы «список продуктов» я бы сделал что-то вроде:

  • Если подключенный пользователь присоединяется к начальнику отдела, выберите все продукты, где product.department_id=connected_user.department_id
  • Если подключенным пользователем является Admin, выберите все продукты

если у вас слишком много запросов и вы не хотите выполнять тысячи предложений if, вы можете создать компонент, поведение или, возможно, расширить метод find() в app_model. Идея состоит в том, чтобы перехватить все запросы и проверить, есть ли в одной из моделей, используемых в запросе, поле с названием "Department_id", если они есть, то добавьте условие model.department_id=connected_user.department_id к запросу.

Я сделал это для одного веб-сайта, который можно просматривать на нескольких языках, и у каждого языка есть свои пользователи, данные, журналы и т. Д., И есть один администратор, который может видеть всю информацию ... и он отлично работает для меня = )

Удачи!

РЕДАКТИРОВАНИЕ: поведение, которое я использую:

<?php 
class LocalizableBehavior extends ModelBehavior { 

    /** 
     * Filter query conditions with the correct `type' field condition. 
     */ 
    function beforeFind(&$model, $query) 
    {
        /**
         * Condition for the paginators that uses joins
        */
        if(isset($query['joins']) && !empty($query['joins'])){
            foreach($query['joins'] as $key => $joinTable){
                if(ClassRegistry::init($joinTable['alias'])->hasField('lang')){
                    $query['joins'][$key]['conditions'][] = $joinTable['alias'].".lang = '".$_SESSION['lang']."'";
                }
            }
        }

        /**
         * condition for the normal find queries
        */
        if($model->hasField('lang') && $model->name != "User"){
                $query['conditions'][$model->name.'.lang'] = $_SESSION['lang'];
        }
        return $query;
    }

} 
?>

это довольно просто, я изменяю запрос, чтобы добавить условие, соответствующее текущему языку ($ _SESSION ['lang']). В контроллере все, что мне нужно сделать, это присоединить LocalizableBehavior и использовать метод find как обычно:

$this->Products->find('all');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...