Security   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 76
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 12
eloc 31
c 1
b 0
f 0
dl 0
loc 76
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A checkRoutes() 0 12 4
A checkApi() 0 9 3
A __construct() 0 4 1
A handle() 0 22 4
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
    public const KEY = 'abteradmin:security';
20
21
    public const TEST_LOGIN_PATH                  = '/login-iddqd';
22
    public const TEST_ADMIN_BASE_PATH             = '/admin-iddqd';
23
    public const TEST_API_BASE_PATH               = '/api-iddqd';
24
    public const TEST_OAUTH2_PRIVATE_KEY_PASSWORD = 'CuDU2M9FRD8ckRxj9dhB82f6VjMs4EMf';
25
26
    protected ICacheBridge $cacheBridge;
27
    protected RoutesConfig $routesConfig;
28
29
    /**
30
     * Security constructor.
31
     *
32
     * @param ICacheBridge $cacheBridge
33
     * @param RoutesConfig $routesConfig
34
     */
35
    public function __construct(ICacheBridge $cacheBridge, RoutesConfig $routesConfig)
36
    {
37
        $this->cacheBridge  = $cacheBridge;
38
        $this->routesConfig = $routesConfig;
39
    }
40
41
    // $next consists of the next middleware in the pipeline
42
    public function handle(Request $request, Closure $next): Response
43
    {
44
        if (Environment::getVar(Env::ENV_NAME, Environment::PRODUCTION) !== Environment::PRODUCTION) {
45
            return $next($request);
46
        }
47
48
        // phpcs:disable Generic.CodeAnalysis.EmptyStatement
49
        try {
50
            if ($this->cacheBridge->has(static::KEY)) {
51
                return $next($request);
52
            }
53
        } catch (\Exception $e) {
54
            // It's always safe to check the security checks, it just makes the response slightly slower
55
        }
56
        // phpcs:enable Generic.CodeAnalysis.EmptyStatement
57
58
        $this->checkRoutes();
59
        $this->checkApi($request);
60
61
        $this->cacheBridge->set(static::KEY, true, PHP_INT_MAX);
62
63
        return $next($request);
64
    }
65
66
    private function checkRoutes()
67
    {
68
        if ($this->routesConfig->getLoginPath() === static::TEST_LOGIN_PATH) {
69
            throw new SecurityException('Invalid ADMIN_LOGIN_PATH environment variable.');
70
        }
71
72
        if ($this->routesConfig->getAdminBasePath() === static::TEST_ADMIN_BASE_PATH) {
73
            throw new SecurityException('Invalid ADMIN_BASE_PATH environment variable.');
74
        }
75
76
        if ($this->routesConfig->getApiBasePath() === static::TEST_API_BASE_PATH) {
77
            throw new SecurityException('Invalid ADMIN_BASE_PATH environment variable.');
78
        }
79
    }
80
81
    /**
82
     * @param Request $request
83
     */
84
    private function checkApi(Request $request)
85
    {
86
        $env = $request->getEnv();
87
88
        if (empty($env[Env::OAUTH2_PRIVATE_KEY_PASSWORD])) {
89
            throw new SecurityException('Invalid OAUTH_PRIVATE_KEY_PASSWORD environment variable.');
90
        }
91
        if ($env[Env::OAUTH2_PRIVATE_KEY_PASSWORD] === static::TEST_OAUTH2_PRIVATE_KEY_PASSWORD) {
92
            throw new SecurityException('Invalid OAUTH_PRIVATE_KEY_PASSWORD environment variable.');
93
        }
94
    }
95
}
96