Failed Conditions
Push — master ( f46d35...cafc71 )
by Maximo
03:48
created

Manager::setApp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gewaer\Acl;
6
7
use Phalcon\Db;
8
use Phalcon\Db\AdapterInterface as DbAdapter;
9
use Phalcon\Acl\Exception;
10
use Phalcon\Acl\Resource;
11
use Phalcon\Acl;
12
use Phalcon\Acl\Role;
13
use Phalcon\Acl\RoleInterface;
14
use Gewaer\Models\Companies;
15
use Gewaer\Models\Apps;
16
use Gewaer\Models\Roles as RolesDB;
17
use Gewaer\Models\AccessList as AccessListDB;
18
use Gewaer\Models\Resources as ResourcesDB;
19
use Phalcon\Acl\Adapter;
20
use BadMethodCallException;
21
use Gewaer\Exception\ModelException;
22
use Gewaer\Models\ResourcesAccesses;
23
24
/**
25
 * Class Manager
26
 *
27
 * Manages Geweaer Multi tenant ACL lists in database
28
 *
29
 * @package Gewaer\Acl
30
 *
31
 * @property Users $userData
32
 * @property Request $request
33
 */
34
class Manager extends Adapter
35
{
36
    /**
37
     * @var DbAdapter
38
     */
39
    protected $connection;
40
41
    /**
42
     * Roles table
43
     * @var string
44
     */
45
    protected $roles;
46
47
    /**
48
     * Resources table
49
     * @var string
50
     */
51
    protected $resources;
52
53
    /**
54
     * Resources Accesses table
55
     * @var string
56
     */
57
    protected $resourcesAccesses;
58
59
    /**
60
     * Access List table
61
     * @var string
62
     */
63
    protected $accessList;
64
65
    /**
66
     * Roles Inherits table
67
     * @var string
68
     */
69
    protected $rolesInherits;
70
71
    /**
72
     * Default action for no arguments is allow
73
     * @var int
74
     */
75
    protected $noArgumentsDefaultAction = Acl::ALLOW;
76
77
    /**
78
     * Company Object
79
     *
80
     * @var Companies
81
     */
82
    protected $company;
83
84
    /**
85
     * App Objc
86
     *
87
     * @var Apps
88
     */
89
    protected $app;
90
91
    /**
92
     * Class constructor.
93
     *
94
     * @param  array $options Adapter config
95
     * @throws Exception
96
     */
97 15
    public function __construct(array $options)
98
    {
99 15
        if (!isset($options['db']) || !$options['db'] instanceof DbAdapter) {
100
            throw new Exception(
101
                'Parameter "db" is required and it must be an instance of Phalcon\Acl\AdapterInterface'
102
            );
103
        }
104
105 15
        $this->connection = $options['db'];
106
107 15
        foreach (['roles', 'resources', 'resourcesAccesses', 'accessList', 'rolesInherits'] as $table) {
108 15
            if (!isset($options[$table]) || empty($options[$table]) || !is_string($options[$table])) {
109
                throw new Exception("Parameter '{$table}' is required and it must be a non empty string");
110
            }
111
112 15
            $this->{$table} = $this->connection->escapeIdentifier($options[$table]);
113
        }
114 15
    }
115
116
    /**
117
     * Set current user Company
118
     *
119
     * @param Companies $company
120
     * @return void
121
     */
122 2
    public function setCompany(Companies $company): void
123
    {
124 2
        $this->company = $company;
125 2
    }
126
127
    /**
128
     * Set current user app
129
     *
130
     * @param Apps $app
131
     * @return void
132
     */
133 8
    public function setApp(Apps $app): void
134
    {
135 8
        $this->app = $app;
136 8
    }
137
138
    /**
139
     * Get the current App
140
     *
141
     * @return void
142
     */
143 11
    public function getApp(): Apps
144
    {
145 11
        if (!is_object($this->app)) {
146 5
            $this->app = new Apps();
147 5
            $this->app->id = 0;
148 5
            $this->app->name = 'Canvas';
149
        }
150
151 11
        return $this->app;
152
    }
153
154
    /**
155
     * Get the current App
156
     *
157
     * @return void
158
     */
159 10
    public function getCompany() : Companies
160
    {
161 10
        if (!is_object($this->company)) {
162 8
            $this->company = new Companies();
163 8
            $this->company->id = 0;
164 8
            $this->company->name = 'Canvas';
165
        }
166
167 10
        return $this->company;
168
    }
169
170
    /**
171
     * {@inheritdoc}
172
     *
173
     * Example:
174
     * <code>
175
     * $acl->addRole(new Phalcon\Acl\Role('administrator'), 'consultor');
176
     * $acl->addRole('administrator', 'consultor');
177
     * </code>
178
     *
179
     * @param  \Phalcon\Acl\Role|string $role
180
     * @param  int   $scope
181
     * @param  string                   $accessInherits
182
     * @return boolean
183
     * @throws \Phalcon\Acl\Exception
184
     */
185 3
    public function addRole($role, $scope = 0, $accessInherits = null): bool
186
    {
187 3
        if (is_string($role)) {
188 1
            $role = $this->setAppByRole($role);
189
190 1
            $role = new Role($role, ucwords($role) . ' Role');
191
        }
192 3
        if (!$role instanceof RoleInterface) {
1 ignored issue
show
introduced by
$role is always a sub-type of Phalcon\Acl\RoleInterface.
Loading history...
193
            throw new Exception('Role must be either an string or implement RoleInterface');
194
        }
195
196 3
        $exists = RolesDB::count([
197 3
            'conditions' => 'name = ?0 AND companies_id = ?1 AND apps_id = ?2',
198 3
            'bind' => [$role->getName(), $this->getCompany()->getId(), $this->getApp()->getId()]
199
        ]);
200
201 3
        if (!$exists) {
202 1
            $rolesDB = new RolesDB();
203 1
            $rolesDB->name = $role->getName();
204 1
            $rolesDB->description = $role->getDescription();
205 1
            $rolesDB->companies_id = $this->getCompany()->getId();
206 1
            $rolesDB->apps_id = $this->getApp()->getId();
207 1
            $rolesDB->scope = $scope;
208 1
            if (!$rolesDB->save()) {
209
                throw new ModelException((string) current($rolesDB->getMessages()));
210
            }
211
212 1
            $accessListDB = new AccessListDB();
213 1
            $accessListDB->roles_name = $role->getName();
214 1
            $accessListDB->roles_id = $rolesDB->getId();
215 1
            $accessListDB->resources_name = '*';
216 1
            $accessListDB->access_name = '*';
217 1
            $accessListDB->allowed = $this->_defaultAccess;
218 1
            $accessListDB->apps_id = $this->getApp()->getId();
219
220 1
            if (!$accessListDB->save()) {
221
                throw new ModelException((string)current($rolesDB->getMessages()));
222
            }
223
        }
224 3
        if ($accessInherits) {
225
            return $this->addInherit($role->getName(), $accessInherits);
226
        }
227 3
        return true;
228
    }
229
230
    /**
231
     * {@inheritdoc}
232
     *
233
     * @param  string $roleName
234
     * @param  string $roleToInherit
235
     * @throws \Phalcon\Acl\Exception
236
     */
237
    public function addInherit($roleName, $roleToInherit): bool
238
    {
239
        $sql = "SELECT COUNT(*) FROM {$this->roles} WHERE name = ?";
240
        $exists = $this->connection->fetchOne($sql, null, [$roleName]);
0 ignored issues
show
Bug introduced by
array($roleName) of type array<integer,string> is incompatible with the type integer expected by parameter $placeholders of Phalcon\Db\AdapterInterface::fetchOne(). ( Ignorable by Annotation )

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

240
        $exists = $this->connection->fetchOne($sql, null, /** @scrutinizer ignore-type */ [$roleName]);
Loading history...
241
        if (!$exists[0]) {
242
            throw new Exception("Role '{$roleName}' does not exist in the role list");
243
        }
244
        $exists = $this->connection->fetchOne(
245
            "SELECT COUNT(*) FROM {$this->rolesInherits} WHERE roles_name = ? AND roles_inherit = ?",
246
            null,
247
            [$roleName, $roleToInherit]
0 ignored issues
show
Bug introduced by
array($roleName, $roleToInherit) of type array<integer,string> is incompatible with the type integer expected by parameter $placeholders of Phalcon\Db\AdapterInterface::fetchOne(). ( Ignorable by Annotation )

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

247
            /** @scrutinizer ignore-type */ [$roleName, $roleToInherit]
Loading history...
248
        );
249
        if (!$exists[0]) {
250
            $this->connection->execute(
251
                "INSERT INTO {$this->rolesInherits} VALUES (?, ?)",
252
                [$roleName, $roleToInherit]
253
            );
254
        }
255
    }
256
257
    /**
258
     * {@inheritdoc}
259
     *
260
     * @param  string  $roleName
261
     * @return boolean
262
     */
263 4
    public function isRole($roleName): bool
264
    {
265 4
        $exists = RolesDB::count([
266 4
            'conditions' => 'name = ?0 AND apps_id = ?1 AND companies_id in (?2, ?3)',
267 4
            'bind' => [$roleName, $this->getApp()->getId(), $this->getCompany()->getId(), 0]
268
        ]);
269
270 4
        return (bool)$exists;
271
    }
272
273
    /**
274
     * {@inheritdoc}
275
     *
276
     * @param  string  $resourceName
277
     * @return boolean
278
     */
279 1
    public function isResource($resourceName): bool
280
    {
281 1
        $exists = ResourcesDB::count([
282 1
            'conditions' => 'name = ?0 AND apps_id in (?1, ?2)',
283 1
            'bind' => [$resourceName, $this->getApp()->getId(), 0]
284
        ]);
285
286 1
        return (bool) $exists;
287
    }
288
289
    /**
290
     * Get a resource by it name
291
     *
292
     * @param  string  $resourceName
293
     * @return ResourcesDB
294
     */
295 5
    protected function getResource(string $resourceName) : ResourcesDB
296
    {
297 5
        $resource = ResourcesDB::findFirst([
298 5
            'conditions' => 'name = ?0 AND apps_id in (?1, ?2)',
299 5
            'bind' => [$resourceName, $this->getApp()->getId(), 0]
300
        ]);
301
302 5
        if (!is_object($resource)) {
303
            throw new ModelException(_('Resource ' . $resourceName . ' not found on this app ' . $this->getApp()->getId()));
304
        }
305
306 5
        return $resource;
307
    }
308
309
    /**
310
     * Get a role by it name
311
     *
312
     * @param  string  $resourceName
313
     * @return RolesDB
314
     */
315 8
    protected function getRole(string $role) : RolesDB
316
    {
317 8
        $role = RolesDB::findFirst([
318 8
            'conditions' => 'name = ?0 AND apps_id = ?1 AND companies_id in (?2, ?3)',
319 8
            'bind' => [$role, $this->getApp()->getId(), $this->getCompany()->getId(), 0]
320
        ]);
321
322 8
        if (!is_object($role)) {
323
            throw new ModelException(_('Roles ' . $role . ' not found on this app ' . $this->getApp()->getId() . ' AND Company' . $this->getCompany()->getId()));
324
        }
325
326 8
        return $role;
327
    }
328
329
    /**
330
     * Given a resource with a dot CRM.Leads , it will set the app
331
     *
332
     * @param string $resource
333
     * @return void
334
     */
335 9
    protected function setAppByResource(string $resource): string
336
    {
337
        //echeck if we have a dot , taht means we are sending the specific app to use
338 9
        if (strpos($resource, '.') !== false) {
339 5
            $appResource = explode('.', $resource);
340 5
            $resource = $appResource[1];
341 5
            $appName = $appResource[0];
342
343
            //look for the app and set it
344 5
            if ($app = Apps::getACLApp($appName)) {
345 5
                $this->setApp($app);
346
            }
347
        }
348
349 9
        return $resource;
350
    }
351
352
    /**
353
     * Given a resource with a dot CRM.Leads , it will set the app
354
     *
355
     * @param string $resource
356
     * @return void
357
     */
358 5
    protected function setAppByRole(string $role) : string
359
    {
360
        //echeck if we have a dot , taht means we are sending the specific app to use
361 5
        if (strpos($role, '.') !== false) {
362 1
            $appRole = explode('.', $role);
363 1
            $role = $appRole[1];
364 1
            $appName = $appRole[0];
365
366
            //look for the app and set it
367 1
            if ($app = Apps::getACLApp($appName)) {
368 1
                $this->setApp($app);
369
            }
370
        }
371
372 5
        return $role;
373
    }
374
375
    /**
376
     * {@inheritdoc}
377
     * Example:
378
     * <code>
379
     * //Add a resource to the the list allowing access to an action
380
     * $acl->addResource(new Phalcon\Acl\Resource('customers'), 'search');
381
     * $acl->addResource('customers', 'search');
382
     * //Add a resource  with an access list
383
     * $acl->addResource(new Phalcon\Acl\Resource('customers'), ['create', 'search']);
384
     * $acl->addResource('customers', ['create', 'search']);
385
     * $acl->addResource('App.customers', ['create', 'search']);
386
     * </code>
387
     *
388
     * @param  \Phalcon\Acl\Resource|string $resource
389
     * @param  array|string                 $accessList
390
     * @return boolean
391
     */
392 1
    public function addResource($resource, $accessList = null): bool
393
    {
394 1
        if (!is_object($resource)) {
395
            //echeck if we have a dot , taht means we are sending the specific app to use
396 1
            $resource = $this->setAppByResource($resource);
397
398 1
            $resource = new Resource($resource);
399
        }
400
401 1
        if (!$this->isResource($resource->getName())) {
402
            $resourceDB = new ResourcesDB();
403
            $resourceDB->name = $resource->getName();
404
            $resourceDB->description = $resource->getDescription();
405
            $resourceDB->apps_id = $this->getApp()->getId();
406
407
            if (!$resourceDB->save()) {
408
                throw new ModelException((string)current($resourceDB->getMessages()));
409
            }
410
        }
411
412 1
        if ($accessList) {
413 1
            return $this->addResourceAccess($resource->getName(), $accessList);
414
        }
415
416
        return true;
417
    }
418
419
    /**
420
     * {@inheritdoc}
421
     *
422
     * @param  string       $resourceName
423
     * @param  array|string $accessList
424
     * @return boolean
425
     * @throws \Phalcon\Acl\Exception
426
     */
427 1
    public function addResourceAccess($resourceName, $accessList): bool
428
    {
429 1
        if (!$this->isResource($resourceName)) {
430
            throw new Exception("Resource '{$resourceName}' does not exist in ACL");
431
        }
432
433 1
        $resource = $this->getResource($resourceName);
434
435 1
        if (!is_array($accessList)) {
436
            $accessList = [$accessList];
437
        }
438
439 1
        foreach ($accessList as $accessName) {
440 1
            $exists = ResourcesAccesses::count([
441 1
                'conditions' => 'resources_id = ?0 AND access_name = ?1 AND apps_id = ?2',
442 1
                'bind' => [$resource->getId(), $accessName, $this->getApp()->getId()]
443
            ]);
444
445 1
            if (!$exists) {
446
                $resourceAccesses = new ResourcesAccesses();
447
                $resourceAccesses->beforeCreate(); //wtf?
448
                $resourceAccesses->resources_name = $resourceName;
449
                $resourceAccesses->access_name = $accessName;
450
                $resourceAccesses->apps_id = $this->getApp()->getId();
451
                $resourceAccesses->resources_id = $resource->getId();
452
453
                if (!$resourceAccesses->save()) {
454 1
                    throw new ModelException((string)current($resourceAccesses->getMessages()));
455
                }
456
            }
457
        }
458 1
        return true;
459
    }
460
461
    /**
462
     * {@inheritdoc}
463
     *
464
     * @return \Phalcon\Acl\Resource[]
465
     */
466
    public function getResources(): \Phalcon\Acl\ResourceInterface
467
    {
468
        $resources = [];
469
470
        foreach (ResourcesDB::find() as $row) {
471
            $resources[] = new Resource($row->name, $row->description);
472
        }
473
        return $resources;
474
    }
475
476
    /**
477
     * {@inheritdoc}
478
     *
479
     * @return RoleInterface[]
480
     */
481
    public function getRoles(): \Phalcon\Acl\RoleInterface
482
    {
483
        $roles = [];
484
485
        foreach (RolesDB::find() as $row) {
486
            $roles[] = new Role($row->name, $row->description);
487
        }
488
        return $roles;
489
    }
490
491
    /**
492
     * {@inheritdoc}
493
     *
494
     * @param string       $resourceName
495
     * @param array|string $accessList
496
     */
497
    public function dropResourceAccess($resourceName, $accessList)
498
    {
499
        throw new BadMethodCallException('Not implemented yet.');
500
    }
501
502
    /**
503
     * {@inheritdoc}
504
     * You can use '*' as wildcard
505
     * Example:
506
     * <code>
507
     * //Allow access to guests to search on customers
508
     * $acl->allow('guests', 'customers', 'search');
509
     * //Allow access to guests to search or create on customers
510
     * $acl->allow('guests', 'customers', ['search', 'create']);
511
     * //Allow access to any role to browse on products
512
     * $acl->allow('*', 'products', 'browse');
513
     * //Allow access to any role to browse on any resource
514
     * $acl->allow('*', '*', 'browse');
515
     * </code>
516
     *
517
     * @param string       $roleName
518
     * @param string       $resourceName
519
     * @param array|string $access
520
     * @param mixed $func
521
     */
522 1
    public function allow($roleName, $resourceName, $access, $func = null)
523
    {
524 1
        return $this->allowOrDeny($roleName, $resourceName, $access, Acl::ALLOW);
525
    }
526
527
    /**
528
     * {@inheritdoc}
529
     * You can use '*' as wildcard
530
     * Example:
531
     * <code>
532
     * //Deny access to guests to search on customers
533
     * $acl->deny('guests', 'customers', 'search');
534
     * //Deny access to guests to search or create on customers
535
     * $acl->deny('guests', 'customers', ['search', 'create']);
536
     * //Deny access to any role to browse on products
537
     * $acl->deny('*', 'products', 'browse');
538
     * //Deny access to any role to browse on any resource
539
     * $acl->deny('*', '*', 'browse');
540
     * </code>
541
     *
542
     * @param  string       $roleName
543
     * @param  string       $resourceName
544
     * @param  array|string $access
545
     * @param  mixed $func
546
     * @return boolean
547
     */
548 3
    public function deny($roleName, $resourceName, $access, $func = null)
549
    {
550 3
        return $this->allowOrDeny($roleName, $resourceName, $access, Acl::DENY);
551
    }
552
553
    /**
554
     * {@inheritdoc}
555
     * Example:
556
     * <code>
557
     * //Does Andres have access to the customers resource to create?
558
     * $acl->isAllowed('Andres', 'Products', 'create');
559
     * //Do guests have access to any resource to edit?
560
     * $acl->isAllowed('guests', '*', 'edit');
561
     * </code>
562
     *
563
     * @param string $role
564
     * @param string $resource
565
     * @param string $access
566
     * @param array  $parameters
567
     * @return bool
568
     */
569 4
    public function isAllowed($role, $resource, $access, array $parameters = null): bool
570
    {
571 4
        $role = $this->setAppByRole($role);
572
        //resoure always overwrites the role app?
573 4
        $resource = $this->setAppByResource($resource);
574 4
        $roleObj = $this->getRole(($role));
575
576 4
        $sql = implode(' ', [
577 4
            'SELECT ' . $this->connection->escapeIdentifier('allowed') . " FROM {$this->accessList} AS a",
578
            // role_name in:
579 4
            'WHERE roles_id IN (',
580
                // given 'role'-parameter
581 4
            'SELECT roles_id ',
582
                // inherited role_names
583 4
            "UNION SELECT roles_inherit FROM {$this->rolesInherits} WHERE roles_id = ?",
584
                // or 'any'
585 4
            "UNION SELECT '*'",
586 4
            ')',
587
            // resources_name should be given one or 'any'
588 4
            "AND resources_name IN (?, '*')",
589
            // access_name should be given one or 'any'
590
            //"AND access_name IN (?, '*')", you need to specify * , we are forcing to check always for permisions
591 4
            'AND access_name IN (?)',
592 4
            'AND apps_id = ? ',
593 4
            'AND roles_id = ? ',
594
            // order be the sum of bools for 'literals' before 'any'
595 4
            'ORDER BY ' . $this->connection->escapeIdentifier('allowed') . ' DESC',
596
            // get only one...
597 4
            'LIMIT 1'
598
        ]);
599
600
        // fetch one entry...
601 4
        $allowed = $this->connection->fetchOne($sql, Db::FETCH_NUM, [$roleObj->getId(), $resource, $access, $this->getApp()->getId(), $roleObj->getId()]);
1 ignored issue
show
Bug introduced by
array($roleObj->getId(),...d(), $roleObj->getId()) of type array<integer,integer|string> is incompatible with the type integer expected by parameter $placeholders of Phalcon\Db\AdapterInterface::fetchOne(). ( Ignorable by Annotation )

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

601
        $allowed = $this->connection->fetchOne($sql, Db::FETCH_NUM, /** @scrutinizer ignore-type */ [$roleObj->getId(), $resource, $access, $this->getApp()->getId(), $roleObj->getId()]);
Loading history...
602
603 4
        if (is_array($allowed)) {
1 ignored issue
show
introduced by
The condition is_array($allowed) is always true.
Loading history...
604 4
            return (bool) $allowed[0];
605
        }
606
607
        /**
608
         * Return the default access action
609
         */
610
        return (bool) $this->_defaultAccess;
611
    }
612
613
    /**
614
     * Returns the default ACL access level for no arguments provided
615
     * in isAllowed action if there exists func for accessKey
616
     *
617
     * @return int
618
     */
619
    public function getNoArgumentsDefaultAction(): int
620
    {
621
        return $this->noArgumentsDefaultAction;
622
    }
623
624
    /**
625
     * Sets the default access level for no arguments provided
626
     * in isAllowed action if there exists func for accessKey
627
     *
628
     * @param int $defaultAccess Phalcon\Acl::ALLOW or Phalcon\Acl::DENY
629
     */
630
    public function setNoArgumentsDefaultAction($defaultAccess)
631
    {
632
        $this->noArgumentsDefaultAction = intval($defaultAccess);
633
    }
634
635
    /**
636
     * Inserts/Updates a permission in the access list
637
     *
638
     * @param  string  $roleName
639
     * @param  string  $resourceName
640
     * @param  string  $accessName
641
     * @param  integer $action
642
     * @return boolean
643
     * @throws \Phalcon\Acl\Exception
644
     */
645 4
    protected function insertOrUpdateAccess($roleName, $resourceName, $accessName, $action)
646
    {
647 4
        $resourceName = $this->setAppByResource($resourceName);
648
649
        /**
650
         * Check if the access is valid in the resource unless wildcard
651
         */
652 4
        if ($resourceName !== '*' && $accessName !== '*') {
653 4
            $resource = $this->getResource($resourceName);
654 4
            $exists = ResourcesAccesses::count([
655 4
                'resources_id = ?0 AND access_name = ?1 AND apps_id in (?2, ?3)',
656 4
                'bind' => [$resource->getId(), $accessName, $this->getApp()->getId(), 0]
657
            ]);
658
659 4
            if (!$exists) {
660
                throw new Exception(
661
                    "Access '{$accessName}' does not exist in resource '{$resourceName}' ({$resource->getId()}) in ACL"
662
                );
663
            }
664
        }
665
        /**
666
         * Update the access in access_list
667
         */
668 4
        $role = $this->getRole($roleName);
669 4
        $exists = AccessListDB::count([
670 4
            'conditions' => 'roles_id = ?0 and resources_name = ?1 AND access_name = ?2 AND apps_id = ?3',
671 4
            'bind' => [$role->getId(), $resourceName, $accessName, $this->getApp()->getId()]
672
        ]);
673
674 4
        if (!$exists) {
675 2
            $accessListDB = new AccessListDB();
676 2
            $accessListDB->roles_id = $role->getId();
677 2
            $accessListDB->roles_name = $roleName;
678 2
            $accessListDB->resources_name = $resourceName;
679 2
            $accessListDB->access_name = $accessName;
680 2
            $accessListDB->allowed = $action;
0 ignored issues
show
Documentation Bug introduced by
The property $allowed was declared of type boolean, but $action is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
681 2
            $accessListDB->apps_id = $this->getApp()->getId();
682
683 2
            if (!$accessListDB->save()) {
684 2
                throw new ModelException((string)current($accessListDB->getMessages()));
685
            }
686
            // $sql = "INSERT INTO {$this->accessList} (roles_name, resources_name, access_name, allowed, apps_id, created_at) VALUES (?, ?, ?, ?, ?, ?)";
687
           // $params = [$roleName, $resourceName, $accessName, $action, $this->getApp()->getId(), date('Y-m-d H:i:s')];
688
        } else {
689 2
            $sql = "UPDATE {$this->accessList} SET allowed = ? " .
690 2
                'WHERE roles_id = ? AND resources_name = ? AND access_name = ? AND apps_id = ?';
691 2
            $params = [$action, $role->getId(), $resourceName, $accessName, $this->getApp()->getId()];
692 2
            $this->connection->execute($sql, $params);
693
        }
694
695
        /**
696
         * Update the access '*' in access_list
697
         */
698 4
        $exists = AccessListDB::count([
699 4
            'conditions' => 'roles_id = ?0 and resources_name = ?1 AND access_name = ?2 AND apps_id = ?3',
700 4
            'bind' => [$role->getId(), $resourceName,  '*', $this->getApp()->getId()]
701
        ]);
702
703 4
        if (!$exists) {
704 2
            $sql = "INSERT INTO {$this->accessList} (roles_name, roles_id, resources_name, access_name, allowed, apps_id, created_at) VALUES (?, ?, ?, ?, ?, ? , ?)";
705 2
            $this->connection->execute($sql, [$roleName, $role->getId(), $resourceName, '*', $this->_defaultAccess, $this->getApp()->getId(), date('Y-m-d H:i:s')]);
706
        }
707
708 4
        return true;
709
    }
710
711
    /**
712
     * Inserts/Updates a permission in the access list
713
     *
714
     * @param  string       $roleName
715
     * @param  string       $resourceName
716
     * @param  array|string $access
717
     * @param  integer      $action
718
     * @throws \Phalcon\Acl\Exception
719
     */
720 4
    protected function allowOrDeny($roleName, $resourceName, $access, $action)
721
    {
722 4
        if (!$this->isRole($roleName)) {
723
            throw new Exception("Role '{$roleName}' does not exist in the list");
724
        }
725 4
        if (!is_array($access)) {
726 2
            $access = [$access];
727
        }
728 4
        foreach ($access as $accessName) {
729 4
            $this->insertOrUpdateAccess($roleName, $resourceName, $accessName, $action);
730
        }
731
732 4
        return true;
733
    }
734
}
735