GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( c67920...7102a7 )
by Samuel
02:36
created

Acl::getPermissionStatus()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 50
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 50
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 25
nc 7
nop 3
1
<?php declare(strict_types=1);
2
3
/**
4
 * This file is part of the Samshal\Acl library
5
 *
6
 * @license MIT
7
 * @copyright Copyright (c) 2016 Samshal http://samshal.github.com
8
 */
9
namespace Samshal\Acl;
10
11
use Samshal\Acl\Role\{
12
    DefaultRole as Role,
13
    RoleInterface
14
};
15
use Samshal\Acl\Resource\{
16
    DefaultResource as Resource,
17
    ResourceInterface
18
};
19
use Samshal\Acl\Permission\{
20
    DefaultPermission as Permission,
21
    PermissionInterface
22
};
23
use Samshal\Acl\Registry\{
24
    GlobalRegistry,
25
    Registry
26
};
27
28
29
/**
30
 * Class Acl
31
 *
32
 * @package samshal.acl
33
 * @author Samuel Adeshina <[email protected]>
34
 * @since 30/05/2016
35
 */
36
class Acl implements AclInterface
37
{
38
    /**
39
     * @var Samshal\Acl\Registry\RegistryInterface $roleRegistry
40
     */
41
    public $roleRegistry;
42
43
    /**
44
     * @var Samshal\Acl\Registry\RegistryInterface $resourceRegistry
45
     */
46
    protected $resourceRegistry;
47
48
    /**
49
     * @var Samshal\Acl\Registry\RegistryInterface $permissionRegistry
50
     */
51
    protected $permissionRegistry;
52
53
    /**
54
     * @var Samshal\Acl\Registry\RegistryInterface $globalRegistry
55
     */
56
    public $globalRegistry;
57
58
    /**
59
     *  @var string[] $sesion
60
     */
61
    protected $session = [];
62
63
    /**
64
     * @var string SYN_ALLOW
65
     */
66
    const SYN_ALLOW = "can";
67
68
    /**
69
     * @var string SYN_DENY
70
     */
71
    const SYN_DENY = "cannot";
72
73
    /**
74
     * Performs bootstrapping
75
     */
76
    public function __construct()
77
    {
78
        self::initRegistries();
79
        self::initSession();
80
    }
81
82
    /**
83
     * Initalizes the registries
84
     *
85
     * @return void
86
     */
87
    protected function initRegistries()
88
    {
89
        $this->roleRegistry = new Registry();
1 ignored issue
show
Documentation Bug introduced by
It seems like new \Samshal\Acl\Registry\Registry() of type object<Samshal\Acl\Registry\Registry> is incompatible with the declared type object<Samshal\Acl\Samsh...stry\RegistryInterface> of property $roleRegistry.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
90
        $this->resourceRegistry = new Registry();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Samshal\Acl\Registry\Registry() of type object<Samshal\Acl\Registry\Registry> is incompatible with the declared type object<Samshal\Acl\Samsh...stry\RegistryInterface> of property $resourceRegistry.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
91
        $this->permissionRegistry = new Registry();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Samshal\Acl\Registry\Registry() of type object<Samshal\Acl\Registry\Registry> is incompatible with the declared type object<Samshal\Acl\Samsh...stry\RegistryInterface> of property $permissionRegistry.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
92
        $this->globalRegistry = new GlobalRegistry();
1 ignored issue
show
Documentation Bug introduced by
It seems like new \Samshal\Acl\Registry\GlobalRegistry() of type object<Samshal\Acl\Registry\GlobalRegistry> is incompatible with the declared type object<Samshal\Acl\Samsh...stry\RegistryInterface> of property $globalRegistry.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
93
    }
94
95
    /**
96
     * Initializes the global session array and sets them to the default value
97
     *
98
     * @return void
99
     */
100
    protected function initSession()
101
    {
102
        $this->session["query"] = true;
103
        unset($this->session["role"], $this->session["status"]);
104
    }
105
106
    /**
107
     * Listen for and intercept properties that're not set
108
     *
109
     * @param string $role;
0 ignored issues
show
Bug introduced by
There is no parameter named $role;. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
110
     * @throws \Exception
111
     * @return AclInterface
112
     */
113
    public function __get(string $role) : AclInterface
114
    {
115
        if ($role === self::SYN_ALLOW || $role === self::SYN_DENY)
116
        {
117
            $this->session["status"] = ($role === self::SYN_ALLOW);
118
119
            if (!empty($this->session["role"]))
120
            {
121
                $this->session["query"] = false;
122
            }
123
124
            return $this;
125
        }
126
127
        if (!$this->roleRegistry->exists($role)) {
128
            throw new \Exception(
129
                sprintf(
130
                    "The role: %s doesnt exist",
131
                    (string)$role
132
                )
133
            );
134
        }
135
136
		$this->session["role"] = $role;
137
138
		return $this;
139
	}
140
141
	/**
142
	 * Listen for and intercept undefined methods
143
	 *
144
	 * @param string $permission
145
	 * @param string[] $args
146
	 * @throws \Exception
147
	 * @return boolean|null
148
	 */
149
	public function __call(string $permission, array $args)
150
	{
151
        if (!$this->permissionRegistry->exists($permission)) {
152
            throw new \Exception(
153
                sprintf(
154
                    "The permission: %s doesnt exist",
155
                    (string)$permission
156
                )
157
            );
158
        }
159
160
        foreach ($args as $arg) {
161
            if (!$this->resourceRegistry->exists($arg)) {
162
                throw new \Exception(
163
                    sprintf(
164
                        "The resource: %s doesnt exist",
165
                        (string)$arg
166
                    )
167
                );
168
            }
169
        }
170
171
        $args = (count($args) > 0) ? $args : $this->resourceRegistry->getRegistryNames();
172
173
		if ($this->session["query"])
174
		{
175
            foreach ($args as $arg)
176
            {
177
                $result = $this->getPermissionStatus(
178
                    $this->session["role"],
179
                    $permission,
180
                    $arg
181
                );
182
183
                if (!$result)
184
                {
185
                    break;
186
                }
187
            }
188
            
189
            $this->initSession();
190
191
            return $result;
1 ignored issue
show
Bug introduced by
The variable $result does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
192
		}
193
194
        foreach ($args as $arg) {
195
            $this->allow(
196
                $this->session["role"],
197
                $permission,
198
                $arg,
199
                (boolean)$this->session["status"]
200
            );
201
        }
202
203
		$this->initSession();
204
	}
205
206
	/**
207
	 * Add a new role object to the registry
208
	 *
209
	 * @param string[] $role
210
	 * @return void
211
	 */
212
	public function addRole(string ...$role)
213
	{
214
		foreach ($role as $_role)
215
		{
216
			$this->roleRegistry->save($_role);
217
		}
218
	}
219
220
	/**
221
	 * Add a new resource object to the registry
222
	 *
223
	 * @param string[] $resource
224
	 * @return void
225
	 */
226
	public function addResource(string ...$resource)
227
	{
228
		foreach ($resource as $_resource)
229
		{
230
			$this->resourceRegistry->save($_resource);
231
		}
232
	}
233
234
	/**
235
	 * Add a new permission object to the registry
236
	 *
237
	 * @param string[] $permission
238
	 * @return void
239
	 */
240
	public function addPermission(string ...$permission)
241
	{
242
		foreach ($permission as $_permission)
243
		{
244
			$this->permissionRegistry->save($_permission);
245
		}
246
	}
247
248
	/**
249
	 * Adds objects lazily.
250
	 *
251
	 * Automatically determine the type of an object and call the appropriate
252
	 * add method on it.
253
	 *
254
	 * @param ObjectInterface[] $objects
255
	 * @throws \Exception
256
	 * @return void
257
	 */
258
	public function add(ObjectInterface ...$objects)
259
	{
260
		foreach ($objects as $object)
261
		{
262
			if ($object instanceof RoleInterface)
263
			{
264
				$this->addRole((string)$object);
265
			}
266
			else if ($object instanceof ResourceInterface)
267
			{
268
				$this->addResource((string)$object);
269
			}
270
			else if ($object instanceof PermissionInterface)
271
			{
272
				$this->addPermission((string)$object);
273
			}
274
			else {
275
	            throw new \Exception(
276
	                sprintf(
277
	                    "%s must implement one of RoleInterface, '.
278
	                    'ResourceInterface and PermissionInterface",
279
	                    $object
280
	                )
281
	            );
282
	        }	
283
		}
284
	}
285
286
    /**
287
     * Allows roles to inherit from the registries of other roles
288
     *
289
     * @param string[] $roles
290
     */
291
    public function inherits(string ...$roles)
292
    {
293
        foreach ($roles as $role)
294
        {
295
            if (!$this->roleRegistry->exists($role)) {
296
                throw new \Exception(
297
                    sprintf(
298
                        "The role: %s doesnt exist",
299
                        (string)$role
300
                    )
301
                );
302
            }
303
304
            $this->roleRegistry->setRegistryValue($this->session["role"], $role);
305
        }
306
307
        $this->initSession();
308
    }
309
310
	/**
311
	 * Change the status option of an assigned permission to true
312
	 *
313
	 * @param string $role;
0 ignored issues
show
Bug introduced by
There is no parameter named $role;. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
314
	 * @param string $permission
315
	 * @param string $resource
316
	 * @param boolean $status Optional
317
	 * @throws \Exception
318
	 * @return void
319
	 */
320
	public function allow(string $role, string $permission, string $resource, bool $status=null)
321
	{
322
        $status = $status ?? true;
323
		if (!$this->roleRegistry->exists($role)) {
324
            throw new \Exception(
325
                sprintf(
326
                    "The role: %s doesnt exist",
327
                    (string)$role
328
                )
329
            );
330
        }
331
332
        if (!$this->permissionRegistry->exists($permission)) {
333
            throw new \Exception(
334
                sprintf(
335
                    "The permission: %s doesnt exist",
336
                    (string)$permission
337
                )
338
            );
339
        }
340
341
        if (!$this->resourceRegistry->exists($resource)) {
342
            throw new \Exception(
343
                sprintf(
344
                    "The resource: %s doesnt exist",
345
                    (string)$resource
346
                )
347
            );
348
        }
349
350
        $this->globalRegistry->save($role, $resource, $permission, $status);
351
    }
352
353
    /**
354
     * Change the status option of an assigned permission to false
355
     *
356
     * @param string $role;
0 ignored issues
show
Bug introduced by
There is no parameter named $role;. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
357
     * @param string $permission
358
     * @param string $resource
359
     * @return void
360
     */
361
    public function deny(string $role, string $permission, string $resource)
362
    {
363
        $this->allow($role, $permission, $resource, false);
364
    }
365
366
    /**
367
     * Retrieve the status of a permission assigned to a role
368
     *
369
     * @param string $role;
0 ignored issues
show
Bug introduced by
There is no parameter named $role;. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
370
     * @param string $permission
371
     * @param string $resource
372
     * @return boolean
373
     */
374
    public function getPermissionStatus(string $role, string $permission, string $resource) : bool
375
    {
376
        if (!$this->roleRegistry->exists($role)) {
377
            throw new \Exception(
378
                sprintf(
379
                    "The role: %s doesnt exist",
380
                    (string)$role
381
                )
382
            );
383
        }
384
385
        if (!$this->permissionRegistry->exists($permission)) {
386
            throw new \Exception(
387
                sprintf(
388
                    "The permission: %s doesnt exist",
389
                    (string)$permission
390
                )
391
            );
392
        }
393
394
        if (!$this->resourceRegistry->exists($resource)) {
395
            throw new \Exception(
396
                sprintf(
397
                    "The resource: %s doesnt exist",
398
                    (string)$resource
399
                )
400
            );
401
        }
402
403
        $roleObject = $this->globalRegistry->get($role);
404
405
        if (isset($roleObject[$resource][$permission]["status"]))
406
        {
407
            return $roleObject[$resource][$permission]["status"];
408
        }
409
410
        $parents = $this->roleRegistry->getRegistry()[$role];
411
412
        foreach ($parents as $parentRole)
413
        {
414
            $permissionStatus = $this->getPermissionStatus($parentRole, $permission, $resource);
415
416
            if ($permissionStatus)
417
            {
418
                return true;
419
            }
420
        }
421
422
        return false;
423
    }
424
}
425