Module.php 3.55 KB
Newer Older
Камалов Эрик's avatar
Камалов Эрик committed
1
2
3
4
5
6
7
8
9
10
<?php

namespace deck\MockRequest;

use deck\MockRequest\models\Request;
use Yii;
use yii\base\Action;
use yii\base\BootstrapInterface;
use yii\caching\TagDependency;
use yii\helpers\IpHelper;
Камалов Эрик's avatar
s    
Камалов Эрик committed
11
use yii\web\Application;
Камалов Эрик's avatar
Камалов Эрик committed
12
13
14
15
16
17
use yii\web\ForbiddenHttpException;
use yii\web\UrlRule;

class Module extends \yii\base\Module implements BootstrapInterface
{

Камалов Эрик's avatar
s    
Камалов Эрик committed
18
19
    public $urlRuleClass = 'yii\web\UrlRule';

Камалов Эрик's avatar
Камалов Эрик committed
20
21
22
23
24
25
26
    public $layout = 'main.php';
    public $allowedIPs = ['127.0.0.1', '::1'];
    public $allowedHosts = [];
    public $checkAccessCallback;

    public $controllerNamespace = 'deck\MockRequest\controllers';

Камалов Эрик's avatar
s    
Камалов Эрик committed
27
28
29
30
    /**
     * @param Application $app
     * @return void
     */
Камалов Эрик's avatar
Камалов Эрик committed
31
32
33
    public function bootstrap($app)
    {
        $routes = [];
Камалов Эрик's avatar
s    
Камалов Эрик committed
34
35
        /** @var Request[] $requests */
        $requests = Yii::$app->cache->getOrSet('mock-requests', function () {
Камалов Эрик's avatar
s    
Камалов Эрик committed
36
            return Request::find()->with(['method'])->where(['is_enabled' => true])->all();
Камалов Эрик's avatar
s    
Камалов Эрик committed
37
38
        }, 3600, new TagDependency(['tags' => 'mock-request']));
        foreach ($requests as $request) {
Камалов Эрик's avatar
Камалов Эрик committed
39
40
            $routes[] = ['class' => UrlRule::class, 'pattern' => sprintf('%s', $request->url), 'route' => sprintf('%s/default/mock', $this->id), 'defaults' => ['id' => $request->id], 'verb' => $request->method->name];
        }
Камалов Эрик's avatar
s    
Камалов Эрик committed
41
        $app->urlManager->addRules($routes, false);
Камалов Эрик's avatar
s    
Камалов Эрик committed
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

        $app->getUrlManager()->addRules([
            [
                'class' => $this->urlRuleClass,
                'route' => $this->getUniqueId(),
                'pattern' => $this->getUniqueId(),
                'normalizer' => false,
                'suffix' => false
            ],
            [
                'class' => $this->urlRuleClass,
                'route' => $this->getUniqueId() . '/<controller>/<action>',
                'pattern' => $this->getUniqueId() . '/<controller:[\w\-]+>/<action:[\w\-]+>',
                'normalizer' => false,
                'suffix' => false
            ]
        ], false);
Камалов Эрик's avatar
Камалов Эрик committed
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    }

    /**
     * @param $action
     * @return bool
     * @throws ForbiddenHttpException
     */
    public function beforeAction($action): bool
    {
        if (!parent::beforeAction($action)) {
            return false;
        }

        if (!$this->checkAccess($action)) {
            throw new ForbiddenHttpException('You are not allowed to access this page.');
        }
        return true;
    }

    protected function checkAccess(Action $action = null): bool
    {
        $allowed = $action->controller->id === 'default' && $action->id === 'mock';
        $ip = Yii::$app->getRequest()->getUserIP();
        foreach ($this->allowedIPs as $filter) {
            if ($filter === '*'
                || $filter === $ip
                || (
                    ($pos = strpos($filter, '*')) !== false
                    && !strncmp($ip, $filter, $pos)
                )
                || (
                    strpos($filter, '/') !== false
                    && IpHelper::inRange($ip, $filter)
                )
            ) {
                $allowed = true;
                break;
            }
        }

        if ($allowed === false) {
            foreach ($this->allowedHosts as $hostname) {
                $filter = gethostbyname($hostname);
                if ($filter === $ip) {
                    $allowed = true;
                    break;
                }
            }
        }

        if ($allowed === false) {
            return false;
        }

        if ($this->checkAccessCallback !== null && call_user_func($this->checkAccessCallback, $action) !== true) {

            return false;
        }

        return true;
    }
}