Yii 2 rbac

на основании


\yii2rbac\common\config\main.php

 dirname(dirname(__DIR__)) . '/vendor',
    'components' => [
        'urlManager' => [
            'class' => 'yii\web\urlManager',
            'enablePrettyUrl' => true,
        ],
        'cache' => [
            'class' => 'yii\caching\FileCache',
        ],
        'authManager' => [
            'class' => 'yii\rbac\DbManager',
        ],
    ],

так использую постгрес. миграции не сработают. берем sql файл из
\localhost\yii2rbac\vendor\yiisoft\yii2\rbac\migrations

восстановление пошло не по плану. что ж создадим таблички сами

CREATE TABLE yii2.auth_rule (
  name TEXT NOT NULL,
  data TEXT,
  created_at TIMESTAMP(0) WITHOUT TIME ZONE,
  updated_at TIMESTAMP(0) WITHOUT TIME ZONE,
  CONSTRAINT auth_rule_pkey PRIMARY KEY(name)
) 
WITH (oids = false);

CREATE TABLE yii2.auth_item (
  name TEXT NOT NULL,
  type INTEGER,
  description TEXT,
  rule_name TEXT,
  data TEXT,
  created_at TIMESTAMP(0) WITHOUT TIME ZONE,
  updated_at TIMESTAMP(0) WITHOUT TIME ZONE,
  CONSTRAINT auth_item_pkey PRIMARY KEY(name),
  CONSTRAINT auth_item_fk FOREIGN KEY (rule_name)
    REFERENCES yii2.auth_rule(name)
    ON DELETE CASCADE
    ON UPDATE CASCADE
    NOT DEFERRABLE
) 
WITH (oids = false);

CREATE TABLE yii2.auth_item_child (
  parent TEXT NOT NULL,
  child TEXT NOT NULL,
  CONSTRAINT auth_item_child_idx PRIMARY KEY(child, parent),
  CONSTRAINT auth_item_child_fk FOREIGN KEY (parent)
    REFERENCES yii2.auth_item(name)
    ON DELETE CASCADE
    ON UPDATE CASCADE
    NOT DEFERRABLE,
  CONSTRAINT auth_item_child_fk1 FOREIGN KEY (child)
    REFERENCES yii2.auth_item(name)
    ON DELETE CASCADE
    ON UPDATE CASCADE
    NOT DEFERRABLE
) 
WITH (oids = false);

CREATE TABLE yii2.auth_assignment (
  item_name TEXT NOT NULL,
  user_id INTEGER NOT NULL,
  created_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT now()::timestamp without time zone,
  CONSTRAINT auth_assignment_idx PRIMARY KEY(item_name, user_id),
  CONSTRAINT auth_assignment_fk FOREIGN KEY (item_name)
    REFERENCES yii2.auth_item(name)
    ON DELETE CASCADE
    ON UPDATE CASCADE
    NOT DEFERRABLE
) 
WITH (oids = false);

подключаем модуль

composer require developeruz/yii2-db-rbac "dev-master"

можеи перейти на http://localhost/yii2rbac/backend/web/index.php//permit/access/role

для управления ролями.

у меня вышел косяк - не увидел таблицы в схеме пришлось править в
\yii2rbac\vendor\yiisoft\yii2\rbac\DbManager.php путь к базе

    public $db = 'db';
    /**
     * @var string the name of the table storing authorization items. Defaults to "auth_item".
     */
    public $itemTable = 'yii2.{{%auth_item}}';
    /**
     * @var string the name of the table storing authorization item hierarchy. Defaults to "auth_item_child".
     */
    public $itemChildTable = 'yii2.{{%auth_item_child}}';
    /**
     * @var string the name of the table storing authorization item assignments. Defaults to "auth_assignment".
     */
    public $assignmentTable = 'yii2.{{%auth_assignment}}';
    /**
     * @var string the name of the table storing rules. Defaults to "auth_rule".
     */
    public $ruleTable = 'yii2.{{%auth_rule}}';

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

