Blame view

common/components/developeruz/db_rbac/behaviors/AccessBehavior.php 2.85 KB
14a09168   Alex Savenko   init commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  <?php

  /**

   * AccessBehavior for Yii2

   *

   * @author Elle <elleuz@gmail.com>

   * @version 0.1

   * @package AccessBehavior for Yii2

   *

   */

  namespace developeruz\db_rbac\behaviors;

  

  use Yii;

  use yii\behaviors\AttributeBehavior;

  use yii\di\Instance;

  use yii\base\Module;

  use yii\web\Application;

  use yii\web\User;

  use yii\filters\AccessControl;

  use yii\web\ForbiddenHttpException;

  

  class AccessBehavior extends AttributeBehavior {

  

      public $rules=[];

  

      private $_rules = [];

  

      public function events()

      {

          return [

              Module::EVENT_BEFORE_ACTION => 'interception',

          ];

      }

  

      public function interception($event)

      {

          if(!isset( Yii::$app->i18n->translations['db_rbac'])){

              Yii::$app->i18n->translations['db_rbac'] = [

                  'class' => 'yii\i18n\PhpMessageSource',

                  'sourceLanguage' => 'ru-Ru',

                  'basePath' => '@developeruz/db_rbac/messages',

              ];

          }

  

          $route = Yii::$app->getRequest()->resolve();

  

          //Проверяем права по конфигу

          $this->createRule();

          $user = Instance::ensure(Yii::$app->user, User::className());

          $request = Yii::$app->getRequest();

          $action = $event->action;

  

          if(!$this->cheсkByRule($action, $user, $request))

          {

              //И по AuthManager

              if(!$this->checkPermission($route))

                  throw new ForbiddenHttpException(Yii::t('db_rbac','Недостаточно прав'));

          }

      }

  

      protected function createRule()

      {

          foreach($this->rules as $controller => $rule)

          {

              foreach ($rule as $singleRule) {

                  if (is_array($singleRule)) {

                      $option = [

                          'controllers' => [$controller],

                          'class' => 'yii\filters\AccessRule'

                      ];

                      $this->_rules[] = Yii::createObject(array_merge($option, $singleRule));

                  }

              }

          }

      }

  

      protected function cheсkByRule($action, $user, $request)

      {

          foreach ($this->_rules as $rule) {

              if ($rule->allows($action, $user, $request))

                  return true;

          }

          return false;

      }

  

      protected function checkPermission($route)

      {

          //$route[0] - is the route, $route[1] - is the associated parameters

  

          $routePathTmp = explode('/', $route[0]);

          $routeVariant = array_shift($routePathTmp);

          if(Yii::$app->user->can($routeVariant, $route[1]))

              return true;

  

          foreach($routePathTmp as $routePart)

          {

              $routeVariant .= '/'.$routePart;

              if(Yii::$app->user->can($routeVariant, $route[1]))

                  return true;

          }

  

          return false;

      }

  }