Cakephp 3.x: как структурировать сложную авторизацию с несколькими ролями - PullRequest
0 голосов
/ 25 февраля 2019

В настоящее время я работаю в большом проекте с CakePHP3.x и пытаюсь сделать код максимально чистым.Вы можете видеть визуальную структуру базы данных на первом изображении:

database structure

Один пользователь имеет несколько ролей.С компонентом Auth и системой префиксов мне удалось обезопасить большинство страниц без особых проблем.Однако в некоторых частях веб-сайта проблема более сложная.

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

Local Manager (secured by the prefix /local)
-- Can edit only his own local group

Regional Manager (secured by the prefix /region)
-- Can edit every local groups included in his region (with /local)
-- Can edit his own region (with /region)

National Manager (secured by the prefix /national)
-- Can edit every region in his own zone (with /region)

Существует устаревшая система, такая как: Local

По URL "local / edit /: id" я должен был сделать что-то вроде этой ведьмы, на самом деле не то, чем я занимаюсь.

<?php
# No id provided : so this is the creation of a new local group
if($id == null){

    # If the user is not a region or a national manager, throw an error
    if(!array_key_exists('region', $this->viewVars['authUser']['auth'])
        && !array_key_exists('national', $this->viewVars['authUser']['auth'])
        && !array_key_exists('dev', $this->viewVars['authUser']['auth'])) {

        throw new NotFoundException(__("Impossible de créer un groupe local (1)"));

    }

# This is an update
} else {

    # Check the local group with the region informations
    $regionID = $this->LocalGroups->find('all')
                        ->select(['region_id'])
                        ->where(['LocalGroups.id'=>$id])
                        ->first();

    # Check the id of the user through the local group table (only has one relationship)
    $userRegionID = $this->LocalGroups->find('all')
                    ->select(['LocalGroups.region_id'])
                    ->where(['id'=>$this->Auth->user()['local_group_id']])
                    ->first();

    # The region dosn't exist, throw an error
    if(!$regionID){
        throw new NotFoundException(__('Impossible de modifier ce groupe local (2)'));
    }

    # The user is a region manager nor a national manager
    if(array_key_exists('region', $this->viewVars['authUser']['auth'])
        && !array_key_exists('dev', $this->viewVars['authUser']['auth'])
        && !array_key_exists('national', $this->viewVars['authUser']['auth'])){

        # If the id of the region associated to the local group is different than the id of the region associated to the user, throw an error
        if($regionID->region->id != $userRegionID->region_id){
            throw new NotFoundException(__('Impossible de modifier ce groupe local (3)'));
        }
    }
    # If the user is a local manager he can only edit his own local group
    elseif(array_key_exists('local', $this->viewVars['authUser']['auth'])
        && !array_key_exists('dev', $this->viewVars['authUser']['auth'])
        && !array_key_exists('region', $this->viewVars['authUser']['auth'])
        && !array_key_exists('national', $this->viewVars['authUser']['auth'])){

        # Check if he owns the local group
        if($id != $this->viewVars['authUser']['local_group_id']){
            throw new NotFoundException(__('Impossible de modifier ce groupe local (4)'));
        }

    }

}

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

Мне действительно нужнонайти хороший план для структурирования моего кода.Не могли бы вы помочь мне?

Cheer, xSPx

...