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 ( 1e02fa...c67920 )
by Samuel
02:56
created

Acl::__call()   B

Complexity

Conditions 9
Paths 22

Size

Total Lines 56
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 56
rs 7.1584
c 0
b 0
f 0
cc 9
eloc 30
nc 22
nop 2

How to fix   Long Method   

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 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
	 * Change the status option of an assigned permission to true
288
	 *
289
	 * @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...
290
	 * @param string $permission
291
	 * @param string $resource
292
	 * @param boolean $status Optional
293
	 * @throws \Exception
294
	 * @return void
295
	 */
296
	public function allow(string $role, string $permission, string $resource, bool $status=null)
297
	{
298
        $status = $status ?? true;
299
		if (!$this->roleRegistry->exists($role)) {
300
            throw new \Exception(
301
                sprintf(
302
                    "The role: %s doesnt exist",
303
                    (string)$role
304
                )
305
            );
306
        }
307
308
        if (!$this->permissionRegistry->exists($permission)) {
309
            throw new \Exception(
310
                sprintf(
311
                    "The permission: %s doesnt exist",
312
                    (string)$permission
313
                )
314
            );
315
        }
316
317
        if (!$this->resourceRegistry->exists($resource)) {
318
            throw new \Exception(
319
                sprintf(
320
                    "The resource: %s doesnt exist",
321
                    (string)$resource
322
                )
323
            );
324
        }
325
326
        $this->globalRegistry->save($role, $resource, $permission, $status);
327
    }
328
329
    /**
330
     * Change the status option of an assigned permission to false
331
     *
332
     * @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...
333
     * @param string $permission
334
     * @param string $resource
335
     * @return void
336
     */
337
    public function deny(string $role, string $permission, string $resource)
338
    {
339
        $this->allow($role, $permission, $resource, false);
340
    }
341
342
    /**
343
     * Retrieve the status of a permission assigned to a role
344
     *
345
     * @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...
346
     * @param string $permission
347
     * @param string $resource
348
     * @return boolean
349
     */
350
    public function getPermissionStatus(string $role, string $permission, string $resource) : bool
351
    {
352
        if (!$this->roleRegistry->exists($role)) {
353
            throw new \Exception(
354
                sprintf(
355
                    "The role: %s doesnt exist",
356
                    (string)$role
357
                )
358
            );
359
        }
360
361
        if (!$this->permissionRegistry->exists($permission)) {
362
            throw new \Exception(
363
                sprintf(
364
                    "The permission: %s doesnt exist",
365
                    (string)$permission
366
                )
367
            );
368
        }
369
370
        if (!$this->resourceRegistry->exists($resource)) {
371
            throw new \Exception(
372
                sprintf(
373
                    "The resource: %s doesnt exist",
374
                    (string)$resource
375
                )
376
            );
377
        }
378
379
380
        $role = $this->globalRegistry->get($role);
381
382
        return $role[$resource][$permission]["status"] ?? false;
383
    }
384
}
385