Skip to content

Модуль авторизации для phact-cmf основанный на роутах.

Notifications You must be signed in to change notification settings

hxss/Authorization

Repository files navigation

Authorization

Модуль авторизации для phact-cmf основанный на роутах.

Установка

  1. подключить модуль и заменить стандартный компонент auth в settings.php:
return [
	'modules' => [
		'Authorization',
		...
	],
	'components' => [
		'auth' => [
			'class' => \Modules\Authorization\Components\Authorization::class,
		],
		...
	],
	...
]
  1. Создать таблицы в бд: php www/index.php Base db.
  2. Заполнить таблицы значениями по-умолчанию: php www/index.php Authorization init.

Общие сведения

Модуль является надстройкой над стандартным модулем auth(entication) и использует его модель User.

  • User получает новое поле groups(М2М). Меняется функционал поля is_superuser(см. "Значения по-умолчанию" п.3.)

Модуль добавляет следующие модели:

  • Group - группы выполняют функции ролей в терминологии RBAC. Являются по сути набором разрешений.
  • Permission - если упростить, разрешения являются таблицей связи(М2М) между группой и роутом с дополнительным полем params(параметры роута). Но на самом деле являются центральным элементом в управление доступами и используются как самостоятельная модель.
  • Route - базовая единица доступа, используемая в модуле. Модель имеет всего 2 поля:
    • name - название роута вида [название неймспейса]:[краткое название роута]('main:index').
    • label - человекочитаемое название роута.

Значения по-умолчанию

После выполнения команды Authorization init будут созданы:

  1. Стандартные роуты:
    • Роуты admin:login и manage:login, необходимые для аутентификации в админках.
    • Общие роуты для каждого неймспейса(модуля) вида [название модуля]:*, например:
admin:*
manage:*
main:*
meta:*
editor:*
...
  1. Стандартные и системные группы:

    • guest - Базовая системная группа, которая будет содержать минимальный необходимый функционал для работы с сайтом. Любой пользователь, включая не аутентифицированных автоматически считается членом этой группы. Эта группа имеет доступ ко всем перечесленным в п.1. роутам, кроме admin:* и manage:*.
    • staff - По-умолчанию имеет доступ к 2 стандартным роутам: admin:* и manage:*.
    • admin - Системная группа. Автоматически получает доступ ко всем возможным роутам, включая создаваемые в будущем, даже если связи группа-роут не указаны явно.
  2. Пользователи. Модуль не создает новых пользователей, но использует существующих для предоставления стандартных доступов:

    • все существующие пользователи становятся членами группы staff.
    • все пользователи с флагом is_superuser становятся членами группы admin. Сам флаг is_superuser в дальнейшем будет являться синонимом наличия группы admin у пользователя.

Использование

Пассивное поведение

Модуль подписывается на событие application.beforeRunController и автоматически проверяет доступ пользователя к текущему роуту. В случае неудачной авторизации выполняется следующий порядок: 0. В лог кладется предупреждение о неудачной попытке доступа.

  1. Генерируется событие вида authorization.403.{$namespace}, где $namespace - неймспейс текущего роута(обычно равен названию модуля). Это событие позволяет каждому конкретному модулю самостоятельно обработать неудачную авторизацию(показать сообщение об ошибке/архивировать/выполнить переадресацию и т.д.).
  2. Если на событие из п.1. никто не отреагировал, герерируется событие authorization.403, которое может использоваться для указания стандартных "глобальных" дейтсвий при ошибке авторизации.
  3. Если событие из п.2. также было проигнорировано - модуль положит в лог сообщение об ошибке авторизации, вернет 403й http-код и остановит выполнение приложения. События из п.1 и п.2. передают такой же набор параметров, что и событие application.beforeRunController.

Ручное использование

Стандартных действий модуля из предыдущего параграфа достаточно для предотвращения несанкционированного доступа к любому роуту. Если же требуются дополнительные действия на основе авторизации(например, шаблонизация интерфейса), можно воспользоваться главным методом модуля:

bool User::hasPermission(string $routeName, array $params = null)

Метод принимает:

  • $routeName - название роута(см. "Общие сведения" Route->name)
  • $params - необазательный аргумент. Ассоциативный массив параметров роута. Служит для уточнения объектов к которым требуется получить доступ на основе параметров роута. Например, для роута admin:update вида /update/{:module}/{:admin}/{:pk} самый подробный запрос на проверку доступа будет выглядеть так:
