Commit 2f8b8e0ff6464eab8d48e8004c1191f99a722eb7

Authored by Dmitryi
1 parent f91c1ae8

this commin on a english)

Права и роли перенес в common components
backend/config/main.php
... ... @@ -16,7 +16,7 @@ return [
16 16 'bootstrap' => ['log'],
17 17 'modules' => [
18 18 'permit' => [
19   - 'class' => 'developeruz\db_rbac\Yii2DbRbac',
  19 + 'class' => 'common\components\developeruz\db_rbac\Yii2DbRbac',
20 20 'params' => [
21 21 'userClass' => 'common\models\User'
22 22 ]
... ...
common/components/developeruz/db_rbac/LICENSE 0 → 100644
  1 +The MIT License (MIT)
  2 +
  3 +Copyright (c) 2014 Elvira Sheina
  4 +
  5 +Permission is hereby granted, free of charge, to any person obtaining a copy
  6 +of this software and associated documentation files (the "Software"), to deal
  7 +in the Software without restriction, including without limitation the rights
  8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9 +copies of the Software, and to permit persons to whom the Software is
  10 +furnished to do so, subject to the following conditions:
  11 +
  12 +The above copyright notice and this permission notice shall be included in all
  13 +copies or substantial portions of the Software.
  14 +
  15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21 +SOFTWARE.
  22 +
... ...
common/components/developeruz/db_rbac/README.md 0 → 100644
  1 +Динамическая настройка прав доступа для Yii2
  2 +============
  3 +
  4 +Модуль для создания ролей и прав доступа через веб-интерфейс, так же имеющий веб интерфейс для назначения ролей пользователям
  5 +Поведение для приложения, проверяющее право доступа к action по внесенным в модуле правилам.
  6 +
  7 +###Установка:###
  8 +```bash
  9 +$ php composer.phar require developeruz/yii2-db-rbac "*"
  10 +```
  11 +
  12 +Для корректной работы модуля необходимо настроить authManager в конфиге приложения (common/config/main.php для advanced или config/web.php и config/console для basic приложения)
  13 +```php
  14 + 'components' => [
  15 + 'authManager' => [
  16 + 'class' => 'yii\rbac\DbManager',
  17 + ],
  18 + ...
  19 + ]
  20 +```
  21 +
  22 +И выполнить миграции, создающие таблицы для DbManager (подразумевается, что коннект к БД для приложения уже настроен)
  23 +```bash
  24 +$ yii migrate --migrationPath=@yii/rbac/migrations/
  25 +```
  26 +
  27 +##Подключение модуля##
  28 +В конфиге приложения (backend/config/main.php для advanced или config/web.php для basic приложения) прописываем модуль
  29 +```php
  30 + 'modules' => [
  31 + 'permit' => [
  32 + 'class' => 'developeruz\db_rbac\Yii2DbRbac',
  33 + ],
  34 + ],
  35 +```
  36 +Если нужно передать layout это можно сделать так:
  37 +```php
  38 + 'modules' => [
  39 + 'permit' => [
  40 + 'class' => 'developeruz\db_rbac\Yii2DbRbac',
  41 + 'layout' => '//admin'
  42 + ],
  43 + ],
  44 +```
  45 +
  46 +Если вы используете ЧПУ, то убедитесь что у вас прописаны правила роутинга для модулей
  47 +```php
  48 +'<module:\w+>/<controller:\w+>/<action:(\w|-)+>' => '<module>/<controller>/<action>',
  49 +'<module:\w+>/<controller:\w+>/<action:(\w|-)+>/<id:\d+>' => '<module>/<controller>/<action>',
  50 +```
  51 +
  52 +**Добавляем ссылки в меню**
  53 +
  54 +**/permit/access/role - управление ролями**
  55 +
  56 +**/permit/access/permission - управление правами доступа**
  57 +
  58 +###Назначение ролей пользователям###
  59 +По многочисленным просьбам в модуль добавлен интерфейс для назначения ролей пользователям.
  60 +
  61 +Для корректной работы модуля нужно указать в параметрах модуля класс `User`.
  62 +```php
  63 +'modules' => [
  64 + 'permit' => [
  65 + 'class' => 'app\modules\db_rbac\Yii2DbRbac',
  66 + 'params' => [
  67 + 'userClass' => 'app\models\User'
  68 + ]
  69 + ],
  70 + ],
  71 +```
  72 +
  73 +Класс User должен реализовывать интерфейс `developeruz\db_rbac\interfaces\UserRbacInterface`.
  74 +В большинстве случаев придется дописать в нем 1 функцию `getUserName()` которая будет возвращать отображаемое имя пользователя.
  75 +```php
  76 +use developeruz\db_rbac\interfaces\UserRbacInterface;
  77 +
  78 +class User extends ActiveRecord implements IdentityInterface, UserRbacInterface
  79 +{
  80 +...
  81 + public function getUserName()
  82 + {
  83 + return $this->username;
  84 + }
  85 +}
  86 +```
  87 +
  88 +**Управление ролью пользователя происходит на странице `/permit/user/view/1` для пользователя с id=1.**
  89 +Удобнее всего дописать кнопку на эту страницу в Grid со списком пользователей.
  90 +```php
  91 +echo GridView::widget([
  92 + 'dataProvider' => $dataProvider,
  93 + 'columns' => [
  94 + ['class' => 'yii\grid\SerialColumn'],
  95 +
  96 + 'id',
  97 + 'username',
  98 + 'email:email',
  99 +
  100 + ['class' => 'yii\grid\ActionColumn',
  101 + 'template' => '{view}&nbsp;&nbsp;{update}&nbsp;&nbsp;{permit}&nbsp;&nbsp;{delete}',
  102 + 'buttons' =>
  103 + [
  104 + 'permit' => function ($url, $model) {
  105 + return Html::a('<span class="glyphicon glyphicon-wrench"></span>', Url::to(['/permit/user/view', 'id' => $model->id]), [
  106 + 'title' => Yii::t('yii', 'Change user role')
  107 + ]); },
  108 + ]
  109 + ],
  110 + ],
  111 +]);
  112 +```
  113 +
  114 +Присвоить роль пользователю можно и в коде, например при создании нового пользователя.
  115 +```php
  116 +$userRole = Yii::$app->authManager->getRole('name_of_role');
  117 +Yii::$app->authManager->assign($userRole, $user->getId());
  118 +```
  119 +
  120 +Проверить, имеет ли пользователь право на действие можно через метод `can()` компонента User
  121 +```php
  122 +Yii::$app->user->can($permissionName);
  123 +```
  124 +$permissionName - может быть как ролью так и правом
  125 +
  126 +##Поведение, динамически проверяющее наличие прав##
  127 +
  128 +Данное поведение позволяет не писать Yii::$app->user->can($permissionName); в каждом action, а проверять права доступа на лету.
  129 +Это удобно для гибкой настройки прав при использовании сторонних модулей.
  130 +
  131 +###Подключение поведения###
  132 +В конфиге того приложения, доступ к которому следует проверять на лету, необходимо подключить поведение
  133 +```php
  134 +use developeruz\db_rbac\behaviors\AccessBehavior;
  135 +
  136 + 'as AccessBehavior' => [
  137 + 'class' => AccessBehavior::className(),
  138 + ]
  139 +```
  140 +С этого момента, после обработки запроса (событие EVENT_AFTER_REQUEST) проверяются права текущего пользователя (Yii::$app->user) на выполнение запрашиваемого действия (Yii::$app->user->can())
  141 +Действие считается разрешенным, если:
  142 + - пользователю разрешен доступ к конкретному action (правило записано как: module/controller/action)
  143 + - пользователю разрешен доступ к любым action данного контроллера (правило записано как: module/controller)
  144 + - пользователю разрешен доступ к любым action данного модуля (правило записано как: module)
  145 +
  146 +###Настройка прав доступа по умолчанию###
  147 +После подключения поведения, доступ становится возможен только авторизованному пользователю, имеющему некие права.
  148 +Для исключений из этого правила можно прописать доступы по умолчанию в том же формате AccessControl, что и в контроллере:
  149 +```php
  150 + 'as AccessBehavior' => [
  151 + 'class' => AccessBehavior::className(),
  152 + 'rules' =>
  153 + ['site' =>
  154 + [
  155 + [
  156 + 'actions' => ['login', 'index'],
  157 + 'allow' => true,
  158 + ],
  159 + [
  160 + 'actions' => ['about'],
  161 + 'allow' => true,
  162 + 'roles' => ['admin'],
  163 + ],
  164 + ]
  165 + ]
  166 + ]
  167 +```
  168 +В приведенном выше примере разрешен доступ любому пользователю к site/login и site/index и доступ пользователя с ролью admin к site/about
  169 +Правила прописанные в конфиге имеют приоритет над динамически настраиваемыми правилами.
0 170 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/Yii2DbRbac.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Yii2DbRbac for Yii2
  4 + *
  5 + * @author Elle <elleuz@gmail.com>
  6 + * @version 0.1
  7 + * @package Yii2DbRbac for Yii2
  8 + *
  9 + */
  10 +namespace common\components\developeruz\db_rbac;
  11 +
  12 +use Yii;
  13 +
  14 +class Yii2DbRbac extends \yii\base\Module
  15 +{
  16 + public $controllerNamespace = 'common\components\developeruz\db_rbac\controllers';
  17 + public $userClass;
  18 +
  19 + public function init()
  20 + {
  21 + parent::init();
  22 + $this->registerTranslations();
  23 + }
  24 +
  25 + public function registerTranslations()
  26 + {
  27 + Yii::$app->i18n->translations['db_rbac'] = [
  28 + 'class' => 'yii\i18n\PhpMessageSource',
  29 + 'sourceLanguage' => 'ru-Ru',
  30 + 'basePath' => '@developeruz/db_rbac/messages',
  31 + ];
  32 + }
  33 +
  34 + public static function t($category, $message, $params = [], $language = null)
  35 + {
  36 + return Yii::t('modules/db_rbac/' . $category, $message, $params, $language);
  37 + }
  38 +}
... ...
common/components/developeruz/db_rbac/behaviors/AccessBehavior.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * AccessBehavior for Yii2
  4 + *
  5 + * @author Elle <elleuz@gmail.com>
  6 + * @version 0.1
  7 + * @package AccessBehavior for Yii2
  8 + *
  9 + */
  10 +namespace developeruz\db_rbac\behaviors;
  11 +
  12 +use Yii;
  13 +use yii\behaviors\AttributeBehavior;
  14 +use yii\di\Instance;
  15 +use yii\base\Module;
  16 +use yii\web\Application;
  17 +use yii\web\User;
  18 +use yii\filters\AccessControl;
  19 +use yii\web\ForbiddenHttpException;
  20 +
  21 +class AccessBehavior extends AttributeBehavior {
  22 +
  23 + public $rules=[];
  24 +
  25 + private $_rules = [];
  26 +
  27 + public function events()
  28 + {
  29 + return [
  30 + Module::EVENT_BEFORE_ACTION => 'interception',
  31 + ];
  32 + }
  33 +
  34 + public function interception($event)
  35 + {
  36 + if(!isset( Yii::$app->i18n->translations['db_rbac'])){
  37 + Yii::$app->i18n->translations['db_rbac'] = [
  38 + 'class' => 'yii\i18n\PhpMessageSource',
  39 + 'sourceLanguage' => 'ru-Ru',
  40 + 'basePath' => '@developeruz/db_rbac/messages',
  41 + ];
  42 + }
  43 +
  44 + $route = Yii::$app->getRequest()->resolve();
  45 +
  46 + //Проверяем права по конфигу
  47 + $this->createRule();
  48 + $user = Instance::ensure(Yii::$app->user, User::className());
  49 + $request = Yii::$app->getRequest();
  50 + $action = $event->action;
  51 +
  52 + if(!$this->cheсkByRule($action, $user, $request))
  53 + {
  54 + //И по AuthManager
  55 + if(!$this->checkPermission($route))
  56 + throw new ForbiddenHttpException(Yii::t('db_rbac','Недостаточно прав'));
  57 + }
  58 + }
  59 +
  60 + protected function createRule()
  61 + {
  62 + foreach($this->rules as $controller => $rule)
  63 + {
  64 + foreach ($rule as $singleRule) {
  65 + if (is_array($singleRule)) {
  66 + $option = [
  67 + 'controllers' => [$controller],
  68 + 'class' => 'yii\filters\AccessRule'
  69 + ];
  70 + $this->_rules[] = Yii::createObject(array_merge($option, $singleRule));
  71 + }
  72 + }
  73 + }
  74 + }
  75 +
  76 + protected function cheсkByRule($action, $user, $request)
  77 + {
  78 + foreach ($this->_rules as $rule) {
  79 + if ($rule->allows($action, $user, $request))
  80 + return true;
  81 + }
  82 + return false;
  83 + }
  84 +
  85 + protected function checkPermission($route)
  86 + {
  87 + //$route[0] - is the route, $route[1] - is the associated parameters
  88 +
  89 + $routePathTmp = explode('/', $route[0]);
  90 + $routeVariant = array_shift($routePathTmp);
  91 + if(Yii::$app->user->can($routeVariant, $route[1]))
  92 + return true;
  93 +
  94 + foreach($routePathTmp as $routePart)
  95 + {
  96 + $routeVariant .= '/'.$routePart;
  97 + if(Yii::$app->user->can($routeVariant, $route[1]))
  98 + return true;
  99 + }
  100 +
  101 + return false;
  102 + }
  103 +}
0 104 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/composer.json 0 → 100644
  1 +{
  2 + "name": "developeruz/yii2-db-rbac",
  3 + "description": "Dynamic control of access rights in YII2",
  4 + "keywords": ["yii", "rbac"],
  5 + "type": "yii2-extension",
  6 + "license": "MIT",
  7 + "authors": [
  8 + {
  9 + "name": "Elvira Sheina",
  10 + "email": "elleuz@gmail.com",
  11 + "homepage": "http://developer.uz"
  12 + }
  13 + ],
  14 + "require": {
  15 + "yiisoft/yii2": "*"
  16 + },
  17 + "support": {
  18 + "issues": "https://github.com/developeruz/yii2-db-rbac/issues"
  19 + },
  20 + "autoload": {
  21 + "psr-4": {
  22 + "developeruz\\db_rbac\\": ""
  23 + }
  24 + }
  25 +}
0 26 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/controllers/AccessController.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * AccessController for Yii2
  4 + *
  5 + * @author Elle <elleuz@gmail.com>
  6 + * @version 0.1
  7 + * @package AccessController for Yii2
  8 + *
  9 + */
  10 +namespace common\components\developeruz\db_rbac\controllers;
  11 +
  12 +use Yii;
  13 +use yii\web\Controller;
  14 +use yii\web\BadRequestHttpException;
  15 +use yii\rbac\Role;
  16 +use yii\rbac\Permission;
  17 +use yii\helpers\ArrayHelper;
  18 +use yii\helpers\Url;
  19 +use yii\validators\RegularExpressionValidator;
  20 +
  21 +class AccessController extends Controller
  22 +{
  23 + protected $error;
  24 + protected $pattern4Role = '/^[a-zA-Z0-9_-]+$/';
  25 + protected $pattern4Permission = '/^[a-zA-Z0-9_\/-]+$/';
  26 +
  27 + public function actions()
  28 + {
  29 + return [
  30 + 'error' => [
  31 + 'class' => 'yii\web\ErrorAction',
  32 + ],
  33 + ];
  34 + }
  35 +
  36 + public function actionRole()
  37 + {
  38 + return $this->render('role');
  39 + }
  40 +
  41 + public function actionAddRole()
  42 + {
  43 + if (Yii::$app->request->post('name')
  44 + && $this->validate(Yii::$app->request->post('name'), $this->pattern4Role)
  45 + && $this->isUnique(Yii::$app->request->post('name'), 'role')
  46 + ) {
  47 + $role = Yii::$app->authManager->createRole(Yii::$app->request->post('name'));
  48 + $role->description = Yii::$app->request->post('description');
  49 + Yii::$app->authManager->add($role);
  50 + $this->setPermissions(Yii::$app->request->post('permissions', []), $role);
  51 + return $this->redirect(Url::toRoute([
  52 + 'update-role',
  53 + 'name' => $role->name
  54 + ]));
  55 + }
  56 +
  57 + $permissions = ArrayHelper::map(Yii::$app->authManager->getPermissions(), 'name', 'description');
  58 + return $this->render(
  59 + 'addRole',
  60 + [
  61 + 'permissions' => $permissions,
  62 + 'error' => $this->error
  63 + ]
  64 + );
  65 + }
  66 +
  67 + public function actionUpdateRole($name)
  68 + {
  69 + $role = Yii::$app->authManager->getRole($name);
  70 +
  71 + $permissions = ArrayHelper::map(Yii::$app->authManager->getPermissions(), 'name', 'description');
  72 + $role_permit = array_keys(Yii::$app->authManager->getPermissionsByRole($name));
  73 +
  74 + if ($role instanceof Role) {
  75 + if (Yii::$app->request->post('name')
  76 + && $this->validate(Yii::$app->request->post('name'), $this->pattern4Role)
  77 + ) {
  78 + if (Yii::$app->request->post('name') != $name && !$this->isUnique(Yii::$app->request->post('name'), 'role')) {
  79 + return $this->render(
  80 + 'updateRole',
  81 + [
  82 + 'role' => $role,
  83 + 'permissions' => $permissions,
  84 + 'role_permit' => $role_permit,
  85 + 'error' => $this->error
  86 + ]
  87 + );
  88 + }
  89 + $role = $this->setAttribute($role, Yii::$app->request->post());
  90 + Yii::$app->authManager->update($name, $role);
  91 + Yii::$app->authManager->removeChildren($role);
  92 + $this->setPermissions(Yii::$app->request->post('permissions', []), $role);
  93 + return $this->redirect(Url::toRoute([
  94 + 'update-role',
  95 + 'name' => $role->name
  96 + ]));
  97 + }
  98 +
  99 + return $this->render(
  100 + 'updateRole',
  101 + [
  102 + 'role' => $role,
  103 + 'permissions' => $permissions,
  104 + 'role_permit' => $role_permit,
  105 + 'error' => $this->error
  106 + ]
  107 + );
  108 + } else {
  109 + throw new BadRequestHttpException(Yii::t('db_rbac', 'Страница не найдена'));
  110 + }
  111 + }
  112 +
  113 + public function actionDeleteRole($name)
  114 + {
  115 + $role = Yii::$app->authManager->getRole($name);
  116 + if ($role) {
  117 + Yii::$app->authManager->removeChildren($role);
  118 + Yii::$app->authManager->remove($role);
  119 + }
  120 + return $this->redirect(Url::toRoute(['role']));
  121 + }
  122 +
  123 +
  124 + public function actionPermission()
  125 + {
  126 + return $this->render('permission');
  127 + }
  128 +
  129 + public function actionAddPermission()
  130 + {
  131 + $permission = $this->clear(Yii::$app->request->post('name'));
  132 + if ($permission
  133 + && $this->validate($permission, $this->pattern4Permission)
  134 + && $this->isUnique($permission, 'permission')
  135 + ) {
  136 + $permit = Yii::$app->authManager->createPermission($permission);
  137 + $permit->description = Yii::$app->request->post('description', '');
  138 + Yii::$app->authManager->add($permit);
  139 + return $this->redirect(Url::toRoute([
  140 + 'update-permission',
  141 + 'name' => $permit->name
  142 + ]));
  143 + }
  144 +
  145 + return $this->render('addPermission', ['error' => $this->error]);
  146 + }
  147 +
  148 + public function actionUpdatePermission($name)
  149 + {
  150 + $permit = Yii::$app->authManager->getPermission($name);
  151 + if ($permit instanceof Permission) {
  152 + $permission = $this->clear(Yii::$app->request->post('name'));
  153 + if ($permission && $this->validate($permission, $this->pattern4Permission)
  154 + ) {
  155 + if($permission!= $name && !$this->isUnique($permission, 'permission'))
  156 + {
  157 + return $this->render('updatePermission', [
  158 + 'permit' => $permit,
  159 + 'error' => $this->error
  160 + ]);
  161 + }
  162 +
  163 + $permit->name = $permission;
  164 + $permit->description = Yii::$app->request->post('description', '');
  165 + Yii::$app->authManager->update($name, $permit);
  166 + return $this->redirect(Url::toRoute([
  167 + 'update-permission',
  168 + 'name' => $permit->name
  169 + ]));
  170 + }
  171 +
  172 + return $this->render('updatePermission', [
  173 + 'permit' => $permit,
  174 + 'error' => $this->error
  175 + ]);
  176 + } else throw new BadRequestHttpException(Yii::t('db_rbac', 'Страница не найдена'));
  177 + }
  178 +
  179 + public function actionDeletePermission($name)
  180 + {
  181 + $permit = Yii::$app->authManager->getPermission($name);
  182 + if ($permit)
  183 + Yii::$app->authManager->remove($permit);
  184 + return $this->redirect(Url::toRoute(['permission']));
  185 + }
  186 +
  187 + protected function setAttribute($object, $data)
  188 + {
  189 + $object->name = $data['name'];
  190 + $object->description = $data['description'];
  191 + return $object;
  192 + }
  193 +
  194 + protected function setPermissions($permissions, $role)
  195 + {
  196 + foreach ($permissions as $permit) {
  197 + $new_permit = Yii::$app->authManager->getPermission($permit);
  198 + Yii::$app->authManager->addChild($role, $new_permit);
  199 + }
  200 + }
  201 +
  202 + protected function validate($field, $regex)
  203 + {
  204 + $validator = new RegularExpressionValidator(['pattern' => $regex]);
  205 + if ($validator->validate($field, $error))
  206 + return true;
  207 + else {
  208 + $this->error[] = Yii::t('db_rbac', 'Значение "{field}" содержит не допустимые символы', ['field' => $field]);
  209 + return false;
  210 + }
  211 + }
  212 +
  213 + protected function isUnique($name, $type)
  214 + {
  215 + if ($type == 'role') {
  216 + $role = Yii::$app->authManager->getRole($name);
  217 + if ($role instanceof Role) {
  218 + $this->error[] = Yii::t('db_rbac', 'Роль с таким именем уже существует: ') . $name;
  219 + return false;
  220 + } else return true;
  221 + } elseif ($type == 'permission') {
  222 + $permission = Yii::$app->authManager->getPermission($name);
  223 + if ($permission instanceof Permission) {
  224 + $this->error[] = Yii::t('db_rbac', 'Правило с таким именем уже существует: ') . $name;
  225 + return false;
  226 + } else return true;
  227 + }
  228 + }
  229 +
  230 + protected function clear($value)
  231 + {
  232 + if (!empty($value)) {
  233 + $value = trim($value, "/ \t\n\r\0\x0B");
  234 + }
  235 +
  236 + return $value;
  237 + }
  238 +}
0 239 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/controllers/UserController.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Controller to attache role for user for Yii2
  4 + *
  5 + * @author Elle <elleuz@gmail.com>
  6 + * @version 0.1
  7 + * @package UserController for Yii2
  8 + *
  9 + */
  10 +namespace common\components\developeruz\db_rbac\controllers;
  11 +
  12 +use Yii;
  13 +use yii\filters\VerbFilter;
  14 +use yii\helpers\ArrayHelper;
  15 +use yii\helpers\Url;
  16 +use yii\web\Controller;
  17 +use yii\web\BadRequestHttpException;
  18 +use developeruz\db_rbac\interfaces\UserRbacInterface;
  19 +use yii\web\NotFoundHttpException;
  20 +
  21 +class UserController extends Controller
  22 +{
  23 + public $moduleName = 'permit';
  24 +
  25 + public function beforeAction($action)
  26 + {
  27 + if(empty(Yii::$app->controller->module->params['userClass'])){
  28 + throw new BadRequestHttpException(Yii::t('db_rbac','Необходимо указать класс User в настройках модуля'));
  29 + }
  30 +
  31 + $user = new Yii::$app->controller->module->params['userClass']();
  32 +
  33 + if(! $user instanceof UserRbacInterface)
  34 + {
  35 + throw new BadRequestHttpException(Yii::t('db_rbac', 'UserClass должен реализовывать интерфейс developeruz\db_rbac\UserRbacInterface'));
  36 + }
  37 +
  38 + return parent::beforeAction($action);
  39 + }
  40 +
  41 + public function actions()
  42 + {
  43 + return [
  44 + 'error' => [
  45 + 'class' => 'yii\web\ErrorAction',
  46 + ],
  47 + ];
  48 + }
  49 +
  50 + public function behaviors()
  51 + {
  52 + return [
  53 + 'verbs' => [
  54 + 'class' => VerbFilter::className(),
  55 + 'actions' => [
  56 + 'update' => ['post'],
  57 + '*' => ['get'],
  58 + ],
  59 + ],
  60 + ];
  61 + }
  62 +
  63 + public function actionView($id)
  64 + {
  65 + $roles = ArrayHelper::map(Yii::$app->authManager->getRoles(), 'name', 'description');
  66 + $user_permit = array_keys(Yii::$app->authManager->getRolesByUser($id));
  67 + $user = $this->findUser($id);
  68 + return $this->render('view', [
  69 + 'user' => $user,
  70 + 'roles' => $roles,
  71 + 'user_permit' => $user_permit,
  72 + 'moduleName' => Yii::$app->controller->module->id
  73 + ]);
  74 + }
  75 +
  76 + public function actionUpdate($id)
  77 + {
  78 + $user = $this->findUser($id);
  79 + Yii::$app->authManager->revokeAll($user->getId());
  80 + if(Yii::$app->request->post('roles')){
  81 + foreach(Yii::$app->request->post('roles') as $role)
  82 + {
  83 + $new_role = Yii::$app->authManager->getRole($role);
  84 + Yii::$app->authManager->assign($new_role, $user->getId());
  85 + }
  86 + }
  87 + return $this->redirect(Url::to(["/".Yii::$app->controller->module->id."/user/view", 'id' => $user->getId()]));
  88 + }
  89 +
  90 + private function findUser($id)
  91 + {
  92 + $class = new Yii::$app->controller->module->params['userClass']();
  93 + $user = $class::findIdentity($id);
  94 + if(empty($user)){
  95 + throw new NotFoundHttpException(Yii::t('db_rbac', 'Пользователь не найден'));
  96 + } else {
  97 + return $user;
  98 + }
  99 + }
  100 +}
0 101 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/interfaces/UserRbacInterface.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\interfaces;
  3 +
  4 +
  5 +interface UserRbacInterface {
  6 +
  7 + public function getId();
  8 + public function getUserName();
  9 + public static function findIdentity($id);
  10 +}
0 11 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/messages/en/db_rbac.php 0 → 100644
  1 +<?php
  2 +return [
  3 + 'Правило с таким именем уже существует: ' => 'Permission with the same name already exists: ',
  4 + 'Роль с таким именем уже существует: ' => 'Role with the same name already exists: ',
  5 + 'Значение "{field}" содержит недопустимые символы' => '"{field}" value contains invalid characters',
  6 + 'Страница не найдена' => 'Page not found',
  7 + 'Недостаточно прав' => 'You not allow to access',
  8 + 'Необходимо указать класс User в настройках модуля' => 'UserClass params must be set in config file',
  9 + 'UserClass должен реализовывать интерфейс developeruz\db_rbac\UserRbacInterface' => 'UserClass must implements developeruz\db_rbac\UserRbacInterface',
  10 + 'Пользователь не найден' => 'User not found'
  11 +];
... ...
common/components/developeruz/db_rbac/views/access/addPermission.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\views\access;
  3 +
  4 +use Yii;
  5 +use yii\helpers\Html;
  6 +use yii\widgets\ActiveForm;
  7 +
  8 +/* @var $this yii\web\View */
  9 +/* @var $model common\models\Links */
  10 +/* @var $form yii\widgets\ActiveForm */
  11 +$this->title = Yii::t('db_rbac', 'Новое правило');
  12 +$this->params['breadcrumbs'][] = ['label' => Yii::t('db_rbac', 'Правила доступа'), 'url' => ['permission']];
  13 +$this->params['breadcrumbs'][] = Yii::t('db_rbac', 'Новое правило');
  14 +?>
  15 +<div class="news-index">
  16 +
  17 + <h1><?= Html::encode($this->title) ?></h1>
  18 +
  19 + <div class="links-form">
  20 + <?php
  21 + if (!empty($error)) {
  22 + ?>
  23 + <div class="error-summary">
  24 + <?php
  25 + echo implode('<br>', $error);
  26 + ?>
  27 + </div>
  28 + <?php
  29 + }
  30 + ?>
  31 +
  32 + <?php $form = ActiveForm::begin(); ?>
  33 +
  34 + <div class="form-group">
  35 + <?= Html::label(Yii::t('db_rbac', 'Текстовое описание')); ?>
  36 + <?= Html::textInput('description'); ?>
  37 + </div>
  38 +
  39 + <div class="form-group">
  40 + <?= Html::label(Yii::t('db_rbac', 'Разрешенный доступ')); ?>
  41 + <?= Html::textInput('name'); ?>
  42 + <?=Yii::t('db_rbac', '
  43 + * Формат module/controller/action<br>
  44 + site/article - доступ к странице site/article<br>
  45 + site - доступ к любым action контроллера site');?>
  46 + </div>
  47 +
  48 + <div class="form-group">
  49 + <?= Html::submitButton(Yii::t('db_rbac', 'Сохранить'), ['class' => 'btn btn-success']) ?>
  50 + </div>
  51 +
  52 + <?php ActiveForm::end(); ?>
  53 +
  54 + </div>
  55 +</div>
... ...
common/components/developeruz/db_rbac/views/access/addRole.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\views\access;
  3 +
  4 +use Yii;
  5 +use yii\helpers\Html;
  6 +use yii\widgets\ActiveForm;
  7 +
  8 +/* @var $this yii\web\View */
  9 +/* @var $model common\models\Links */
  10 +/* @var $form yii\widgets\ActiveForm */
  11 +
  12 +$this->title = Yii::t('db_rbac', 'Новая роль');
  13 +$this->params['breadcrumbs'][] = ['label' => Yii::t('db_rbac', 'Управление ролями'), 'url' => ['role']];
  14 +$this->params['breadcrumbs'][] = 'Новая роль';
  15 +?>
  16 +<div class="news-index">
  17 +
  18 + <h1><?= Html::encode($this->title) ?></h1>
  19 +
  20 + <div class="links-form">
  21 + <?php
  22 + if (!empty($error)) {
  23 + ?>
  24 + <div class="error-summary">
  25 + <?php
  26 + echo implode('<br>', $error);
  27 + ?>
  28 + </div>
  29 + <?php
  30 + }
  31 + ?>
  32 + <?php $form = ActiveForm::begin(); ?>
  33 +
  34 + <div class="form-group">
  35 + <?= Html::label(Yii::t('db_rbac', 'Название роли')); ?>
  36 + <?= Html::textInput('name'); ?>
  37 + * только латинские буквы, цифры и _ -
  38 + </div>
  39 +
  40 + <div class="form-group">
  41 + <?= Html::label(Yii::t('db_rbac', 'Текстовое описание')); ?>
  42 + <?= Html::textInput('description'); ?>
  43 + </div>
  44 +
  45 + <div class="form-group">
  46 + <?= Html::label(Yii::t('db_rbac', 'Разрешенные доступы')); ?>
  47 + <?= Html::checkboxList('permissions', null, $permissions, ['separator' => '<br>']); ?>
  48 + </div>
  49 +
  50 + <div class="form-group">
  51 + <?= Html::submitButton(Yii::t('db_rbac', 'Сохранить'), ['class' => 'btn btn-success']) ?>
  52 + </div>
  53 +
  54 + <?php ActiveForm::end(); ?>
  55 +
  56 + </div>
  57 +</div>
0 58 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/views/access/permission.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\views\access;
  3 +
  4 +use Yii;
  5 +use yii\data\ArrayDataProvider;
  6 +use yii\grid\GridView;
  7 +use yii\grid\DataColumn;
  8 +use yii\helpers\Url;
  9 +use yii\helpers\Html;
  10 +
  11 +$this->title = Yii::t('db_rbac', 'Правила доступа');
  12 +$this->params['breadcrumbs'][] = $this->title;
  13 +?>
  14 +<div class="news-index">
  15 +
  16 + <h1><?= Html::encode($this->title) ?></h1>
  17 +
  18 + <p>
  19 + <?= Html::a(Yii::t('db_rbac', 'Добавить новое правило'), ['add-permission'], ['class' => 'btn btn-success']) ?>
  20 + </p>
  21 +<?php
  22 +$dataProvider = new ArrayDataProvider([
  23 + 'allModels' => Yii::$app->authManager->getPermissions(),
  24 + 'sort' => [
  25 + 'attributes' => ['name', 'description'],
  26 + ],
  27 + 'pagination' => [
  28 + 'pageSize' => 10,
  29 + ],
  30 + ]);
  31 +?>
  32 +
  33 +<?=GridView::widget([
  34 + 'dataProvider' => $dataProvider,
  35 + 'columns' => [
  36 + ['class' => 'yii\grid\SerialColumn'],
  37 + [
  38 + 'class' => DataColumn::className(),
  39 + 'attribute' => 'name',
  40 + 'label' => Yii::t('db_rbac', 'Правило')
  41 + ],
  42 + [
  43 + 'class' => DataColumn::className(),
  44 + 'attribute' => 'description',
  45 + 'label' => Yii::t('db_rbac', 'Описание')
  46 + ],
  47 + ['class' => 'yii\grid\ActionColumn',
  48 + 'template' => '{update} {delete}',
  49 + 'buttons' =>
  50 + [
  51 + 'update' => function ($url, $model) {
  52 + return Html::a('<span class="glyphicon glyphicon-pencil"></span>', Url::toRoute(['update-permission', 'name' => $model->name]), [
  53 + 'title' => Yii::t('yii', 'Update'),
  54 + 'data-pjax' => '0',
  55 + ]); },
  56 + 'delete' => function ($url, $model) {
  57 + return Html::a('<span class="glyphicon glyphicon-trash"></span>', Url::toRoute(['delete-permission','name' => $model->name]), [
  58 + 'title' => Yii::t('yii', 'Delete'),
  59 + 'data-confirm' => Yii::t('yii', 'Are you sure you want to delete this item?'),
  60 + 'data-method' => 'post',
  61 + 'data-pjax' => '0',
  62 + ]);
  63 + }
  64 + ]
  65 + ],
  66 + ]
  67 + ]);
  68 +?>
  69 +</div>
0 70 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/views/access/role.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\views\access;
  3 +
  4 +use Yii;
  5 +use yii\data\ArrayDataProvider;
  6 +use yii\grid\GridView;
  7 +use yii\grid\DataColumn;
  8 +use yii\helpers\Url;
  9 +use yii\helpers\Html;
  10 +use yii\helpers\ArrayHelper;
  11 +
  12 +$this->title = Yii::t('db_rbac', 'Управление ролями');
  13 +$this->params['breadcrumbs'][] = $this->title;
  14 +?>
  15 +<div class="news-index">
  16 +
  17 + <h1><?= Html::encode($this->title) ?></h1>
  18 +
  19 + <p>
  20 + <?= Html::a(Yii::t('db_rbac', 'Добавить роль'), ['add-role'], ['class' => 'btn btn-success']) ?>
  21 + </p>
  22 +<?php
  23 +$dataProvider = new ArrayDataProvider([
  24 + 'allModels' => Yii::$app->authManager->getRoles(),
  25 + 'sort' => [
  26 + 'attributes' => ['name', 'description'],
  27 + ],
  28 + 'pagination' => [
  29 + 'pageSize' => 10,
  30 + ],
  31 + ]);
  32 +?>
  33 +
  34 +<?=GridView::widget([
  35 + 'dataProvider' => $dataProvider,
  36 + 'columns' => [
  37 + ['class' => 'yii\grid\SerialColumn'],
  38 + [
  39 + 'class' => DataColumn::className(),
  40 + 'attribute' => 'name',
  41 + 'label' => Yii::t('db_rbac', 'Роль')
  42 + ],
  43 + [
  44 + 'class' => DataColumn::className(),
  45 + 'attribute' => 'description',
  46 + 'label' => Yii::t('db_rbac', 'Описание')
  47 + ],
  48 + [
  49 + 'class' => DataColumn::className(),
  50 + 'label' => Yii::t('db_rbac', 'Разрешенные доступы'),
  51 + 'format' => ['html'],
  52 + 'value' => function($data) { return implode('<br>',array_keys(ArrayHelper::map(Yii::$app->authManager->getPermissionsByRole($data->name), 'description', 'description')));}
  53 + ],
  54 + ['class' => 'yii\grid\ActionColumn',
  55 + 'template' => '{update} {delete}',
  56 + 'buttons' =>
  57 + [
  58 + 'update' => function ($url, $model) {
  59 + return Html::a('<span class="glyphicon glyphicon-pencil"></span>', Url::toRoute(['update-role', 'name' => $model->name]), [
  60 + 'title' => Yii::t('yii', 'Update'),
  61 + 'data-pjax' => '0',
  62 + ]); },
  63 + 'delete' => function ($url, $model) {
  64 + return Html::a('<span class="glyphicon glyphicon-trash"></span>', Url::toRoute(['delete-role','name' => $model->name]), [
  65 + 'title' => Yii::t('yii', 'Delete'),
  66 + 'data-confirm' => Yii::t('yii', 'Are you sure you want to delete this item?'),
  67 + 'data-method' => 'post',
  68 + 'data-pjax' => '0',
  69 + ]);
  70 + }
  71 + ]
  72 + ],
  73 + ]
  74 + ]);
  75 +?>
  76 +</div>
0 77 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/views/access/updatePermission.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\views\access;
  3 +
  4 +use Yii;
  5 +use yii\helpers\Html;
  6 +use yii\widgets\ActiveForm;
  7 +
  8 +/* @var $this yii\web\View */
  9 +/* @var $model common\models\Links */
  10 +/* @var $form yii\widgets\ActiveForm */
  11 +
  12 +$this->title = Yii::t('db_rbac', 'Редактирование правила: ') . ' ' . $permit->description;
  13 +$this->params['breadcrumbs'][] = ['label' => Yii::t('db_rbac', 'Правила доступа'), 'url' => ['permission']];
  14 +$this->params['breadcrumbs'][] = Yii::t('db_rbac', 'Редактирование правила');
  15 +?>
  16 +<div class="news-index">
  17 +
  18 + <h1><?= Html::encode($this->title) ?></h1>
  19 +
  20 + <div class="links-form">
  21 +
  22 + <?php
  23 + if (!empty($error)) {
  24 + ?>
  25 + <div class="error-summary">
  26 + <?php
  27 + echo implode('<br>', $error);
  28 + ?>
  29 + </div>
  30 + <?php
  31 + }
  32 + ?>
  33 +
  34 + <?php $form = ActiveForm::begin(); ?>
  35 +
  36 + <div class="form-group">
  37 + <?= Html::label(Yii::t('db_rbac', 'Текстовое описание')); ?>
  38 + <?= Html::textInput('description', $permit->description); ?>
  39 + </div>
  40 +
  41 + <div class="form-group">
  42 + <?= Html::label(Yii::t('db_rbac', 'Разрешенный доступ')); ?>
  43 + <?= Html::textInput('name', $permit->name); ?>
  44 + </div>
  45 +
  46 + <div class="form-group">
  47 + <?= Html::submitButton(Yii::t('db_rbac', 'Сохранить'), ['class' => 'btn btn-success']) ?>
  48 + </div>
  49 +
  50 + <?php ActiveForm::end(); ?>
  51 +
  52 + </div>
  53 +</div>
0 54 \ No newline at end of file
... ...
common/components/developeruz/db_rbac/views/access/updateRole.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\views\access;
  3 +
  4 +use Yii;
  5 +use yii\helpers\Html;
  6 +use yii\widgets\ActiveForm;
  7 +
  8 +$this->title = Yii::t('db_rbac', 'Редактирование роли: ') . ' ' . $role->name;
  9 +$this->params['breadcrumbs'][] = ['label' => Yii::t('db_rbac', 'Управление ролями'), 'url' => ['role']];
  10 +$this->params['breadcrumbs'][] = Yii::t('db_rbac', 'Редактирование');
  11 +?>
  12 +<div class="news-index">
  13 +
  14 + <h1><?= Html::encode($this->title) ?></h1>
  15 +
  16 + <div class="links-form">
  17 +
  18 + <?php
  19 + if (!empty($error)) {
  20 + ?>
  21 + <div class="error-summary">
  22 + <?php
  23 + echo implode('<br>', $error);
  24 + ?>
  25 + </div>
  26 + <?php
  27 + }
  28 + ?>
  29 +
  30 + <?php $form = ActiveForm::begin(); ?>
  31 +
  32 + <div class="form-group">
  33 + <?= Html::label(Yii::t('db_rbac', 'Название роли')); ?>
  34 + <?= Html::textInput('name', $role->name); ?>
  35 + </div>
  36 +
  37 + <div class="form-group">
  38 + <?= Html::label(Yii::t('db_rbac', 'Текстовое описание')); ?>
  39 + <?= Html::textInput('description', $role->description); ?>
  40 + </div>
  41 +
  42 + <div class="form-group">
  43 + <?= Html::label(Yii::t('db_rbac', 'Разрешенные доступы')); ?>
  44 + <?= Html::checkboxList('permissions', $role_permit, $permissions, ['separator' => '<br>']); ?>
  45 + </div>
  46 +
  47 + <div class="form-group">
  48 + <?= Html::submitButton(Yii::t('db_rbac', 'Сохранить'), ['class' => 'btn btn-success']) ?>
  49 + </div>
  50 +
  51 + <?php ActiveForm::end(); ?>
  52 +
  53 + </div>
  54 +</div>
... ...
common/components/developeruz/db_rbac/views/user/view.php 0 → 100644
  1 +<?php
  2 +namespace developeruz\db_rbac\views\user;
  3 +
  4 +use Yii;
  5 +use yii\helpers\Html;
  6 +use yii\widgets\ActiveForm;
  7 +
  8 +?>
  9 +<h3><?=Yii::t('db_rbac', 'Управление ролями пользователя');?> <?= $user->getUserName(); ?></h3>
  10 +<?php $form = ActiveForm::begin(['action' => ["/{$moduleName}/user/update", 'id' => $user->getId()]]); ?>
  11 +
  12 +<?= Html::checkboxList('roles', $user_permit, $roles, ['separator' => '<br>']); ?>
  13 +
  14 +<div class="form-group">
  15 + <?= Html::submitButton(Yii::t('db_rbac', 'Сохранить'), ['class' => 'btn btn-success']) ?>
  16 +</div>
  17 +
  18 +<?php ActiveForm::end(); ?>
  19 +
... ...
common/config/main.php
... ... @@ -2,8 +2,8 @@
2 2 return [
3 3 'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
4 4 'modules' => [
5   - 'permit' => [
6   - 'class' => 'app\modules\db_rbac\Yii2DbRbac',
  5 + 'permit' => [
  6 + 'class' => 'common\components\developeruz\db_rbac\Yii2DbRbac',
7 7 'params' => [
8 8 'userClass' => 'common\models\User'
9 9 ]
... ...