Passed
Push — master ( 4b954d...b01812 )
by Gabor
03:38
created

AclMiddleware::__invoke()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.9197
c 0
b 0
f 0
cc 4
eloc 11
nc 3
nop 2
1
<?php
2
/**
3
 * WebHemi.
4
 *
5
 * PHP version 5.6
6
 *
7
 * @copyright 2012 - 2016 Gixx-web (http://www.gixx-web.com)
8
 * @license   https://opensource.org/licenses/MIT The MIT License (MIT)
9
 *
10
 * @link      http://www.gixx-web.com
11
 */
12
13
namespace WebHemi\Middleware\Security;
14
15
use Exception;
16
use WebHemi\Adapter\Auth\AuthAdapterInterface;
17
use WebHemi\Adapter\Http\ResponseInterface;
18
use WebHemi\Adapter\Http\ServerRequestInterface;
19
use WebHemi\Auth\Result;
20
use WebHemi\Data\Coupler\UserToGroupCoupler;
21
use WebHemi\Data\Coupler\UserToPolicyCoupler;
22
use WebHemi\Data\Coupler\UserGroupToPolicyCoupler;
23
use WebHemi\Data\Entity\User\UserEntity;
24
use WebHemi\Middleware\MiddlewareInterface;
25
use WebHemi\Middleware\Action;
26
27
/**
28
 * Class AclMiddleware.
29
 */
30
class AclMiddleware implements MiddlewareInterface
31
{
32
    /** @var AuthAdapterInterface */
33
    private $authAdapter;
34
    /** @var UserToPolicyCoupler */
35
    private $userToPolicyCoupler;
36
    /** @var UserToGroupCoupler */
37
    private $userToGroupCoupler;
38
    /** @var UserGroupToPolicyCoupler */
39
    private $userGroupToPolicyCoupler;
40
    /** @var array */
41
    private $middlewareWhiteList = [
42
        Action\Auth\LoginAction::class,
43
        Action\Auth\LogoutAction::class,
44
    ];
45
46
    /**
47
     * AclMiddleware constructor.
48
     * @param AuthAdapterInterface     $authAdapter
49
     * @param UserToPolicyCoupler      $userToPolicyCoupler
50
     * @param UserToGroupCoupler       $userToGroupCoupler
51
     * @param UserGroupToPolicyCoupler $userGroupToPolicyCoupler
52
     */
53
    public function __construct(
54
        AuthAdapterInterface $authAdapter,
55
        UserToPolicyCoupler $userToPolicyCoupler,
56
        UserToGroupCoupler $userToGroupCoupler,
57
        UserGroupToPolicyCoupler $userGroupToPolicyCoupler
58
    ) {
59
        $this->authAdapter = $authAdapter;
60
        $this->userToPolicyCoupler = $userToPolicyCoupler;
61
        $this->userToGroupCoupler = $userToGroupCoupler;
62
        $this->userGroupToPolicyCoupler = $userGroupToPolicyCoupler;
63
    }
64
65
    /**
66
     * A middleware is a callable. It can do whatever is appropriate with the Request and Response objects.
67
     * The only hard requirement is that a middleware MUST return an instance of \Psr\Http\Message\ResponseInterface.
68
     * Each middleware SHOULD invoke the next middleware and pass it Request and Response objects as arguments.
69
     *
70
     * @param ServerRequestInterface $request
71
     * @param ResponseInterface      $response
72
     * @throws Exception
73
     * @return ResponseInterface
74
     */
75
    public function __invoke(ServerRequestInterface &$request, ResponseInterface $response)
76
    {
77
        $actionMiddleware = $request->getAttribute(ServerRequestInterface::REQUEST_ATTR_RESOLVED_ACTION_CLASS);
78
79
        if (!in_array($actionMiddleware, $this->middlewareWhiteList) && !$this->authAdapter->hasIdentity()) {
80
            /** @var Result $result */
81
            $result = $this->authAdapter->authenticate();
82
83
            if (!$result->isValid()) {
84
                throw new Exception($result->getMessage());
85
            }
86
87
            $userEntity = $result->getIdentity();
88
            $this->authAdapter->setIdentity($userEntity);
0 ignored issues
show
Bug introduced by
It seems like $userEntity defined by $result->getIdentity() on line 87 can be null; however, WebHemi\Adapter\Auth\Aut...nterface::setIdentity() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
89
        } else {
90
            $userEntity = $this->authAdapter->getIdentity();
0 ignored issues
show
Unused Code introduced by
$userEntity is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
91
        }
92
93
        // TODO: now we have the user entity, so let's check it against the policies...
94
95
        return $response;
96
    }
97
}
98