поправил \yii2rbac\vendor\yiisoft\yii2\rbac\DbManager.php

    protected function addItem($item)
    {
        //$time = time();
        $time = date("Y-m-d H:i:s"); 

для выпадающего списка ролей нужно создать модель


при создании базы удивило отсутствие айдишников. сейчас при создании списка это аукнулось. в auth_item создаю поле id, делаю его serial

На самом деле pg нормально отрабатывает если прописать так \yii2rbac\common\config\db.php

 'yii\db\Connection',
    //'dsn' => 'mysql:host=localhost;dbname=localdb',
    'dsn' => 'pgsql:host=*.ru;port=5432;dbname=DB_*',
    'username' => '*',
    'password' => '*',
    'charset' => 'utf8',
    'schemaMap' => [
        'pgsql' => [
            'class' => 'yii\db\pgsql\Schema',
            'defaultSchema' => 'yii2', //specify your schema here
        ]
    ],
    'on afterOpen' => function ($event)
    {
        $event->sender->createCommand("SET search_path TO yii2")->execute();
    }
];


пришлось снова поправить модель \localhost\yii2rbac\backend\models\Role.php

    public static function tableName()
    {
        return Yii::$app->params['pgschema'] . '.auth_item';
    }

yii2rbac\backend\views\user\_form.php

use yii\helpers\ArrayHelper;
use backend\models\Role;
 
Html::activeDropDownList(
        $model,
        'id_role',
        ArrayHelper::map(
            Role::find()->all(), 'id', 'name'
        )
    )

получил
поправим localhost\yii2rbac\backend\models\MyUser.php

    public function beforeSave($insert)
    {
        if (!$this->isNewRecord)
        {
            $command = static::getDb()->createCommand("SELECT password_hash FROM yii2.\"user\" where id =$this->id")->queryScalar();

            if ($command != $this->password_hash)
            {
                $this->password_hash = Yii::$app->security->generatePasswordHash($this->password_hash);
            }
        }
           // $userId = \Yii::$app->user->identity->id;
            $userId = $this->id;
            $command = static::getDb()->createCommand("SELECT name FROM yii2.\"auth_item\" where id =$this->id_role")->queryScalar();
            $userRole = Yii::$app->authManager->getRole($command);
            Yii::$app->authManager->revokeAll($userId);
            Yii::$app->authManager->assign($userRole, $this->id);
       
        return parent::beforeSave($insert);
    }

проверяем \yii2rbac\frontend\controllers\SiteController.php

    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'only' => ['logout', 'signup','about'],
                'rules' => [
                    [
                        'actions' => ['signup'],
                        'allow' => true,
                        'roles' => ['?'],
                        
                    ],
                    [
                        'actions' => ['logout'],
                        'allow' => true,
                        'roles' => ['@'],
                      //  'roles' => ['admin'],
                    ],
                         [
                    'actions' => ['about'],
                    'allow' => true,
                    'roles' => ['admin'],
                ],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'logout' => ['post'],
                ],
            ],
            
        ];
    }

если не админ то по /yii2rbac/frontend/web/index.php/site/about

\yii2rbac\backend\controllers\UserController.php
добавим проверку прав в контролере пользователей


use yii\filters\AccessControl;

    public function behaviors()
    {
        return [
                'access' => [
                'class' => AccessControl::className(),
                'only' => ['delete'],
                'rules' => [                   
                    [
                    'actions' => ['delete'],
                    'allow' => true,
                    'roles' => ['admin'],
                ],
                ],
            ],            
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'delete' => ['post'],
                ],
            ],
        ];
    }

но думаю можно и просто убрать кнопки в \yii2rbac\backend\views\user\index.php

    $user = \Yii::$app->user;
 $isAdmin = $user->can('superadmin') || $user->can('admin'); // true если юзер является админом
 // если роль "superadmin" наследуется от "admin" то для проверки будет достаточно только одно условия
 // $isAdmin = $user->can('admin'); # true если пользователь имеет права админа

    if (true === $isAdmin)
    {
    $buttons =   ['class' => 'yii\grid\ActionColumn',
                'template' => '{view} {update} {delete}',
               // 'view'=>
                ];
    }
    else 
    {
        $buttons =   ['class' => 'yii\grid\ActionColumn',
                'template' => '{view}',
               // 'view'=>
                ];
    }
    echo GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],

            'id',
            'username',
            //'password_hash',
            'id_role',
            'comment:ntext',
            // 'created_at',
            // 'ban_date',
            // 'status',
            // 'auth_key:ntext',
          
            $buttons
        
        ],
    ]); 

Популярные сообщения из этого блога

Пишем логи на C# (.NET). Легкий способ.

Средства для работы с базой данный PostgreSql

Авторизация yii 2 из базы