Passed
Push — master ( 7f699f...e24ab0 )
by Kirill
03:06
created

Rule   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 50
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 18
c 1
b 0
f 0
dl 0
loc 50
rs 10
wmc 5

2 Methods

Rating   Name   Duplication   Size   Complexity  
A allows() 0 20 4
A __construct() 0 3 1
1
<?php
2
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Spiral\Security;
13
14
use Spiral\Core\ResolverInterface;
15
use Spiral\Security\Exception\RuleException;
16
17
/**
18
 * Rule class provides ability to verify permission request via specified method (by default
19
 * "check") using resolver interface. As side effect check method will support method injections.
20
 *
21
 * Example:
22
 *
23
 * class MyRule extends Rule
24
 * {
25
 *      public function check($actor, $post)
26
 *      {
27
 *          return $post->author_id == $actor->id;
28
 *      }
29
 * }
30
 */
31
abstract class Rule implements RuleInterface
32
{
33
    //Method to be used for checking (support for method injection).
34
    protected const CHECK_METHOD = 'check';
35
36
    /**
37
     * Set of aliases to be used for method injection.
38
     *
39
     * @var array
40
     */
41
    protected const ALIASES = [
42
        'user' => 'actor'
43
    ];
44
45
    /* @var ResolverInterface */
46
    protected $resolver;
47
48
    /**
49
     * @param ResolverInterface $resolver
50
     */
51
    public function __construct(ResolverInterface $resolver)
52
    {
53
        $this->resolver = $resolver;
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     *
59
     * @throws RuleException
60
     */
61
    public function allows(ActorInterface $actor, string $permission, array $context): bool
62
    {
63
        $parameters = compact('actor', 'permission', 'context') + $context;
64
65
        //Mounting aliases
66
        foreach (static::ALIASES as $target => $alias) {
67
            $parameters[$target] = $parameters[$alias];
68
        }
69
70
        try {
71
            $method = new \ReflectionMethod($this, static::CHECK_METHOD);
72
            $method->setAccessible(true);
73
        } catch (\ReflectionException $e) {
74
            throw new RuleException($e->getMessage(), $e->getCode(), $e);
75
        }
76
77
        try {
78
            return $method->invokeArgs($this, $this->resolver->resolveArguments($method, $parameters));
79
        } catch (\Throwable $e) {
80
            throw new RuleException(sprintf('[%s] %s', get_class($this), $e->getMessage()), $e->getCode(), $e);
81
        }
82
    }
83
}
84