Passed
Push — master ( f2f9fb...1cd2da )
by Fran
02:56
created

Security::checkAdmin()   B

Complexity

Conditions 11
Paths 28

Size

Total Lines 42
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 11

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 11
eloc 28
nc 28
nop 3
dl 0
loc 42
ccs 31
cts 31
cp 1
crap 11
rs 7.3166
c 2
b 0
f 1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace PSFS\base;
4
5
use PSFS\base\types\helpers\AuthHelper;
6
use PSFS\base\types\helpers\Inspector;
7
use PSFS\base\types\helpers\ResponseHelper;
8
use PSFS\base\types\traits\SecureTrait;
9
use PSFS\base\types\traits\Security\FlashesTrait;
10
use PSFS\base\types\traits\Security\ProfileTrait;
11
use PSFS\base\types\traits\SingletonTrait;
12
use PSFS\base\types\traits\TestTrait;
13
14
/**
15
 * Class Security
16
 * @package PSFS
17
 */
18
class Security
19
{
20
    // sha1('FLASHES')
21
    const FLASH_MESSAGE_TOKEN = '4680c68435db1bfbf17c3fcc4f7b39d2c6122504';
22
    const LOGGED_USER_TOKEN = '__U_T_L__';
23
24
    use SecureTrait;
25
    use SingletonTrait;
26
    use TestTrait;
27
    use ProfileTrait;
28
    use FlashesTrait;
29
30
    /**
31
     * @var bool $authorized
32
     */
33
    private $authorized = FALSE;
34
35
    /**
36
     * @var bool $checked
37
     */
38
    private $checked = false;
39
40
    /**
41
     * Constructor por defecto
42
     */
43 2
    public function init()
44
    {
45 2
        $this->initSession();
46 2
        if (NULL === $this->getSessionKey('__FLASH_CLEAR__')) {
47 2
            $this->clearFlashes();
48 2
            $this->setSessionKey('__FLASH_CLEAR__', microtime(TRUE));
49
        }
50 2
        $this->user = $this->hasSessionKey(AuthHelper::USER_ID_TOKEN) ? unserialize($this->getSessionKey(AuthHelper::USER_ID_TOKEN)) : null;
51 2
        $this->admin = $this->hasSessionKey(AuthHelper::ADMIN_ID_TOKEN) ? unserialize($this->getSessionKey(AuthHelper::ADMIN_ID_TOKEN)) : null;
52 2
        if (null === $this->admin) {
53 2
            $this->checkAdmin();
54
        }
55 2
        $this->setLoaded(true);
56
    }
57
58
    /**
59
     * @return array|null
60
     */
61 4
    public function getAdmins()
62
    {
63 4
        return Cache::getInstance()->getDataFromFile(CONFIG_DIR . DIRECTORY_SEPARATOR . 'admins.json', Cache::JSONGZ, true);
64
    }
65
66
    /**
67
     * @param string $user
68
     * @param string $pass
69
     * @param boolean $force
70
     *
71
     * @return bool
72
     */
73 5
    public function checkAdmin($user = NULL, $pass = NULL, $force = false)
74
    {
75 5
        Logger::log('Checking admin session');
76 5
        if ((!$this->authorized && !$this->checked) || $force) {
77 4
            $admins = $this->getAdmins();
78 4
            $token = null;
79 4
            if (null !== $admins) {
80 2
                if(empty($user)) {
81
                    // First try, traditional basic auth
82 2
                    Inspector::stats('[Auth] Checking Basic Auth');
83 2
                    list($user, $token) = AuthHelper::checkBasicAuth($user, $pass, $admins);
84
                }
85 2
                if(empty($user)) {
86
                    // Second try, cookie auth
87 1
                    Inspector::stats('[Auth] Checking Basic Auth PSFS');
88 1
                    list($user, $token) = AuthHelper::checkComplexAuth($admins);
89
                }
90 2
                if (!empty($user) && !empty($admins[$user])) {
91 1
                    $auth = $admins[$user]['hash'];
92 1
                    $this->authorized = ($auth === $token);
93 1
                    if ($this->authorized) {
94 1
                        $this->updateAdmin($user, $admins[$user]['profile']);
95 1
                        $encrypted = AuthHelper::encrypt("$user:$pass", AuthHelper::SESSION_TOKEN);
96 1
                        ResponseHelper::setCookieHeaders([
97 1
                            [
98 1
                                'name' => AuthHelper::generateProfileHash(),
99 1
                                'value' => $encrypted,
100 1
                                'http' => true,
101 1
                                'domain' => '',
102 1
                            ]
103 1
                        ]);
104 1
                        $this->setSessionKey(AuthHelper::SESSION_TOKEN, $encrypted);
105
                    }
106
                } else {
107 2
                    $this->admin = null;
108 2
                    $this->setSessionKey(AuthHelper::SESSION_TOKEN, null);
109
                }
110 2
                $this->checked = true;
111
            }
112
        }
113
114 5
        return $this->authorized || self::isTest();
115
    }
116
117
    /**
118
     * Método que calcula si se está logado o para acceder a administración
119
     * @return bool
120
     */
121 4
    public function canAccessRestrictedAdmin()
122
    {
123 4
        return (null !== $this->admin && !preg_match('/^\/admin\/login/i', Request::requestUri())) || self::isTest();
0 ignored issues
show
Bug introduced by
It seems like PSFS\base\Request::requestUri() can also be of type null; however, parameter $subject of preg_match() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

123
        return (null !== $this->admin && !preg_match('/^\/admin\/login/i', /** @scrutinizer ignore-type */ Request::requestUri())) || self::isTest();
Loading history...
124
    }
125
126
    /**
127
     * Servicio que devuelve una pantalla de error porque se necesita estar authenticado
128
     *
129
     * @param string|null $route
130
     *
131
     * @return string|null
132
     * @throws exception\GeneratorException
133
     */
134
    public function notAuthorized($route)
135
    {
136
        return Template::getInstance()->render('notauthorized.html.twig', array(
137
            'route' => $route,
138
        ));
139
    }
140
141
    /**
142
     * @return bool
143
     */
144 1
    public function isSuperAdmin()
145
    {
146 1
        $users = $this->getAdmins();
147 1
        $logged = $this->getAdmin();
148 1
        if (is_array($logged)
149 1
            && array_key_exists('alias', $logged)
150 1
            && array_key_exists($logged['alias'], $users)) {
151 1
            $security = $users[$logged['alias']]['profile'];
152 1
            return AuthHelper::ADMIN_ID_TOKEN === $security;
153
        }
154
155
        return FALSE;
156
    }
157
158
}
159