Phact::app()->user->hasPermission('admin:update', [
	'module' => 'main',
	'admin' => 'PostAdmin',
	'pk' => 3,
]);

В массиве параметров необязетльно указывать все параметры или можно указать пустое значение для параметра, который вас не интересует. Метод возвращает true, если пользователь имеет доступ к указанным роуту с параметрами, иначе false.

Принцип проверки доступа

Теория

В процессе проверки доступа будут сравниваться указанные роут и его параметры с оными у имеющихся у пользователя разрешений(все разрешения всех групп, в которых состоит пользователь). Разрешение имеющееся у пользователя должно быть >= запрошенному. Процедура сравнения разрешений:

  1. Сравнение роутов:
    • Считается, что общий роут 'admin:*' > 'admin:update'. В таком случае метод немедленно возвращает true.
    • Роуты равны, если равны их названия: 'admin:update' = 'admin:update'. Если роуты равны - выполняется сравнение параметров.
  2. Сравнение параметров:
    • Каждое разрешение может иметь перечисление из нескольких значений для каждого параметра роута. В таком случае список разрешеных значений будет представлен в виде подмассива:
      [
      	'module' => [
      		'admin',
      		'main',
      	],
      	'admin' => 'PostAdmin',
      	'pk' => 3,
      ]
      
    • любой параметр может быть пропущем, в таком случае пустое значение олицетворяет весь спектр возможных значений. Например, доступ ко всем админкам из модулей admin и main:
      [
      	'module' => [
      		'admin',
      		'main',
      	],
      	'admin' => '',
      ]
      
    • при сравнение параметров требуется, чтобы имеющиеся "покрывали" запрошенные. Т.е. чтобы в массиве перечисленных разрешенных параметров присутствовало значение параметра, указанное во входном массиве функции hasPermission или чтобы параметры, имеющиеся у пользователя были пустыми.

Примеры

Дано: пользователь имеет разрешение к роуту admin:update с параметрами:

[
	'module' => [
		'admin',
		'main',
	],
	'admin' => '',
	'pk' => ['4', '5'],
]

Доступ к редактирование всех моделей из модулей admin и main с ключами 4 или 5.

Тесты:

Phact::app()->user->hasPermission('admin:update') == false 

// каждый не уточненный параметр олицетворяет все возможные значения


Phact::app()->user->hasPermission('admin:update', [
	'module' => '',
	'admin' => 'asdasd',
	'pk' => '4',
]) == false

// значения указанные для модуля предполагает любое возможное, когда доступ разрешен к 2 конкретным значениям


Phact::app()->user->hasPermission('admin:update', [
	'module' => 'editor',
	'admin' => '',
	'pk' => '4',
]) == false

// значения указанные для модуля отсутствует в списке разрешенных


Phact::app()->user->hasPermission('admin:update', [
	'module' => 'main',
	'admin' => 'asdasd',
	'pk' => '4',
]) == true

// значения указанные для модуля и ключа присутствуют в имеющихся перечислениях, значение параметра admin может быть любым


Phact::app()->user->hasPermission('admin:update', [
	'module' => 'main',
	'admin' => '',
	'pk' => '4',
]) == true

Phact::app()->user->hasPermission('manage:update', [
	'module' => 'main',
	'pk' => '4',
]) == true

Phact::app()->user->hasPermission('admin:update', [
	'module' => 'main',
	'admin' => '',
]) == false

Настройка доступа в админке

В панели администратора настраиваются связи User - Group и Group - Permission.

При настройке разрешений можно отдельно подключать списки значений для каждого параметра роута.

permission_form

Списки привязываются к имени параметра внутри своего модуля, т.е. списки для параметра module в модуле Main и Manage необходимо настраивать отдельно. Так же каждый список может указать список конкретных роутов, к которым он может применяться.

Для настройки списков используется класс Authorization\RouteParamsList\RouteParamsList, от которого необходимо унаследовать свой класс списков и положить в неймспейс вида Modules\[ModuleName]\RouteParamsList\[ListName]. В минимальной конфигурации такой класс должен реализовать метод initList(), который должен сгенерировать ассоциативный массив. Ключи этого массива будут использоваться для хранения данных в бд, а значения могут быть человекочитаемыми.

Значения параметров без подключенных списков можно перечислять разделяя их символом |.

About

Модуль авторизации для phact-cmf основанный на роутах.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published