Skip to content

Endytech/UserPermissions

Repository files navigation

Это advanced yii2, как обычно init, composer, common/config - DB и migrate

Добавляем миграцией role_id в таблицу user

$this->addColumn('user', 'role_id', 'INTEGER(3)');

Дополнительно миграцией создаю админа admin@cybtronix.com с паролем из ТЗ п.1.3

Добавляем роли и определяющие роль методы в модель user

namespace common\models;
...
class User extends ActiveRecord implements IdentityInterface
{
...
   const ROLE_ADMIN = 1;
   const ROLE_SUPERVISOR = 2;
   const ROLE_ACQUISITION_MANAGER = 3;
   const ROLE_SUPPLIER = 4;

   public function isAdmin()
   {
       return $this->role_id == self::ROLE_ADMIN;
   }
   public function isSupervisor()
   {
       return $this->role_id == self::ROLE_SUPERVISOR;
   }
   public function isManager()
   {
       return $this->role_id == self::ROLE_ACQUISITION_MANAGER;
   }
   public function isSupplier()
   {
       return $this->role_id == self::ROLE_SUPPLIER;
   }
…

Добавляем класс UserPermissions, чтобы сделать его компонентом приложения где user берется как \Yii::$app->user->identity, а остальные данные, если требуется, передаются в функцию при ее вызове. common\components\UserPermissions.php

<?php
namespace common\components;

class UserPermissions
{
   public function canViewProcurement($procurement)
   {
       $currentUserID = \Yii::$app->user->getId();
       $currentUser = \Yii::$app->user->identity;

       if (\Yii::$app->user->isGuest) {
           return false;
       }

       if ($currentUser->isAdmin()) {
           return true;
       }

       if ($currentUser->isSupervisor()) {
           return true;
       }

       if ($currentUser->isManager()) {
           if ($procurement) {
               if ($procurement->procurement_status == Procurement::STATUS_DELETED){
                   return false;
               }
               if ($procurement->procurement_owner == $currentUserID) {
                   return true;
               }
           } else {
               return false;
           }
       }

  if ($currentUser->isSupplier()) {
            if ($procurement) {
                switch ($procurement->procurement_status){
                    case Procurement::STATUS_PLANNED_FOR_EXECUTION:
                        return false;
                    case Procurement::STATUS_BIDDING:
                        return true;
                    case Procurement::STATUS_DECISION_MAKING:
                        if ($currentUser->hasTenderBids($procurement)){
                            return true;
                        }
                        break;
                    case Procurement::STATUS_IN_PROGRESS:
                        if ($currentUser->isWinnerTender($procurement)){
                            return true;
                        }
                        break;
                    case Procurement::STATUS_PROCUREMENT_COMPLETED:
                        if ($currentUser->isWinnerTender($procurement)){
                            return true;
                        }
                        break;
                    case Procurement::STATUS_CANCELLED:
                        return false;
                    case Procurement::STATUS_ARCHIVED:
                        return false;
                    case Procurement::STATUS_DELETED:
                        return false;
                }
            } else {
                return false;
            }
        }
       return false;
   }

}

Добавляем компонент UserPermissions в приложение common\config\main.php

'components' => [
   'cache' => [
       'class' => 'yii\caching\FileCache',
   ],
   'UserPermissions' => [
       'class' => 'common\components\UserPermissions',
   ],
],

Теперь вызывая UserPermissions в любом месте приложения можно выполнить проверку

if (\Yii::$app->UserPermissions->canViewProcurement([])) {
   echo 'Can View';
}

Для контроля доступа к действиям контроллера используем AccessControl, в случае необходимости передать в проверку модель используем matchCallback:

class ProcurementController extends Controller
{
    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'actions' => ['index', 'error'],
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                    [
                        'actions' => ['create', 'update', 'delete'],
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                    [
                        'actions' => ['view'],
                        'allow' => true,
                        'roles' => ['@'],
                        'matchCallback' => function ($rule, $action) {
                            $procurement=$this->findModel(Yii::$app->request->get('id'));
                            return \Yii::$app->UserPermissions->canViewProcurement($procurement);
                        }
                    ],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'delete' => ['POST'],
                ],
            ],
        ];
    }

Для консоли или создать отдельную функцию в UserPermissions и передавать пользователя или можно в конфигурации подключить User и устанавливать пользователей вручную console\config\main.php

'components' => [
    'log' => [
        'targets' => [
            [
                'class' => 'yii\log\FileTarget',
                'levels' => ['error', 'warning'],
            ],
        ],
    ],
    'user' => [
        'class' => 'yii\web\User',
        'identityClass' => 'common\models\User',
        'enableAutoLogin' => true,
        'identityCookie' => ['name' => '_identity-console', 'httpOnly' => true],
    ],
],

Задаем вручную в identity в действии консольного контроллера

namespace console\controllers;

use common\models\User;
use yii\console\Controller;

class UserPermissionController extends Controller
{
    public function actionTest()
    {
        $users = User::find()->all();
        foreach ($users as $user) {

            \Yii::$app->user->setIdentity($user);

            if (\Yii::$app->UserPermissions->canViewProcurement([])) {
                echo 'User '. $user->email . ' Can View Procurement';
            }
//создать отдельную функцию в UserPermissions и передавать в функцию пользователя
//            if (\Yii::$app->UserPermissions->canUsersViewProcurement($user, [])) {
//                echo 'User '. $user->email . ' Can View Procurement';
//            }
        }
    }
}

About

Test UserPermissions

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published