AttachRefreshTokenOnSuccessListener::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 4
cts 4
cp 1
rs 9.7
c 0
b 0
f 0
cc 1
nc 1
nop 7
crap 1
1
<?php
2
3
/*
4
 * This file is part of the GesdinetJWTRefreshTokenBundle package.
5
 *
6
 * (c) Gesdinet <http://www.gesdinet.com/>
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
namespace Gesdinet\JWTRefreshTokenBundle\EventListener;
13
14
use Gesdinet\JWTRefreshTokenBundle\Model\RefreshTokenInterface;
15
use Gesdinet\JWTRefreshTokenBundle\Model\RefreshTokenManagerInterface;
16
use Gesdinet\JWTRefreshTokenBundle\Request\RequestRefreshToken;
17
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent;
18
use Symfony\Component\Security\Core\User\UserInterface;
19
use Symfony\Component\Validator\Validator\ValidatorInterface;
20
use Symfony\Component\HttpFoundation\RequestStack;
21
use Symfony\Component\PropertyAccess\PropertyAccessor;
22
23
class AttachRefreshTokenOnSuccessListener
24
{
25
    /**
26
     * @var RefreshTokenManagerInterface
27 4
     */
28
    protected $refreshTokenManager;
29 4
30 4
    /**
31 4
     * @var int
32 4
     */
33
    protected $ttl;
34 3
35
    /**
36 3
     * @var ValidatorInterface
37 3
     */
38 3
    protected $validator;
39
40 3
    /**
41 1
     * @var RequestStack
42
     */
43
    protected $requestStack;
44 2
45
    /**
46 2
     * @var string
47 1
     */
48 1
    protected $userIdentityField;
49 1
50 1
    /**
51
     * @var string
52 1
     */
53 1
    protected $tokenParameterName;
54 1
55 1
    /**
56
     * @var bool
57 1
     */
58 1
    protected $singleUse;
59 1
60 1
    /**
61 1
     * AttachRefreshTokenOnSuccessListener constructor.
62
     *
63
     * @param RefreshTokenManagerInterface $refreshTokenManager
64
     * @param int                          $ttl
65
     * @param ValidatorInterface           $validator
66
     * @param RequestStack                 $requestStack
67
     * @param string                       $userIdentityField
68
     * @param string                       $tokenParameterName
69 1
     * @param bool                         $singleUse
70
     */
71 1
    public function __construct(
72 1
        RefreshTokenManagerInterface $refreshTokenManager,
73
        $ttl,
74
        ValidatorInterface $validator,
75 2
        RequestStack $requestStack,
76 2
        $userIdentityField,
77
        $tokenParameterName,
78
        $singleUse
79
    ) {
80
        $this->refreshTokenManager = $refreshTokenManager;
81
        $this->ttl = $ttl;
82
        $this->validator = $validator;
83
        $this->requestStack = $requestStack;
84
        $this->userIdentityField = $userIdentityField;
85
        $this->tokenParameterName = $tokenParameterName;
86
        $this->singleUse = $singleUse;
87
    }
88
89
    public function attachRefreshToken(AuthenticationSuccessEvent $event)
90
    {
91
        $data = $event->getData();
92
        $user = $event->getUser();
93
        $request = $this->requestStack->getCurrentRequest();
94
95
        if (!$user instanceof UserInterface) {
96
            return;
97
        }
98
99
        $refreshTokenString = RequestRefreshToken::getRefreshToken($request, $this->tokenParameterName);
0 ignored issues
show
Bug introduced by
It seems like $request defined by $this->requestStack->getCurrentRequest() on line 93 can be null; however, Gesdinet\JWTRefreshToken...oken::getRefreshToken() 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...
100
101
        if ($refreshTokenString && true === $this->singleUse) {
102
            $refreshToken = $this->refreshTokenManager->get($refreshTokenString);
103
            $refreshTokenString = null;
104
105
            if ($refreshToken instanceof RefreshTokenInterface) {
106
                $this->refreshTokenManager->delete($refreshToken);
107
            }
108
        }
109
110
        if ($refreshTokenString) {
111
            $data[$this->tokenParameterName] = $refreshTokenString;
112
        } else {
113
            $datetime = new \DateTime();
114
            $datetime->modify('+'.$this->ttl.' seconds');
115
116
            $refreshToken = $this->refreshTokenManager->create();
117
118
            $accessor = new PropertyAccessor();
119
            $userIdentityFieldValue = $accessor->getValue($user, $this->userIdentityField);
120
121
            $refreshToken->setUsername($userIdentityFieldValue);
122
            $refreshToken->setRefreshToken();
123
            $refreshToken->setValid($datetime);
124
125
            $valid = false;
126
            while (false === $valid) {
127
                $valid = true;
128
                $errors = $this->validator->validate($refreshToken);
129
                if ($errors->count() > 0) {
130
                    foreach ($errors as $error) {
131
                        if ('refreshToken' === $error->getPropertyPath()) {
132
                            $valid = false;
133
                            $refreshToken->setRefreshToken();
134
                        }
135
                    }
136
                }
137
            }
138
139
            $this->refreshTokenManager->save($refreshToken);
140
            $data[$this->tokenParameterName] = $refreshToken->getRefreshToken();
141
        }
142
143
        $event->setData($data);
144
    }
145
}
146