Acl::checkUserAccess()   F
last analyzed

Complexity

Conditions 144
Paths 148

Size

Total Lines 189
Code Lines 175

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 144
eloc 175
nc 148
nop 2
dl 0
loc 189
rs 3.0133
c 0
b 0
f 0

How to fix   Long Method    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
/**
4
 * sysPass
5
 *
6
 * @author    nuxsmin
7
 * @link      https://syspass.org
8
 * @copyright 2012-2019, Rubén Domínguez nuxsmin@$syspass.org
9
 *
10
 * This file is part of sysPass.
11
 *
12
 * sysPass is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation, either version 3 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * sysPass is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 *  along with sysPass.  If not, see <http://www.gnu.org/licenses/>.
24
 */
25
26
namespace SP\Core\Acl;
27
28
use SP\Core\Context\ContextInterface;
29
use SP\Core\Context\SessionContext;
30
use SP\Core\Events\Event;
31
use SP\Core\Events\EventDispatcher;
32
use SP\Core\Events\EventMessage;
33
34
defined('APP_ROOT') || die();
35
36
/**
37
 * Esta clase es la encargada de calcular las access lists de acceso a usuarios.
38
 */
39
final class Acl implements ActionsInterface
40
{
41
    /**
42
     * @var Actions
43
     */
44
    protected static $action;
45
    /**
46
     * @var SessionContext
47
     */
48
    private $context;
49
    /**
50
     * @var EventDispatcher
51
     */
52
    private $eventDispatcher;
53
54
    /**
55
     * Acl constructor.
56
     *
57
     * @param ContextInterface $context
58
     * @param EventDispatcher  $eventDispatcher
59
     * @param Actions|null     $action
60
     */
61
    public function __construct(ContextInterface $context, EventDispatcher $eventDispatcher, Actions $action = null)
62
    {
63
        $this->context = $context;
0 ignored issues
show
Documentation Bug introduced by
$context is of type SP\Core\Context\ContextInterface, but the property $context was declared to be of type SP\Core\Context\SessionContext. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
64
        $this->eventDispatcher = $eventDispatcher;
65
66
        self::$action = $action;
67
    }
68
69
    /**
70
     * Returns action route
71
     *
72
     * @param $actionId
73
     *
74
     * @return string
75
     */
76
    public static function getActionRoute($actionId)
77
    {
78
        try {
79
            return self::$action !== null ? self::$action->getActionById($actionId)->getRoute() : '';
80
        } catch (ActionNotFoundException $e) {
81
            processException($e);
82
        }
83
84
        return '';
85
    }
86
87
    /**
88
     * Obtener el nombre de la acción indicada
89
     *
90
     * @param int  $actionId El id de la acción
91
     * @param bool $translate
92
     *
93
     * @return string
94
     * @internal param bool $shortName Si se devuelve el nombre corto de la acción
95
     */
96
    public static function getActionInfo($actionId, $translate = true)
97
    {
98
        try {
99
            $text = self::$action->getActionById($actionId)->getText();
100
            return $translate ? __($text) : $text;
101
        } catch (ActionNotFoundException $e) {
102
            processException($e);
103
        }
104
105
        return '';
106
    }
107
108
    /**
109
     * Comprobar los permisos de acceso del usuario a los módulos de la aplicación.
110
     *
111
     * @param int $action con el Id de la acción
112
     * @param int $userId opcional, con el Id del usuario
113
     *
114
     * @return bool
115
     */
116
    public function checkUserAccess($action, $userId = 0)
117
    {
118
        if (!($userProfile = $this->context->getUserProfile())) {
119
            return false;
120
        }
121
122
        $userData = $this->context->getUserData();
123
124
        if ($userData->getIsAdminApp()) {
125
            return true;
126
        }
127
128
        switch ($action) {
129
            case self::ACCOUNT_VIEW:
130
                return ($userData->getIsAdminAcc() || $userProfile->isAccView() || $userProfile->isAccEdit());
131
            case self::ACCOUNT_VIEW_PASS:
132
                return ($userData->getIsAdminAcc() || $userProfile->isAccViewPass());
133
            case self::ACCOUNT_HISTORY_VIEW:
134
                return ($userData->getIsAdminAcc() || $userProfile->isAccViewHistory());
135
            case self::ACCOUNT_EDIT:
136
                return ($userData->getIsAdminAcc() || $userProfile->isAccEdit());
137
            case self::ACCOUNT_EDIT_PASS:
138
                return ($userData->getIsAdminAcc() || $userProfile->isAccEditPass());
139
            case self::ACCOUNT_CREATE:
140
                return ($userData->getIsAdminAcc() || $userProfile->isAccAdd());
141
            case self::ACCOUNT_COPY:
142
                return ($userData->getIsAdminAcc() || ($userProfile->isAccAdd() && $userProfile->isAccView()));
143
            case self::ACCOUNT_DELETE:
144
                return ($userData->getIsAdminAcc() || $userProfile->isAccDelete());
145
            case self::ACCOUNT_FILE:
146
                return ($userData->getIsAdminAcc() || $userProfile->isAccFiles());
147
            case self::ITEMS_MANAGE:
148
                return ($userData->getIsAdminAcc()
149
                    || $userProfile->isMgmCategories()
150
                    || $userProfile->isMgmCustomers()
151
                    || $userProfile->isMgmAccounts()
152
                    || $userProfile->isMgmFiles()
153
                    || $userProfile->isMgmTags()
154
                    || $userProfile->isMgmCustomFields()
155
                    || $userProfile->isMgmPublicLinks());
156
            case self::CONFIG:
157
                return ($userProfile->isConfigGeneral()
158
                    || $userProfile->isConfigEncryption()
159
                    || $userProfile->isConfigBackup()
160
                    || $userProfile->isConfigImport());
161
            case self::CONFIG_GENERAL:
162
            case self::CONFIG_ACCOUNT:
163
            case self::CONFIG_WIKI:
164
            case self::CONFIG_LDAP:
165
            case self::CONFIG_MAIL:
166
            case self::PLUGIN:
167
            case self::PLUGIN_SEARCH:
168
            case self::PLUGIN_DISABLE:
169
            case self::PLUGIN_ENABLE:
170
            case self::PLUGIN_RESET:
171
            case self::PLUGIN_VIEW:
172
                return $userProfile->isConfigGeneral();
173
            case self::CONFIG_IMPORT:
174
                return $userProfile->isConfigImport();
175
            case self::CATEGORY:
176
            case self::CATEGORY_SEARCH:
177
            case self::CATEGORY_VIEW:
178
            case self::CATEGORY_CREATE:
179
            case self::CATEGORY_EDIT:
180
            case self::CATEGORY_DELETE:
181
                return $userProfile->isMgmCategories();
182
            case self::CLIENT:
183
            case self::CLIENT_SEARCH:
184
            case self::CLIENT_VIEW:
185
            case self::CLIENT_CREATE:
186
            case self::CLIENT_EDIT:
187
            case self::CLIENT_DELETE:
188
                return $userProfile->isMgmCustomers();
189
            case self::CUSTOMFIELD:
190
            case self::CUSTOMFIELD_SEARCH:
191
            case self::CUSTOMFIELD_VIEW:
192
            case self::CUSTOMFIELD_CREATE:
193
            case self::CUSTOMFIELD_EDIT:
194
            case self::CUSTOMFIELD_DELETE:
195
                return $userProfile->isMgmCustomFields();
196
            case self::PUBLICLINK:
197
            case self::PUBLICLINK_SEARCH:
198
            case self::PUBLICLINK_VIEW:
199
            case self::PUBLICLINK_EDIT:
200
            case self::PUBLICLINK_DELETE:
201
                return $userProfile->isMgmPublicLinks();
202
            case self::PUBLICLINK_CREATE:
203
            case self::PUBLICLINK_REFRESH:
204
                return ($userProfile->isMgmPublicLinks() || $userProfile->isAccPublicLinks());
205
            case self::ACCOUNTMGR:
206
            case self::ACCOUNTMGR_SEARCH:
207
            case self::ACCOUNTMGR_HISTORY:
208
            case self::ACCOUNTMGR_HISTORY_SEARCH:
209
                return ($userData->getIsAdminAcc() || $userProfile->isMgmAccounts());
210
            case self::FILE:
211
            case self::FILE_SEARCH:
212
            case self::FILE_DELETE:
213
            case self::FILE_VIEW:
214
            case self::FILE_DOWNLOAD:
215
                return $userProfile->isMgmFiles();
216
            case self::TAG:
217
            case self::TAG_SEARCH:
218
            case self::TAG_VIEW:
219
            case self::TAG_CREATE:
220
            case self::TAG_EDIT:
221
            case self::TAG_DELETE:
222
                return $userProfile->isMgmTags();
223
            case self::CONFIG_CRYPT:
224
                return $userProfile->isConfigEncryption();
225
            case self::CONFIG_BACKUP:
226
                return $userProfile->isConfigBackup();
227
            case self::ACCESS_MANAGE:
228
                return ($userProfile->isMgmUsers()
229
                    || $userProfile->isMgmGroups()
230
                    || $userProfile->isMgmProfiles()
231
                    || $userProfile->isMgmApiTokens());
232
            case self::SECURITY_MANAGE:
233
                return $userProfile->isEvl()
234
                    || $userProfile->isMgmUsers();
235
            case self::USER:
236
            case self::USER_SEARCH:
237
            case self::USER_VIEW:
238
            case self::USER_CREATE:
239
            case self::USER_EDIT:
240
            case self::USER_DELETE:
241
            case self::TRACK:
242
            case self::TRACK_SEARCH:
243
            case self::TRACK_CLEAR:
244
            case self::TRACK_UNLOCK:
245
                return $userProfile->isMgmUsers();
246
            case self::USER_EDIT_PASS:
247
                // Comprobar si el usuario es distinto al de la sesión
248
                return ($userId === $userData->getId() || $userProfile->isMgmUsers());
249
            case self::GROUP:
250
            case self::GROUP_SEARCH:
251
            case self::GROUP_VIEW:
252
            case self::GROUP_CREATE:
253
            case self::GROUP_EDIT:
254
            case self::GROUP_DELETE:
255
                return $userProfile->isMgmGroups();
256
            case self::PROFILE:
257
            case self::PROFILE_SEARCH:
258
            case self::PROFILE_VIEW:
259
            case self::PROFILE_CREATE:
260
            case self::PROFILE_EDIT:
261
            case self::PROFILE_DELETE:
262
                return $userProfile->isMgmProfiles();
263
            case self::AUTHTOKEN:
264
            case self::AUTHTOKEN_SEARCH:
265
            case self::AUTHTOKEN_VIEW:
266
            case self::AUTHTOKEN_CREATE:
267
            case self::AUTHTOKEN_EDIT:
268
            case self::AUTHTOKEN_DELETE:
269
                return $userProfile->isMgmApiTokens();
270
            case self::ITEMPRESET:
271
            case self::ITEMPRESET_SEARCH:
272
            case self::ITEMPRESET_VIEW:
273
            case self::ITEMPRESET_CREATE:
274
            case self::ITEMPRESET_EDIT:
275
            case self::ITEMPRESET_DELETE:
276
                return $userProfile->isMgmItemsPreset();
277
            case self::EVENTLOG:
278
            case self::EVENTLOG_SEARCH:
279
            case self::EVENTLOG_CLEAR:
280
                return $userProfile->isEvl();
281
            case self::CUSTOMFIELD_VIEW_PASS:
282
                return ($userData->getIsAdminApp() || $userProfile->isAccViewPass());
283
            case self::ACCOUNT_REQUEST:
284
            case self::NOTIFICATION:
285
            case self::NOTIFICATION_VIEW:
286
            case self::NOTIFICATION_SEARCH:
287
            case self::NOTIFICATION_CHECK:
288
                return true;
289
        }
290
291
        try {
292
            $actionName = self::$action->getActionById($action)->getName();
293
        } catch (ActionNotFoundException $e) {
294
            $actionName = __u('N/A');
295
        }
296
297
        $this->eventDispatcher->notifyEvent('acl.deny',
298
            new Event($this, EventMessage::factory()
299
                ->addDescription(__u('Access denied'))
300
                ->addDetail(__u('Action'), $actionName)
301
                ->addDetail(__u('User'), $userData->getLogin()))
302
        );
303
304
        return false;
305
    }
306
}