Completed
Push — master ( 298ac7...0024da )
by Oleg
12:58
created

GenerateTemporaryTokenAction::createToken()   B

Complexity

Conditions 4
Paths 10

Size

Total Lines 34
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 6.3324

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 9
cts 19
cp 0.4737
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 26
nc 10
nop 2
crap 6.3324
1
<?php
2
declare(strict_types=1);
3
4
namespace SlayerBirden\DataFlowServer\Authentication\Controller;
5
6
use Doctrine\ORM\EntityManager;
7
use Doctrine\ORM\ORMException;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Message\ServerRequestInterface;
10
use Psr\Http\Server\MiddlewareInterface;
11
use Psr\Http\Server\RequestHandlerInterface;
12
use Psr\Log\LoggerInterface;
13
use SlayerBirden\DataFlowServer\Authentication\Exception\PermissionDeniedException;
14
use SlayerBirden\DataFlowServer\Authentication\TokenManagerInterface;
15
use SlayerBirden\DataFlowServer\Domain\Entities\User;
16
use SlayerBirden\DataFlowServer\Notification\DangerMessage;
17
use SlayerBirden\DataFlowServer\Notification\SuccessMessage;
18
use SlayerBirden\DataFlowServer\Stdlib\Validation\ValidationResponseFactory;
19
use Zend\Diactoros\Response\JsonResponse;
20
use Zend\Hydrator\ExtractionInterface;
21
use Zend\InputFilter\InputFilterInterface;
22
23
class GenerateTemporaryTokenAction implements MiddlewareInterface
24
{
25
    /**
26
     * @var EntityManager
27
     */
28
    private $entityManager;
29
    /**
30
     * @var TokenManagerInterface
31
     */
32
    private $tokenManager;
33
    /**
34
     * @var LoggerInterface
35
     */
36
    private $logger;
37
    /**
38
     * @var ExtractionInterface
39
     */
40
    private $extraction;
41
    /**
42
     * @var InputFilterInterface
43
     */
44
    private $inputFilter;
45
46 4
    public function __construct(
47
        EntityManager $entityManager,
0 ignored issues
show
Bug introduced by
You have injected the EntityManager via parameter $entityManager. This is generally not recommended as it might get closed and become unusable. Instead, it is recommended to inject the ManagerRegistry and retrieve the EntityManager via getManager() each time you need it.

The EntityManager might become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:

function someFunction(ManagerRegistry $registry) {
    $em = $registry->getManager();
    $em->getConnection()->beginTransaction();
    try {
        // Do something.
        $em->getConnection()->commit();
    } catch (\Exception $ex) {
        $em->getConnection()->rollback();
        $em->close();

        throw $ex;
    }
}

If that code throws an exception and the EntityManager is closed. Any other code which depends on the same instance of the EntityManager during this request will fail.

On the other hand, if you instead inject the ManagerRegistry, the getManager() method guarantees that you will always get a usable manager instance.

Loading history...
48
        InputFilterInterface $inputFilter,
49
        TokenManagerInterface $tokenManager,
50
        LoggerInterface $logger,
51
        ExtractionInterface $extraction
52
    ) {
53 4
        $this->entityManager = $entityManager;
54 4
        $this->tokenManager = $tokenManager;
55 4
        $this->logger = $logger;
56 4
        $this->extraction = $extraction;
57 4
        $this->inputFilter = $inputFilter;
58 4
    }
59
60
    /**
61
     * @inheritdoc
62
     */
63 4
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
64
    {
65 4
        $userId = (int)$request->getAttribute('id');
66 4
        $data = $request->getParsedBody();
67 4
        $this->inputFilter->setData($data);
0 ignored issues
show
Bug introduced by
It seems like $data defined by $request->getParsedBody() on line 66 can also be of type null or object; however, Zend\InputFilter\InputFilterInterface::setData() does only seem to accept array|object<Traversable>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
68
69 4
        if ($this->inputFilter->isValid()) {
70 4
            return $this->createToken($userId, $data['resources']);
71
        } else {
72
            return (new ValidationResponseFactory())('token', $this->inputFilter);
73
        }
74
    }
75
76 4
    private function createToken(int $userId, array $resources): ResponseInterface
77
    {
78
        try {
79
            /** @var User $user */
80 4
            $user = $this->entityManager->find(User::class, $userId);
81 4
            if ($user) {
82 4
                $token = $this->tokenManager->getTmpToken($user, $resources);
83 4
                return new JsonResponse([
84 4
                    'data' => [
85 4
                        'token' => $this->extraction->extract($token),
86
                        'validation' => [],
87
                    ],
88
                    'success' => true,
89 4
                    'msg' => new SuccessMessage('Token created'),
90 4
                ], 200);
91
            } else {
92
                $msg = new DangerMessage('User not found');
93
            }
94
        } catch (PermissionDeniedException $exception) {
95
            $msg = new DangerMessage($exception->getMessage());
96
        } catch (ORMException $exception) {
97
            $this->logger->error((string)$exception);
98
            $msg = new DangerMessage('There was an error while obtaining tmp token.');
99
        }
100
101
        return new JsonResponse([
102
            'data' => [
103
                'token' => null,
104
                'validation' => [],
105
            ],
106
            'success' => false,
107
            'msg' => $msg,
108
        ], 400);
109
    }
110
}
111