CakePhp и пользовательские разрешения - PullRequest
1 голос
/ 19 июля 2011

Мне нужна система, которая позволит пользователям изменять связанные с ними данные.

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

как это сделать с acl & auth (концепция конечно)?

1 Ответ

1 голос
/ 19 июля 2011

Я видел этот вопрос несколько раз.Из документа «Торт» написано:

Списки контроля доступа, или ACL, обрабатывают две основные вещи: вещи, которые нужны, и вещи, которые нужны.

Теория, вы можете обрабатывать все элементы в вашем приложении, используя ACL, но я вижу несколько проблем с этим:

  • Допустим, у вас есть 10 тыс. элементов в магазине в вашей таблице элементов, ну, вы будетеиметь одинаковое количество элементов в вашей таблице ACO.Теперь, если вы добавляете пользователя, вам нужно будет предоставить ему доступ к элементам в таблице ARO_ACO (еще 10 000 элементов ДЛЯ КАЖДОГО ПОЛЬЗОВАТЕЛЯ!)
  • ... хорошо, возможно, я преувеличил в первом примере.Потому что вы можете сгруппировать элементы и в таблице ACO, и установить только разрешения для группы в таблице ACO_ARO.Но теперь это может быть кошмаром для выполнения запросов в вашем приложении, представьте, если вы хотите создать отфильтрованный нумерованный список элементов.Вам нужно будет попросить ACO (который теперь находится в древовидной структуре) и таблицу ARO_ACO подсчитать и разбить элементы на страницы ... и даже если это будет сделано автоматически, у вас будет проблема с производительностью

По моему мнению, лучше использовать ACL, чтобы предоставлять разрешения только методам контроллеров (CRUD) и управлять разрешениями элементов в вашем коде, устанавливая условие в ваших запросах:

$this->Items->find('all',array('conditions'=>array('store_id'=>$this->Auth->user('store_id'))))

Но выВозможно, потребуется повторить это условие везде, чтобы вы могли создать Поведение, которое изменит запросы, чтобы добавить условие в предложение WHERE, чтобы вы всегда возвращали / редактировали элементы текущего хранилища.Например, создайте поведение, подобное этому:

    /** 
     * 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('store_id')){
                    $query['joins'][$key]['conditions'][] = $joinTable['alias'].".store_id = '".$_SESSION['store_id']."'";
                }
            }
        }

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

В контроллере мне просто нужно вызвать метод find как обычно

$this->Items->find('all');

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

...