Passed
Push — master ( cbcfd0...888846 )
by Daniel
05:09
created

JWTManager::createFromPayload()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 1
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the Silverback API Components Bundle Project
5
 *
6
 * (c) Daniel West <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Silverback\ApiComponentsBundle\Security;
15
16
use Lexik\Bundle\JWTAuthenticationBundle\Exception\InvalidPayloadException;
17
use Lexik\Bundle\JWTAuthenticationBundle\Exception\JWTDecodeFailureException;
18
use Lexik\Bundle\JWTAuthenticationBundle\Exception\UserNotFoundException;
19
use Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\PreAuthenticationJWTUserToken;
20
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
21
use Silverback\ApiComponentsBundle\Event\JWTRefreshedEvent;
22
use Silverback\ApiComponentsBundle\RefreshToken\Storage\RefreshTokenStorageInterface;
23
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
24
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
25
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
26
use Symfony\Component\Security\Core\User\UserInterface;
27
use Symfony\Component\Security\Core\User\UserProviderInterface;
28
29
/**
30
 * @author Vincent Chalamon <[email protected]>
31
 */
32
final class JWTManager implements JWTTokenManagerInterface
33
{
34
    private JWTTokenManagerInterface $decorated;
35
    private EventDispatcherInterface $dispatcher;
36
    private UserProviderInterface $userProvider;
37
    private RefreshTokenStorageInterface $storage;
38
39
    public function __construct(JWTTokenManagerInterface $decorated, EventDispatcherInterface $dispatcher, UserProviderInterface $userProvider, RefreshTokenStorageInterface $storage)
40
    {
41
        $this->decorated = $decorated;
42
        $this->dispatcher = $dispatcher;
43
        $this->userProvider = $userProvider;
44
        $this->storage = $storage;
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50
    public function create(UserInterface $user): string
51
    {
52
        $this->storage->expireAll($user);
53
        $this->storage->create($user);
54
55
        return $this->decorated->create($user);
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61
    public function decode(TokenInterface $token)
62
    {
63
        try {
64
            return $this->decorated->decode($token);
65
        } catch (JWTDecodeFailureException $exception) {
66
            if (JWTDecodeFailureException::EXPIRED_TOKEN !== $exception->getReason()) {
67
                throw $exception;
68
            }
69
70
            $payload = $exception->getPayload();
71
            $idClaim = $this->getUserIdClaim();
72
73
            if (!isset($payload[$idClaim])) {
74
                throw new InvalidPayloadException($idClaim);
75
            }
76
77
            $identity = $payload[$idClaim];
78
79
            try {
80
                $user = $this->userProvider->loadUserByUsername($identity);
81
            } catch (UsernameNotFoundException $e) {
82
                throw new UserNotFoundException($idClaim, $identity);
83
            }
84
85
            $refreshToken = $this->storage->findOneByUser($user);
86
            if (!$refreshToken || $refreshToken->isExpired()) {
87
                throw $exception;
88
            }
89
90
            $this->storage->expireAll($user);
91
92
            $this->storage->create($user);
93
94
            $accessToken = $this->create($user);
95
96
            $this->dispatcher->dispatch(new JWTRefreshedEvent($accessToken));
97
98
            return $this->decorated->decode(new PreAuthenticationJWTUserToken($accessToken));
99
        }
100
    }
101
102
    /**
103
     * {@inheritdoc}
104
     */
105
    public function setUserIdentityField($field)
106
    {
107
        return $this->decorated->setUserIdentityField($field);
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113
    public function getUserIdentityField(): string
114
    {
115
        return $this->decorated->getUserIdentityField();
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     */
121
    public function getUserIdClaim(): string
122
    {
123
        return $this->decorated->getUserIdClaim();
124
    }
125
126
    /**
127
     * {@inheritdoc}
128
     */
129
    public function createFromPayload(UserInterface $user, array $payload)
130
    {
131
        return $this->decorated->createFromPayload($user, $payload);
0 ignored issues
show
Bug introduced by
The method createFromPayload() does not exist on Lexik\Bundle\JWTAuthenti...WTTokenManagerInterface. Did you maybe mean create()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

131
        return $this->decorated->/** @scrutinizer ignore-call */ createFromPayload($user, $payload);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
132
    }
133
}
134