Passed
Push — master ( 80fed1...32ef61 )
by Peter
09:46
created

Security::checkRoutes()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 12
rs 10
cc 4
nc 4
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Admin\Http\Middleware;
6
7
use AbterPhp\Admin\Config\Routes as RoutesConfig;
8
use AbterPhp\Framework\Constant\Env;
9
use AbterPhp\Framework\Exception\Security as SecurityException;
10
use Closure;
11
use Opulence\Cache\ICacheBridge;
12
use Opulence\Environments\Environment;
13
use Opulence\Http\Requests\Request;
14
use Opulence\Http\Responses\Response;
15
use Opulence\Routing\Middleware\IMiddleware;
16
17
class Security implements IMiddleware
18
{
19
    const KEY = 'abteradmin:security';
20
21
    const TEST_LOGIN_PATH                  = '/login-iddqd';
22
    const TEST_ADMIN_BASE_PATH             = '/admin-iddqd';
23
    const TEST_API_BASE_PATH               = '/api-iddqd';
24
    const TEST_OAUTH2_PRIVATE_KEY_PASSWORD = 'CuDU2M9FRD8ckRxj9dhB82f6VjMs4EMf';
25
26
    /** @var ICacheBridge */
27
    protected $cacheBridge;
28
29
    /**
30
     * Security constructor.
31
     *
32
     * @param ICacheBridge $cacheBridge
33
     */
34
    public function __construct(ICacheBridge $cacheBridge)
35
    {
36
        $this->cacheBridge = $cacheBridge;
37
    }
38
39
    // $next consists of the next middleware in the pipeline
40
    public function handle(Request $request, Closure $next): Response
41
    {
42
        if (Environment::getVar(Env::ENV_NAME, Environment::PRODUCTION) !== Environment::PRODUCTION) {
43
            return $next($request);
44
        }
45
46
        // phpcs:disable Generic.CodeAnalysis.EmptyStatement
47
        try {
48
            if ($this->cacheBridge->has(static::KEY)) {
49
                return $next($request);
50
            }
51
        } catch (\Exception $e) {
52
            // It's always safe to check the security checks, it just makes the response slightly slower
53
        }
54
        // phpcs:enable Generic.CodeAnalysis.EmptyStatement
55
56
        $this->checkRoutes();
57
        $this->checkApi($request);
58
59
        $this->cacheBridge->set(static::KEY, true, PHP_INT_MAX);
60
61
        return $next($request);
62
    }
63
64
    private function checkRoutes()
65
    {
66
        if (RoutesConfig::getLoginPath() === static::TEST_LOGIN_PATH) {
67
            throw new SecurityException('Invalid ADMIN_LOGIN_PATH environment variable.');
68
        }
69
70
        if (RoutesConfig::getAdminBasePath() === static::TEST_ADMIN_BASE_PATH) {
71
            throw new SecurityException('Invalid ADMIN_BASE_PATH environment variable.');
72
        }
73
74
        if (RoutesConfig::getApiBasePath() === static::TEST_API_BASE_PATH) {
75
            throw new SecurityException('Invalid ADMIN_BASE_PATH environment variable.');
76
        }
77
    }
78
79
    /**
80
     * @param Request $request
81
     */
82
    private function checkApi(Request $request)
83
    {
84
        $env = $request->getEnv();
85
86
        if (empty($env[Env::OAUTH2_PRIVATE_KEY_PASSWORD])) {
87
            throw new SecurityException('Invalid OAUTH_PRIVATE_KEY_PASSWORD environment variable.');
88
        }
89
        if ($env[Env::OAUTH2_PRIVATE_KEY_PASSWORD] === static::TEST_OAUTH2_PRIVATE_KEY_PASSWORD) {
90
            throw new SecurityException('Invalid OAUTH_PRIVATE_KEY_PASSWORD environment variable.');
91
        }
92
    }
93
}
94